values

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2026 License: Apache-2.0 Imports: 36 Imported by: 0

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.
  • 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

Constants

View Source
const (
	RelOpEquals              = relOpEquals
	RelOpNotEquals           = relOpNotEquals
	RelOpLessThan            = relOpLessThan
	RelOpLessThanOrEquals    = relOpLessThanOrEquals
	RelOpGreaterThan         = relOpGreaterThan
	RelOpGreaterThanOrEquals = relOpGreaterThanOrEquals
	RelOpIsDistinctFrom      = relOpIsDistinctFrom
	RelOpNotDistinctFrom     = relOpNotDistinctFrom
	RelOpIsNull              = relOpIsNull
	RelOpNotNull             = relOpNotNull
)

The comparisons a RelOpValue carries.

View Source
const ArrayAggNoLimit = -1

ArrayAggNoLimit is Java's ArrayAggValue.NO_LIMIT.

View Source
const PseudoFieldRowVersion = "__ROW_VERSION"

PseudoFieldRowVersion is the name of the row-version pseudo-field — Java's PseudoField.ROW_VERSION.getFieldName() (PseudoField.java:36-44: the "__" prefix plus the enum constant's name).

When a schema template stores row versions, every planner-facing record layout is extended with one trailing field of this name and type (Java: RecordMetaData.getPlannerType → Type.Record.addPseudoFields, RecordMetaData.java:732-739 / Type.java:2358-2368), unless the record descriptor already defines a REAL field of the same name — the real-column-wins rule of addPseudoFields' containsKey skip.

View Source
const WrappedArrayValuesFieldName = "values"

WrappedArrayValuesFieldName is the wrapper's single repeated field name (Java: NullableArrayUtils.REPEATED_FIELD_NAME).

Variables

View Source
var (
	RowNumberEfSearch      = IntegerOption("hnswEfSearch")
	RowNumberReturnVectors = BooleanOption("vectorReturnVectors")
)

RowNumberEfSearch and RowNumberReturnVectors are RowNumberFn's options, named after the vector scan options they feed (VectorIndexScanOptions HNSW_EF_SEARCH and VECTOR_RETURN_VECTORS).

View Source
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).

View Source
var ErrWholeRowProjection = errors.New(
	"projection list is a single bare QuantifiedObjectValue (one-slot whole-row projection): " +
		"the executor emits one slot per projection, so this wraps the inner row instead of " +
		"passing it through; project the inner's columns per-field instead")

ErrWholeRowProjection is returned by ProjectionResultValue when the projection list is a single bare RECORD-typed QuantifiedObjectValue — a "one-slot whole-row projection". A scalar QOV is an ordinary scalar slot (not a wrapped row) and is admitted.

THIS IS A DERIVATION REFUSING TO SYNTHESISE A ROW. It is NOT a constructor guard and the shape is NOT unbuildable — say so here, in the file that owns the error, because earlier text in three files claimed the opposite and this is where a reader looks first.

A query block's result and the physical projection plan both derive their row here, so this refusal is what stops either claiming a row it cannot name.

WHY THE SHAPE CANNOT ANSWER. The executor emits one positional slot PER PROJECTION, so this projection produces a 1-slot row WRAPPING its inner's row, and the wrapper has no name for its single field. Java never has the shape at all — GraphExpansion expands SELECT * into per-field columns, and Go's SELECT * builds no projection node either.

WHAT IS STILL OWED, and is RFC-226 §4.4(c)'s follow-on rather than something this error delivers: the two rules that yield an inner's N-field row into the projection's OWN memo reference make two differently-shaped plans co-members of one equivalence class. Refusing the derivation does not stop that; only deleting the rules does. Do not read this guard as having closed it.

Functions

func AccessorNamePath

func AccessorNamePath(v Value) ([]string, bool)

AccessorNamePath returns the ordered accessor NAME path (root QOV/alias EXCLUDED) of a plan-time column reference, from the two STRUCTURED representations only (RFC-187 §3.0):

(a) nested Child chain → walk Child, prepend each Field, stop at the root QOV
(b) baked Resolved     → Resolved.Accessors[].Field (Child is the root QOV, excluded)

ok=false — a conservative "cannot establish identity", callers MUST NOT match — when:

  • any accessor is pure-ordinal (Field==""): a machinery-owned bake has no name to compare, so identity is asserted-unknown here rather than falling back to a silent name match;
  • a LAZY Field carries a '.' (flat-dotted "form c"): the string is AMBIGUOUS — a real nested path (addr.city) and an alias-qualified leaf (T.city / leg.COL, composed by clustered_outer_scalar / cascades_translator) are indistinguishable as strings, so splitting on '.' would be the very string hack this kills AND could mis-root an alias as an accessor. We deliberately do NOT split (this also disposes of the quoted-"a.b"-identifier concern — no split, no hack). Such a value must not reach a match site; if one does, ok=false makes it a loud conservative miss, never a wrong bind.

Names are UPPER-cased to the resolver's normalization rule so identity is case-insensitive at every accessor.

This is the match-DOMAIN column identity: the candidate side is name-based by construction (columnNames []string, no ordinals), so identity can only be compared in the name domain. The ordinal identity (FieldPath.Equals) is a different, evaluation-domain concern; unifying them by ordinalizing the candidate is the RFC-187 §8 / RFC-173-endgame follow-up.

func AccessorNamePathKey

func AccessorNamePathKey(v Value) (string, bool)

AccessorNamePathKey returns a canonical map key for a column reference's accessor path (the path segments joined with a NUL separator), or ok=false when the path cannot be established (AccessorNamePath !ok). It is the map-keyed form of column identity over plain FieldValue references: two such references produce the same key iff ColumnNamePathsEqual reports them equal, so a set keyed by this string distinguishes a nested addr.city from a same-leaf-named top-level city. (It does NOT cover the CardinalityValue wrapper ColumnNamePathsEqual also handles — a CardinalityValue yields ok=false here; the key-form callers, S7/S9 grouping keys, never pass one.)

func AccessorNamePathMatchesNames

func AccessorNamePathMatchesNames(v Value, candidate []string) bool

AccessorNamePathMatchesNames reports whether v's accessor name path equals the given candidate name path (already UPPER-cased accessor names, root→leaf). It is the value↔declared-path form used by the sites whose candidate side is a string path (aggregate group/agg columns, ordered index/PK sort columns) rather than a Value. A single-element candidate (a top-level column) therefore cannot match a nested query path — the fix for those sites (RFC-187 §3.2/§3.3).

THE ToUpper ON THE CANDIDATE IS LOAD-BEARING AND MUST NOT BE DELETED ALONE. It looks like one more site of RFC-237's fold class, and the candidate side genuinely does arrive canonical now. But AccessorNamePath (above) still folds the VALUE side, deliberately: five tests pin case-insensitive accessor identity as a match-domain rule (`lazyFlat("city")` equals `lazyFlat("CITY")`, `bakedFused("ADDR","City")` equals `bakedFused("addr","city")`). Fold one side and not the other and a verbatim candidate can never meet an upper-folded path — measured: an aggregate index over quoted columns silently stopped matching. The two folds are one decision. Change them together or not at all, and see RFC-237 §9 for what would settle whether to remove both.

func AliasMapSize

func AliasMapSize(m AliasMap) int

AliasMapSize returns the number of pairs in m.

func ArithmeticOperandIsPrimitive

func ArithmeticOperandIsPrimitive(tc TypeCode) bool

ArithmeticOperandIsPrimitive is Java's TypeCode.isPrimitive() as ArithmeticValue.encapsulate checks each operand before it looks up a lane (ArithmeticValue.java:215-220): UNKNOWN, NULL, BOOLEAN, BYTES, DOUBLE, FLOAT, INT, LONG, STRING, VECTOR and VERSION are primitive; ENUM, RECORD, UUID, ARRAY, RELATION, NONE and ANY are not (Type.java:774-791). It differs from TypeCode.IsPrimitive, which calls UUID primitive and UNKNOWN and NULL not. Go has no VECTOR code (a vector column types as BYTES here, primitive as Java's VECTOR is); DATE and TIMESTAMP, Go-only codes, are primitive (they have no lane either way).

func AssertOrdinalJoinSeed

func AssertOrdinalJoinSeed(rc *RecordConstructorValue)

AssertOrdinalJoinSeed is the LOUD ordinal-join seed-shape validator: the 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, 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 (strictness lives at 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 instead of panicking).

Lives in values (not executor) because the translator is the caller of record — a seed must never be built without this assert.

func BuildStructMessage

func BuildStructMessage(
	md protoreflect.MessageDescriptor,
	fields map[string]any,
	convert func(fd protoreflect.FieldDescriptor, v any) (protoreflect.Value, error),
) (protoreflect.Value, error)

BuildStructMessage builds the nested message a STRUCT value stores, from the evaluated record constructor's field map. It is the structural half of Java's RecordConstructorValue.eval (RecordConstructorValue.java:113-139): walk the TARGET descriptor's fields, set each field present in the map, leave a NULL field ABSENT (:135's null branch — absence is what makes a nullable struct field read back as NULL), and reject a NULL at a non-nullable field.

The per-field VALUE conversion is the caller's, passed in: the plan-time writer (INSERT … VALUES) and the executor writer (UPDATE, INSERT … SELECT) have their own scalar lanes, already documented as siblings, and this exists so the STRUCTURE is not implemented twice alongside them.

func CanBridgeOrderingFieldValues

func CanBridgeOrderingFieldValues(left, right Value) bool

CanBridgeOrderingFieldValues reports whether two non-structurally-equal ordering Values may safely be reconciled by their ordinal-free column name.

The bridge is deliberately narrow. SQL requested orderings are often plan-time-baked (COL#ordinal), while candidate orderings are rebuilt as lazy flat fields (COL); those two representations need to meet. Two baked fields never meet through this helper: different ordinals are different reads, even when their display names match. Childful/nested paths are also excluded because a leaf name does not identify their source slot.

Callers must test structural equality first. This helper handles only the representation bridge, including the harmless case-only difference between two lazy flat field names.

func CanBridgeOrderingValueRoots

func CanBridgeOrderingValueRoots(left, right Value) bool

CanBridgeOrderingValueRoots reconciles the two safe representation seams an ordering request crosses on its way to a scan candidate:

  • a lazy flat field and the same baked flat field;
  • a field rooted at its owning SELECT quantifier and the same source-local candidate field.

The second bridge normally requires exactly one QOV-rooted side and compares the complete accessor name path. There is one deliberately narrower rooted exception: a values-owned tagged-current root may bridge to one ordinary named root. That is the physical-provider -> logical-request phase boundary; two named roots remain ambiguous (self-join hazard), and two independently minted current roots name different owner phases. A shared current handle is accepted only for an otherwise structurally identical value.

When both values carry baked paths, their ordinal paths must also agree; this prevents a QOV-rooted NAME#1 from collapsing with source-local NAME#2. A baked value may still bridge to a lazy value with the same complete name path. Callers must scope a request to its owning quantifier before using this bridge.

func CanonicalTimestampText

func CanonicalTimestampText(t time.Time) string

CanonicalTimestampText is the TIMESTAMP text of an instant: UTC, to the second.

func CastEvaluated

func CastEvaluated(v any, source, target Type) (any, error)

CastEvaluated applies CAST to a value whose declared SQL source type is known. A float64 carrier alone cannot distinguish FLOAT from DOUBLE. This shares the scalar/array conversion used by CastValue without constructing a child Value.

func CastPairDefined

func CastPairDefined(from, to TypeCode) bool

CastPairDefined reports whether an explicit CAST from `from` to `to` has a defined operator (Java CastValue's construction-time gate — "No cast defined from X to Y" otherwise). Identity always casts; NULL casts to anything.

func CastTypesDefined

func CastTypesDefined(from, to Type) bool

CastTypesDefined supplements the operator table with structural type checks. VECTOR has no conversion operator: only an identical shape can flow through unchanged. ARRAY casts must admit their element conversion recursively.

func CensusQOVShape

func CensusQOVShape(rv Value) (isQOV, typed bool, label string)

CensusQOVShape classifies a minted select result for the select-result-mint census, which cannot see the unexported QOV it inspects.

func CheckPromotionsTrie

func CheckPromotionsTrie(target, current Type) error

CheckPromotionsTrie is the admission half of Java's PromoteValue.computePromotionsTrie (PromoteValue.java:355-443): whether a value of type current can be stored in a slot of type target, walking records field by field (by position) and arrays element-wise. It answers only the verdict; carrying out the promotion is the caller's converter.

  • ANY takes anything.
  • A primitive (Java's TypeCode.isPrimitive: NULL, BOOLEAN, BYTES, DOUBLE, FLOAT, INT, LONG, STRING, VERSION, and Go's DATE and TIMESTAMP) of the slot's code needs nothing; into an array or a record it is refused (isPromotionNeeded's check); otherwise it needs a promotion the promotion map holds (IsPromotable).
  • NONE (the untyped `[]`) needs NONE_TO_ARRAY.
  • An enum takes only an enum equal to it but for nullability (Type.Enum compares its values, not its name); a UUID a UUID.
  • Records need as many fields, each admitted; arrays their elements.

Where the two codes differ past the primitive arm (an enum into a string, an array into a scalar) Java fails a bare Verify.verify, an internal error ("XX000 null"); that is a refusal Java did not design, and this answers it with the designed one, INCOMPATIBLE_TYPE.

An UNKNOWN current type (Go's unresolved placeholder, which Java never plans with) is not a verdict: it is admitted here and left to the converter.

func CheckRangeBounds

func CheckRangeBounds(position, end, step int64) error

CheckRangeBounds is Java's RangeValue.Cursor.checkValidRange.

func ClaimableOrderingPrefix

func ClaimableOrderingPrefix(layout Type, names []string) int

ClaimableOrderingPrefix returns the leading name-resolved ordering prefix. Typed keys can use ClaimableTypedKeyPrefix or TypeTerminatesOrderingClaim directly.

func ClaimableTypedKeyPrefix

func ClaimableTypedKeyPrefix(keys []Value) int

ClaimableTypedKeyPrefix is ClaimableOrderingPrefix for keys that carry their OWN declared type and have no flowed layout to resolve against — grouping keys, which the translator mints already typed.

A nil key is skipped rather than treated as terminating: an unidentifiable key is the same "burden of proof sits on the float side" trade TypeTerminatesOrderingClaim documents.

Two DIFFERENT questions are answered by this one count, and it is worth naming both because only the first is about ordering:

  • Does the producer's advertised ORDER hold? Only for the leading prefix, so the claim is truncated there.
  • Is the input CLUSTERED by the full grouping key? A streaming aggregation compares each row against the PREVIOUS group only, which is sound exactly when rows equal under the grouping identity are ADJACENT. A float coordinate breaks that too, and more sharply: the grouping identity is java.lang.Double.equals, which makes every NaN payload one value, while the tuple encoding scatters those payloads into two blocks at OPPOSITE ENDS of the key space. So the same group opens, closes and reopens, and the aggregation emits it twice. A consumer asking that question needs the count to reach len(keys) — a prefix is not enough, because clustering is a property of the whole key.

func CollectCorrelatedToOfValue

func CollectCorrelatedToOfValue(v Value, out map[CorrelationIdentifier]struct{}) map[CorrelationIdentifier]struct{}

CollectCorrelatedToOfValue unions v's correlations into out, allocating out when nil. Callers folding several Value trees can share one result set.

func ColumnCanExtendOrderingClaim

func ColumnCanExtendOrderingClaim(layout Type, name string) bool

ColumnCanExtendOrderingClaim resolves name against layout and reports whether that column may extend an ordering claim.

Returns true when the column cannot be shown to be a FLOAT/DOUBLE — see TypeTerminatesOrderingClaim for why the burden of proof sits on that side.

An AMBIGUOUS name (a layout declaring it twice, which is constructible because NewRecordType's duplicate check is case-SENSITIVE while column resolution is case-INSENSITIVE) terminates the claim if ANY matching field is a float. Addressability of an ambiguous key is a SEPARATE contract, already enforced downstream by the unique-match rule in bakeOrderingColumnIn — this predicate deliberately does not duplicate it, and answers only the question it owns: could this coordinate be a float?

func ColumnCouldBeFloat

func ColumnCouldBeFloat(layout Type, name string) bool

ColumnCouldBeFloat resolves name against layout and reports whether that coordinate COULD hold a float — the question a signed-zero widening decision needs, and deliberately NOT the negation of ColumnCanExtendOrderingClaim.

The two differ exactly where the layout cannot answer, and the difference is the whole reason this exists. ColumnCanExtendOrderingClaim is permissive on an unresolvable layout (nil, not a *RecordType, no fields, name absent) because its own use is "may this coordinate extend a claim?", where permissive means GRANT and the burden of proof sits on the float side.

Inverted into a float test that answer flips meaning: "not a float" becomes "no signed zero", which becomes "this equality PINS", which is assume-SOUND — the unsound direction. A burden-of-proof direction does not survive an inversion, and reading one predicate backwards to answer the other silently turned a conservative default into an optimistic one.

That state is not hypothetical. plans.NewRecordQueryIndexPlan defaults a nil flowedType to UnknownType, and AggregateIndexMatchCandidate passes UnknownType explicitly; UnknownType is a *PrimitiveType, so it takes the not-a-record arm and every coordinate on such a plan reads as non-float. MEASURED live: a reachability probe in that arm fired under the planner suite.

So this asks positively and fails CLOSED — an unresolvable coordinate could be a float, so a zero-capable equality on it does not pin and the claim is refused. The cost is a sort that may not have been needed; the alternative cost is a wrong row order.

func ColumnNamePathsEqual

func ColumnNamePathsEqual(a, b Value) bool

ColumnNamePathsEqual reports whether two plan-time column references denote the same accessor path (RFC-187 §3.0). It is the single match-domain column-identity notion; every value↔value match site routes through it.

Returns false — a conservative reject (the caller leaves the predicate a residual filter / does not elide the sort → correct rows, correct order via the slower path) — when either side's AccessorNamePath is !ok, or the paths differ at ANY position: every intermediate accessor is compared, not just the leaf, not leaf+root — which is what distinguishes a nested path from a same-leaf-named top-level column.

CardinalityValue is a transparent wrapper: CARDINALITY(x) matches CARDINALITY(y) iff x and y denote the same column. (DistanceRowNumber's metric-class discrimination is handled at its call site, which then compares the partition/argument column paths through this function.)

func ColumnNameValue

func ColumnNameValue(v Value) string

ColumnNameValue renders v exactly like ExplainValue but WITHOUT the baked `#<ordinal>` accessor discriminators — the NAME-derivation rendering. Every place that derives an OUTPUT COLUMN NAME from a Value (aggregate result columns, group-key output columns, sort-key field refs, projection column defs) must use this form, never ExplainValue: a reference's column NAME must not change when the reference is bound to its ordinal at plan time, or the naming lockstep between the layers that render the name from DIFFERENT instances of the same reference (one baked, one lazy) silently breaks. ExplainValue keeps the ordinal discriminators for EXPLAIN/debug output, where collapsing two different reads is itself a bug.

func CompareExactInts

func CompareExactInts(a, b any) (int, bool)

CompareExactInts compares two values EXACTLY when both are admitted integer forms — int/int8/int16/int32/int64 plus the uint/uint64 half the tuple layer uses for positive values above math.MaxInt64. ok=false when either side is not an integer. The order is by true numeric value — the order the FDB tuple integer encoding gives an indexed column — computed on (negative, magnitude) form so no pair round-trips through float64 (promotion ties adjacent values above 2^53 and at the 2^63 boundary).

func CompareFloat64

func CompareFloat64(a, b float64) int

CompareFloat64 is a total order over float64 faithful to Java's java.lang.Double.compare and Double.doubleToLongBits. Java Record Layer ordered comparisons use that order, and its boxed equality uses Double.equals, so both distinguish the zero signs and canonicalize NaNs. Go predicate comparison intentionally prechecks native IEEE equality in predicates.cmpAny: it makes -0 equal +0 while retaining this total order for non-equal values and NaNs. Sort, merge, and dedup consumers call this helper directly and therefore retain the Java/FDB-compatible zero-sign order.

Two edge values differ from Go's native float comparison:

  • NaN sorts GREATER than every non-NaN value, and NaN compares equal to NaN (native `<`/`>` are both false, and `==` is false).
  • Negative zero sorts strictly BEFORE positive zero: -0.0 < 0.0 (native `==` treats them as equal).

This matches FDB tuple order for ordinary values and the two zero signs, but deliberately not for arbitrary raw NaN encodings. FDB preserves NaN sign and payload, placing negative and positive NaNs in separate physical regions; this logical comparator canonicalizes them. Planner ordering/SARG proofs must therefore reject an unbounded or range-bound FLOAT/DOUBLE coordinate unless a separate normalization or compensation proof is available.

func CompareOrdered

func CompareOrdered(a, b any) (int, error)

CompareOrdered is a total order over the concrete scalar/binary Go types the query engine's row and IN-list values take (the int/uint/float variants, bool, string, []byte, [16]byte UUID, and nil). It is the single Java-faithful natural order this codebase uses wherever two runtime values must be ranked against each other outside of an indexed comparison: in-memory sort, merge-cursor ordering keys, and a SORTED IN-join's literal list (cascades.sortInJoinValues).

Two edge cases differ from Go's native comparison operators, matching java.lang.Double.compare exactly (see CompareFloat64): NaN sorts greater than every non-NaN value and compares equal to NaN, and -0.0 sorts strictly before +0.0. Every other typed arm matches FDB's own tuple encoding order, so an in-memory ordering agrees with what an indexed scan of the same column would produce.

nil sorts before every other value (a nil pair compares equal). A pair with no shared typed arm returns a loud error rather than silently picking a wrong order — the planner's type checking is expected to exclude cross-type comparisons before this is ever called on production data, so this arm is a defensive backstop, not a designed code path.

func ContainsAggregate

func ContainsAggregate(v Value) bool

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

func ContainsBakedOrdinal(v Value) bool

ContainsBakedOrdinal reports whether any FieldValue in v's subtree carries a MACHINERY-OWNED (FrontierPinned) baked-ordinal marker — the structural "is this an ordinal-join value tree" probe the join machinery keys on (SelectMergeRule target loop, the executor's ordinal-join construction). Deliberately blind to UNPINNED baked nodes (source-relative resolver bakes): those carry no join-frontier contract and must not trip join-seed machinery.

func DedupFieldNames

func DedupFieldNames(names []string) []string

DedupFieldNames is THE rule that keeps a name-addressed record type name-addressable when a projection repeats an output name: a later occurrence takes a numeric suffix (`A`, `A_2`, `A_3`). It is a property of the TYPE, never of the SQL: Java has no such suffix — Type.Record keeps repeated field names and every read is bound by ordinal — so nothing user-visible may carry it. The result-set label of `SELECT a, a FROM T` is [A A].

Exported so that every layout that must equal a projection's runtime row (the ordinal seed's leg type, derived from the logical projection) applies the same rule instead of restating the names verbatim: a leg type that said [G G] over a row the projection emits as [G G_2] is a different ordinal domain, and the baked positional read of the second slot then declined and fell back to a by-name read that answered the FIRST G.

func DependsOnStatementClock

func DependsOnStatementClock(v Value) bool

func DerivedStorageName

func DerivedStorageName(name string) string

DerivedStorageName is the protobuf spelling Java gives a name that states none (Field.of, EnumValue.from: ProtoUtils.toProtoBufCompliantName).

func DescribeType

func DescribeType(typ Type) string

DescribeType renders a Type as a compact, comparable shape for a diagnostic: `RECORD(LID:LONG,VAL:LONG?)`, `ARRAY<INT>`, `LONG?`. A trailing `?` marks nullable. It is the public twin of the rendering the exact-type conflicts use, for callers outside this package that hold a Type rather than a handle.

func DisplayColumnName

func DisplayColumnName(v Value, alias string) string

DisplayColumnName is the USER-VISIBLE label for a projected column: the alias when the column carries one, else its own name with the QUALIFIER removed — Java's Identifier.withoutQualifier, applied by the top-level clearQualifier (Identifier.java:101-106). `SELECT n.sk` is column SK.

This is deliberately NOT OutputColumnName. The qualifier belongs in the internal slot key, where it is what keeps two legs' same-named columns apart; it does not belong in anything a user names the column by. Wherever a projection's name CROSSES into SQL — a result-set label, a CTE's column list — the display form is the authority, and disagreeing about that is how one recursive CTE came to declare its column N.SK while every reference to it resolved SK.

The leaf is taken from the RESOLVED ACCESSORS, never by splitting the rendered name: a column may legally be named with a dot in it (`"A.ID"`), and a last-dot split would tear that name in half.

func EffectiveListField

func EffectiveListField(fd protoreflect.FieldDescriptor) (list protoreflect.FieldDescriptor, wrapped, ok bool)

EffectiveListField resolves a column field to its effective REPEATED field:

  • a flat repeated field returns itself (wrapped=false);
  • a singular message field whose message is the wrapper returns the inner `values` field (wrapped=true);
  • anything else returns (nil, false, false).

func EqualsWithoutChildren

func EqualsWithoutChildren(a, b Value) bool

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

func EvaluateConstant(v Value) (out any, ok bool)

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 ExactTypesEqual

func ExactTypesEqual(left, right ExactTypeHandle) bool

ExactTypesEqual reports whether two exact handles denote the same type. It is FlowedTypesEqual for callers that hold bare handles rather than quantifiers — an expression's snapshotted target or result type, say — and it exists for the same reason: `left.Type().Equals(right.Type())` builds two whole graphs to answer a boolean, and both operands were already immutable identities.

Read its contract off exactTypesEqual, not off pointer identity: two handles can denote one type and still be two objects, because interning keys on the record and enum name that Type.Equals ignores.

Two absent handles are NOT equal, matching FlowedTypesEqual. `Type()` on a nil handle yields a nil Type and the comparison it replaces panicked there, so there is no prior answer to preserve — and "neither side can state a type" is not evidence that they state the same one.

func ExplainPlanValues

func ExplainPlanValues(vs []Value) []string

ExplainPlanValues renders one plan node's retained Value program in a stable local correlation namespace. Unique correlations are allocation identities, so their process-global numeric suffixes must not leak into plan text: doing so makes two structurally identical plans explain differently solely because another query happened to allocate aliases first.

A program with one unique correlation and no bare QOV omits that root, which preserves the familiar `ID#0` spelling for a projection over one input. With multiple unique roots (or a bare scalar QOV) the roots are numbered q$0, q$1, ... by first structural occurrence. Named correlations — including a quoted user alias whose text looks like q$7 — are never rewritten.

func ExplainValue

func ExplainValue(v Value) string

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 ExplainValueOverInput

func ExplainValueOverInput(v Value, input CorrelationIdentifier) string

ExplainValueOverInput renders v like ExplainValue with the input correlation spelled as the current row, as Java prints a plan's own input as `_`. The input alias is minted per planning run; printing it would make the plan text depend on allocation order, and so would any other unique root v reads (an outer row the plan is correlated to), which is numbered as ExplainPlanValues numbers its roots.

func ExplicitStorageName

func ExplicitStorageName(name, storage string) string

ExplicitStorageName is storage when name does not already imply it.

func ExtractFromIndexEntry

func ExtractFromIndexEntry(v Value, baseAlias CorrelationIdentifier, source TupleSource, ordinalPath []int) (FieldValue, Value, bool)

ExtractFromIndexEntry is Java's Value.extractFromIndexEntryMaybe: the ExtractFromIndexKeyValueRuleSet computed over an index entry column's Value v. It answers the base field the column holds and the reader that recovers that field from the entry bound under the current correlation. A column that is no field of the base (an arithmetic function, a field of an exploded element) has no extraction, nor does one whose type no entry leaf can carry.

func FieldNameForProtoField

func FieldNameForProtoField(field protoreflect.FieldDescriptor) string

FieldNameForProtoField is THE single authority for the NAME a stored column's slot carries in a values.Type: the user identifier, VERBATIM.

A protobuf field name is the STORAGE spelling — `$`, `.` and `__` are escaped (`a$b` is stored as `A__1B`). Java keeps the two apart on the type itself: `Type.Record.fromDescriptorPreservingName` records `ProtoUtils.toUserIdentifier(descriptor.getName())` as the name and the raw descriptor name as the storage name, and `Type.Record.Field` does the same per column — the wire keeps the escaped spelling, the SQL surface sees the user's.

Go's SQL catalog already un-escapes (rlcatalog), so a Value-tier type built straight off the descriptor states a DIFFERENT name for the same column than the reference that reads it. Under RFC-232 those two are compared as exact types, so the disagreement is not cosmetic: it is a hard "type disagrees with declared binding" at evaluation, and every query over a table with an escaped identifier fails.

It does not FOLD, for the same reason Java does not: the only normalization in the language is at the parse boundary (SemanticAnalyzer.normalizeString — quoted keeps its case, unquoted folds UPPER), and every catalog comparison after it is exact. A fold here was invisible for a DDL-created schema, whose descriptor names are already the normalized spelling, and wrong for everything else — it named a column something no reference could spell, and it made the index-matching bridge miss SILENTLY (RFC-237 §2.1).

func FlowedRowShapeEquals

func FlowedRowShapeEquals(value QuantifiedObjectValue, typ Type) bool

FlowedRowShapeEquals is FlowedRowShapesAgree against an ordinary Type — a declared row an executor binding carries, say — where there is no second handle to compare with.

It routes the quantifier's side through the SHARED thawed graph, so the walk runs against a graph allocated once per interned type rather than once per call. That is the whole saving available on this shape; see FlowedTypeEquals.

func FlowedRowShapesAgree

func FlowedRowShapesAgree(left, right QuantifiedObjectValue) bool

FlowedRowShapesAgree reports whether two quantified object values denote the SAME BOUND ROW, answered from the exact handles. It is QuantifiedRowShapesAgree's question — see that function for why the top-level nullable bit is excluded from a row's shape and why one alias legitimately carries two QOVs differing only there — with neither graph built.

Same relation, not an approximation of it: exactRowShapesAgree is the handle-side twin, and every ordered pair of a type corpus is swept in exact_type_equality_differential_test.go to keep the two answering alike.

func FlowedTypeEquals

func FlowedTypeEquals(value QuantifiedObjectValue, typ Type) bool

FlowedTypeEquals reports whether value flows exactly typ.

The other side is an ordinary Type here — a layout's carrier, a plan's declared row, a query result — so there is no second handle to compare against and the graph has to be walked. What this avoids is BUILDING one: SharedFlowedType hands back the thawed graph cached on the interned handle, so the walk runs against a value that is allocated once per interned type for the life of the process instead of once per call.

Argument order does not affect the answer. Every Type implementation's Equals type-asserts the operand to its own concrete type before comparing anything, so all six are symmetric, and a call site that had the ordinary type on the left reads the same through here. TestTypeEqualsIsSymmetricOverTheCorpus pins that rather than leaving it as a claim, because it is the one property that lets these call sites be rewritten without checking each one's orientation.

The result is READ-ONLY on the value's side and this function never lets it escape — that is the whole reason the shared graph is safe here while FlowedType stays the default everywhere the graph is stored or handed onward.

func FlowedTypesEqual

func FlowedTypesEqual(left, right QuantifiedObjectValue) bool

FlowedTypesEqual reports whether two quantified object values flow the same row type. It is what `left.FlowedType().Equals(right.FlowedType())` asks, answered from the immutable exact handles, building NEITHER graph.

The spelling it replaces allocates two complete Type graphs to produce one bool, and thaw was the single largest allocator in the planner because of it. The handles are already there: a quantified object value IS an exact handle plus a correlation, and comparing two handles is a pointer test, then a hash, then one bytes.Equal over a canonical encoding.

It is `exactTypesEqual` and NOT handle pointer identity, and the difference is the whole reason this function exists rather than being written inline at each call site. Identity is strictly STRICTER than Type.Equals: the intern table keys on the record and enum NAME, while RecordType.Equals and EnumType.Equals deliberately ignore it to match Java. Two Equals-equal rows can therefore hold two handles, and an identity test would call them different — a false negative, in the direction that changes plans. The canonical encoding exact_type.go builds excludes the name precisely because Equals does, which is what makes this substitution equal by construction rather than by an argument about interning. exact_type_equality_differential_test.go sweeps every ordered pair of a type corpus to keep it that way, and fails on 22 pairs if anyone "simplifies" this to `==`.

A value that cannot state a flowed row answers FALSE rather than panicking, as the expression it replaces did when the LEFT side was unusable — and answered false, inconsistently, when the right side was. Every caller here is asking whether two rows are the same, and "cannot tell" and "not the same" lead to the same fail-safe branch: rebuild, refuse the rewrite, miss the lookup.

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, and UnmatchedAggregateValue. 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 GetCorrelatedToWithoutChildrenOfValue

func GetCorrelatedToWithoutChildrenOfValue(
	v Value,
) map[CorrelationIdentifier]struct{}

GetCorrelatedToWithoutChildrenOfValue returns only the correlations carried by v itself, excluding correlations contributed by descendant Values.

This is the Go counterpart of Java Value.getCorrelatedToWithoutChildren(). Keep the switch in lockstep with the correlation-bearing leaf cases in GetCorrelatedToOfValue. Composite wrappers such as FieldValue and ExistsValue deliberately contribute nothing here even though their full subtree correlation set is non-empty.

func GetOption

func GetOption[T any](o CallSiteOptions, option CallSiteOption[T]) (T, bool, error)

GetOption is Options.get: the option's value coerced to its type.

func IsAny

func IsAny(t Type) bool

IsAny reports whether t is the universal supertype. Mirrors Java's `Type.isAny()`.

func IsArithmeticFunction

func IsArithmeticFunction(function string) bool

IsArithmeticFunction reports whether function (any case) is one of ArithmeticValue's logical operators, the functions Java builds through encapsulate and so the ones a lane decides.

func IsArray

func IsArray(t Type) bool

IsArray reports whether t is an ARRAY (concrete or erased). Mirrors Java's `Type.isArray()`.

func IsCanonicalCurrentOnlyOrdinalLayout

func IsCanonicalCurrentOnlyOrdinalLayout(layout OrdinalLayout) (bool, error)

IsCanonicalCurrentOnlyOrdinalLayout reports whether layout carries only its tagged-current object and therefore needs no retained-source bindings or per-row window presence. Record tile shape may be flat or nested: both are canonical carrier-relative addressing once source windows are absent.

A valid windowed layout returns (false, nil). Foreign, nil, and typed-nil views fail loudly before any interface method is invoked, matching the other layout purpose APIs.

func IsCascadesSafeScalarFunction

func IsCascadesSafeScalarFunction(name string) bool

IsCascadesSafeScalarFunction reports whether the named scalar function is admitted to the Cascades SQL pipeline.

func IsConstantExpression

func IsConstantExpression(v Value) bool

IsConstantExpression also admits statement-pool references: row-independent, but their value is known only at execution.

func IsConstantOver

func IsConstantOver(v Value, localAliases map[CorrelationIdentifier]struct{}) bool

IsConstantOver reports whether v is constant over an operator binding localAliases: it reads neither those aliases nor the operator's input row, and holds no aggregate or queried value (Java's MatchConstantValueRule, whose AggregateValue includes the record constructor).

func IsConstantValue

func IsConstantValue(v Value) bool

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 code that only acts on fully-foldable operands (e.g. range enclosure's compile-time comparand).

func IsEnum

func IsEnum(t Type) bool

IsEnum reports whether t is an ENUM. Mirrors Java's `Type.isEnum()`.

func IsFunctionallyDependentOn

func IsFunctionallyDependentOn(v Value, otherValue Value) bool

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

func IsIndexOnly(v Value) bool

IsIndexOnly is a helper that any Value can call to check whether v requires an index scan to produce its result.

func IsMixedSeedElementType

func IsMixedSeedElementType(t Type) bool

IsMixedSeedElementType decides whether a bare QuantifiedObjectValue carrying this type is the MIXED seed's whole-object SCALAR element — Java's `isPrimitive()` branch, the element the seed cannot ofOrdinal-bake and so gives its own synthesized 1-field window.

It is one predicate rather than two identical ones because the planner's window derivation (OrdinalSeedLegWindows) and the executor's span derivation (unnestMixedSeedSpans / ordinalJoinSpans) must agree on it BIT FOR BIT: they walk independently, and a disagreement about which field is the element is a wrong-offset read of every field after it. Two copies of a rule agree until one of them is edited.

The test is "not a RECORD", and it is a PROXY for the question actually being asked — is this field one slot, or is it a leg occupying width-many? — so it is worth being exact about why the proxy holds, because it did not always.

It holds because a LEG's quantifier object now states its row. While the flowed object value was minted untyped, an untyped leg was not a record either, so a leg flowing a whole multi-column row was admitted as a one-column element and a 2-slot record constructor of bare untyped quantifier objects was accepted outright, at widths nobody had checked. Typing the flowed value closed that: a leg reads as a RecordType and is rejected here, measured as flowed 848 of 848 leg derivations over the real-FDB corpus with underivable at zero. The bakeability census asserts that zero, so the fact this proxy rests on is enforced rather than assumed.

What it does NOT do is demand a STATED type, and that is deliberate rather than an oversight. An unnest element over an array of STRUCTS is a genuine whole-object element — one slot, the whole struct, exactly the case this arm exists for — and its type is UNKNOWN because Go does not infer array element types that far. Requiring a stated type declines it and `SELECT "X" FROM TS, TS."ITEMS" AS "X"` stops resolving. So an unstated type stays admitted, and the leg side is what carries the discrimination.

func IsNonEvaluable

func IsNonEvaluable(v Value) bool

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

func IsNone(t Type) bool

IsNone reports whether t is the NONE type (untyped empty array). Mirrors Java's `Type.isNone()`.

func IsNull

func IsNull(t Type) bool

IsNull reports whether t is the NULL literal's type (TypeCodeNull). Mirrors Java's `Type.isNull()`.

func IsNullStrictValue

func IsNullStrictValue(v Value) bool

IsNullStrictValue reports whether v is one of the classes Java's CollapseNullStrictValueOverNullValueRule.VALUE_CLASSES lists: ArithmeticValue, CastValue, FieldValue, NotValue, PromoteValue and SubscriptValue. KEEP IN SYNC with that list.

func IsOrdinalFieldName

func IsOrdinalFieldName(name string) bool

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 positional-merge and Explode-ordinality producers are the only writers of these keys in a merged row).

func IsOrdinalJoinRV

func IsOrdinalJoinRV(v Value) bool

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

func IsPositionalMergeRC(v Value) bool

IsPositionalMergeRC is the VALUE-level half of the structural merge-select recognition (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 ordinal join construction triggers on.

func IsPromotable

func IsPromotable(from, to Type) bool

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 IsPromotionNeeded

func IsPromotionNeeded(from, to Type) (needed, ok bool)

IsPromotionNeeded is PromoteValue.isPromotionNeeded: whether a value of type from must be promoted to be used as type to. Nullability is not part of it; a record needs promotion when a field's type, name or position differs. ok is false where Java raises INCOMPATIBLE_TYPE (records of different arity, a primitive against a structure).

func IsRecord

func IsRecord(t Type) bool

IsRecord reports whether t is a RECORD. Mirrors Java's `Type.isRecord()`.

func IsRelation

func IsRelation(t Type) bool

IsRelation reports whether t is a RELATION. Mirrors Java's `Type.isRelation()`.

func IsRowVersionPseudoField

func IsRowVersionPseudoField(name string, t Type) bool

IsRowVersionPseudoField reports whether a resolved field is THE row-version pseudo-field: name and type must both match, mirroring the two-sided check Java applies before emitting VersionKeyExpression.VERSION for it (MaterializedViewIndexGenerator.toFieldKeyExpression, MaterializedViewIndexGenerator.java:821-823: type equality with PseudoField.ROW_VERSION.getType() AND field-name equality).

func IsUnresolved

func IsUnresolved(t Type) bool

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 IsUuid

func IsUuid(t Type) bool

IsUuid reports whether t is a UUID. Mirrors Java's `Type.isUuid()`.

func IsWrappedArrayDescriptor

func IsWrappedArrayDescriptor(md protoreflect.MessageDescriptor) bool

IsWrappedArrayDescriptor reports whether md is the NullableArrayWrapper shape: exactly one field, named "values", repeated. Mirrors Java's NullableArrayUtils.isWrappedArrayDescriptor.

func JavaDoubleToString

func JavaDoubleToString(f float64) string

JavaDoubleToString is Java's Double.toString(double).

func LayoutProvides

func LayoutProvides(layout OrdinalLayout, source QuantifiedObjectValue) (bool, error)

LayoutProvides reports whether layout contains the exact source window. A missing window is a typed optional physical miss, not an untyped false.

func LayoutSatisfies

func LayoutSatisfies(layout OrdinalLayout, required RequiredBindings) (bool, error)

LayoutSatisfies applies one immutable binding manifest to a candidate provided layout. Missing windows are a normal physical incompatibility; malformed/extra/colliding sources remain errors.

func LayoutWindowNullSupplying

func LayoutWindowNullSupplying(layout OrdinalLayout, source QuantifiedObjectValue) (bool, error)

LayoutWindowNullSupplying reports whether one exact local source window is null-supplying. This is physical layout authority: record nullability alone cannot distinguish a retained nullable value from a source which was absent because an outer-join edge did not match.

func LayoutWindowWithin

func LayoutWindowWithin(layout OrdinalLayout, source, parent QuantifiedObjectValue) (bool, error)

LayoutWindowWithin reports whether every carrier path of source's window lies inside parent's window: a source buried in a retained box leg, which a join may publish without its child binding that source on its own.

func LegAwareRootOrdinal

func LegAwareRootOrdinal(vt FieldValue, srcOrd int, rc *RecordConstructorValue, fallbackOrd int) int

LegAwareRootOrdinal resolves the seed-RC slot for a SourceRelativeBaked reference collapsed over a flat leg-concatenation seed (a merged box/join whose RC concatenates each leg's columns, every field a baked FieldValue over its OWN leg's QOV — NewRawRecordConstructorValue, values.go). The reference's baked ordinal is relative to its OWN leg, so applying it directly to the seed picks the wrong slot; and with columns colliding across legs (dept.id AND emp.id) a bare-name match picks the first occurrence — again the wrong leg, the raw-RC duplicate-name conflation. Disambiguate by the reference's OWN leg (vt.Child's correlation): pick the seed field whose value is a FieldValue over that SAME correlation, matched by leg-relative ORDINAL.

Two name arms used to sit under that, and both are gone (RFC-197 item 3):

  • a within-leg name TIEBREAK, for a seed field carrying no baked ordinal. "A single source has unique column names" is the argument it rested on, and it is an argument for the ordinal, not against it: where the names are unique the ordinal answers identically, and where they are not the name is wrong. A seed field with no ordinal states nothing, so it is skipped.
  • a cross-leg name FALLBACK, for a seed whose leg field is a bare QOV rather than a per-column FieldValue (a lateral unnest). It resolved a UNIQUE name and poisoned a duplicate — the guard being the admission that the key was wrong, since two bare-QOV legs exposing the same column reach here indistinguishable. Every such seed now poisons.

Poison (-1) is the fail-closed answer for both: the caller leaves the reference UN-COLLAPSED rather than collapsing it onto a slot chosen by a display name, which is loud on a positional row and never a wrong slot. It is the same ambiguity-poison discipline bakeMergeComparisonKeys and rich_ordering apply.

Deliberately NOT falling back to fallbackOrd: that is the reference's RAW leg-relative ordinal, and applying it to the box's concatenated RC picks the FIRST leg's slot — the wrong-leg bug this function exists to prevent (it once turned `e.id IS NULL` into `d.id IS NULL` and made a LEFT-join anti-join return zero rows). fallbackOrd is used only where a leg-relative rebase was never needed.

func LikeOperation

func LikeOperation(operand any, pattern any) (any, error)

LikeOperation is LikeOperatorValue.likeOperation (LikeOperatorValue.java:93-105): NULL for a NULL operand, a NULL pattern record or an absent pattern; otherwise the match.

func MatchLike

func MatchLike(text, pattern string, escape *string) (bool, error)

MatchLike is LikeOperatorValue.matchLike (LikeOperatorValue.java:145-241), ported over the same UTF-16 code units Java's String holds: `%` matches any run, `_` one unit or one surrogate pair, an escaped character that unit literally; nothing treats a line terminator specially. A nil escape is no escape. The escape and every escape sequence met are re-checked as Java re-checks them.

func MessageFromRowValues

func MessageFromRowValues(md protoreflect.MessageDescriptor, vals []any) (protoreflect.Message, error)

MessageFromRowValues builds a message of md from row values by field position, leaving the field of a nil value unset: a RecordConstructorValue's message over values already evaluated.

func NestedResolvedPath

func NestedResolvedPath(v Value) (string, bool)

NestedResolvedPath returns the upper-cased dotted PATH a FUSED NESTED field reference reads, and reports whether v is one.

THE DEFINITION OF "NESTED" IS THE MULTI-ACCESSOR RESOLVED PATH, and it is one function because the predicate is the whole subtlety. The SQL resolver FUSES `n.sk` into ONE FieldValue with Resolved=[N,SK] — Java does exactly the same fuse (SemanticAnalyzer.lookupNestedField, SemanticAnalyzer.java:598 `FieldValue.ofFieldsAndFuseIfPossible`) and then names the result by the REQUESTED IDENTIFIER `n.sk` rather than by the fused value (SemanticAnalyzer.java:599).

`Field` cannot substitute, and the reason SURVIVED the mint fix that made it the LEAF name. It used to answer "what struct does this read out of", so `n.sk` and `n.co` shared it; it now answers "which member", so `t1.n.sk` and a flat `sk` share it instead. Either way it is one segment of a path and the question here needs all of them. Every output-naming authority must take the path. Reading `Field` there spells two different columns alike, and a name-keyed reader then serves one of them where the other was asked for.

THE PATH IS QUALIFIED WHEN THE REFERENCE HAS A CHILD, and that is a decision, not a leak. With ≥2 FROM sources the resolver emits the reference through its quantifier (`resolveScopedColumn`'s correlated arm), so the FieldValue carries `Child = QOV(T1)` and this returns `T1.N.SK`; with one source it returns `N.SK`. MEASURED end-to-end: `SELECT n.sk, n.co FROM t1, t2` explains as `Project([T1.N#1.SK#0, T1.N#1.CO#1], ...)` against `Project([N#1.SK#0, ...])` for the single-source form.

The qualifier is KEPT because dropping it would be the same conflation one level up: over `FROM t1, t2` where both declare an `n`, `T1.N.SK` and `T2.N.SK` are different columns and a bare `N.SK` collapses them in exactly the name-keyed maps this predicate exists to protect. It is also what the two neighbouring authority already does for a childful reference — `sortKeyFieldRef` renders `LEG.COL` (cascades_translator.go) — so qualifying here makes the nested arm agree with it rather than inventing another rule. The remaining asymmetry is ProjectionColumnName's own non-nested arm, which returns a bare `Field`; that arm is deliberately untouched, because changing it moves emitted names for every flat qualified projection and is a separate change.

Java agrees, and structurally: the fused nested reference is named by the REQUESTED IDENTIFIER (`SemanticAnalyzer.java:599`), an `Identifier` whose `fullyQualifiedName()` retains its qualifiers, and the top-level projection then strips them for the user-visible label (`Identifier.withoutQualifier`, Identifier.java:101). Go does the same: the display label for both forms is the bare leaf `SK` — measured, so the qualifier is an INTERNAL slot key and never reaches the user.

A path step can never contain the `#` that explainValueOrdinals escapes: a struct member name must be a valid protobuf identifier and DDL refuses anything else ("field name \"a#1\": a#1 it not a valid protobuf identifier", measured). That is now belt AND braces rather than the only argument — the escape no longer fires on an ordinal-free rendering at all. See the escape's own note in explainValueOrdinals.

func NewWrappedArrayMessage

func NewWrappedArrayMessage(fd protoreflect.FieldDescriptor) (msg *dynamicpb.Message, values protoreflect.List)

NewWrappedArrayMessage builds an empty wrapper message instance for the given wrapper field (a field whose message is the wrapper shape). The caller appends elements to the returned list and stores the message value on the field.

func OrderingFieldPair

func OrderingFieldPair(a, b Value) bool

OrderingFieldPair reports whether both ordering values are plain FieldValue column reads. It is the TYPE test that dispatches the two ordering comparators: a pair inside this class is decided by SameOrderingColumn and by nothing else, with no fallthrough.

Finality is what the type test buys: an UNKNOWN-domain or rootless FieldValue cannot fall through to a weaker comparison and bridge two distinct exact columns (StatesOrderingColumn carries that witness).

A CardinalityValue wrapping a field is deliberately OUTSIDE the class. It is not a column of any row layout, so it has no column identity to state and is matched as a whole Value instead.

func OrdinalCarrierMatchState

func OrdinalCarrierMatchState(
	layout OrdinalLayout,
	presence WindowMatchPresence,
) (matched bool, known bool, err error)

OrdinalCarrierMatchState reads the optional whole-current-object state after exact-recognizing both inputs. Absence of a carrier marker is not an error: ordinary rows predate no match decision and are therefore treated as present by their executor owner. A hostile presence implementation is never invoked through its public interface.

func OrdinalFieldName

func OrdinalFieldName(ordinal int) string

OrdinalFieldName is the display name 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 positional row type carries these names for the WITH-ORDINALITY element/ordinal slots; an ordinal-addressed FieldValue (Java's `FieldValue.ofOrdinalNumber`) reads the slot by ordinal.

func OrdinalSeedLegLayout

OrdinalSeedLegLayout is OrdinalSeedLegWindowsAcceptingNested plus the TOP-LEVEL RUN LIST: the windows that TILE the merged row, in offset order.

THE MAP CANNOT SERVE THIS, and that is why the walk returns it rather than a caller deriving it. finalizeSeedWindows' rightmost-leaf case REPLACES a box run's own entry with a narrower sub-window — deliberately, because the box IS its rightmost leaf under the sourceBinding convention and an alias-qualified read must window the leaf rather than look the name up across the whole concat. So after finalization "the windows that tile the row" is simply not recoverable from the map: one of the tiles has been overwritten by something narrower, and nothing distinguishes that from a seed that always had a narrow leg there.

It is the planner twin of what the executor already returns — ordinalJoinSpansOf's `spans []legSpan`, in offset order — which is the shape this list is modelled on rather than invented against.

Callers that only need the addressable map keep the two-value entries; this answers the different question "how many legs TILE this row, and what shape is each".

The run list preserves tiling that finalization's narrower map entries lose; it has no production consumer.

func OrdinalWindowMatchState

func OrdinalWindowMatchState(
	layout OrdinalLayout,
	presence WindowMatchPresence,
	source QuantifiedObjectValue,
) (bool, error)

OrdinalWindowMatchState returns the exact per-row match state of one null-supplying source window. Both layout and presence are values-owned and exact-recognized; missing state is a malformed physical row, never an invitation to infer absence from all-NULL field values.

func OutputColumnName

func OutputColumnName(v Value, alias string) string

OutputColumnName is the projection OUTPUT-name authority: the name that keys the emitted positional row's slot for a projected column, 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 — two copies of this rule have disagreed before (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 delegate here.

func ParseJavaUUID

func ParseJavaUUID(s string) ([16]byte, bool)

ParseJavaUUID parses s exactly as java.util.UUID.fromString does: five dash-separated hex components, each read by Long.parseLong(radix 16) (so a sign, Unicode digits and short or over-wide components are accepted) and masked to its field width; no braces, URN prefix or undashed form.

func ParseTemporalText

func ParseTemporalText(s string) (time.Time, error)

ParseTemporalText reads the text of a DATE or TIMESTAMP value, in UTC. The year domain keeps every canonical text parseable and in instant order: an offset can carry a year-9999 text into year 10000 in UTC.

func ProjectionColumnName

func ProjectionColumnName(v Value) string

ProjectionColumnName is the projection output-column NAMING CONTRACT: the name a projected Value's result is keyed under, alias-absent, in the emitted positional row's type. A NESTED FieldValue projects under its resolved PATH ("N.SK"); any other FieldValue under its (possibly dotted) Field; any other Value under its upper-cased ORDINAL-FREE 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 loud OrdinalResolutionError on valid SQL.

ORDINAL-FREE IS THE WHOLE POINT OF THE THIRD ARM, and it was ExplainValue until the corpus showed what that costs. An ordinal is a PLAN-TIME BINDING of a reference; a column's name is not, so a name carrying one changes when the same reference is baked — the lockstep ColumnNameValue exists to hold. The composite arm was the one route that could mint such a name (the other two return schema text), and it did: `SELECT id + 1` inside a CTE keyed its output `(C1.ID#0 + 1)`, which the enclosing projection then re-read as a FIELD whose text contains a `#`, so the explain escape doubled it and the slot key read `(C1.ID##0 + 1)`. One line of the corpus carried it (cte.yaml#25) — the escape mechanism is in explainValueOrdinals' fieldValue arm, which now doubles only when it is rendering ordinals to disambiguate from.

The nested arm is NOT a special case bolted on: it is the same rule the sort side already applies (sortKeyExtraColumnName) and the same rule Java applies to every resolved reference. `Field` carries ONE segment — the struct root when this was written, the leaf now — so without the path `SELECT n.sk, n.co` emitted two slots named `N` (measured, visible to the user as duplicate column labels over correct data) and `SELECT t1.n.sk, sk` would emit two named `SK`. The path is what separates them.

func ProjectionOutputIdentityKey

func ProjectionOutputIdentityKey(v Value, alias string) string

ProjectionOutputIdentityKey returns an opaque, boundary-safe discriminator for the parts of a projection's executor-visible output name that semantic Value identity does not already preserve.

A non-empty alias is the entire output-name authority, normalized exactly as OutputColumnName normalizes it. Without an alias, the Value's tree shape, operators, literals, and correlation structure already participate in semantic identity; the missing discriminator is every FieldValue's rendered display path. In particular, baked FieldValues compare by ordinal path alone, while ProjectionColumnName and ExplainValue still render their Field text (and a multi-accessor Explain renders every resolvedAccessor.Field). Walking all nested FieldValues therefore distinguishes both A#0 from B#0 and arithmetic expressions containing those reads.

CorrelationIdentifier spellings are deliberately excluded. They are alpha-renamable planner binders, not SQL output aliases: SemanticEqualsUnderAliasMap equates their Values through an AliasMap and SemanticHashCode is alias-invariant so hash-first memo lookup can find those equal expressions. A stable SQL-visible projection name is carried by an explicit projection alias or by FieldValue display paths, both folded here.

func ProjectionOutputSchemaIdentityOverrides

func ProjectionOutputSchemaIdentityOverrides(
	projections []Value,
	aliases []string,
	outputNames []string,
) ([]string, error)

ProjectionOutputSchemaIdentityOverrides returns only the externally frozen portion of a projection schema: each slot whose authoritative output name differs from the name the Value program and aliases naturally derive. The resulting sparse vector is suitable for memo identity.

This distinction is load-bearing. Internal Value names can contain alpha-renamable correlation identifiers (a scalar-subquery QOV is the canonical example), so folding every derived result field name into a hash breaks alias invariance. Conversely, an SQL boundary may deliberately freeze a different positional key (`S.ID` over a Value naturally named `ID`); that difference is executable schema and must keep the projections apart. nil is returned when no frozen name adds information beyond the natural schema.

func ProjectionSlotName

func ProjectionSlotName(v Value, alias string) string

ProjectionSlotName is the name a projection's frozen output schema gives a slot BEFORE deduplication — the alias when the item carries one, the display name (qualifier stripped) for a column reference, and OutputColumnName's rendering for everything else. It is the rule exactProjectionForLogicalProject freezes with, and the rule a consumer must re-derive the natural schema by when it asks whether a frozen name is that schema's own deduplication suffix or an external rename. Two copies of the rule have disagreed before: the natural schema was once re-derived by OutputColumnName alone, which names a nested reference by its dotted path (`N.SK`) where the freeze names it `SK`, so `SELECT sk, n.sk` read the frozen `SK_2` as a rename and published the suffix as a label.

func ProtoFieldReadsValue

func ProtoFieldReadsValue(m protoreflect.Message, fd protoreflect.FieldDescriptor) bool

ProtoFieldReadsValue is the presence rule by which a query reads a record's field: a repeated field is always read (as its list), a singular one only when it is set, and is otherwise NULL. Set is protobuf-java's hasField for either kind of presence, so an implicit-presence (proto3) field at its default is NULL.

An unset proto2 field that declares a default is NULL too, though Java's field reader, MessageHelpers.getFieldOnMessage (MessageHelpers.java:124-142), reads the default: a query never hands it the stored record. QueryResult.fromQueriedRecord (QueryResult.java:256-281) first copies the record into a message of the plan's type (MessageHelpers.deepCopyMessage, which copies getAllFields, the set fields), whose descriptor, generated from the type, declares no default. Measured through SQL on both engines (conformance "WS-J an unset field with a declared default reads as the target reads it"): SELECT *, a projection and a predicate all read NULL.

func ProtoFieldToRowValue

func ProtoFieldToRowValue(fd protoreflect.FieldDescriptor, v protoreflect.Value) any

ProtoFieldToRowValue converts one proto FIELD value to the engine's row-value domain — the SINGLE conversion both the executor's record→row materialization and this package's struct descent use (exported so the two cannot drift; the executor's protoFieldToGo delegates here). Repeated fields become []any (a downstream Explode's collection); a proto map stays its raw Go value; scalars and UUID/message leaves go through protoScalarToRowValue.

func ProtoRecordDescriptorCompatible

func ProtoRecordDescriptorCompatible(descriptor protoreflect.MessageDescriptor, declared ExactTypeHandle) bool

ProtoRecordDescriptorCompatible admits a protobuf-backed output carrier against an exact logical declaration. Storage is addressed by ordinal, not logical field names. Logical scalar/record nullability is not descriptor presence; nullable arrays may also read an already-unwrapped repeated field. Duplicate declared names are not representable as a protobuf record type; machinery-owned duplicate columns retain their ordinal-row representation.

func ProtoScalarKindToRowValue

func ProtoScalarKindToRowValue(kind protoreflect.Kind, v protoreflect.Value) any

ProtoScalarKindToRowValue is the kind-keyed scalar conversion (no UUID/ message handling — that needs the descriptor, see protoScalarToRowValue). Exported as the single source of truth the executor's kind-based conversion calls directly, so the record→row and struct-descent conversions cannot drift on the scalar arms.

func PullUpValues

func PullUpValues(toBePulledUp []Value, resultValue Value, alias CorrelationIdentifier) (map[Value]Value, error)

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 QuantifiedRowShapesAgree

func QuantifiedRowShapesAgree(left, right Type) bool

QuantifiedRowShapesAgree reports whether two exact QOV flowed types denote the SAME BOUND ROW. It is the one comparison every runtime QOV *lookup* uses, and it deliberately excludes the top-level nullable bit.

That bit is not part of a row's shape: on a quantifier it declares that the quantifier's row may be ABSENT, and absence is carried structurally by the binding itself — a nil row, or a positive explicit-absence proof — never by the row's type. Evaluating FieldValue(qov, i) against a present row is bit-identical whichever way the bit is set, and against an absent one both yield NULL, so the bit can decide nothing at a lookup.

One alias therefore legitimately carries two QOVs differing only there. That pairing is Java's, not a Go accident: an outer join's OUTPUT columns are pulled up through Quantifier.pullUpResultColumnsWithNullability(true), which mints QuantifiedObjectValue.of(alias, rowType.withNullability(true)), while the same alias's ON/WHERE predicates keep reading getFlowedObjectValue() — the leg's own, non-nullable row. Java binds both by alias alone; Go's exact channel keeps the strictly stronger check on everything that IS shape.

Field names, ordinals, arity, record names and every NESTED nullability still have to match exactly, so a foreign owner spelled with the same alias is still refused. Type DERIVATION sites (layout window construction, the null-supplying proofs, metadata nullability) must keep comparing with Equals: there the bit is the whole point.

func QuantifierFlowsAScalarRow

func QuantifierFlowsAScalarRow(value Value) bool

QuantifierFlowsAScalarRow reports whether value is a quantified object value whose flowed row is NOT a record — the shape an UNNEST leg over a scalar array produces, where the quantifier's "row" is one bare value rather than a struct.

It exists because both callers were spelling the same three-part test inline (is it a QOV, can it state a row, is that row a non-record) and the middle part is only there to make the third safe. Naming the question keeps the guard from being read as redundant and dropped, which would turn "cannot state a row" into "flows a scalar row" — the wrong answer, and a silently wrong output LABEL rather than a crash.

func RangeAliasPairs

func RangeAliasPairs(m AliasMap, yield func(AliasPair) bool) bool

RangeAliasPairs calls yield for each pair of m until it returns false, and reports whether every call returned true. The order is unspecified.

func ReadsConstantPool

func ReadsConstantPool(v Value) bool

DependsOnStatementClock reports whether the value tree contains a CURRENT_TIMESTAMP-family function — one whose result is defined by the statement clock rather than by its (zero) arguments. The executor computes this ONCE per operator to decide whether a bare frontier row must be wrapped in a clock-bearing RowEvalContext: evaluating such a value against a bare OrdinalRow falls back to per-row time.Now() and drifts across the rows of one statement, which SQL forbids. ReadsConstantPool reports whether v dereferences a statement constant pool, which only a RowEvalContext with the statement binder can resolve.

func RecordNameForDescriptor

func RecordNameForDescriptor(descriptor protoreflect.MessageDescriptor) string

RecordNameForDescriptor is FieldNameForProtoField's twin for the record's own name, un-escaped by the same rule.

func ResolveAssignmentColumn

func ResolveAssignmentColumn(names []string, column string) (idx, hits int)

ResolveAssignmentColumn resolves one name of a DML statement's assigned field (a segment of an UPDATE's SET column: a qualifier, a column or a struct field) among the names at that level, to its position. names are user identifiers: a descriptor field's storage name decoded once (FieldNameForProtoField). The caller (the SET column's resolution) walks the segments level by level, as Java's SemanticAnalyzer resolves the identifier against the target Type.Record, and the FieldPath it builds carries the resolved ordinals RecordQueryUpdatePlan keys its transformation trie by, so nothing looks the name up again. Nothing here may decode a name a second time: the storage escaping is not injective under it (`a$b` is stored as a__1b, `a__1b` as a__01b, and decoding `a__1b` again gives `a$b`).

column is normalized (a quoted identifier keeps its case, an unquoted one is upper case). An exact match wins; otherwise one case-insensitive match does, the lookup extension DIVERGENCES.md declares ("Identifier resolution: Go over-resolves case"). hits is the number of columns the deciding pass matched: 1 resolved (idx is its position), 0 no such column, more than one ambiguous.

func RowValuesFromMessage

func RowValuesFromMessage(msg protoreflect.Message) []any

RowValuesFromMessage is MessageFromRowValues' inverse: each field of msg in the row domain, nil where unset.

func SameColumnPath

func SameColumnPath(a, b *fieldPath) bool

SameColumnPath reports whether two RESOLVED accessor paths denote the same column. It is the ORDINAL-PATH element of the identity triple asked BETWEEN two references, rather than resolved into a caller's stated layout the way IdentityIn is — the shape a matcher holding both operands needs. The CORRELATION element is not covered here; SameOrderingColumn compares it separately before consulting this path predicate.

Java's FieldPath.equals is element-wise ordinal equality with the per-step name excluded (FieldValue.java:411-420, over resolvedAccessor.equals at :676-685, which is getOrdinal()-only). Go needs two proofs on top, both for shapes Java cannot express:

  • the DOMAIN, KNOWN on both sides and equal. Java's childValue is non-null and typed, so the layout an ordinal indexes is always derivable; Go mints childless bakes, and two ordinal-equal paths can address two different layouts. An ordinal conflation reads as authoritative, which is strictly worse than the name conflation it would replace.
  • a NON-NEGATIVE ordinal at every step. Java asserts ordinal >= 0 at construction (FieldValue.java:651); Go mints Ordinal -1 name-only accessors at its unnest/gather/index-expansion seeds. Two of those are ordinal-equal BY CONSTRUCTION, so an ordinal comparison over them is vacuous and would bind two distinct nested fields as one.

Both declines are the fail-closed direction: a refused match costs a rewrite, an accepted one binds the wrong column.

func SameLeg

func SameLeg(a, b CorrelationIdentifier) bool

SameLeg reports whether two identifiers name the same quantifier — the CORRELATION element of RFC-197's identity triple, compared in ONE place so every proof that asks "does this value read that leg?" gets the same answer.

The comparison is EXACT, matching Java, whose CorrelationIdentifier.equals is `Objects.equals(id, that.id)` (CorrelationIdentifier.java:132).

Exactness is not merely Java-fidelity here — it is load-bearing. Alias namespaces in this planner are deliberately case-DISJOINT: the semantic scope upper-folds every user correlation at its single registration chokepoint (semantic/scope.go), while UniqueCorrelationIdentifier mints the machine counter in LOWERCASE (`q$1`). scope.go states the consequence it is protecting: a quoted `"q$5"` cannot forge a planner-minted q$5. A case-folding comparison erases exactly that protection — it lets a user alias that upper-folds onto the minted namespace be accepted as the minted leg, and every caller of this helper is a proof about which row a value reads. A forged match there is a wrong-rows plan or a fabricated cardinality, not a lost optimization.

The same call was already made independently at the qualified-key rewrite in rule_implement_nested_loop_join.go, whose comment reads "a fold here would let a quoted user alias cross into the lowercase machine namespace". This helper now agrees with it rather than contradicting it.

Folding was tempting because the translator does not upper-case aliases consistently — some paths fold an alias at construction and others pass the spelling through verbatim — so an exact comparison can fail to recognize a leg that really is the right one. (This used to cite three specific translator lines; two of them had already drifted onto unrelated code, which is why the claim is stated structurally now. A line number is not a citation once the file moves under it.) That costs a DECLINE — every caller reads "cannot tell" as "do not apply the correction" — and it is the translator's inconsistency to fix at the source, not this helper's to mask. Masking it here would trade a recoverable missed optimization for an unrecoverable forged identity. An UNSTATED identifier (the Go zero value, empty name) names nothing, and two of them name nothing in common. Go's zero value has no Java analogue — Quantifier.getAlias() is @Nonnull and a CorrelationIdentifier is never constructed empty — so the only way to hold one here is a producer that forgot to state an identity. Answering "same leg" for that pair is how an unstated-identity leg binds a zero-value correlation and starts serving its slots: every caller reads true as "this correlation names this leg". Declining turns the omission into the miss it actually is.

func SameOrderingColumn

func SameOrderingColumn(a, b Value) bool

SameOrderingColumn reports whether two ORDERING Values denote the same column by identity: the same ordinal path in the same STATED layout, read off the same exact root. Both sides must have stated an identity; a side that has not declines, and nothing here consults a display name.

It is the ordinal-domain counterpart of CanBridgeOrderingValueRoots' name comparison, and it exists because the obvious alternative is unsound: ValuesStructurallyEqual routes two baked FieldValues through FieldPath.Equals, which is ordinal-only and DOMAIN-BLIND (Java's resolvedAccessor.equals, FieldValue.java:675-689 — sound there because a Java FieldValue always has a non-null typed childValue, so the layout an ordinal indexes is never in question). RFC-232 now gives both candidate and request keys exact QOV roots. Requiring root equality keeps self-join columns apart and makes the comparator reflexive, symmetric, and transitive.

func ScalarFunctionNames

func ScalarFunctionNames() []string

ScalarFunctionNames returns a fresh sorted snapshot of registered spellings. Aliases remain separate because each is an independently reachable SQL name.

func SemanticEqualsUnderAliasMap

func SemanticEqualsUnderAliasMap(a, b Value, aliases AliasMap) bool

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

func SemanticHashCode(v Value) uint64

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 SemanticHashCodeIn

func SemanticHashCodeIn(h io.Writer, v Value) uint64

SemanticHashCodeIn is SemanticHashCode in the mode of the enclosing hash h.

func SetCensusHooks

func SetCensusHooks(leg *CensusHooks, ordering *OrderingHooks)

SetCensusHooks installs (or, with nil, removes) the two census slots.

func SetRelOpEvaluator

func SetRelOpEvaluator(f func(comparison RelOpComparison, left, right any) (any, error))

SetRelOpEvaluator installs the comparison evaluation RelOpValues use.

func StatesOrderingColumn

func StatesOrderingColumn(v Value) bool

StatesOrderingColumn reports whether ONE ordering value has stated a column identity SameOrderingColumn can read — a flat-or-nested resolved path in a known layout, off an exact quantifier root.

It is deliberately a ONE-VALUE predicate, and that shape is the whole point. The pairwise form it replaced ("do BOTH sides state an identity?") was used to DISPATCH: identity decided the pair when both stated one, and a pair where either side did not fell through to the domain-blind structural comparison. That dispatch is INTRANSITIVE inside the FieldValue class. Witness, all three values baked at ordinal path [0]:

A = [0] in layout D1          states an identity
B = [0] in layout D2          states an identity
U = [0], layout UNKNOWN       states none

Identity separates A from B (different layouts, EqualsWithoutChildren's FieldValue arm never looks at the layout). Availability dispatch sends both A~U and B~U to the structural arm, which compares ordinals only and says EQUAL. So U≡A, U≡B, A≢B — and a comparator that is not an equivalence relation makes every set it builds depend on INSERTION ORDER, which is a nondeterministic plan.

So dispatch is by TYPE — both operands *fieldValue means identity decides and the decision is FINAL — and this predicate exists only to CLASSIFY the population, never to choose an arm. A value that does not state an identity is UNADDRESSABLE: the comparator declines it, and the fix belongs at the producer that minted it without a layout.

func StringToEnumNumber

func StringToEnumNumber(ed protoreflect.EnumDescriptor, name string) (int64, error)

StringToEnumNumber is Java's PromoteValue.stringToEnumValue over a stored enum descriptor (PromoteValue.java:151-161): the first declared value whose user identifier (ProtoUtils.toUserIdentifier of its name) equals name, else INVALID_ENUM_VALUE. It is what writes a string into an enum column, where Java's STRING_TO_ENUM promotion runs; no other type promotes to an enum.

func ToFloat64

func ToFloat64(v any) (f float64, isFloat, numeric bool)

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 ToInt64

func ToInt64(v any) (int64, bool)

ToInt64 reports whether v is an integral type; returns the int64 promotion when so.

func TupleElementToRowValue

func TupleElementToRowValue(v any) any

TupleElementToRowValue converts a decoded tuple element read off an index entry or primary key into the row domain base records are read into, so a column compares, sorts, dedups and joins alike whichever access path sourced it: a tuple UUID is [16]byte, a FLOAT (a 32-bit tuple float) is float64 as ProtoScalarKindToRowValue widens it, and a VERSION index's versionstamp is the record version's 12 raw bytes (FDBRecordVersion.toBytes). Java's tupleValueToRuntimeValue conversions (INT, BYTES, ENUM) are identities here.

func TypeTerminatesOrderingClaim

func TypeTerminatesOrderingClaim(t Type) bool

TypeTerminatesOrderingClaim returns true for FLOAT/DOUBLE because tuple NaN ordering differs from logical ordering. It ignores scan bounds.

Unknown layouts retain sort elimination; soundness depends on SQL columns carrying types. Keep range-aware refinements here so planner and rowdiff use the same policy.

func ValidateOrdinalJoinSeedForLegs

func ValidateOrdinalJoinSeedForLegs(rc *RecordConstructorValue, legs []QuantifiedObjectValue) error

ValidateOrdinalJoinSeedForLegs checks the complete declared input population, including zero-width legs which cannot be inferred from field runs. Each non-empty leg must contribute every direct, frontier-pinned ordinal exactly once, in declaration order. Empty legs contribute multiplicity, not fields.

func ValidateOrdinalLayoutAdmission

func ValidateOrdinalLayoutAdmission(view OrdinalLayout) error

ValidateOrdinalLayoutAdmission exact-recognizes a layout without invoking methods on a hostile interface implementation.

func ValidateProjectionAliasSources

func ValidateProjectionAliasSources(
	sources []ProjectionAliasSource,
	aliasMinted []bool,
	slots int,
) error

ValidateProjectionAliasSources checks a slot-parallel alias-source vector. A source can exist only for a machinery-minted alias, and absence must carry no hidden correlation. A short vector is valid and means uncaptured sources.

func ValidateRequiredBindingsAdmission

func ValidateRequiredBindingsAdmission(view RequiredBindings) error

ValidateRequiredBindingsAdmission exact-recognizes a binding manifest without invoking methods on a hostile interface implementation.

func ValueSize

func ValueSize(v Value) int

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

func ValuesStructurallyEqual(a, b Value) bool

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

func WalkValue(v Value, visit func(Value) bool)

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 AccessorPathClass

type AccessorPathClass int

AccessorPathClass is one call's outcome. These partition every call to AccessorNamePath.

const (
	AccessorPathOKAllBaked AccessorPathClass = iota
	AccessorPathOKHasLazy
	AccessorPathDeclineDotted
	AccessorPathDeclinePureOrdinal
	AccessorPathDeclineEmptyName
	AccessorPathDeclineNotAColumn
	AccessorPathClassCount
)

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
	// AggBitmapConstructAgg is BITMAP_CONSTRUCT_AGG(expr): Java's
	// NumericAggregationValue.BitmapConstructAgg, over an INT or LONG operand,
	// a BYTES bitmap. Go has no streaming accumulator for it; it reaches the
	// graph so an index definition can be built from it.
	AggBitmapConstructAgg
	// AggArrayAgg is ARRAY_AGG(expr [IGNORE|RESPECT NULLS] [LIMIT n]): Java's ArrayAggValue.
	AggArrayAgg
)

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
	// IgnoreNulls and Limit are ARRAY_AGG's null treatment and in-call LIMIT
	// (ArrayAggNoLimit when absent); zero for every other op.
	IgnoreNulls bool
	Limit       int
}

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 NewArrayAggValue

func NewArrayAggValue(operand Value, ignoreNulls bool, limit int) *AggregateValue

NewArrayAggValue is ARRAY_AGG(operand) with its null treatment and limit.

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       → permuted_min    (current-extremum index, tracks deletes)
AggMax       → permuted_max    (current-extremum index, tracks deletes)
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(*): NullableLong. COUNT is non-null inside its own group, but a GroupBy row can itself be null-supplied by an outer relational edge; the exact flowed aggregate-row contract therefore carries the widened nullable type.
  • 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).

func (*AggregateValue) WithOperand

func (a *AggregateValue) WithOperand(operand Value) *AggregateValue

WithOperand copies a with a new operand, keeping every option.

type AliasMap

type AliasMap interface {
	Target(CorrelationIdentifier) (CorrelationIdentifier, bool)
	Source(CorrelationIdentifier) (CorrelationIdentifier, bool)
	// contains filtered or unexported methods
}

AliasMap is an immutable, validated bijection. The reverse lookup is part of the contract because composing or extending an alias map must not silently admit two sources for one target.

func EmptyAliasMap

func EmptyAliasMap() AliasMap

EmptyAliasMap returns the immutable validated identity map. It avoids making callers handle the impossible NewAliasMap(nil) error path.

func ExtendAliasMap

func ExtendAliasMap(base AliasMap, pairs []AliasPair) (AliasMap, bool, error)

ExtendAliasMap returns an immutable extension. A legitimate pairing conflict reports compatible=false; malformed or foreign input is an error.

func NewAliasMap

func NewAliasMap(pairs []AliasPair) (AliasMap, error)

NewAliasMap validates and snapshots pairs as a bijection. Current is a reserved correlation kind and may map only to itself.

type AliasPair

type AliasPair struct {
	Source CorrelationIdentifier
	Target CorrelationIdentifier
}

AliasPair is one source-to-target alpha-renaming entry.

type AndOrOp

type AndOrOp int

AndOrOp identifies the boolean connector. Mirrors Java's `AndOrValue.Operator` enum.

const (
	// AndOrAnd is short-circuit logical AND with Kleene 3VL.
	AndOrAnd AndOrOp = iota
	// AndOrOr is short-circuit logical OR with Kleene 3VL.
	AndOrOr
)

func (AndOrOp) String

func (op AndOrOp) String() string

String returns the SQL keyword for explain / debug print.

type AndOrValue

type AndOrValue struct {
	Op    AndOrOp
	Left  Value
	Right Value
}

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: NullableBoolean, as Java's AndOrValue (a BooleanValue).

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) Name

func (v *AndOrValue) Name() string

Name returns the SQL keyword.

func (*AndOrValue) Type

func (*AndOrValue) Type() Type

Type is NullableBoolean whatever the operands: Java's AndOrValue does not override BooleanValue.getResultType, primitiveType(BOOLEAN), which is nullable (BooleanValue.java:40-42).

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 ArithmeticComplexOperandError

type ArithmeticComplexOperandError struct{}

ArithmeticComplexOperandError is Java's SemanticException ARGUMENT_TO_ARITHMETIC_OPERATOR_IS_OF_COMPLEX_TYPE, raised by ArithmeticValue.encapsulate (ArithmeticValue.java:215-220) for an operand whose type is not primitive (ENUM, RECORD, UUID, ARRAY).

func (*ArithmeticComplexOperandError) Error

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

type ArithmeticLane

type ArithmeticLane struct {
	Function    string
	Left, Right TypeCode
	Result      TypeCode
}

ArithmeticLane is one row of Java's ArithmeticValue.PhysicalOperator table (ArithmeticValue.java:406-522): a logical operator, the operand type codes it is defined over, and its result type code. Function is the logical operator's lower-case name, the name a key expression's function carries (MaterializedViewIndexGenerator.java:574).

func ArithmeticLanes

func ArithmeticLanes() []ArithmeticLane

ArithmeticLanes is a copy of the whole table, in Java's order.

func EncapsulateArithmeticLane

func EncapsulateArithmeticLane(function string, left, right TypeCode) (ArithmeticLane, error)

EncapsulateArithmeticLane is ArithmeticValue.encapsulate's decision over two operand type codes, in Java's order: each operand's type must be primitive (ArithmeticComplexOperandError, the left checked first), then the operator must have a lane over the pair (ArithmeticLaneMismatchError).

func LookupArithmeticLane

func LookupArithmeticLane(function string, left, right TypeCode) (ArithmeticLane, bool)

LookupArithmeticLane is Java's getOperatorMap().get(new BinaryOperatorSignature(operator, left, right)): the row for function (any case) over the two operand type codes, if there is one.

type ArithmeticLaneMismatchError

type ArithmeticLaneMismatchError struct{}

ArithmeticLaneMismatchError is Java's VerifyException from ArithmeticValue.encapsulate (ArithmeticValue.java:226-229): no physical operator takes the two operand types.

func (*ArithmeticLaneMismatchError) Error

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
	// The bit and bitmap operators are ArithmeticValue's logical operators
	// too (Java's LogicalOperator, ArithmeticValue.java:366-378), resolved
	// through the same lane table.
	OpBitOr
	OpBitAnd
	OpBitXor
	OpBitmapBucketNumber
	OpBitmapBucketOffset
	OpBitmapBitPosition
)

func ArithmeticOpForLogicalName

func ArithmeticOpForLogicalName(name string) (ArithmeticOp, bool)

ArithmeticOpForLogicalName is the operator a lane's function names.

func (ArithmeticOp) LogicalOperatorName

func (o ArithmeticOp) LogicalOperatorName() string

LogicalOperatorName is Java's LogicalOperator name in lower case: the name the lane table (arithmetic_lanes.go) and a key expression's function carry (getLogicalOperator().name().toLowerCase()).

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 {
	Long bool
}

ArithmeticOverflowError is returned by ArithmeticValue.Evaluate when integer arithmetic overflows. Callers (the executor) convert this to SQLSTATE 22003 NUMERIC_VALUE_OUT_OF_RANGE. Long marks an overflow in a LONG lane, whose message is Java's Math.*Exact(long) "long overflow"; an INT lane's is "integer overflow".

func (*ArithmeticOverflowError) Error

func (e *ArithmeticOverflowError) Error() string

type ArithmeticValue

type ArithmeticValue struct {
	Op    ArithmeticOp
	Left  Value
	Right Value
	// contains filtered or unexported fields
}

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 NewArithmeticValue

func NewArithmeticValue(op ArithmeticOp, left, right Value) (*ArithmeticValue, error)

NewArithmeticValue is Java's ArithmeticValue.encapsulate (ArithmeticValue. java:213-231): the lane is resolved once, here, from the operand types, and an operand pair Java refuses is refused (EncapsulateArithmeticLane). An operand of unknown type defers the lane to the runtime operands, since Go cannot know what Java would have typed it; a known complex operand is refused even then, as Java checks each operand before the lane.

func (*ArithmeticValue) Children

func (a *ArithmeticValue) Children() []Value

func (*ArithmeticValue) Evaluate

func (a *ArithmeticValue) Evaluate(evalCtx any) (any, error)

func (*ArithmeticValue) Lane

func (a *ArithmeticValue) Lane() (ArithmeticLane, bool)

Lane is the physical operator the value was constructed with, and false when its operands' types were unknown then.

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 INT when BOTH are INT (Java's ADD_II/DIV_II/MOD_II declare result INT — without this the static property re-erases the width the lane dispatch keys on, and `(a+b)+c` over INT columns escapes the int32 bounds at the outer op), else LONG (the conservative integer default, also used when an operand type is unknown). NULL propagates through Evaluate, so the result is nullable.

func (*ArithmeticValue) WithOperands

func (a *ArithmeticValue) WithOperands(left, right Value) *ArithmeticValue

WithOperands is a with the operands replaced and its lane kept, as Java's withChildren keeps the physical operator (ArithmeticValue.java:138-143).

type ArrayConstructorValue

type ArrayConstructorValue struct {
	ElementType Type
	Elements    []Value
}

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`).

The explicit-type constructor, like Java's of(children, elementType), expects the planner to resolve and promote its children first. It does not validate them; Evaluate returns their values verbatim. Reconstruction validates the retained element type before injecting promotions, so a rewrite cannot silently attach incompatible children to that metadata.

Result type: non-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 NewLightArrayConstructorValue

func NewLightArrayConstructorValue(items []Value) (*ArrayConstructorValue, error)

NewLightArrayConstructorValue is the `__internal_array` built-in, AbstractArrayConstructorValue.encapsulateInternal: the element type is the maximum of the items' types, and an item whose type differs other than in nullability is promoted to it (AbstractArrayConstructorValue.java:144-178).

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`.

The raw Go constructor tolerates nil child Values as nil elements. Java rejects nil children when copying its constructor arguments.

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.

The UNTYPED empty literal `[]` (element type NONE) is special: its result type is the bare NONE type, not Array(NONE) — matching Java's emptyArrayOfNone (AbstractArrayConstructorValue.java:304, getResultType() returns Type.noneType()). NONE is what the promotion lattice keys on (NONE_TO_ARRAY; Type.maximumType's NONE arms), so `arr = []` promotes the literal to the column's ARRAY type instead of failing an Array(NONE)-vs-Array(T) recursion.

func (*ArrayConstructorValue) WithChildren

func (v *ArrayConstructorValue) WithChildren(newChildren []Value) *ArrayConstructorValue

WithChildren retains the declared element type, rejecting incompatible replacement children with nil. Checked planners use WithChildrenChecked to retain the reconstruction diagnostic.

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 comparableEqual for other types, including protobuf message value equality.

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

func NewArrayType(nullable bool, elementType Type) *ArrayType

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) Code

func (*ArrayType) Code() TypeCode

Code implements Type — always TypeCodeArray.

func (*ArrayType) Equals

func (a *ArrayType) Equals(other Type) bool

Equals implements Type. Structural — Nullable + ElementType.Equals. Two ArrayTypes both with nil ElementType are equal; one nil + one non-nil are not.

func (*ArrayType) IsErased

func (a *ArrayType) IsErased() bool

IsErased reports whether the array's element type isn't filled in yet. Mirrors Java's `Type.Array.isErased()` — typically true for the empty-array literal `[]` before inference resolves what it should adopt from context (target column / sibling expression).

func (*ArrayType) IsNullable

func (a *ArrayType) IsNullable() bool

IsNullable implements Type.

func (*ArrayType) String

func (a *ArrayType) String() string

String implements Type. Renders as `ARRAY<INT NOT NULL> NULL` / `ARRAY<?>` (when ElementType is nil).

type BakedNameContextError

type BakedNameContextError struct {
	Field   string
	Ordinal int
}

BakedNameContextError reports a BAKED FieldValue (ordinal authoritative) evaluated against a NAME-keyed or unrecognized row context. 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 ordinal identity exists to avoid. (A nil context stays NULL — that is the appendNullLeg / nil-binding path.)

func (*BakedNameContextError) Error

func (e *BakedNameContextError) Error() string

type BinaryRelOpValue

type BinaryRelOpValue struct {
	FunctionName string
	Comparison   RelOpComparison
	Left, Right  Value
	// contains filtered or unexported fields
}

BinaryRelOpValue is Java's RelOpValue.BinaryRelOpValue: a binary comparison as a nullable boolean value, typed by its physical operator.

func NewBinaryRelOpValue

func NewBinaryRelOpValue(comparison RelOpComparison, left, right Value) (*BinaryRelOpValue, error)

NewBinaryRelOpValue is RelOpValue.encapsulate for two arguments (RelOpValue.java:340-382).

func (*BinaryRelOpValue) Children

func (v *BinaryRelOpValue) Children() []Value

func (*BinaryRelOpValue) EqualsWithoutChildrenValue

func (v *BinaryRelOpValue) EqualsWithoutChildrenValue(other Value) bool

func (*BinaryRelOpValue) Evaluate

func (v *BinaryRelOpValue) Evaluate(evalCtx any) (any, error)

Evaluate is BinaryPhysicalOperator.eval: a NULL operand makes the result NULL except for the null-safe comparisons; otherwise the operator decides.

func (*BinaryRelOpValue) Name

func (v *BinaryRelOpValue) Name() string

func (*BinaryRelOpValue) PhysicalOperator

PhysicalOperator is the operator's proto enum.

func (*BinaryRelOpValue) SemanticHashDiscriminator

func (v *BinaryRelOpValue) SemanticHashDiscriminator() uint64

func (*BinaryRelOpValue) Type

func (*BinaryRelOpValue) Type() Type

Type is BooleanValue.getResultType: nullable BOOLEAN.

func (*BinaryRelOpValue) WithChildrenValue

func (v *BinaryRelOpValue) WithChildrenValue(newChildren []Value) Value

type BindingOrigin

type BindingOrigin uint8

BindingOrigin classifies one exact QOV used by a physical evaluation phase. Origins are disjoint: a correlation may never be both an edge and a window, or both an external and an edge.

const (
	BindingOriginInvalid BindingOrigin = iota
	BindingOriginCurrent
	BindingOriginEdge
	BindingOriginWindow
	BindingOriginExternal
)

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 NewBooleanValue

func NewBooleanValue(v bool) *BooleanValue

NewBooleanValue wraps a Go bool.

func (*BooleanValue) Children

func (*BooleanValue) Children() []Value

func (*BooleanValue) Evaluate

func (b *BooleanValue) Evaluate(any) (any, error)

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 CallSiteArguments

type CallSiteArguments struct {
	// contains filtered or unexported fields
}

CallSiteArguments is Java's CallSiteArguments: the arguments of one function invocation, positional or named, with its call-site options and window specification. A value is immutable; the With methods return a copy.

func NamedCallSite

func NamedCallSite(names []string, values []Value) CallSiteArguments

NamedCallSite is CallSiteArguments.ofNamed, in the given order.

func PositionalCallSite

func PositionalCallSite(values ...Value) CallSiteArguments

PositionalCallSite is CallSiteArguments.ofPositional.

func (CallSiteArguments) ArgumentNames

func (a CallSiteArguments) ArgumentNames() []string

func (CallSiteArguments) Arguments

func (a CallSiteArguments) Arguments() []Value

func (CallSiteArguments) Arity

func (a CallSiteArguments) Arity() int

func (CallSiteArguments) HasOptions

func (a CallSiteArguments) HasOptions() bool

func (CallSiteArguments) IsNamed

func (a CallSiteArguments) IsNamed() bool

func (CallSiteArguments) IsSimple

func (a CallSiteArguments) IsSimple() bool

func (CallSiteArguments) IsWindowed

func (a CallSiteArguments) IsWindowed() bool

func (CallSiteArguments) Options

func (a CallSiteArguments) Options() CallSiteOptions

func (CallSiteArguments) Window

func (CallSiteArguments) WithOptions

func (CallSiteArguments) WithWindow

type CallSiteErrorCode

type CallSiteErrorCode int

CallSiteErrorCode is the SemanticException.ErrorCode a call-site option failure raises.

const (
	// CallSiteIncompatibleType is INCOMPATIBLE_TYPE: a NULL value or one its
	// option cannot take.
	CallSiteIncompatibleType CallSiteErrorCode = iota + 1
	// CallSiteFunctionUndefined is FUNCTION_UNDEFINED_FOR_GIVEN_ARGUMENT_TYPES:
	// a repeated or unsupported option.
	CallSiteFunctionUndefined
)

type CallSiteOption

type CallSiteOption[T any] struct {
	// contains filtered or unexported fields
}

CallSiteOption is Java's CallSiteArguments.Option: a named option and the coercion to its declared type.

func BooleanOption

func BooleanOption(name string) CallSiteOption[bool]

BooleanOption is Option.ofBoolean: only an actual boolean.

func DoubleOption

func DoubleOption(name string) CallSiteOption[float64]

DoubleOption is Option.ofDouble: any number.

func EnumOption

func EnumOption(name string, constants ...string) CallSiteOption[EnumConstant]

EnumOption is Option.ofEnum over the given constants: text naming one, ignoring case.

func IntegerOption

func IntegerOption(name string) CallSiteOption[int32]

IntegerOption is Option.ofInteger.

func LongOption

func LongOption(name string) CallSiteOption[int64]

LongOption is Option.ofLong.

func StringOption

func StringOption(name string) CallSiteOption[string]

StringOption is Option.ofString.

func (CallSiteOption[T]) Coerce

func (o CallSiteOption[T]) Coerce(raw any) (T, error)

Coerce is Option.coerce: NULL is refused, a value of the declared type is taken as is, anything else goes through the option's coercion.

func (CallSiteOption[T]) Name

func (o CallSiteOption[T]) Name() string

type CallSiteOptionError

type CallSiteOptionError struct {
	Code     CallSiteErrorCode
	Function string
	Option   string
	Detail   string
}

CallSiteOptionError is the SemanticException CallSiteArguments raises for an option, with its log info.

func (*CallSiteOptionError) Error

func (e *CallSiteOptionError) Error() string

type CallSiteOptions

type CallSiteOptions struct {
	// contains filtered or unexported fields
}

CallSiteOptions is CallSiteArguments.Options: raw option values by name, in the order given.

func (CallSiteOptions) IsEmpty

func (o CallSiteOptions) IsEmpty() bool

func (CallSiteOptions) Names

func (o CallSiteOptions) Names() []string

func (CallSiteOptions) Resolve

func (o CallSiteOptions) Resolve(function string, supported ...callSiteOptionResolver) (CallSiteOptions, error)

Resolve is Options.resolve: every option must be one the function supports, and is coerced to that option's type.

type CallSiteOptionsBuilder

type CallSiteOptionsBuilder struct {
	// contains filtered or unexported fields
}

CallSiteOptionsBuilder is Options.Builder.

func NewCallSiteOptionsBuilder

func NewCallSiteOptionsBuilder() *CallSiteOptionsBuilder

func (*CallSiteOptionsBuilder) Build

func (*CallSiteOptionsBuilder) PutRaw

func (b *CallSiteOptionsBuilder) PutRaw(name string, raw any) error

PutRaw is Builder.putRaw: NULL and a repeated name are refused.

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

type CastValue struct {
	Child  Value
	Target Type
}

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

func NewCastValue(child Value, target Type) *CastValue

NewCastValue constructs a CastValue.

func (*CastValue) Children

func (c *CastValue) Children() []Value

func (*CastValue) Evaluate

func (c *CastValue) Evaluate(evalCtx any) (any, error)

func (*CastValue) Name

func (c *CastValue) Name() string

func (*CastValue) Type

func (c *CastValue) Type() Type

Type is the target, NULL only when the operand can be (Java's CastValue); an untyped operand's type says nothing, so its cast stays nullable.

type CensusHooks

type CensusHooks struct {
	LegIdentityLeg             func(leg RecordTypeLeg)
	LegIdentityComparison      func(site LegIdentitySite, legName, corrName string)
	LegIdentityConversion      func(site LegIdentitySite, leg, corr CorrelationIdentifier, retiredVerdict bool)
	SeedWindowRead             func(site SeedWindowSite, class SeedWindowReadClass)
	SeedWindowLookup           func(site SeedWindowSite, found bool)
	SeedWindowLookupOfKind     func(site SeedWindowSite, found bool, kind LegKind)
	InnerScalarLegTitleAt      func(producer InnerLegProducer, corr CorrelationIdentifier, title string)
	QualifierRecovery          func(site QualifierRecoverySite, class QualifierRecoveryClass, name, identity string)
	SelectResultMint           func(site SelectResultMintSite, rv Value)
	DottedRowTypeDerivation    func(fields []Field)
	AccessorPathCall           func(class AccessorPathClass)
	AccessorPathDottedWitness  func(name string)
	FieldValueMint             func(field string, baked bool)
	OrderingBridgeDotted       func(leftName, rightName string, answered bool)
	MergeSlotTyping            func(corr CorrelationIdentifier, slotType Type, scavenged bool)
	ResultTypeRead             func(site string, t Type)
	LegColumnProvenance        func(rt *RecordType, name string, flatHit, flatAmbiguous bool, matched *RecordTypeLeg, qualifier string, owner CorrelationIdentifier)
	UnnestLegMintCall          func(site UnnestLegMintSite)
	UnnestLegMintName          func(site UnnestLegMintSite, name string)
	UnnestLegMintBranchReached func(site UnnestLegMintSite)
	UnnestLegMintArm           func(site UnnestLegMintSite, arm UnnestLegMintArm)
	UnnestLegOrdinalTwinCall   func()
}

CensusHooks is the planner's test-only census sink; its storage and reports live in pkg/internal/querycensus, which installs it. Production leaves it nil.

func Census

func Census() *CensusHooks

Census returns the leg-identity census hooks, or nil when the census is off: a record site costs one atomic load and one untaken branch.

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) Name

func (*CollateValue) Name() string

Name returns the SQL function name.

func (*CollateValue) Type

func (*CollateValue) Type() Type

Type is nullable BYTES, Java's primitiveType(BYTES).

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 ColumnIdentity

type ColumnIdentity struct {
	// Correlation is the quantifier whose row the ordinal indexes. The zero
	// value means "the value's own source", used by sites whose references are
	// uncorrelated (a leaf-relative metadata column).
	Correlation CorrelationIdentifier

	// Domain is the layout the ordinal indexes. Always KNOWN in a
	// ColumnIdentity that some producer returned ok for: every derivation
	// below routes through OrdinalIn, which fails closed on an unknown domain
	// on either side.
	Domain OrdinalDomain

	// Ordinal is the column's position in Domain. Always >= 0 for the same
	// reason: OrdinalIn declines the `-1` name-only accessors Go mints at its
	// unnest/gather/index-expansion seeds, where two accessors are
	// ordinal-equal by construction and the name is the only identity left.
	Ordinal int
}

ColumnIdentity is a column's identity — RFC-197's triple, as ONE comparable key an escaping helper can return instead of a bare display name.

Java's counterpart is `FieldValue.resolvedAccessor`, whose `equals` is ordinal-only (FieldValue.java:684) and whose constructor asserts `ordinal >= 0` (FieldValue.java:651) — the name is deliberately excluded from identity there and is excluded here. Go needs two elements Java's accessor gets for free: the CORRELATION (ordinal 0 of two quantifiers are different columns, and Java's rebase machinery keeps that on the value's own child), and the DOMAIN (Java derives it from the non-null typed `childValue`; Go mints childless bakes and must carry a token).

The type deliberately has NO string field, at any depth reachable from a call site:

  • `OrdinalDomain.sig` is unexported and is a signature of a WHOLE ordered layout, obtainable only from OrdinalDomainOfType/OrdinalDomainOfColumnNames. A single column's display name cannot be put there.
  • `CorrelationIdentifier.name` is unexported and is a QUANTIFIER alias, a different identity element with its own producers — never a column name.

That is a structural defense, not a stylistic one: the key type simply has nowhere to put a display name, and `column_identity_test.go`'s reflection walk fails the build if that ever stops being true.

func CorrelatedFieldIdentityIn

func CorrelatedFieldIdentityIn(v Value, frontier OrdinalDomain) (ColumnIdentity, bool)

CorrelatedFieldIdentityIn is the checked public purpose API for consumers that need a correlated, single-column identity without depending on the package-private FieldValue representation.

func OrderingIdentityOf

func OrderingIdentityOf(v Value) (ColumnIdentity, bool)

OrderingIdentityOf is the identity an ORDERING key is addressed by: the correlation its root reads from, the layout that root indexes, and the ordinal within it.

This is the resolution Java gets for free. Java's `Ordering` is a `PartiallyOrderedSet<Value>` and a `SetMultimap<Value, Binding>` keyed by `Value.equals` (Ordering.java:176-183, :336) — semantic equality under the EMPTY alias map, so a correlation identifier must match exactly and a display name is never consulted. Go cannot key on the Value itself because the two sides are built by different producers and are not pointer- or structurally-equal even when they name the same column; so the identity is extracted and compared instead of the whole node.

It declines — and the caller must then treat the key as UNADDRESSABLE, never fall back to a name — for:

  • anything that is not a FieldValue (an arithmetic or function ordering key has no column identity to state);
  • a chained accessor path (more than one accessor, or a non-QOV child): the root's layout is not the layout the deeper ordinal indexes, exactly as IdentityIn declines;
  • a LAZY node, a negative name-only ordinal, or an unknown domain — the three shapes where an ordinal comparison would be vacuous or would address some other layout.

The correlation is the element that keeps two quantifiers over the SAME table apart: `o.a` and `i.a` in a self-join share a domain and an ordinal and are different columns.

Every admitted FieldValue has an exact QOV root. A malformed or legacy childless value therefore states no ordering identity and declines.

func OrdinalOfNameIn

func OrdinalOfNameIn(layout Type, name string) (ColumnIdentity, bool)

OrdinalOfNameIn resolves a METADATA column name — an index definition's column list, a primary key's column list, a proto descriptor's field — to its ordinal in a stated layout.

This is the ONLY sanctioned direction for a name in this file, and it is the boundary rule of RFC-197: the metadata layer names its columns, that name is resolved ONCE against the layout it indexes, and it dies there. The result is a ColumnIdentity, so no caller downstream can compare names again.

Matching is case-insensitive FIRST-MATCH against the layout's declared column order — the resolver's own sourceColumnOrdinal rule, and the same fold OrdinalDomain's signature applies. RecordType.FieldIndexUnique is deliberately NOT used: it matches EXACTLY, and the metadata lists this function resolves (index definitions, primary keys, proto descriptors) do not agree with a record type's field spelling on case, so an exact match would silently decline a column that is plainly there.

A name the layout does not declare, or a layout with no declared column order, declines.

func (ColumnIdentity) WithCorrelation

func (c ColumnIdentity) WithCorrelation(corr CorrelationIdentifier) ColumnIdentity

WithCorrelation returns a copy of the identity read off the given quantifier. Used where a metadata-resolved identity (which has no quantifier of its own) must be compared against a reference read off a named join leg.

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

Name returns the SQL function name.

func (*ConditionSelectorValue) Type

func (*ConditionSelectorValue) Type() Type

Type returns NotNullInt — the selector returns an integer index.

Type is nullable INT, Java's primitiveType(INT): Evaluate returns NULL when no implication holds.

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 ConstantAgnosticHash

type ConstantAgnosticHash struct{ io.Writer }

ConstantAgnosticHash hashes every constant alike, as Java's planHash(VC0) does for the ConstantObjectValue each SQL literal plans as (ConstantObjectValue.java:163-166).

type ConstantDeref

type ConstantDeref interface {
	// DereferenceConstant distinguishes a bound NULL from an absent pool entry.
	DereferenceConstant(alias CorrelationIdentifier, constantID string) (any, bool)
}

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. A missing binding fails, as Java's "Missing binding" does (EvaluationContext.java:184-192).

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 (*ConstantObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}

A constant-pool binding is not a row correlation, matching Java ConstantObjectValue.

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

type ConstantValue struct {
	Value any
	Typ   Type
}

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) Evaluate

func (c *ConstantValue) Evaluate(any) (any, error)

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 {
	// GetCorrelatedTo returns the set of Quantifier IDs this value
	// 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 CurrentCorrelation

func CurrentCorrelation() CorrelationIdentifier

CurrentCorrelation returns the reserved current-row correlation. It is stable and comparable by value but is not assignable package state; its private kind cannot be forged through NamedCorrelationIdentifier.

func MergeCorrelationIdentifier

func MergeCorrelationIdentifier(ordinal uint64) CorrelationIdentifier

MergeCorrelationIdentifier is the planner's alias for the quantifier over a merged join sub-product, numbered per planning run. Nothing outside the expression binding it can refer to it, so the memo may rename it.

The name embeds a double quote, the one character no parsed SQL identifier can contain (DOUBLE_QUOTE_ID: '"' ~'"'+ '"' strips its quotes), so a quoted user alias such as "$m1" cannot collide with it.

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) IsMergeAlias

func (c CorrelationIdentifier) IsMergeAlias() bool

IsMergeAlias reports whether c was minted by MergeCorrelationIdentifier.

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 CorrelationIdentifierAllocator

type CorrelationIdentifierAllocator struct {
	// contains filtered or unexported fields
}

CorrelationIdentifierAllocator allocates deterministic identities within one query construction. Owners share it with their child scopes, not with other queries. Like Java's debugger-local uniqueId index, its sequence is independent of earlier planning in the process. The namespace is disjoint from the global rewrite allocator, and the private kind remains distinct from SQL names. This construction-local allocator is not safe for concurrent use.

func (*CorrelationIdentifierAllocator) Next

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

Name returns the value name matching Java's NAME constant.

func (*CosineDistanceRowNumberValue) Type

Type is nullable LONG, Java's primitiveType(LONG).

func (*CosineDistanceRowNumberValue) WithChildren

func (v *CosineDistanceRowNumberValue) WithChildren(newChildren []Value) *CosineDistanceRowNumberValue

WithChildren returns a fresh CosineDistanceRowNumberValue with children re-split via SplitNewChildren.

type DeclaredNameClashError

type DeclaredNameClashError struct {
	// Name is the protobuf MESSAGE name both shapes claim — the declared
	// record name after escaping (`a.b` is reported as `a__2b`), because that
	// is what collides and what Java's guard compares
	// (registerTypeToTypeNameMapping's inverse lookup is over proto names).
	Name string
	// Existing is the shape already defined under Name; Incoming the second.
	Existing Type
	Incoming Type
}

DeclaredNameClashError reports two record shapes DECLARED under one name in one repository — `STRUCT foo (1 AS p)` beside `STRUCT foo (2 AS p, 3 AS q)`. Each has a message form, but two DescriptorProtos of one name make a file that does not validate. Java refuses the second REGISTRATION (registerTypeToTypeNameMapping: IllegalArgumentException) and would fail again at build; Go refuses at the same point. It is a different failure from a ProtoTypeError, which is a type with NO message form: a caller that keeps a map representation for the latter must not swallow this one. Anonymous shapes never take part — their namespace is unreachable from any identifier (see the file header).

func (*DeclaredNameClashError) Error

func (e *DeclaredNameClashError) Error() string

type DerivedValue

type DerivedValue struct {
	ChildrenList []Value
	ResultType   Type
}

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.

func (*DerivedValue) Evaluate

func (*DerivedValue) Evaluate(any) (any, error)

Evaluate panics — DerivedValue is non-evaluable. Pattern-match at the planner level instead.

func (*DerivedValue) Name

func (*DerivedValue) Name() string

Name returns the debug-print kind.

func (*DerivedValue) Type

func (v *DerivedValue) Type() Type

Type returns the bound result type.

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 is nullable LONG, as Java's four *DistanceRowNumberValue classes are (primitiveType(LONG)).

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 is nullable DOUBLE, Java's primitiveType(DOUBLE): a NULL operand or a dimension mismatch evaluates to NULL.

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

Name returns the value name matching Java's NAME constant.

func (*DotProductDistanceRowNumberValue) Type

Type is nullable LONG, Java's primitiveType(LONG).

func (*DotProductDistanceRowNumberValue) WithChildren

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.

func (*EmptyValue) Evaluate

func (*EmptyValue) Evaluate(any) (any, error)

Evaluate returns nil — empty record has no value to extract.

func (*EmptyValue) Name

func (*EmptyValue) Name() string

Name returns the debug-print kind.

func (*EmptyValue) Type

func (*EmptyValue) Type() Type

Type returns an empty nullable RecordType: Evaluate returns NULL, and Java's EmptyValue keeps Value's default, a nullable UNKNOWN.

type EncapsulationError

type EncapsulationError struct{ Detail string }

EncapsulationError is the SemanticException INCOMPATIBLE_TYPE an encapsulate raises.

func (*EncapsulationError) Error

func (e *EncapsulationError) Error() string

type EnumConstant

type EnumConstant string

EnumConstant is the value of an enum option: one of its constants, so that raw text is never taken for one without the check.

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
	// StorageName is the protobuf spelling when it differs from EnumName;
	// empty means EnumName (Java's Type.Enum.storageName).
	StorageName string
}

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.

Like Java Type.Enum (unlike relational DataType.EnumType), Equals ignores the nominal name and compares nullability plus the ordered member list.

func NewEnumType

func NewEnumType(name string, nullable bool, values []EnumValue) *EnumType

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) Code

func (*EnumType) Code() TypeCode

Code implements Type — always TypeCodeEnum.

func (*EnumType) Equals

func (e *EnumType) Equals(other Type) bool

Equals implements Type. Structural — nullable + ordered values.

func (*EnumType) IsNullable

func (e *EnumType) IsNullable() bool

IsNullable implements Type.

func (*EnumType) LookupValueByName

func (e *EnumType) LookupValueByName(name string) (EnumValue, bool)

LookupValueByName returns the enum value matching name plus a found flag. Empty string returns (zero, false).

func (*EnumType) LookupValueByNumber

func (e *EnumType) LookupValueByNumber(number int32) (EnumValue, bool)

LookupValueByNumber returns the enum value matching number plus a found flag.

func (*EnumType) String

func (e *EnumType) String() string

String implements Type. Renders as `[name] ENUM<v1=0, v2=1> [NOT NULL | NULL]`.

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
	// StorageName is the protobuf spelling when Name does not imply it; empty
	// means DerivedStorageName(Name) (Java's EnumValue.storageName).
	StorageName string
}

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).

func (EnumValue) Equals

func (e EnumValue) Equals(other EnumValue) bool

Equals reports structural equality — Name + Number.

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

Name returns the value name matching Java's NAME constant.

func (*EuclideanDistanceRowNumberValue) Type

Type is nullable LONG, Java's primitiveType(LONG).

func (*EuclideanDistanceRowNumberValue) WithChildren

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

IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.

func (*EuclideanSquareDistanceRowNumberValue) Name

Name returns the value name matching Java's NAME constant.

func (*EuclideanSquareDistanceRowNumberValue) Type

Type is nullable LONG, Java's primitiveType(LONG).

func (*EuclideanSquareDistanceRowNumberValue) WithChildren

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 is NullableBoolean. Java's EvaluatesToValue keeps Value's default type, a nullable UNKNOWN; Go keeps the BOOLEAN code its evaluation returns.

type ExactTypeHandle

type ExactTypeHandle interface {
	Type() Type
	CanonicalBytes() []byte
	RelationInner() (ExactTypeHandle, bool)

	// Code and IsNullable answer the two questions a caller most often wants
	// from a handle, WITHOUT thawing it. Both were previously reachable only as
	// `handle.Type().Code()`, which builds an entire Type graph — recursively,
	// for a record — and discards it to read one field. thaw was the largest
	// single allocator in the planner, and this was one of the routes into it.
	//
	// They are on the INTERFACE rather than beside it as free functions because
	// a handle that cannot state its own code is not a type identity, and
	// because the interface is sealed by isExactTypeHandleView: no
	// implementation outside this package can exist, so widening it breaks
	// nobody.
	Code() TypeCode
	IsNullable() bool
	// contains filtered or unexported methods
}

ExactTypeHandle is an immutable read view of a checked type snapshot.

Type returns the SHARED thawed graph and callers must treat it as READ-ONLY; CanonicalBytes still returns a defensive copy, because those bytes ARE the identity a QOV and every memo boundary compare on, and handing out the slice would let a caller move an interning key.

The asymmetry is deliberate and is the whole shape of RFC-234: the ordinary Type graph is a DERIVATION of the identity and nothing in production writes to one, so it can be shared; the canonical bytes are the identity itself.

func AsExactTypeHandle

func AsExactTypeHandle(value any) (ExactTypeHandle, bool)

AsExactTypeHandle exact-recognizes the package-owned immutable handle. An embedded interface or a nil embedded view is not admitted.

func ExactRelationOf

func ExactRelationOf(object Type) (ExactTypeHandle, error)

ExactRelationOf snapshots object and wraps it in exactly one RELATION layer.

func ExactRelationOfHandle

func ExactRelationOfHandle(object ExactTypeHandle) (ExactTypeHandle, error)

ExactRelationOfHandle is ExactRelationOf for a caller that already holds the object handle: it wraps it in exactly one RELATION layer without thawing.

func ExactTypeForValue

func ExactTypeForValue(value Value) (ExactTypeHandle, error)

ExactTypeForValue returns the exact handle describing value's type, taking the one value already carries rather than deriving it again.

It exists because the derivation is not cheap and the round trip was pure waste. Type() builds a fresh ordinary graph on every call — deliberately, so no caller can mutate the identity a QOV and every memo boundary depend on — and a caller that immediately re-snapshots that graph walks it all the way back to the interned node it started from. Measured over a 200-plan IN-list sweep, that round trip was the largest single planner allocator on this branch.

Interning is what makes the shortcut exactly equivalent rather than merely equivalent-looking: the long way round returns the same OBJECT, so this is the same handle by identity and not just by content.

That rests on every path building an exact node routing through the intern table, which is not self-evident and was not true — the record-constructor type and the nullability-widened copy each built one directly. TestEveryExactNodeIsInterned is the check, because the failure is silent: an un-interned node is a correct TYPE and answers nothing wrongly, it merely compares unequal to an identical interned one wherever children are compared by pointer.

func FlowedExactType

func FlowedExactType(value QuantifiedObjectValue) ExactTypeHandle

FlowedExactType returns value's flowed row as its exact handle, or nil when the value cannot state one.

It is the cheap replacement for `value.FlowedType()` at every site that only interrogates the row — is there one, what code is it, is it nullable — rather than needing an ordinary graph. FlowedType builds that graph, recursively, and those sites then read one field off it and drop it.

The nil is an UNTYPED nil, deliberately. Returning the (*exactType)(nil) that a bad value carries would give callers a non-nil interface wrapping a nil pointer, so the `!= nil` test every one of these sites performs would answer TRUE for a value with no row — silently inverting the guard it replaced.

func SnapshotExactType

func SnapshotExactType(typ Type) (ExactTypeHandle, error)

SnapshotExactType checks and freezes an ordinary Type graph.

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,
	flowed Type,
) (*ExistsValue, error)

NewExistsValue constructs EXISTS over an exact existential object. The QOV's flowed type is explicit and constructor failures are propagated.

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) Name

func (*ExistsValue) Name() string

Name returns the debug-print kind.

func (*ExistsValue) Type

func (*ExistsValue) Type() Type

Type is NullableBoolean: Java's ExistsValue does not override BooleanValue.getResultType, primitiveType(BOOLEAN), which is nullable (BooleanValue.java:40-42).

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 ExplicitNullQuantifiedObjectBinder

type ExplicitNullQuantifiedObjectBinder interface {
	IsExplicitNullQuantifiedBinding(QuantifiedObjectValue) (bool, error)
}

ExplicitNullQuantifiedObjectBinder is the optional proof carried by a binder that can intentionally bind SQL NULL for a statically non-nullable edge. The only current producer is FirstOrDefault: its empty arm is represented by an exact physical row shell plus explicit absence, rather than by changing the child QOV's declared type. Ordinary binders need not implement this; a nil delegated non-nullable QOV remains a loud nullability mismatch without this positive proof.

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.FieldIndexUnique) for soundness even on
	// a raw RecordType. Anonymous fields share Name="" but have distinct Ordinals.
	Ordinal int
	// Index is the protobuf field number of a descriptor-derived field, 0
	// when there is none (Java's fieldIndexOptional). Provenance only.
	Index int32
	// StorageName is the protobuf field name when Name does not imply it;
	// empty means DerivedStorageName(Name) (Java's Field.of). Provenance only.
	StorageName string
}

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.

func LookupFieldPathUnique

func LookupFieldPathUnique(row Type, path []string) (Field, bool)

LookupFieldPathUnique resolves a field path from row, each step by LookupFieldUnique; false for an empty path or a step that is not exactly one field of a record.

func (Field) Equals

func (f Field) Equals(other Field) bool

Equals reports whether two Fields are structurally equal: same Name + Ordinal + FieldType.Equals.

type FieldPathView

type FieldPathView interface {
	Len() int
	Ordinals() []int
	Accessor(int) (ResolvedAccessorView, bool)
	// Transitional physical-addressing read views. They remain read-only while
	// RFC-232's OrdinalLayout migration removes OrdinalDomain/pin state from
	// logical Values.
	RootDomain() OrdinalDomain
	IsFrontierPinned() bool
	// contains filtered or unexported methods
}

FieldPathView exposes only defensive/read-only path information.

type FieldRequest

type FieldRequest interface {
	// contains filtered or unexported methods
}

FieldRequest is a sealed, exactly-one-step semantic access request.

func FieldByName

func FieldByName(semanticName string) (FieldRequest, error)

FieldByName constructs one semantic-name request. It never splits dots.

func FieldByNameAndOrdinal

func FieldByNameAndOrdinal(semanticName string, ordinal int) (FieldRequest, error)

FieldByNameAndOrdinal constructs a request whose two authorities must agree.

func FieldByOrdinal

func FieldByOrdinal(ordinal int) (FieldRequest, error)

FieldByOrdinal constructs one non-negative ordinal request.

type FieldValue

type FieldValue interface {
	Value
	ChildValue() Value
	Path() FieldPathView
	DisplayName() string
	ResultType() Type
	// contains filtered or unexported methods
}

FieldValue is the immutable read view of one completely resolved field access. The concrete implementation is package-private so neither a zero value nor partially initialized path can enter a Value graph.

func AsFieldValue

func AsFieldValue(value Value) (FieldValue, bool)

AsFieldValue exact-recognizes only the values-owned immutable concrete node. Embedded and nil-embedded interface impostors are rejected without invoking any of their methods.

func ReanchorFieldValue

func ReanchorFieldValue(
	field FieldValue,
	target QuantifiedObjectValue,
	layout OrdinalLayout,
) (FieldValue, error)

ReanchorFieldValue maps one exact source-relative field access onto the exact current carrier owned by layout. The mapping is entirely ordinal: no display name or inferred start offset participates.

type FirstOrDefaultStreamingValue

type FirstOrDefaultStreamingValue struct {
	ChildValue         Value
	OnEmptyResultValue Value
}

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

Name returns the SQL function name (matches FirstOrDefaultValue).

func (*FirstOrDefaultStreamingValue) 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 (v *FromOrderedBytesValue) Evaluate(evalCtx any) (any, error)

Evaluate decodes the child's bytes and answers the first element in the row domain (TupleOrdering.unpack(bytes, direction).get(0), then tupleValueToRuntimeValue). Java requires the bytes non-null.

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

type InOpValue struct {
	Probe Value
	List  Value // expected to evaluate to []any at runtime
}

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

func NewInOpValue(probe, list Value) *InOpValue

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 NewJavaInOpValue

func NewJavaInOpValue(operand, array Value) (*InOpValue, error)

NewJavaInOpValue is InOpValue.InFn.encapsulateInternal (InOpValue.java:230-268): the operand or the array is promoted to the maximum of the operand and element types.

func (*InOpValue) Children

func (v *InOpValue) Children() []Value

Children returns probe + list. Lets WalkValue traverse both operands as a standard 2-child Value.

func (*InOpValue) Evaluate

func (v *InOpValue) Evaluate(evalCtx any) (any, error)

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).

func (*InOpValue) Name

func (*InOpValue) Name() string

Name returns the debug-print kind.

func (*InOpValue) Type

func (*InOpValue) Type() Type

Type is always nullable boolean (NULL propagation through Kleene 3VL forces nullable).

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 is nullable INT, Java's primitiveType(INT): Evaluate returns NULL without an incarnation in its context.

type IncompatibleOrderingTypeError

type IncompatibleOrderingTypeError struct {
	Typ Type
}

IncompatibleOrderingTypeError mirrors Java's SemanticException.ErrorCode.ORDERING_IS_OF_INCOMPATIBLE_TYPE: the type cannot participate in an ordering (and therefore cannot be a grouping requirement) even after record flattening — arrays and relations have no primitive leaf decomposition.

func (*IncompatibleOrderingTypeError) Error

type IncompatibleTypeError

type IncompatibleTypeError struct {
	// Field is the slot's path from the admitted record, dotted; empty for
	// a bare value.
	Field    string
	From, To Type
}

IncompatibleTypeError is Java's SemanticException INCOMPATIBLE_TYPE raised while a value is admitted to a slot of another type: no promotion takes the value's type to the slot's. The SQL layer renders it as 22000, "A value cannot be assigned to a variable because …".

func (*IncompatibleTypeError) Error

func (e *IncompatibleTypeError) Error() string

type IndexEntryObjectValue

type IndexEntryObjectValue struct {
	IndexEntryAlias CorrelationIdentifier
	Source          TupleSource
	OrdinalPath     []int
	ResultType      Type
}

IndexEntryObjectValue is a LEAF Value that reads one element of an index entry's KEY or VALUE tuple by an ordinal path (Java's "Dewey id"). Mirrors Java's IndexEntryObjectValue: the entry is the correlation binding of IndexEntryAlias (Quantifier.current() in the plans that read entries), KEY reads the entry's key and any other source its value, a NULL midway answers NULL, and the element is converted into the row domain (TupleFieldsHelper.tupleValueToRuntimeValue; TupleElementToRowValue here). The result type is a primitive, enum or UUID (Java's constructor Verify).

func NewIndexEntryObjectValue

func NewIndexEntryObjectValue(alias CorrelationIdentifier, source TupleSource, ordinalPath []int, resultType Type) (*IndexEntryObjectValue, error)

NewIndexEntryObjectValue constructs the leaf; a result type that is not a primitive, enum or UUID is refused, as Java's constructor refuses it.

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 reads the element at OrdinalPath of the bound entry's KEY or VALUE tuple. A missing or mistyped binding is an error, as Java's requireNonNull and cast are.

func (*IndexEntryObjectValue) Explain

func (v *IndexEntryObjectValue) Explain() string

Explain is Java's `KEY:[0]`.

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) ReadTuples

func (v *IndexEntryObjectValue) ReadTuples(key, value tuple.Tuple) (any, error)

ReadTuples is Evaluate over an entry's KEY and VALUE tuples already in hand, for a cursor that reads every entry of a scan.

func (*IndexEntryObjectValue) Type

func (v *IndexEntryObjectValue) Type() Type

Type returns the bound result type.

type IndexEntryRecordReader

type IndexEntryRecordReader struct {
	// contains filtered or unexported fields
}

IndexEntryRecordReader is Java's IndexEntryToRecordValueHelper: a trie over the queried record's field path, each node holding the reader of the field it covers. Go keys a node by the field's ordinal in its record type, the identity its FieldValues carry; Java keys by name, unique in a record.

func (*IndexEntryRecordReader) Cover

func (n *IndexEntryRecordReader) Cover(v Value)

Cover makes v this field's reader unless an earlier source covers it already: the first covering entry column wins.

func (*IndexEntryRecordReader) CoverField

func (n *IndexEntryRecordReader) CoverField(field FieldValue, reader Value) bool

CoverField records the reader of field, descending a node per step of its path (ScanWithFetchMatchCandidate.recordCoveredField).

func (*IndexEntryRecordReader) Covers

func (n *IndexEntryRecordReader) Covers() bool

Covers reports whether any field is covered below this node.

func (*IndexEntryRecordReader) ToRecordValue

func (n *IndexEntryRecordReader) ToRecordValue(target *RecordType) *RecordConstructorValue

ToRecordValue builds the record of target from the covered fields, in target's field order; a field nothing covers is absent.

func (*IndexEntryRecordReader) WithChild

func (n *IndexEntryRecordReader) WithChild(ordinal int) *IndexEntryRecordReader

WithChild is the node of the field at ordinal, created on first use.

type IndexEntryTuples

type IndexEntryTuples interface {
	IndexEntryKey() tuple.Tuple
	IndexEntryValue() tuple.Tuple
}

IndexEntryTuples is the raw KEY and VALUE tuples of an index entry, the binding an IndexEntryObjectValue reads (*recordlayer.IndexEntry).

type IndexOnly

type IndexOnly interface {
	Value
	IsIndexOnly() bool
}

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

type IndexableAggregate interface {
	Value
	GetIndexTypeName() string
}

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.

func (*IndexedValue) Evaluate

func (*IndexedValue) Evaluate(any) (any, error)

Evaluate panics — IndexedValue is a placeholder, not a computable expression. The panic message is loud so misuse doesn't silently return nil and confuse downstream evaluators.

func (*IndexedValue) Name

func (*IndexedValue) Name() string

Name returns the debug-print kind.

func (*IndexedValue) Type

func (v *IndexedValue) Type() Type

Type returns the bound result type.

type InnerLegProducer

type InnerLegProducer int

InnerLegProducer names WHICH correlated-scalar seed minted an inner leg.

There are TWO, and RFC-212 §10.3 v1 named only one of them — which is exactly the error this census exists to catch, so the producer is recorded rather than assumed.

const (
	InnerLegProducerClusteredOuter InnerLegProducer = iota
	InnerLegProducerSingleSource
)

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

Error is Java's SemanticException text for INVALID_CAST: the code's own message, "Invalid cast operation", then the detail (SemanticException.java:89), which is the message the target reports.

type InvalidEnumValueError

type InvalidEnumValueError struct {
	Value string
}

InvalidEnumValueError mirrors SemanticException.INVALID_ENUM_VALUE: the string comparand is not a declared member of the target enum.

func (*InvalidEnumValueError) Error

func (e *InvalidEnumValueError) Error() string

type InvalidUUIDValueError

type InvalidUUIDValueError struct {
	Value string
}

InvalidUUIDValueError mirrors SemanticException.INVALID_UUID_VALUE: a string read as a UUID (STRING_TO_UUID, by CAST or by promotion into a UUID slot) is not one. Java's relational layer leaves the code in INTERNAL_ERROR (XX000, ExceptionUtil.translateErrorCode's default arm) with this message; it is not an INVALID_CAST, even from a CAST.

func (*InvalidUUIDValueError) Error

func (e *InvalidUUIDValueError) 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 LegIdentitySite

type LegIdentitySite int

LegIdentitySite identifies one leg-identity comparison site.

const (
	LegSiteRowLegsBinder LegIdentitySite = iota
	LegSiteBuriedLegWindow
	LegSiteTextVsIdentity
	LegSiteLeftOuterExistential
	LegSiteFinalizeSeedWindows
	LegSiteSelectOutputLegs
	LegSiteNLJPlanAlias
	LegSiteOrdinalSlotInLegWindow
	LegIdentitySiteCount
)

type LegKind

type LegKind int

LegKind says HOW a leg occupies the carrying type: as a flat RUN of columns, or as a single slot holding the leg's whole row.

It is an EXPLICIT discriminator with an INVALID zero value, and both halves of that are decided rather than incidental.

EXPLICIT, because the alternative is inference and every candidate inference is wrong on a legitimate shape. `len(Typ.Fields) == 1`, "the field type is a record", `Width == 1` — a one-column flat leg whose single column is a struct satisfies all three and is not nested. An inference that is silently wrong is silently wrong about WHICH COLUMN a read addresses, which is the wrong-offset wrong-rows failure this layout authority was consolidated into one place to prevent.

INVALID at zero, because Go's zero value would otherwise mean LegKindFlatRun — the same inference one level down, made by the language instead of by a reader, and made for a producer that never thought about the question. The precedent is on this file's own constructor: deleting `Alias:` from two producers left the whole suite green, because the zero CorrelationIdentifier is a legal value nobody checks. A kind that could be omitted reproduces that failure one field over.

Every reader DECLINES or fails LOUD on LegKindUnset. A leg reaching a consumer without a stated kind is a producer bug and must surface as one.

const (
	// LegKindUnset is the INVALID zero. See the type doc.
	LegKindUnset LegKind = iota

	// LegKindFlatRun: the leg occupies the consecutive slot range
	// [Start, Start+Width) of the carrying type, one slot per leg column. Every
	// leg boundary that existed before nested windows is this kind.
	LegKindFlatRun

	// LegKindNested: the leg occupies the SINGLE slot at Start, and that slot
	// holds the leg's whole row.
	//
	// This is Java's shape, not a Go extension. PartitionSelectRule collapses the
	// lower quantifiers into `RecordConstructorValue.ofColumns(… Column::unnamedOf)`
	// — one unnamed column per quantifier, each holding that quantifier's whole
	// record Message — and a reference to a collapsed sibling becomes
	// `FieldValue.ofOrdinalNumber(QOV(newUpper), index)`, a one-step ordinal walk
	// that returns the leg's whole Message because the field is of message type.
	// Nesting is free there; here it needs saying out loud.
	LegKindNested
)

func (LegKind) String

func (k LegKind) String() string

type LikeError

type LikeError struct{ Kind LikeErrorKind }

LikeError is a LIKE semantic error, with Java's message.

func (*LikeError) Error

func (e *LikeError) Error() string

type LikeErrorKind

type LikeErrorKind int

LikeErrorKind is one of the four semantic errors Java's LIKE raises (SemanticException.ErrorCode, SemanticException.java:47-57).

const (
	// LikeOperandNotString is OPERAND_OF_LIKE_OPERATOR_IS_NOT_STRING (22F00).
	LikeOperandNotString LikeErrorKind = iota + 1
	// LikeEscapeNotSingleChar is ESCAPE_CHAR_OF_LIKE_OPERATOR_IS_NOT_SINGLE_CHAR (22019).
	LikeEscapeNotSingleChar
	// LikeEscapeConflict is ESCAPE_CHARACTER_CONFLICT (2200B).
	LikeEscapeConflict
	// LikeInvalidEscapeSequence is INVALID_ESCAPE_SEQUENCE (22025).
	LikeInvalidEscapeSequence
)

type LikeOperatorValue

type LikeOperatorValue struct {
	Probe   Value
	Pattern Value
}

LikeOperatorValue is Java's LikeOperatorValue: `probe LIKE pattern`, the pattern a PatternForLikeValue (LikeOperatorValue.java:83-105). NULL when the probe is NULL or the pattern absent.

func NewLikeOperatorValue

func NewLikeOperatorValue(probe, pattern Value) *LikeOperatorValue

NewLikeOperatorValue constructs the LIKE Value.

func NewLikeOperatorValueChecked

func NewLikeOperatorValueChecked(probe Value, pattern *PatternForLikeValue) (*LikeOperatorValue, error)

NewLikeOperatorValueChecked is Java's encapsulate (LikeOperatorValue.java:320-327): the probe NULL-typed or STRING, the pattern a PatternForLikeValue.

func (*LikeOperatorValue) Children

func (v *LikeOperatorValue) Children() []Value

Children returns probe + pattern.

func (*LikeOperatorValue) Evaluate

func (v *LikeOperatorValue) Evaluate(evalCtx any) (any, error)

Evaluate is LikeOperatorValue.eval: the probe, then the pattern record, then likeOperation.

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 LikePattern

type LikePattern struct {
	Pattern *string
	Escape  *string
}

LikePattern is a PatternForLikeValue's result, Java's record: a nil field is an absent one.

type MacroFunction

type MacroFunction struct {
	Name   string
	Params []QuantifiedObjectValue
	// ParamTypes are the declared types, which keep a record's storage name
	// the quantified objects' exact types do not.
	ParamTypes []Type
	ParamNames []string
	// Defaults holds each parameter's default, nil where there is none.
	Defaults []Value
	Body     Value
}

MacroFunction is Java's UserDefinedMacroFunction: a body Value over one quantified object per parameter, expanded at each call by substituting the arguments for the parameters.

func MacroFunctionFromProto

func MacroFunctionFromProto(p *gen.PUserDefinedMacroFunction) (*MacroFunction, error)

MacroFunctionFromProto is UserDefinedMacroFunction.fromProto.

func (*MacroFunction) Expand

func (m *MacroFunction) Expand(args []Value) (Value, error)

Expand is encapsulateFromArgumentValues: the body with each parameter's quantified object replaced by its argument.

func (*MacroFunction) HasNamedParameters

func (m *MacroFunction) HasNamedParameters() bool

HasNamedParameters is CatalogedFunction.hasNamedParameters: a function read from metadata that stored no parameter names takes positional calls only.

func (*MacroFunction) ParamIndex

func (m *MacroFunction) ParamIndex(name string) int

ParamIndex is the position of the parameter named name, or -1.

func (*MacroFunction) ToProto

func (m *MacroFunction) ToProto() (*gen.PUserDefinedFunction, error)

ToProto is UserDefinedMacroFunction.toProto: one serialization context over the parameters, their defaults and the body, in that order.

type NarrowValue

type NarrowValue struct {
	Child  Value
	Target Type
	// contains filtered or unexported fields
}

NarrowValue is a value stored into a slot of a declared Target type that its own type does not promote to. A recursive CTE's temporary table is typed by the seed's row (SemanticAnalyzer.getRecursiveCteType) and Java writes later rows into it as they are, so the declared type can be NOT NULL where the written value is nullable, or of another type altogether. Evaluation fails for a value the slot cannot hold instead of letting it flow under a type that misdescribes it.

func NewNarrowValue

func NewNarrowValue(child Value, target Type) *NarrowValue

NewNarrowValue narrows child to target.

func (*NarrowValue) Children

func (n *NarrowValue) Children() []Value

func (*NarrowValue) Evaluate

func (n *NarrowValue) Evaluate(evalCtx any) (any, error)

func (*NarrowValue) Name

func (*NarrowValue) Name() string

func (*NarrowValue) Type

func (n *NarrowValue) Type() Type

type NonEvaluable

type NonEvaluable interface {
	Value
	IsNonEvaluable() bool
}

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 NonNullableFieldError

type NonNullableFieldError struct {
	Field string
}

NonNullableFieldError reports a NULL assigned to a field whose type forbids it — Java's `Verify.verify(fieldType.isNullable(), "Cannot set a non-nullable field to the NULL value")` inside RecordConstructorValue.eval (RecordConstructorValue.java:135). Carried as a typed error so each caller can state it in its own error vocabulary (the SQL layer as 23502) without a second copy of the rule.

func (*NonNullableFieldError) Error

func (e *NonNullableFieldError) Error() string

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).

func NewNotValue

func NewNotValue(child Value) *NotValue

NewNotValue constructs a NotValue.

func (*NotValue) Children

func (n *NotValue) Children() []Value

func (*NotValue) Evaluate

func (n *NotValue) Evaluate(evalCtx any) (any, error)

func (*NotValue) Name

func (*NotValue) Name() string

func (*NotValue) Type

func (*NotValue) Type() Type

Type is NullableBoolean whatever the child: Java's NotValue does not override BooleanValue.getResultType, primitiveType(BOOLEAN), which is nullable (BooleanValue.java:40-42).

type NullArrayElementError

type NullArrayElementError struct{}

NullArrayElementError is Java's SemanticException for an ARRAY element that evaluates to NULL under a NOT NULL element type (0A000).

func (*NullArrayElementError) Error

func (*NullArrayElementError) Error() string

type NullAssignmentError

type NullAssignmentError struct {
	// Field is the slot's path, dotted.
	Field string
	To    Type
}

NullAssignmentError is Java's SemanticException NULL_ASSIGNMENT: a NULL assigned to a slot whose type is not nullable, found when the value is applied (MessageHelpers.coerceObject, per row). The SQL layer renders it as XX000, "A null value cannot be assigned to a variable that is of a non-nullable type."

func (*NullAssignmentError) Error

func (e *NullAssignmentError) Error() string

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

func NewNullValue(typ Type) *NullValue

NewNullValue constructs a NullValue of the given type.

func (*NullValue) Children

func (*NullValue) Children() []Value

func (*NullValue) Evaluate

func (*NullValue) Evaluate(any) (any, error)

func (*NullValue) Name

func (*NullValue) Name() string

func (*NullValue) Type

func (n *NullValue) Type() Type

Type returns the typed-NULL annotation (UnknownType when unannotated). SQL NULL is always nullable so the result is forced to nullable regardless of how the caller stored Typ.

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.

func (*ObjectValue) Name

func (*ObjectValue) Name() string

Name returns the debug-print kind.

func (*ObjectValue) Type

func (v *ObjectValue) Type() Type

Type returns the bound result type.

type OfTypeValue

type OfTypeValue struct {
	Child        Value
	ExpectedType Type
}

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:

  1. NULL probe → returns ExpectedType.IsNullable().
  2. 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).

func (*OfTypeValue) Name

func (*OfTypeValue) Name() string

Name returns the debug-print kind.

func (*OfTypeValue) Type

func (*OfTypeValue) Type() Type

Type is always nullable boolean.

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 OrderingComparisonSite

type OrderingComparisonSite int

OrderingComparisonSite identifies one of the two ordering-value comparators.

const (
	OrderingSiteRequestedVsCandidate OrderingComparisonSite = iota
	OrderingSiteIntersectionKeys
	OrderingComparisonSiteCount
)

type OrderingHooks

type OrderingHooks struct {
	OrderingComparison func(site OrderingComparisonSite, left, right Value, bridge func(a, b Value) bool)
}

OrderingHooks is the ordering-comparison census's sink. That census switches independently of the leg-identity family, so it gets its own slot.

func OrderingCensus

func OrderingCensus() *OrderingHooks

OrderingCensus returns the ordering-comparison census hooks, or nil.

type OrdinalBinderStorage

type OrdinalBinderStorage struct {
	// contains filtered or unexported fields
}

OrdinalBinderStorage is uninitialized room for the row binder InitOrdinalObjectBinder builds. A caller that already allocates a per-row holder — the executor allocates one for the row's evaluation context and its outer/edge binders — embeds this and pays for the layout binder in the SAME allocation instead of a second one. The binder itself stays unexported: the storage is opaque and only the returned interface is usable.

type OrdinalCarrierKind

type OrdinalCarrierKind uint8

OrdinalCarrierKind distinguishes record carriers from scalar carriers.

const (
	OrdinalCarrierInvalid OrdinalCarrierKind = iota
	OrdinalCarrierRecord
	OrdinalCarrierScalar
)

type OrdinalDomain

type OrdinalDomain struct {
	// contains filtered or unexported fields
}

OrdinalDomain names the LAYOUT an ordinal indexes — the third element of column identity (RFC-197: identity is (correlation, domain, ordinal path)).

The same ordinal under the same correlation can address two different layouts: a MACHINERY-OWNED bake's ordinal is final for the executor's assembled row / leg window, while a SOURCE-RELATIVE bake's ordinal indexes the reference's OWN source's declared column order (see FieldPath.FrontierPinned). Comparing ordinals across those two layouts is a type error that reads as authoritative, which is strictly worse than the name conflation this workstream exists to end. So an ordinal is only comparable against a STATED layout, and OrdinalIn is the only way to ask.

The token identifies a layout STRUCTURALLY: the ordered list of the layout's column names. That is exactly the soundness condition for reusing an ordinal — position k of two layouts with the same ordered column list is the same slot — and it is derivable independently by the producer (which resolves a name against a declared column order) and by the consumer (which holds the descriptor-shaped row type). Two structurally identical layouts of different provenance are interchangeable FOR POSITIONAL PURPOSES; distinguishing which quantifier a reference belongs to is the CORRELATION element's job, checked separately by every caller.

The zero value is UNKNOWN: a producer that cannot state which layout its ordinal indexes mints no token, and OrdinalIn fails closed on it. Unknown is therefore the safe default for every construction site that has not been taught its domain — a declined optimization, never a wrong slot.

func OrdinalDomainOfColumnNames

func OrdinalDomainOfColumnNames(cols []string) OrdinalDomain

OrdinalDomainOfColumnNames derives the token for a layout given as an ordered column-name list — the shape the translator's bakers resolve against.

The encoding is length-prefixed so it is INJECTIVE: ["A","B"] and ["A|B"] (or ["AB"]) must not collide, or two different layouts would answer to one token and the check would be theatre. Names are upper-cased because every resolution path in the engine matches case-insensitively. An empty list yields the UNKNOWN token: a layout with no columns states nothing, and treating "" as a real domain would make every not-yet-taught producer's zero token match it.

func OrdinalDomainOfQuantified

func OrdinalDomainOfQuantified(qov QuantifiedObjectValue) OrdinalDomain

OrdinalDomainOfQuantified is OrdinalDomainOfType for a quantifier's flowed row, taking the token off the value's own exact handle. The spelling through FlowedType() thaws a whole ordinary Type graph and then walks it to build a string the handle can already answer with; a foreign QOV view still goes the long way round.

func OrdinalDomainOfType

func OrdinalDomainOfType(t Type) OrdinalDomain

OrdinalDomainOfType derives the token for a layout given as a flowed record type — the shape match candidates, seeds and the executor hold. Anything but a *RecordType (UnknownType, a primitive, a multi-record-type index's degraded row type) has no single column order and yields the UNKNOWN token, so a caller that cannot name its layout fails closed by construction.

func (OrdinalDomain) IsKnown

func (d OrdinalDomain) IsKnown() bool

IsKnown reports whether the token names a layout at all. An unknown token (the zero value) never satisfies OrdinalIn, on either side of the check.

func (OrdinalDomain) String

func (d OrdinalDomain) String() string

String renders the token for diagnostics. Not an identity: use ==.

type OrdinalLayout

type OrdinalLayout interface {
	Carrier() QuantifiedObjectValue
	CarrierKind() OrdinalCarrierKind
	// WindowSources returns the exact local source objects retained inside the
	// carrier. The returned slice is an immutable-view copy; each QOV remains
	// values-owned and can be passed back to exact binding APIs.
	WindowSources() []QuantifiedObjectValue
	// NullSupplyingWindowSources returns, IN WINDOW ORDER, the sources whose
	// match state a binder requires and cannot infer. It exists so a component
	// that must CARRY that state across a boundary — a continuation, a spill —
	// can enumerate exactly the sources it has to carry, in an order both sides
	// agree on without naming anything. Row contents cannot substitute: a
	// matched row of all-NULL columns and an unmatched row are identical in the
	// slots and different in meaning.
	NullSupplyingWindowSources() []QuantifiedObjectValue
	RawEqual(OrdinalLayout) bool
	EqualUnderAliases(OrdinalLayout, AliasMap) bool
	AliasFreeHash() uint64
	// contains filtered or unexported methods
}

OrdinalLayout is the immutable physical description of one evaluation phase. Its concrete representation is values-owned and exact-recognized at every purpose API.

func LayoutWithSeedLegs

func LayoutWithSeedLegs(layout OrdinalLayout, resultValue Value) OrdinalLayout

LayoutWithSeedLegs returns layout with its carrier stating the leg boundaries the RESULT VALUE knows, for the case where the layout itself cannot know them.

A layout derives boundaries from its own source windows, which works whenever it has one window per leg. It does not work for the shape that matters most: a merged box row published as ONE window covering the whole concat. There the only description of which source owns which slots lives in the seed RecordConstructor, and a carrier built without it flows a row whose qualified reads resolve into the first leg. So the two halves are joined at the one point that holds both — the plan's own admission of (result value, layout).

Layouts that already state boundaries are returned untouched, as is any layout whose seed cannot state them exactly, so this only ever ADDS physical information. Identity is unaffected: legs are not part of exact-type identity, and the layout's alias-free hash is carried over unchanged because nothing hashable changed.

func NewFlatOrdinalLayoutForResult

func NewFlatOrdinalLayoutForResult(result Value, sources []OrdinalOutputSource) (OrdinalLayout, error)

NewFlatOrdinalLayoutForResult derives a physical flat carrier and exact source windows from a RecordConstructor result program. A record source in field mode must occur exactly once per field as one-step FieldValues. Any exact source (including a scalar) may instead occupy one complete ObjectPath slot. Computed/constant output fields remain ordinary flat carrier slots.

Partial sources deliberately fail instead of fabricating sparse records: a downstream source-relative FieldValue is legal only when the whole typed QOV object can be bound. Projections that retain only part of a source must address their output through the carrier/current QOV instead.

func NewFlatOrdinalLayoutForRetainedResult

func NewFlatOrdinalLayoutForRetainedResult(result Value, nullSupplying []QuantifiedObjectValue) (OrdinalLayout, error)

NewFlatOrdinalLayoutForRetainedResult discovers every complete exact QOV retained by a flat result program and publishes an object/field window for it. Partial sources are intentionally absent: they cannot be materialized as a whole typed object. nullSupplying identifies the subset whose edge may be unmatched on a row.

func NewFlatOrdinalLayoutForRetainedResultWithSources

func NewFlatOrdinalLayoutForRetainedResultWithSources(
	result Value,
	nullSupplying []QuantifiedObjectValue,
	additional []OrdinalOutputSource,
) (OrdinalLayout, error)

NewFlatOrdinalLayoutForRetainedResultWithSources adds exact producer-proven whole-object sources to the sources discovered directly in result. This is used by a materializing parent whose flat result program copies one scalar source out of a selected child carrier: the scalar is no longer a direct QOV slot in the parent's program, but the child producer and the parent's output ordinal together still prove its complete ObjectPath.

additional is not a compatibility escape hatch. NewFlatOrdinalLayoutForResult revalidates every source and path against result and rejects duplicate correlations, exact-type conflicts, and paths which do not select the exact source type.

func NewOrdinalLayout

func NewOrdinalLayout(
	carrier QuantifiedObjectValue,
	tiles []OrdinalTileSpec,
	windows []OrdinalWindowSpec,
) (OrdinalLayout, error)

NewOrdinalLayout validates and snapshots a record-carrier layout.

func NewOrdinalLayoutForCarrierType

func NewOrdinalLayoutForCarrierType(
	typ Type,
	tiles []OrdinalTileSpec,
	windows []OrdinalWindowSpec,
) (OrdinalLayout, error)

NewOrdinalLayoutForCarrierType is the purpose factory for an owner that has not yet published its current QOV. It snapshots typ, privately mints the exact current handle, and atomically validates the layout around that handle. The handle is exposed only as layout.Carrier().

func NewScalarOrdinalLayout

func NewScalarOrdinalLayout(carrier QuantifiedObjectValue) (OrdinalLayout, error)

NewScalarOrdinalLayout validates an exact scalar current carrier. Scalar layouts deliberately contain neither tiles nor source windows.

func NewScalarOrdinalLayoutForCarrierType

func NewScalarOrdinalLayoutForCarrierType(typ Type) (OrdinalLayout, error)

NewScalarOrdinalLayoutForCarrierType is the scalar counterpart of NewOrdinalLayoutForCarrierType.

type OrdinalOutputSource

type OrdinalOutputSource struct {
	Source QuantifiedObjectValue
	// ObjectPath is non-nil when the result retains Source as one complete
	// nested object instead of copying its fields into separate output slots.
	// NewFlatOrdinalLayoutForRetainedResult derives this only from a bare exact
	// record QOV occupying one RecordConstructor slot.
	ObjectPath    []int
	NullSupplying bool
}

OrdinalOutputSource declares a quantified source whose complete object is retained by a flat RecordConstructor output. A record can be retained field-by-field or as one nested object; a scalar is necessarily retained as one object slot. NullSupplying is physical edge information; it is never inferred from a nullable logical type.

type OrdinalResolutionError

type OrdinalResolutionError struct {
	Field     string
	Ordinal   int
	Available []string
}

OrdinalResolutionError is the loud internal error 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

type OrdinalRow interface {
	Get(ordinal int) (any, bool)
}

OrdinalRow is the ordinal-model runtime row FieldValue.Evaluate reads. It is satisfied structurally by executor.PositionalRow, which lives in a higher layer — the interface here avoids the import cycle.

Get(ordinal) is the ONLY read: every FieldValue carries a plan-time-baked ordinal (Resolved) and reads its slot positionally — Java's MessageHelpers.getFieldValueForFieldOrdinals. A miss is a loud error (never a silent NULL): column existence is validated at plan time (42703), so a runtime miss is a malformed plan. There is no name-keyed read arm — Java's runtime never sees a column name (FieldValue.java:164-169).

type OrdinalSeedLegWindow

type OrdinalSeedLegWindow struct {
	// Kind says whether Offset starts a flat RUN of the leg's columns or names
	// the SINGLE slot holding the leg's whole row. Its zero value is
	// LegKindUnset, which is invalid: every reader below declines or fails loud
	// on it rather than defaulting to flatRun, because defaulting is an inference
	// about which column a read addresses and the language is not entitled to
	// make it. See LegKind's own doc for why no structural inference works.
	Kind LegKind

	// Offset is the leg's first slot in the merged row for a flatRun window, and
	// the leg's ONE slot for a nested one. Reading it without dispatching on Kind
	// is the wrong-offset wrong-rows failure this authority exists to prevent.
	Offset int
	// Typ is the leg's own record type, under BOTH kinds — never a one-field
	// wrapper describing the slot. Readers bound a leg-local ordinal against it
	// before composing, so a wrapper would decline every leg-local ordinal >= 1
	// and resolve ordinal 0 against the wrapper: a silent wrong-column read on
	// exactly the shape the bound check exists to catch.
	Typ *RecordType

	// Alias is the window's leg IDENTITY: the correlation of the quantifier whose
	// row occupies this window, carried VERBATIM from the seed's own
	// QuantifiedObjectValue.
	//
	// It is never minted from the upper-folded alias text: the fold is a no-op
	// where the correlation is already upper and manufactures a forgery where it
	// is not, since the machine namespace is LOWERCASE and folding a minted q$N
	// yields the Q$N that SameLeg exists to exclude.
	//
	// The map's KEYS are this same identifier, so there is one namespace, not two
	// held apart. A text key would merge the two alias namespaces the rest of this
	// package keeps deliberately DISJOINT — user correlations upper-folded at the
	// semantic scope, machine mints lowercase — so a quoted "q$5" and a
	// planner-minted q$5 would be one key while being two legs.
	//
	// querycensus.AssertSeedWindowReaderCensus floors each of the five keyed readers so one
	// going dark reds instead of printing a clean-looking zero, and hard-zeros its
	// two DECLINE classes.
	Alias CorrelationIdentifier
}

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. 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 OrdinalTileKind

type OrdinalTileKind uint8

OrdinalTileKind identifies how a consecutive range of fields is physically represented inside one record carrier.

const (
	OrdinalTileInvalid OrdinalTileKind = iota
	OrdinalTileFlat
	OrdinalTileNested
)

type OrdinalTileSpec

type OrdinalTileSpec struct {
	Parent []int
	Start  int
	Width  int
	Kind   OrdinalTileKind
}

OrdinalTileSpec is mutable construction input. NewOrdinalLayout snapshots Parent and never retains this value.

type OrdinalWindowSpec

type OrdinalWindowSpec struct {
	Source        QuantifiedObjectValue
	ObjectPath    []int
	FieldPaths    [][]int
	NullSupplying bool
}

OrdinalWindowSpec declares where one exact source object is represented in the carrier. Exactly one of ObjectPath and FieldPaths must be non-nil.

type ParameterBinder

type ParameterBinder interface {
	BindParameter(ordinal int, name string) (any, bool)
}

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

type ParameterObjectValue struct {
	ParameterName string
	ResultType    Type
}

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

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) Evaluate

func (p *ParameterValue) Evaluate(evalCtx any) (any, error)

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

type PatternForLikeValue struct {
	PatternChild Value
	EscapeChild  Value
}

PatternForLikeValue is Java's PatternForLikeValue: a LIKE pattern and its escape, evaluated into a two-field record — field 1 the pattern, field 2 the escape, each absent when NULL (PatternForLikeValue.java:92-131). The escape is validated whenever it is present, the pattern against it only when both are.

func NewPatternForLikeValue

func NewPatternForLikeValue(pattern, escape Value) *PatternForLikeValue

NewPatternForLikeValue is the value over a pattern and an escape; an absent ESCAPE is a NULL escape child, as Java's visitor builds it.

func NewPatternForLikeValueChecked

func NewPatternForLikeValueChecked(pattern, escape Value) (*PatternForLikeValue, error)

NewPatternForLikeValueChecked is Java's encapsulate (PatternForLikeValue.java:231-239): the pattern and the escape are each NULL-typed or STRING.

func (*PatternForLikeValue) Children

func (v *PatternForLikeValue) Children() []Value

Children returns [pattern, escape].

func (*PatternForLikeValue) Evaluate

func (v *PatternForLikeValue) Evaluate(evalCtx any) (any, error)

Evaluate is PatternForLikeValue.eval: the pattern is evaluated first, then the escape, which is validated when present, and the pattern against it when both are.

func (*PatternForLikeValue) Name

func (*PatternForLikeValue) Name() string

Name returns the SQL function name.

func (*PatternForLikeValue) Type

func (*PatternForLikeValue) Type() Type

Type is the two-field record.

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 NewJavaPickValue

func NewJavaPickValue(selector Value, alternatives []Value) (*PickValue, error)

NewJavaPickValue is PickValue.PickValueFn.encapsulate (PickValue.java:235-256): the alternatives are promoted to their maximum type, which made nullable is the result type.

func NewPickValue

func NewPickValue(selector Value, alternatives []Value, resultType Type) *PickValue

NewPickValue constructs the picker with selector + alternatives + result Type.

func (*PickValue) Children

func (v *PickValue) Children() []Value

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.

func (*PickValue) Evaluate

func (v *PickValue) Evaluate(evalCtx any) (any, error)

Evaluate computes Alternatives[Selector.Evaluate].

Returns nil if:

  • Selector is nil-Value or evaluates to nil.
  • Selector doesn't evaluate to an integer kind.
  • The resolved index is out of bounds for Alternatives.
  • The chosen alternative is nil-Value.

func (*PickValue) Name

func (*PickValue) Name() string

Name returns the debug-print kind.

func (*PickValue) Type

func (v *PickValue) Type() Type

Type returns the bound result type.

type PrimitiveType

type PrimitiveType struct {
	TypeCode TypeCode
	Nullable bool
}

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) Code

func (p *PrimitiveType) Code() TypeCode

Code implements Type.

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 ProjectionAliasSource

type ProjectionAliasSource struct {
	Source  CorrelationIdentifier
	Present bool
}

ProjectionAliasSource is the structured source identity captured when the planner machinery mints a projection alias for an internal datum key.

The source is deliberately independent of the Value that computes the slot. Physical planning can reanchor that Value onto an exact current-row carrier, but doing so must not rewrite the authored source that supplied the alias. Present distinguishes an uncaptured source from the zero correlation; callers must never recover a missing source by parsing the alias spelling.

func NewProjectionAliasSource

func NewProjectionAliasSource(source CorrelationIdentifier) ProjectionAliasSource

NewProjectionAliasSource constructs a present structured source. A zero correlation cannot name an authored source, so it stays absent.

type PromoteValue

type PromoteValue struct {
	Child  Value
	Target Type
	// contains filtered or unexported fields
}

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 converts numeric carriers to the target width and handles the STRING→UUID representation change. Other promotion families remain representation-preserving.

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 NewPromoteValueChecked

func NewPromoteValueChecked(child Value, target Type) (*PromoteValue, error)

NewPromoteValueChecked eagerly prepares the relation and reports admission errors.

func (*PromoteValue) BindPromotionTypes

func (p *PromoteValue) BindPromotionTypes(repo *TypeProtoRepository) error

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)

func (*PromoteValue) ForEachMessageDescriptor

func (p *PromoteValue) ForEachMessageDescriptor(visit func(protoreflect.MessageDescriptor))

ForEachMessageDescriptor visits the immutable target descriptors bound to this promotion, including nested record and array-element promotions.

func (*PromoteValue) Name

func (*PromoteValue) Name() string

func (*PromoteValue) Prepare

func (p *PromoteValue) Prepare() error

Prepare prepares a direct struct literal. It never repairs a mutated prepared node: use checked reconstruction to create a new relation instead.

func (*PromoteValue) RegisterPromotionTypes

func (p *PromoteValue) RegisterPromotionTypes(repo *TypeProtoRepository) error

RegisterPromotionTypes and BindPromotionTypes are the collect and bind halves used by the plan finalizer. Both precede publication to concurrent evaluators.

func (*PromoteValue) Type

func (p *PromoteValue) Type() Type

Type returns the declared target including its nullability, as Java's PromoteValue.getResultType does. Source nullability is not substituted.

type PromotionError

type PromotionError struct{ Reason string }

PromotionError reports an invalid declared coercion, unprepared literal, or mutation of an already prepared relation. It is detected before child evaluation.

func (*PromotionError) Error

func (e *PromotionError) Error() string

type ProtoTypeError

type ProtoTypeError struct {
	// TypeName is the offending type rendered via Type.String().
	TypeName string
	// Reason states what about it has no protobuf form.
	Reason string
}

ProtoTypeError reports a type that cannot be given a protobuf descriptor. Java throws RecordCoreException from the addProtoField of the types that have no protobuf form (FUNCTION at Type.java:3414, and the erased/unresolved shapes that fail their Objects.requireNonNull).

func (*ProtoTypeError) Error

func (e *ProtoTypeError) Error() string

func (*ProtoTypeError) JavaRecordCoreException

func (*ProtoTypeError) JavaRecordCoreException()

type QOVPrototype

type QOVPrototype struct {
	// contains filtered or unexported fields
}

QOVPrototype is what NewQuantifiedObjectValue derives from a flowed type: its exact snapshot and source layout. Deriving it once lets QOVs over the same unchanged type skip re-snapshotting it.

func NewQOVPrototype

func NewQOVPrototype(flowed Type) (*QOVPrototype, error)

NewQOVPrototype snapshots flowed as NewQuantifiedObjectValue does.

func (*QOVPrototype) QuantifiedObjectValue

func (p *QOVPrototype) QuantifiedObjectValue(correlation CorrelationIdentifier) (QuantifiedObjectValue, error)

QuantifiedObjectValue is NewQuantifiedObjectValue over the prototype's type.

type QualifierRecoveryClass

type QualifierRecoveryClass int

QualifierRecoveryClass is one decision's bucket. The six partition every call.

const (
	QualRecCarried QualifierRecoveryClass = iota
	QualRecAgreed
	QualRecDiverged
	QualRecManufactured
	QualRecLeafOnly
	QualRecBare
	QualRecHeuristicDecline
	QualRecClassCount
)

func ClassifyQualifierRecovery

func ClassifyQualifierRecovery(name, identity string, identityPresent bool) (QualifierRecoveryClass, string)

ClassifyQualifierRecovery is the shared classifier for a site that splits a rendered name and MAY hold a structured qualifier for the same reference.

It exists so the six sites cannot drift in how they bucket the same situation. A site that classified by hand would be free to call its own disagreement "manufactured" (no counterparty) rather than "DIVERGED", which is precisely the reading that would make the hard zero pass while the misread continued.

`identity` is the structured qualifier the site holds, or "" when it holds none — and holding none is a different fact from holding an EMPTY one, which is why an unqualified structured identity must be passed as its own signal via identityPresent.

type QualifierRecoverySite

type QualifierRecoverySite int

QualifierRecoverySite is one of the four dark splitters named in querycensus/name_split_census.go's header. The parseColRef family contributes THREE sites rather than one: its 27 production call sites are overwhelmingly display or lookup, and only three of them manufacture a qualifier that then DECIDES something. Those three are what is counted, individually, because they are three different decisions with three different counterparties and a single merged "parseColRef" number could not answer the conversion question for any of them.

const (
	QualRecSiteRecursiveRemap QualifierRecoverySite = iota
	QualRecSiteExistsSortSplit
	QualRecSiteDerivedUnnestSource
	QualRecSiteProjScopeClassify
	QualRecSiteProjQualVsScan
	QualRecSiteDisplayLabelStrip
	QualRecSiteCount
)

type QuantifiedObjectBinder

type QuantifiedObjectBinder interface {
	GetQuantifiedBinding(QuantifiedObjectValue) (value any, present bool, err error)
}

QuantifiedObjectBinder resolves an exact QOV to its whole runtime object. The boolean distinguishes an absent binding from a present SQL NULL.

func InitOrdinalObjectBinder

func InitOrdinalObjectBinder(
	storage *OrdinalBinderStorage,
	layout OrdinalLayout,
	carrier any,
	presence WindowMatchPresence,
	base QuantifiedObjectBinder,
) (QuantifiedObjectBinder, error)

InitOrdinalObjectBinder is NewOrdinalObjectBinder writing into storage the caller owns. storage must be zero and must not be reused while the returned binder is live.

func NewOrdinalObjectBinder

func NewOrdinalObjectBinder(
	layout OrdinalLayout,
	carrier any,
	presence WindowMatchPresence,
	base QuantifiedObjectBinder,
) (QuantifiedObjectBinder, error)

NewOrdinalObjectBinder materializes the current carrier and every local source window for one row. A record carrier is an OrdinalRow (or nil only for a nullable current record); a scalar carrier is the scalar datum itself. External/edge bindings may be delegated to base.

func NewRequiredOrdinalObjectBinder

func NewRequiredOrdinalObjectBinder(
	layout OrdinalLayout,
	carrier any,
	presence WindowMatchPresence,
	required RequiredBindings,
	edgeBindings []TypedEdgeBinding,
	base QuantifiedObjectBinder,
) (QuantifiedObjectBinder, error)

NewRequiredOrdinalObjectBinder constructs the runtime binder only after the planning-time origin manifest proves that the selected layout provides exactly its local window sources and that every declared edge has one runtime whole-object binding. External origins continue through base.

type QuantifiedObjectValue

type QuantifiedObjectValue interface {
	Value
	Correlation() CorrelationIdentifier
	FlowedType() Type
	// contains filtered or unexported methods
}

QuantifiedObjectValue is the sealed read view of one correlation-bearing whole object. Its flowed type is an immutable exact snapshot, not a mutable ordinary Type graph retained from the caller.

func AsQuantifiedObjectValue

func AsQuantifiedObjectValue(value Value) (QuantifiedObjectValue, bool)

AsQuantifiedObjectValue exact-recognizes the package-owned concrete node.

func CurrentPhaseCarrierForEdge

func CurrentPhaseCarrierForEdge(edge QuantifiedObjectValue) (QuantifiedObjectValue, error)

CurrentPhaseCarrierForEdge returns the reserved-current carrier that denotes the row phase a declared physical edge delivers. The edge's exact flowed type is carried over unchanged, so the result is the exact QOV a selected child's layout would publish for that same phase — TranslateDeclaredEdgeRoot's own precondition is that declaration and target agree on the exact shape.

It exists for the alias-to-current rebases Java spells as AliasMap.ofAliases(quantifier.getAlias(), Quantifier.current()): a value an expression states over one of its own child EDGES, handed to that child's Reference, has to arrive in the reference's own row space, because the reference has never heard of the parent's alias for it.

Pair it with TranslateDeclaredEdgeRoot as the TARGET, never as the declaration. The shape precondition — declaration and target agree on the exact object — is satisfied by construction, since the edge's exact type is carried over unchanged. The result is a CURRENT correlation, though, and TranslateDeclaredEdgeRoot rejects a current declaration outright, so passing it on the other side is an error rather than a no-op.

The exact type is what makes the target well-defined: every member of a Reference carries that Reference's result type (memo admission enforces it), so the carrier derived from the edge describes the row every member of that group delivers, not one alternative's.

func NewPhysicalCarrierQOV

func NewPhysicalCarrierQOV(correlation CorrelationIdentifier, layout OrdinalLayout) (QuantifiedObjectValue, error)

NewPhysicalCarrierQOV is NewQuantifiedObjectValue(correlation, PhysicalCarrierType(layout)), rebinding a record carrier's frozen snapshot and layout as rebase does.

func NewQuantifiedObjectValue

func NewQuantifiedObjectValue(
	correlation CorrelationIdentifier,
	flowed Type,
) (QuantifiedObjectValue, error)

NewQuantifiedObjectValue snapshots flowed and returns an exact QOV. The ordinary constructor cannot mint the reserved current correlation; current handles belong to the checked owner-value builder.

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

type QueriedValue struct {
	RecordTypes []string
	ResultType  Type
}

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.

func (*QueriedValue) Evaluate

func (*QueriedValue) Evaluate(any) (any, error)

Evaluate returns nil — QueriedValue is a placeholder. Specialized planner rewrites resolve it to concrete Field / QuantifiedObject values before any row-level eval.

func (*QueriedValue) Name

func (*QueriedValue) Name() string

Name returns the debug-print kind.

func (*QueriedValue) Type

func (v *QueriedValue) Type() Type

Type returns the bound result type.

type RangeBoundsError

type RangeBoundsError struct{ Message string }

RangeBoundsError is Java's RecordCoreException from Cursor.checkValidRange.

func (*RangeBoundsError) Error

func (e *RangeBoundsError) Error() string

func (*RangeBoundsError) JavaRecordCoreException

func (*RangeBoundsError) JavaRecordCoreException()

type RangeValue

type RangeValue struct {
	BeginInclusive Value
	EndExclusive   Value
	Step           Value
}

RangeValue is the built-in range(begin, end, step) table function (Java's RangeValue): a stream of rows (ID LONG) from beginInclusive up to but not including endExclusive. Children are LONG-promoted at construction.

func NewRangeValue

func NewRangeValue(begin, end, step Value) *RangeValue

func (*RangeValue) Bounds

func (r *RangeValue) Bounds(evalCtx any) (begin, end, step int64, err error)

Bounds evaluates the three children and applies Java's checkValidRange.

func (*RangeValue) Cardinality

func (r *RangeValue) Cardinality() (int64, bool)

Cardinality is Java's floorDiv(end - begin, step) over constant bounds.

func (*RangeValue) Children

func (r *RangeValue) Children() []Value

Children returns [begin, end, step].

func (*RangeValue) Evaluate

func (*RangeValue) Evaluate(any) (any, error)

Evaluate: a streaming value has no scalar result (Java throws).

func (*RangeValue) EvaluateAsStream

func (r *RangeValue) EvaluateAsStream(evalCtx any) []int64

EvaluateAsStream materialises the range, or nil when the bounds are invalid.

func (*RangeValue) Name

func (*RangeValue) Name() string

func (*RangeValue) Type

func (*RangeValue) Type() Type

Type is the per-row record type (ID LONG).

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

func NewRankValue(partitioningValues []Value) *RankValue

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

func (*RankValue) Evaluate(evalCtx any) (any, error)

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) Name

func (*RankValue) Name() string

Name returns the SQL function name.

func (*RankValue) Type

func (*RankValue) Type() Type

Type is nullable LONG, Java's primitiveType(LONG): Evaluate returns NULL without a rank in its context.

func (*RankValue) WithChildren

func (r *RankValue) WithChildren(newChildren []Value) *RankValue

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 RecordConstructorField

type RecordConstructorField struct {
	Name  string
	Value Value
}

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
	// contains filtered or unexported fields
}

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 NewRawRecordConstructorValue

func NewRawRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue

NewRawRecordConstructorValue constructs a machinery-owned positional RecordConstructorValue keeping every field name VERBATIM — duplicate names allowed. It exists for ordinal-join seeds and private aggregate output rows: a join's ordinal RC concatenates the 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 the duplicate-name identity pins are unconstructible without them.

NEVER use this for a user-facing projection RC: NewRecordConstructorValue (above) appends _2/_3 suffixes, which is correct there (SQL projection column naming) — a raw duplicate is not addressable by name at all: the plan-time lookup declines on the ambiguity, so a projection built this way would lose the columns rather than name them, the exact conflation ordinal identity exists to avoid.

func NewRecordConstructorValue

func NewRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue

NewRecordConstructorValue constructs a RecordConstructorValue. Duplicate field names are deduplicated by DedupFieldNames so the record type stays name-addressable; see there for why the suffix is internal.

func ProjectionResultValue

func ProjectionResultValue(projections []Value, aliases []string) (*RecordConstructorValue, error)

ProjectionResultValue builds the row a projection PRODUCES, as a record constructor over its projected values and output aliases. It is the single authority for that derivation, shared by the logical projection expression and its physical twin so the two cannot drift.

Slot names come from OutputColumnName — the same authority the executor uses to name the emitted positional row — so the type a projection STATES matches the row it EMITS. A slot that still resolves to no name takes Java's ordinal spelling, "_"+i (Type.java normalizeFields).

Duplicate names go through NewRecordConstructorValue's _2/_3 dedup, never the raw constructor: a raw duplicate under name-keyed lookup resolves to the first match, the exact conflation ordinal identity exists to prevent.

func ProjectionResultValueForOutputSchema

func ProjectionResultValueForOutputSchema(
	projections []Value,
	aliases []string,
	outputNames []string,
) (*RecordConstructorValue, error)

ProjectionResultValueForOutputSchema builds the exact row a projection produces while optionally preserving a schema that was already established by the logical SQL boundary. A nil outputNames derives names from the Value program and aliases exactly like ProjectionResultValue. A non-nil slice is authoritative: alpha-rebasing a Value onto a physical child must not rename the SQL column it computes.

A one-slot whole-record QOV is still rejected even with an explicit name: the executor emits one slot per projection, so naming that slot does not make it equivalent to the inner record's N top-level fields.

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 the constructed record.

STAMPED (the plan path): a dynamicpb message of the baked descriptor, which is what Java always produces (RecordConstructorValue.eval builds a DynamicMessage from the per-plan TypeRepository). This is the only form that can reach the driver as an api.Struct, because a bare map carries no declared field ORDER and no type identity.

UNSTAMPED: the name-keyed map. It is the representation for constructors that never went through a plan walk at all — constant folding evaluates a constructor at build time (before any plan exists to walk), and unit tests hand-build constructors directly; neither has a repository to bake against, and neither reaches the driver.

A constructor IN a plan is usually stamped, but NOT always. FinalizePlan's doc owns the enumeration of when it is not: a type with no message form; a record or field name protoname cannot escape; and a row whose descriptor cannot VALIDATE for a reason other than a declared-name clash. None of the three fails the query.

An unstamped constructor does not imply this branch runs for it. The plan paths that emit a row — executeMap, the record-constructor arm of the flat-map cursor, evaluateOrdinalJoinRow — build a dense PositionalRow field by field, and the result set reads those slots by ORDINAL, so an unstamped row still delivers every field. The duplicate-name join regression in queryfixtures.DuplicateNameJoinQuery pins both ID slots under FDB. Failed registration now rolls back, so unrelated computed constructors keep their descriptors while the invalid ordinal row remains raw.

func (*RecordConstructorValue) MessageDescriptor

func (r *RecordConstructorValue) MessageDescriptor() protoreflect.MessageDescriptor

MessageDescriptor returns the stamped descriptor, or nil if this constructor was never walked by FinalizePlan.

func (*RecordConstructorValue) Name

Name returns the debug-print kind.

func (*RecordConstructorValue) SetMessageDescriptor

func (r *RecordConstructorValue) SetMessageDescriptor(md protoreflect.MessageDescriptor)

SetMessageDescriptor stamps the plan-time descriptor. Plan-time only — see the field comment for why a later write races.

func (*RecordConstructorValue) SetTypeName

func (r *RecordConstructorValue) SetTypeName(name string)

SetTypeName records the declared name of a named struct literal. Plan-time only, for the same reason SetMessageDescriptor is.

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).

func (*RecordConstructorValue) TypeName

func (r *RecordConstructorValue) TypeName() string

TypeName returns the declared name of a named struct literal, or "" when the record is anonymous.

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
	// StorageName is the record's protobuf message name where it differs
	// from RecordName (Java's Type.Record storageName).
	StorageName 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: 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 — layout metadata only.
	//
	// Memo identity ignores it. The memo keys a record type on
	// values.SemanticHashCode, values.SemanticEqualsUnderAliasMap and
	// values.EqualsWithoutChildren (plus String(), which is not identity but is
	// what EXPLAIN goldens diff on), pinned by
	// executor.TestLegColumnOwner_TheLegTableReachesNoMemoIdentity; the two memo
	// sites that dispatch into Equals are pinned by
	// expressions.TestMemoExpressionIdentity_IgnoresTheLegTable.
	Legs []RecordTypeLeg
}

RecordType is the Type impl for struct-shaped data. Mirrors Java's Record nested type. Two RecordType instances are Equal iff their Nullable flags match AND their Fields slice is element-wise equal (same length, each Field equals at the same index). The record's own name is provenance; field names remain part of Field equality.

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

OrdinalSeedLegWindows derives per-leg windows (leg IDENTITY → 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: translated/fused, folded, 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 (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).

THIS ENTRY'S ACCEPT SET IS FROZEN, and freezing it is a design decision rather than inertia. It has many call sites and most of them consume the result as a nil/non-nil PREDICATE — "is this an ordinal seed?" — and at a nil/non-nil predicate, POPULATION IS MEANING: a shape that starts returning non-nil does not keep the same semantics over a larger population, it flips that consumer's branch. Widening here to admit the nested kind would silently change rule arms nobody analysed. The nested acceptance is OrdinalSeedLegWindowsAcceptingNested, a separate opt-in entry.

It also DECLINES, fail-closed, any seed carrying a nested leg — rather than returning it top-level-only. A caller given top-level-only windows would silently be missing sub-windows it would have had for a flat box leg, and a declined optimization is recoverable while a wrong ordinal is not.

func OrdinalSeedLegWindowsAcceptingNested

func OrdinalSeedLegWindowsAcceptingNested(rc *RecordConstructorValue) (map[CorrelationIdentifier]OrdinalSeedLegWindow, *RecordType)

OrdinalSeedLegWindowsAcceptingNested is OrdinalSeedLegWindows plus the NESTED leg kind (RFC-200). It is a separate entry point, opted into by exactly three sites, and the separation is the whole design: see OrdinalSeedLegWindows for why widening the shared boundary would flip consumers this acceptance never analysed.

The flag controls exactly two decisions and nothing else:

  • whether a whole-RC POSITIONAL MERGE is recognized at the head, yielding one nested window per slot;
  • whether finalizeSeedWindows emits a nested SUB-window for a nested leg of a carrying run, instead of declining the seed.

Everything else — the pristine walk, the mixed-element walk, the coverage checks, the >= 2 window rule — is byte-identical between the two entries.

func PhysicalFlowedRecordTypeOf

func PhysicalFlowedRecordTypeOf(v QuantifiedObjectValue) *RecordType

PhysicalFlowedRecordTypeOf is physicalFlowedRecordType for a caller OUTSIDE this package that is about to RE-MINT a QOV from an existing one, and it exists because that re-mint is where the physical layout is otherwise lost.

FlowedType withholds .Legs on purpose — layout must not reach the semantic surface, and TestQOVSourceLayoutIsImmutableNonSemanticAndBecomesPhysicalWindows pins that. But NewQuantifiedObjectValue snapshots its source layout FROM THE TYPE IT IS GIVEN, so re-minting through the public type yields a QOV whose layout is silently empty. A merged row then reports no leg boundaries, the window derivation emits ONE run spanning the whole concat keyed by the box's rightmost leaf (the sourceBinding convention), and an alias-qualified read resolves at runOffset+ordinal — inside the FIRST leg. Measured on `FOA FULL OUTER FOB`: `FOB.K` read FOA's K, inverting EXISTS and NOT EXISTS.

Returns nil when the value is not a record-typed QOV, so a caller keeps the type it already had rather than substituting one.

This is a PHYSICAL accessor, never a semantic one: exact-type identity does not consider .Legs, so a type from here compares equal to the same type from FlowedType. Use it where the physical row is what is being carried, and FlowedType everywhere else.

func WithoutPseudoFields

func WithoutPseudoFields(rt *RecordType) *RecordType

WithoutPseudoFields is a planner-facing record layout without the trailing pseudo-fields Go's layouts carry: the table's own type, Java's RecordLayerTable.getType(), which addPseudoFields never extends. It is the type an INSERT's rows are admitted against (RecordQueryInsertPlan.insertPlan computes its promotions over the table type). A record with no trailing pseudo-field is returned as it is.

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 — nullable + element-wise field equality.

RecordName is deliberately NOT compared, matching Java's Type.Record.equals/computeHashCode, which hash and compare (typeCode, isNullable, fields) and never the name. A record type's name is PROVENANCE — which descriptor or alias the shape was derived from — not identity: the same row reached by two routes legitimately carries two names (a leg typed from its table descriptor vs the same leg re-derived through a projection), and Java lets those compare equal because nothing downstream reads rows by record name.

Making the name identity is not a stricter version of the same check, it is a DIFFERENT one, and it fails in the direction that rejects correct plans: an exact QOV minted from the descriptor and the one minted from the derived row then denote "different" types for one alias and the binder refuses a lookup it must serve.

func (*RecordType) FieldIndexUnique

func (r *RecordType) FieldIndexUnique(name string) (int, bool)

FieldIndexUnique returns the SLICE POSITION of the field named `name`, and only when the name matches EXACTLY ONE field. Absent and DUPLICATED both report false.

The slice position 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. Empty name never matches (anonymous fields aren't addressable by name).

It replaced a first-match `FieldIndex`, which was deleted rather than kept beside it. A record type may legitimately carry repeated names — a leg-concat of two sources merges `A.K` and `B.K` into one row, and the raw &RecordType{...} literals on the join path exist precisely because NewRecordType refuses to build that shape — so a first match is indistinguishable from a correct answer, and the caller has no way to tell them apart afterwards. Disambiguating needs leg identity the type alone does not carry. Keeping both forms would have left the first-match one as a copy target for the next site; every caller that survives the removal either carries an ordinal or declines.

func (*RecordType) FieldNameHits

func (r *RecordType) FieldNameHits(name string) int

FieldNameHits reports HOW MANY fields declare `name` — 0 absent, 1 unambiguous, >1 duplicated. Empty name never matches, exactly as FieldIndexUnique.

It exists because FieldIndexUnique's single `found` flag folds two facts a caller may have to treat DIFFERENTLY. Absent is routinely benign: a canonical column missing from one layout keys as NULL, a leg column the source row does not carry stays unbound. Duplicated is never benign — the value exists, twice, and answering NULL for it is a silent wrong answer rather than a missing one. A caller whose absent branch means "there is nothing to read" MUST NOT reach that branch for a name the row declares twice, and this is how it tells.

Callers that would do the same thing either way keep using FieldIndexUnique; this is not a first-match escape hatch, and it returns no ordinal for the duplicated case precisely so it cannot become one.

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) IsNullable

func (r *RecordType) IsNullable() bool

IsNullable implements Type.

func (*RecordType) LookupFieldUnique

func (r *RecordType) LookupFieldUnique(name string) (Field, bool)

LookupFieldUnique is FieldIndexUnique returning the field rather than its position. Same contract: exactly one match, or false.

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 {
	// Kind preserves the row layout across planner seed windows and runtime binders.
	Kind LegKind

	// Alias identifies the quantifier whose row occupies this leg.
	// Compare it through SameLeg; reconstructing it from Name loses identity.
	Alias CorrelationIdentifier

	// Name is the text label used by dotted-column binding and diagnostics.
	// Correlation-based lookups must compare Alias with SameLeg instead.
	Name string

	Start int // its first slot within the carrying type
	// Width counts slots in the carrying type: columns for a flat run,
	// or one slot holding the whole row for a nested leg.
	Width int
}

RecordTypeLeg is one buried source's boundary within a clustered box leg's flat ordinal concat (see RecordType.Legs).

func NewRecordTypeLeg

func NewRecordTypeLeg(kind LegKind, alias CorrelationIdentifier, name string, start, width int) RecordTypeLeg

NewRecordTypeLeg requires explicit kind and correlation identity so callers cannot omit them as they could in a struct literal.

func SeedTilingLegs

func SeedTilingLegs(rv Value, width int) []RecordTypeLeg

SeedTilingLegs recovers the leg boundaries a seed RecordConstructor states, for a producer that derives a row TYPE from a result VALUE.

The two describe the same row and only one of them carries boundaries: the type is a flat field list, while the seed says which source owns which slots. A producer that keeps only the type hands downstream a row that has forgotten where its legs start — and that reads not as "no legs" but as ONE run over the whole concat, keyed by the box's rightmost leaf, so an alias-qualified column resolves inside the FIRST leg.

The windows map is not itself a tiling: finalization both adds per-leaf sub-windows beside a box run and replaces a run with a narrower one, so entries can overlap (a `C$BOX` run at 0 and its first leaf also at 0). The tiling is recovered by taking, at each cursor position, the NARROWEST window starting exactly there — leaves tile, their enclosing run does not.

Returns nil unless the result tiles `width` exactly with at least two legs, so a shape this cannot describe keeps today's behaviour rather than being given boundaries that are only probably right.

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 is nullable LONG, Java's primitiveType(LONG): Evaluate returns NULL for a record without a type key.

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 RelOpComparison

type RelOpComparison int

RelOpComparison is the Comparisons.Type of a RelOpValue.

type RelOpError

type RelOpError struct {
	// Complex is COMPARAND_TO_COMPARISON_IS_OF_COMPLEX_TYPE; otherwise
	// COMPARISON_OF_INCOMPATIBLE_TYPES.
	Complex bool
	Detail  string
}

RelOpError is the SemanticException RelOpValue.encapsulate raises.

func (*RelOpError) Error

func (e *RelOpError) Error() string

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 RequiredBindings

type RequiredBindings interface {
	WindowSources() []QuantifiedObjectValue
	ValidateAgainst(OrdinalLayout) (bool, error)
	// contains filtered or unexported methods
}

RequiredBindings is the immutable binding-origin manifest for one physical evaluation phase. WindowSources returns a defensive slice of immutable QOV views.

func CollectRequiredBindings

func CollectRequiredBindings(
	current QuantifiedObjectValue,
	roots []Value,
	edges []TypedEdgeDeclaration,
	externals []TypedExternalDeclaration,
) (result RequiredBindings, err error)

CollectRequiredBindings classifies every exact QOV root in one phase. The roots slice is the union of the phase result, conditions, properties and SARG values; callers must not collect each lane independently.

type ResolutionError

type ResolutionError struct {
	ErrorCode ResolutionErrorCode
	Path      string
	Detail    string
}

ResolutionError carries a stable code while retaining enough path context for a useful planning diagnostic. It never wraps a partially constructed value.

func (*ResolutionError) Code

func (*ResolutionError) Error

func (e *ResolutionError) Error() string

type ResolutionErrorCode

type ResolutionErrorCode uint16

ResolutionErrorCode is the stable machine-readable failure taxonomy for checked type, correlation, value, and ordinal construction.

const (
	TypeNil ResolutionErrorCode = iota + 1
	TypeTypedNil
	TypeCycle
	TypeUnresolved
	TypeErased
	TypeMalformedCode
	TypeMalformedOrdinal
	CorrelationZero
	CorrelationForeignValue
	CorrelationKindMismatch
	CorrelationTypeConflict
	FlowedTypeUnavailable
	FlowedTypeDisagreement
	FieldNilChild
	FieldUnsupportedChild
	FieldEmptyPath
	FieldInvalidRequest
	FieldNegativeOrdinal
	FieldOutOfRange
	FieldNonRecord
	FieldUnknownName
	FieldAmbiguousName
	FieldNameOrdinalMismatch
	FieldIncompatibleRoot
	LayoutForeignValue
	LayoutNonRecordCarrier
	LayoutInvalidTile
	LayoutTileGap
	LayoutTileOverlap
	LayoutInvalidPath
	LayoutInvalidWindow
	LayoutDuplicateSource
	LayoutTypeMismatch
	LayoutNullabilityMismatch
	LayoutCarrierMismatch
	LayoutSourceNotProvided
	LayoutPresenceMissing
	LayoutRuntimeShape
	LayoutNormalizationUnsupported
	LayoutNormalizationTypeMismatch
	ReanchorInvalidValue
	ReanchorTargetMismatch
	ReanchorUnmappedSource
	ReanchorInvalidMappedPath
	ReanchorResultTypeMismatch
	UnboundCorrelation
	AggregateInvalidFunction
	AggregateMissingOperand
	AggregateUnexpectedOperand
	AggregateUnsupportedOperand
	AggregateTypeMismatch
	AggregateLaneMismatch
	AggregateOutputNoMatch
	AggregateOutputAmbiguous
	RewriteNilReplacement
	RewriteValueCycle
	RewriteInvalidCallbackOutput
	RewriteInvalidArity
	RewriteNonComparableNode
	RewriteInvalidTranslation
	UnsupportedValueRebuild
	RuleDirectMutation
	MemoUnsupportedExpression
	MemoResultTypeMismatch
	MemoBatchConflict
	MemoMissingRelationWrapper
	MemoDoubleRelationWrapper
	MemoEmptyReference
	MemoInvalidHandle
	MemoProvisionalEscape
	MemoReferenceCycle
	MemoTransactionClosed
	MemoReentrantTransaction
)

type ResolvedAccessorView

type ResolvedAccessorView interface {
	Ordinal() int
	DisplayName() (string, bool)
	FieldType() Type
	// contains filtered or unexported methods
}

ResolvedAccessorView is one ordinal resolved against its enclosing exact record type. DisplayName is diagnostic metadata only.

type RowEvalContext

type RowEvalContext struct {
	// Positional is the authoritative ordinal-model row for the non-join
	// frontier — the SOLE runtime row. When non-nil, FieldValue resolution goes
	// through the ordinal path (the plan-time-baked ordinal, resolveOrdinal), a
	// loud OrdinalResolutionError on a miss, NO name resolution. 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
	// Objects is the exact-QOV binding authority for an admitted physical
	// evaluation layout. When present, QOV evaluation never falls through to
	// Positional or the alias-only legacy correlation binder.
	Objects          QuantifiedObjectBinder
	Binder           ParameterBinder
	Correlations     CorrelationBinder
	ScalarSubqueries map[CorrelationIdentifier]any // pre-evaluated scalar subquery results
	// Clock supplies the statement-stable CURRENT_TIMESTAMP-family instant
	// (StatementClock). Set from the executor's EvaluationContext so every
	// row of one statement observes the same time; nil falls back to
	// time.Now() per evaluation (the pre-statement-clock behavior).
	Clock StatementClock
}

RowEvalContext is a composite evaluation context for Value.Evaluate that carries the ordinal frontier row plus prepared-statement parameters (ParameterBinder), correlation bindings (CorrelationBinder), and pre-evaluated scalar subqueries. Pass this when evaluating expressions that mix field references, parameters, and correlation bindings (e.g. InJoin explode aliases).

func (*RowEvalContext) BindParameter

func (r *RowEvalContext) BindParameter(ordinal int, name string) (any, bool)

func (*RowEvalContext) DereferenceConstant

func (r *RowEvalContext) DereferenceConstant(alias CorrelationIdentifier, constantID string) (any, bool)

DereferenceConstant preserves constant pools through row-context adapters.

func (*RowEvalContext) GetCorrelationBinding

func (r *RowEvalContext) GetCorrelationBinding(id CorrelationIdentifier) (any, bool)

func (*RowEvalContext) StatementNow

func (r *RowEvalContext) StatementNow() time.Time

StatementNow implements StatementClock by delegating to the carried Clock; without one it degrades to the wall clock, which is the per-evaluation drift the statement clock exists to prevent — callers that need statement stability must set Clock.

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 EncapsulateRowNumber

func EncapsulateRowNumber(args CallSiteArguments) (*RowNumberValue, error)

EncapsulateRowNumber is RowNumberFn.encapsulate: a built-in function takes no named arguments and row_number no positional one; its options are resolved against EF_SEARCH and RETURN_VECTORS, and the window gives the partitioning and argument values.

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 is nullable LONG, Java's primitiveType(LONG): Evaluate returns NULL without a row number in its context.

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 ScalarFunctionArgumentDiagnosis

type ScalarFunctionArgumentDiagnosis int

ScalarFunctionArgumentDiagnosis is the outcome of Java's two-step argument admission for a function that declares a physical-operator map.

const (
	// ScalarFunctionArgumentsOK — the call is admissible.
	ScalarFunctionArgumentsOK ScalarFunctionArgumentDiagnosis = iota
	// ScalarFunctionArgumentsIncompatible — the argument types have no common
	// type. Java's SemanticException INCOMPATIBLE_TYPE; the caller raises
	// 22000.
	ScalarFunctionArgumentsIncompatible
	// ScalarFunctionArgumentsNoOperator — the arguments agree on a type, but
	// no physical operator implements the function for it. Java's
	// FUNCTION_UNDEFINED_FOR_GIVEN_ARGUMENT_TYPES; the caller raises 22F00.
	ScalarFunctionArgumentsNoOperator
)

func DiagnoseScalarFunctionArguments

func DiagnoseScalarFunctionArguments(name string, args []Value) ScalarFunctionArgumentDiagnosis

DiagnoseScalarFunctionArguments runs Java's argument admission for a function that declares an operator map, and reports WHICH of the two rejections applies — they carry different SQLSTATEs and the corpus asserts both, so collapsing them into one "bad arguments" answer would be wrong half the time.

Java (VariadicFunctionValue.encapsulate, :190-212):

  1. fold the argument types with Type.maximumType; a null fold is INCOMPATIBLE_TYPE → 22000.
  2. look up a PhysicalOperator for the folded type; a miss is FUNCTION_UNDEFINED_FOR_GIVEN_ARGUMENT_TYPES → 22F00.

Both steps are decided here rather than deferring step 1 to the existing runtime path, because Go's CommonValueType is MORE PERMISSIVE than Java's maximumType: it folds (BYTES, STRING) to BYTES, so `greatest(bytes_col, 'a')` would otherwise plan and return a value where Java rejects the query outright. Folding with maximumTypeCode here is what makes the rejection happen at all.

This does not touch CommonValueType itself, which serves COALESCE, IFNULL and IF as well; those follow Java's own (different) admission and are not in this function's scope.

type ScalarFunctionValue

type ScalarFunctionValue struct {
	FuncName string
	Args     []Value
	Typ      Type
}

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 registered in scalarFunctionCatalog (string, math, date-part, bit, and null/comparison helpers). The same definition selects evaluator dispatch, result typing, and Cascades admission.

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 result Type. Nullability follows Java's VariadicFunctionValue for the three functions Java has (:339-376): COALESCE is nullable only when every argument is, GREATEST and LEAST when any is. Every Go-only function is nullable, since several return NULL on non-NULL input.

type ScalarSubqueryValue

type ScalarSubqueryValue struct {
	Alias CorrelationIdentifier
	// Typ is the inner plan's single output column type, threaded from
	// SubqueryPlanner.BuildScalar so the plan-time gates (comparison
	// promotion, cast pairs) see the real type — an Unknown-typed scalar
	// subquery evaded every gate a direct column reference hits. nil
	// (underivable inner shape) reports UnknownType, the pre-threading
	// behavior.
	Typ Type
}

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, typ Type) *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 — correct-or-loud:

  • *RowEvalContext with the alias PRESENT: the bound result (nil = the subquery legitimately yielded zero rows → SQL NULL).
  • *RowEvalContext with the alias ABSENT, or ANY other non-nil context (a raw datum map, a bare scalar row): loud *UnboundScalarSubqueryError. A context that cannot carry the binding is unanswerable at row time — silently answering NULL made every comparison against it UNKNOWN and vanished rows with no signal (the executor's no-bindings filter paths pass the raw Datum map as the row context, so the map arm is a REAL runtime read, not a plan-time probe).
  • nil: plan-time speculative probe (Comparison.Eval's documented constant-RHS contract; rule fold probes) — stays a non-committal nil. No binding can exist before execution, and subquery values are correlated (GetCorrelatedTo) so compile-time comparison classification defers them anyway.

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 (v *ScalarSubqueryValue) Type() Type

type ScalarTypeMismatchError

type ScalarTypeMismatchError struct {
	Message string
}

ScalarTypeMismatchError is a GREATEST/LEAST argument or field assignment of the wrong type (Java's SemanticException INCOMPATIBLE_TYPE); SQL reports it as 22000.

func (*ScalarTypeMismatchError) Error

func (e *ScalarTypeMismatchError) Error() string

type SealedTypeRepositoryError

type SealedTypeRepositoryError struct{ TypeName string }

SealedTypeRepositoryError reports an attempt to extend a published graph. A new type requires a new repository, never mutation of descriptors in use.

func (*SealedTypeRepositoryError) Error

func (e *SealedTypeRepositoryError) Error() string

type SeedWindowReadClass

type SeedWindowReadClass int

SeedWindowReadClass is one read's bucket. The four partition every read.

const (
	SeedWindowHit SeedWindowReadClass = iota
	SeedWindowMiss
	SeedWindowQualifiedNoIdentity
	SeedWindowChildlessBaked
	SeedWindowNestedHit
	SeedWindowReadClassCount
)

type SeedWindowSite

type SeedWindowSite int

SeedWindowSite is one keyed reader of a seed-window map. These are ALL of them in production. The map's remaining call sites consume it as a nil/non-nil PREDICATE ("is this an ordinal seed?") and never key it, which is not a read and is not counted here.

const (
	SeedWindowSiteExistentialRebase SeedWindowSite = iota
	SeedWindowSiteBoxLegRef
	SeedWindowSiteBoxSurvivorQOV
	SeedWindowSiteBoxSurvivorCorrelation
	SeedWindowSiteGatheredGroupSlot
	SeedWindowSiteCount
)

type SelectResultMintSite

type SelectResultMintSite int

SelectResultMintSite names one non-test select-result-value construction.

The identity is the SITE, not the file position: line numbers on this path have already invalidated several written-down attributions of this population.

const (
	SelectResultMintExistsSelect SelectResultMintSite = iota
	SelectResultMintSiteCount
)

type SelfEqualsWithoutChildren

type SelfEqualsWithoutChildren interface {
	EqualsWithoutChildrenValue(other Value) bool
}

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

type SelfWithChildren interface {
	WithChildrenValue(newChildren []Value) Value
}

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 SerializationContext

type SerializationContext struct {
	// contains filtered or unexported fields
}

SerializationContext is Java's PlanSerializationContext for types: a record type is written in full once and by reference id afterwards, record types being the same when their names and structure are (RecordTypeWithNameEquivalence).

func NewSerializationContext

func NewSerializationContext() *SerializationContext

func (*SerializationContext) TypeFromProto

func (c *SerializationContext) TypeFromProto(p *gen.PType) (Type, error)

TypeFromProto is Java's Type.fromTypeProto.

func (*SerializationContext) TypeToProto

func (c *SerializationContext) TypeToProto(t Type) (*gen.PType, error)

TypeToProto is Java's Type.toTypeProto.

func (*SerializationContext) ValueFromProto

func (c *SerializationContext) ValueFromProto(p *gen.PValue) (Value, error)

ValueFromProto is Java's Value.fromValueProto for the same values.

func (*SerializationContext) ValueToProto

func (c *SerializationContext) ValueToProto(v Value) (*gen.PValue, error)

ValueToProto is Java's Value.toValueProto for the values a SQL macro body is built from.

type SlotAssignmentError

type SlotAssignmentError struct {
	// Null marks a NULL written to a NOT NULL slot.
	Null bool
	From Type
	To   Type
}

SlotAssignmentError reports a value a narrowed slot cannot hold.

func (*SlotAssignmentError) Error

func (e *SlotAssignmentError) Error() string

type StatementClock

type StatementClock interface {
	StatementNow() time.Time
}

StatementClock is the optional evalCtx capability supplying the statement-stable timestamp: SQL fixes CURRENT_TIMESTAMP / CURRENT_DATE / CURRENT_TIME per STATEMENT, so every reference inside one statement must observe the same instant. Evaluation contexts that carry a statement time (the executor's EvaluationContext, the INSERT-VALUES fold) implement this; without it the arms fall back to time.Now().

type StreamingValue

type StreamingValue interface {
	Value
	EvaluateAsStream(evalCtx any) []any
}

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 TautologicalValue

type TautologicalValue struct{}

TautologicalValue is the relational layer's TautologicalValue: the always-true implication a CASE's ELSE selects with.

func (TautologicalValue) Children

func (TautologicalValue) Children() []Value

func (TautologicalValue) EqualsWithoutChildrenValue

func (TautologicalValue) EqualsWithoutChildrenValue(other Value) bool

func (TautologicalValue) Evaluate

func (TautologicalValue) Evaluate(any) (any, error)

func (TautologicalValue) Name

func (TautologicalValue) Name() string

func (TautologicalValue) SemanticHashDiscriminator

func (TautologicalValue) SemanticHashDiscriminator() uint64

func (TautologicalValue) Type

func (TautologicalValue) Type() Type

func (TautologicalValue) WithChildrenValue

func (v TautologicalValue) WithChildrenValue([]Value) Value

type TemporalTextError

type TemporalTextError struct {
	Text        string
	OutOfDomain bool
}

TemporalTextError is a text that is not the text of a DATE or TIMESTAMP value. OutOfDomain marks a text that parses but whose UTC year is outside 0000-9999.

func (*TemporalTextError) Error

func (e *TemporalTextError) Error() string

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.

func (*ThrowsValue) Evaluate

func (*ThrowsValue) Evaluate(any) (any, error)

Evaluate panics — ThrowsValue marks an unreachable branch. Loud panic message ensures planner bugs that route data through the dead branch surface immediately.

func (*ThrowsValue) Name

func (*ThrowsValue) Name() string

Name returns the debug-print kind.

func (*ThrowsValue) Type

func (v *ThrowsValue) Type() Type

Type returns the bound result type.

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.

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 (v *ToOrderedBytesValue) Evaluate(evalCtx any) (any, error)

Evaluate packs the child as a one-element tuple in the direction (TupleOrdering.pack(Key.Evaluated.scalar(child).toTuple(), direction)). The row domain widens FLOAT to float64, so a FLOAT child is narrowed back to the float32 element Java packs, or the bytes would not match the index.

func (*ToOrderedBytesValue) Name

func (*ToOrderedBytesValue) Name() string

Name returns the SQL function name.

func (*ToOrderedBytesValue) Type

func (*ToOrderedBytesValue) Type() Type

Type is nullable BYTES, Java's primitiveType(BYTES), though the encoder produces bytes for every 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

Build snapshots the accumulated entries — the returned map is IMMUTABLE (Java's ImmutableMap.copyOf): further builder use cannot mutate a map already handed out (sharing b.fns let a built empty map stop defining only identities when the builder was reused).

func (*TranslationMapBuilder) When

type TranslationMapWhen

type TranslationMapWhen struct {
	// contains filtered or unexported fields
}

TranslationMapWhen is the intermediate of the .When(alias).Then(fn) pair.

func (*TranslationMapWhen) Then

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`, numbered as its proto (PTupleSource), so the zero value is no source.

const (
	// TupleSourceKey selects the index entry's KEY tuple.
	TupleSourceKey TupleSource = iota + 1
	// TupleSourceValue selects the index entry's VALUE tuple.
	TupleSourceValue
	// TupleSourceOther reads the VALUE tuple, as every non-KEY source does
	// in Java's IndexEntryObjectValue.eval.
	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
	// 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
)

The legacy `ValueType` enum (TypeUnknown / TypeInt / TypeString / TypeBool / TypeFloat) is retired — every Value impl's Type() returns the rich Type directly. Only the members whose NAME MATCHES THEIR VALUE remain as bridge vars; TypeString is NullableString and TypeBool is NullableBoolean, so neither can mislead.

TypeInt and TypeFloat are gone. Both named one type and were another — TypeInt was NullableLong, TypeFloat was NullableDouble — and between them they produced eight tests that read as coverage for the type in their name while asserting the other one's behaviour, plus a live wrong-rows bug where the walker routed `CAST(x AS FLOAT)` through the DOUBLE-coded alias so the cast never rounded to binary32. Every use of both meant the wider type and now says so. Name the type you mean: NullableInt / NullableLong / NullableFloat / NullableDouble.

Legacy bridge retirement: RFC-025.

func CommonValueType

func CommonValueType(branches []Value) Type

CommonValueType computes the common supertype of value branches and makes it nullable. Literal NULL branches carry no constraint; a non-NULL branch with unknown type keeps the result unknown.

func ExplodeOrdinalityResultType

func ExplodeOrdinalityResultType(elementType Type) Type

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 ExplodeOrdinalityResultTypeNamed

func ExplodeOrdinalityResultTypeNamed(elementType Type, elementName, ordinalName string) Type

ExplodeOrdinalityResultTypeNamed is ExplodeOrdinalityResultType with its two slots named: a SQL `AS e AT o` unnest names them after its aliases, so the quantifier over the Explode flows exactly the row its references read.

func FieldTypeForProtoField

func FieldTypeForProtoField(fd protoreflect.FieldDescriptor) Type

FieldTypeForProtoField maps a proto field descriptor to the logical column Type the engine gives that field's slot. It is THE single authority for "what type is this stored column", and every layout describing a stored record's row must derive its field types from it.

Having exactly one of these is the point, not a tidiness preference. The layout is derived independently on two paths — the plain full-scan leaf (cascades_translator's tableColumns) and the sargable match candidate (executor.PositionalTypeForDescriptor) — and those two paths feed the SAME planner decisions about the same table. When one of them typed its fields and the other stamped UnknownType on all of them, a type-directed rule silently reached opposite conclusions depending on which access path was under consideration: the ordering-claim predicate could prove a column was a DOUBLE on the scan leaf and could not prove it on the index candidate, so a predicated query kept the unsound sort elision that the unpredicated form of the same query had already lost. A second copy of this switch is the same bug waiting to be reintroduced.

Conventions, all deliberate:

  • Nullability is Java's (Type.Record.Field.fromDescriptor): a field that is not an array is nullable unless it is REQUIRED, a proto3 scalar without explicit presence included (its default reads as absent, protoFieldNullable); a flat repeated field is a NOT NULL array of NOT NULL elements.
  • Repeated fields are exact ARRAYs. ProtoFieldToRowValue materializes them as []any, so returning the element scalar (the old bug) or Unknown (the old workaround) both misdescribe the executable slot.
  • Proto maps remain UnknownType: ProtoFieldToRowValue intentionally keeps their native protoreflect.Map carrier and the Type algebra has no map kind. An executable exact-type boundary therefore rejects map-bearing rows instead of laundering them as a record or array.
  • The tuple_fields.UUID wrapper message is UUID — it materializes as a neutral [16]byte, not as a raw message (see protoScalarToRowValue). Any OTHER message field is UnknownType: its slot stays a raw proto.Message, and a recursive message has no finite structural type.
  • Known message descriptors become structural RECORDs. Cyclic back-edges become exact AnyRecord leaves: the carrier is still a record, but a finite FieldValue path may not descend through the erased recursive edge. UUID keeps its dedicated scalar representation.
  • Enums keep their descriptor identity when it is representable by the Type algebra. Aliased enums and unsigned integers use LONG, matching the int64 carrier emitted by ProtoScalarKindToRowValue.

func MaximumType

func MaximumType(t1, t2 Type) Type

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 (Java Type.java:596-602 — the maximum of NONE and a promotable other side is simply the other side).

ARRAY × ARRAY and RECORD × RECORD recurse structurally into their element / field types; ENUM and RELATION have their own arms below.

Mirrors Java's `Type.maximumType(t1, t2)`.

func MaximumTypeOfMany

func MaximumTypeOfMany(types ...Type) Type

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 NewAnyRecordType

func NewAnyRecordType(nullable bool) Type

NewAnyRecordType constructs an exact erased RECORD type. Unlike AnyType and UnknownType, AnyRecord has a fully decided identity (RECORD plus nullability), so exact type snapshots and QOV boundaries can safely admit it. Its erased field layout still cannot be used to resolve a FieldValue.

func PhysicalCarrierType

func PhysicalCarrierType(layout OrdinalLayout) Type

PhysicalCarrierType is the row an OrdinalLayout's carrier describes, WITH its leg boundaries — the type to use whenever the PHYSICAL row is what is being carried, which is every use of a layout's carrier.

It replaces the `layout.Carrier().FlowedType()` idiom. That spelling reaches through a physical object for the SEMANTIC type, which withholds boundaries on purpose, and the loss is invisible at the call site: the type is the right width with the right fields, and only a later qualified read discovers that the row no longer says which source owns which slots. Since NewQuantifiedObjectValue snapshots its layout from the type it is handed, the idiom silently launders layout out of every value re-minted through it.

Comparisons are unaffected — exact-type identity and RecordType.Equals both ignore .Legs — so this is safe wherever the old spelling was used to compare as well as where it was used to re-mint.

func ScalarFunctionDeclaredResultType

func ScalarFunctionDeclaredResultType(name string) (Type, bool)

ScalarFunctionDeclaredResultType returns the catalogued base result type for any route, including dedicated BIT* and CURRENT_* grammar forms. Generic polymorphic calls return TypeUnknown here and use ScalarFunctionResultType with their arguments for concrete inference.

func ScalarFunctionResultType

func ScalarFunctionResultType(name string, args []Value) (Type, bool)

ScalarFunctionResultType resolves the result type for a name admitted by the generic ScalarFunctionCall grammar route. Dedicated BIT* and CURRENT_* routes are intentionally excluded even though their definitions live in the same catalog.

func ScalarTypeForProtoKind

func ScalarTypeForProtoKind(fd protoreflect.FieldDescriptor) Type

ScalarTypeForProtoKind is FieldTypeForProtoField's kind switch with repetition ignored: it answers "what type does ONE value of this field descriptor have", so applied to a repeated field it states the ELEMENT type rather than UnknownType.

The seam exists because a caller that has already accounted for repetition — one typing an array's element, where the repeatedness belongs to the enclosing array type — must not have the collapse applied a second time. Every convention listed on FieldTypeForProtoField except the repeated/map collapse applies here unchanged, and both functions remain the same single copy of the mapping: FieldTypeForProtoField is this switch plus the collapse, never a parallel transcription of it.

func SharedExactType

func SharedExactType(handle ExactTypeHandle) Type

SharedExactType is SharedFlowedType for a bare exact handle: the thawed graph WITHOUT the defensive copy, for readers that only ask it a question. Same read-only contract, same reason — see SharedFlowedType.

func SharedFlowedType

func SharedFlowedType(value QuantifiedObjectValue) Type

SharedFlowedType is FlowedType WITHOUT the defensive copy, for readers that only ask the graph a question and never retain or mutate it.

THE DEFENSIVE COPY IS DELIBERATE AND PINNED (a getter that leaks a mutable graph lets a caller rename the carrier's own fields under it), so it stays the default and this is the deliberate opt-out — named so a reader has to mean it. The opt-out exists because the executor asks the same question once per ROW: does this row's shape equal the carrier's. Answering it by rebuilding the whole graph made a 20k-row scan allocate ~4M objects reconstructing a value that is a pure function of an immutable handle.

Callers must treat the result as READ-ONLY. Use FlowedType anywhere the graph is stored, handed onward, or modified.

func WithNullability

func WithNullability(t Type, nullable bool) Type

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.

func WithRecordTypeLegs

func WithRecordTypeLegs(typ Type, legs []RecordTypeLeg) Type

WithRecordTypeLegs returns typ carrying legs, copy-on-write, or typ unchanged when there is nothing to attach or typ is not a record.

It is the "adopt the boundaries another producer already stated" half of the member-agreement scan: WithSeedTilingLegs derives a table from a seed VALUE, this one carries an already-derived table across to a row that states none. Legs are not part of exact-type identity (RecordType.Equals ignores them), so this adds physical information without moving any interning key, memo dedup or plan equality.

func WithSeedTilingLegs

func WithSeedTilingLegs(typ Type, rv Value) Type

WithSeedTilingLegs returns typ carrying the boundaries rv states, or typ unchanged when it already has them or the seed cannot state them exactly.

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
	TypeCodeVector
)

func JavaAggregateResultCode

func JavaAggregateResultCode(fn string, operandCode TypeCode) (TypeCode, bool)

JavaAggregateResultCode is THE Java aggregate result-type table at the TypeCode level (NumericAggregationValue / CountValue, tag 4.12.11.0): COUNT and COUNT(*) return LONG regardless of operand; AVG returns DOUBLE for every numeric operand; SUM/MIN/MAX return the OPERAND's code — and Java defines those operators ONLY over INT/LONG/FLOAT/ DOUBLE (SUM_I/L/F/D, MIN_*, MAX_*), so any other operand code has no row (ok=false). Consumers document their own nullability choice at the call site.

func ScalarCodeForProtoKind

func ScalarCodeForProtoKind(fd protoreflect.FieldDescriptor) (TypeCode, bool)

ScalarCodeForProtoKind is the ALLOCATION-FREE half of the scalar mapping: the TypeCode a descriptor's kind carries, without building the Type that names it. ok=false for a kind with no scalar answer (a record, or one this engine does not map), which the caller must then handle structurally.

It exists because two callers want different halves of one decision, and splitting the decision is the only way to keep it a single authority. ScalarTypeForProtoKind needs the Type. The exact-type compatibility check needs only the code, and it runs per FIELD READ per ROW — building a Type there (and, for an enum, its value slice and number set) allocated O(rows × accesses × width) of garbage to answer a question about an int.

The enum arm is the reason this is not a plain switch on Kind: a number-ALIASING enum maps to LONG rather than to an enum type, and that is only knowable by scanning the descriptor's values. The scan allocates nothing, unlike constructing the EnumType it is deciding against.

func (TypeCode) IsNumeric

func (tc TypeCode) IsNumeric() bool

IsNumeric reports whether tc is one of the numeric types (arithmetic + comparison promotion targets).

func (TypeCode) IsPrimitive

func (tc TypeCode) IsPrimitive() bool

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.

func (TypeCode) String

func (tc TypeCode) String() string

String renders the code as the SQL-ish type name ("INT", "STRING", "BOOLEAN", …). Used by EXPLAIN output and error messages so the rendered surface matches Java's TypeCode.name() output.

type TypeProtoRepository

type TypeProtoRepository struct {
	// contains filtered or unexported fields
}

TypeProtoRepository collects computed types and publishes their descriptor graph. RegisterType validates each complete closure transactionally. Seal compiles the final graph before any plan binds descriptors; subsequent registration cannot replace it. Incremental MessageDescriptorFor callers remain supported, but only the sealed publication path guarantees identity across registrations.

func NewTypeProtoRepository

func NewTypeProtoRepository() *TypeProtoRepository

NewTypeProtoRepository returns an empty repository.

func (*TypeProtoRepository) FileDescriptorProtoForTest

func (p *TypeProtoRepository) FileDescriptorProtoForTest() *descriptorpb.FileDescriptorProto

FileDescriptorProtoForTest exposes the accumulated file in its RELATIVE, pre-compilation form. It exists so the descriptor SHAPE — labels, field numbers, the presence of type vs type_name, the wrapper's structure — can be asserted directly rather than inferred from a round-trip, which is where a shape divergence from Java would hide.

func (*TypeProtoRepository) MessageDescriptorFor

func (p *TypeProtoRepository) MessageDescriptorFor(t Type) (protoreflect.MessageDescriptor, error)

MessageDescriptorFor returns the synthetic descriptor for t, defining it on first use and serving it from the cache afterwards.

func (*TypeProtoRepository) RegisterType

func (p *TypeProtoRepository) RegisterType(t Type) error

RegisterType validates a complete type closure without publishing descriptors. Failed roots leave neither names nor partial definitions behind.

func (*TypeProtoRepository) Seal

func (p *TypeProtoRepository) Seal() error

Seal publishes one immutable descriptor graph. Lookups are safe concurrently; callers must register every type before handing any descriptor to a plan.

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) MessageDescriptorFor

func (r *TypeRepository) MessageDescriptorFor(t Type) (protoreflect.MessageDescriptor, error)

MessageDescriptorFor returns the synthetic protobuf message descriptor for t, defining it (and its whole type closure) on first use. Java: TypeRepository.newMessageBuilder(Type) → getProtoTypeName → the descriptor (TypeRepository.java:160-176).

Only a type with a MESSAGE form has one: a RECORD, or an array whose nullable-wrapper is a message. Anything else is a *ProtoTypeError.

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 TypedEdgeBinding

type TypedEdgeBinding interface {
	Declaration() TypedEdgeDeclaration
	// contains filtered or unexported methods
}

TypedEdgeBinding combines an admitted edge declaration with the whole runtime object carried by that edge. Present SQL NULL is represented by a nil object and is legal only for a nullable QOV.

func BindTypedEdge

func BindTypedEdge(declaration TypedEdgeDeclaration, wholeObject any) (TypedEdgeBinding, error)

BindTypedEdge validates a runtime whole-object binding without exposing it through the planning-time declaration view.

type TypedEdgeDeclaration

type TypedEdgeDeclaration interface {
	QOV() QuantifiedObjectValue
	// contains filtered or unexported methods
}

TypedEdgeDeclaration is the immutable planning-time declaration of one complete object flowing over a quantifier edge.

func NewTypedEdgeDeclaration

func NewTypedEdgeDeclaration(qov QuantifiedObjectValue) (TypedEdgeDeclaration, error)

NewTypedEdgeDeclaration snapshots one exact non-current edge QOV.

type TypedExternalDeclaration

type TypedExternalDeclaration interface {
	QOV() QuantifiedObjectValue
	// contains filtered or unexported methods
}

TypedExternalDeclaration declares one exact correlation delegated to the surrounding evaluation context.

func NewTypedExternalDeclaration

func NewTypedExternalDeclaration(qov QuantifiedObjectValue) (TypedExternalDeclaration, error)

NewTypedExternalDeclaration snapshots one exact non-current external QOV.

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

func NewUdfValue(name string, resultType Type, args []Value, call func(args []any) any) *UdfValue

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

func (u *UdfValue) Children() []Value

Children returns the Args list — UDF arguments are the only Value children.

func (*UdfValue) Evaluate

func (u *UdfValue) Evaluate(evalCtx any) (any, error)

Evaluate walks each arg's Evaluate and hands the resulting `[]any` to Call. Returns nil if Call is nil (placeholder mode).

func (*UdfValue) Name

func (u *UdfValue) Name() string

Name returns the UDF function name (used for debug print + planner equivalence keying).

func (*UdfValue) Type

func (u *UdfValue) Type() Type

Type returns the declared return type.

func (*UdfValue) WithChildren

func (u *UdfValue) WithChildren(newChildren []Value) *UdfValue

WithChildren returns a new UdfValue with the given children substituted for Args. Function name, result type, and Call body carry through unchanged.

type UnaryRelOpValue

type UnaryRelOpValue struct {
	FunctionName string
	Comparison   RelOpComparison
	Child        Value
	// contains filtered or unexported fields
}

UnaryRelOpValue is Java's RelOpValue.UnaryRelOpValue: IS [NOT] NULL as a boolean value.

func NewUnaryRelOpValue

func NewUnaryRelOpValue(comparison RelOpComparison, child Value) (*UnaryRelOpValue, error)

NewUnaryRelOpValue is RelOpValue.encapsulate for one argument (RelOpValue.java:328-339).

func (*UnaryRelOpValue) Children

func (v *UnaryRelOpValue) Children() []Value

func (*UnaryRelOpValue) EqualsWithoutChildrenValue

func (v *UnaryRelOpValue) EqualsWithoutChildrenValue(other Value) bool

func (*UnaryRelOpValue) Evaluate

func (v *UnaryRelOpValue) Evaluate(evalCtx any) (any, error)

Evaluate is UnaryPhysicalOperator.eval: Objects.isNull / Objects.nonNull.

func (*UnaryRelOpValue) Name

func (v *UnaryRelOpValue) Name() string

func (*UnaryRelOpValue) PhysicalOperator

PhysicalOperator is the operator's proto enum.

func (*UnaryRelOpValue) SemanticHashDiscriminator

func (v *UnaryRelOpValue) SemanticHashDiscriminator() uint64

func (*UnaryRelOpValue) Type

func (*UnaryRelOpValue) Type() Type

Type is BooleanValue.getResultType: nullable BOOLEAN.

func (*UnaryRelOpValue) WithChildrenValue

func (v *UnaryRelOpValue) WithChildrenValue(newChildren []Value) Value

type UnboundConstantError

type UnboundConstantError struct {
	Alias          CorrelationIdentifier
	ConstantID     string
	NullForNotNull bool
}

UnboundConstantError reports a constant reference evaluated without its pool entry; returning NULL instead would silently change query results.

func (*UnboundConstantError) Error

func (e *UnboundConstantError) Error() string

type UnboundEvalContextError

type UnboundEvalContextError struct {
	Field       string
	Correlation string
	CtxType     string
}

UnboundEvalContextError reports a FieldValue whose evaluation resolved to NOTHING: an UNRECOGNIZED non-nil context type, or a correlated reference whose correlation is UNBOUND and whose context supplies no frontier positional row. Production flows only OrdinalRow / *RowEvalContext / CorrelationBinder / nil, so reaching one of these tails is a planner/executor bug — LOUD for pinned and unpinned alike; a silent NULL would hide it. DISTINCT from BakedNameContextError (a PINNED node meeting a name-keyed context that DID resolve to a value): here nothing resolved at all. A nil context stays NULL (the appendNullLeg / nil-binding path) and never reaches here; a correlation that DID match a non-ordinal value (e.g. the executor's buildLegBinder raw leg) returns that value and never reaches here either.

func (*UnboundEvalContextError) Error

func (e *UnboundEvalContextError) Error() string

type UnboundScalarSubqueryError

type UnboundScalarSubqueryError struct {
	Alias CorrelationIdentifier
}

UnboundScalarSubqueryError reports a runtime evaluation of a ScalarSubqueryValue whose result was never bound in the evaluation context — an orchestration bug in the caller (the plan's scalar subqueries must be pre-evaluated and bound via EvaluationContext.WithScalarSubqueries before execution). Distinct from a subquery that legitimately returned zero rows: that binds a PRESENT nil (SQL NULL). Before this error existed, an absent binding silently evaluated to NULL and comparisons against it vanished rows with no signal.

func (*UnboundScalarSubqueryError) Error

type UndeclaredStructFieldError

type UndeclaredStructFieldError struct {
	Struct string
	Extra  int
	Total  int
}

UndeclaredStructFieldError reports a record constructor carrying a name the target struct does not declare.

func (*UndeclaredStructFieldError) Error

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 (*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) Type

func (*UnmatchedAggregateValue) Type() Type

type UnnestLegMintArm

type UnnestLegMintArm int

UnnestLegMintArm is WHICH arm a seed-tested branch point took.

It exists because a per-site call count of ZERO at a `!seedWindowed` else-branch is AMBIGUOUS on its own, and the ambiguity has opposite consequences. "Never reached" says the shape is not planned; "reached, took the ordinal arm" says the shape IS planned and its conversion has already happened on the other side of the branch. Both readings support demoting a conversion booked against the name arm, and they imply different follow-ups — so the census must not leave the reader to pick one.

The arm is recorded AT the arm, and the branch's REACH is recorded INDEPENDENTLY at the branch point, before any arm is chosen. Both halves are necessary and the second one was missing when this census first shipped: the renderer computed the branch total AS the sum of the arms, so an arm added without a `CensusHooks.UnnestLegMintArm` call would silently SHRINK the printed `reached N` instead of showing up as a gap. That is the summed denominator this RFC's own text calls "true by construction", one field over from the twin counter that was given a real one.

It bites hardest at the joinPredicate branch, where the census guard doubles as the third arm (`else if jpCensus`): inserting an `else if` ahead of it steals silently from `leg-relative`. With an independent reach counter that theft is an ARM PARTITION FAIL, not a quieter number.

const (
	UnnestLegMintArmName UnnestLegMintArm = iota
	UnnestLegMintArmOrdinalTwin
	UnnestLegMintArmPlanTimeBake
	UnnestLegMintArmLegRelative
	UnnestLegMintArmCount
)

type UnnestLegMintSite

type UnnestLegMintSite int

UnnestLegMintSite is one call site of the name-keyed `rebaseUnnestOuterLegPredicate`. The five partition its callers, and they are named for WHY they reach it rather than for their line numbers, which move.

const (
	UnnestLegMintSiteNonChainedMerge UnnestLegMintSite = iota
	UnnestLegMintSiteAnchoredNonExists
	UnnestLegMintSiteBuriedNotWindowed
	UnnestLegMintSiteJoinPredNotWindowed
	UnnestLegMintSiteChainedNameModel
	UnnestLegMintSiteCount
)

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

func DeconstructRecord(v Value) ([]Value, error)

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 EvaluateConstantComparand

func EvaluateConstantComparand(v Value) Value

EvaluateConstantComparand is SimplifyPredicateValue that also EVALUATES every composite whose children are constant (arithmetic, CAST, PROMOTE, scalar functions, CASE) into a literal of its type. It is Java's `comparison.getComparand(null, null)` where a comparison is converted to a stored form -- the sparse-index predicate's IndexComparison (IndexComparison.java:166) -- and is NOT a simplification: no query plan evaluates a constant at plan time.

func InjectPromotion

func InjectPromotion(v Value, target Type) Value

InjectPromotion is Java's PromoteValue.inject (PromoteValue.java:441-451): v unchanged when it already has the type; retyped when it can result in it (canResultInType: an untyped NULL or a CAST, to a nullable target); otherwise a PromoteValue. A non-NULL literal is promoted, never retyped (LiteralValue.canResultInType holds only for a nullable literal type).

func LiteralValue

func LiteralValue(lit any) Value

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 PinValueToExactFrontier

func PinValueToExactFrontier(value Value, carrier QuantifiedObjectValue) (Value, error)

PinValueToExactFrontier marks every admitted field path rooted at carrier as a machinery-owned read of that exact physical frontier. The pointer check is the authority: another current QOV with the same record shape represents a different producer phase and is left unchanged, as are named outer/source correlations.

A materializing plan uses this after it has checked-reanchored an evaluation program onto its selected child's output carrier. The pin tells the runtime evaluator to read the already-materialized flat row directly rather than routing the unpinned path through retained join-leg windows. It is excluded from Value equality/hash/explain, so this changes only the evaluation contract, not memo identity.

func PrimitiveAccessorsForType

func PrimitiveAccessorsForType(typ Type, base func() Value) ([]Value, error)

PrimitiveAccessorsForType ports Values.primitiveAccessorsForType (Values.java:99-121): recurse a RECORD type into accessors for its primitive leaf elements, in declared field order. For the flowed record ((a, b) as x, c as y) with primitive a, b, c it returns {_.x.a, _.x.b, _.y}. A non-record type yields the base value itself — Java asserts isPrimitive()||isEnum() there and throws ORDERING_IS_OF_INCOMPATIBLE_TYPE otherwise; Go rejects the two codes with no leaf decomposition (ARRAY, RELATION) and otherwise admits, including UNKNOWN: an untyped key (a bound parameter, an internal expression) is not evidence of an unorderable one, the same leniency sortKeysAreOrderable applies on the ORDER BY path.

This flattening is what makes GROUP BY <struct> answerable: the grouping path expresses its pre-aggregate ordering requirement over these primitive leaves (ImplementStreamingAggregationRule.java:111, GroupByExpression.java:434, PushRequestedOrderingThroughGroupByRule.java:141), so no comparator ever orders whole record values.

base is a supplier, exactly like Java's baseValueSupplier: each leaf accessor chain is built over a fresh base invocation. Go Values are immutable and structurally shared, so suppliers returning the same node are fine.

func PullUpValue

func PullUpValue(v Value, resultValue Value, alias CorrelationIdentifier) (Value, error)

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(QOV(alias), "a") // input field "x" becomes output field "a"
  • v = FV("y") → FV(QOV(alias), "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(QOV(alias), "x")

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 ReanchorOwnedValueForLayout

func ReanchorOwnedValueForLayout(
	value Value,
	target QuantifiedObjectValue,
	layout OrdinalLayout,
	owned map[CorrelationIdentifier]struct{},
) (Value, error)

ReanchorOwnedValueForLayout is ReanchorValueForLayout for a Value that may also read outer correlations: a root the layout does not window crosses onto the carrier only when owned lists it. Every other root, including a same-typed outer leg, is preserved for the evaluation context to bind.

func ReanchorOwnedValueThroughProducer

func ReanchorOwnedValueThroughProducer(
	value Value,
	producer Value,
	target QuantifiedObjectValue,
	owned map[CorrelationIdentifier]struct{},
) (Value, error)

ReanchorOwnedValueThroughProducer rewrites fields supplied by a record-producing Value onto that producer's exact output carrier. This is the checked lineage bridge used before a materializer discards its input layout's source windows, and it is the ONLY exported way in: an ownership set is mandatory, because the bridge's name fallback is a false-accept machine without one.

Only roots listed in owned may be claimed by producer. A foreign or outer root comes back BYTE-FOR-BYTE UNCHANGED even when a one-slot producer exposes the same accessor name and leaf type, and an unresolved root then fails loudly downstream instead of silently reading a neighbouring column. Three wrong-answer bugs came out of the name-only path — A.VAL and B.VAL both reading A's slot, an EXISTS answering on another leg's ID, a sort key read under an aliased column's label — so the caller must state what the producer owns rather than let the match decide.

Within the owned set a field is selected by its complete accessor-name path and exact result type: a matching source correlation wins when duplicate column names exist, and absent that ownership proof exactly one matching producer slot is required. The producer's output ordinal — not a copied input ordinal — is the address installed on target.

func ReanchorValueForLayout

func ReanchorValueForLayout(
	value Value,
	target QuantifiedObjectValue,
	layout OrdinalLayout,
) (Value, error)

ReanchorValueForLayout rewrites every source-relative FieldValue that the layout can address onto the layout's exact current carrier. It also moves a bare reserved-current QOV onto that carrier. The rewrite is copy-on-write and atomic: an invalid mapped path or exact-type disagreement returns no partial Value.

A non-current source absent from layout is preserved. Such a root may be a declared physical edge or an outer correlation supplied by the evaluation context; the owning plan validates those bindings. A source that layout does provide is never left relative, which is load-bearing at materialization boundaries where source windows are intentionally discarded after the row is built.

func RebaseValueChecked

func RebaseValueChecked(v Value, aliases AliasMap) (Value, error)

RebaseValueChecked performs the alias-only rebase through the same checked reconstruction authority used by TranslationMap. It preserves exact QOV types, rejects current-kind changes through the validated AliasMap, and returns no original/partial tree when an enclosing FieldValue cannot be rebuilt.

func RebuildFieldValue

func RebuildFieldValue(field FieldValue, child Value) (Value, error)

RebuildFieldValue retains an admitted FieldValue's resolved path on the same exact root type, otherwise re-resolving it and refusing type/nullability drift.

func Replace

func Replace(v Value, replacementFn func(Value) Value) Value

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

func ReplaceLeavesMaybe(v Value, replaceFn func(Value) Value) Value

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

func ReplaceLeavesOnceMaybe(v Value, replaceFn func(Value) Value) Value

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 ResolveFieldAccess

func ResolveFieldAccess(child Value, path []FieldRequest) (Value, error)

ResolveFieldAccess resolves the complete request path atomically. It returns Value because resolving through a record constructor may collapse to the constructor's selected child rather than allocating a FieldValue.

func ResolveFieldOrdinals

func ResolveFieldOrdinals(child Value, ordinals []int) (Value, error)

ResolveFieldOrdinals is the compact purpose API for code which already owns a proven ordinal vector. It still validates the entire vector against the child's exact type before publishing a Value.

func ResolveOrdinalSeedAccess

func ResolveOrdinalSeedAccess(child Value, ordinal int, suffix []FieldRequest) (Value, error)

ResolveOrdinalSeedAccess constructs a machinery-owned seed access whose first component is a top-level physical slot and whose remaining components are ordinary semantic descent requests. The root pin is derived here from the exact QOV and cannot be supplied independently; suffixes never acquire a second physical offset. This is the fused collection form used by lateral unnest over a nested record column.

func ResolveOrdinalSeedField

func ResolveOrdinalSeedField(child Value, ordinal int) (Value, error)

ResolveOrdinalSeedField constructs the one-field access used by ordinal join/gather seed machinery. Unlike an ordinary semantic field access, the root ordinal is final for the exact QOV layout captured here, so the path is stamped FrontierPinned together with the domain derived from that same immutable exact root. Callers cannot supply either marker independently.

This is deliberately narrower than ResolveFieldOrdinals: a physical seed is always one top-level slot of one exact quantified object. Nested semantic access, record-constructor collapse, and already-built FieldValues must use the ordinary resolver and cannot acquire a seed contract accidentally.

func SimplifyPredicateValue

func SimplifyPredicateValue(v Value) Value

SimplifyPredicateValue is SimplifyValue for a value inside a predicate: it also folds a COALESCE over constant heads, Java's EvaluateConstantCoalesceRule, which only the predicate value rule set carries (DereferenceConstantObjectValueRuleSet.java:50-56). A COALESCE in a result value is never folded, so it evaluates every argument.

func SimplifyValue

func SimplifyValue(v Value) Value

SimplifyValue is Java's DefaultValueSimplificationRuleSet (DefaultValueSimplificationRuleSet.java:40-80), bottom-up: the null-strict collapse and the field-over-constructor and field-over-field compositions. Like Java's, it EVALUATES nothing: `1 + 2` stays `1 + 2` and is computed when the plan runs (RFC-257 WS-E 5.4(b)); EvaluateConstantComparand is the one evaluation, for a comparand that must be stored as a literal.

Returns the input unchanged when nothing applies — pointer-equality stable so callers can cheaply check for "did anything happen?".

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 the checked rewrite authority, where an enclosing exact FieldValue FUSES over an exact FieldValue replacement (replace.go — Java's withNewChild = ofFieldsAndFuseIfPossible). Pointer-stable when nothing translates. This Value-only compatibility surface cannot return the typed reconstruction error, so it returns nil on failure; callers that need the diagnostic use TranslateCorrelationsChecked.

func TranslateCorrelationsChecked

func TranslateCorrelationsChecked(v Value, m TranslationMap) (Value, error)

TranslateCorrelationsChecked applies a TranslationMap through the checked rewrite spine. In particular, a FieldValue whose QOV leaf changes is rebuilt from the replacement's exact root; incompatible replacements return a typed error and no original or partially rebuilt Value.

func TranslateDeclaredEdgeRoot

func TranslateDeclaredEdgeRoot(
	value Value,
	declaration QuantifiedObjectValue,
	target QuantifiedObjectValue,
) (Value, error)

TranslateDeclaredEdgeRoot replaces QOV leaves that belong to one declared physical edge with an exact target QOV. Unlike TranslatePhaseRoot, this matches the declaration by correlation plus exact type rather than object pointer: Quantifier.RequireFlowedObjectValue snapshots a new values-owned QOV on each call, so pointer identity is not stable across plan construction and extraction. A same-correlation leaf with another exact type is retained: a merged-row source window may conventionally share the whole edge's alias, and exact type is what distinguishes those two declarations. The owning plan validates any root that remains after layout/source normalization.

func TranslateLogicalSourceNameNormalization

func TranslateLogicalSourceNameNormalization(
	value Value,
	source CorrelationIdentifier,
	target QuantifiedObjectValue,
) (Value, error)

TranslateLogicalSourceNameNormalization RE-ROOTS every QOV at source onto the target INSTANCE when the two denote the same exact row. Logical table sources commonly retain a nominal record name (EMP RECORD<...>) while their physical scan publishes the same executor row anonymously; both are the same row, and the physical carrier is the instance the producer's layout and its retained windows are keyed by.

It is a re-rooting, NOT a type conversion. It once was a conversion — record names were part of Go's Type identity, so a nominal row and its anonymous carrier were two "different" types and this bridge existed to cross them. Names are provenance in Java (Type.Record.equals compares typeCode, nullability and fields only) and now in Go, so the two sides are simply equal and what remains to move is which QOV instance the program hangs from.

A narrower retained window that shares the source correlation, a foreign correlation, or any structural drift remains untouched. Eligible FieldValues are rebuilt by their complete ordinal path, and the rewrite is atomic on error.

func TranslateLogicalSourceNameNormalizationInValue

func TranslateLogicalSourceNameNormalizationInValue(
	value Value,
	source CorrelationIdentifier,
	authority Value,
) (Value, error)

TranslateLogicalSourceNameNormalizationInValue retargets a logical source onto the one exact same-correlation row declaration already retained by authority. It is the producer-local form used when the selected child's scan type is anonymous but the producer result has preserved the physical named source window. No target is minted from a child edge: the exact QOV embedded in authority is reused, and ambiguity/conflicting target declarations decline.

func TranslateLogicalSourceNameNormalizationToCorrelation

func TranslateLogicalSourceNameNormalizationToCorrelation(
	value Value,
	source CorrelationIdentifier,
	targetType Type,
) (Value, error)

TranslateLogicalSourceNameNormalizationToCorrelation is the retained-window form of TranslateLogicalSourceNameNormalization. It changes only the exact top-level record name while preserving the logical source correlation. A materializing producer (NLJ/FlatMap) can then prove that source's output ordinal through its retained result program; changing the alias to the whole physical edge first would erase the source ownership needed for duplicate and nested fields.

Every QOV rooted at source is considered independently. Only one whose full concrete row differs from targetType by the top-level record name is rebuilt; narrower same-alias windows, structural drift, and foreign correlations are left untouched.

func TranslateLogicalSourceRoot

func TranslateLogicalSourceRoot(
	value Value,
	declaration QuantifiedObjectValue,
	target QuantifiedObjectValue,
) (Value, error)

TranslateLogicalSourceRoot moves one explicitly declared logical source onto the exact physical QOV selected for that source. Logical join seeds retain a nominal record identity (for example B RECORD<...>) while stored-row plans publish the executor's physical carrier (RECORD<...>). Those are not equal exact types, so an alias-only rebase leaves a Value that names the physical edge with the logical type and cannot be bound at runtime.

The declaration makes this conversion unambiguous. A FieldValue is eligible only when its root matches BOTH the declaration's correlation and exact type; a same-correlation retained window of another type remains untouched. The complete ordinal path is then resolved again on target and its exact result type must stay unchanged. Thus this bridge may discard a phase-local root record name, but it cannot change which slot is read, its leaf type, or its nullability. A bare declared QOV becomes target directly.

The rewrite is copy-on-write and atomic: any selected path that the physical target cannot represent returns an error and no partial Value.

func TranslateNullExtendedPhaseRoot

func TranslateNullExtendedPhaseRoot(
	value Value,
	source QuantifiedObjectValue,
	target QuantifiedObjectValue,
) (Value, error)

TranslateNullExtendedPhaseRoot crosses the ONE phase boundary where a row's exact type legitimately changes: an operator that may emit NO row for its child republishes the child's row widened to nullable. Ordinals, arity, field names, record names and every NESTED nullability are unchanged — only the top-level bit moves, and only in the widening direction.

This exists because that boundary is otherwise IMPASSABLE by construction and was being crossed by guesswork instead. A lineage walk stops at any wrapper whose layout differs from its child's, which is right in general — provenance must not leak through a reshaping operator — but a null-extension wrapper is not reshaping anything. The value then arrived at the enclosing producer still rooted on the child's row, no ownership proof could place it, and the only thing that ever resolved it was one output slot happening to carry the same accessor name. On `SELECT ma.id, b.bid, c.cid FROM mb b JOIN mc c ON b.ref = c.cid RIGHT JOIN ma ON ma.id = b.bid` that name match is correct; give the box two same-named columns and it is a coin flip that reads the wrong one.

The widening direction is asserted rather than tolerated in both directions. Narrowing a nullable row onto a NOT NULL phase would be a claim that a row which may be absent is always present, which is exactly the fact an outer join exists to record.

func TranslatePhaseRoot

func TranslatePhaseRoot(
	value Value,
	source QuantifiedObjectValue,
	target QuantifiedObjectValue,
) (Value, error)

TranslatePhaseRoot atomically replaces one exact QOV root with another exact QOV of the same semantic object shape. It preserves every resolved FieldValue path and never maps a physical carrier prefix; layout-relative mapping belongs exclusively to ReanchorFieldValue.

func TranslateProjectionInputNameNormalization

func TranslateProjectionInputNameNormalization(
	value Value,
	declaration QuantifiedObjectValue,
	target QuantifiedObjectValue,
) (Value, error)

TranslateProjectionInputNameNormalization moves a projection program from the logical input row declaration onto the exact physical input edge when the producer changed only its top-level output field names. Duplicate SQL aliases are the motivating case: the logical derived-table row can legally contain [X, X, Y], while the projection producer publishes the unambiguous physical row [X, X_2, Y]. The field ordinal remains the identity.

This is deliberately narrower than a general row conversion. Declaration and target must use the same exact correlation, have the same concrete record name, width, record nullability, field ordinals, and exact field types. Only the top-level field names may disagree; nested names remain part of each field's exact type. A matching FieldValue is rebuilt by its complete ordinal path, so neither a rendered name nor a name lookup participates. Same-correlation leaves of another exact type and foreign correlations are retained for their owning binding authority to validate.

func TranslateProjectionInputNameNormalizationToCorrelation

func TranslateProjectionInputNameNormalizationToCorrelation(
	value Value,
	source CorrelationIdentifier,
	targetType Type,
) (Value, error)

TranslateProjectionInputNameNormalizationToCorrelation is the source-correlation form of TranslateProjectionInputNameNormalization. It is used at a boundary where the physical producer's exact row type is known but the logical declaration is embedded in the Value program, such as a correlated access program read through a selected scan's carrier.

Only an exact source-correlated record whose top-level field names actually differ, but whose record identity, width, nullability, ordinals, and exact leaf types all agree, is moved. Same-named declarations are pointer-stable; foreign/current roots and every structural drift are retained for their own binding authority. The ordinary checked Value rebuild preserves the complete resolved ordinal path and rejects a result-type change atomically.

func TryResolveFieldAccess

func TryResolveFieldAccess(child Value, path []FieldRequest) (Value, bool, error)

TryResolveFieldAccess converts only the RFC's documented optional-candidate resolution misses into an inapplicable result.

func WithChildren

func WithChildren(v Value, newChildren []Value) Value

WithChildren reconstructs a Value with new children. Array and non-leaf field reconstruction failures return nil; unchanged leaves are retained.

func WithChildrenChecked

func WithChildrenChecked(v Value, newChildren []Value) (Value, error)

WithChildrenChecked reconstructs a Value while retaining typed field/array reconstruction errors for callers outside this package.

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 VectorType

type VectorType struct {
	Nullable   bool
	Precision  int
	Dimensions int
}

VectorType is Java Type.Vector: precision and dimensions are part of identity.

func NewVectorType

func NewVectorType(nullable bool, precision, dimensions int) *VectorType

func (*VectorType) Code

func (*VectorType) Code() TypeCode

func (*VectorType) Equals

func (v *VectorType) Equals(other Type) bool

func (*VectorType) IsNullable

func (v *VectorType) IsNullable() bool

func (*VectorType) String

func (v *VectorType) String() string

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.

func (*VersionValue) Name

func (*VersionValue) Name() string

Name returns the debug-print kind.

func (*VersionValue) Type

func (*VersionValue) Type() Type

Type returns NullableVersion.

type WindowMatch

type WindowMatch struct {
	Source  QuantifiedObjectValue
	Matched bool
}

WindowMatch records the row-local match state of one null-supplying object. Ordinarily Source names a retained source window. A row-producing operator that fabricates an exact physical carrier for a missing whole object (for example FirstOrDefault's empty arm) records the layout's current carrier instead. NewWindowMatchPresence snapshots and validates these mutable inputs.

type WindowMatchPresence

type WindowMatchPresence interface {
	MatchState(QuantifiedObjectValue) (matched bool, known bool)
	// contains filtered or unexported methods
}

WindowMatchPresence is the immutable, values-owned match-state view consumed by an ordinal binder. The marker is not admission: consumers exact-recognize the private concrete before reading it.

func NewOrdinalCarrierMatchPresence

func NewOrdinalCarrierMatchPresence(layout OrdinalLayout, matched bool) (WindowMatchPresence, error)

NewOrdinalCarrierMatchPresence records whether layout's complete current object exists on one physical row. The carrier itself remains an exact, correctly-sized ordinal shell even when unmatched; the marker is what keeps that SQL NULL object distinct from a matched record whose every field is independently SQL NULL.

func NewWindowMatchPresence

func NewWindowMatchPresence(matches []WindowMatch) (WindowMatchPresence, error)

NewWindowMatchPresence constructs immutable per-row match state. One correlation may occur only once and with one exact type.

func NewWindowMatchPresenceFromCorrelations

func NewWindowMatchPresenceFromCorrelations(layout OrdinalLayout, bindings CorrelationBinder) (WindowMatchPresence, error)

NewWindowMatchPresenceFromCorrelations snapshots the per-row match state of every null-supplying window in layout from an existing leg/edge binder. A present nil binding is unmatched; a present non-nil row is matched (including a row whose every field is SQL NULL). Missing required bindings fail loudly.

type WindowOrderingPart

type WindowOrderingPart struct {
	Value      Value
	Descending bool
	NullsLast  bool
}

WindowOrderingPart is Java's WindowOrderingPart: an ordering value and its requested direction.

type WindowSpecification

type WindowSpecification struct {
	Partitioning []Value
	Ordering     []WindowOrderingPart
}

WindowSpecification is CallSiteArguments.WindowSpecification.

func (WindowSpecification) IsNone

func (w WindowSpecification) IsNone() bool

type WindowedValue

type WindowedValue struct {
	PartitioningValues []Value
	ArgumentValues     []Value
}

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL