Replay each path's selectors through the walk for the family fence, require a key for a name, refuse a name shadowing a key, a table reading its own family and an ancestor's column clash, add the row node and family.go, and pin eight rows inline
Tests / vet + fmt + tests (pull_request) Successful in 1m8s
Tests / Gitea release from CHANGELOG.md (pull_request) Has been skipped

This commit is contained in:
2026-09-17 12:54:24 +02:00
parent fb83aa6178
commit 047237f361
14 changed files with 419 additions and 277 deletions
+6 -9
View File
@@ -262,18 +262,12 @@ func checkNoRepeatedRead(format string, c formatOps, refs map[string]refBinding)
type draws struct {
variant map[string]node
value map[string]draw
pins [4]tablePin // the rows pinned, inline so a render pinning a few tables stays off the heap
pins [8]tablePin // the rows pinned, inline so a render over a country's five-deep geo tree stays off the heap
npins int
more map[*table]int // the rows pinned past the inline four
more map[*table]int // the rows pinned past the inline eight
s *session // what draws a row; nil where a walk only proves selectors
}
// tablePin is one table's pinned row.
type tablePin struct {
t *table
row int
}
// draw is what one read drew: its text, and whether it landed on a null.
type draw struct {
text string
@@ -298,7 +292,7 @@ func readField(s *session, t *template, held *draws, sc drawScope, a arm) draw {
if r, done := d.value[a.path]; done {
return r
}
leaf, _ := walkPath(t.fields[a.key], a.tail, pathWalk{
leaf, err := walkPath(t.fields[a.key], a.tail, pathWalk{
// Hold the draw at every level passed through, so two paths sharing a
// prefix share it.
choice: func(c *choice, rest []string) ([]node, error) {
@@ -318,6 +312,9 @@ func readField(s *session, t *template, held *draws, sc drawScope, a arm) draw {
},
pins: d,
})
if err != nil {
panic(fmt.Sprintf("fejkdata: %q: %v; a fence should have refused this at New", a.name, err))
}
r := renderLeaf(s, leaf, sc)
if d.value == nil {
d.value = map[string]draw{}