Skip to content

Commit fecf50a

Browse files
committed
chore(query): give caveats back canonical keys, simplifying code
1 parent e3062d9 commit fecf50a

File tree

4 files changed

+27
-49
lines changed

4 files changed

+27
-49
lines changed

pkg/query/canonicalize.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,6 @@ func isNullOutline(outline Outline) bool {
258258

259259
// assignNodeIDs recursively assigns a unique OutlineNodeID to each node bottom-up,
260260
// recording each node's serialized CanonicalKey in keys.
261-
// Filter operations (see isFilterOperation) are left with ID == 0 and are not
262-
// added to the map; they derive their canonical key on demand via Serialize().
263261
func assignNodeIDs(outline Outline, keys map[OutlineNodeID]CanonicalKey) Outline {
264262
// Recurse on children first (bottom-up)
265263
if len(outline.SubOutlines) > 0 {
@@ -270,11 +268,6 @@ func assignNodeIDs(outline Outline, keys map[OutlineNodeID]CanonicalKey) Outline
270268
outline.SubOutlines = newSubs
271269
}
272270

273-
// Filter operations don't get their own canonical ID
274-
if isFilterOperation(outline) {
275-
return outline // ID remains 0
276-
}
277-
278271
id := OutlineNodeID(nodeIDCounter.Add(1))
279272
outline.ID = id
280273
keys[id] = outline.Serialize()

pkg/query/canonicalize_test.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,20 +1237,22 @@ func TestCanonicalKey_WithCaveats(t *testing.T) {
12371237
canonical, err := CanonicalizeOutline(outline)
12381238
require.NoError(err)
12391239

1240-
// Caveat (filter) nodes have ID == 0 and are not in the map
1241-
require.Equal(OutlineNodeID(0), canonical.Root.ID,
1242-
"caveat (filter) root should have ID == 0")
1243-
require.True(canonical.CanonicalKeys[canonical.Root.ID].IsEmpty(),
1244-
"filter nodes should not be in the CanonicalKeys map")
1240+
// Caveat nodes now receive their own canonical ID and key
1241+
require.NotEqual(OutlineNodeID(0), canonical.Root.ID,
1242+
"caveat root should have a non-zero ID")
1243+
require.False(canonical.CanonicalKeys[canonical.Root.ID].IsEmpty(),
1244+
"caveat nodes should be in the CanonicalKeys map")
12451245

1246-
// The canonical key for a filter node equals its child's canonical key
1246+
// The caveat's canonical key is identified by name only, independent of its child
12471247
child := canonical.Root.SubOutlines[0]
12481248
require.False(canonical.CanonicalKeys[child.ID].IsEmpty(),
12491249
"child of caveat should have a canonical key in the map")
1250-
require.Equal(canonical.Root.Serialize(), canonical.CanonicalKeys[child.ID],
1251-
"caveat's Serialize() should equal child's canonical key")
1252-
1253-
// The canonical key reflects the underlying data, not the caveat wrapper
1254-
require.NotContains(canonical.Root.Serialize().String(), "cav:",
1255-
"filter operation canonical key should not mention the caveat")
1250+
require.NotEqual(canonical.Root.Serialize(), canonical.CanonicalKeys[child.ID],
1251+
"caveat's Serialize() should differ from child's canonical key")
1252+
1253+
// The canonical key includes the caveat name
1254+
require.Contains(canonical.Root.Serialize().String(), "cav:",
1255+
"caveat canonical key should mention the caveat name")
1256+
require.Equal("C(cav:age_check)", canonical.Root.Serialize().String(),
1257+
"caveat canonical key format")
12561258
}

pkg/query/outline.go

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,10 @@ func (co CanonicalOutline) Compile() (Iterator, error) {
8585

8686
// compileOutline recursively builds an Iterator tree from an Outline,
8787
// looking up each node's CanonicalKey from the provided map.
88-
// Filter operations (ID == 0) derive their canonical key on the fly via Serialize().
8988
func compileOutline(outline Outline, keys map[OutlineNodeID]CanonicalKey) (Iterator, error) {
90-
var key CanonicalKey
91-
if isFilterOperation(outline) {
92-
key = outline.Serialize()
93-
} else {
94-
var ok bool
95-
key, ok = keys[outline.ID]
96-
if !ok {
97-
return nil, spiceerrors.MustBugf("outline node ID %d not found in CanonicalKeys map - outline must come from a CanonicalOutline", outline.ID)
98-
}
89+
key, ok := keys[outline.ID]
90+
if !ok {
91+
return nil, spiceerrors.MustBugf("outline node ID %d not found in CanonicalKeys map - outline must come from a CanonicalOutline", outline.ID)
9992
}
10093

10194
// First, recursively compile all subiterators (bottom-up)
@@ -359,14 +352,6 @@ func Decompile(it Iterator) (Outline, error) {
359352
}
360353
}
361354

362-
// isFilterOperation returns true for Outline nodes that are pure filter
363-
// operations and therefore do not have their own canonical representation.
364-
// Filter operations are transparent: their canonical key is their child's key.
365-
// Currently only CaveatIteratorType qualifies.
366-
func isFilterOperation(o Outline) bool {
367-
return o.Type == CaveatIteratorType
368-
}
369-
370355
type OutlineMutation func(Outline) Outline
371356

372357
// MutateOutline performs a bottom-up traversal of the outline tree, applying
@@ -544,17 +529,9 @@ func caveatCompare(a, b *core.ContextualizedCaveat) int {
544529
// Format: <Type>(<Args>)[<Sub1>,<Sub2>,...]
545530
// Returns a CanonicalKey wrapping the serialized string.
546531
//
547-
// Filter operations (e.g. CaveatIteratorType) are transparent: their canonical
548-
// key is their child's key, since filters do not affect the set identity.
532+
// CaveatIterator nodes are identified solely by their caveat name, independent
533+
// of their position in the tree. Their subiterators are not included in the key.
549534
func (outline Outline) Serialize() CanonicalKey {
550-
// Filter operations are transparent — delegate to child
551-
if isFilterOperation(outline) {
552-
if len(outline.SubOutlines) > 0 {
553-
return outline.SubOutlines[0].Serialize()
554-
}
555-
return CanonicalKey("")
556-
}
557-
558535
var result strings.Builder
559536

560537
// Add type (single character)
@@ -570,6 +547,12 @@ func (outline Outline) Serialize() CanonicalKey {
570547
}
571548
}
572549

550+
// Caveat nodes are identified solely by their name, independent of
551+
// their position in the tree. Do not include subiterators in the key.
552+
if outline.Type == CaveatIteratorType {
553+
return CanonicalKey(result.String())
554+
}
555+
573556
// Add subiterators if present
574557
if len(outline.SubOutlines) > 0 {
575558
result.WriteByte('[')

pkg/query/outline_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,9 +1377,9 @@ func TestSerializeOutline(t *testing.T) {
13771377
},
13781378
}
13791379

1380-
// Caveat is a filter operation — Serialize() delegates to its child
1380+
// Caveat nodes are identified by name only; subiterators are not included
13811381
key := outline.Serialize()
1382-
require.Equal("0", key.String())
1382+
require.Equal("C(cav:age_check)", key.String())
13831383
})
13841384

13851385
t.Run("AliasIteratorType", func(t *testing.T) {

0 commit comments

Comments
 (0)