Documentation
¶
Overview ¶
Package values is the Value-tier of the Go Cascades planner port — scalar / row-context expressions that compose into predicates, projections, and join keys. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values` package.
Contents:
- Value interface (Children, Type, Name, Evaluate) + concrete subtypes: Constant, Field, Arithmetic, Boolean, Cast, Null, Aggregate, QuantifiedObject, Promote, RecordConstructor, Parameter, ScalarFunction, Not.
- ExplainValue — SQL-ish renderer used by plan-cache keying and EXPLAIN output.
- SimplifyValue — standalone constant-fold over a Value tree (free function; the rule-driven equivalent lives in cascades's `Simplify`).
- LiteralValue / ToInt64 / ToFloat64 — coercion helpers promoted from comparisons.go (RFC-025 Phase 1) so both values/ and predicates/ can call them without a layering cycle.
- CorrelationIdentifier + Correlated — Quantifier-tracking surface used by Values to declare which upstream Quantifier they depend on; rewrite rules consult this when checking correlation-shape preservation.
- ExpressionFolder + DefaultFolder — testable seam for plan-time constant folding (RFC-025 §"Closing the leaks").
- The Type hierarchy (`type.go`) — the rich `Type` interface + `TypeCode` enum + concrete impls (`PrimitiveType`, `RecordType`, `ArrayType`, `EnumType`, `RelationType`), canonical singletons for every primitive (incl. UUID, VERSION, None, Any), `TypeRepository`, `WithNullability`, the `IsPromotable` / `MaximumType` / `MaximumTypeOfMany` promotion lattice (with structural recursion through ARRAY / RECORD / ENUM / RELATION), and shape predicates (`IsNull`, `IsArray`, …). Every Value impl's `Type()` returns the rich `Type` directly — the legacy `ValueType` enum + `FromValueType` / `ToValueType` bridges are retired. Once `type.go` exceeds ~1500 LOC it splits into a dedicated `cascades/typing/` sub-package per RFC-025.
Imports: nothing else from `pkg/recordlayer/query/plan/cascades/...`. `predicates/`, `matching/`, and root `cascades` all import this package; the dependency arrow points inward to keep cycles out.
Index ¶
- Variables
- func AssertOrdinalJoinSeed(rc *RecordConstructorValue)
- func ContainsAggregate(v Value) bool
- func ContainsBakedOrdinal(v Value) bool
- func EqualsWithoutChildren(a, b Value) bool
- func EvaluateConstant(v Value) (out any, ok bool)
- func ExplainValue(v Value) string
- func GetCorrelatedToOfAnchoredJoinLegs(rc *RecordConstructorValue) map[CorrelationIdentifier]struct{}
- func GetCorrelatedToOfValue(v Value) map[CorrelationIdentifier]struct{}
- func IsAny(t Type) bool
- func IsArray(t Type) bool
- func IsCascadesSafeScalarFunction(name string) bool
- func IsConstantValue(v Value) bool
- func IsEnum(t Type) bool
- func IsFunctionallyDependentOn(v Value, otherValue Value) bool
- func IsIndexOnly(v Value) bool
- func IsNonEvaluable(v Value) bool
- func IsNone(t Type) bool
- func IsNull(t Type) bool
- func IsOrdinalFieldName(name string) bool
- func IsOrdinalJoinRV(v Value) bool
- func IsPositionalMergeRC(v Value) bool
- func IsPromotable(from, to Type) bool
- func IsRecord(t Type) bool
- func IsRelation(t Type) bool
- func IsUnresolved(t Type) bool
- func IsUuid(t Type) bool
- func LikeMatch(pattern, s string, escape rune) bool
- func MergeSeedLegsOfValue(v Value) map[CorrelationIdentifier]struct{}
- func OrdinalFieldName(ordinal int) string
- func OutputColumnName(v Value, alias string) string
- func ProjectionColumnName(v Value) string
- func PullUpValues(toBePulledUp []Value, resultValue Value, alias CorrelationIdentifier) map[Value]Value
- func SemanticEqualsUnderAliasMap(a, b Value, aliases AliasMap) bool
- func SemanticHashCode(v Value) uint64
- func ToFloat64(v any) (f float64, isFloat, numeric bool)
- func ToInt64(v any) (int64, bool)
- func ValueSize(v Value) int
- func ValuesStructurallyEqual(a, b Value) bool
- func WalkValue(v Value, visit func(Value) bool)
- type AggregateEvalError
- type AggregateOp
- type AggregateValue
- type AliasMap
- type AnchoredJoinLeg
- type AndOrOp
- type AndOrValue
- type ArithmeticDivisionByZeroError
- type ArithmeticOp
- type ArithmeticOverflowError
- type ArithmeticValue
- type ArrayConstructorValue
- type ArrayDistinctValue
- type ArrayType
- type BakedNameContextError
- type BooleanValue
- type CardinalityValue
- type CastValue
- type CollateValue
- type ConditionSelectorValue
- type ConstantDeref
- type ConstantObjectValue
- type ConstantValue
- type Correlated
- type CorrelationBinder
- type CorrelationIdentifier
- type CosineDistanceRowNumberValue
- func (*CosineDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*CosineDistanceRowNumberValue) IsIndexOnly() bool
- func (*CosineDistanceRowNumberValue) Name() string
- func (*CosineDistanceRowNumberValue) Type() Type
- func (v *CosineDistanceRowNumberValue) WithChildren(newChildren []Value) *CosineDistanceRowNumberValue
- type DerivedValue
- type DistanceOperator
- type DistanceRowNumberValue
- type DistanceValue
- type DotProductDistanceRowNumberValue
- func (*DotProductDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*DotProductDistanceRowNumberValue) IsIndexOnly() bool
- func (*DotProductDistanceRowNumberValue) Name() string
- func (*DotProductDistanceRowNumberValue) Type() Type
- func (v *DotProductDistanceRowNumberValue) WithChildren(newChildren []Value) *DotProductDistanceRowNumberValue
- type EmptyValue
- type EnumType
- type EnumValue
- type EuclideanDistanceRowNumberValue
- func (*EuclideanDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*EuclideanDistanceRowNumberValue) IsIndexOnly() bool
- func (*EuclideanDistanceRowNumberValue) Name() string
- func (*EuclideanDistanceRowNumberValue) Type() Type
- func (v *EuclideanDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanDistanceRowNumberValue
- type EuclideanSquareDistanceRowNumberValue
- func (*EuclideanSquareDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*EuclideanSquareDistanceRowNumberValue) IsIndexOnly() bool
- func (*EuclideanSquareDistanceRowNumberValue) Name() string
- func (*EuclideanSquareDistanceRowNumberValue) Type() Type
- func (v *EuclideanSquareDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanSquareDistanceRowNumberValue
- type EvaluatesTo
- type EvaluatesToValue
- type ExistsValue
- func (v *ExistsValue) Children() []Value
- func (v *ExistsValue) Evaluate(ctx any) (any, error)
- func (v *ExistsValue) GetChild() Value
- func (v *ExistsValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*ExistsValue) Name() string
- func (*ExistsValue) Type() Type
- func (v *ExistsValue) WithNewChild(c Value) *ExistsValue
- type ExpressionFolder
- type Field
- type FieldPath
- type FieldValue
- func NewFieldValue(child Value, field string, typ Type) *FieldValue
- func NewFieldValueOfOrdinal(child Value, ordinal int) (*FieldValue, error)
- func NewFieldValueWithResolvedOrdinal(field string, ordinal int, typ Type) *FieldValue
- func NewFlatFieldValue(field string, typ Type) *FieldValue
- func NewOrdinalFieldValue(child Value, ordinal int, typ Type) *FieldValue
- type FirstOrDefaultStreamingValue
- func (v *FirstOrDefaultStreamingValue) Children() []Value
- func (v *FirstOrDefaultStreamingValue) Evaluate(evalCtx any) (any, error)
- func (*FirstOrDefaultStreamingValue) Name() string
- func (v *FirstOrDefaultStreamingValue) Type() Type
- func (v *FirstOrDefaultStreamingValue) WithChildren(newChildren []Value) *FirstOrDefaultStreamingValue
- type FirstOrDefaultValue
- type FromOrderedBytesValue
- type InOpValue
- type IncarnationValue
- type IndexEntryObjectValue
- type IndexEntryReader
- type IndexOnly
- type IndexOnlyAggregateOp
- type IndexOnlyAggregateValue
- func (v *IndexOnlyAggregateValue) Children() []Value
- func (*IndexOnlyAggregateValue) Evaluate(any) (any, error)
- func (v *IndexOnlyAggregateValue) GetIndexTypeName() string
- func (*IndexOnlyAggregateValue) IsIndexOnly() bool
- func (*IndexOnlyAggregateValue) IsNonEvaluable() bool
- func (v *IndexOnlyAggregateValue) Name() string
- func (v *IndexOnlyAggregateValue) Type() Type
- func (v *IndexOnlyAggregateValue) WithChildren(newChildren []Value) *IndexOnlyAggregateValue
- type IndexableAggregate
- type IndexedValue
- type InvalidArgumentError
- type InvalidCastError
- type LeafValue
- type LikeOperatorValue
- type NonEvaluable
- type NotValue
- type NullValue
- type ObjectValue
- type OfTypeValue
- type OrderedBytesDirection
- type OrdinalBakeError
- type OrdinalResolutionError
- type OrdinalRow
- type OrdinalSeedLegWindow
- type ParameterBinder
- type ParameterObjectValue
- func (*ParameterObjectValue) Children() []Value
- func (v *ParameterObjectValue) Evaluate(evalCtx any) (any, error)
- func (*ParameterObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*ParameterObjectValue) Name() string
- func (v *ParameterObjectValue) RebaseLeaf(_ CorrelationIdentifier) Value
- func (v *ParameterObjectValue) Type() Type
- type ParameterValue
- type PatternForLikeValue
- type PickValue
- type PrimitiveType
- type PromoteValue
- type QuantifiedObjectValue
- func (*QuantifiedObjectValue) Children() []Value
- func (q *QuantifiedObjectValue) Evaluate(evalCtx any) (any, error)
- func (q *QuantifiedObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*QuantifiedObjectValue) Name() string
- func (q *QuantifiedObjectValue) RebaseLeaf(targetAlias CorrelationIdentifier) Value
- func (q *QuantifiedObjectValue) Type() Type
- type QuantifiedRecordValue
- type QueriedValue
- type RangeValue
- type RankValue
- type ReEnumerationLeg
- type RecordConstructorField
- type RecordConstructorValue
- func NewAnchoredJoinRecord(legs []AnchoredJoinLeg) *RecordConstructorValue
- func NewRawRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue
- func NewReEnumerationAnchoredRecord(parent *RecordConstructorValue, legs []ReEnumerationLeg) *RecordConstructorValue
- func NewRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue
- func NewScalarSubqueryAnchoredRecord(outer AnchoredJoinLeg, innerAlias CorrelationIdentifier, scalarColKey string) *RecordConstructorValue
- type RecordType
- func (*RecordType) Code() TypeCode
- func (r *RecordType) Equals(other Type) bool
- func (r *RecordType) FieldIndex(name string) (int, bool)
- func (r *RecordType) GetField(ordinal int) (Field, bool)
- func (r *RecordType) IsNullable() bool
- func (r *RecordType) LookupField(name string) (Field, bool)
- func (r *RecordType) String() string
- type RecordTypeLeg
- type RecordTypeValue
- type RegularTranslationMap
- type RelationType
- type ResolvedAccessor
- type RowEvalContext
- type RowNumberHighOrderValue
- type RowNumberValue
- type ScalarFunctionValue
- type ScalarSubqueryValue
- type ScalarTypeMismatchError
- type SelfEqualsWithoutChildren
- type SelfSemanticHash
- type SelfWithChildren
- type StreamingValue
- type StrictRankLimitValue
- func (v *StrictRankLimitValue) Children() []Value
- func (v *StrictRankLimitValue) EqualsWithoutChildrenValue(other Value) bool
- func (v *StrictRankLimitValue) Evaluate(evalCtx any) (any, error)
- func (v *StrictRankLimitValue) Name() string
- func (v *StrictRankLimitValue) Type() Type
- func (v *StrictRankLimitValue) WithChildren(newChildren []Value) Value
- type SubscriptValue
- type ThrowsValue
- type ToOrderedBytesValue
- type TranslationFunction
- type TranslationMap
- type TranslationMapBuilder
- type TranslationMapWhen
- type TupleSource
- type Type
- type TypeCode
- type TypeRegistrationError
- type TypeRepository
- type UdfValue
- type UnmatchedAggregateValue
- func (*UnmatchedAggregateValue) Children() []Value
- func (*UnmatchedAggregateValue) Evaluate(_ any) (any, error)
- func (v *UnmatchedAggregateValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*UnmatchedAggregateValue) IsNonEvaluable() bool
- func (*UnmatchedAggregateValue) Name() string
- func (*UnmatchedAggregateValue) Type() Type
- type Value
- func DeconstructRecord(v Value) []Value
- func LiteralValue(lit any) Value
- func MapFieldValues(v Value, transform func(*FieldValue) Value) Value
- func PullUpValue(v Value, resultValue Value, alias CorrelationIdentifier) Value
- func PushDownValue(v Value, resultValue Value, upperAlias CorrelationIdentifier) Value
- func PushDownValues(toBePushedDown []Value, resultValue Value, upperAlias CorrelationIdentifier) []Value
- func RebaseValue(v Value, aliases AliasMap) Value
- func Replace(v Value, replacementFn func(Value) Value) Value
- func ReplaceLeavesMaybe(v Value, replaceFn func(Value) Value) Value
- func ReplaceLeavesOnceMaybe(v Value, replaceFn func(Value) Value) Value
- func SimplifyAll(in []Value) []Value
- func SimplifyValue(v Value) Value
- func SimplifyValueWithContext(v Value, ctx ValueSimplifyContext) Value
- func TranslateCorrelations(v Value, m TranslationMap) Value
- func WithChildren(v Value, newChildren []Value) Value
- type ValueSimplifyContext
- type VersionValue
- type WindowedValue
Constants ¶
This section is empty.
Variables ¶
var CurrentAlias = CorrelationIdentifier{/* contains filtered or unexported fields */}
CurrentAlias is the well-known CorrelationIdentifier representing "the current row". Mirrors Java's `Quantifier.current()` — used by set-operation comparison key values and other contexts where a Value references "the row currently being processed" without binding to a specific named Quantifier.
var Empty = &EmptyValue{}
Empty is the canonical EmptyValue instance. Callers should prefer this over allocating a new one — pointer identity makes equality checks O(1).
var OracleBakedNameFallback bool
OracleBakedNameFallback is the §5 dual-window differential's TEST-ONLY bridge: when true, a BAKED FieldValue evaluated against a NAME-keyed row context reads its display name instead of erroring — recreating the pre-RFC-173 name model end-to-end (including its duplicate-name conflation, which is exactly why dup-name corpus shapes are carved out of the differential by RFC citation). It travels WITH executor. DisablePositionalEmission — the dualwindow harness sets both at the phase barrier. NEVER set in production: with the flag false (always, outside the oracle), a baked node hitting a name-keyed context is a loud *BakedNameContextError, because the gated ordinal frontier guarantees positional rows — a name-keyed context there is a planner/executor bug. Retires with the name map in Slice 4.
var ReportUnresolvedReference func(field string, available []string)
ReportUnresolvedReference, when non-nil, is invoked by FieldValue.Evaluate whenever a Strict RowEvalContext is asked for a local field name that is not present in its (complete) row. It is the RFC-048 W1 "no unresolved reference" invariant: a silent name->NULL — the cardinal silent-wrong — is turned into a loud, attributable signal. It is nil by default (zero production overhead and behaviour beyond the map lookup that already happens); test/debug builds install a hook that fails the test. `field` is the missing name; `available` is the row's actual key set (for diagnostics).
Functions ¶
func AssertOrdinalJoinSeed ¶
func AssertOrdinalJoinSeed(rc *RecordConstructorValue)
AssertOrdinalJoinSeed is the LOUD RFC-173 ordinal-join seed-shape validator: the Slice 2 translator calls it on every ordinal join RC it builds, where the pristine shape IS guaranteed by construction — every field a BAKED FieldValue over a leg QuantifiedObjectValue flowing a *RecordType, exactly TWO consecutive full-coverage leg runs with baked ordinals 0..width-1 ascending. Any violation panics: at the SEED a malformed ordinal RC is unconditionally a planner bug (review W3a-1 ruling: strictness lives seed-time, where legitimate result-value rewrites — wrapper merges, folded projections, partial coverage — cannot yet have happened; the executor's cursor-side ordinalJoinSpans probe DECLINES those shapes, never panics).
Lives in values (not executor) because the TRANSLATOR is the caller of record — the standing review condition on the W3b seed: a seed flip that lands without this assert is a NAK on sight.
func ContainsAggregate ¶
ContainsAggregate reports whether v has any AggregateValue in its subtree. Common gate for rules that only apply to scalar expressions — aggregates need the accumulator path, not per-row Evaluate.
func ContainsBakedOrdinal ¶
ContainsBakedOrdinal reports whether any FieldValue in v's subtree carries a FRONTIER-PINNED baked-ordinal marker — the structural "is this an S2 gated-join ordinal value tree" probe the coexistence-window drift asserts key on (SelectMergeRule target loop, the executor's ordinal-join birth). Deliberately blind to UNPINNED baked nodes (the recursive-CTE wrap): those carry no join-frontier contract and must not trip join-seed machinery. Retires with the name model in Slice 4.
func EqualsWithoutChildren ¶
EqualsWithoutChildren checks whether two Values are the same type with the same non-child attributes, WITHOUT recursing into children. This is the Go equivalent of Java's Value.equalsWithoutChildren().
For leaf values (no children) this is equivalent to ValuesStructurallyEqual. For composite values it checks the type and any type-specific attributes (operator, field names, etc.) but does NOT compare children.
Returns true if a and b have the same concrete type and the same non-child attributes (e.g. same ArithmeticOp, same field names in RecordConstructorValue, same CastValue target type, etc.).
func EvaluateConstant ¶
EvaluateConstant attempts to fold v to a concrete literal at plan time. Returns (literal, true) when v is constant (per IsConstantValue); (nil, false) otherwise. Safe on nil (returns (nil, false)). Useful for rules that want to pre-compute a constant sub-expression without writing an `if isConstant { eval and wrap }` dance every time.
A data-dependent runtime error from Evaluate (arithmetic overflow, division by zero, invalid cast, type mismatch) is reported as "not foldable" — (nil, false). This is the plan-time decline-to-fold path: the typed runtime-error family now returns via the error channel, so the error is swallowed here (leave the node) rather than surfacing a query error from the planner.
Genuinely programmer-invariant panics (e.g. an AggregateValue buried inside a constant tree that IsConstantValue should have excluded) are planner bugs and now surface rather than being silently swallowed — the residual recover that masked them has been collapsed.
func ExplainValue ¶
ExplainValue renders a Value as a readable expression string. Free function rather than a Value-interface method so existing third-party Value impls (once the port grows) don't have to track another method. Walks children recursively for composite values like ArithmeticValue / CastValue.
Output style matches SQL-ish expression rendering:
ConstantValue → the literal as %v FieldValue → the field name ArithmeticValue → (left OP right) BooleanValue → TRUE / FALSE / NULL CastValue → CAST(child AS TypeX) NullValue → NULL
func GetCorrelatedToOfAnchoredJoinLegs ¶
func GetCorrelatedToOfAnchoredJoinLegs(rc *RecordConstructorValue) map[CorrelationIdentifier]struct{}
GetCorrelatedToOfAnchoredJoinLegs returns the leg-quantifier correlations of a source-anchored join RESULT value (RFC-077 F2, partition-time RE-EXPOSURE). GetCorrelatedToOfValue deliberately does NOT descend into an anchored-join RC (exploration-time hiding keeps the search space bounded); this is the explicit counterpart that DOES, so PartitionSelectRule's predicate classification and AddMergeSeedAliases can see the buried leg aliases. It walks each field's value tree (FieldValue(QOV(leg), col) — possibly NESTED, when a leg is itself an anchored join not yet simplified away) and collects every QuantifiedObjectValue correlation, treating the anchored-RC children as ordinary nodes to descend.
Returns nil for a nil or non-anchored input.
func GetCorrelatedToOfValue ¶
func GetCorrelatedToOfValue(v Value) map[CorrelationIdentifier]struct{}
GetCorrelatedToOfValue walks v + its descendants and returns the union of every correlation-bearing leaf Value's alias. Handles QuantifiedObjectValue, QuantifiedRecordValue, ScalarSubqueryValue, ObjectValue, UnmatchedAggregateValue, and ConstantObjectValue. ExistsValue is a transparent composite — its child QuantifiedObjectValue is reached via the Children() descent.
Returns nil for nil input. Returns a non-nil empty map for trees with no correlations.
Ports Java's Value.getCorrelatedTo().
func IsArray ¶
IsArray reports whether t is an ARRAY (concrete or erased). Mirrors Java's `Type.isArray()`.
func IsCascadesSafeScalarFunction ¶
IsCascadesSafeScalarFunction reports whether the named scalar function is supported by the Cascades planner. Single authoritative list — all callers (translator, predicate upgrade, unsupported-function detection) must use this.
func IsConstantValue ¶
IsConstantValue reports whether v's Evaluate is row-context- independent — its value is known at plan time. True for ConstantValue, NullValue, BooleanValue, and any composite whose children are all constants (`1 + 2`, `CAST(5 AS STRING)`). False for FieldValue / QuantifiedObjectValue / AggregateValue and any composite containing them.
Used by rule matchers that only fire on fully-foldable operands (e.g. ComparisonConstantSimplifyRule's whitelist).
func IsFunctionallyDependentOn ¶
IsFunctionallyDependentOn reports whether v is functionally dependent on otherValue — meaning v's output is fully determined by otherValue's output. Ports Java's Value.isFunctionallyDependentOn.
Returns true if all correlation-bearing leaves in v reference the same correlation as otherValue (when otherValue is a QOV). Returns false if any leaf references a different scope, or if otherValue is not a QOV.
func IsIndexOnly ¶
IsIndexOnly is a helper that any Value can call to check whether v requires an index scan to produce its result.
func IsNonEvaluable ¶
IsNonEvaluable is a helper that any Value can call to check whether v is plan-time-only. Avoids type-assertion boilerplate in callers.
func IsNone ¶
IsNone reports whether t is the NONE type (untyped empty array). Mirrors Java's `Type.isNone()`.
func IsNull ¶
IsNull reports whether t is the NULL literal's type (TypeCodeNull). Mirrors Java's `Type.isNull()`.
func IsOrdinalFieldName ¶
IsOrdinalFieldName reports whether name is a planner-internal ordinal-addressed field key (`_0`, `_1`, …) — OrdinalFieldName's inverse, digits-only (OrdinalFieldName never emits signs, so `_-1`/`_+0` are NOT ordinal keys). User columns cannot take this form (a parsed identifier's leading `_` is legal, but the S3 positional-merge and Explode-ordinality producers are the only writers of these keys in a merged row).
func IsOrdinalJoinRV ¶
IsOrdinalJoinRV reports whether v is an ordinal-model JOIN-SELECT result value: a raw (non-anchored) RC whose every field is a FrontierPinned baked reference over a quantifier — the flat N-leg seed and its TranslationMap- translated upper forms (fused multi-accessor paths included) — spanning at least two distinct root quantifiers. This is the ordinal counterpart of the AnchoredJoin marker for the interning gate: the shapes whose quantifiers have no external identity consumer, where alias-IDENTITY dedup re-explodes the join re-enumeration's shared sub-products per bipartition. A lazy field anywhere (CTE column renames, computed projections) declines — those selects keep the alias-identity dedup that Go's column derivation requires.
func IsPositionalMergeRC ¶
IsPositionalMergeRC is the VALUE-level half of the S3 structural merge-select recognition (W2 ruling Q3 — no imperative marker, the exact shape PartitionSelectRule.java:284-291 builds and nothing else can): an RC whose every field is auto-generated-named ("_i", in position order — Java Type.java:2922 isAutoGenerated) and whose value is a BARE QOV of a distinct quantifier. The SELECT-level half (the QOVs are the select's own owned ForEach quantifiers, covering them) lives at the interning gate; the executor checks the QOVs against its two legs. Unconstructible from SQL: the generator names all columns, so CTE column-rename selects never match. Lives beside ContainsBakedOrdinal — the two value-shape probes the ordinal birth triggers on.
func IsPromotable ¶
IsPromotable reports whether `from` can be implicitly promoted to `to` without an explicit CAST. Returns true when:
- from.Code() == to.Code() (identity, same type code).
- The (from.Code, to.Code) pair is in the promotionMap.
Mirrors Java's `PromoteValue.isPromotable`. Nullability is NOT part of the promotion check — a NOT NULL value can always be stored in a nullable slot of the same code, and a nullable value being stored in a NOT NULL slot is rejected at the caller (NOT NULL constraint), not by promotion.
Arrays / records / enums / vectors with structural inner types need element-by-element checks done by the caller (Java's isPromotionNeeded recurses for these); IsPromotable only handles the top-level code pair.
func IsRelation ¶
IsRelation reports whether t is a RELATION. Mirrors Java's `Type.isRelation()`.
func IsUnresolved ¶
IsUnresolved reports whether t is one of the placeholder types (UNKNOWN / NULL / NONE / ANY) — i.e. the type isn't a concrete shape that can carry data on its own. Mirrors Java's `Type.isUnresolved()`.
func LikeMatch ¶
LikeMatch implements SQL `LIKE` matching:
- `%` matches zero or more characters
- `_` matches exactly one character
- `escape` (if non-zero) makes the next character a literal
Greedy backtrack; O(|pattern| * |s|) worst case. Returns true iff the pattern matches the whole string (SQL LIKE is anchored on both ends).
Conformance contract: this is the canonical SQL LIKE matcher used by both the QueryPredicate-layer ComparisonLike (via predicates package) AND the Value-layer LikeOperatorValue. Java's `Comparisons.likeMatcher` is the spec; this implementation has been fuzz-tested against a regex oracle in `pkg/recordlayer/query/plan/cascades/predicates/comparisons_test.go` (FuzzLikeMatch / FuzzLikeMatchEscape). Any divergence between this and Java's `likeMatcher` is a conformance bug.
Trailing-escape behaviour: a trailing escape rune (no following character) is MALFORMED → no match (a fuzz-found bug fix).
func MergeSeedLegsOfValue ¶
func MergeSeedLegsOfValue(v Value) map[CorrelationIdentifier]struct{}
MergeSeedLegsOfValue returns the SOURCE-LEG correlations a value tree depends on THROUGH a merged (source-anchored join) row — the partition-time re-exposure twin of GetCorrelatedToOfValue, at the value level rather than the predicate level (predicates.AddMergeSeedAliases).
A multi-source lateral UNNEST reads a BURIED leg's column through the merged outer row: `FieldValue{Field:"A.ARR", Child:QOV(B)}` reads `QOV(B)["A.ARR"]` where B is the rightmost (flow) leg and A is a NON-flow leg merged into B's row. GetCorrelatedToOfValue reports only {B} (the QOV it references), so the genuine dependency on A is INVISIBLE — and PartitionSelectRule/ PartitionBinarySelectRule, which classify bipartition validity from the correlation order, would let `{B, Explode}` separate from A, materializing the Explode against a bare B row where `A.ARR` is unbound (zero rows). This recovers the buried leg A from the DOTTED field prefix: a FieldValue whose Field is `LEG.COL` (and whose Child resolves to a QuantifiedObjectValue — i.e. it reads off a merged quantifier's row, not a literal anchored RC) genuinely depends on the source leg `LEG`. The anchored merged row always names its legs by their source alias as the dotted prefix (NewAnchoredJoinRecord), and those source aliases ARE the sibling quantifier aliases after the merge flattens — so the prefix maps directly to the owned quantifier.
Returns a non-nil (possibly empty) map; nil input yields an empty map.
func OrdinalFieldName ¶
OrdinalFieldName is the runtime map key used for an anonymous record field addressed by ordinal position. Java's planner names anonymous explode-with-ordinality fields `_0` (element) and `_1` (ordinal) — see the `q1._0` / `q1._1` access in the EXPLAIN output. The runtime Datum is a name-keyed `map[string]any`, so an ordinal-addressed FieldValue (Java's `FieldValue.ofOrdinalNumber`) reads the `_<ordinal>` key.
func OutputColumnName ¶
OutputColumnName is the projection OUTPUT-name authority: the name that keys the emitted positional row's slot for a projected column (executeProjection's posNames) and therefore the name any downstream re-reader must use on the ordinal frontier — the upper-cased ALIAS when the column carries one, else the ProjectionColumnName rendering. It lives here so every site derives the name from ONE rule instead of a hand-synchronized copy: the RFC-173 Slice-1 alias-frontier bug was exactly two copies of this rule disagreeing (the executor wrote alias-preferring slot names while the recursive-CTE leg wrap re-read by ProjectionColumnName alone — a loud OrdinalResolutionError on valid SQL, no fallback by design). Both sites now delegate here.
func ProjectionColumnName ¶
ProjectionColumnName is the projection output-column NAMING CONTRACT: the name a projected Value's result is keyed under in the executor's name-keyed row (executeProjection's projNames) and, alias-absent, in the positional row's type (posNames). A FieldValue projects under its (possibly dotted) Field; any other Value under its upper-cased explain rendering (a computed expression like `n + 1` is keyed "(N + 1)"). Shared here so the planner/translator side can READ a projection's output by the exact key the executor WRITES — reading by any other rendering (e.g. the logical layer's un-parenthesized "N + 1") is a silent NULL under the name model and a loud OrdinalResolutionError under the ordinal model (RFC-173 §5 dual-window differential, first catch).
func PullUpValues ¶
func PullUpValues(toBePulledUp []Value, resultValue Value, alias CorrelationIdentifier) map[Value]Value
PullUpValues translates a list of values through a result value, returning a map from original value to pulled-up value. Values that cannot be pulled up are omitted from the map.
This is the batch form used by Ordering.PullUpThroughValue.
func SemanticEqualsUnderAliasMap ¶
SemanticEqualsUnderAliasMap reports whether two Values are equal up to the quantifier-alias correspondence in `aliases` — the bool, alias-map-keyed counterpart of EqualsWithoutChildren+children, for memo interning and relational EqualsWithoutChildren (RFC-040 040.2). Correlation-bearing leaf Values compare their alias through the map (an unmapped alias maps to itself, so identical aliases compare equal under the empty map); every other Value compares structurally via EqualsWithoutChildren and recurses children under the same map.
This is consistent with SemanticHashCode: when this returns true, the two values have equal SemanticHashCode (both alias-invariant on the leaf aliases). Distinct from the cascades ValueEquivalence path, which carries QueryPlanConstraints for match-candidate compensation; this is the constraint-free bool primitive the expression/memo layer needs.
func SemanticHashCode ¶
SemanticHashCode returns an ALIAS-INVARIANT structural hash of a Value: the contract (Java Correlated.semanticHashCode) is
SemanticEqualsUnderAliasMap(a, b, m) ⟹ SemanticHashCode(a) == SemanticHashCode(b)
for ANY alias map m — so the hash must NOT depend on specific quantifier-alias names. Correlation-bearing leaf Values (QuantifiedObjectValue, QuantifiedRecord, Object, ConstantObject, Exists, ScalarSubquery, UnmatchedAggregate, IndexEntryObject, JoinMerge) hash to a per-type tag with the alias EXCLUDED; value-bearing leaves (ConstantValue, BooleanValue, ParameterValue) fold their literal; structural Values fold a type tag + children.
Lives in the values package (RFC-040 040.1b relocation) so both expressions (for relational EqualsWithoutChildren/HashCodeWithoutChildren, 040.2) and cascades (memoEqual) can use it without an import cycle. Inert until those call sites switch to it.
func ToFloat64 ¶
ToFloat64 reports whether v is numeric (int-like or float) and returns its float64 promotion. isFloat distinguishes native-float inputs from integral ones promoted here — comparison-time promotion uses it to prefer the int path when both sides are integral.
func ValueSize ¶
ValueSize returns the total node count in v (v + all descendants). Counterpart to PredicateSize for the Value tree. Rule authors use this to gate expensive rewrites that would otherwise explode tree size.
func ValuesStructurallyEqual ¶
ValuesStructurallyEqual reports whether two Values are structurally equal: same concrete Go type, same metadata, and recursively equal children. Stronger than ExplainValue comparison which could theoretically collide on structurally different values that render the same string.
func WalkValue ¶
WalkValue applies visit to every node in v's subtree, pre-order. If visit returns false, descent into that node's children is skipped (siblings + ancestors continue). Rule authors use this for tree-wide searches — e.g. "does any sub-expression reference this correlation?" or "does this Value tree contain an aggregate?".
Safe on nil: returns immediately. Mirrors WalkPredicate over the Value side of the hierarchy.
Types ¶
type AggregateEvalError ¶
type AggregateEvalError struct {
Message string
}
AggregateEvalError is returned by AggregateValue.Evaluate when an aggregate node is reached on the per-row scalar evaluation path — e.g. an aggregate used in WHERE (`WHERE COUNT(*) > 0`). Java rejects this shape at plan time ("unable to eval an aggregation function with eval()"); Go's planner does not yet (TODO: plan-time rejection of aggregate-in-scalar-context), so the misuse reaches row eval. It is genuinely reachable from user query data, so it must return an error rather than panic (RFC-087 residual-panic audit, gate #1). The executor maps this to SQLSTATE 42803 (grouping error).
func (*AggregateEvalError) Error ¶
func (e *AggregateEvalError) Error() string
type AggregateOp ¶
type AggregateOp int
AggregateOp identifies an aggregate function. Mirrors the subset of Java's `AggregateValue` that the embedded engine currently lowers to a Record Layer aggregate-index query.
const ( AggInvalid AggregateOp = iota // unassigned — rejects if ever evaluated AggCount // COUNT(expr) AggCountStar // COUNT(*) AggSum // SUM(expr) AggMin // MIN(expr) AggMax // MAX(expr) AggAvg // AVG(expr) — rejects at Evaluate, no streaming impl )
Enum of aggregate operators Go supports. Ordered to match Java's bi-map so serialised plans round-trip.
func (AggregateOp) Symbol ¶
func (op AggregateOp) Symbol() string
Symbol returns the canonical SQL function name.
type AggregateValue ¶
type AggregateValue struct {
Op AggregateOp
Operand Value // nil iff Op == AggCountStar
}
AggregateValue represents an aggregate function application — `COUNT(*)`, `SUM(col)`, `MIN(expr)`, etc. The Operand is the argument (nil for COUNT(*)); the Op identifies which aggregate.
AggregateValue does NOT implement per-row Evaluate — aggregates span rows and need an accumulator. Evaluate returns nil to make the ignore-of-row-context explicit; rule code identifies AggregateValues by type-assertion and routes them to the aggregate operator (hash-agg, streaming-agg, index-backed agg) at build time.
func NewAggregateValue ¶
func NewAggregateValue(op AggregateOp, operand Value) *AggregateValue
NewAggregateValue constructs an AggregateValue. Panics on inconsistent op/operand combos (AggCountStar with operand, non-CountStar without operand) — these are static programmer errors, not runtime data problems.
func (*AggregateValue) Children ¶
func (a *AggregateValue) Children() []Value
Children returns the operand as a single child (empty for COUNT(*)). Lets WalkValue traverse aggregate arguments.
func (*AggregateValue) Evaluate ¶
func (a *AggregateValue) Evaluate(any) (any, error)
Evaluate returns AggregateEvalError — aggregates are multi-row and have no single-row Evaluate semantics. Rule / plan code type-asserts AggregateValue and routes it to an accumulator instead of calling Evaluate. The misuse path (an aggregate in a per-row scalar position, e.g. WHERE COUNT(*) > 0) is reachable from user data, so it returns a typed error rather than panicking (RFC-087 residual-panic audit).
func (*AggregateValue) GetIndexTypeName ¶
func (a *AggregateValue) GetIndexTypeName() string
GetIndexTypeName returns the FDB index-type name that backs this aggregate when an aggregate index is available. Mirrors Java's `IndexableAggregateValue.getIndexTypeName()` (Java's interface marker; Go uses an accessor on AggregateValue itself).
The mapping:
AggCount → COUNT_NOT_NULL (counts non-null values)
AggCountStar → COUNT (counts all rows incl. NULL)
AggSum → SUM
AggMin → MIN_EVER_LONG (or MIN_EVER_TUPLE for non-numeric)
AggMax → MAX_EVER_LONG (or MAX_EVER_TUPLE)
AggAvg → "" (no direct index — computed from
SUM/COUNT pair instead)
AggInvalid → ""
Returns the empty string when no FDB index type backs this aggregate. The planner consults this to decide whether to lower to an index-aggregate scan (constant-cost lookup) or fall back to a streaming aggregator (linear-time row scan).
func (*AggregateValue) IsNonEvaluable ¶
func (*AggregateValue) IsNonEvaluable() bool
IsNonEvaluable on AggregateValue returns true — aggregates are multi-row and can't be evaluated per-row by the standard Evaluate path. Implements NonEvaluable.
func (*AggregateValue) Name ¶
func (*AggregateValue) Name() string
Name returns the debug-print kind.
func (*AggregateValue) Type ¶
func (a *AggregateValue) Type() Type
Type returns the rich Type the aggregate produces, matching Java's per-operator resultTypeCode (NumericAggregationValue.PhysicalOperator):
- COUNT / COUNT(*): NotNullLong (zero on empty groups).
- AVG: NullableDouble — AVG is real division, always DOUBLE regardless of operand type (Java AVG_{I,L,F,D} → DOUBLE). NOT operand-derived: AVG(BIGINT) is DOUBLE, not LONG.
- SUM / MIN / MAX: nullable; Type derived from the operand when available, else NullableLong (Java SUM_L→LONG, MIN/MAX→operand).
type AliasMap ¶
type AliasMap map[CorrelationIdentifier]CorrelationIdentifier
AliasMap maps old correlation identifiers to new ones. Used during plan construction when a quantifier's alias changes and downstream values need to reference the new alias.
type AnchoredJoinLeg ¶
type AnchoredJoinLeg struct {
Alias CorrelationIdentifier
Columns []Field
}
AnchoredJoinLeg is one source leg of a source-anchored join result (RFC-077): a quantifier alias and the columns its result row carries (name + type).
type AndOrOp ¶
type AndOrOp int
AndOrOp identifies the boolean connector. Mirrors Java's `AndOrValue.Operator` enum.
type AndOrValue ¶
AndOrValue is the Value-layer AND/OR connector — binary boolean operator with Kleene three-valued logic semantics. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.AndOrValue`.
Java has parallel predicate-layer AndPredicate / OrPredicate (already ported); this Value-layer variant exists for cases where AND/OR appears in a NON-predicate context — typically SQL projections like `SELECT a AND b FROM t` where the connector itself is the row's emitted Value, not a filter.
Result type: NotNullBoolean when both operands are NOT NULL, else NullableBoolean (per SQL Kleene rules — TRUE OR NULL = TRUE, FALSE AND NULL = FALSE, but TRUE AND NULL = NULL).
Eval semantics (Kleene 3VL):
AND | TRUE FALSE NULL -----------|------------------- TRUE | TRUE FALSE NULL FALSE | FALSE FALSE FALSE NULL | NULL FALSE NULL OR | TRUE FALSE NULL -----------|------------------- TRUE | TRUE TRUE TRUE FALSE | TRUE FALSE NULL NULL | TRUE NULL NULL
Short-circuit: if the LEFT operand evaluates to the dominant value (FALSE for AND, TRUE for OR), the right operand is not evaluated. Mirrors Java's eval-side optimisation. The right is evaluated for non-dominant left values (including NULL).
Non-bool operand handling: if either operand evaluates to a non- bool / non-NULL value, eval returns nil (UNKNOWN — type-degraded).
func NewAndOrValue ¶
func NewAndOrValue(op AndOrOp, left, right Value) *AndOrValue
NewAndOrValue constructs an AND/OR Value.
func (*AndOrValue) Children ¶
func (v *AndOrValue) Children() []Value
Children returns [left, right].
func (*AndOrValue) Evaluate ¶
func (v *AndOrValue) Evaluate(evalCtx any) (any, error)
Evaluate computes the Kleene 3VL result with short-circuit.
func (*AndOrValue) Type ¶
func (v *AndOrValue) Type() Type
Type returns NotNullBoolean iff BOTH operands have NOT NULL boolean types, else NullableBoolean. Mirrors Java's AndOrValue.getResultType which OR-reduces operand nullabilities.
Rationale: when both operands are non-nullable booleans, the result is always TRUE or FALSE — never NULL. (NULL only enters the eval through a NULL operand, which can't happen with NOT NULL operand types.) The dispatch matches the conventional SQL type-inference for boolean connectors.
Falls back to NullableBoolean if either operand is missing / non-boolean / nullable.
func (*AndOrValue) WithChildren ¶
func (v *AndOrValue) WithChildren(newChildren []Value) *AndOrValue
WithChildren returns a fresh AndOrValue with the given children. Caller is responsible for passing exactly 2 children; less raises out-of-bounds at access time.
type ArithmeticDivisionByZeroError ¶
type ArithmeticDivisionByZeroError struct{}
ArithmeticDivisionByZeroError is returned by ArithmeticValue.Evaluate when division or modulo by zero is attempted. Callers (the executor) convert this to the appropriate SQL error.
func (*ArithmeticDivisionByZeroError) Error ¶
func (*ArithmeticDivisionByZeroError) Error() string
type ArithmeticOp ¶
type ArithmeticOp int
ArithmeticOp is a subset of SQL arithmetic — enough to build a non-trivial matcher.
const ( OpAdd ArithmeticOp = iota OpSub OpMul OpDiv OpMod )
func (ArithmeticOp) Symbol ¶
func (o ArithmeticOp) Symbol() string
Symbol returns the SQL-text form of the arithmetic operator. Exposed for callers that want to render the op without going through ExplainValue (e.g. error messages, plan diagnostics). Lower-case `symbol` continues to be the package-internal alias.
type ArithmeticOverflowError ¶
type ArithmeticOverflowError struct{}
ArithmeticOverflowError is returned by ArithmeticValue.Evaluate when integer arithmetic overflows. Callers (the executor) convert this to SQLSTATE 22003 NUMERIC_VALUE_OUT_OF_RANGE.
func (*ArithmeticOverflowError) Error ¶
func (*ArithmeticOverflowError) Error() string
type ArithmeticValue ¶
type ArithmeticValue struct {
Op ArithmeticOp
Left Value
Right Value
}
ArithmeticValue is a binary arithmetic over two child Values. Evaluate recurses left + right and applies the op with numeric promotion (float arithmetic when either operand is float64, else int64; mixed non-numeric operands are a ScalarTypeMismatchError). NULL on either side propagates (SQL semantics). Division by zero returns nil (UNKNOWN).
func (*ArithmeticValue) Children ¶
func (a *ArithmeticValue) Children() []Value
func (*ArithmeticValue) Name ¶
func (a *ArithmeticValue) Name() string
func (*ArithmeticValue) Type ¶
func (a *ArithmeticValue) Type() Type
Type returns the arithmetic result Type by numeric promotion of the operand types: DOUBLE if either operand is DOUBLE, else FLOAT if either is FLOAT, else LONG (the conservative integer default, also used when an operand type is unknown). Mirrors Java's ArithmeticValue result typing and the float promotion Evaluate already performs. NULL propagates through Evaluate, so the result is nullable.
type ArrayConstructorValue ¶
ArrayConstructorValue evaluates an N-element ARRAY[a, b, c, ...] SQL literal — gathers each child Value's evaluation into a `[]any` representing the array. Mirrors Java's `LightArrayConstructorValue` (the simple, non-protobuf-message variant of `AbstractArrayConstructorValue`).
All children must produce values compatible with the declared `ElementType`. Go does NOT enforce per-element type validation at construction — Java's `injectPromotions` chain handles type-coercion via `PromoteValue` wrappers; the planner is expected to pre-resolve children to compatible types before reaching this constructor. Mismatched child types surface at evaluation as nil-typed elements in the produced slice.
Result type: nullable Array(ElementType). Java's getResultType() returns `Type.Array(elementType)` (always non-nullable since the constructor produces a concrete array literal); Go matches by emitting `&ArrayType{Nullable: false, ElementType: ...}`.
Empty-array case: an array constructor with zero children produces an empty slice (NOT nil) — Java's eval likewise returns `ImmutableList.of()`. This distinguishes "empty array" from "NULL array" — important for SQL CARDINALITY / ARRAY_LENGTH operations where empty has length 0 and NULL has length NULL.
func NewArrayConstructorValue ¶
func NewArrayConstructorValue(elementType Type, elements []Value) *ArrayConstructorValue
NewArrayConstructorValue constructs an array literal from N element Values, declaring the array's element type. ElementType can be UnknownType when the planner hasn't yet resolved child types — eval still works, child evaluations flow through.
func (*ArrayConstructorValue) Children ¶
func (v *ArrayConstructorValue) Children() []Value
Children returns the element Values.
func (*ArrayConstructorValue) Evaluate ¶
func (v *ArrayConstructorValue) Evaluate(evalCtx any) (any, error)
Evaluate gathers each child's evaluation into a `[]any`.
Empty constructor returns an empty `[]any{}` (NOT nil) so callers can distinguish empty-array from NULL-array via `len(result) == 0 && result != nil`.
Nil child Values are tolerated — produce a nil element. Per Java, this is the same as a child evaluating to NULL.
func (*ArrayConstructorValue) Name ¶
func (*ArrayConstructorValue) Name() string
Name returns the SQL function name.
func (*ArrayConstructorValue) Type ¶
func (v *ArrayConstructorValue) Type() Type
Type returns Array(ElementType), non-nullable. Even an empty array constructor produces a non-nullable empty array — NULL arrays come from elsewhere (a column value of NULL, etc.), not from the constructor.
func (*ArrayConstructorValue) WithChildren ¶
func (v *ArrayConstructorValue) WithChildren(newChildren []Value) *ArrayConstructorValue
WithChildren returns a fresh ArrayConstructorValue with new elements. Element type carries through unchanged — caller is responsible for ensuring new children's types are compatible.
type ArrayDistinctValue ¶
type ArrayDistinctValue struct {
Child Value
// Typ is the result Type — matches Child's Type for arrays.
// Defaults to UnknownType if not set.
Typ Type
}
ArrayDistinctValue is the SQL `ARRAY_DISTINCT` operator: yields the input array with duplicate elements removed (preserving the first-occurrence order of the original). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. ArrayDistinctValue`.
CONFORMANCE: matches Java's eval — returns the input list with `Stream.distinct()` applied (first-seen order). NULL input propagates to NULL.
Type matches the Child's array Type (Go assumes the Child produces an array — Java's constructor `Verify.verify(innerResultType.isArray())` enforces this; Go accepts a Value of any Type but the Evaluate degrades to nil if Child doesn't return a slice).
func NewArrayDistinctValue ¶
func NewArrayDistinctValue(child Value) *ArrayDistinctValue
NewArrayDistinctValue constructs the operator over the given child Value. Type defaults to UnknownType if not provided.
func (*ArrayDistinctValue) Children ¶
func (v *ArrayDistinctValue) Children() []Value
Children returns [Child].
func (*ArrayDistinctValue) Evaluate ¶
func (v *ArrayDistinctValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the deduped array (first-seen order). Returns nil if Child evaluates to nil or non-slice.
Element equality uses bytes.Equal for []byte and Go's == for other types (matching values.equalsAny semantics — see value_in.go for the byte-slice-safe contract).
func (*ArrayDistinctValue) Name ¶
func (*ArrayDistinctValue) Name() string
Name returns the debug-print kind.
func (*ArrayDistinctValue) Type ¶
func (v *ArrayDistinctValue) Type() Type
Type returns the result type (matches Child's type).
type ArrayType ¶
type ArrayType struct {
// Nullable reports whether the array column allows NULL.
Nullable bool
// ElementType is the type of the array's values. May be nil
// when type inference hasn't filled it in (typically transient
// during plan-time analysis; runtime arrays always have a
// concrete element type by the time they're evaluated).
ElementType Type
}
ArrayType is the Type impl for ordered collections. Mirrors Java's Array nested type. Carries an ElementType (the type of the array's values) plus a Nullable flag (whether the array column itself can be NULL).
Two ArrayType instances are Equal iff their Nullable + ElementType match. nil ElementType represents an array whose element type isn't inferred yet (e.g. an empty array literal pre-type-inference) and is equal only to another ArrayType with nil ElementType.
func NewArrayType ¶
NewArrayType constructs an ArrayType. nil elementType is allowed for the "type not yet inferred" case; callers can fill it in via WithElementType once inference produces a concrete type.
func (*ArrayType) Equals ¶
Equals implements Type. Structural — Nullable + ElementType.Equals. Two ArrayTypes both with nil ElementType are equal; one nil + one non-nil are not.
type BakedNameContextError ¶
BakedNameContextError reports a BAKED FieldValue (ordinal authoritative) evaluated against a NAME-keyed or unrecognized row context outside the §5 oracle. Never a silent name read or silent NULL: the display name is diagnostics-only and resolving by it would return the FIRST of duplicate same-named columns — the conflation RFC-173 exists to kill. (A nil context stays NULL — that is the sanctioned appendNullLeg / nil-binding path, contract ruling #3.)
func (*BakedNameContextError) Error ¶
func (e *BakedNameContextError) Error() string
type BooleanValue ¶
type BooleanValue struct {
Value *bool // nil = UNKNOWN
}
BooleanValue is a literal true / false (and NULL when Value is nil — SQL UNKNOWN at the Value layer).
NAMING CAVEAT: Java has a `BooleanValue` of the same name but it's an INTERFACE (Value→QueryPredicate translation shim), not a concrete type. The Go-side concrete is closer to Java's `LiteralValue<Boolean>`. The name collision is regrettable but the Go code references this concrete type explicitly; rule code should not pattern-match on `*BooleanValue` thinking it has Java's interface semantics.
func (*BooleanValue) Children ¶
func (*BooleanValue) Children() []Value
func (*BooleanValue) Name ¶
func (*BooleanValue) Name() string
func (*BooleanValue) Type ¶
func (b *BooleanValue) Type() Type
Type returns the boolean literal's Type — NotNullBoolean for concrete TRUE/FALSE; NullableBoolean when Value is nil (the SQL UNKNOWN-at-Value-layer case).
type CardinalityValue ¶
type CardinalityValue struct {
Child Value
}
CardinalityValue is the SQL `CARDINALITY` operator: yields the number of elements in an array. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. CardinalityValue`.
CARDINALITY(arr) ↔ CardinalityValue{Child: arr}
CONFORMANCE: matches Java's eval — returns the array length as an integer. NULL array → NULL (Java: childResult == null ? null : size()).
The result Type is a nullable 32-bit INT — Java's `Type.primitiveType(Type.TypeCode.INT)` ("array indexes and sizes are 32-bit integers"), nullable because a NULL array yields NULL. The metadata layer reports this column as INTEGER.
Java's ctor asserts the child is array-typed (`SemanticException.check(childValue.getResultType().isArray(), INCOMPATIBLE_TYPE)`). In Go the array-type validation lives at the SQL walk site (expr.walkCardinality), the earliest point with the resolved argument Type and access to the SQLSTATE error codes — a non-array argument raises CANNOT_CONVERT_TYPE there, matching the yamsql. This constructor stays a permissive data builder so the tree-rewrite machinery (withChildren) can reconstruct the node without re-validating.
func NewCardinalityValue ¶
func NewCardinalityValue(child Value) *CardinalityValue
NewCardinalityValue constructs the operator over the given array-typed child Value. Array-type validation is performed at the walk site (see the type doc); this builder does not re-check.
func (*CardinalityValue) Children ¶
func (v *CardinalityValue) Children() []Value
Children returns [Child].
func (*CardinalityValue) Evaluate ¶
func (v *CardinalityValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the array length. Mirrors Java's eval: childResult == null ? null : ((List)childResult).size(). A NULL array (nil child result) yields NULL; an empty array yields 0; a populated array yields its element count. Returns int64 (the codebase's integer eval representation; the column metadata is INTEGER via Type()). A non-slice child result yields nil — Java would ClassCastException, but array-type validation at the walk site keeps the child array-typed, so this is an unreachable defensive guard, not a silent type-degrade.
func (*CardinalityValue) Name ¶
func (*CardinalityValue) Name() string
Name returns the debug-print kind.
func (*CardinalityValue) Type ¶
func (*CardinalityValue) Type() Type
Type returns nullable INT — Java's `Type.primitiveType(Type.TypeCode.INT)`. A NULL array makes the result NULL, so the type is nullable; the width is 32-bit INT (reported as INTEGER), not LONG.
type CastValue ¶
CastValue converts a child Value's result to a target Type. Go handles the trivial conversions our existing corpus needs: int ↔ string (via strconv-free formatting), bool ↔ int (false=0, true=1). Unknown conversions return nil (UNKNOWN) — extend the Evaluate switch when a corpus query needs a new pair.
func NewCastValue ¶
NewCastValue constructs a CastValue.
type CollateValue ¶
type CollateValue struct {
StringChild Value
LocaleChild Value // nil = use registry default locale
StrengthChild Value // nil = use registry default strength
}
CollateValue applies a locale-specific collation to a string, producing a sort-key BYTES blob suitable for use as part of an index key. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.CollateValue`.
SQL surface:
collate(name, 'en_US', 'PRIMARY')
↑ string ↑ locale ↑ strength
Locale and strength are optional — Java's grammar allows `collate(name)`, `collate(name, locale)`, or `collate(name, locale, strength)`.
Strength enum (mirrors java.text.Collator):
- PRIMARY: only base-letter differences matter ('a' = 'A', 'a' ≠ 'b').
- SECONDARY: + accent differences ('a' ≠ 'á', 'a' = 'A').
- TERTIARY: + case differences ('a' ≠ 'A').
- IDENTICAL: full Unicode normalisation.
Used in collation-aware sort + comparison: the produced BYTES blob is a normalised sort key — sorting / comparing the keys lexicographically reproduces locale-aware ordering.
Result type: NotNullBytes. Even when the input string is NULL, the produced sort key is a sentinel byte sequence (Java's behaviour); Go surfaces nil in that branch (no sentinel).
Eval is a placeholder: the collation machinery exists on the index side (pkg/recordlayer/collate_function_key_expression.go wires golang.org/x/text/collate) but is NOT wired into this Value's Evaluate. The Value-shape is reachable for parser / planner / serialisation work; a query that needs runtime COLLATE evaluation must wire that machinery through here first.
func NewCollateValue ¶
func NewCollateValue(stringChild, localeChild, strengthChild Value) *CollateValue
NewCollateValue constructs a collate-encoder. localeChild + strengthChild may be nil to indicate "use defaults".
func (*CollateValue) Children ¶
func (v *CollateValue) Children() []Value
Children returns [stringChild, localeChild?, strengthChild?] — optional children are skipped when nil. Mirrors Java's computeChildren ImmutableList.builder pattern.
func (*CollateValue) Evaluate ¶
func (*CollateValue) Evaluate(any) (any, error)
Evaluate is a placeholder — real eval needs golang.org/x/text/collate wiring. Returns nil per the existing placeholder pattern.
func (*CollateValue) WithChildren ¶
func (v *CollateValue) WithChildren(newChildren []Value) *CollateValue
WithChildren returns a fresh CollateValue with new children. Caller is responsible for passing the right number of children (1 / 2 / 3); the constructor reflects the count back into the optional fields.
type ConditionSelectorValue ¶
type ConditionSelectorValue struct {
Implications []Value
}
ConditionSelectorValue evaluates a list of boolean "implication" Values in order and returns the 0-based INDEX of the first TRUE implication. Returns nil if no implication evaluates TRUE. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ConditionSelectorValue`.
Companion to PickValue: together they implement SQL CASE expressions:
CASE WHEN c1 THEN v1
WHEN c2 THEN v2
ELSE def END
↓ Cascades planner lowering
PickValue(
selector = ConditionSelectorValue(c1, c2, TRUE),
alternatives = [v1, v2, def],
type = inferredType,
)
The trailing TRUE implication captures the implicit ELSE — the selector returns the def's index when no earlier predicate matches.
Result type: INT (NotNullInt — except when no implication matches, where eval returns nil; the type is still INT as a discriminator even though the value can be NULL at runtime).
Eval contract:
- Walks each implication in source order.
- First implication that evaluates TRUE → returns its 0-based index as int64.
- All implications FALSE / NULL / non-bool → returns nil.
Per Java's eval, only Boolean.TRUE matches — Boolean.FALSE and non-boolean / null results don't trigger the index return.
func NewConditionSelectorValue ¶
func NewConditionSelectorValue(implications []Value) *ConditionSelectorValue
NewConditionSelectorValue constructs the selector with the given implication list. Defensive copy of the slice so caller mutations don't bleed into Value state.
func (*ConditionSelectorValue) Children ¶
func (v *ConditionSelectorValue) Children() []Value
Children returns the implications list — the only Value children.
func (*ConditionSelectorValue) Evaluate ¶
func (v *ConditionSelectorValue) Evaluate(evalCtx any) (any, error)
Evaluate walks implications in order. Returns the 0-based int64 index of the first TRUE implication, nil if none match.
Strict-TRUE check: only `bool == true` triggers the index return. Boolean.FALSE, NULL, or non-boolean results don't match. Mirrors Java's `Boolean.TRUE.equals(result)` strict check.
func (*ConditionSelectorValue) Name ¶
func (*ConditionSelectorValue) Name() string
Name returns the SQL function name.
func (*ConditionSelectorValue) Type ¶
func (*ConditionSelectorValue) Type() Type
Type returns NotNullInt — the selector returns an integer index.
Note: Java's getResultType() returns Type.primitiveType(INT) which is the *Java-level* type signature; the eval may return null at runtime when no implication matches. The Type accessor is the declared type, not the dynamic type. SQL's nullable wrapping happens at the consumer (PickValue) when interpreting the selector's nil-runtime-result.
func (*ConditionSelectorValue) WithChildren ¶
func (v *ConditionSelectorValue) WithChildren(newChildren []Value) *ConditionSelectorValue
WithChildren returns a fresh ConditionSelectorValue with the given implications substituted. Used by the simplification driver when child rewrites land on the implications.
type ConstantDeref ¶
type ConstantDeref interface {
// DereferenceConstant returns the value bound to (alias,
// constantID) at evaluation time, or nil if no binding exists.
DereferenceConstant(alias CorrelationIdentifier, constantID string) any
}
ConstantDeref is the optional EvaluationContext capability for dereferencing a ConstantObjectValue. Implementations look up the constant by (alias, constantID) in the planner's per-alias constant map.
Mirrors Java's EvaluationContext.dereferenceConstant.
type ConstantObjectValue ¶
type ConstantObjectValue struct {
Alias CorrelationIdentifier
ConstantID string
ResultType Type
}
ConstantObjectValue is a NAMED reference to a constant captured during planning. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. ConstantObjectValue`.
The constant value itself is stored in an EvaluationContext at execution time, keyed by (alias, constantId). At plan-time the Value carries only the placeholder reference + the bound Type; the actual value is dereferenced when Evaluate runs against an EvaluationContext.
Why a named placeholder instead of a literal: parameter binding, plan-cache reuse, and constant capture during query rewriting all need to defer the actual constant until execution-time. Plan-time rewrites operate on the placeholder; execution dereferences.
Type is whatever the planner determined at capture time — typically nullable to allow NULL constants.
CONFORMANCE NOTE: Java's eval consults EvaluationContext.dereferenceConstant + PromoteValue.isPromotionNeeded for type promotion when the runtime constant's type doesn't match the bound result type. Go's Evaluate matches Java 1:1: dereference the constant, then apply promoteConstant when the runtime type differs from ResultType.
func NewConstantObjectValue ¶
func NewConstantObjectValue(alias CorrelationIdentifier, constantID string, resultType Type) *ConstantObjectValue
NewConstantObjectValue constructs the placeholder.
func (*ConstantObjectValue) Children ¶
func (*ConstantObjectValue) Children() []Value
Children returns the empty slice — leaf.
func (*ConstantObjectValue) Evaluate ¶
func (v *ConstantObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate dereferences the constant via evalCtx's ConstantDeref capability. Returns nil if evalCtx doesn't implement ConstantDeref or if the binding is missing.
Matches Java's ConstantObjectValue.eval: after dereferencing, applies numeric type promotion when the runtime object's type doesn't match the bound ResultType. Relation-typed results are returned as-is (no promotion for structured stream types).
func (*ConstantObjectValue) GetCorrelatedTo ¶
func (v *ConstantObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the singleton set containing the alias — ConstantObjectValue depends on the alias's binding.
func (*ConstantObjectValue) Name ¶
func (*ConstantObjectValue) Name() string
Name returns the debug-print kind.
func (*ConstantObjectValue) Type ¶
func (v *ConstantObjectValue) Type() Type
Type returns the bound result type.
type ConstantValue ¶
ConstantValue is a literal. Evaluate returns Value verbatim.
Typ carries the literal's rich Type. NULL constants (`Value == nil`) keep Typ for the typed-NULL case (e.g. `CAST(NULL AS INT)`); the constructor / call sites set the canonical singleton appropriate for the literal's Go runtime type.
func (*ConstantValue) Children ¶
func (c *ConstantValue) Children() []Value
func (*ConstantValue) Name ¶
func (c *ConstantValue) Name() string
func (*ConstantValue) Type ¶
func (c *ConstantValue) Type() Type
Type returns the constant's rich Type. Nullability is derived from Value: nil Value → nullable (a typed NULL literal); non-nil Value → NOT NULL (the literal carries a concrete value, so by definition can't be NULL). Mirrors Java's `LiteralValue.computeReturnType` shape.
The Typ field's own nullability is overridden — callers shouldn't have to pre-compute the right NotNull / Nullable singleton; the presence/absence of Value is the authoritative signal.
type Correlated ¶
type Correlated interface {
// references. A "leaf" value (ConstantValue) returns an empty
// set. A FieldValue on Quantifier q returns {q}.
GetCorrelatedTo() map[CorrelationIdentifier]struct{}
}
Correlated is the interface Java's `Correlated<T>` maps to. A Correlated value knows which CorrelationIdentifiers it depends on, and can rebind them (used by TranslationMap rewrites). Correlation-bearing Values and Predicates implement it.
type CorrelationBinder ¶
type CorrelationBinder interface {
GetCorrelationBinding(id CorrelationIdentifier) (any, bool)
}
CorrelationBinder is an optional eval-context capability for resolving correlation bindings. When QuantifiedObjectValue.Evaluate is called with a context implementing this interface, it resolves the correlated row. Mirrors Java's EvaluationContext.getBinding(CORRELATION, alias).
type CorrelationIdentifier ¶
type CorrelationIdentifier struct {
// contains filtered or unexported fields
}
CorrelationIdentifier is an opaque alias for a Quantifier — two distinct Quantifiers get distinct IDs. Comparable by value (underlying string) so CorrelationIdentifiers can live in maps.
func NamedCorrelationIdentifier ¶
func NamedCorrelationIdentifier(name string) CorrelationIdentifier
NamedCorrelationIdentifier wraps an explicit name (e.g. a SQL alias). Two NamedCorrelationIdentifiers with the same name are equal — unlike UniqueCorrelationIdentifier which always allocates.
func UniqueCorrelationIdentifier ¶
func UniqueCorrelationIdentifier() CorrelationIdentifier
UniqueCorrelationIdentifier generates a fresh CorrelationIdentifier with a monotonically-increasing suffix. Used when the analyzer needs to allocate a new Quantifier mid-rewrite. Java calls the equivalent `CorrelationIdentifier.uniqueID()`.
Format: "q$1", "q$2", ... — leading 'q' matches Java's convention so explain output diffs cleanly against Java's.
func UniqueUnmatchedID ¶
func UniqueUnmatchedID() CorrelationIdentifier
UniqueUnmatchedID generates a fresh CorrelationIdentifier for a new unmatched aggregate. Mirrors Java's UnmatchedAggregateValue.uniqueId().
func (CorrelationIdentifier) IsZero ¶
func (c CorrelationIdentifier) IsZero() bool
IsZero reports whether c is the zero-value CorrelationIdentifier. Useful for nil-checks without a pointer.
func (CorrelationIdentifier) Name ¶
func (c CorrelationIdentifier) Name() string
Name returns the underlying identifier string.
func (CorrelationIdentifier) String ¶
func (c CorrelationIdentifier) String() string
String implements fmt.Stringer.
type CosineDistanceRowNumberValue ¶
type CosineDistanceRowNumberValue struct {
WindowedValue
}
CosineDistanceRowNumberValue is the cosine-distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by cosine distance from a reference vector. More similar vectors (smaller cosine distance) get lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.CosineDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Cosine distance measures angular difference: 0 = identical direction, 1 = orthogonal, 2 = opposite.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewCosineDistanceRowNumberValue ¶
func NewCosineDistanceRowNumberValue(partitioningValues, argumentValues []Value) *CosineDistanceRowNumberValue
NewCosineDistanceRowNumberValue constructs a cosine-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*CosineDistanceRowNumberValue) Evaluate ¶
func (*CosineDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*CosineDistanceRowNumberValue) IsIndexOnly ¶
func (*CosineDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*CosineDistanceRowNumberValue) Name ¶
func (*CosineDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*CosineDistanceRowNumberValue) Type ¶
func (*CosineDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*CosineDistanceRowNumberValue) WithChildren ¶
func (v *CosineDistanceRowNumberValue) WithChildren(newChildren []Value) *CosineDistanceRowNumberValue
WithChildren returns a fresh CosineDistanceRowNumberValue with children re-split via SplitNewChildren.
type DerivedValue ¶
DerivedValue is a placeholder Value that wraps a list of children without computing a result. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.DerivedValue`.
Used by:
- The planner during plan rewrites that need to track child dependencies but don't yet know how to compute a result.
- Match-candidate compatibility checks that consult the derived-from-which-children property.
DerivedValue is "non-evaluable" — Evaluate panics. Pattern-match against it; don't try to run it at the per-row level.
func NewDerivedValue ¶
func NewDerivedValue(children []Value) *DerivedValue
NewDerivedValue constructs a DerivedValue with UnknownType.
func NewDerivedValueWithType ¶
func NewDerivedValueWithType(children []Value, resultType Type) *DerivedValue
NewDerivedValueWithType constructs a DerivedValue with the given result Type.
func (*DerivedValue) Children ¶
func (v *DerivedValue) Children() []Value
Children returns the wrapped children.
type DistanceOperator ¶
type DistanceOperator int
DistanceOperator enumerates the vector-distance metrics SQL can invoke as scalar functions over vector-typed columns. Mirrors Java's `DistanceValue.DistanceOperator` verbatim — the SQL infix notation matches Java's enum names lowered.
const ( // DistanceEuclidean is sqrt(sum((a_i - b_i)^2)) — L2 distance. DistanceEuclidean DistanceOperator = iota // DistanceEuclideanSquare is sum((a_i - b_i)^2) — squared L2, // avoids the sqrt for speed (same ordering as L2 for KNN). DistanceEuclideanSquare // DistanceCosine is 1 - (a·b)/(|a|·|b|) — angle-based; range [0, 2]. DistanceCosine // DistanceDotProduct is -(a·b) — negated dot product so smaller // values = MORE similar (matches the "distance" convention where // 0 = identical). DistanceDotProduct )
func (DistanceOperator) String ¶
func (op DistanceOperator) String() string
String returns the SQL function name (lowercase per Java's SQL grammar — `euclidean_distance` etc.).
type DistanceRowNumberValue ¶
type DistanceRowNumberValue struct {
WindowedValue
Metric DistanceOperator
EfSearch *int
IsReturningVectors *bool
}
DistanceRowNumberValue is the K-NN search Value: ROW_NUMBER() computed within an HNSW vector index traversal, ORDERED BY a specific distance metric. Mirrors Java's `EuclideanDistanceRowNumberValue` / `EuclideanSquareDistanceRowNumberValue` / `CosineDistanceRowNumberValue` / `DotProductDistanceRowNumberValue` — Java has FOUR concrete classes, one per metric.
The Go port UNIFIES the four into a single concrete type with a `Metric` field discriminator. The Java distinction matters because the K-NN match rule selects on the concrete class type; the Go unified design makes K-NN rules switch on Metric instead (a one-line `if v.Metric == DistanceCosine`-style check). Both expressions are equally matchable; the unified design avoids 4× class-per-metric duplication.
Used by the HNSW K-NN search-rewrite rule: when a query of the form
ROW_NUMBER() OVER (PARTITION BY ... ORDER BY <metric>(field, queryVec)) <= K
is detected, the planner rewrites it into a ScanIndex over the HNSW index with a DistanceRankValueComparison capturing K + queryVec; the resulting plan emits row-numbered candidates from the index's graph traversal directly. This Value is the post-rewrite shape — its eval is INDEX-ONLY (the ROW_NUMBER value is computed during the index search, not from the base record).
Result type: NotNullLong. ROW_NUMBER is always populated, 1-based.
The HNSW config (EfSearch + IsReturningVectors) carries through from the higher-order ROW_NUMBER form — same fields as RowNumberValue's HNSW knobs.
func NewDistanceRowNumberValue ¶
func NewDistanceRowNumberValue(metric DistanceOperator, partitioningValues, argumentValues []Value, efSearch *int, isReturningVectors *bool) *DistanceRowNumberValue
NewDistanceRowNumberValue constructs a metric-specific row-number value. partitioningValues are the OVER PARTITION BY columns; argumentValues typically contain the distance arguments (vector field + query vector) that the ORDER BY references.
func (*DistanceRowNumberValue) Evaluate ¶
func (*DistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (`_row_number` key) — same as base RowNumberValue. Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*DistanceRowNumberValue) IsIndexOnly ¶
func (*DistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — like base RowNumberValue, K-NN row-numbers are computed during HNSW index traversal and can't be reproduced from base record data alone.
func (*DistanceRowNumberValue) Name ¶
func (v *DistanceRowNumberValue) Name() string
Name returns a metric-specific function name matching Java's per-class naming convention:
euclidean_distance_row_number euclidean_square_distance_row_number cosine_distance_row_number dot_product_distance_row_number
func (*DistanceRowNumberValue) Type ¶
func (*DistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated.
func (*DistanceRowNumberValue) WithChildren ¶
func (v *DistanceRowNumberValue) WithChildren(newChildren []Value) *DistanceRowNumberValue
WithChildren returns a fresh DistanceRowNumberValue with split children — partition + argument lists rebuilt via SplitNewChildren, metric + HNSW config carry through unchanged.
type DistanceValue ¶
type DistanceValue struct {
Operator DistanceOperator
LeftChild Value
RightChild Value
}
DistanceValue computes a distance metric between two vector expressions. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.DistanceValue`.
SQL surface:
WHERE euclidean_distance(embedding, queryVec) < 0.5 ORDER BY cosine_distance(vec_field, target) ASC LIMIT 10
Used in similarity-search + nearest-neighbor queries — typically paired with HNSW vector indexes via the K-NN query rewrite that transforms `ROW_NUMBER() OVER (ORDER BY distance(...)) <= K` into a DistanceRankValueComparison + index-backed scan. The distance computation itself is a scalar Value evaluated per-row.
Result type: NotNullDouble. All distance metrics produce a non-NULL real number when both operands are non-NULL vectors.
Eval contract:
- LeftChild + RightChild evaluate to []float64 (vector representation in Go; Java uses RealVector).
- Mismatched-length vectors → eval returns nil (type-degraded).
- NULL vectors → Java throws RecordCoreException; Go returns nil (Go surfaces the error as nil per existing pattern; downstream rules can choose to reject earlier at planner level).
Note: eval is functional for `[]float64` operands — vector type support is gated on broader infrastructure (Type.Vector + binary vector encoding), but the metric math itself works directly on double slices for testability + plan-equivalence with Java.
func NewDistanceValue ¶
func NewDistanceValue(op DistanceOperator, left, right Value) *DistanceValue
NewDistanceValue constructs a distance computation.
func (*DistanceValue) Children ¶
func (v *DistanceValue) Children() []Value
Children returns [left, right].
func (*DistanceValue) Evaluate ¶
func (v *DistanceValue) Evaluate(evalCtx any) (any, error)
Evaluate computes the distance metric. Returns nil when either operand is NULL or when the operands aren't compatible vectors.
func (*DistanceValue) Name ¶
func (v *DistanceValue) Name() string
Name returns the SQL function name for this distance metric.
func (*DistanceValue) Type ¶
func (*DistanceValue) Type() Type
Type returns NotNullDouble — distance metrics produce non-NULL real numbers given non-NULL vector operands.
type DotProductDistanceRowNumberValue ¶
type DotProductDistanceRowNumberValue struct {
WindowedValue
}
DotProductDistanceRowNumberValue is the dot-product-distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by dot product distance from a reference vector. Vectors with larger dot products (more aligned) get lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.DotProductDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Dot product distance is the negative dot product: vectors with higher dot products (more similar) have smaller distances.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewDotProductDistanceRowNumberValue ¶
func NewDotProductDistanceRowNumberValue(partitioningValues, argumentValues []Value) *DotProductDistanceRowNumberValue
NewDotProductDistanceRowNumberValue constructs a dot-product-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*DotProductDistanceRowNumberValue) Evaluate ¶
func (*DotProductDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*DotProductDistanceRowNumberValue) IsIndexOnly ¶
func (*DotProductDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*DotProductDistanceRowNumberValue) Name ¶
func (*DotProductDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*DotProductDistanceRowNumberValue) Type ¶
func (*DotProductDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*DotProductDistanceRowNumberValue) WithChildren ¶
func (v *DotProductDistanceRowNumberValue) WithChildren(newChildren []Value) *DotProductDistanceRowNumberValue
WithChildren returns a fresh DotProductDistanceRowNumberValue with children re-split via SplitNewChildren.
type EmptyValue ¶
type EmptyValue struct{}
EmptyValue represents an empty record (zero fields). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.EmptyValue`.
Used by:
- Default value for COUNT(*) over an empty set (returns 0; the empty record is the unit element for COUNT).
- Insert/Update/Delete operations that don't return a row but need a Value-shaped placeholder for the planner.
- Any rewrite that produces a "no-op" Value tree.
Type is the empty RecordType (no fields, non-null).
Evaluate returns nil (no fields → nothing to evaluate).
func NewEmptyValue ¶
func NewEmptyValue() *EmptyValue
NewEmptyValue returns the canonical EmptyValue. Callers can use this or the package-level `Empty` singleton interchangeably.
func (*EmptyValue) Children ¶
func (*EmptyValue) Children() []Value
Children returns the empty slice — leaf.
type EnumType ¶
type EnumType struct {
// EnumName is the enum's type identifier — empty string for
// anonymous enums (rare in real schemas but legal).
EnumName string
// Nullable reports whether the enum column allows NULL.
Nullable bool
// Values are the declared enum members in declared order.
Values []EnumValue
}
EnumType is the Type impl for SQL ENUM columns. Mirrors Java's Enum nested type. Carries an EnumName (the enum's type identifier) plus an ordered list of EnumValues.
Two EnumType instances are Equal iff their EnumName + Nullable match AND their Values slice is element-wise equal.
func NewEnumType ¶
NewEnumType constructs an EnumType. The Values slice is defensively copied. Panics on duplicate Name OR duplicate Number within Values — both are schema-level errors per Java + protobuf.
func (*EnumType) LookupValueByName ¶
LookupValueByName returns the enum value matching name plus a found flag. Empty string returns (zero, false).
func (*EnumType) LookupValueByNumber ¶
LookupValueByNumber returns the enum value matching number plus a found flag.
type EnumValue ¶
type EnumValue struct {
// Name is the enum member's identifier.
Name string
// Number is the declared ordinal (matches protobuf semantics —
// stable across schema evolution; renames are forbidden but
// repurposing a number is a hard breaking change).
Number int32
}
EnumValue is one member of an EnumType. Mirrors Java's Enum.EnumValue — a Name + Number pair where the Number is the declared ordinal (matches the protobuf enum-value semantics).
type EuclideanDistanceRowNumberValue ¶
type EuclideanDistanceRowNumberValue struct {
WindowedValue
}
EuclideanDistanceRowNumberValue is the Euclidean-distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by Euclidean distance from a reference vector. Closer vectors receive lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.EuclideanDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Euclidean distance is sqrt(sum((a_i - b_i)^2)) — the standard L2 distance.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewEuclideanDistanceRowNumberValue ¶
func NewEuclideanDistanceRowNumberValue(partitioningValues, argumentValues []Value) *EuclideanDistanceRowNumberValue
NewEuclideanDistanceRowNumberValue constructs a Euclidean-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*EuclideanDistanceRowNumberValue) Evaluate ¶
func (*EuclideanDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*EuclideanDistanceRowNumberValue) IsIndexOnly ¶
func (*EuclideanDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*EuclideanDistanceRowNumberValue) Name ¶
func (*EuclideanDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*EuclideanDistanceRowNumberValue) Type ¶
func (*EuclideanDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*EuclideanDistanceRowNumberValue) WithChildren ¶
func (v *EuclideanDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanDistanceRowNumberValue
WithChildren returns a fresh EuclideanDistanceRowNumberValue with children re-split via SplitNewChildren.
type EuclideanSquareDistanceRowNumberValue ¶
type EuclideanSquareDistanceRowNumberValue struct {
WindowedValue
}
EuclideanSquareDistanceRowNumberValue is the squared-Euclidean- distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by squared Euclidean distance from a reference vector. Closer vectors receive lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.EuclideanSquareDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Squared Euclidean distance is sum((a_i - b_i)^2) — same ordering as L2 without the sqrt cost, making it computationally cheaper for nearest-neighbor searches where only relative ordering matters.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewEuclideanSquareDistanceRowNumberValue ¶
func NewEuclideanSquareDistanceRowNumberValue(partitioningValues, argumentValues []Value) *EuclideanSquareDistanceRowNumberValue
NewEuclideanSquareDistanceRowNumberValue constructs a squared- Euclidean-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*EuclideanSquareDistanceRowNumberValue) Evaluate ¶
func (*EuclideanSquareDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*EuclideanSquareDistanceRowNumberValue) IsIndexOnly ¶
func (*EuclideanSquareDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*EuclideanSquareDistanceRowNumberValue) Name ¶
func (*EuclideanSquareDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*EuclideanSquareDistanceRowNumberValue) Type ¶
func (*EuclideanSquareDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*EuclideanSquareDistanceRowNumberValue) WithChildren ¶
func (v *EuclideanSquareDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanSquareDistanceRowNumberValue
WithChildren returns a fresh EuclideanSquareDistanceRowNumberValue with children re-split via SplitNewChildren.
type EvaluatesTo ¶
type EvaluatesTo int
EvaluatesTo discriminates the four supported evaluations.
const ( // EvaluatesToTrue is `x IS TRUE`. EvaluatesToTrue EvaluatesTo = iota // EvaluatesToFalse is `x IS FALSE`. EvaluatesToFalse // EvaluatesToNull is `x IS NULL`. EvaluatesToNull // EvaluatesToNotNull is `x IS NOT NULL`. EvaluatesToNotNull )
type EvaluatesToValue ¶
type EvaluatesToValue struct {
Child Value
Eval EvaluatesTo
}
EvaluatesToValue tests whether a child Value's runtime evaluation matches one of four boolean-shaped predicates: IS TRUE, IS FALSE, IS NULL, IS NOT NULL. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. EvaluatesToValue`.
x IS TRUE ↔ EvaluatesToValue{Child: x, Eval: EvaluatesToTrue}
x IS NULL ↔ EvaluatesToValue{Child: x, Eval: EvaluatesToNull}
Used by:
- SQL `IS [NOT] {NULL,TRUE,FALSE}` predicates lowered to the Value layer.
- Plan rewrites that need to pattern-match on these specific truth-value shapes.
Type is always non-null boolean (these predicates have a defined result for any operand — even NULL maps to TRUE/FALSE).
func NewEvaluatesToValue ¶
func NewEvaluatesToValue(child Value, eval EvaluatesTo) *EvaluatesToValue
NewEvaluatesToValue constructs the predicate Value.
func (*EvaluatesToValue) Children ¶
func (v *EvaluatesToValue) Children() []Value
Children returns the single child.
func (*EvaluatesToValue) Evaluate ¶
func (v *EvaluatesToValue) Evaluate(evalCtx any) (any, error)
Evaluate computes the predicate.
Rules:
- x IS TRUE: true iff x evaluates to bool true; false otherwise.
- x IS FALSE: true iff x evaluates to bool false; false otherwise.
- x IS NULL: true iff x evaluates to nil; false otherwise.
- x IS NOT NULL: true iff x evaluates to non-nil; false otherwise.
Type mismatches (non-bool x with IS TRUE / IS FALSE) return false — the runtime value isn't a boolean true / false, so the predicate is false (not UNKNOWN).
func (*EvaluatesToValue) Name ¶
func (*EvaluatesToValue) Name() string
Name returns the debug-print kind.
func (*EvaluatesToValue) Type ¶
func (*EvaluatesToValue) Type() Type
Type returns NotNullBoolean — these predicates always return a definite truth value (UNKNOWN propagation is handled by the IS [NOT] {NULL,TRUE,FALSE} semantics).
type ExistsValue ¶
type ExistsValue struct {
// Value is the child Value — a *QuantifiedObjectValue over the
// existential quantifier's object. The correlation is carried by
// this child, NOT by ExistsValue itself.
Value Value
}
ExistsValue is the Value-layer SQL `EXISTS` operator: yields TRUE if a subquery's row stream is non-empty. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ExistsValue` (4.12 `c9274172c`), which refactored it from a non-evaluable leaf quantifier wrapper into a proper EVALUABLE ValueWithChild.
EXISTS (SELECT ... FROM t WHERE ...)
↔ ExistsValue{Value: QuantifiedObjectValue{Correlation: αsubq}}
The child is a *QuantifiedObjectValue over the subquery's existential quantifier. EXISTS is true iff that quantifier's object (the current row of the subplan) is non-null — i.e. the subplan yielded at least one row (Java's `getChild().eval() != null`).
There is ONE EXISTS representation (RFC-141): WHERE-EXISTS is this value funnelled through ToQueryPredicate() → ExistentialValuePredicate; a projected EXISTS uses the value directly as a column. The standalone alias-leaf ExistsPredicate was deleted.
Type is non-null boolean (EXISTS always has a definite truth value — even on empty subqueries it returns FALSE).
func NewExistsValue ¶
func NewExistsValue(alias CorrelationIdentifier) *ExistsValue
NewExistsValue constructs the Value over the existential alias. The signature is preserved so callers that pass an alias don't change: it wraps the alias in a QuantifiedObjectValue child.
func NewExistsValueWithChild ¶
func NewExistsValueWithChild(v Value) *ExistsValue
NewExistsValueWithChild constructs the Value over an explicit child (a *QuantifiedObjectValue). Mirrors Java's `new ExistsValue(value)`.
func (*ExistsValue) Children ¶
func (v *ExistsValue) Children() []Value
Children returns the singleton list containing the child Value — ExistsValue is now a transparent composite, so all alias-aware walks (correlation, rebase, hash, equals) descend into the child QuantifiedObjectValue, which carries the correlation.
func (*ExistsValue) Evaluate ¶
func (v *ExistsValue) Evaluate(ctx any) (any, error)
Evaluate returns whether the child quantifier's object is non-null — i.e. the subplan yielded at least one row. Java: `getChild().eval(store, context) != null`.
func (*ExistsValue) GetChild ¶
func (v *ExistsValue) GetChild() Value
GetChild returns the child Value (the existential QuantifiedObjectValue). Mirrors Java's ValueWithChild.getChild().
func (*ExistsValue) GetCorrelatedTo ¶
func (v *ExistsValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo delegates to the child — the correlation is carried by the child QuantifiedObjectValue, not by ExistsValue.
func (*ExistsValue) Type ¶
func (*ExistsValue) Type() Type
Type returns NotNullBoolean — EXISTS always has a definite truth value.
func (*ExistsValue) WithNewChild ¶
func (v *ExistsValue) WithNewChild(c Value) *ExistsValue
WithNewChild returns a copy of this ExistsValue over a rebased/translated child. Mirrors Java's ValueWithChild.withNewChild().
type ExpressionFolder ¶
ExpressionFolder is the testable surface for plan-time constant folding of standalone Values. Implementations: DefaultFolder (production — composes SimplifyValue with EvaluateConstant), and any caller-provided test fake that returns canned answers without invoking real simplification.
Why an interface, not a free function: callers like `embedded.foldConstantProjections` need to be unit-testable without constructing a real catalog + Resolver + metadata. With an injected folder, the routing logic ("did we already fold this slot? is the slice big enough?") can be exercised against a fake folder that returns whatever the test wants. Per RFC-025 §"Closing the leaks".
Contract: Fold returns (foldedValue, true) when v is a row-context- independent Value whose evaluation produces a Go-native scalar that LiteralValue can faithfully re-wrap. Returns (nil, false) on a non-foldable input — a FieldValue, a ParameterValue, an AggregateValue, or any composite containing those. Nil v returns (nil, false) — the boundary so callers don't need to nil-guard.
func DefaultFolder ¶
func DefaultFolder() ExpressionFolder
DefaultFolder returns the production ExpressionFolder. Its Fold runs SimplifyValue first (so partial folds compose: `name + (1+2)` simplifies to `name + 3` even though the result isn't constant) and then EvaluateConstant for the all-constant case. Failure modes surface as ok=false, never panic.
type Field ¶
type Field struct {
// Name is the field's identifier. Empty string is legal and
// represents an anonymous field — `RECORD<INT, STRING>` produces
// fields with Name="" but distinct Ordinals.
Name string
// FieldType is the field's type. Never nil — anonymous /
// untyped fields use UnknownType.
FieldType Type
// Ordinal is the field's position in the record (0-based). It is the
// Java *ordinal* (Type.Record.computeFieldNameToOrdinal = list position),
// NOT the protobuf fieldIndex/tag. NewRecordType normalizes Ordinal to the
// slice position, so Fields[i].Ordinal == i; ordinal resolution reads the
// slice position directly (RecordType.FieldIndex) for soundness even on a
// raw RecordType. Anonymous fields share Name="" but have distinct Ordinals.
Ordinal int
}
Field is one field of a RecordType. Mirrors Java's Record.Field — name + type + ordinal. The Ordinal carries the declared position for stable ordering across maps; two Fields with the same Name but different Ordinals are NOT equal.
type FieldPath ¶
type FieldPath struct {
Accessors []ResolvedAccessor
// FrontierPinned carries the S2 gated-join FRONTIER CONTRACT: the node was
// baked at a gated-join seed whose executor births positional rows, so a
// name-keyed read is a planner/executor bug (loud *BakedNameContextError,
// bakedNameReadGuard). Unpinned baked nodes (the recursive-CTE wrap) have
// no such guarantee and keep the quiet name-model read off the positional
// frontier. The contract is a property of the VALUE, invariant under
// transformation — pullup/pushdown passthrough copies strip Child but
// share this pointer, so keying the guard on child presence would let a
// semantics-preserving rewrite silently demote a loud node (unification
// review ruling). Lives ON THE PATH, once, not per-accessor: the contract
// governs the ROOT read context; accessors beyond the first read nested
// records, where the bit is meaningless (S3 staging ruling — N copies of
// a one-meaning bit desynchronize). EXCLUDED from identity/hash/Explain:
// an evaluation-contract marker, not a value distinction. Dies in Slice 4
// with the guard and the name model.
FrontierPinned bool
}
FieldPath is the RFC-173 S3 multi-accessor path — Java's FieldValue.FieldPath (FieldValue.java:373): ONE FieldValue node holds a whole path, never chained nodes. IMMUTABLE after construction (replace-never-mutate, the S2 accessor convention carried over): FieldValue copy sites share the pointer; WithSuffix returns a NEW path (Java :525-534). In the S2-compatible window every production path is single-accessor (the gated-join seed and the recursive-CTE wrap); multi-accessor paths are produced only by the baked-gated compose rule until the S3-W2/W3 flip widens it. INVARIANT: a FieldPath carried by a FieldValue is NON-EMPTY — a zero-step path reads nothing and is not a meaningful accessor (Java's FieldPath.EMPTY exists only for prefix arithmetic Go doesn't port in W1). Both constructors (NewFieldPathOfSingle, WithSuffix) uphold it; Root()/Last() panic on a hand-built violation rather than tolerating it.
func NewFieldPathOfSingle ¶
NewFieldPathOfSingle is Java's FieldPath.ofSingle (FieldValue.java:563) — the constructor every S2-era single-accessor bake goes through.
func (*FieldPath) Equals ¶
Equals is Java FieldPath.equals (FieldValue.java:411-420): element-wise list equality over the accessors' ORDINALS (the S3-W3 flip landed Java's ResolvedAccessor.equals = getOrdinal()-only, :675-689). The per-step Field is NOT compared — display/rendering, not identity. FrontierPinned is likewise excluded (evaluation contract, not identity).
func (*FieldPath) Last ¶
func (p *FieldPath) Last() ResolvedAccessor
Last returns the final accessor — the path's display leaf (Java getLastFieldAccessor, FieldValue.java:459).
func (*FieldPath) Root ¶
func (p *FieldPath) Root() ResolvedAccessor
Root returns the first accessor — the one the ROOT read context resolves (positional row slot / name-keyed Datum key).
func (*FieldPath) Single ¶
func (p *FieldPath) Single() (ResolvedAccessor, bool)
Single returns the path's only accessor when the path is single-step — the S2-era shape every join-seed probe expects; ok=false for multi-accessor paths (probes DECLINE those shapes until S3-W2 makes them real).
func (*FieldPath) WithSuffix ¶
WithSuffix returns a NEW path with suffix's accessors appended — Java's FieldPath.withSuffix (FieldValue.java:525-534); neither input is mutated. The frontier pin comes from the RECEIVER: fusing inner.WithSuffix(outer) keeps the INNER path's root read context (the compose rule's shape), and the pin governs exactly that root.
type FieldValue ¶
type FieldValue struct {
Field string
Typ Type
Child Value // base value (nil = legacy flat field reference)
// Resolved is the RFC-173 baked-ordinal marker — Java's construction-time
// FieldPath resolution, where the accessor IS an ordinal and runtime access
// is positional. nil = LAZY node (today's model: the column position is
// re-derived from the child's flowed type on every resolveOrdinal). Non-nil
// = BAKED node: resolveOrdinal returns the accessor's ordinal directly, so
// a positional-row read is row.Get(ordinal) — position-preserving by
// construction, and therefore sound under DUPLICATE output names, which
// every name-based resolution collapses (RecordType.FieldIndex is
// first-match; the name-keyed Datum is last-wins). Field is then a DISPLAY
// name for diagnostics and name-model coexistence.
//
// Two construction shapes during the coexistence window:
// - NewFieldValueOfOrdinal (gated-join seeds): child-bearing over a typed
// leg QOV, FrontierPinned — the executor guarantees positional rows, so
// a name-keyed read is a loud *BakedNameContextError.
// - NewFieldValueWithResolvedOrdinal (recursive-CTE leg wrap): childless,
// unpinned — no frontier guarantee; off the positional frontier Field
// names the Datum read key, so one Value works under both row models.
// Both are SINGLE-accessor paths; multi-accessor paths exist only via the
// baked-gated compose rule (S3-W1, dark) until the S3-W2/W3 flip.
//
// Identity refinement (contract, RFC-173 §4 Slice 2 ruling #2, widened
// element-wise by the S3 staging ruling): BAKED nodes compare by
// per-element (Field, Ordinal) list equality (FieldPath.Equals); baked vs
// lazy is UNEQUAL (worst case a missed dedup, never a conflation); lazy vs
// lazy stays name-only. FrontierPinned is EXCLUDED from
// identity/hash/Explain (an evaluation-contract marker, not a value
// distinction — like Java excluding name/type from ResolvedAccessor
// equality). Every FieldValue copy/rebuild site MUST preserve this marker —
// dropping it silently degrades a baked node to lazy, which conflates
// duplicate same-named columns at different ordinals (§5 duplicate-name
// pin). For baked nodes Field equals the LAST accessor's name (Java
// getLastFieldName) — display and name-model coexistence only.
Resolved *FieldPath
}
FieldValue references a column by name on a base value. In the full Java model, FieldValue always has a child value (typically a QuantifiedObjectValue correlated to a quantifier) and a FieldPath (multi-step for nested access). In Go, Child is optional for backward compatibility: nil Child = leaf field reference (flat model used by existing code).
With Child set, FieldValue participates in correlation tracking: GetCorrelatedToOfValue walks into Children() and discovers the child's correlation. This is essential for push-through rules that need to know whether a value is correlated to a specific quantifier.
Field-name contract: callers constructing FieldValue via the SQL resolver (expr.ResolveIdentifier) receive the case-folded (upper- case) form, matching Identifier.Name(). Downstream row producers MUST normalise their map keys to the same form.
func NewFieldValue ¶
func NewFieldValue(child Value, field string, typ Type) *FieldValue
NewFieldValue constructs a FieldValue with a child (base) value. Mirrors Java's FieldValue(childValue, FieldPath).
func NewFieldValueOfOrdinal ¶
func NewFieldValueOfOrdinal(child Value, ordinal int) (*FieldValue, error)
NewFieldValueOfOrdinal constructs a BAKED FieldValue accessing the child's record field by ORDINAL position — Java's `FieldValue.ofOrdinalNumber(childValue, ordinalNumber)` (FieldValue.java:335): the position is resolved ONCE, here, and carried on the node (Resolved); resolveOrdinal returns it without re-deriving from the child type. The DISPLAY name (Field) and Typ are read from the child's RecordType at `ordinal` — the name serves diagnostics and name-model coexistence (Datum keys, explain); the ordinal is authoritative (it survives even when a runtime row's type names disagree with the display name).
NOT the same as NewOrdinalFieldValue (above): that is the LEGACY lazy `_<ordinal>` NAME-emulation (ordinal access spelled as name access on the OrdinalFieldName key, used by the lateral-unnest lowering) — it resolves by name at runtime and carries no baked marker. This constructor is the RFC-173 Slice 2 eager path; the `_N` emulation dies with the name machinery in Slice 4.
Errors loudly (Java raises; no silent fallback) when the child does not flow a *RecordType or the ordinal is out of range.
func NewFieldValueWithResolvedOrdinal ¶
func NewFieldValueWithResolvedOrdinal(field string, ordinal int, typ Type) *FieldValue
NewFieldValueWithResolvedOrdinal constructs a flat FieldValue carrying a plan-time-resolved ordinal accessor — Java's FieldValue.ofOrdinalNumber. On an ordinal-frontier row the read is row.Get(ordinal) (positional by construction, duplicate-name-proof); on a name-keyed row it reads by field name exactly like NewFlatFieldValue — the accessor is UNPINNED (no join-frontier contract; the caller — the recursive-CTE leg wrap — has legs that legitimately flow name-keyed rows until S3/S4 flips joins positional). Distinct from NewOrdinalFieldValue, which is a NAME encoding (`_<ordinal>` Datum key) for anonymous WITH-ORDINALITY fields, not positional access.
func NewFlatFieldValue ¶
func NewFlatFieldValue(field string, typ Type) *FieldValue
NewFlatFieldValue constructs a FieldValue without a child (legacy flat model).
func NewOrdinalFieldValue ¶
func NewOrdinalFieldValue(child Value, ordinal int, typ Type) *FieldValue
NewOrdinalFieldValue accesses a record field by ORDINAL position, mirroring Java's `FieldValue.ofOrdinalNumber(child, ordinal)`. Go's runtime Datum is a name-keyed map, and anonymous record fields (the element/ordinal of a WITH ORDINALITY Explode) are keyed by their ordinal name `_0`/`_1` (see OrdinalFieldName) — so ordinal access is name access on the `_<ordinal>` key. Used by the lateral-unnest lowering to bind the AS alias to field 0 (element) and the AT alias to field 1 (the INT NOT NULL ordinal).
func (*FieldValue) Children ¶
func (f *FieldValue) Children() []Value
func (*FieldValue) Name ¶
func (f *FieldValue) Name() string
func (*FieldValue) Type ¶
func (f *FieldValue) Type() Type
Type returns the field's rich Type. FieldValue stores the column type as-is; callers that know NOT NULL information from the catalog set Typ to the non-nullable form.
type FirstOrDefaultStreamingValue ¶
FirstOrDefaultStreamingValue is the streaming variant of FirstOrDefaultValue. Returns the first element produced by its streaming child Value, or the default Value if the stream is empty. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.FirstOrDefaultStreamingValue`.
The child should implement StreamingValue. RangeValue returns []int64 (not []any), so it doesn't satisfy StreamingValue and is handled by an explicit type-switch fallback in Evaluate.
func NewFirstOrDefaultStreamingValue ¶
func NewFirstOrDefaultStreamingValue(childValue, onEmpty Value) *FirstOrDefaultStreamingValue
NewFirstOrDefaultStreamingValue constructs the streaming first- or-default. The childValue should implement StreamingValue or be a *RangeValue (adapted internally).
func (*FirstOrDefaultStreamingValue) Children ¶
func (v *FirstOrDefaultStreamingValue) Children() []Value
Children returns [childValue, onEmptyResultValue].
func (*FirstOrDefaultStreamingValue) Evaluate ¶
func (v *FirstOrDefaultStreamingValue) Evaluate(evalCtx any) (any, error)
Evaluate pulls the first element from the streaming child, or returns the default value if the stream is empty.
func (*FirstOrDefaultStreamingValue) Name ¶
func (*FirstOrDefaultStreamingValue) Name() string
Name returns the SQL function name (matches FirstOrDefaultValue).
func (*FirstOrDefaultStreamingValue) Type ¶
func (v *FirstOrDefaultStreamingValue) Type() Type
Type returns the child's type. The stream element type IS the result type (we pull one element, fall back to default which must be type-compatible).
func (*FirstOrDefaultStreamingValue) WithChildren ¶
func (v *FirstOrDefaultStreamingValue) WithChildren(newChildren []Value) *FirstOrDefaultStreamingValue
WithChildren returns a fresh FirstOrDefaultStreamingValue with the given children. Caller passes exactly 2 children (childValue, onEmptyResultValue).
type FirstOrDefaultValue ¶
type FirstOrDefaultValue struct {
Array Value
Default Value
// Typ is the result type — Java's constructor sets it to the
// array element type. Defaults to UnknownType.
Typ Type
}
FirstOrDefaultValue returns the first element of an array, OR a default value if the array is empty / NULL. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. FirstOrDefaultValue`.
FIRST_OR_DEFAULT(arr, default)
↔ FirstOrDefaultValue{Array: arr, Default: default}
Used by the planner for materializing scalar subquery results where the subquery may return zero rows.
CONFORMANCE: matches Java's eval semantics:
- NULL array → NULL (the default isn't returned for NULL).
- Empty array → Default's evaluated value.
- Non-empty array → first element.
Type is the array's element type (Java's constructor enforces the array.elementType == default.type invariant; Go accepts whatever type the caller provides).
func NewFirstOrDefaultValue ¶
func NewFirstOrDefaultValue(array, defaultVal Value, resultType Type) *FirstOrDefaultValue
NewFirstOrDefaultValue constructs the operator.
func (*FirstOrDefaultValue) Children ¶
func (v *FirstOrDefaultValue) Children() []Value
Children returns [Array, Default].
func (*FirstOrDefaultValue) Evaluate ¶
func (v *FirstOrDefaultValue) Evaluate(evalCtx any) (any, error)
Evaluate returns Array[0] OR Default.Evaluate when Array is empty.
Returns nil if:
- Array is nil-Value or evaluates to nil.
- Array doesn't evaluate to a slice.
func (*FirstOrDefaultValue) Name ¶
func (*FirstOrDefaultValue) Name() string
Name returns the debug-print kind.
func (*FirstOrDefaultValue) Type ¶
func (v *FirstOrDefaultValue) Type() Type
Type returns the bound result type.
type FromOrderedBytesValue ¶
type FromOrderedBytesValue struct {
Child Value
Direction OrderedBytesDirection
TargetType Type
}
FromOrderedBytesValue decodes an ordered-bytes blob (the output of ToOrderedBytesValue) back to the original typed value. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.FromOrderedBytesValue`.
The decoder needs the encoded direction (so it knows whether to undo the DESC inversion) and the target type (so it knows what Tuple element type to extract). Java's class carries both fields.
As the inverse of ToOrderedBytesValue, this Value typically appears in covering-index / index-only access plans where the planner has rewritten a SQL projection to read the encoded form from an index entry.
func NewFromOrderedBytesValue ¶
func NewFromOrderedBytesValue(child Value, direction OrderedBytesDirection, targetType Type) *FromOrderedBytesValue
NewFromOrderedBytesValue constructs the decoder.
func (*FromOrderedBytesValue) Children ¶
func (v *FromOrderedBytesValue) Children() []Value
Children returns the single child Value.
func (*FromOrderedBytesValue) Evaluate ¶
func (*FromOrderedBytesValue) Evaluate(any) (any, error)
Evaluate is currently a placeholder — returns nil. Real eval wires tuple.UnpackOrdered (the Go equivalent of Java's TupleOrdering.unpack). Same gating as ToOrderedBytesValue.
func (*FromOrderedBytesValue) Name ¶
func (*FromOrderedBytesValue) Name() string
Name returns the SQL function name.
func (*FromOrderedBytesValue) Type ¶
func (v *FromOrderedBytesValue) Type() Type
Type returns the target type — the decoded value's natural type. Note: Java's getResultType() returns the target type made nullable, since decoding may produce NULL for the NULL-sentinel byte sequence. Go mirrors that — wraps target in nullable.
type InOpValue ¶
InOpValue is the Value-layer SQL `IN` operator: tests whether a probe value matches any element of a list of candidate values. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades. values.InOpValue`.
probe IN (a, b, c) ↔ InOpValue{Probe: probe, List: [a, b, c]}
Why a Value-layer IN in addition to the predicate-layer `ComparisonPredicate{Type: ComparisonIn}`: rules that operate at the Value tree (e.g. fold a constant probe against a constant list) need a Value-shaped node. The predicate-side path is reserved for evaluation; the Value-side path is for plan rewrites.
Java's InOpValue carries an `inListValue` Value (typically LiteralValue wrapping a list, or a ListValue node), making it possible to express IN against dynamic lists. Go accepts a generic List Value field that can be a literal []any (for static IN-lists) or any other Value that evaluates to a slice at runtime.
Evaluate semantics — Kleene 3VL:
- probe IN (NULL, ...) where probe is non-NULL: TRUE if any non-NULL element matches, otherwise UNKNOWN (NULL propagation).
- NULL IN (anything): UNKNOWN.
- Empty list: FALSE (no match possible).
Type is always nullable boolean — IN can produce NULL via Kleene propagation.
func NewInOpValue ¶
NewInOpValue constructs an InOpValue.
Either Probe or List nil produces a Value that always evaluates to nil (UNKNOWN). Defensive — callers should construct with both operands set.
func (*InOpValue) Children ¶
Children returns probe + list. Lets WalkValue traverse both operands as a standard 2-child Value.
func (*InOpValue) Evaluate ¶
Evaluate computes probe IN list with SQL three-valued semantics.
Returns:
- true if probe matches any non-NULL element of the list.
- false if probe doesn't match any list element AND the list contains no NULLs.
- nil (UNKNOWN) if probe is NULL, OR probe doesn't match a non- NULL element AND the list contains a NULL (NULL propagation).
- nil if probe or list is nil-Value, or list doesn't evaluate to a slice.
equalsAny performs numeric coercion for mixed int/float comparisons, matching Java's Comparisons.evalComparison(EQUALS).
type IncarnationValue ¶
type IncarnationValue struct{}
IncarnationValue is a LEAF Value that returns the record store's incarnation number — an integer counter the store advances whenever its versionstamp prefix is "fresh" (e.g. after a tenant move / re-key). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IncarnationValue`.
SQL-callable as `get_versionstamp_incarnation()`. The underlying purpose is to let queries detect store-incarnation changes when processing versionstamp-keyed data — two versionstamps from different incarnations are not directly comparable, so a query that joins / dedups across versionstamp boundaries uses this to scope correctness.
Result type: INT (NOT NULL — every store has an incarnation).
Per Java's contract, eval requires a non-null FDBRecordStoreBase; Go accepts an evalCtx that exposes an "incarnation" key (the row-shape harness pattern shared with VersionValue), and otherwise returns nil. FDBRecordStore.GetIncarnation() exists on the store side, but no execution path threads a store into this Value's Evaluate — it is parser / planner / fuzz-reachable without a store-bound runtime evaluator, matching the non-evaluable placeholder pattern of ObjectValue / QueriedValue / CardinalityValue.
func NewIncarnationValue ¶
func NewIncarnationValue() *IncarnationValue
NewIncarnationValue constructs the singleton-shape leaf.
IncarnationValue carries no per-instance state; every constructed instance is semantically equal. Returning a freshly allocated pointer (rather than a package-level singleton) preserves the per-call allocation contract used throughout the cascades package — callers that compare via pointer-identity won't be confused by interned reuse.
func (*IncarnationValue) Children ¶
func (*IncarnationValue) Children() []Value
Children returns the empty slice — leaf, no operands.
func (*IncarnationValue) Evaluate ¶
func (*IncarnationValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the incarnation from the evalCtx if present. Mirrors VersionValue's row-shape harness pattern: when evalCtx is a `map[string]any` the evaluator looks up the "incarnation" key.
Returns nil if:
- evalCtx is nil.
- evalCtx is not a row-shape map.
- The map has no "incarnation" key.
Real store-bound evaluation lands when execution integration surfaces FDBRecordStore.GetIncarnation() through the eval context.
func (*IncarnationValue) Name ¶
func (*IncarnationValue) Name() string
Name returns the debug-print kind, matching Java's `get_versionstamp_incarnation` SQL function name.
func (*IncarnationValue) Type ¶
func (*IncarnationValue) Type() Type
Type returns NotNullInt — every record store has a non-null incarnation (zero is a valid initial value, not absence).
type IndexEntryObjectValue ¶
type IndexEntryObjectValue struct {
IndexEntryAlias CorrelationIdentifier
Source TupleSource
OrdinalPath []int
ResultType Type
}
IndexEntryObjectValue is a LEAF Value that references a specific position inside an IndexEntry's KEY or VALUE tuple, identified by an ordinal path (the Java-side "Dewey id"). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IndexEntryObjectValue`.
Used by covering-index plans + index-only access paths: when a query can be answered directly from the index entry's key/value tuples (without fetching the underlying record), this Value extracts a specific column from those tuples by ordinal walk.
Conceptually:
IndexEntryObjectValue(alias, KEY, [0]) — first KEY column
IndexEntryObjectValue(alias, KEY, [2]) — third KEY column
IndexEntryObjectValue(alias, VALUE, [0, 1]) — second sub-field
of first VALUE column
The alias identifies WHICH index-entry binding to read in the EvaluationContext (a query may join several indexed scans, each flowing its own IndexEntry).
Constraints (matches Java's Verify.verify in the constructor):
- resultType must be primitive, enum, or UUID — IndexEntry tuples can only hold leaf-type Tuple-encodable values; structs are extracted via separate FieldValue chains, not through ordinal paths.
- Go enforces this via planner-checked precondition rather than a runtime panic — Java's Verify would crash; we surface as a no-op-ready Value that evaluates to nil if the type contract is violated.
Eval contract:
- evalCtx must be a `map[CorrelationIdentifier]any` shape with a binding for `IndexEntryAlias`. The bound value is expected to expose `PrimaryKey() / IndexValues()` (the `*recordlayer.IndexEntry` shape) — typed as `IndexEntryReader` here to keep the values package free of the recordlayer dependency.
- On lookup miss, returns nil (matches the "non-evaluable yet" pattern of placeholder Values like ObjectValue / VersionValue).
func NewIndexEntryObjectValue ¶
func NewIndexEntryObjectValue(alias CorrelationIdentifier, source TupleSource, ordinalPath []int, resultType Type) *IndexEntryObjectValue
NewIndexEntryObjectValue constructs the leaf. Caller is responsible for the resultType-primitive-or-enum-or-UUID precondition; the constructor doesn't enforce because the Type-classification helpers (IsPrimitive / IsEnum / etc.) live alongside the planner pipeline and Go defers the check to caller (matches Java's Verify.verify-vs-runtime split).
func (*IndexEntryObjectValue) Children ¶
func (*IndexEntryObjectValue) Children() []Value
Children returns the empty slice — leaf, no operands.
func (*IndexEntryObjectValue) Evaluate ¶
func (v *IndexEntryObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate walks the ordinal path through the bound IndexEntry's KEY or VALUE tuple. Returns nil if:
- evalCtx is nil.
- evalCtx is not a `map[CorrelationIdentifier]any`.
- The map has no binding for IndexEntryAlias.
- The bound value isn't an IndexEntryReader.
- The ordinal walk runs off the end of the tuple.
func (*IndexEntryObjectValue) GetCorrelatedTo ¶
func (*IndexEntryObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the empty set — IndexEntryObjectValue matches Java's getCorrelatedToWithoutChildren contract which returns Set.of() (it deliberately doesn't surface the entry alias as a correlation, because the alias is a "binding-side" reference, not a dataflow correlation).
func (*IndexEntryObjectValue) Name ¶
func (*IndexEntryObjectValue) Name() string
Name returns the debug-print kind.
func (*IndexEntryObjectValue) Type ¶
func (v *IndexEntryObjectValue) Type() Type
Type returns the bound result type.
type IndexEntryReader ¶
type IndexEntryReader interface {
// PrimaryKey returns the KEY tuple of the index entry — the
// indexed-column tuple plus the trailing primary-key columns.
PrimaryKey() any
// IndexValues returns the VALUE tuple of the index entry — the
// payload tuple (typically empty for VALUE indexes; populated
// for KeyWithValue covering-index entries).
IndexValues() any
}
IndexEntryReader is the minimal interface IndexEntryObjectValue needs to walk an FDB index entry. The Go *recordlayer.IndexEntry type satisfies this contract via its PrimaryKey + IndexValues methods. Defined here (rather than imported from recordlayer) to keep the cycle-free dependency direction values → ø.
type IndexOnly ¶
IndexOnly is the Go-side counterpart to Java's `Value.IndexOnlyValue` interface marker. Any Value whose result can ONLY be produced by an index scan (vs a streaming aggregator over the base records) implements this marker.
Used by: RowNumberValue, DistanceRowNumberValue, IndexOnlyAggregateValue.
Planner / matcher code can type-assert against this to refuse to optimise paths that would require running the value over a base- record scan — they MUST be matched against an index, otherwise the plan fails to compile.
type IndexOnlyAggregateOp ¶
type IndexOnlyAggregateOp int
IndexOnlyAggregateOp enumerates the index-only aggregate operators — aggregations that MUST be backed by an aggregate index because they can't be evaluated by a streaming aggregator at runtime. Mirrors Java's `IndexOnlyAggregateValue.PhysicalOperator` (MAX_EVER_LONG / MIN_EVER_LONG).
const ( // IndexOnlyMaxEverLong is the running-max-since-time-zero // aggregate, backed by FDB's MAX_EVER_LONG index. Returns the // largest value ever seen across all writes to the indexed // column — even if the row has since been deleted. IndexOnlyMaxEverLong IndexOnlyAggregateOp = iota // IndexOnlyMinEverLong is the corresponding MIN_EVER aggregate. IndexOnlyMinEverLong )
func (IndexOnlyAggregateOp) String ¶
func (op IndexOnlyAggregateOp) String() string
String returns the canonical operator name (matches Java's PhysicalOperator enum names).
type IndexOnlyAggregateValue ¶
type IndexOnlyAggregateValue struct {
Op IndexOnlyAggregateOp
Child Value
}
IndexOnlyAggregateValue represents a compile-time aggregation that MUST be backed by an aggregate index — it cannot be evaluated by a streaming aggregator at runtime. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IndexOnlyAggregateValue`.
Java has two abstract subclasses (MaxEverValue, MinEverValue) per operator. The Go port unifies via an Op field — same matchability pattern as DistanceRowNumberValue.
At plan time, the planner must match this Value against an aggregate index of the corresponding type (MAX_EVER_LONG / MIN_EVER_LONG). If no matching index exists, the plan fails to compile — Java throws SemanticException; Go would surface the failure at the rule level (IsIndexOnly() returns true so the planner knows to refuse to optimise without an index).
Eval is a placeholder — IndexOnlyAggregateValue is non-evaluable by definition (Java's eval throws IllegalStateException; Go's surface returns nil per the existing pattern).
Implements the IndexableAggregate interface — GetIndexTypeName returns the operator name for index lookup.
func NewIndexOnlyAggregateValue ¶
func NewIndexOnlyAggregateValue(op IndexOnlyAggregateOp, child Value) *IndexOnlyAggregateValue
NewIndexOnlyAggregateValue constructs a compile-time aggregate of the given operator over child.
func (*IndexOnlyAggregateValue) Children ¶
func (v *IndexOnlyAggregateValue) Children() []Value
Children returns the single child Value.
func (*IndexOnlyAggregateValue) Evaluate ¶
func (*IndexOnlyAggregateValue) Evaluate(any) (any, error)
Evaluate is a placeholder — Java throws IllegalStateException since this aggregate is compile-time-only. Go surfaces nil per the placeholder pattern.
func (*IndexOnlyAggregateValue) GetIndexTypeName ¶
func (v *IndexOnlyAggregateValue) GetIndexTypeName() string
GetIndexTypeName returns the FDB index-type name backing this aggregate. Implements the IndexableAggregate interface so matchers + planner rules can pick aggregates eligible for index- scan lowering.
func (*IndexOnlyAggregateValue) IsIndexOnly ¶
func (*IndexOnlyAggregateValue) IsIndexOnly() bool
IsIndexOnly returns true — this aggregate MUST be backed by an index. Planner rules consult this to refuse to optimise without a matching index.
func (*IndexOnlyAggregateValue) IsNonEvaluable ¶
func (*IndexOnlyAggregateValue) IsNonEvaluable() bool
IsNonEvaluable returns true — IndexOnlyAggregateValue is compile-time-only by definition. Implements NonEvaluable.
func (*IndexOnlyAggregateValue) Name ¶
func (v *IndexOnlyAggregateValue) Name() string
Name returns the operator's canonical name.
func (*IndexOnlyAggregateValue) Type ¶
func (v *IndexOnlyAggregateValue) Type() Type
Type returns the child's type — Java's getResultType returns child.getResultType() unchanged.
func (*IndexOnlyAggregateValue) WithChildren ¶
func (v *IndexOnlyAggregateValue) WithChildren(newChildren []Value) *IndexOnlyAggregateValue
WithChildren returns a fresh IndexOnlyAggregateValue with the new child. Op carries through unchanged.
type IndexableAggregate ¶
IndexableAggregate is the Go-side counterpart to Java's IndexableAggregateValue interface. Any Value that has an index- backed aggregate form can implement this — currently only AggregateValue (when its Op has a non-empty index-type name).
Planner / matcher code can type-assert against this interface to pick aggregates eligible for index-scan lowering:
if iav, ok := v.(IndexableAggregate); ok && iav.GetIndexTypeName() != "" {
// can lower to index-aggregate scan
}
type IndexedValue ¶
type IndexedValue struct {
ResultType Type
}
IndexedValue is a leaf placeholder representing a column value bound to an indexed-key position. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IndexedValue`.
Used by index-pushdown rules during pattern matching: a logical FieldValue can be matched against an IndexedValue placeholder to verify that the predicate's column corresponds to an indexed position in the candidate index.
IndexedValue is a "non-evaluable" Value — it represents a position in an index key, not a computed result. Calling Evaluate panics so misuse surfaces loudly.
func NewIndexedValue ¶
func NewIndexedValue(resultType Type) *IndexedValue
NewIndexedValue constructs an IndexedValue with the given result Type. Pass UnknownType when the position's type isn't yet resolved.
func (*IndexedValue) Children ¶
func (*IndexedValue) Children() []Value
Children returns the empty slice — leaf.
type InvalidArgumentError ¶
type InvalidArgumentError struct {
Message string
}
InvalidArgumentError is returned by a scalar function when an argument is outside the function's mathematical domain — currently SQRT of a negative number. The executor converts this to SQLSTATE 22023 INVALID_PARAMETER_VALUE. Distinct from ScalarTypeMismatchError (wrong argument *type*); this is a wrong argument *value* of the right type.
func (*InvalidArgumentError) Error ¶
func (e *InvalidArgumentError) Error() string
type InvalidCastError ¶
type InvalidCastError struct {
Message string
}
InvalidCastError is returned by CastValue.Evaluate when a cast is out of range or structurally invalid (NaN→INT, overflow, etc.). The executor converts this to SQLSTATE 22F3H INVALID_CAST.
func (*InvalidCastError) Error ¶
func (e *InvalidCastError) Error() string
type LeafValue ¶
type LeafValue interface {
Value
// RebaseLeaf returns a new Value that is the same as this one but
// with correlated identifiers updated to targetAlias. Returns this
// if there are no correlated identifiers to update.
//
// Ports Java's LeafValue.rebaseLeaf(CorrelationIdentifier).
RebaseLeaf(targetAlias CorrelationIdentifier) Value
}
LeafValue is the Go counterpart of Java's LeafValue interface — a scalar value type that has no children. LeafValues participate in translation/rebasing via RebaseLeaf, which returns a new Value with correlation identifiers updated to a target alias.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.values.LeafValue.
type LikeOperatorValue ¶
LikeOperatorValue is the Value-layer SQL `LIKE` operator: tests whether a string value matches a SQL LIKE pattern. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. LikeOperatorValue`.
probe LIKE 'abc%' ↔ LikeOperatorValue{Probe: probe, Pattern: 'abc%'}
Why a Value-layer LIKE in addition to the predicate-layer ComparisonLike: rules that operate on the Value tree (e.g. fold a constant probe against a constant pattern, or extract a prefix for index-pushdown) need a Value-shaped node.
SQL LIKE wildcards:
- `%` matches zero or more characters
- `_` matches exactly one character
- other characters match literally
Delegates to the canonical LikeMatch helper (shared with the QueryPredicate-layer ComparisonLike). The matcher is pinned by FuzzLikeMatch / FuzzLikeMatchEscape against a regex oracle and matches Java's `Comparisons.likeMatcher` semantics.
Note: this Value-level LIKE carries no ESCAPE (escape rune = 0). ESCAPE support lives on the predicate layer (Comparison.Escape, predicates/comparisons.go) and in the shared LikeMatch helper — add the field here only if a Value-level ESCAPE consumer appears.
Evaluate semantics — Kleene 3VL:
- non-NULL probe + non-NULL pattern: true if pattern matches, false otherwise.
- NULL probe OR NULL pattern: nil (UNKNOWN).
- Non-string probe: nil (type-degraded).
Type is always nullable boolean.
func NewLikeOperatorValue ¶
func NewLikeOperatorValue(probe, pattern Value) *LikeOperatorValue
NewLikeOperatorValue constructs the LIKE Value.
func (*LikeOperatorValue) Children ¶
func (v *LikeOperatorValue) Children() []Value
Children returns probe + pattern.
func (*LikeOperatorValue) Evaluate ¶
func (v *LikeOperatorValue) Evaluate(evalCtx any) (any, error)
Evaluate computes probe LIKE pattern.
func (*LikeOperatorValue) Name ¶
func (*LikeOperatorValue) Name() string
Name returns the debug-print kind.
func (*LikeOperatorValue) Type ¶
func (*LikeOperatorValue) Type() Type
Type is always nullable boolean (NULL propagation).
type NonEvaluable ¶
NonEvaluable is the Go-side counterpart to Java's `Value.NonEvaluableValue` interface marker. Any Value that can't be evaluated at runtime (plan-time-only placeholders like AggregateValue, IndexOnlyAggregateValue) implements this marker.
Planner / matcher code can type-assert against this to refuse to pass non-evaluable Values to runtime evaluators.
Java's NonEvaluableValue is a true marker interface (no methods); the Go equivalent uses one method whose presence (and the implied `true` return) IS the marker.
type NotValue ¶
type NotValue struct {
Child Value
}
NotValue is the Value-layer NOT — the boolean negation of a single child Value. Mirrors Java's `com.apple.foundationdb.record.query. plan.cascades.values.NotValue`.
Why a Value-layer NOT in addition to the predicate-layer NotPredicate: boolean negation appears in non-predicate contexts too — e.g. `SELECT NOT(active) FROM t` where the result column carries a nullable boolean, not a 3VL truth value the predicate system can route. Cascades rules that float between Value and QueryPredicate representations need a Value-shaped NOT so the rebuild stays a Value tree. Java's NotValue.toQueryPredicate() bridges back to NotPredicate when the surrounding context calls for it; Go keeps the layers separate — the only value→predicate bridge is the EXISTS one (predicates/existential_value_predicate.go).
Evaluate semantics — Kleene 3VL:
- NOT TRUE = FALSE
- NOT FALSE = TRUE
- NOT NULL = NULL (NULL propagates)
- NOT non-bool = nil (UNKNOWN — degraded type mismatch)
Type is always TypeBool (NOT is a boolean operator).
type NullValue ¶
type NullValue struct {
Typ Type // type NULL was cast to; UnknownType when unconstrained
}
NullValue is the SQL NULL literal — evaluates to nil regardless of context. Not collapsed into ConstantValue{Value: nil} because having a dedicated type lets rule matchers check for NULL specifically (without also matching `Value: nil` ConstantValues that happen to represent a NULL literal in a non-type-annotated way).
func NewNullValue ¶
NewNullValue constructs a NullValue of the given type.
type ObjectValue ¶
type ObjectValue struct {
Alias CorrelationIdentifier
ResultType Type
}
ObjectValue is a generic typed-object placeholder bound to a CorrelationIdentifier. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ObjectValue`.
Used by Java to represent "any object" in expression contexts — generic counterpart to QuantifiedObjectValue (which specifically represents a Quantifier's flowed object). ObjectValue is more general: used in non-quantifier contexts where the planner needs a typed placeholder bound to a specific alias.
Type is whatever the planner determined at capture time.
Non-evaluable: ObjectValue is a placeholder; specialized evaluation paths (quantifier dereferencing, etc.) handle it before reaching the per-row Eval contract. Evaluate returns nil to make the no-row-eval contract explicit.
func NewObjectValue ¶
func NewObjectValue(alias CorrelationIdentifier, resultType Type) *ObjectValue
NewObjectValue constructs a typed object placeholder bound to the given alias.
func (*ObjectValue) Children ¶
func (*ObjectValue) Children() []Value
Children returns the empty slice — leaf.
func (*ObjectValue) Evaluate ¶
func (*ObjectValue) Evaluate(any) (any, error)
Evaluate returns nil — ObjectValue is a placeholder. Specialized evaluation paths handle it before reaching per-row Eval.
func (*ObjectValue) GetCorrelatedTo ¶
func (v *ObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the singleton set containing the bound alias.
type OfTypeValue ¶
OfTypeValue is a runtime type guard: tests whether a child Value's runtime evaluation matches an expected Type. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.OfTypeValue`.
OfTypeValue{Child: x, ExpectedType: int} ↔ "is x a runtime int?"
Used by:
- Type-aware rule rewrites that want to gate transformations on a runtime-type assertion (e.g. an arithmetic rule that only fires when both operands are numeric at evaluation time).
- The planner's PartialMatch infrastructure (Java) — type guards factor into match-candidate compatibility checks.
Evaluate semantics:
- Returns true if the child's evaluated value matches ExpectedType.
- Returns nil (UNKNOWN) if the child evaluates to nil — NULL is compatible with any nullable type but Go conservatively reports UNKNOWN; extend the rule if nullable / non-nullable semantics ever matter to a consumer.
- Returns false otherwise.
Type is always nullable boolean (Kleene-3VL guarded).
The implementation is a Type-code match (TypeCodeBoolean == TypeCodeBoolean). It deliberately does NOT walk RecordType / ArrayType structurally — no consumer compares structured types here; extend the match if one appears.
func NewOfTypeValue ¶
func NewOfTypeValue(child Value, expectedType Type) *OfTypeValue
NewOfTypeValue constructs the type-guard Value.
func (*OfTypeValue) Children ¶
func (v *OfTypeValue) Children() []Value
Children returns the single child Value.
func (*OfTypeValue) Evaluate ¶
func (v *OfTypeValue) Evaluate(evalCtx any) (any, error)
Evaluate checks the child's runtime value against ExpectedType via TypeCode match. Returns nil if either operand is nil-shaped.
Go compares only TypeCodes — TypeCodeBoolean matches a runtime bool, TypeCodeLong matches a runtime int64, etc. Field- level structural comparison (e.g. RecordType field-set match) is not implemented; extend if a consumer compares structured types.
CONFORMANCE: matches Java's OfTypeValue.eval semantics:
- NULL probe → returns ExpectedType.IsNullable().
- Primitive-to-primitive: STRICT TypeCode match (Java's `type.nullable().equals(expectedType.nullable())` reduces to a TypeCode comparison since nullability is normalised on both sides).
Verified against Java's OfTypeValueTest: `OfType(42 (int), LONG)` returns FALSE in Java even though INT is promotable to LONG in other contexts. Go matches this strict primitive behavior.
Two Java branches NOT replicated (Go has no consumer that feeds this Value proto messages or non-primitive promotions):
- DynamicMessage probe → returns `expectedType.isRecord()`.
- Non-primitive cross-type promotion via PromoteValue. resolvePhysicalOperator (only triggers for non-primitive sources — records, arrays).
type OrderedBytesDirection ¶
type OrderedBytesDirection int
OrderedBytesDirection enumerates the four ordering modes Java's `TupleOrdering.Direction` supports — combinations of (ASC|DESC) × (NULLS_FIRST|NULLS_LAST). Mirrors Java's enum verbatim so plan hashes / explain output diff cleanly across language boundaries.
const ( // OrderedBytesAscNullsFirst sorts ascending; NULL sorts BEFORE // any non-null value (lowest). OrderedBytesAscNullsFirst OrderedBytesDirection = iota // OrderedBytesAscNullsLast sorts ascending; NULL sorts AFTER any // non-null value (highest). OrderedBytesAscNullsLast // OrderedBytesDescNullsFirst sorts descending; NULL sorts BEFORE // (which becomes "highest" under DESC, since the iteration is // reversed). OrderedBytesDescNullsFirst // OrderedBytesDescNullsLast sorts descending; NULL sorts AFTER. OrderedBytesDescNullsLast )
func (OrderedBytesDirection) IsAscending ¶
func (d OrderedBytesDirection) IsAscending() bool
IsAscending reports whether the direction encodes an ASC ordering. Used by ordering-property analysis to determine whether the produced bytes preserve or invert the underlying value's natural ordering.
func (OrderedBytesDirection) String ¶
func (d OrderedBytesDirection) String() string
String renders the direction for explain / debug print.
type OrdinalBakeError ¶
type OrdinalBakeError struct {
Ordinal int
ChildType Type // the child's flowed type (nil for a nil child)
Reason string // which precondition failed: nil child / non-record child / out of range
}
OrdinalBakeError is the loud construction-time error NewFieldValueOfOrdinal returns when the requested ordinal cannot be resolved against the child's flowed type — the Go analog of Java's resolveFieldPath raising SemanticException(FIELD_ACCESS_INPUT_NON_RECORD_TYPE) for a non-record child and IndexOutOfBoundsException for an out-of-range ordinal (FieldValue.java:273-296). Never a silent fallback: a bake failure is a planner bug, not a NULL.
func (*OrdinalBakeError) Error ¶
func (e *OrdinalBakeError) Error() string
type OrdinalResolutionError ¶
OrdinalResolutionError is the loud internal error (RFC-173 Slice 1) raised when a FieldValue's column cannot be resolved against the authoritative ordinal runtime row. Authority + a silent name-map fallback would mean a resolution bug never surfaces, so this is a query error, not a NULL. Ordinal is the resolved ordinal, or -1 for a flat-reference (name->ordinal) miss. Available carries the row type's column names (when the row exposes them) so the failure is diagnosable from the message alone.
func (*OrdinalResolutionError) Error ¶
func (e *OrdinalResolutionError) Error() string
type OrdinalRow ¶
OrdinalRow is the RFC-173 ordinal-model runtime row FieldValue.Evaluate reads on the authoritative (non-join) frontier, in place of the legacy name-keyed map[string]any. It is satisfied structurally by executor.PositionalRow, which lives in a higher layer — the interface here avoids the import cycle.
Get(ordinal) is the primary path: a FieldValue with a typed child resolves its column to an ordinal (resolveOrdinal, against the child Type) and reads the slot positionally — Java's MessageHelpers.getFieldValueForFieldOrdinals. GetByName(name) serves a Go-only FLAT FieldValue (nil child, no child Type to resolve against): it resolves name->ordinal against the ROW's own Type (the authoritative positional type — e.g. a CTE's renamed columns, positionally aligned to the slots), NOT the legacy name map. Both loud-error (never a silent NULL) on a miss: on the authoritative frontier column existence is validated at plan time (42703), so a runtime miss is a malformed plan.
type OrdinalSeedLegWindow ¶
type OrdinalSeedLegWindow struct {
Offset int
Typ *RecordType
}
OrdinalSeedLegWindow is one leg's window in a pristine ordinal join seed's merged positional layout: the leg's starting slot and its flowed record type (design ruling on the W4-left slice: the layout derivation lives in ONE place — this package — with the planner's existential rebase delegating here and the executor's span derivation pinned to agree by a cross-agreement fixture; independent walks drift, and layout drift is wrong-offset wrong-rows).
type ParameterBinder ¶
ParameterBinder is an optional eval-context capability: when ParameterValue.Evaluate is called with a context that implements this interface, the parameter is resolved to its bound value. Otherwise Evaluate returns nil (SQL UNKNOWN), which is the safe default for plan-time evaluation where no bindings exist.
type ParameterObjectValue ¶
ParameterObjectValue represents a plan-cache parameter binding — a named placeholder whose value is supplied at execution time via the EvaluationContext. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ParameterObjectValue`.
Key fields:
- ParameterName: the parameter name (Java: parameterAlias stored as a string, not a CorrelationIdentifier).
- ResultType: the declared Type of the parameter.
Evaluate returns the parameter's value from the eval context's ParameterBinder capability, or nil when no binding exists.
Not correlated: ParameterObjectValue's getCorrelatedToWithoutChildren() returns the empty set in Java — parameter names are NOT CorrelationIdentifiers. The parameter's runtime value is resolved from the EvaluationContext, not from a quantifier binding.
func NewParameterObjectValue ¶
func NewParameterObjectValue(parameterName string, resultType Type) *ParameterObjectValue
NewParameterObjectValue constructs a ParameterObjectValue.
func (*ParameterObjectValue) Children ¶
func (*ParameterObjectValue) Children() []Value
Children returns the empty slice — leaf.
func (*ParameterObjectValue) Evaluate ¶
func (v *ParameterObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the parameter's value from the eval context's ParameterBinder capability. Returns nil when the context doesn't implement ParameterBinder or when no binding exists.
Mirrors Java's ParameterObjectValue.eval which calls context.getBinding(parameterName).
func (*ParameterObjectValue) GetCorrelatedTo ¶
func (*ParameterObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the empty set — parameter names are NOT CorrelationIdentifiers. Matches Java's ParameterObjectValue.getCorrelatedToWithoutChildren() returning ImmutableSet.of().
func (*ParameterObjectValue) Name ¶
func (*ParameterObjectValue) Name() string
Name returns the debug-print kind.
func (*ParameterObjectValue) RebaseLeaf ¶
func (v *ParameterObjectValue) RebaseLeaf(_ CorrelationIdentifier) Value
RebaseLeaf returns this unchanged — ParameterObjectValue has no correlation to rebase. Mirrors Java's ParameterObjectValue.rebaseLeaf returning `this`.
func (*ParameterObjectValue) Type ¶
func (v *ParameterObjectValue) Type() Type
Type returns the declared result type. Parameter bindings can be NULL, so the result is forced to nullable.
type ParameterValue ¶
type ParameterValue struct {
Ordinal int // 1-based positional index; 0 ⇒ named parameter
ParamName string // populated when Ordinal == 0
Typ Type // UnknownType until upstream type inference fills it
}
ParameterValue is a placeholder for a prepared-statement parameter — `?` (positional, Ordinal>=1) or `:name` (named, Ordinal=0). Its concrete value is unknown at plan time, so Evaluate returns nil unless the eval context implements ParameterBinder. Treated as non-constant by IsConstantValue, so constant-fold rules decline to fire on `x = ?` / `x = :foo`.
Plan-cache keying: ExplainValue renders a parameter as `?N` / `:name`, which means `WHERE x = ?` and `WHERE x = ?` for two different bind-values share the same Explain string — the seam a future plan cache will key on.
Runtime evaluation goes through the ParameterBinder interface: an evalCtx that implements it (RowEvalContext.Binder) resolves the binding by ordinal/name; without a binder the value degrades to NULL — acceptable only for plan-time / explain-time evaluation.
func NewNamedParameterValue ¶
func NewNamedParameterValue(name string) *ParameterValue
NewNamedParameterValue constructs a named `:name` parameter.
func NewParameterValue ¶
func NewParameterValue(ordinal int) *ParameterValue
NewParameterValue constructs a positional `?` parameter (1-based).
func (*ParameterValue) Children ¶
func (*ParameterValue) Children() []Value
func (*ParameterValue) Name ¶
func (*ParameterValue) Name() string
func (*ParameterValue) Type ¶
func (p *ParameterValue) Type() Type
Type returns the parameter's rich Type. Parameter bindings can be NULL so the result is forced to nullable regardless of how the caller stored Typ.
type PatternForLikeValue ¶
PatternForLikeValue is the SQL `patternForLike(pattern, escape)` function — converts a SQL LIKE pattern (with `%` / `_` wildcards and an optional escape char) to a regex-form string, wrapped in `^...$`. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.PatternForLikeValue`.
This Value is part of Java's LIKE-operator surface: Java's `LikeOperatorValue.eval` consumes the regex string produced here via `java.util.regex.Pattern`. Our Go LikeOperatorValue does NOT consume the regex — it routes through the canonical `values.LikeMatch` matcher, which works DIRECTLY on the SQL pattern with `%` / `_` (no regex involvement). PatternForLikeValue is therefore a planner-side surface only in Go: SQL queries that reference `patternForLike(...)` lower to this Value, but the produced regex string isn't consumed by any Go runtime path.
We still port it because:
- It's a SQL-callable function that may appear in user queries (Java's grammar exposes `patternForLike` as a builtin).
- Plan-level equivalence with Java requires the same Value tree shape — even when the actual eval path differs.
- Direct Java → Go SQL plan ports won't fail with "unknown function" when this surface is reached.
Result type: NotNullString (the regex form is always a string).
Eval contract (matches Java):
- patternChild evaluates to a string. If NULL, eval returns NULL.
- escapeChild evaluates to a string OR NULL.
- NULL → standard transformation (no escape).
- exactly 1 character → escape-aware transformation (escape+`_` → literal `_`, escape+`%` → literal `%`).
- other length → returns nil (Java throws SemanticException; Go defers to evaluator-side reporting). Documented as a planner-checked precondition.
Java's `LikeOperatorValue.likeOperation` calls `Pattern.compile(rhs)` WITHOUT DOTALL — Go's default regexp behavior (`.` does NOT match `\n`) is already aligned.
func NewPatternForLikeValue ¶
func NewPatternForLikeValue(pattern, escape Value) *PatternForLikeValue
NewPatternForLikeValue constructs the value with required pattern and optional escape children.
func (*PatternForLikeValue) Children ¶
func (v *PatternForLikeValue) Children() []Value
Children returns [pattern, escape].
func (*PatternForLikeValue) Evaluate ¶
func (v *PatternForLikeValue) Evaluate(evalCtx any) (any, error)
Evaluate produces the regex-form string with `^...$` anchors. Returns nil if the pattern is NULL or the escape is malformed.
func (*PatternForLikeValue) Name ¶
func (*PatternForLikeValue) Name() string
Name returns the SQL function name.
func (*PatternForLikeValue) Type ¶
func (*PatternForLikeValue) Type() Type
Type returns NotNullString.
type PickValue ¶
type PickValue struct {
Selector Value
Alternatives []Value
// Typ is the result type — Java resolves from alternative types.
// Defaults to UnknownType.
Typ Type
}
PickValue picks one of N alternative Values based on an integer selector. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.PickValue`.
PickValue{Selector: 1, Alternatives: [a, b, c]}.Evaluate(ctx)
↔ Alternatives[1].Evaluate(ctx) = b.Evaluate(ctx)
Used by the planner for case-style branching where the selector is computed at runtime (e.g. switching between alternative projection shapes based on row context).
CONFORMANCE: matches Java's eval — Selector evaluates to an integer; alternatives[selector] is then evaluated. NULL selector → NULL. Out-of-bounds selector returns nil (defensive; Java would throw IndexOutOfBoundsException — Go swallows for the row-eval contract).
Type is the bound result type (Java's constructor resolves it from the alternatives' types — promotion lattice merge).
func NewPickValue ¶
NewPickValue constructs the picker with selector + alternatives + result Type.
func (*PickValue) Children ¶
Children returns [Selector, alt0, alt1, ...].
Position-stable: nil entries are PRESERVED in the output (not filtered) so that the index returned by Selector.Evaluate stays aligned with the index into the children list. Filtering nils would silently shift later alternatives toward earlier positions — Evaluate would then index into a wrong slot. The caller's nil-handling lives in Evaluate (a nil-resolved alternative returns nil rather than dereferencing).
PickValue intentionally does NOT have a WithChildren method — the simplification driver doesn't rebuild PickValues. If a future caller needs to rewrite PickValue's children, the rebuild must use indexed assignment (NOT a fresh constructor over Children()) since Selector + Alternatives are position-coupled.
type PrimitiveType ¶
PrimitiveType is the Type impl for scalar types (INT, BOOLEAN, STRING, …). Two PrimitiveType values are Equal iff their Code + Nullable match.
func NewPrimitiveType ¶
func NewPrimitiveType(code TypeCode, nullable bool) *PrimitiveType
NewPrimitiveType constructs a PrimitiveType. Panics if code is a structured code (RECORD / ARRAY / ENUM / RELATION) — those have dedicated constructors (NewRecordType / NewArrayType / NewEnumType / NewRelationType). UNKNOWN / ANY / NONE / NULL are accepted because they're frequently useful as placeholder Types even though they're not "primitive" per IsPrimitive's sense.
func (*PrimitiveType) Equals ¶
func (p *PrimitiveType) Equals(other Type) bool
Equals implements Type. Structural — Code + Nullable.
func (*PrimitiveType) IsNullable ¶
func (p *PrimitiveType) IsNullable() bool
IsNullable implements Type.
func (*PrimitiveType) String ¶
func (p *PrimitiveType) String() string
String implements Type. Renders as "INT NOT NULL", "STRING NULL", …
type PromoteValue ¶
PromoteValue wraps a child Value to coerce it to a target SQL type when the analyzer inserts an implicit conversion. E.g. `int_col = 5.0` rewrites to `PromoteValue(int_col, FLOAT) = 5.0` so the comparison sees two FLOATs.
Distinct from CastValue: Cast is an explicit `CAST(x AS T)` that the user wrote; Promote is machine-inserted and cost-modelled separately. Mirrors Java's `PromoteValue`.
Evaluate currently delegates to Child.Evaluate — cmpAny already promotes numerics at runtime, so an explicit Promote in the tree is a no-op evaluation-wise. The value is in having the coercion visible at plan time so rule matchers can simplify `Promote(x, x.Type)` → `x`.
func NewPromoteValue ¶
func NewPromoteValue(child Value, target Type) *PromoteValue
NewPromoteValue constructs a PromoteValue. Rejects nil child and nil / Unknown Target — both are programmer errors.
func (*PromoteValue) Children ¶
func (p *PromoteValue) Children() []Value
Children returns the single child as a one-element slice.
func (*PromoteValue) Evaluate ¶
func (p *PromoteValue) Evaluate(evalCtx any) (any, error)
Evaluate delegates to the child for the numeric/cross-width case — Go treats Promote as a no-op there since cmpAny already handles cross-width promotion, and plan-time inspection (explain, rewrite rules) is where those Promotes earn their keep.
The ONE runtime-active arm is STRING → UUID (Java's PromoteValue.STRING_TO_UUID, `UUID.fromString`): a UUID column has no native proto/SQL primitive, so `uuid_col = '<uuid>'` arrives as a STRING comparand. Promoting it to UUID here parses the canonical string into a neutral 16-byte value ([16]byte, matching Java's java.util.UUID — no `tuple` import so `values` stays wire-agnostic). The scan-range packer turns that [16]byte into a `tuple.UUID` at the FDB wire boundary, so the equality probe hits the 0x30 index entry instead of packing a 0x02 string that never matches.
func (*PromoteValue) Type ¶
func (p *PromoteValue) Type() Type
Type returns the promotion target. Nullability is inherited from the child — promoting a NOT NULL value preserves NOT NULL.
type QuantifiedObjectValue ¶
type QuantifiedObjectValue struct {
Correlation CorrelationIdentifier
// Typ is the row type (struct shape) this quantifier produces —
// a *RecordType on the typed frontier (RFC-173; the translator
// stamps it from the inner expression's result type), or
// UnknownType where inference hasn't reached.
Typ Type
}
QuantifiedObjectValue represents "the current row of the quantifier identified by Correlation". Emitted by the analyzer for references like `t` in `SELECT t.col FROM tbl AS t` — the parent expression (`t.col`) then projects a FieldValue with operand = QuantifiedObjectValue{Correlation: t}.
Mirrors Java's `QuantifiedObjectValue`. Evaluate reads the row directly out of the eval context when it's a `map[CorrelationIdentifier]map[string]any` (the multi-source shape); for the single-source `map[string]any` shape it returns the map verbatim so downstream FieldValue lookups can index into it.
func NewQuantifiedObjectValue ¶
func NewQuantifiedObjectValue(corr CorrelationIdentifier) *QuantifiedObjectValue
NewQuantifiedObjectValue constructs a QuantifiedObjectValue. Zero correlation is rejected — a quantifier without an identifier is a design error, not something the analyzer should allow.
func NewQuantifiedObjectValueOfType ¶
func NewQuantifiedObjectValueOfType(corr CorrelationIdentifier, typ Type) *QuantifiedObjectValue
NewQuantifiedObjectValueOfType constructs a QuantifiedObjectValue whose flowed value carries a known type. Used where the quantifier flows a SCALAR of a known type — e.g. a lateral array unnest's element quantifier, whose flowed value is one array element (the array's elementType), not an UnknownType row. Carrying the real type lets result-set column metadata report it (a STRING array's element is STRING, not the UnknownType→BIGINT fallback). A nil typ degrades to UnknownType, matching NewQuantifiedObjectValue.
func (*QuantifiedObjectValue) Children ¶
func (*QuantifiedObjectValue) Children() []Value
Children returns an empty slice — the quantifier is a leaf in the Value tree, with its correlation link being external metadata (not a child Value).
func (*QuantifiedObjectValue) Evaluate ¶
func (q *QuantifiedObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate extracts the row bound to this quantifier's correlation. Eval context shapes this impl handles:
- map[CorrelationIdentifier]map[string]any — multi-source shape, returns the nested map for this correlation (nil if missing).
- map[string]any — single-source compat shim: IGNORES q.Correlation and returns the whole map. Safe only when there's one QuantifiedObjectValue in play; multi-source callers MUST use the per-correlation shape or two quantifiers with different correlations silently evaluate to the same row.
- anything else — nil.
The single-source shim exists so existing single-table tests / callers that feed a bare row map keep working while the eval path migrates. New callers MUST NOT rely on it — thread the per-correlation shape end-to-end. The shim is scheduled for removal once no caller needs it.
Downstream FieldValue / nested-field resolvers then index into the returned map to pick a specific column.
func (*QuantifiedObjectValue) GetCorrelatedTo ¶
func (q *QuantifiedObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo implements the Correlated interface — returns a set containing this quantifier's correlation.
func (*QuantifiedObjectValue) Name ¶
func (*QuantifiedObjectValue) Name() string
Name returns the debug-print kind.
func (*QuantifiedObjectValue) RebaseLeaf ¶
func (q *QuantifiedObjectValue) RebaseLeaf(targetAlias CorrelationIdentifier) Value
RebaseLeaf on QuantifiedObjectValue returns a new QuantifiedObjectValue with the target alias, preserving the type. Ports Java's QuantifiedObjectValue.rebaseLeaf.
func (*QuantifiedObjectValue) Type ¶
func (q *QuantifiedObjectValue) Type() Type
Type returns the row reference Type. Always nullable — rows pass through as nullable (e.g. LEFT JOIN's right side).
type QuantifiedRecordValue ¶
type QuantifiedRecordValue struct {
Alias CorrelationIdentifier
ResultType Type
}
QuantifiedRecordValue represents the entire QUERIED RECORD flowing from a Quantifier — the FDBQueriedRecord shape that carries the stored protobuf message plus version + primary-key metadata. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.QuantifiedRecordValue`.
Distinction from QuantifiedObjectValue:
- QuantifiedObjectValue evaluates to the OBJECT bound to the alias — for record-typed quantifiers this is the proto Message, for repeated-field unnest it's the inner element, for non-record types it's the raw datum.
- QuantifiedRecordValue evaluates to the QUERIED RECORD specifically — a record-shaped tuple of (storedRecord, version, primaryKey). Java's eval calls `binding.getQueriedRecord()` rather than `getMessage()` or `getDatum()`.
The two coexist because:
- Record-typed planner reasoning needs the metadata attached to the record (version, PK); QuantifiedRecordValue carries that intent.
- Per-message proto field access uses QuantifiedObjectValue and descends via FieldValue chains.
In Go both Values evaluate identically through the row-shape harness — the executor does not dispatch FDBQueriedRecord vs Message, so only the TYPE-level distinction is live: planner matchers test for the QuantifiedRecordValue marker specifically (e.g. MatchCandidate-side rules that need the full queried record).
Eval contract: returns the queried-record bound to `alias` in the eval context. Go accepts a `map[string]any` keyed by alias name (sharing VersionValue / IncarnationValue's harness pattern); a nil / non-map / missing-key context returns nil.
func NewQuantifiedRecordValue ¶
func NewQuantifiedRecordValue(alias CorrelationIdentifier, resultType Type) *QuantifiedRecordValue
NewQuantifiedRecordValue constructs a record-flow placeholder bound to the given alias and typed at resultType.
resultType is expected to be record-typed (the Java constructor admits any Type but downstream planner matchers select on resultType.isRecord()). Go doesn't enforce — Type kind inspection is planner-side; constructor is permissive to keep the test surface honest.
func (*QuantifiedRecordValue) Children ¶
func (*QuantifiedRecordValue) Children() []Value
Children returns the empty slice — leaf, no operands.
func (*QuantifiedRecordValue) Evaluate ¶
func (v *QuantifiedRecordValue) Evaluate(evalCtx any) (any, error)
Evaluate looks up the queried record bound to alias in the eval context. Returns nil if evalCtx is nil or not a row-shape map.
func (*QuantifiedRecordValue) GetCorrelatedTo ¶
func (v *QuantifiedRecordValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the singleton set containing the bound alias — Java's QuantifiedValue contract surfaces the alias as a dataflow correlation.
func (*QuantifiedRecordValue) Name ¶
func (*QuantifiedRecordValue) Name() string
Name returns the debug-print kind.
func (*QuantifiedRecordValue) Type ¶
func (v *QuantifiedRecordValue) Type() Type
Type returns the bound record's type.
type QueriedValue ¶
QueriedValue is a leaf placeholder representing the FROM-clause row context (the "what's been queried"). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.QueriedValue`.
Used by the planner during semantic resolution: a SELECT * projection lowers to QueriedValue + RecordConstructor over the queried record types' fields. The Value is non-evaluable — specialized planner rewrites resolve it to concrete Field / QuantifiedObject values before reaching the row-eval layer.
Go accepts an optional record-type-name list and a result Type. Both are advisory; the actual type comes from the queried record store's metadata at execution time.
func NewQueriedValue ¶
func NewQueriedValue(recordTypes []string, resultType Type) *QueriedValue
NewQueriedValue constructs the placeholder.
func (*QueriedValue) Children ¶
func (*QueriedValue) Children() []Value
Children returns the empty slice — leaf.
type RangeValue ¶
RangeValue is the SQL range(begin, end, step) table-valued function — produces a stream of LONG values from `beginInclusive` (default 0) up to but not including `endExclusive`, stepped by `step` (default 1). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RangeValue`.
Java's class is a STREAMING value (`StreamingValue` + `CreatesDynamicTypesValue`) — its primary eval path is `evalAsStream` which returns a `RecordCursor<QueryResult>`. The scalar `eval` method throws because per-row evaluation makes no sense for a table-function. Go mirrors this: Evaluate returns nil per the placeholder pattern, and a separate EvaluateAsStream method materialises the finite range as `[]int64` for testability.
Result type: a 1-column record with LONG-valued column "ID" — the row shape Java's currentRangeValue produces. Go exposes the element type (NotNullLong) directly via Type since record-typed returns are awkward without StreamingValue / record-type sub-shape support; consumers that care about the row shape can wrap in a RecordConstructorValue.
Cardinality is statically known when begin/end/step all evaluate to constants — useful for the cost model to estimate. Go exposes Cardinality() with the same `floorDiv(end-begin, step)` formula Java uses.
func NewRangeValue ¶
func NewRangeValue(begin, end, step Value) *RangeValue
NewRangeValue constructs a RangeValue. All three children are REQUIRED (Java's grammar lets begin and step default to 0 and 1 respectively, but those defaults are added at the parser level — the constructed Value carries explicit children).
func (*RangeValue) Cardinality ¶
func (r *RangeValue) Cardinality() (int64, bool)
Cardinality returns the static row count if all three children are constant-foldable to int64, else returns (-1, false).
Mirrors Java's getCardinalities — used by the cost model when the planner has a RangeValue table function in scope and wants to size operators above it.
func (*RangeValue) Children ¶
func (r *RangeValue) Children() []Value
Children returns [begin, end, step] in source order (matches Java's withChildren list ordering).
func (*RangeValue) Evaluate ¶
func (*RangeValue) Evaluate(any) (any, error)
Evaluate is a placeholder — RangeValue is a streaming Value; per-row eval makes no sense. Java throws IllegalStateException; Go surfaces nil per the existing placeholder pattern.
Use EvaluateAsStream for the materialised range expansion.
func (*RangeValue) EvaluateAsStream ¶
func (r *RangeValue) EvaluateAsStream(evalCtx any) []int64
EvaluateAsStream materialises the finite range as a slice of int64 elements: [begin, begin+step, begin+2*step, ...) up to but excluding `end`. Returns nil if any of the children evaluate to non-int64, or if the range is degenerate (step <= 0 with positive direction, etc.).
Real Java RangeValue produces a streaming RecordCursor — the finite materialisation here is for tests + cost-model cardinality estimation. Production execution would route through a streaming integration (gated on StreamingValue port).
func (*RangeValue) Type ¶
func (*RangeValue) Type() Type
Type returns NotNullLong — the element type of the produced range.
Note: Java's getResultType() returns Type.Record (a 1-column record with LONG-valued "ID"). Go exposes the element type directly because record-typed Type wrappers without proper StreamingValue support would force the seed to introduce the streaming infrastructure piecemeal. Wrapping in a RecordConstructorValue at the call site is the canonical way to produce the record-shaped row.
type RankValue ¶
type RankValue struct {
WindowedValue
}
RankValue is the SQL RANK() window function — assigns 1-based rank within each partition, sharing rank across ORDER BY ties (and skipping ranks accordingly: 1, 1, 3, 4, 4, 6). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RankValue`.
RANK has NO operand arguments — Java's grammar is `RANK() OVER (PARTITION BY ... ORDER BY ...)`; the windowing happens via the surrounding window definition. ArgumentValues is always empty (Java's constructor takes them but RANK's BuiltIn passes empty argumentValues at parse time).
Result type: NotNullLong. RANK over an empty partition still produces 1 for the first row; never NULL.
Eval: window-aware. Go accepts a row-shape evalCtx of
map[string]any{"_rank": int64(N)}
— the test harness pattern. Real execution wires a streaming-window accumulator that increments rank counters per partition; Go exposes the current rank via this side channel so window-tagged Values are testable without the full streaming framework.
func NewRankValue ¶
NewRankValue constructs a RANK() value with the given partitioning columns. Java's constructor takes (partitioning, argument) — RANK passes empty argumentValues. We expose only the partitioning parameter to match RANK()'s actual SQL surface.
func (*RankValue) Evaluate ¶
Evaluate returns the current rank from the row-shape harness pattern. The harness supplies the window-accumulator's current rank via the `_rank` key; in a real execution the rank is computed by the streaming window operator.
Returns nil if evalCtx is nil / non-map / has no `_rank` key — matches the placeholder-Value pattern used elsewhere in the package.
func (*RankValue) WithChildren ¶
WithChildren returns a new RankValue with the given children re-split via WindowedValue.SplitNewChildren. Java's withChildren reconstructs the partition+argument lists by position.
Per Java's RANK semantics, argument values should remain empty after withChildren — the partitioning columns are the only children RANK actually carries.
type ReEnumerationLeg ¶
type ReEnumerationLeg struct {
Alias CorrelationIdentifier
Sources []CorrelationIdentifier
}
ReEnumerationLeg names one leg of a re-enumerated merge level (RFC-077 7.6): the quantifier the leg's columns are anchored to (Alias), and the parent-quantifier aliases whose columns flow into this leg (Sources). For a leg that PASSES THROUGH a quantifier the parent already binds (an original table, or a merge quantifier from a prior level), Sources is the singleton {Alias} — its columns are read straight from the parent. For a NEWLY-CREATED merge quantifier ($m) that collapses ≥2 lower quantifiers, Alias is the new merge alias and Sources is every collapsed quantifier — $m's row carries the UNION of their columns under their source-table-qualified (dotted) names.
type RecordConstructorField ¶
RecordConstructorField pairs a field name with the Value that computes its contents. Named so the output has a struct shape downstream consumers (projections, aggregations) can address by name.
type RecordConstructorValue ¶
type RecordConstructorValue struct {
Fields []RecordConstructorField
// AnchoredJoin marks a source-anchored join RESULT value (RFC-077 7.6):
// the RecordConstructorValue NewAnchoredJoinRecord builds, whose fields are
// each FieldValue(QuantifiedObjectValue(leg), col) over the enclosing
// select's OWN immediate join quantifiers. It is the structural successor of
// the retired opaque merge's Seed provenance bit, carrying the SAME
// dual-purpose semantics (RFC-077 F2):
// - exploration-time HIDING: GetCorrelatedToOfValue does NOT descend into an
// anchored-join RC, so its self-bound leg QOVs are excluded from the
// value's reported external correlation set (mirroring the retired seed bit's
// "report nothing"). Reporting them inflates every enclosing select's
// correlation order and tips the ≥4-way STAR past the task budget.
// - partition-time RE-EXPOSURE: PartitionSelectRule keeps ALL lower aliases
// live for an anchored-join result (the seed never names the real
// projection), and AddMergeSeedAliases re-collects the buried leg QOVs by
// walking INTO the RC's fields — so a predicate reading a buried column is
// classified as spanning, not pushed below the merge (the 0-row bug).
//
// An ORDINARY RecordConstructorValue (a SELECT projection) leaves this false:
// its correlations are real and must be reported. The flag is the honest
// structural marker that "this RC is a join result, not a user projection",
// NOT a downstream-observable heuristic — and it is PRESERVED through every
// Value reconstruction (WithChildren, Replace, RebaseValue, and the value
// simplifier's RecordConstructor/liftConstructor rebuilds) so the hiding
// survives SelectMergeRule's flatten-time substitution of nested join legs.
AnchoredJoin bool
}
RecordConstructorValue constructs a record (struct) from named children. Used by the analyzer for SELECT projection output (`SELECT a, b+1 AS c` → Record{a: a, c: b+1}) and anywhere a tuple-of-values is needed (ORDER BY key groups, aggregate keys).
Mirrors Java's `RecordConstructorValue`.
func NewAnchoredJoinRecord ¶
func NewAnchoredJoinRecord(legs []AnchoredJoinLeg) *RecordConstructorValue
NewAnchoredJoinRecord builds the source-anchored join result value (RFC-077): a RecordConstructorValue whose fields are FieldValue(QuantifiedObjectValue(legAlias), col) — one per column of each leg. This replaces the retired opaque, name-keyed merge and its after-the-fact field re-anchoring: every projected field names its source quantifier directly, exactly as Java's RecordConstructorValue of FieldValue(QOV(leg), col) does.
Naming preserves the retired opaque merge's bare+qualified key set so name-based resolution (composeFieldOverConstructor: field(RC, name) → the leg FieldValue) keeps working for EVERY reference the SARG/derivation can pull up — exactly the keys the executor still builds physically (the cursor's mergeRows writes both the bare and the ALIAS.COL form):
- EVERY column gets a qualified ALIAS.COL field (upper-cased, matching the merge's ToUpper qualification), so a qualified reference (e.g. A.NAME) ALWAYS resolves — including to a column whose bare name happens to be unique;
- EVERY column also gets a bare field, LAST-LEG-WINS on a cross-leg collision — exactly the retired opaque merge's runtime, which wrote every leg's keys bare (later legs overwrite earlier ones for a shared name). A RecordConstructorValue cannot hold two fields of the same name, so for a duplicated bare name only the LAST leg's column gets the bare field (the earlier legs are still reachable by their qualified ALIAS.COL). Emitting bare-only-when-unique instead (an earlier cut) dropped the bare key for duplicated columns, which broke 3+-way joins with 0 rows: by INVARIANT (sourceAlias(LogicalJoin)=sourceAlias(o.Right), cascades_translator.go), a quantifier OVER an inner join is aliased to its right leg, so a qualified predicate FieldValue(QOV(rightLeg), COL) reads the join's merged row by the bare COL key. last-leg-wins = the right leg = QOV(rightLeg)'s alias, so the bare key resolves to exactly the source the predicate means — by construction, not coincidence.
The field VALUE always carries the original (non-upper-cased) column name so the leg's QuantifiedObjectValue field access matches the source row's key.
ALREADY-QUALIFIED (DOTTED) leg columns — NESTED joins. A join leg's exposed columns are themselves anchored-RC field names: an inner join (A⋈B) exposes A.ID, B.ID, etc. When such a DOTTED name is a column of a parent leg, it propagates VERBATIM — the field name stays "A.ID" (NOT re-qualified to "PARENTLEG.A.ID") and the value is FieldValue(QOV(parentLeg), "A.ID"). This mirrors the executor's "preserve already-qualified keys verbatim, never re-prefix" (mergeRows): each table contributes a DISTINCT prefix, so a dotted key never collides across legs and reaches the right source via the parent leg's merged row. A dotted column gets NO extra bare/qualified form (it is already the resolvable key), matching the merge.
func NewRawRecordConstructorValue ¶
func NewRawRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue
NewRawRecordConstructorValue constructs a RecordConstructorValue keeping every field name VERBATIM — duplicate names allowed. It exists for the RFC-173 ordinal-join seeds (review W3 ruling: dedicated raw RC constructor): the 2-way join's ordinal RC concatenates the two legs' columns, each field a BAKED FieldValue over its leg's QOV, and duplicate names across legs (`SELECT * FROM a JOIN b` with same-named columns) MUST survive verbatim — positional access is by ordinal, so duplicates are unambiguous, and §5's duplicate-name identity pin is unconstructible without them.
NEVER use this for a name-model RC: NewRecordConstructorValue (above) appends _2/_3 suffixes, which is correct there (SQL projection column naming, name-keyed Datum rows) — a raw duplicate in the name model silently resolves to the first match, the exact conflation RFC-173 exists to kill.
func NewReEnumerationAnchoredRecord ¶
func NewReEnumerationAnchoredRecord(parent *RecordConstructorValue, legs []ReEnumerationLeg) *RecordConstructorValue
NewReEnumerationAnchoredRecord builds the source-anchored result value for a PartitionSelectRule re-enumeration level (RFC-077 7.6), replacing the retired opaque merge. Each leg's columns are read from the parent anchored RC (grouped by anchoring quantifier) and re-anchored to the leg's quantifier. It emits EXACTLY the retired opaque merge's bare+qualified key set so name resolution is preserved (review condition 2):
- a SOURCE-TABLE-qualified field SRC.COL for EVERY column, anchored to QOV(legAlias). For a pass-through original-table leg the row carries the column BARE (FieldValue(QOV(table), "COL")); for a merge quantifier ($m, collapsing ≥2 tables) the row preserves the DOTTED key (FieldValue(QOV($m), "SRC.COL")) — mergeRows keeps dotted keys verbatim, runtime untouched;
- a BARE field COL, LAST-LEG-WINS on a cross-leg collision, anchored to QOV(legAlias) reading the BARE key — both a leaf table row and a merge row carry bare keys (mergeRows writes them), so an UNQUALIFIED projection of a buried column resolves, exactly as the executor's mergeRows still writes bare keys (the buried-column-bare-projection 0-row regression otherwise).
legs must already be in the rule's canonical (alias-name-sorted) order so two bipartitions producing the same leg-set intern to one Reference (the anchored RC's structural identity is order-sensitive). Returns nil if the parent is not anchored or a leg's source columns are unavailable; in practice every parent reaching the rule is anchored and every leg's source is a parent quantifier, so resolution always succeeds — the rule's callers panic on a nil (fail-loud on a proven-unreachable invariant rather than store a nil result value silently).
func NewRecordConstructorValue ¶
func NewRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue
NewRecordConstructorValue constructs a RecordConstructorValue. Duplicate field names are deduplicated by appending a numeric suffix (_2, _3, ...) to later occurrences, matching SQL semantics where `SELECT a, a FROM T` produces columns a, a_2.
func NewScalarSubqueryAnchoredRecord ¶
func NewScalarSubqueryAnchoredRecord(outer AnchoredJoinLeg, innerAlias CorrelationIdentifier, scalarColKey string) *RecordConstructorValue
NewScalarSubqueryAnchoredRecord builds the source-anchored result value for a correlated-scalar-subquery join seed (RFC-077 7.6), replacing the retired opaque merge seed. The outer leg is anchored exactly as a binary join leg (bare + qualified + dotted-verbatim, via NewAnchoredJoinRecord), so the outer projections resolve both bare and qualified. The inner leg is the scalar subquery's SINGLE exposed value, anchored with one field:
- Name: <innerAlias>.<scalarColKey> (upper-cased) — EXACTLY the field name replaceScalarSubqueryRef reads (it qualifies the scalar reference under the inner quantifier's alias), so composeFieldOverConstructor resolves it by name;
- Value: FieldValue(QOV(innerAlias), scalarColKey) — reads the inner row's scalar by the key the inner quantifier's row carries it under.
This re-qualifies scalarColKey under innerAlias even when scalarColKey is itself DOTTED (a non-aggregate subquery keeps its source qualifier, e.g. "C.NAME"), which NewAnchoredJoinRecord cannot do (it propagates dotted leg columns verbatim). The inner field has NO bare form: the projection always reads the scalar via the qualified name, and the executor's runtime mergeRows likewise only ever exposes the inner scalar prefixed under innerAlias — so a bare inner field would have no consumer and could spuriously shadow an outer column of the same bare name.
func (*RecordConstructorValue) Children ¶
func (r *RecordConstructorValue) Children() []Value
Children returns each field's Value as a flat list, in field declaration order. Lets WalkValue traverse the whole tree.
func (*RecordConstructorValue) Evaluate ¶
func (r *RecordConstructorValue) Evaluate(evalCtx any) (any, error)
Evaluate produces a map[string]any with each field evaluated. Downstream consumers (projections, field-access) index into this map by field name.
func (*RecordConstructorValue) Name ¶
func (*RecordConstructorValue) Name() string
Name returns the debug-print kind.
func (*RecordConstructorValue) Type ¶
func (r *RecordConstructorValue) Type() Type
Type synthesises a RecordType from the constructor's fields. The outer record is anonymous + nullable (we can't prove an inferred record is NOT NULL).
type RecordType ¶
type RecordType struct {
// RecordName is the optional record name. Empty string means
// anonymous — frequently the case for projection result rows
// that haven't been bound to a named struct.
RecordName string
// Nullable reports whether the record allows NULL — i.e. a
// nullable column whose type is this RecordType. Anonymous
// records typically default to nullable since plan-time
// inference can't always prove non-nullness.
Nullable bool
// Fields are the record's fields in declared order. Empty slice
// means a record with no fields (legal — `RECORD<>` is the unit
// type). Never nil.
Fields []Field
// Legs marks the buried-leg boundaries of a CLUSTERED box leg's flat
// ordinal concat (RFC-173 item 3): the translator's ordinalLegType walks
// the box's legs and records each buried source's binding + starting
// slot, so the ONE layout authority (OrdinalSeedLegWindows) can emit
// additive per-buried-leg sub-windows — a projection read qualified by a
// buried alias resolves positionally exactly like a top-level leg's
// (Java's rewire-by-ordinal: a buried source is just another
// quantifier's window). Empty for every non-clustered leg type; carries
// NO identity semantics (Equals/Hash ignore it — layout metadata only).
Legs []RecordTypeLeg
}
RecordType is the Type impl for struct-shaped data. Mirrors Java's Record nested type. Two RecordType instances are Equal iff their Name + Nullable match AND their Fields slice is element-wise equal (same length, each Field equals at the same index).
Anonymous records (no name) are common — `RECORD<INT, STRING>` produces a RecordType with Name="" and the corresponding Fields. Named records carry a schema-level table or struct name.
func NewRecordType ¶
func NewRecordType(name string, nullable bool, fields []Field) *RecordType
NewRecordType constructs a RecordType. The Fields slice is defensively copied; callers' modifications to their input slice won't affect the constructed type.
Panics on duplicate field names within Fields (anonymous fields with Name="" are exempt — they're disambiguated by Ordinal). Java errors at the same point with SemanticException; Go panics so callers get an immediate stack trace.
func OrdinalSeedLegWindows ¶
func OrdinalSeedLegWindows(rc *RecordConstructorValue) (map[string]OrdinalSeedLegWindow, *RecordType)
OrdinalSeedLegWindows derives per-leg windows (UPPER alias → window, in a map) plus the merged row's RecordType from a gated ordinal seed RC. TWO shapes are accepted (decline-not-panic — nil windows for anything else: anchored, translated/fused, folded, S3 positional-merge):
- PRISTINE (fully-baked AS+AT, or the 2+1 join seed): EVERY field a single-accessor frontier-pinned bake over a leg QOV, consecutive full-coverage runs (AssertOrdinalJoinSeed's shape).
- MIXED single-source lateral-unnest (W4c no-AT): a full baked OUTER leg run followed by EXACTLY ONE trailing bare-QuantifiedObjectValue element over a NON-record type (Java's isPrimitive() whole-object scalar element, which cannot be ofOrdinal-baked). Its OWN 1-field leg window is synthesized so `<AS>.<AS>` resolves positionally — the element and the outer each carry their own ALIAS.COL namespace, which is what stops a name shared by the element AS alias and an outer column from mis-resolving.
This MUST agree bit-for-bit with the executor's ordinalJoinSpans/ unnestMixedSeedSpans (the cross-agreement invariant — independent walks drift, and layout drift is wrong-offset wrong-rows; pinned by a fixture).
The merged type's field names are the seed's OUTPUT names in order (the element name uppercased to match the executor); duplicates SURVIVE (positional access).
func (*RecordType) Code ¶
func (*RecordType) Code() TypeCode
Code implements Type — always TypeCodeRecord.
func (*RecordType) Equals ¶
func (r *RecordType) Equals(other Type) bool
Equals implements Type. Structural — name + nullable + element- wise field equality.
func (*RecordType) FieldIndex ¶
func (r *RecordType) FieldIndex(name string) (int, bool)
FieldIndex returns the SLICE POSITION of the field named `name` plus a found flag. This is the field's sound ordinal — mirroring Java's ordinal, which Type.Record.computeFieldNameToOrdinal builds as the field's LIST POSITION (IntStream.range + identity), not the protobuf fieldIndex. Unlike reading a stored Field.Ordinal, position is correct even for a raw RecordType that was built without NewRecordType's normalization (RFC-173 P1 review). Empty name never matches (anonymous fields aren't addressable by name).
func (*RecordType) GetField ¶
func (r *RecordType) GetField(ordinal int) (Field, bool)
GetField returns the field at the given ordinal plus a found flag. Negative or out-of-range ordinals return (Field{}, false).
func (*RecordType) LookupField ¶
func (r *RecordType) LookupField(name string) (Field, bool)
LookupField returns the named field plus a found flag. Empty name always returns (Field{}, false) — anonymous fields aren't addressable by name.
func (*RecordType) String ¶
func (r *RecordType) String() string
String implements Type. Renders as `[name] RECORD<f1 INT, f2 STRING NULL> [NOT NULL | NULL]`.
type RecordTypeLeg ¶
type RecordTypeLeg struct {
Name string // UPPER binding of the source
Start int // its first slot within the carrying type
Width int // its column count
}
RecordTypeLeg is one buried source's boundary within a clustered box leg's flat ordinal concat (see RecordType.Legs).
type RecordTypeValue ¶
type RecordTypeValue struct {
Child Value
}
RecordTypeValue extracts the record-type discriminator from a record. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RecordTypeValue`.
Used by:
- Type filters (TypeFilterExpression's predicate equivalent at the Value layer): `recordType(record) IN ('OrderHistory', 'Order')` is rewritten to a TypeFilter scan.
- Index-pushdown rules that select an index based on which record types the planner can serve via that index.
The child Value must evaluate to a record-shaped object that carries a "_recordType" or similar discriminator field. Java gets the type-key from the FDBRecordStore's metadata; Go extracts via map lookup for "_recordType" — the convention used by the Go embedded engine's row-shape.
Type is non-null long (the record-type discriminator is an implicit int64 in Java; record-type names map to integer IDs). In practice Go accepts either string or int64 returns.
func NewRecordTypeValue ¶
func NewRecordTypeValue(child Value) *RecordTypeValue
NewRecordTypeValue constructs the extractor.
func (*RecordTypeValue) Children ¶
func (v *RecordTypeValue) Children() []Value
Children returns the single child.
func (*RecordTypeValue) Evaluate ¶
func (v *RecordTypeValue) Evaluate(evalCtx any) (any, error)
Evaluate extracts the record-type discriminator. Looks up the "_recordType" key in the row map; returns nil if not present.
Other row shapes (proto messages, structs) require dedicated extractors per shape — wired when execution lands.
func (*RecordTypeValue) Name ¶
func (*RecordTypeValue) Name() string
Name returns the debug-print kind.
func (*RecordTypeValue) Type ¶
func (*RecordTypeValue) Type() Type
Type returns NotNullLong — the record-type discriminator is always present on a valid record.
type RegularTranslationMap ¶
type RegularTranslationMap struct {
// contains filtered or unexported fields
}
RegularTranslationMap is the immutable map-backed implementation (RegularTranslationMap.java:42-140). Build via NewTranslationMapBuilder.
func (*RegularTranslationMap) ApplyTranslationFunction ¶
func (t *RegularTranslationMap) ApplyTranslationFunction(sourceAlias CorrelationIdentifier, leafValue Value) Value
func (*RegularTranslationMap) ContainsSourceAlias ¶
func (t *RegularTranslationMap) ContainsSourceAlias(alias CorrelationIdentifier) bool
func (*RegularTranslationMap) DefinesOnlyIdentities ¶
func (t *RegularTranslationMap) DefinesOnlyIdentities() bool
type RelationType ¶
type RelationType struct {
// InnerType is the row type. nil for erased relations.
InnerType Type
}
RelationType is the type of a stream of rows — typically the result of SELECT, the materialised value of a CTE, or the type of a subquery. Mirrors Java's `Type.Relation`.
Always non-nullable: a relation is always defined as a stream of rows, even if that stream happens to be empty. NULL relations don't exist in the type system. WithNullability(true) on a RelationType panics.
InnerType is the type of each row in the stream — typically a RecordType. nil InnerType means "erased" — Java treats this as "the inner type was once known but has been intentionally dropped" (e.g. when crossing an API boundary that doesn't preserve it). Two erased relations compare equal regardless of what their inner types USED to be.
func NewRelationType ¶
func NewRelationType(inner Type) *RelationType
NewRelationType constructs a RelationType with the given inner row type. nil inner is allowed and produces an erased relation.
func (*RelationType) Code ¶
func (*RelationType) Code() TypeCode
Code implements Type — always TypeCodeRelation.
func (*RelationType) Equals ¶
func (r *RelationType) Equals(other Type) bool
Equals implements Type. Two RelationTypes are equal iff their inner types are structurally equal (or both erased).
func (*RelationType) IsErased ¶
func (r *RelationType) IsErased() bool
IsErased reports whether the relation has no concrete inner row type. Mirrors Java's Type.Erasable.isErased().
func (*RelationType) IsNullable ¶
func (*RelationType) IsNullable() bool
IsNullable implements Type — always false. RELATION is never nullable per Java's contract.
func (*RelationType) String ¶
func (r *RelationType) String() string
String implements Type. Renders as `RELATION<inner>` for typed relations and `RELATION<?>` for erased ones.
type ResolvedAccessor ¶
type ResolvedAccessor struct {
// Field is the PER-STEP display name (Java ResolvedAccessor.getField();
// "" = pure ordinal access, Java's null name). NOT part of the path's
// identity — the S3-W3 flip landed Java's ordinal-only element equality
// (FieldValue.java:675-689); the name survives for the coexistence
// window's name-model reads (descendResolvedPath map descent,
// nameReadRootKey, the §5 oracle) and Explain rendering, and dies with
// them in S4.
Field string
Ordinal int
}
ResolvedAccessor is the construction-time-resolved accessor a BAKED FieldValue carries — Java's FieldValue.ResolvedAccessor (FieldValue.java:~630), whose equals/hashCode are ordinal-only. Deliberately minimal for Slice 2's 2-way wedge (a single ordinal); Slice 3 widens it to a multi-accessor path (Java's FieldPath + the compose rule) when nested/buried ordinal paths land.
IMMUTABLE after construction: FieldValue copy sites deliberately SHARE the pointer (withChildren, the pullup/pushdown passthrough copies). Any future change to the accessor — including Slice 3's path widening — must REPLACE it with a new value, never mutate in place, or every shared copy silently changes identity (review convention pin).
type RowEvalContext ¶
type RowEvalContext struct {
Datum map[string]any
// Positional is the RFC-173 Slice 1 authoritative ordinal-model row for the
// non-join frontier. When non-nil, FieldValue resolution goes through the
// ordinal path (resolveOrdinal / GetByName against the row's own type) BEFORE
// the name-keyed Datum — a loud OrdinalResolutionError on a miss, NO name-map
// fallback (RFC-173). It is the single frontier quantifier's row: an outer
// correlation still resolves via Correlations first, and only an unbound
// (frontier) quantifier reference falls through to this row.
Positional OrdinalRow
Binder ParameterBinder
Correlations CorrelationBinder
ScalarSubqueries map[CorrelationIdentifier]any // pre-evaluated scalar subquery results
// Strict turns a local field-reference miss (a top-level FieldValue whose
// name is absent from Datum) from a silent nil into a reported violation
// via ReportUnresolvedReference. It is set ONLY when evaluating against a
// row whose key set is complete — i.e. a computed/synthetic row (aggregate
// output, projection, join-merge) that has no proto-style optional-field
// omissions, where an absent name is unambiguously an unresolved reference
// rather than a legitimate SQL NULL. Base-record rows (which legitimately
// omit unset optional fields) leave this false. See RFC-048 W1.
Strict bool
}
RowEvalContext is a composite evaluation context for Value.Evaluate that satisfies FieldValue (datum map), ParameterValue (ParameterBinder), and CorrelationBinder. Pass this when evaluating expressions that mix field references, prepared-statement parameters, and correlation bindings (e.g. InJoin explode aliases).
func (*RowEvalContext) BindParameter ¶
func (r *RowEvalContext) BindParameter(ordinal int, name string) (any, bool)
func (*RowEvalContext) GetCorrelationBinding ¶
func (r *RowEvalContext) GetCorrelationBinding(id CorrelationIdentifier) (any, bool)
type RowNumberHighOrderValue ¶
RowNumberHighOrderValue is a partially-applied ROW_NUMBER() window function — a curried form that carries the optional HNSW configuration parameters (EfSearch + IsReturningVectors) ahead of the actual partition + argument values. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RowNumberHighOrderValue`.
Usage flow (matches Java's higher-order resolution):
- Parser encounters `ROW_NUMBER(ef_search: 100)` — this constructs a RowNumberHighOrderValue with the configuration baked in, but no partition or argument values yet.
- Higher-order Apply receives the partition + argument values (typically the OVER clause's PARTITION BY + ORDER BY columns).
- Apply produces a fully-configured RowNumberValue with all four pieces (partition, argument, ef_search, is_returning_vectors).
The high-order pattern lets configuration parameters be specified separately from the window specification — Java's `OPTIONS` clause supports `ROW_NUMBER(ef_search: 100) OVER (PARTITION BY ...)`.
LEAF Value: takes no children. The carried HNSW configuration is not Value-typed — it's static metadata.
Eval is a placeholder — the real Apply path lands when the parser + higher-order resolution machinery is in place. RowNumberHighOrderValue itself never produces row-numbered output; it produces a RowNumberValue when applied.
func NewRowNumberHighOrderValue ¶
func NewRowNumberHighOrderValue(efSearch *int, isReturningVectors *bool) *RowNumberHighOrderValue
NewRowNumberHighOrderValue constructs the curried form. Both configuration parameters are optional — nil means "use HNSW index defaults".
func (*RowNumberHighOrderValue) Apply ¶
func (h *RowNumberHighOrderValue) Apply(partitioningValues, argumentValues []Value) *RowNumberValue
Apply produces a fully-configured RowNumberValue from this curried form by attaching the partition + argument values.
The Java equivalent is `evalWithoutStore` returning a BuiltInFunction that, when called with partition+argument arguments, allocates the final RowNumberValue. Go expresses this directly with a method.
Configuration carries through verbatim — EfSearch + IsReturningVectors land in the resulting RowNumberValue's HNSW knobs.
func (*RowNumberHighOrderValue) Children ¶
func (*RowNumberHighOrderValue) Children() []Value
Children returns the empty slice — leaf Value.
func (*RowNumberHighOrderValue) Evaluate ¶
func (*RowNumberHighOrderValue) Evaluate(any) (any, error)
Evaluate is a placeholder — high-order values don't have a per-row eval. The Apply path lands when the higher-order resolution machinery wires in.
func (*RowNumberHighOrderValue) Name ¶
func (*RowNumberHighOrderValue) Name() string
Name returns the canonical higher-order function name.
func (*RowNumberHighOrderValue) Type ¶
func (*RowNumberHighOrderValue) Type() Type
Type returns UnknownType — high-order values don't have a direct runtime type until applied. Java's getResultType() inherits from the high-order superclass which doesn't pin a type.
type RowNumberValue ¶
type RowNumberValue struct {
WindowedValue
EfSearch *int // optional HNSW ef_search override
IsReturningVectors *bool // optional HNSW vector-payload toggle
}
RowNumberValue is the SQL ROW_NUMBER() window function — assigns a UNIQUE 1-based sequential number within each partition (no tie-sharing — distinct from RANK whose ties share a number). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RowNumberValue`.
Per Java's contract, ROW_NUMBER is INDEX-ONLY (Java's class implements Value.IndexOnlyValue): the row number can only be produced during an HNSW index traversal — typically when the surrounding query is `ORDER BY <distance>` over a vector index. The query planner refuses to compute ROW_NUMBER without a suitable index. Go records this constraint in IsIndexOnly() (the analyzer / matchers can read it without importing a separate Value.IndexOnlyValue marker interface).
HNSW configuration parameters (from Java's `OPTIONS` clause):
- EfSearch: HNSW search-quality knob — higher values increase recall (accuracy) at the cost of performance. nil = use the index's default `ef_search`.
- IsReturningVectors: whether the index scan returns the actual vector payloads (true) or only distance + ID (false / nil = omit vectors, smaller transfer).
Both are optional pointers so a missing OPTION in the SQL surface remains representable as nil rather than a sentinel value.
Per the Java doc, ROW_NUMBER over distance(<vector>, queryVec) followed by `<= K` is the K-NN search pattern that gets transformed into a DistanceRankValueComparison + matched against HNSW indexes. Go implements that transform in predicates/distance_rank_transform.go (the port of Java's RowNumberValue.transformComparisonMaybe), with Java's four metric-specific classes unified into DistanceRowNumberValue (value_distance_row_number.go). This bare RowNumberValue is the PRE-transform shape the parser constructs.
Result type: NotNullLong (ROW_NUMBER is always populated, 1-based).
func NewRowNumberValue ¶
func NewRowNumberValue(partitioningValues, argumentValues []Value, efSearch *int, isReturningVectors *bool) *RowNumberValue
NewRowNumberValue constructs a ROW_NUMBER() value. partitioning values + argument values follow the Java contract (Java's argumentValues for the index-tied form is the distance argument list; bare ROW_NUMBER() takes empty arguments).
func (*RowNumberValue) Evaluate ¶
func (*RowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern. The harness exposes the streaming-window operator's per-row row-number counter via the `_row_number` key.
Returns nil if evalCtx is nil / non-map / has no `_row_number` key — matches the placeholder-Value pattern.
func (*RowNumberValue) IsIndexOnly ¶
func (*RowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — ROW_NUMBER cannot be computed outside of an index scan (the row-number value is computed during the index's search-graph traversal, not from the base record). Java's equivalent is the IndexOnlyValue marker interface; Go uses an accessor.
Planner / matcher code should consult IsIndexOnly to refuse to optimise ROW_NUMBER paths that don't have a matching index available — Java's MatchCandidate-side validation does the same.
func (*RowNumberValue) Name ¶
func (*RowNumberValue) Name() string
Name returns the SQL function name.
func (*RowNumberValue) Type ¶
func (*RowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated.
func (*RowNumberValue) WithChildren ¶
func (r *RowNumberValue) WithChildren(newChildren []Value) *RowNumberValue
WithChildren returns a new RowNumberValue with the children re-split via WindowedValue.SplitNewChildren. Both partition + arg lists are reconstructed; the HNSW config carries through unchanged.
type ScalarFunctionValue ¶
ScalarFunctionValue is a row-scalar function call — `UPPER(name)`, `LENGTH(str)`, etc. Args carries the evaluated sub-Values; Name is the canonical (UPPER-CASE) function identifier as it appears in the catalog. Children returns Args so IsConstantValue / WalkValue recurse normally — `UPPER('foo')` is a constant composite and folds via EvaluateConstant; `UPPER(name)` is non-constant because the FieldValue arg is non-constant.
The supported family is the one gated by IsCascadesSafeScalarFunction (string, math, date-part, bit, and null/comparison helpers); the runtime semantics live in evalScalarFunction, the single dispatch seam a future production registry can replace without touching the Value contract.
func NewScalarFunctionValue ¶
func NewScalarFunctionValue(name string, typ Type, args ...Value) *ScalarFunctionValue
NewScalarFunctionValue builds a ScalarFunctionValue. The function name is upper-cased so callers can pass case-insensitive identifiers.
func (*ScalarFunctionValue) Children ¶
func (s *ScalarFunctionValue) Children() []Value
func (*ScalarFunctionValue) Evaluate ¶
func (s *ScalarFunctionValue) Evaluate(evalCtx any) (any, error)
func (*ScalarFunctionValue) Name ¶
func (*ScalarFunctionValue) Name() string
func (*ScalarFunctionValue) Type ¶
func (s *ScalarFunctionValue) Type() Type
Type returns the scalar function's rich result Type. Most scalar functions can return NULL on NULL input — the result is forced to nullable regardless of how the caller stored Typ.
type ScalarSubqueryValue ¶
type ScalarSubqueryValue struct {
Alias CorrelationIdentifier
}
ScalarSubqueryValue represents a scalar subquery expression `(SELECT MAX(v) FROM t2)` in the value tree. The Alias field is the correlation identifier for the inner plan — the executor pre-runs the inner plan and binds its single scalar result under this alias in the evaluation context. Evaluate reads it back.
SQL standard semantics:
- Exactly one column (else 42601 syntax error)
- At most one row (else 21000 cardinality violation)
- Zero rows → NULL
Uncorrelated only — correlated scalar subqueries would require per-row re-execution (not in scope).
func NewScalarSubqueryValue ¶
func NewScalarSubqueryValue(alias CorrelationIdentifier) *ScalarSubqueryValue
func (*ScalarSubqueryValue) Children ¶
func (*ScalarSubqueryValue) Children() []Value
func (*ScalarSubqueryValue) Evaluate ¶
func (v *ScalarSubqueryValue) Evaluate(evalCtx any) (any, error)
Evaluate retrieves the pre-computed scalar subquery result from the evaluation context. The executor stores scalar subquery results under a dedicated ScalarSubqueryBinding key.
func (*ScalarSubqueryValue) GetCorrelatedTo ¶
func (v *ScalarSubqueryValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the alias so the planner knows this value depends on the scalar subquery's quantifier.
func (*ScalarSubqueryValue) Name ¶
func (*ScalarSubqueryValue) Name() string
func (*ScalarSubqueryValue) Type ¶
func (*ScalarSubqueryValue) Type() Type
type ScalarTypeMismatchError ¶
type ScalarTypeMismatchError struct {
Message string
}
ScalarTypeMismatchError is returned by scalar functions (GREATEST, LEAST) when arguments have incompatible types. The executor converts this to SQLSTATE 22000 DATA_EXCEPTION.
func (*ScalarTypeMismatchError) Error ¶
func (e *ScalarTypeMismatchError) Error() string
type SelfEqualsWithoutChildren ¶
SelfEqualsWithoutChildren lets a Value implement its own structural node-equality — the analogue of Java's per-type Value.equalsWithoutChildren. EqualsWithoutChildren's type switch can only enumerate Value implementations defined in THIS package; a Value defined elsewhere (e.g. expr.predicateValue, which would create an import cycle if referenced here) MUST implement this so the Cascades matcher can compare it instead of hitting the unhandled-type panic. Children() is still walked by ValuesStructurallyEqual, so a leaf Value (Children() empty) returns its full node identity here.
type SelfSemanticHash ¶
type SelfSemanticHash interface {
SemanticHashDiscriminator() uint64
}
SelfSemanticHash lets a Value implemented outside this package contribute its own discriminator to the semantic hash — the hash analog of SelfEqualsWithoutChildren (a type the writeSemanticHash switch can't reach would otherwise collide into the bare Name() bucket). The returned value MUST be derived from the same non-child attributes EqualsWithoutChildrenValue compares (and be alias-free), so the equal⟹same-hash memo invariant holds.
type SelfWithChildren ¶
SelfWithChildren lets a Value defined outside this package reconstruct itself with new children, so values.WithChildren (and Replace/RebaseValue, which build new trees bottom-up) can rewrite it without this package's type switch enumerating it. The WithChildren analogue of SelfEqualsWithoutChildren and SelfSemanticHash. The newChildren slice has the same length and order as the value's Children().
type StreamingValue ¶
StreamingValue extends Value with streaming evaluation. Mirrors Java's StreamingValue interface — Values that can produce a stream of elements rather than a single scalar result.
type StrictRankLimitValue ¶
type StrictRankLimitValue struct {
K Value
}
StrictRankLimitValue computes the row cap of a STRICT distance-rank predicate `ROW_NUMBER() OVER (ORDER BY distance(...)) < K` whose K is a RUNTIME value (a bound parameter — RFC-156 parameterized vector rank limit). The number of admitted rows is max(0, K-1).
It exists so the runtime LIMIT that bounds an ordered vector stream never expresses the strict adjustment with general CHECKED subtraction. `K - 1` underflows at K = math.MinInt64 (the ONLY K where it can), which an ArithmeticValue surfaces as an ArithmeticOverflowError — aborting a query that semantically selects NO rows (ROW_NUMBER() ≥ 1 is never < a K ≤ 1). This value mirrors the executor's scan-side rank-cap guard exactly: K ≤ 1 ⇒ 0 (computed WITHOUT subtracting, so K = math.MinInt64 cannot wrap K-1 to a huge positive), else K - 1 (K ≥ 2 ⇒ no underflow). NULL K propagates.
func (*StrictRankLimitValue) Children ¶
func (v *StrictRankLimitValue) Children() []Value
func (*StrictRankLimitValue) EqualsWithoutChildrenValue ¶
func (v *StrictRankLimitValue) EqualsWithoutChildrenValue(other Value) bool
EqualsWithoutChildrenValue: the node has no own attributes beyond its child K (compared separately by ValuesStructurallyEqual's recursion), so two strict rank caps are node-equal iff they are the same concrete type.
func (*StrictRankLimitValue) Evaluate ¶
func (v *StrictRankLimitValue) Evaluate(evalCtx any) (any, error)
func (*StrictRankLimitValue) Name ¶
func (v *StrictRankLimitValue) Name() string
func (*StrictRankLimitValue) Type ¶
func (v *StrictRankLimitValue) Type() Type
func (*StrictRankLimitValue) WithChildren ¶
func (v *StrictRankLimitValue) WithChildren(newChildren []Value) Value
WithChildren rebuilds the node around a rebased K so RebaseValue's generic recursion never drops a correlated K (a bound-parameter ConstantObjectValue).
type SubscriptValue ¶
type SubscriptValue struct {
Source Value
Index Value
// Typ is the bound element type. Defaults to UnknownType.
Typ Type
}
SubscriptValue is the Value-layer SQL array subscript: yields the element of `Source` at `Index`. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.SubscriptValue`.
arr[1] ↔ SubscriptValue{Source: arr, Index: 1}
CONFORMANCE: Index is 1-BASED per SQL standard (Foundation Section 4.10.2). Java's eval explicitly says: "If n is the cardinality of A, then the ordinal position p of an element is an integer in the range 1 ≤ p ≤ n."
Out-of-bounds Index returns NULL (UNKNOWN) — Java DOES NOT raise an out-of-bound error, matches SQL semantics.
NULL propagation: NULL Index OR NULL Source → NULL result.
func NewSubscriptValue ¶
func NewSubscriptValue(source, index Value, resultType Type) *SubscriptValue
NewSubscriptValue constructs the subscript Value with the given source array Value, index Value, and result Type.
func (*SubscriptValue) Children ¶
func (v *SubscriptValue) Children() []Value
Children returns [Source, Index].
func (*SubscriptValue) Evaluate ¶
func (v *SubscriptValue) Evaluate(evalCtx any) (any, error)
Evaluate returns Source[Index-1] (1-based per SQL standard).
Returns nil (UNKNOWN) if:
- Source or Index is nil-Value or evaluates to nil
- Source doesn't evaluate to a slice ([]any)
- Index isn't an integer kind
- Index is out of bounds
func (*SubscriptValue) Name ¶
func (*SubscriptValue) Name() string
Name returns the debug-print kind.
func (*SubscriptValue) Type ¶
func (v *SubscriptValue) Type() Type
Type returns the bound element type.
type ThrowsValue ¶
type ThrowsValue struct {
ResultType Type
}
ThrowsValue is a leaf Value that panics if evaluated. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. ThrowsValue`.
Used by the planner for "this code path should be unreachable" markers — a Value placeholder that signals a dead branch in the plan tree. If a planner bug causes the dead branch to actually execute, the panic surfaces immediately rather than silently returning nil.
Type is whatever the planner wants the placeholder to advertise (so type-checking passes through the dead branch).
func NewThrowsValue ¶
func NewThrowsValue(resultType Type) *ThrowsValue
NewThrowsValue constructs the placeholder with the given Type.
func (*ThrowsValue) Children ¶
func (*ThrowsValue) Children() []Value
Children returns the empty slice — leaf.
type ToOrderedBytesValue ¶
type ToOrderedBytesValue struct {
Child Value
Direction OrderedBytesDirection
}
ToOrderedBytesValue encodes its child Value's evaluation as a FoundationDB-compatible ordered-bytes blob suitable for use as part of an index key. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ToOrderedBytesValue`.
Used by index-key construction: the planner lowers a SQL ORDER-BY-expression-as-index-prefix to a chain of ToOrderedBytes applications — each column's ordering direction baked into the produced bytes so a forward FDB scan over the index produces rows in the requested SQL order.
Java's eval calls `TupleOrdering.pack(Key.Evaluated.scalar(child), direction)` — packs the child as a 1-element FDB tuple, then applies direction-aware encoding (DESC inverts bits / reverses NULL placement). Go's direction-aware encoding exists on the index side (pkg/recordlayer/order_function_key_expression.go) but is NOT wired into this Value's Evaluate — eval returns nil per the non-evaluable placeholder pattern shared with VersionValue / IncarnationValue / ObjectValue.
Result type: NotNullBytes. Even when the child is NULL, the encoding produces a sentinel byte sequence, so the byte output is always populated.
func NewToOrderedBytesValue ¶
func NewToOrderedBytesValue(child Value, direction OrderedBytesDirection) *ToOrderedBytesValue
NewToOrderedBytesValue constructs the encoder.
func (*ToOrderedBytesValue) Children ¶
func (v *ToOrderedBytesValue) Children() []Value
Children returns the single child Value.
func (*ToOrderedBytesValue) CreateInverse ¶
func (v *ToOrderedBytesValue) CreateInverse(newChild Value, originalType Type) *FromOrderedBytesValue
CreateInverse returns the FromOrderedBytesValue that decodes the ordered-bytes form back to the original value. Java's createInverseValueMaybe always returns Optional.of — the encoding is always invertible. We expose the inverse as a method for matchers / rules that need to canonicalise To→From chains.
Per Java's signature, the inverse takes a NEW child (the ordered-bytes input the inverse decodes) and the ORIGINAL child's result type (so the inverse knows what type to decode to).
func (*ToOrderedBytesValue) Evaluate ¶
func (*ToOrderedBytesValue) Evaluate(any) (any, error)
Evaluate is currently a placeholder — returns nil. Real eval wires tuple.PackOrdered (the Go equivalent of Java's TupleOrdering.pack). The Value-shape is reachable for planner / matcher / serialisation work today; runtime integration lands when index-key-construction port reaches this branch.
func (*ToOrderedBytesValue) Name ¶
func (*ToOrderedBytesValue) Name() string
Name returns the SQL function name.
func (*ToOrderedBytesValue) Type ¶
func (*ToOrderedBytesValue) Type() Type
Type returns NotNullBytes — the encoder produces bytes regardless of input.
type TranslationFunction ¶
type TranslationFunction func(sourceAlias CorrelationIdentifier, leafValue Value) Value
TranslationFunction rewrites one correlation-bearing LEAF value bound to sourceAlias into its replacement — Java's TranslationMap.TranslationFunction (TranslationMap.java:79-98). The function owns the replacement's SHAPE (plain ofOrdinalNumber in the merge case — composition with enclosing references is the rebuild's job, never the function's).
type TranslationMap ¶
type TranslationMap interface {
ContainsSourceAlias(alias CorrelationIdentifier) bool
ApplyTranslationFunction(sourceAlias CorrelationIdentifier, leafValue Value) Value
// DefinesOnlyIdentities reports that applying the map is a no-op —
// TranslateCorrelations returns its input unchanged (pointer-stable).
DefinesOnlyIdentities() bool
}
TranslationMap is Java's TranslationMap interface: alias membership, per-leaf application, and the identity early-out.
type TranslationMapBuilder ¶
type TranslationMapBuilder struct {
// contains filtered or unexported fields
}
TranslationMapBuilder accumulates alias→function entries — RegularTranslationMap.Builder (RegularTranslationMap.java:145-228). Usage: NewTranslationMapBuilder().When(a).Then(fn).When(b).Then(fn2).Build().
func NewTranslationMapBuilder ¶
func NewTranslationMapBuilder() *TranslationMapBuilder
func (*TranslationMapBuilder) Build ¶
func (b *TranslationMapBuilder) Build() TranslationMap
Build snapshots the accumulated entries — the returned map is IMMUTABLE (Java's ImmutableMap.copyOf): further builder use cannot mutate a map already handed out (review catch: sharing b.fns let a built empty map stop defining only identities when the builder was reused).
func (*TranslationMapBuilder) When ¶
func (b *TranslationMapBuilder) When(alias CorrelationIdentifier) *TranslationMapWhen
type TranslationMapWhen ¶
type TranslationMapWhen struct {
// contains filtered or unexported fields
}
TranslationMapWhen is the intermediate of the .When(alias).Then(fn) pair.
func (*TranslationMapWhen) Then ¶
func (w *TranslationMapWhen) Then(fn TranslationFunction) *TranslationMapBuilder
Then registers the function for the pending alias. A duplicate alias is a caller bug — Java Verifies against it (RegularTranslationMap.java:204); loud here too, a silent overwrite would drop a rebase.
type TupleSource ¶
type TupleSource int
TupleSource enumerates the two tuple-bearing fields of an FDB IndexEntry — the index KEY (primary scan tuple) or the index VALUE (associated payload tuple). Mirrors Java's `IndexKeyValueToPartialRecord.TupleSource`.
const ( // TupleSourceKey selects the index entry's KEY tuple. TupleSourceKey TupleSource = iota // TupleSourceValue selects the index entry's VALUE tuple. TupleSourceValue // TupleSourceOther is the fallback used when an index entry has // neither KEY nor VALUE semantics for a given column (e.g. // extracting a deferred-fetch field from a non-covering index). TupleSourceOther )
func (TupleSource) String ¶
func (s TupleSource) String() string
String renders the tuple source for explain / debug print.
type Type ¶
type Type interface {
// Code returns this type's TypeCode.
Code() TypeCode
// IsNullable reports whether the type allows NULL values. SQL
// columns default to nullable; PRIMARY KEY columns and explicit
// NOT NULL columns are non-nullable.
IsNullable() bool
// Equals reports structural equality with other. Implementations
// MUST compare Code + Nullable AT MINIMUM; structured types
// extend the contract to compare child fields / element types.
Equals(other Type) bool
// String renders the type in SQL-ish form ("INT NOT NULL",
// "STRING NULL"). Used by EXPLAIN output.
String() string
}
Type is the rich type-system handle replacing ValueType. Carries the type code plus nullability; concrete impls add structure (RecordType.Fields, ArrayType.Element, …) as the port lands them.
Equals tests structural equality — two distinct PrimitiveType instances with the same Code + Nullable are equal. Pointer- equality is NOT a substitute (the helper constants below exist precisely so callers can share a canonical pointer per (code, nullable) pair when they need to).
var ( // NullableInt is INT NULL — INT column with no NOT NULL constraint. NullableInt Type = &PrimitiveType{TypeCode: TypeCodeInt, Nullable: true} // NotNullInt is INT NOT NULL — typical PRIMARY KEY column shape. NotNullInt Type = &PrimitiveType{TypeCode: TypeCodeInt, Nullable: false} // NullableLong is LONG NULL (BIGINT default). NullableLong Type = &PrimitiveType{TypeCode: TypeCodeLong, Nullable: true} // NotNullLong is LONG NOT NULL. NotNullLong Type = &PrimitiveType{TypeCode: TypeCodeLong, Nullable: false} // NullableFloat is FLOAT NULL. NullableFloat Type = &PrimitiveType{TypeCode: TypeCodeFloat, Nullable: true} // NotNullFloat is FLOAT NOT NULL. NotNullFloat Type = &PrimitiveType{TypeCode: TypeCodeFloat, Nullable: false} // NullableDouble is DOUBLE NULL. NullableDouble Type = &PrimitiveType{TypeCode: TypeCodeDouble, Nullable: true} // NotNullDouble is DOUBLE NOT NULL. NotNullDouble Type = &PrimitiveType{TypeCode: TypeCodeDouble, Nullable: false} // NullableString is STRING NULL (VARCHAR default). NullableString Type = &PrimitiveType{TypeCode: TypeCodeString, Nullable: true} // NotNullString is STRING NOT NULL. NotNullString Type = &PrimitiveType{TypeCode: TypeCodeString, Nullable: false} // NullableBoolean is BOOLEAN NULL. NullableBoolean Type = &PrimitiveType{TypeCode: TypeCodeBoolean, Nullable: true} // NotNullBoolean is BOOLEAN NOT NULL. NotNullBoolean Type = &PrimitiveType{TypeCode: TypeCodeBoolean, Nullable: false} // NullableBytes is BYTES NULL. NullableBytes Type = &PrimitiveType{TypeCode: TypeCodeBytes, Nullable: true} // NotNullBytes is BYTES NOT NULL. NotNullBytes Type = &PrimitiveType{TypeCode: TypeCodeBytes, Nullable: false} // NullableUuid is UUID NULL — 16-byte primitive, NOT a structured // type in fdb-relational's grammar (RelationalParser.g4 lists UUID // among primitiveType siblings). NullableUuid Type = &PrimitiveType{TypeCode: TypeCodeUuid, Nullable: true} // NotNullUuid is UUID NOT NULL. NotNullUuid Type = &PrimitiveType{TypeCode: TypeCodeUuid, Nullable: false} // NullableVersion is VERSION NULL — fdb-record-layer's 12-byte // FDBRecordVersion (10-byte global versionstamp + 2-byte local). NullableVersion Type = &PrimitiveType{TypeCode: TypeCodeVersion, Nullable: true} // NotNullVersion is VERSION NOT NULL. NotNullVersion Type = &PrimitiveType{TypeCode: TypeCodeVersion, Nullable: false} // NullableDate is DATE NULL. NullableDate Type = &PrimitiveType{TypeCode: TypeCodeDate, Nullable: true} // NotNullDate is DATE NOT NULL. NotNullDate Type = &PrimitiveType{TypeCode: TypeCodeDate, Nullable: false} // NullableTimestamp is TIMESTAMP NULL. NullableTimestamp Type = &PrimitiveType{TypeCode: TypeCodeTimestamp, Nullable: true} // NotNullTimestamp is TIMESTAMP NOT NULL. NotNullTimestamp Type = &PrimitiveType{TypeCode: TypeCodeTimestamp, Nullable: false} // NullType is the type of the NULL literal — always nullable // (a NULL is by definition not a value of a specific type, but // can be assigned to any nullable column). Distinct from // UnknownType: NULL has a concrete code, UNKNOWN doesn't. NullType Type = &PrimitiveType{TypeCode: TypeCodeNull, Nullable: true} // UnknownType is the placeholder for "type not yet inferred" — // used by Value impls that don't yet have a real type computed. UnknownType Type = &PrimitiveType{TypeCode: TypeCodeUnknown, Nullable: true} // NoneType is the type of the untyped empty array literal `[]`. // Identity-promotes to any ARRAY type without changing // nullability — when an empty array appears in a context that // expects ARRAY<T>, NONE adopts T as its element type. // Always non-nullable. Mirrors Java's `Type.NONE`. NoneType Type = &PrimitiveType{TypeCode: TypeCodeNone, Nullable: false} // AnyType is the universal supertype — every Type is assignable // to it. Used by quantifiers and pre-resolution placeholders // where a concrete type isn't known at construction. Always // nullable. Mirrors Java's `Type.ANY`. AnyType Type = &PrimitiveType{TypeCode: TypeCodeAny, Nullable: true} )
Canonical singletons for the most common (code, nullable) pairs. Callers that need to share a pointer (e.g. for fast equality checks via `==`) use these. Mirrors Java's Type.NULL / NONE / UUID_NULL_INSTANCE constants.
var ( // TypeUnknown is the placeholder for "type not yet inferred". // Maps to the canonical UnknownType singleton. TypeUnknown Type = UnknownType // TypeInt is the legacy name for the package's default integer // width — bridged to LONG (BIGINT default; matches Java Record // Layer's int64 representation). TypeInt Type = NullableLong // TypeString is the legacy name for STRING — bridged to // NullableString. TypeString Type = NullableString // TypeBool is the legacy name for BOOLEAN — bridged to // NullableBoolean. Note BooleanValue's Type() returns // NotNullBoolean (literals are NOT NULL); compare via // `.Code() != TypeCodeBoolean` when nullability is irrelevant. TypeBool Type = NullableBoolean // TypeFloat is the legacy name for the package's default float // width — bridged to DOUBLE (matches Java Record Layer's // float64 representation). TypeFloat Type = NullableDouble )
The legacy `ValueType` enum (TypeUnknown / TypeInt / TypeString / TypeBool / TypeFloat) is retired — every Value impl's Type() returns the rich Type directly. The names below remain as Type-typed vars so existing call sites (`Typ: values.TypeInt`) keep working — the value's Go type changes (Type instead of int), the constant name doesn't.
Legacy bridge retirement: RFC-025.
func ExplodeOrdinalityResultType ¶
ExplodeOrdinalityResultType builds the result type of a WITH-ORDINALITY Explode: an anonymous 2-field record (element, INT NOT NULL ordinal). Mirrors Java's `ExplodeExpression.explodeResultType(elementType, true)`.
func MaximumType ¶
MaximumType returns the smallest Type both `t1` and `t2` can be promoted to without explicit CAST, or nil if no such type exists. Used during arithmetic / comparison planning to homogenise operand types: `INT + LONG` plans as `LONG + LONG → LONG`, `FLOAT + DOUBLE` plans as `DOUBLE + DOUBLE → DOUBLE`, etc.
Nullability rule: result is nullable iff EITHER input is nullable.
NULL handling: if one side is the NULL literal type and the other is promotable, the result is the other side made nullable. Both NULL → NULL.
NONE handling: NONE is the type of the untyped empty array `[]`; it identity-promotes to any ARRAY type without changing nullability. (NOT yet implemented for arrays — primitives only for now; structured-type recursion lands with the next port.)
This is the primitive-only version. RECORD / ARRAY recursion is future work — caller should fall back to nil for compound types and let the caller decide how to handle the gap.
Mirrors Java's `Type.maximumType(t1, t2)`.
func MaximumTypeOfMany ¶
MaximumTypeOfMany folds MaximumType across all `types`. Returns nil if any pair is incompatible, or if the slice is empty. Useful for IN-list analysis (`x IN (1, 2L, 3.0)` needs the lifted type for x to compare against), CASE expressions (every WHEN's result must be promotable to a common type), and UNION column-type reconciliation.
Mirrors Java's `Type.maximumType(Iterable<Type>)`.
func WithNullability ¶
WithNullability returns a Type with the same shape as t but the given nullability. For PrimitiveType it returns one of the canonical singletons; for structured types it returns a new instance. nil t returns nil. Mirrors Java's Type.withNullability(boolean).
Used by callers that derive a Type from a parent context (e.g. "the result of LEFT JOIN's right side is the right table's row type but nullable") without having to manually clone-and-mutate.
type TypeCode ¶
type TypeCode int
TypeCode enumerates the well-known SQL types. Mirrors Java's `Type.TypeCode`; numeric values are NOT wire-stable (we don't serialise plans yet — RFC-024 punts on hash compatibility).
const ( // TypeCodeUnknown is the zero value — represents "type not yet // inferred" rather than the SQL NULL type. Distinct from // TypeCodeNull which is "the NULL literal's type". TypeCodeUnknown TypeCode = iota TypeCodeNull TypeCodeBoolean TypeCodeInt TypeCodeLong TypeCodeFloat TypeCodeDouble TypeCodeString TypeCodeBytes TypeCodeVersion TypeCodeEnum TypeCodeRecord TypeCodeArray TypeCodeRelation TypeCodeNone TypeCodeAny TypeCodeUuid TypeCodeDate TypeCodeTimestamp )
func (TypeCode) IsNumeric ¶
IsNumeric reports whether tc is one of the numeric types (arithmetic + comparison promotion targets).
func (TypeCode) IsPrimitive ¶
IsPrimitive reports whether tc names a scalar (vs structured) type. Mirrors Java's `TypeCode.isPrimitive()`. Composite shapes (RECORD, ARRAY, RELATION) and the special placeholders (UNKNOWN, ANY, NONE, FUNCTION) all return false.
type TypeRegistrationError ¶
type TypeRegistrationError struct {
// Name is the type name that triggered the error. Empty when the
// caller passed an empty name.
Name string
// Reason is a short human-readable description of what failed.
Reason string
}
TypeRegistrationError is returned by Register on validation failures. Mirrors the structured-error pattern in CLAUDE.md.
func (*TypeRegistrationError) Error ¶
func (e *TypeRegistrationError) Error() string
Error implements error.
type TypeRepository ¶
type TypeRepository struct {
// contains filtered or unexported fields
}
TypeRepository is the registry for named types. Mirrors Java's TypeRepository — a map from QName to Type used to resolve named references like `CREATE TYPE Foo AS RECORD<...>` followed by a later `... value Foo NOT NULL ...` column declaration.
Not concurrency-safe: per-query / per-statement instance, not a global. The Java equivalent is built up during semantic analysis and discarded after planning.
func NewTypeRepository ¶
func NewTypeRepository() *TypeRepository
NewTypeRepository constructs an empty TypeRepository.
func (*TypeRepository) Lookup ¶
func (r *TypeRepository) Lookup(name string) (Type, bool)
Lookup returns the registered type for name plus a found flag.
func (*TypeRepository) Names ¶
func (r *TypeRepository) Names() []string
Names returns the registered type names in insertion-undefined order. Caller-friendly for diagnostics — the slice is freshly allocated each call.
func (*TypeRepository) Register ¶
func (r *TypeRepository) Register(name string, t Type) error
Register adds a named type. Empty name returns an error (anonymous types aren't addressable). Duplicate-name registration returns an error so the caller can decide whether to treat it as a redefinition (typical CREATE TYPE Foo error) or a no-op (idempotent re-registration in tests).
func (*TypeRepository) Size ¶
func (r *TypeRepository) Size() int
Size returns the number of registered types.
type UdfValue ¶
type UdfValue struct {
// FunctionName is the user-facing UDF name (e.g. "MY_FN"). Two
// UdfValues with the same FunctionName + same arg types are
// planner-equivalent (same UDF call shape).
FunctionName string
// ResultType is the declared return type of the UDF. Java's
// equivalent comes from UdfFunction.getReturnType().
ResultType Type
// Args are the operand Values whose evaluations feed Call.
Args []Value
// Call is the UDF body — receives the evaluated argument values
// in source order, returns the UDF's result. Required: a UdfValue
// with a nil Call evaluates to nil regardless of args (matches the
// "non-evaluable yet" placeholder pattern).
Call func(args []any) any
}
UdfValue represents a user-defined function (UDF) call. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.UdfValue`.
Java's UdfValue is an ABSTRACT class — concrete UDFs subclass it, override `call(List<Object>)` to supply business logic, and pair with a UdfFunction for parameter-type description / planner registration. The Go port uses a function-typed field (`Call func(args []any) any`) instead of inheritance — the idiomatic Go shape for "subclass-supplied behaviour".
Stateless and stateful UDFs are both representable: a stateless UDF's Call is a pure function over args; a stateful UDF closes over an accumulator (the implementor's responsibility — UdfValue itself does not enforce purity).
Plan-level identity: each UDF gets a stable Name (the implementor-supplied function name) so two UdfValue calls with the same Name + same children compare semantically equal. This is the Go-side stand-in for Java's `getClass().getCanonicalName()` keying — the FQ class name uniquely identifies the UDF implementation in Java; Name does the same in Go.
Eval: walks each child Value's Evaluate, collects results into `[]any`, hands to the user-supplied Call function. Per Java, argument NULLs propagate at the user's discretion — Call is called with the raw evaluated args; the user is responsible for NULL-handling within their UDF body.
func NewUdfValue ¶
NewUdfValue constructs a UDF call.
The Call function is REQUIRED for runtime evaluation; passing nil is allowed at construction time so the planner can build UDF call shapes before the implementation is wired (e.g. during analyser phase). A nil Call surfaces nil from Evaluate per the placeholder-Value contract.
func (*UdfValue) Children ¶
Children returns the Args list — UDF arguments are the only Value children.
func (*UdfValue) Evaluate ¶
Evaluate walks each arg's Evaluate and hands the resulting `[]any` to Call. Returns nil if Call is nil (placeholder mode).
func (*UdfValue) Name ¶
Name returns the UDF function name (used for debug print + planner equivalence keying).
func (*UdfValue) WithChildren ¶
WithChildren returns a new UdfValue with the given children substituted for Args. Function name, result type, and Call body carry through unchanged.
type UnmatchedAggregateValue ¶
type UnmatchedAggregateValue struct {
UnmatchedID CorrelationIdentifier
}
UnmatchedAggregateValue is a non-evaluable marker value that stands for an aggregate expression not yet matched to a candidate during index matching. It carries a unique CorrelationIdentifier (the "unmatched ID") that links back to the original query aggregate via the GroupByMappings.unmatchedAggregatesMap.
During Compensation.Intersect, when an aggregate that was previously unmatched becomes matched (because a second index covers it), the replaceUnmatchedAggregateValues function replaces these markers with the actual translated aggregate value.
Ports Java's GroupByExpression.UnmatchedAggregateValue.
func NewUnmatchedAggregateValue ¶
func NewUnmatchedAggregateValue(id CorrelationIdentifier) *UnmatchedAggregateValue
func (*UnmatchedAggregateValue) Children ¶
func (*UnmatchedAggregateValue) Children() []Value
func (*UnmatchedAggregateValue) Evaluate ¶
func (*UnmatchedAggregateValue) Evaluate(_ any) (any, error)
func (*UnmatchedAggregateValue) GetCorrelatedTo ¶
func (v *UnmatchedAggregateValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
func (*UnmatchedAggregateValue) IsNonEvaluable ¶
func (*UnmatchedAggregateValue) IsNonEvaluable() bool
func (*UnmatchedAggregateValue) Name ¶
func (*UnmatchedAggregateValue) Name() string
func (*UnmatchedAggregateValue) Type ¶
func (*UnmatchedAggregateValue) Type() Type
type Value ¶
type Value interface {
// Children returns the immediate sub-Values of this node.
// Leaf Values return an empty slice (never nil — keeps matcher
// code free of nil checks).
Children() []Value
// Type is the rich result Type of evaluating this Value
// (the legacy ValueType enum is retired; Type() returns the
// rich Type directly). Never nil —
// implementations return UnknownType when the type genuinely
// isn't known yet.
Type() Type
// Name is a debug string for error messages + explain output.
// Not part of the matcher DSL.
Name() string
// Evaluate produces the Go-native value this Value represents
// against an eval context. Leaf ConstantValue ignores the
// context; FieldValue looks up its column; ArithmeticValue
// recurses. The context is opaque (`any`) so different
// subsystems can pass their own row shape — tests use
// `map[string]any`.
//
// Returns (value, nil) on success — (nil, nil) is SQL NULL.
// (nil, err) signals a data-dependent runtime error (arithmetic
// overflow, division by zero, invalid cast, type mismatch);
// callers propagate it instead of recovering a panic.
Evaluate(evalCtx any) (any, error)
}
Value is the root of the Value hierarchy. Concrete Values implement Children / Type / Name / Evaluate; matchers downcast via type switches / type assertions on the concrete Go type.
Java equivalent: `Value extends Correlated<Value>, TreeLike<Value>, Typed, ...`. The initial port keeps Children + Type + Name + a simple Evaluate since those are the surfaces rules touch. The `Correlated.GetCorrelatedTo` contract is declared separately (see correlation.go) and implemented by those Values that reference a Quantifier; leaf values opt out.
func DeconstructRecord ¶
DeconstructRecord flattens a record-typed Value into its constituent field Values. Mirrors Java's `Values.deconstructRecord(Value)`.
Used by planner rules that need to look at individual field expressions inside a record-shaped Value:
For a RecordConstructorValue, returns the children Values directly (one per field). Pointer-stable: if the caller wants to rewrite a single field's Value, working with the flat list and re-constructing avoids deep cloning.
For any other record-typed Value (e.g. QuantifiedRecordValue, QueriedValue, RecordTypeValue when wrapping a record), returns FieldValue accessors keyed by the field name — one per record field. The caller can substitute or simplify these individually then re-construct.
Returns nil if v is nil or its Type isn't a record. The caller is expected to check via the returned slice's length (zero = not-record OR record with zero fields, either of which is a degenerate case).
func LiteralValue ¶
LiteralValue wraps a Go-native literal in the matching Value subtype: nil → NullValue, bool → BooleanValue, otherwise a ConstantValue. Typ defaults to TypeUnknown; the simplifier does not depend on the type tag today — it inspects the wrapped Value subtype.
func MapFieldValues ¶
func MapFieldValues(v Value, transform func(*FieldValue) Value) Value
MapFieldValues recursively walks a Value tree and applies transform to every FieldValue encountered at any depth. Non-FieldValue leaf nodes are returned unchanged. Composite nodes are rebuilt with transformed children when at least one child changed.
This handles all common composite Value types by type-switching and manually reconstructing the node with updated children. Types with a WithChildren method use that; types without one are reconstructed by field. Unknown composite types fall back to returning v unchanged (conservative: won't corrupt, won't transform FieldValues nested inside an unrecognized composite).
The full type-switch ensures that nested expressions like UPPER(A.NAME), A.X + B.Y, CAST(A.COL AS INT), CASE WHEN A.X > 0 ... have their FieldValues properly transformed at any depth, unlike the old childReplacer-interface approach which only handled ~10 types.
Used by rule_push_filter_below_join.go and rule_implement_nested_loop_join.go to strip alias prefixes from FieldValues at arbitrary nesting depth.
func PullUpValue ¶
func PullUpValue(v Value, resultValue Value, alias CorrelationIdentifier) Value
PullUpValue rewrites v so that it references the output of resultValue, viewed through alias.
Ports the essential logic of Java's Value.pullUp rule set (MatchValueRule, MatchFieldValueAgainstQuantifiedObjectValueRule, MatchOrCompensateFieldValueRule, CompensateRecordConstructorRule) as a direct recursive algorithm rather than a rule-engine dispatch.
Returns nil if v cannot be expressed in terms of resultValue.
Examples (where resultValue = RecordConstructor(a=FV("x"), b=FV("y"))):
- v = FV("x") → FV("a") // input field "x" becomes output field "a"
- v = FV("y") → FV("b") // input field "y" becomes output field "b"
- v = resultValue → QOV(alias) // the whole result maps to the output alias
For non-RecordConstructor result values (e.g. a QuantifiedObjectValue passthrough), v is matched directly:
- v = resultValue → QOV(alias)
- v = FV("x"), resultValue = QOV(q) → FV("x") // field access passes through
func PushDownValue ¶
func PushDownValue(v Value, resultValue Value, upperAlias CorrelationIdentifier) Value
PushDownValue rewrites v (which references the output of resultValue) to be expressed in terms of the inputs of resultValue. This is the inverse of PullUpValue.
Examples (where resultValue = RecordConstructor(a=FV("x"), b=FV("y"))):
- v = FV("a") → FV("x") // output field "a" maps to input "x"
- v = FV("b") → FV("y") // output field "b" maps to input "y"
- v = QOV(alias) → resultValue // the whole output maps to the result
Returns nil if the push-down fails.
func PushDownValues ¶
func PushDownValues(toBePushedDown []Value, resultValue Value, upperAlias CorrelationIdentifier) []Value
PushDownValues translates a list of values through a result value, returning the pushed-down values in order. Values that cannot be pushed down are returned as nil entries.
func RebaseValue ¶
RebaseValue replaces correlation references in a value tree according to the alias map. Returns the original value if no references match.
Leaf values with correlation aliases (QuantifiedObjectValue, QuantifiedRecordValue, ScalarSubqueryValue, ObjectValue) have their alias remapped directly. All other non-leaf values (including ExistsValue, a transparent composite over a QuantifiedObjectValue) recursively rebase children and reconstruct via WithChildren — no per-type wiring needed.
Ports Java's Value.rebase(AliasMap): leaf values override rebaseLeaf(); non-leaf values use the default rebase() which recurses children and calls withChildren().
func Replace ¶
Replace applies replacementFn to every node in the Value tree rooted at v, in pre-order (parent before children). If replacementFn returns nil, the entire subtree is removed (Replace returns nil). If replacementFn returns a different Value, that Value's children are then recursed. If replacementFn returns the same Value unchanged, children are recursed and the original node is kept unless a child was replaced.
Copy-on-write: a node's children list is only allocated when at least one child was actually replaced — identical subtrees reuse the original pointers.
Matches Java's `TreeLike.replace(UnaryOperator<T>)` semantics exactly: pre-order traversal, CoW, nil-propagation.
func ReplaceLeavesMaybe ¶
ReplaceLeavesMaybe applies replaceFn only to leaf nodes (Values with no children) in pre-order. Non-leaf nodes are traversed but not passed to replaceFn. Matches Java's `TreeLike.replaceLeavesMaybe(UnaryOperator<T>)`.
Returns nil if replaceFn returns nil for any leaf.
func ReplaceLeavesOnceMaybe ¶
ReplaceLeavesOnceMaybe is Java's TreeLike.replaceLeavesMaybe(op, visitNewLeaves=false): it applies replaceFn to leaf nodes, but does NOT re-apply it to leaves INTRODUCED by a replacement. After a leaf is replaced, every leaf of the replacement subtree is recorded (by pointer identity) and skipped on the subsequent re-descent.
This is the correct semantics for SELF-REFERENTIAL substitutions — e.g. TranslationMap substituting alias B with a value that itself references B (the source-anchored join RC anchors its right-leg columns to QOV(B), while the parent quantifier over the join is ALSO aliased B). Plain Replace / ReplaceLeavesMaybe re-descend into the replacement, re-match B, and loop forever. Tracking new leaves breaks the cycle exactly as Java does.
Returns nil if replaceFn returns nil for any (original) leaf.
func SimplifyAll ¶
SimplifyAll batch-applies SimplifyValue to a list of Values. Mirrors Java's `Values.simplify(Iterable<Value>, ...)`.
Returns a fresh slice of the same length as the input. The pointer-equality short-circuit IS preserved: if no Value changed, the returned slice contains the original pointers. Callers can detect "no fold happened" via deep slice-pointer equality.
func SimplifyValue ¶
SimplifyValue is the standalone-Value counterpart to Simplify. Folds constant sub-trees in a Value (e.g. SELECT-list expressions or projection arguments that never reach a comparison and so never hit ComparisonConstantSimplifyRule).
Two-phase per node, post-order:
- Recurse into children — fold them first so partial folds work (e.g. `name + (1+2)` becomes `name + 3` in one pass).
- If the rebuilt node is fully constant per IsConstantValue, fold to a literal Value via LiteralValue (preserves the original Type so downstream type checks stay consistent).
Returns the input unchanged when nothing folds — pointer-equality stable so callers can cheaply check for "did anything happen?".
Why a free function rather than a CascadesRule: the rule framework targets QueryPredicate matchers; standalone Values have no surrounding predicate to match against. (Java models this as its ValueSimplificationRuleSet; Go's equivalent is this fold.)
Coverage: ArithmeticValue, CastValue, PromoteValue, ScalarFunctionValue, NotValue. Other composites (RecordConstructorValue, AggregateValue) are not folded — Aggregate inherently needs row context, RecordConstructor seldom appears in a fold-able position. Adding more shapes is mechanical when need arises (extend isFoldableComposite + simplifyChildren).
func SimplifyValueWithContext ¶
func SimplifyValueWithContext(v Value, ctx ValueSimplifyContext) Value
SimplifyValueWithContext applies context-aware simplification rules that SimplifyValue cannot handle. Ports Java's EliminateArithmeticValueWithConstantRule, FoldConstantRule, and LiftConstructorRule.
Call SimplifyValue first (context-free), then SimplifyValueWithContext on the result with the appropriate context.
func TranslateCorrelations ¶
func TranslateCorrelations(v Value, m TranslationMap) Value
TranslateCorrelations applies the map to every correlation-bearing leaf of v — Java's Value.translateCorrelations (Value.java:347-368): identity early-out, then replaceLeavesMaybe with visitNewLeaves=false (Go's ReplaceLeavesOnceMaybe — replacement leaves are never re-translated, the load-bearing semantics for self-referential substitutions). Rebuilds go through withChildren, where a baked enclosing FieldValue FUSES over a baked FieldValue replacement (replace.go — Java's withNewChild = ofFieldsAndFuseIfPossible). Pointer-stable when nothing translates.
func WithChildren ¶
WithChildren is the exported entry point for reconstructing a Value with new children. Delegates to the unexported withChildren.
type ValueSimplifyContext ¶
type ValueSimplifyContext struct {
ConstantAliases map[CorrelationIdentifier]struct{}
IsRoot bool
}
ValueSimplifyContext carries context for context-aware value simplification. Matches Java's AbstractRuleCall fields: constantAliases + isRoot.
type VersionValue ¶
type VersionValue struct {
Child Value
}
VersionValue extracts the FDBRecordVersion (12-byte versionstamp + local) from a record. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.VersionValue`.
Used by VERSION-aware queries:
- SELECT version(record) FROM t
- WHERE version(record) > X (versionstamp range queries)
- ORDER BY version(record) (versionstamp-ordered scans)
The child Value must evaluate to a record-shaped object that carries a "version" field — typically a QuantifiedObjectValue flowing the queried record. Go extracts via map["version"] lookup on the standard row shape; a consumer that flows a typed FDBQueriedRecord must populate that entry.
Type is nullable VERSION (12-byte composite). NULL when the record's version is unknown / unset.
func NewVersionValue ¶
func NewVersionValue(child Value) *VersionValue
NewVersionValue constructs a VersionValue.
func (*VersionValue) Children ¶
func (v *VersionValue) Children() []Value
Children returns the single child Value.
func (*VersionValue) Evaluate ¶
func (v *VersionValue) Evaluate(evalCtx any) (any, error)
Evaluate extracts the version from the child's evaluated value. The child is expected to produce a map with a "version" key (the standard row-shape), or a struct with a similar accessor.
Returns nil if:
- Child is nil-shaped or evaluates to nil.
- The evaluated record has no version field.
- The version field is itself nil.
Returns the version (typically []byte or a 12-byte tuple) on success.
type WindowedValue ¶
WindowedValue is the base shape for all SQL window-function values (RANK, ROW_NUMBER, DENSE_RANK, NTILE, percentile/lag/lead, etc.). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.WindowedValue` (an abstract class; in Go we use embedding via a plain struct).
The shape is two parallel Value lists:
- PartitioningValues — the PARTITION BY columns. Rows that share the same tuple of these values form a single window-frame group; the windowed aggregate restarts per group.
- ArgumentValues — the function-specific arguments. RANK has no arguments (uses ORDER BY); NTILE has one (the bucket count); LAG / LEAD have 1-3 (offset, default, etc.).
Java's WindowedValue is abstract — concrete subclasses (RankValue, RowNumberValue, NTileValue, ...) supply the per-row evaluation semantics. The Go port keeps this as a plain struct embedded by concrete window types; the empty Evaluate contract matches the AggregateValue pattern (window functions can't eval per-row alone — they need the whole partition context).
**Per Java's constructor preconditions**: argumentValues must be non-empty for non-RANK window functions; the Go port mirrors this at construction. RANK's empty argumentValues is a special case handled by NewRankValue.
func NewWindowedValue ¶
func NewWindowedValue(partitioningValues, argumentValues []Value) *WindowedValue
NewWindowedValue constructs the embedded base. argumentValues may be empty (RANK / DENSE_RANK / ROW_NUMBER take no operand args — the windowing happens via ORDER BY); concrete subclasses with required operand args validate at their constructor.
func (*WindowedValue) Children ¶
func (w *WindowedValue) Children() []Value
Children returns partition + argument values concatenated. Mirrors Java's WindowedValue.computeChildren which builds ImmutableList<>.addAll(partitioning).addAll(argument).
func (*WindowedValue) Evaluate ¶
func (*WindowedValue) Evaluate(any) (any, error)
Evaluate returns nil — windowed aggregates can't eval per-row without a full partition context. Concrete subclasses MAY override to evaluate against a window-frame harness (see RankValue.Evaluate for the rank-tracking eval pattern).
func (*WindowedValue) SplitNewChildren ¶
func (w *WindowedValue) SplitNewChildren(newChildren []Value) (partition, argument []Value)
SplitNewChildren splits a flat newChildren slice back into (partition, argument) lists by position — matching Java's `splitNewChildren` helper that subclass `withChildren` implementations call to reconstruct the partition/arg split.
Length contract:
- Expected: len(newChildren) == len(PartitioningValues) + len(ArgumentValues). When the simplification driver passes newChildren = w.Children() this holds by construction.
- SHORT input (len(newChildren) < len(PartitioningValues)): n is clipped to len(newChildren), partition gets all of newChildren, argument is empty. Permissive — silently drops trailing partitioning slots.
- LONG input (len(newChildren) > len(PartitioningValues) + len(ArgumentValues)): the surplus goes into argument without bounds check. Permissive — caller's invariant to enforce.
Today's only callers are the per-subclass `WithChildren` implementations (RankValue, RowNumberValue, DistanceRowNumberValue), which receive exactly len(Children()) values from the planner, so the permissive-on-mismatch behaviour never bites in practice. New callers must pass an exactly-sized slice; otherwise either partition or argument silently truncates.
Source Files
¶
- coercion.go
- correlation.go
- folder.go
- functional_dependency.go
- leaf_value.go
- like_match.go
- map_field_values.go
- ordinal_join_seed.go
- ordinal_seed_layout.go
- pullup.go
- rebase.go
- replace.go
- semantic_equals.go
- semantic_hash.go
- simplifier_value.go
- translation_map.go
- type.go
- value_anchored_join_record.go
- value_andor.go
- value_array_constructor.go
- value_array_distinct.go
- value_cardinality.go
- value_collate.go
- value_condition_selector.go
- value_constant_object.go
- value_correlation.go
- value_cosine_distance_row_number.go
- value_derived.go
- value_distance.go
- value_distance_row_number.go
- value_dot_product_distance_row_number.go
- value_empty.go
- value_euclidean_distance_row_number.go
- value_euclidean_square_distance_row_number.go
- value_evaluates_to.go
- value_exists.go
- value_first_or_default.go
- value_first_or_default_streaming.go
- value_in.go
- value_incarnation.go
- value_index_entry_object.go
- value_index_only_aggregate.go
- value_indexed.go
- value_like.go
- value_not.go
- value_object.go
- value_oftype.go
- value_ordered_bytes.go
- value_parameter_object.go
- value_pattern_for_like.go
- value_pick.go
- value_quantified_record.go
- value_queried.go
- value_range.go
- value_rank.go
- value_recordtype.go
- value_row_number.go
- value_row_number_high_order.go
- value_scalar_subquery.go
- value_strict_rank_limit.go
- value_subscript.go
- value_throws.go
- value_udf.go
- value_unmatched_aggregate.go
- value_version.go
- value_windowed.go
- values.go
- values_helpers.go