// Small shared helpers for the planner.
package plan import ( ) // eqFold is a case-insensitive name compare (function/procedure names). func eqFold(, string) bool { return strings.EqualFold(, ) } // lower is ASCII lowercasing for name dispatch. func lower( string) string { return strings.ToLower() } // sortSlice sorts s by less (a stable order is not required by callers). func sortSlice[ any]( [], func(, ) bool) { sort.Slice(, func(, int) bool { return ([], []) }) } // exprEqual is structural expression equality (the Rust derived ==), // used to match an ORDER BY key against a projected expression. func exprEqual(, ast.Expr) bool { return reflect.DeepEqual(, ) } // setLen is a nil-tolerant nodeset length (a nil set is empty). func setLen( *nodeset.Set) int { if == nil { return 0 } return .Len() } // setSlice is a nil-tolerant nodeset materialization. func setSlice( *nodeset.Set) []uint32 { if == nil { return nil } return .ToSlice() } // seekProbes is the set of index keys a single-value property seek must // probe for v: the value itself plus its numeric twin when one exists // (the index matches stored values exactly; equality coerces). func seekProbes( value.Value) []value.Value { if , := value.NumericTwin(); { return []value.Value{, } } return []value.Value{} } // seekCard is the posting count a single-value property seek yields for v // across all its probes. func seekCard( graph.Graph, , string, value.Value) uint64 { var uint64 for , := range seekProbes() { += uint64(setLen(.NodesWithProperty(, , ))) } return } // seekNodes is the sorted, deduplicated id set a single-value property // seek yields for v across all its probes (the exact set the built scan // serves). func seekNodes( graph.Graph, , string, value.Value) []graph.NodeID { var []graph.NodeID for , := range seekProbes() { = append(, setSlice(.NodesWithProperty(, , ))...) } slices.Sort() return slices.Compact() }