Documentation
¶
Overview ¶
Package values is the Value-tier of the Go Cascades planner port — scalar / row-context expressions that compose into predicates, projections, and join keys. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values` package.
Contents:
- Value interface (Children, Type, Name, Evaluate) + concrete subtypes: Constant, Field, Arithmetic, Boolean, Cast, Null, Aggregate, QuantifiedObject, Promote, RecordConstructor, Parameter, ScalarFunction, Not.
- ExplainValue — SQL-ish renderer used by plan-cache keying and EXPLAIN output.
- SimplifyValue — standalone constant-fold over a Value tree (free function; the rule-driven equivalent lives in cascades's `Simplify`).
- LiteralValue / ToInt64 / ToFloat64 — coercion helpers promoted from comparisons.go (RFC-025 Phase 1) so both values/ and predicates/ can call them without a layering cycle.
- CorrelationIdentifier + Correlated — Quantifier-tracking surface used by Values to declare which upstream Quantifier they depend on; rewrite rules consult this when checking correlation-shape preservation.
- ExpressionFolder + DefaultFolder — testable seam for plan-time constant folding (RFC-025 §"Closing the leaks").
- The Type hierarchy (`type.go`) — the rich `Type` interface + `TypeCode` enum + concrete impls (`PrimitiveType`, `RecordType`, `ArrayType`, `EnumType`, `RelationType`), canonical singletons for every primitive (incl. UUID, VERSION, None, Any), `TypeRepository`, `WithNullability`, the `IsPromotable` / `MaximumType` / `MaximumTypeOfMany` promotion lattice (with structural recursion through ARRAY / RECORD / ENUM / RELATION), and shape predicates (`IsNull`, `IsArray`, …). Every Value impl's `Type()` returns the rich `Type` directly — the legacy `ValueType` enum + `FromValueType` / `ToValueType` bridges are retired. Once `type.go` exceeds ~1500 LOC it splits into a dedicated `cascades/typing/` sub-package per RFC-025.
Imports: nothing else from `pkg/recordlayer/query/plan/cascades/...`. `predicates/`, `matching/`, and root `cascades` all import this package; the dependency arrow points inward to keep cycles out.
Index ¶
- Constants
- Variables
- func AccessorNamePath(v Value) ([]string, bool)
- func AccessorNamePathKey(v Value) (string, bool)
- func AccessorNamePathMatchesNames(v Value, candidate []string) bool
- func AccessorPathCensus() [accessorPathClassCount]int
- func AccessorPathDottedOrigins() []string
- func AccessorPathDottedWitnesses() map[string]int
- func AssertAccessorPathCensus(w io.Writer, gates *AccessorPathGates) bool
- func AssertDottedLegQualifierCensus(w io.Writer, floors *DottedLegQualifierFloors) bool
- func AssertDottedRowTypeProducerCensus(w io.Writer, floor *DottedRowTypeProducerFloor) bool
- func AssertDottedWitnessAttribution(w io.Writer, floors *DottedWitnessFloors) bool
- func AssertFieldValueMintCensus(w io.Writer, gates *FieldValueMintGates) bool
- func AssertLegIdentityCensus(w io.Writer, floors map[LegIdentitySite]int64) bool
- func AssertLegIdentityCensusWith(w io.Writer, exp LegIdentityExpectations) bool
- func AssertNameSplitCensus(w io.Writer, floors *NameSplitFloors) bool
- func AssertOrdinalJoinSeed(rc *RecordConstructorValue)
- func AssertQualifierRecoveryCensus(w io.Writer, exp *QualifierRecoveryExpectations, corpus string) bool
- func AssertSeedWindowReaderCensus(w io.Writer, floors *SeedWindowReaderFloors) bool
- func AssertSelectResultMintCensus(w io.Writer, floors *SelectResultMintFloors) bool
- func BuildStructMessage(md protoreflect.MessageDescriptor, fields map[string]any, ...) (protoreflect.Value, error)
- func CanBridgeOrderingFieldValues(left, right Value) bool
- func CanBridgeOrderingValueRoots(left, right Value) bool
- func CastPairDefined(from, to TypeCode) bool
- func ClaimableOrderingPrefix(layout Type, names []string) int
- func ClaimableTypedKeyPrefix(keys []Value) int
- func ColumnCanExtendOrderingClaim(layout Type, name string) bool
- func ColumnCouldBeFloat(layout Type, name string) bool
- func ColumnNamePathsEqual(a, b Value) bool
- func ColumnNameValue(v Value) string
- func CompareExactInts(a, b any) (int, bool)
- func CompareFloat64(a, b float64) int
- func CompareOrdered(a, b any) (int, error)
- func ContainsAggregate(v Value) bool
- func ContainsBakedOrdinal(v Value) bool
- func DependsOnStatementClock(v Value) bool
- func DescribeType(typ Type) string
- func DisplayColumnName(v Value, alias string) string
- func DottedLegQualifierCensus() ([dottedLegSiteCount][dottedLegClassCount]int, []string)
- func DottedRowTypeProducerCensus() (dotted, plain int, witnesses []string)
- func DottedWitnessAttribution() (attributed, unattributed []string, mintedCount int)
- func DumpAccessorPathCensus(w io.Writer, label string)
- func DumpFieldValueMintCensus(w io.Writer, label string)
- func DumpOrderingBridgeDottedCensus(w io.Writer, label string)
- func EffectiveListField(fd protoreflect.FieldDescriptor) (list protoreflect.FieldDescriptor, wrapped, ok bool)
- func EqualsWithoutChildren(a, b Value) bool
- func EvaluateConstant(v Value) (out any, ok bool)
- func ExactTypesEqual(left, right ExactTypeHandle) bool
- func ExplainPlanValues(vs []Value) []string
- func ExplainValue(v Value) string
- func FieldNameForProtoField(field protoreflect.FieldDescriptor) string
- func FieldValueMintCensus() (total int, counts [fieldMintClassCount]int)
- func FieldValueMintOrigins() []string
- func FlowedRowShapeEquals(value QuantifiedObjectValue, typ Type) bool
- func FlowedRowShapesAgree(left, right QuantifiedObjectValue) bool
- func FlowedTypeEquals(value QuantifiedObjectValue, typ Type) bool
- func FlowedTypesEqual(left, right QuantifiedObjectValue) bool
- func FormatDottedLegQualifierCensus() string
- func FormatDottedRowTypeProducerCensus() string
- func FormatDottedWitnessAttribution() string
- func FormatSeedWindowReaderCensus() string
- func FormatSelectResultMintCensus() string
- func GetCorrelatedToOfValue(v Value) map[CorrelationIdentifier]struct{}
- func GetCorrelatedToWithoutChildrenOfValue(v Value) map[CorrelationIdentifier]struct{}
- func IsAny(t Type) bool
- func IsArray(t Type) bool
- func IsCanonicalCurrentOnlyOrdinalLayout(layout OrdinalLayout) (bool, error)
- func IsCascadesSafeScalarFunction(name string) bool
- func IsConstantValue(v Value) bool
- func IsEnum(t Type) bool
- func IsFunctionallyDependentOn(v Value, otherValue Value) bool
- func IsIndexOnly(v Value) bool
- func IsMixedSeedElementType(t Type) bool
- func IsNonEvaluable(v Value) bool
- func IsNone(t Type) bool
- func IsNull(t Type) bool
- func IsOrdinalFieldName(name string) bool
- func IsOrdinalJoinRV(v Value) bool
- func IsPositionalMergeRC(v Value) bool
- func IsPromotable(from, to Type) bool
- func IsRecord(t Type) bool
- func IsRelation(t Type) bool
- func IsRowVersionPseudoField(name string, t Type) bool
- func IsUnresolved(t Type) bool
- func IsUuid(t Type) bool
- func IsWrappedArrayDescriptor(md protoreflect.MessageDescriptor) bool
- func JavaDoubleToString(f float64) string
- func JavaFloatToString(f float32) string
- func LayoutProvides(layout OrdinalLayout, source QuantifiedObjectValue) (bool, error)
- func LayoutSatisfies(layout OrdinalLayout, required RequiredBindings) (bool, error)
- func LayoutWindowNullSupplying(layout OrdinalLayout, source QuantifiedObjectValue) (bool, error)
- func LegAwareRootOrdinal(vt FieldValue, srcOrd int, rc *RecordConstructorValue, fallbackOrd int) int
- func LegIdentityCensusEnabled() bool
- func LegIdentitySampleCap() int
- func LegSiteNeitherMustBeZero(site LegIdentitySite) bool
- func LegSiteNeitherSampled(site LegIdentitySite) bool
- func LikeMatch(pattern, s string, escape rune) bool
- func NameSplitCensus() ([nameSplitSiteCount][nameSplitClassCount]int, []string)
- func NestedResolvedPath(v Value) (string, bool)
- func NewWrappedArrayMessage(fd protoreflect.FieldDescriptor) (msg *dynamicpb.Message, values protoreflect.List)
- func NoteFieldValueMint(field string, baked bool)
- func NoteOrderingBridgeDotted(leftName, rightName string, answered bool)
- func OrderingBridgeDottedCensus() (int, [bridgeDottedClassCount]int, map[string]int)
- func OrderingFieldPair(a, b Value) bool
- func OrdinalCarrierMatchState(layout OrdinalLayout, presence WindowMatchPresence) (matched bool, known bool, err error)
- func OrdinalFieldName(ordinal int) string
- func OrdinalSeedLegLayout(rc *RecordConstructorValue) (map[CorrelationIdentifier]OrdinalSeedLegWindow, *RecordType, ...)
- func OrdinalWindowMatchState(layout OrdinalLayout, presence WindowMatchPresence, ...) (bool, error)
- func OutputColumnName(v Value, alias string) string
- func ProjectionColumnName(v Value) string
- func ProjectionOutputIdentityKey(v Value, alias string) string
- func ProjectionOutputSchemaIdentityOverrides(projections []Value, aliases []string, outputNames []string) ([]string, error)
- func ProtoFieldToRowValue(fd protoreflect.FieldDescriptor, v protoreflect.Value) any
- func ProtoScalarKindToRowValue(kind protoreflect.Kind, v protoreflect.Value) any
- func PullUpValues(toBePulledUp []Value, resultValue Value, alias CorrelationIdentifier) (map[Value]Value, error)
- func QualifierRecoveryCensus() ([qualRecSiteCount][qualRecClassCount]int, ...)
- func QualifierRecoveryWitnessCap() int
- func QuantifiedRowShapesAgree(left, right Type) bool
- func QuantifierFlowsAScalarRow(value Value) bool
- func RecordAccessorPathCall(class AccessorPathClass)
- func RecordAccessorPathDottedWitness(name string)
- func RecordDottedArmAnswer(name string, owner CorrelationIdentifier)
- func RecordDottedLegQualifier(site DottedLegSite, qual string, matchedAlias CorrelationIdentifier, ...)
- func RecordDottedRowTypeDerivation(fields []Field)
- func RecordInnerScalarLegTitleAt(producer InnerLegProducer, corr CorrelationIdentifier, title string)
- func RecordLegIdentityComparison(site LegIdentitySite, legName, corrName string)
- func RecordLegIdentityConversion(site LegIdentitySite, leg, corr CorrelationIdentifier, retiredVerdict bool)
- func RecordLegIdentityLeg(leg RecordTypeLeg)
- func RecordNameForDescriptor(descriptor protoreflect.MessageDescriptor) string
- func RecordNameSplit(site NameSplitSite, class NameSplitClass, name string)
- func RecordQualifierRecovery(site QualifierRecoverySite, class QualifierRecoveryClass, ...)
- func RecordSeedWindowLookup(site SeedWindowSite, found bool)
- func RecordSeedWindowLookupOfKind(site SeedWindowSite, found bool, kind LegKind)
- func RecordSeedWindowRead(site SeedWindowSite, class SeedWindowReadClass)
- func RecordSelectResultMint(site SelectResultMintSite, rv Value)
- func ReportLegIdentityCensus(w io.Writer, label string)
- func ResetAccessorPathCensus()
- func ResetDottedLegQualifierCensus()
- func ResetDottedRowTypeProducerCensus()
- func ResetDottedWitnessAttribution()
- func ResetFieldValueMintCensus()
- func ResetLegIdentityCensus()
- func ResetNameSplitCensus()
- func ResetOrderingBridgeDottedCensus()
- func ResetQualifierRecoveryCensus()
- func ResetSeedWindowReaderCensus()
- func ResetSelectResultMintCensus()
- func SameColumnPath(a, b *fieldPath) bool
- func SameLeg(a, b CorrelationIdentifier) bool
- func SameOrderingColumn(a, b Value) bool
- func SeedWindowReaderCensus() [seedWindowSiteCount][seedWindowReadClassCount]int
- func SemanticEqualsUnderAliasMap(a, b Value, aliases AliasMap) bool
- func SemanticHashCode(v Value) uint64
- func SetLegIdentityCensusEnabled(on bool)
- func StatesOrderingColumn(v Value) bool
- func ToFloat64(v any) (f float64, isFloat, numeric bool)
- func ToInt64(v any) (int64, bool)
- func TypeTerminatesOrderingClaim(t Type) bool
- func ValidateOrdinalLayoutAdmission(view OrdinalLayout) error
- func ValidateProjectionAliasSources(sources []ProjectionAliasSource, aliasMinted []bool, slots int) error
- func ValidateRequiredBindingsAdmission(view RequiredBindings) error
- func ValueSize(v Value) int
- func ValuesStructurallyEqual(a, b Value) bool
- func WalkValue(v Value, visit func(Value) bool)
- type AccessorPathClass
- type AccessorPathGates
- type AggregateEvalError
- type AggregateOp
- type AggregateValue
- type AliasMap
- type AliasPair
- type AndOrOp
- type AndOrValue
- type ArithmeticDivisionByZeroError
- type ArithmeticOp
- type ArithmeticOverflowError
- type ArithmeticValue
- type ArrayConstructorValue
- type ArrayDistinctValue
- type ArrayType
- type BakedNameContextError
- type BindingOrigin
- type BooleanValue
- type BridgeDottedClass
- type CardinalityValue
- type CastValue
- type CollateValue
- type ColumnIdentity
- type ConditionSelectorValue
- type ConstantDeref
- type ConstantObjectValue
- type ConstantValue
- type Correlated
- type CorrelationBinder
- type CorrelationIdentifier
- type CosineDistanceRowNumberValue
- func (*CosineDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*CosineDistanceRowNumberValue) IsIndexOnly() bool
- func (*CosineDistanceRowNumberValue) Name() string
- func (*CosineDistanceRowNumberValue) Type() Type
- func (v *CosineDistanceRowNumberValue) WithChildren(newChildren []Value) *CosineDistanceRowNumberValue
- type DerivedValue
- type DistanceOperator
- type DistanceRowNumberValue
- type DistanceValue
- type DotProductDistanceRowNumberValue
- func (*DotProductDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*DotProductDistanceRowNumberValue) IsIndexOnly() bool
- func (*DotProductDistanceRowNumberValue) Name() string
- func (*DotProductDistanceRowNumberValue) Type() Type
- func (v *DotProductDistanceRowNumberValue) WithChildren(newChildren []Value) *DotProductDistanceRowNumberValue
- type DottedLegClass
- type DottedLegLookup
- type DottedLegQualifierFloors
- type DottedLegSite
- type DottedRowTypeProducerFloor
- type DottedWitnessFloors
- type EmptyValue
- type EnumType
- type EnumValue
- type EuclideanDistanceRowNumberValue
- func (*EuclideanDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*EuclideanDistanceRowNumberValue) IsIndexOnly() bool
- func (*EuclideanDistanceRowNumberValue) Name() string
- func (*EuclideanDistanceRowNumberValue) Type() Type
- func (v *EuclideanDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanDistanceRowNumberValue
- type EuclideanSquareDistanceRowNumberValue
- func (*EuclideanSquareDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
- func (*EuclideanSquareDistanceRowNumberValue) IsIndexOnly() bool
- func (*EuclideanSquareDistanceRowNumberValue) Name() string
- func (*EuclideanSquareDistanceRowNumberValue) Type() Type
- func (v *EuclideanSquareDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanSquareDistanceRowNumberValue
- type EvaluatesTo
- type EvaluatesToValue
- type ExactTypeHandle
- func AsExactTypeHandle(value any) (ExactTypeHandle, bool)
- func ExactRelationOf(object Type) (ExactTypeHandle, error)
- func ExactRelationOfHandle(object ExactTypeHandle) (ExactTypeHandle, error)
- func ExactTypeForValue(value Value) (ExactTypeHandle, error)
- func FlowedExactType(value QuantifiedObjectValue) ExactTypeHandle
- func SnapshotExactType(typ Type) (ExactTypeHandle, error)
- type ExistsValue
- func (v *ExistsValue) Children() []Value
- func (v *ExistsValue) Evaluate(ctx any) (any, error)
- func (v *ExistsValue) GetChild() Value
- func (v *ExistsValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*ExistsValue) Name() string
- func (*ExistsValue) Type() Type
- func (v *ExistsValue) WithNewChild(c Value) *ExistsValue
- type ExplicitNullQuantifiedObjectBinder
- type ExpressionFolder
- type Field
- type FieldMintClass
- type FieldPathView
- type FieldRequest
- type FieldValue
- type FieldValueMintGates
- type FirstOrDefaultStreamingValue
- func (v *FirstOrDefaultStreamingValue) Children() []Value
- func (v *FirstOrDefaultStreamingValue) Evaluate(evalCtx any) (any, error)
- func (*FirstOrDefaultStreamingValue) Name() string
- func (v *FirstOrDefaultStreamingValue) Type() Type
- func (v *FirstOrDefaultStreamingValue) WithChildren(newChildren []Value) *FirstOrDefaultStreamingValue
- type FirstOrDefaultValue
- type FromOrderedBytesValue
- type InOpValue
- type IncarnationValue
- type IncompatibleOrderingTypeError
- type IndexEntryObjectValue
- type IndexEntryReader
- type IndexOnly
- type IndexOnlyAggregateOp
- type IndexOnlyAggregateValue
- func (v *IndexOnlyAggregateValue) Children() []Value
- func (*IndexOnlyAggregateValue) Evaluate(any) (any, error)
- func (v *IndexOnlyAggregateValue) GetIndexTypeName() string
- func (*IndexOnlyAggregateValue) IsIndexOnly() bool
- func (*IndexOnlyAggregateValue) IsNonEvaluable() bool
- func (v *IndexOnlyAggregateValue) Name() string
- func (v *IndexOnlyAggregateValue) Type() Type
- func (v *IndexOnlyAggregateValue) WithChildren(newChildren []Value) *IndexOnlyAggregateValue
- type IndexableAggregate
- type IndexedValue
- type InnerLegProducer
- type InvalidArgumentError
- type InvalidCastError
- type LeafValue
- type LegCensusChannel
- type LegIdentityCensus
- type LegIdentityExpectations
- type LegIdentitySite
- type LegKind
- type LegacyMapScalarFunction
- type LikeOperatorValue
- type NameSplitClass
- type NameSplitFloors
- type NameSplitSite
- type NonEvaluable
- type NonNullableFieldError
- type NotValue
- type NullValue
- type ObjectValue
- type OfTypeValue
- type OrderedBytesDirection
- type OrdinalBinderStorage
- type OrdinalCarrierKind
- type OrdinalDomain
- type OrdinalLayout
- func LayoutWithSeedLegs(layout OrdinalLayout, resultValue Value) OrdinalLayout
- func NewFlatOrdinalLayoutForResult(result Value, sources []OrdinalOutputSource) (OrdinalLayout, error)
- func NewFlatOrdinalLayoutForRetainedResult(result Value, nullSupplying []QuantifiedObjectValue) (OrdinalLayout, error)
- func NewFlatOrdinalLayoutForRetainedResultWithSources(result Value, nullSupplying []QuantifiedObjectValue, ...) (OrdinalLayout, error)
- func NewOrdinalLayout(carrier QuantifiedObjectValue, tiles []OrdinalTileSpec, ...) (OrdinalLayout, error)
- func NewOrdinalLayoutForCarrierType(typ Type, tiles []OrdinalTileSpec, windows []OrdinalWindowSpec) (OrdinalLayout, error)
- func NewScalarOrdinalLayout(carrier QuantifiedObjectValue) (OrdinalLayout, error)
- func NewScalarOrdinalLayoutForCarrierType(typ Type) (OrdinalLayout, error)
- type OrdinalOutputSource
- type OrdinalResolutionError
- type OrdinalRow
- type OrdinalSeedLegWindow
- type OrdinalTileKind
- type OrdinalTileSpec
- type OrdinalWindowSpec
- type ParameterBinder
- type ParameterObjectValue
- func (*ParameterObjectValue) Children() []Value
- func (v *ParameterObjectValue) Evaluate(evalCtx any) (any, error)
- func (*ParameterObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*ParameterObjectValue) Name() string
- func (v *ParameterObjectValue) RebaseLeaf(_ CorrelationIdentifier) Value
- func (v *ParameterObjectValue) Type() Type
- type ParameterValue
- type PatternForLikeValue
- type PickValue
- type PrimitiveType
- type ProjectionAliasSource
- type PromoteValue
- type ProtoTypeError
- type QualifierRecoveryClass
- type QualifierRecoveryExpectations
- type QualifierRecoveryFloors
- type QualifierRecoverySite
- type QuantifiedObjectBinder
- func InitOrdinalObjectBinder(storage *OrdinalBinderStorage, layout OrdinalLayout, carrier any, ...) (QuantifiedObjectBinder, error)
- func NewOrdinalObjectBinder(layout OrdinalLayout, carrier any, presence WindowMatchPresence, ...) (QuantifiedObjectBinder, error)
- func NewRequiredOrdinalObjectBinder(layout OrdinalLayout, carrier any, presence WindowMatchPresence, ...) (QuantifiedObjectBinder, error)
- type QuantifiedObjectValue
- type QuantifiedRecordValue
- type QueriedValue
- type RangeValue
- type RankValue
- type RecordConstructorField
- type RecordConstructorValue
- func NewRawRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue
- func NewRecordConstructorValue(fields ...RecordConstructorField) *RecordConstructorValue
- func ProjectionResultValue(projections []Value, aliases []string) (*RecordConstructorValue, error)
- func ProjectionResultValueForOutputSchema(projections []Value, aliases []string, outputNames []string) (*RecordConstructorValue, error)
- func (r *RecordConstructorValue) Children() []Value
- func (r *RecordConstructorValue) Evaluate(evalCtx any) (any, error)
- func (r *RecordConstructorValue) MessageDescriptor() protoreflect.MessageDescriptor
- func (*RecordConstructorValue) Name() string
- func (r *RecordConstructorValue) SetMessageDescriptor(md protoreflect.MessageDescriptor)
- func (r *RecordConstructorValue) SetTypeName(name string)
- func (r *RecordConstructorValue) Type() Type
- func (r *RecordConstructorValue) TypeName() string
- type RecordType
- func NewRecordType(name string, nullable bool, fields []Field) *RecordType
- func OrdinalSeedLegWindows(rc *RecordConstructorValue) (map[CorrelationIdentifier]OrdinalSeedLegWindow, *RecordType)
- func OrdinalSeedLegWindowsAcceptingNested(rc *RecordConstructorValue) (map[CorrelationIdentifier]OrdinalSeedLegWindow, *RecordType)
- func PhysicalFlowedRecordTypeOf(v QuantifiedObjectValue) *RecordType
- func (*RecordType) Code() TypeCode
- func (r *RecordType) Equals(other Type) bool
- func (r *RecordType) FieldIndexUnique(name string) (int, bool)
- func (r *RecordType) FieldNameHits(name string) int
- func (r *RecordType) GetField(ordinal int) (Field, bool)
- func (r *RecordType) IsNullable() bool
- func (r *RecordType) LookupFieldUnique(name string) (Field, bool)
- func (r *RecordType) String() string
- type RecordTypeLeg
- type RecordTypeValue
- type RegularTranslationMap
- type RelationType
- type RequiredBindings
- type ResolutionError
- type ResolutionErrorCode
- type ResolvedAccessorView
- type RowEvalContext
- type RowNumberHighOrderValue
- type RowNumberValue
- type ScalarFunctionArgumentDiagnosis
- type ScalarFunctionValue
- type ScalarSubqueryValue
- type ScalarTypeMismatchError
- type SeedWindowReadClass
- type SeedWindowReaderFloors
- type SeedWindowSite
- type SelectResultMintCounters
- type SelectResultMintFloors
- type SelectResultMintSite
- type SelfEqualsWithoutChildren
- type SelfSemanticHash
- type SelfWithChildren
- type StatementClock
- type StreamingValue
- type StrictRankLimitValue
- func (v *StrictRankLimitValue) Children() []Value
- func (v *StrictRankLimitValue) EqualsWithoutChildrenValue(other Value) bool
- func (v *StrictRankLimitValue) Evaluate(evalCtx any) (any, error)
- func (v *StrictRankLimitValue) Name() string
- func (v *StrictRankLimitValue) Type() Type
- func (v *StrictRankLimitValue) WithChildren(newChildren []Value) Value
- type SubscriptValue
- type ThrowsValue
- type ToOrderedBytesValue
- type TranslationFunction
- type TranslationMap
- type TranslationMapBuilder
- type TranslationMapWhen
- type TupleSource
- type Type
- func CommonValueType(branches []Value) Type
- func ExplodeOrdinalityResultType(elementType Type) Type
- func FieldTypeForProtoField(fd protoreflect.FieldDescriptor) Type
- func MaximumType(t1, t2 Type) Type
- func MaximumTypeOfMany(types ...Type) Type
- func NewAnyRecordType(nullable bool) Type
- func PhysicalCarrierType(layout OrdinalLayout) Type
- func ScalarFunctionDeclaredResultType(name string) (Type, bool)
- func ScalarFunctionResultType(name string, args []Value) (Type, bool)
- func ScalarTypeForProtoKind(fd protoreflect.FieldDescriptor) Type
- func SharedExactType(handle ExactTypeHandle) Type
- func SharedFlowedType(value QuantifiedObjectValue) Type
- func WithNullability(t Type, nullable bool) Type
- func WithRecordTypeLegs(typ Type, legs []RecordTypeLeg) Type
- func WithSeedTilingLegs(typ Type, rv Value) Type
- type TypeCode
- type TypeProtoRepository
- type TypeRegistrationError
- type TypeRepository
- type TypedEdgeBinding
- type TypedEdgeDeclaration
- type TypedExternalDeclaration
- type UdfValue
- type UnboundEvalContextError
- type UnboundScalarSubqueryError
- type UndeclaredStructFieldError
- type UnmatchedAggregateValue
- func (*UnmatchedAggregateValue) Children() []Value
- func (*UnmatchedAggregateValue) Evaluate(_ any) (any, error)
- func (v *UnmatchedAggregateValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
- func (*UnmatchedAggregateValue) IsNonEvaluable() bool
- func (*UnmatchedAggregateValue) Name() string
- func (*UnmatchedAggregateValue) Type() Type
- type Value
- func DeconstructRecord(v Value) ([]Value, error)
- func LiteralValue(lit any) Value
- func MapFieldValues(v Value, transform func(*fieldValue) Value) Value
- func PinValueToExactFrontier(value Value, carrier QuantifiedObjectValue) (Value, error)
- func PrimitiveAccessorsForType(typ Type, base func() Value) ([]Value, error)
- func PullUpValue(v Value, resultValue Value, alias CorrelationIdentifier) (Value, error)
- func PushDownValue(v Value, resultValue Value, upperAlias CorrelationIdentifier) Value
- func PushDownValues(toBePushedDown []Value, resultValue Value, upperAlias CorrelationIdentifier) []Value
- func ReanchorOwnedValueThroughProducer(value Value, producer Value, target QuantifiedObjectValue, ...) (Value, error)
- func ReanchorValueForLayout(value Value, target QuantifiedObjectValue, layout OrdinalLayout) (Value, error)
- func RebaseValueChecked(v Value, aliases AliasMap) (Value, error)
- func RebuildFieldValue(field FieldValue, child Value) (Value, error)
- func Replace(v Value, replacementFn func(Value) Value) Value
- func ReplaceLeavesMaybe(v Value, replaceFn func(Value) Value) Value
- func ReplaceLeavesOnceMaybe(v Value, replaceFn func(Value) Value) Value
- func ResolveFieldAccess(child Value, path []FieldRequest) (Value, error)
- func ResolveFieldOrdinals(child Value, ordinals []int) (Value, error)
- func ResolveOrdinalSeedAccess(child Value, ordinal int, suffix []FieldRequest) (Value, error)
- func ResolveOrdinalSeedField(child Value, ordinal int) (Value, error)
- func SimplifyAll(in []Value) []Value
- func SimplifyValue(v Value) Value
- func SimplifyValueWithContext(v Value, ctx ValueSimplifyContext) Value
- func TranslateCorrelations(v Value, m TranslationMap) Value
- func TranslateCorrelationsChecked(v Value, m TranslationMap) (Value, error)
- func TranslateDeclaredEdgeRoot(value Value, declaration QuantifiedObjectValue, target QuantifiedObjectValue) (Value, error)
- func TranslateLogicalSourceNameNormalization(value Value, source CorrelationIdentifier, target QuantifiedObjectValue) (Value, error)
- func TranslateLogicalSourceNameNormalizationInValue(value Value, source CorrelationIdentifier, authority Value) (Value, error)
- func TranslateLogicalSourceNameNormalizationToCorrelation(value Value, source CorrelationIdentifier, targetType Type) (Value, error)
- func TranslateLogicalSourceRoot(value Value, declaration QuantifiedObjectValue, target QuantifiedObjectValue) (Value, error)
- func TranslateNullExtendedPhaseRoot(value Value, source QuantifiedObjectValue, target QuantifiedObjectValue) (Value, error)
- func TranslatePhaseRoot(value Value, source QuantifiedObjectValue, target QuantifiedObjectValue) (Value, error)
- func TranslateProjectionInputNameNormalization(value Value, declaration QuantifiedObjectValue, target QuantifiedObjectValue) (Value, error)
- func TranslateProjectionInputNameNormalizationToCorrelation(value Value, source CorrelationIdentifier, targetType Type) (Value, error)
- func TryResolveFieldAccess(child Value, path []FieldRequest) (Value, bool, error)
- func WithChildren(v Value, newChildren []Value) Value
- type ValueSimplifyContext
- type VersionValue
- type WindowMatch
- type WindowMatchPresence
- func NewOrdinalCarrierMatchPresence(layout OrdinalLayout, matched bool) (WindowMatchPresence, error)
- func NewWindowMatchPresence(matches []WindowMatch) (WindowMatchPresence, error)
- func NewWindowMatchPresenceFromCorrelations(layout OrdinalLayout, bindings CorrelationBinder) (WindowMatchPresence, error)
- type WindowedValue
Constants ¶
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.
const WrappedArrayValuesFieldName = "values"
WrappedArrayValuesFieldName is the wrapper's single repeated field name (Java: NullableArrayUtils.REPEATED_FIELD_NAME).
Variables ¶
var Empty = &EmptyValue{}
Empty is the canonical EmptyValue instance. Callers should prefer this over allocating a new one — pointer identity makes equality checks O(1).
var 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.
What actually holds: every LogicalProjectionExpression constructor is a plain struct fill that validates nothing, so the one-slot whole-row projection can be built and IS built (expressions/flowed_value_typing_test.go's TestLogicalProjectionFallsBackToUntypedQOV). What this error does is stop the projection CLAIMING a row it cannot name; GetResultValue then falls back to an untyped QOV, which is the pre-RFC-226 decline kept deliberately for the one shape that cannot answer. The fallback is a LIVE arm, not dead code.
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 ¶
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 ¶
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 ¶
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 AccessorPathCensus ¶
func AccessorPathCensus() [accessorPathClassCount]int
AccessorPathCensus reports the class vector.
func AccessorPathDottedOrigins ¶
func AccessorPathDottedOrigins() []string
AccessorPathDottedOrigins returns the captured producer stacks.
func AccessorPathDottedWitnesses ¶
AccessorPathDottedWitnesses returns a copy of the witness set.
func AssertAccessorPathCensus ¶
func AssertAccessorPathCensus(w io.Writer, gates *AccessorPathGates) bool
AssertAccessorPathCensus checks the process census against its gates.
func AssertDottedLegQualifierCensus ¶
func AssertDottedLegQualifierCensus(w io.Writer, floors *DottedLegQualifierFloors) bool
AssertDottedLegQualifierCensus checks the census's hard zeros and its floors.
There are TWO hard zeros and they are different failures of the same table.
MATCH-ALIAS-DIFFERS: a leg matched on its OWN BINDING text while stating a different identity. That is the leg table having two spellings that disagree, resolved by the weaker one — the same contradiction the seed-window census refuses, seen through the one channel that cannot be re-keyed. A leg matched through its scan TABLE name is a different fact and has its own class; the zero would be unsatisfiable if the two were folded together, which is what the first measurement did. It is worth asserting HERE precisely because this reader will keep matching on text until its counterparty carries parsed segments: the guarantee that the text it matches names the leg the identity names is all that holds the channel together in the meantime.
MATCH-NO-ALIAS: a leg matched and states NO identity at all. This class was documented as blocking from the day it was written and was never gated, so its zero was a sentence rather than a check. It is the same defect the seed-window authority now declines on (an Alias-less leg files under the zero identifier and a second one displaces it), seen from the reader side: the leg table carries an entry whose identity nothing can compare, so the day the counterparty carries segments this leg has nothing to be matched against and the conversion silently loses it. Fix the PRODUCER; the two documented text boundaries that mint a leg from a string both set Name and Alias from that one string, so a leg reaching here without an identity came from neither.
func AssertDottedRowTypeProducerCensus ¶
func AssertDottedRowTypeProducerCensus(w io.Writer, floor *DottedRowTypeProducerFloor) bool
AssertDottedRowTypeProducerCensus checks the process census against a floor.
func AssertDottedWitnessAttribution ¶
func AssertDottedWitnessAttribution(w io.Writer, floors *DottedWitnessFloors) bool
AssertDottedWitnessAttribution checks both floors and the owner-collision zero.
func AssertFieldValueMintCensus ¶
func AssertFieldValueMintCensus(w io.Writer, gates *FieldValueMintGates) bool
AssertFieldValueMintCensus checks the process census against its gates.
func AssertLegIdentityCensus ¶
func AssertLegIdentityCensus(w io.Writer, floors map[LegIdentitySite]int64) bool
AssertLegIdentityCensus checks the census and reports whether it failed.
The ZERO assertions hold over ANY population — a fold-only pair, a diverged text/identity pair, an unstated identity, a RETIRED-VERDICT divergence, or a mixed instrument is a defect whether the corpus was one query or the whole suite — so they run always. That is FIVE, and callers must enumerate all five when they announce what a narrowed run still checks: an enumeration that omits the retired-verdict zero omits the one assertion that measures the conversion itself, which is the reason this census exists. Only the population FLOORS describe a particular corpus, and those are checked only for the sites the caller supplies: pass nil to assert the zeros over a narrowed run. Skipping the zeros along with the floors is how a filtered invocation used to report "floors not checked" while quietly also not checking the five things that are always checkable.
func AssertLegIdentityCensusWith ¶
func AssertLegIdentityCensusWith(w io.Writer, exp LegIdentityExpectations) bool
AssertLegIdentityCensusWith is AssertLegIdentityCensus with the zero-side guards a corpus may declare. See LegIdentityExpectations.
func AssertNameSplitCensus ¶
func AssertNameSplitCensus(w io.Writer, floors *NameSplitFloors) bool
AssertNameSplitCensus checks the census's hard zero and its floors, writing a report to w. Returns TRUE if anything FAILED — the convention its siblings on this path use, so a call site reading `if failed := ...` means what it says.
The HARD ZERO is SPLIT-QUALIFIED at both of THIS CENSUS's two sites — not at every splitter in Go — and it is asserted rather than floored because it is not a population to be kept healthy: it is the debt, and the whole claim of the projection-channel conversion is that production traffic no longer produces any AT THESE ARMS. A non-zero means either an un-migrated producer has started carrying dotted text where a triple belongs, or a machinery-minted label has acquired a dot. The failure text names both readings because the fix differs — and for the second it names the RULING rather than an escalation, since Java settles what a nameless projection output resolves to (nothing).
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 AssertQualifierRecoveryCensus ¶
func AssertQualifierRecoveryCensus(w io.Writer, exp *QualifierRecoveryExpectations, corpus string) bool
AssertQualifierRecoveryCensus checks the census's hard zero, its saturation guards and its floors, writing a report to w. Returns TRUE if anything FAILED — the convention its siblings on this path use.
THE HARD ZERO IS **DIVERGED**, and it is the only zero this census asserts. That is a deliberate departure from its sibling, which asserts its debt bucket at zero: here MANUFACTURED is expected to be non-zero at several sites, because the whole finding is that these splitters exist and are reached. Asserting it at zero would either be false on the day it was written or would have to be relaxed into meaninglessness. What CANNOT be tolerated is a split that contradicts an identity the site was holding at the time — that is not debt, it is a wrong answer.
func AssertSeedWindowReaderCensus ¶
func AssertSeedWindowReaderCensus(w io.Writer, floors *SeedWindowReaderFloors) bool
AssertSeedWindowReaderCensus checks the two hard zeros and the floors.
floors is nil when the run is NARROWED (-test.run), exactly as its siblings do it: the zeros still run, over whatever population the filter reached, and at zero they hold vacuously.
func AssertSelectResultMintCensus ¶
func AssertSelectResultMintCensus(w io.Writer, floors *SelectResultMintFloors) bool
AssertSelectResultMintCensus checks the per-site partition, the untyped-QOV zero, and the per-site call floors.
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 ¶
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 ¶
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 CastPairDefined ¶
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 ClaimableOrderingPrefix ¶
ClaimableOrderingPrefix returns how many of names (resolved against layout, in order) may be claimed as an ordering — the count of leading columns before the first one that terminates the claim.
This is the single entry point for producers that build an ordering key list from a metadata column-NAME sequence. Asking it in one place is the point: a producer that re-implements the predicate at its own call site is how two derivations drift apart and classify the same column differently.
It is NOT the only shape a producer comes in, and an earlier revision of this comment claimed it was ("the single entry point for every producer"). That was false, and the two producers it did not cover — the streaming aggregation and the aggregate index, whose ordering is over GROUPS rather than rows — were returning wrong rows on a real cluster while this file asserted they could not. A producer holding already-typed key VALUES asks TypeTerminatesOrderingClaim directly instead; the predicate is shared, the entry point is not. plans/ordering.go's header enumerates which producer asks which, and which need not ask at all.
func ClaimableTypedKeyPrefix ¶
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 ColumnCanExtendOrderingClaim ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
ContainsAggregate reports whether v has any AggregateValue in its subtree. Common gate for rules that only apply to scalar expressions — aggregates need the accumulator path, not per-row Evaluate.
func ContainsBakedOrdinal ¶
ContainsBakedOrdinal reports whether any FieldValue in v's subtree carries a 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 DependsOnStatementClock ¶
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.
func DescribeType ¶
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 ¶
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 DottedLegQualifierCensus ¶
DottedLegQualifierCensus reports the per-site class matrix and the witnesses.
func DottedRowTypeProducerCensus ¶
DottedRowTypeProducerCensus reports the counts and the distinct dotted row shapes the generic path derived.
func DottedWitnessAttribution ¶
DottedWitnessAttribution reports, per observed name, whether it is attributed to a correlated-scalar seed inner leg BY IDENTITY.
func DumpAccessorPathCensus ¶
DumpAccessorPathCensus renders the class vector.
func DumpFieldValueMintCensus ¶
DumpFieldValueMintCensus renders the census, with the partition check and the vacuity guard ahead of any zero-class claim.
func DumpOrderingBridgeDottedCensus ¶
DumpOrderingBridgeDottedCensus renders it, vacuity guard first.
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 ¶
EqualsWithoutChildren checks whether two Values are the same type with the same non-child attributes, WITHOUT recursing into children. This is the Go equivalent of Java's Value.equalsWithoutChildren().
For leaf values (no children) this is equivalent to ValuesStructurallyEqual. For composite values it checks the type and any type-specific attributes (operator, field names, etc.) but does NOT compare children.
Returns true if a and b have the same concrete type and the same non-child attributes (e.g. same ArithmeticOp, same field names in RecordConstructorValue, same CastValue target type, etc.).
func EvaluateConstant ¶
EvaluateConstant attempts to fold v to a concrete literal at plan time. Returns (literal, true) when v is constant (per IsConstantValue); (nil, false) otherwise. Safe on nil (returns (nil, false)). Useful for rules that want to pre-compute a constant sub-expression without writing an `if isConstant { eval and wrap }` dance every time.
A data-dependent runtime error from Evaluate (arithmetic overflow, division by zero, invalid cast, type mismatch) is reported as "not foldable" — (nil, false). This is the plan-time decline-to-fold path: the typed runtime-error family now returns via the error channel, so the error is swallowed here (leave the node) rather than surfacing a query error from the planner.
Genuinely programmer-invariant panics (e.g. an AggregateValue buried inside a constant tree that IsConstantValue should have excluded) are planner bugs and now surface rather than being silently swallowed — the residual recover that masked them has been collapsed.
func 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 ¶
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 ¶
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 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 FieldValueMintCensus ¶
FieldValueMintCensus returns the independent total and the class vector.
func FieldValueMintOrigins ¶
func FieldValueMintOrigins() []string
FieldValueMintOrigins returns the captured producer stacks for the dotted classes.
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 FormatDottedLegQualifierCensus ¶
func FormatDottedLegQualifierCensus() string
FormatDottedLegQualifierCensus renders the census for a harness to log.
func FormatDottedRowTypeProducerCensus ¶
func FormatDottedRowTypeProducerCensus() string
FormatDottedRowTypeProducerCensus renders the process census for a harness to log.
func FormatDottedWitnessAttribution ¶
func FormatDottedWitnessAttribution() string
FormatDottedWitnessAttribution renders the census for a harness to log.
func FormatSeedWindowReaderCensus ¶
func FormatSeedWindowReaderCensus() string
FormatSeedWindowReaderCensus renders the per-site table for a harness to log.
func FormatSelectResultMintCensus ¶
func FormatSelectResultMintCensus() string
FormatSelectResultMintCensus renders the census for a harness to log.
func GetCorrelatedToOfValue ¶
func GetCorrelatedToOfValue(v Value) map[CorrelationIdentifier]struct{}
GetCorrelatedToOfValue walks v + its descendants and returns the union of every correlation-bearing leaf Value's alias. Handles QuantifiedObjectValue, QuantifiedRecordValue, ScalarSubqueryValue, ObjectValue, UnmatchedAggregateValue, and ConstantObjectValue. ExistsValue is a transparent composite — its child QuantifiedObjectValue is reached via the Children() descent.
Returns nil for nil input. Returns a non-nil empty map for trees with no correlations.
Ports Java's Value.getCorrelatedTo().
func 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 IsArray ¶
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 ¶
IsCascadesSafeScalarFunction reports whether the named scalar function is admitted to the Cascades SQL pipeline.
func IsConstantValue ¶
IsConstantValue reports whether v's Evaluate is row-context- independent — its value is known at plan time. True for ConstantValue, NullValue, BooleanValue, and any composite whose children are all constants (`1 + 2`, `CAST(5 AS STRING)`). False for FieldValue / QuantifiedObjectValue / AggregateValue and any composite containing them.
Used by rule matchers that only fire on fully-foldable operands (e.g. ComparisonConstantSimplifyRule's whitelist).
func IsFunctionallyDependentOn ¶
IsFunctionallyDependentOn reports whether v is functionally dependent on otherValue — meaning v's output is fully determined by otherValue's output. Ports Java's Value.isFunctionallyDependentOn.
Returns true if all correlation-bearing leaves in v reference the same correlation as otherValue (when otherValue is a QOV). Returns false if any leaf references a different scope, or if otherValue is not a QOV.
func IsIndexOnly ¶
IsIndexOnly is a helper that any Value can call to check whether v requires an index scan to produce its result.
func IsMixedSeedElementType ¶
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 ¶
IsNonEvaluable is a helper that any Value can call to check whether v is plan-time-only. Avoids type-assertion boilerplate in callers.
func IsNone ¶
IsNone reports whether t is the NONE type (untyped empty array). Mirrors Java's `Type.isNone()`.
func IsNull ¶
IsNull reports whether t is the NULL literal's type (TypeCodeNull). Mirrors Java's `Type.isNull()`.
func IsOrdinalFieldName ¶
IsOrdinalFieldName reports whether name is a planner-internal ordinal-addressed field key (`_0`, `_1`, …) — OrdinalFieldName's inverse, digits-only (OrdinalFieldName never emits signs, so `_-1`/`_+0` are NOT ordinal keys). User columns cannot take this form (a parsed identifier's leading `_` is legal, but the positional-merge and Explode-ordinality producers are the only writers of these keys in a merged row).
func IsOrdinalJoinRV ¶
IsOrdinalJoinRV reports whether v is an ordinal-model JOIN-SELECT result value: a raw (non-anchored) RC whose every field is a FrontierPinned baked reference over a quantifier — the flat N-leg seed and its TranslationMap- translated upper forms (fused multi-accessor paths included) — spanning at least two distinct root quantifiers. This is the ordinal counterpart of the AnchoredJoin marker for the interning gate: the shapes whose quantifiers have no external identity consumer, where alias-IDENTITY dedup re-explodes the join re-enumeration's shared sub-products per bipartition. A lazy field anywhere (CTE column renames, computed projections) declines — those selects keep the alias-identity dedup that Go's column derivation requires.
func IsPositionalMergeRC ¶
IsPositionalMergeRC is the VALUE-level half of the 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 ¶
IsPromotable reports whether `from` can be implicitly promoted to `to` without an explicit CAST. Returns true when:
- from.Code() == to.Code() (identity, same type code).
- The (from.Code, to.Code) pair is in the promotionMap.
Mirrors Java's `PromoteValue.isPromotable`. Nullability is NOT part of the promotion check — a NOT NULL value can always be stored in a nullable slot of the same code, and a nullable value being stored in a NOT NULL slot is rejected at the caller (NOT NULL constraint), not by promotion.
Arrays / records / enums / vectors with structural inner types need element-by-element checks done by the caller (Java's isPromotionNeeded recurses for these); IsPromotable only handles the top-level code pair.
func IsRelation ¶
IsRelation reports whether t is a RELATION. Mirrors Java's `Type.isRelation()`.
func IsRowVersionPseudoField ¶
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 ¶
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 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 ¶
JavaDoubleToString is Java's Double.toString(double).
func JavaFloatToString ¶
JavaFloatToString is Java's Float.toString(float).
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 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 LegIdentityCensusEnabled ¶
func LegIdentityCensusEnabled() bool
LegIdentityCensusEnabled reports the gate state.
func LegIdentitySampleCap ¶
func LegIdentitySampleCap() int
LegIdentitySampleCap exposes that bound to the harnesses that gate on the witness sets.
A gate that walks a site's witnesses and clears each one against an allowlist is only as complete as the witness set: once the set is SATURATED, a further DISTINCT anomaly still increments the count but retains no witness, so the walk clears every witness it can see and the gate passes with a real divergence counted. Nothing about the count reveals that — a harness must compare the witness length against this cap and fail on saturation.
func LegSiteNeitherMustBeZero ¶
func LegSiteNeitherMustBeZero(site LegIdentitySite) bool
LegSiteNeitherMustBeZero reports whether a site's Neither population is a FAILURE rather than ordinary traffic.
It is true exactly at the sites whose recorded pair is two spellings of ONE leg that must therefore denote the same thing: a leg's own (Name, Alias.Name()). Everywhere else the pair is a lookup against a leg it is allowed not to be, so Neither counts misses and only FoldOnlyEqual can indict.
LegSiteNLJPlanAlias is deliberately NOT here even though its pair is also two spellings of one leg: measured, the select's source-alias slice can carry a re-minted identifier while its quantifier keeps the user alias, and that divergence is the reason to prefer the quantifier rather than a reason to fail. See that site's comment.
The distinction is the reason FoldOnlyEqual == 0 was not enough on its own: a producer that stores Name "X" against Alias "Y" lands in Neither and leaves the fold-only count at zero while the text channel and the identity channel have diverged.
func LegSiteNeitherSampled ¶
func LegSiteNeitherSampled(site LegIdentitySite) bool
LegSiteNeitherSampled reports whether a site's Neither witnesses are worth retaining.
It is a SUPERSET of LegSiteNeitherMustBeZero, and the gap between them is the whole reason it is a separate predicate. Sampling used to be tied to the assertion, which meant the one site whose Neither = 12 motivated building the sampler — LegSiteNLJPlanAlias, whose Neither is deliberately not asserted because a stale source alias is a reason to prefer the quantifier rather than a failure — never sampled. The number that justified the instrument was the number the instrument could not explain.
The criterion is "is the pair two spellings of ONE leg?", not "is its zero enforced?": at those sites a Neither is diagnostic no matter what the gate does with it. Everywhere else Neither is per-row lookup traffic and sampling it would put a mutex in the row loop.
func LikeMatch ¶
LikeMatch implements SQL `LIKE` matching:
- `%` matches zero or more characters, none of which may be a line terminator
- `_` matches exactly one character that is not a line terminator
- `escape` (if non-zero) makes a following `%` or `_` literal
Greedy backtrack; O(|pattern| * |s|) worst case.
Conformance contract: this is the ONE runtime SQL LIKE matcher. It backs the QueryPredicate-layer ComparisonLike (via the predicates package), the Value-layer LikeOperatorValue, and the map-backed INFORMATION_SCHEMA WHERE evaluator. Java's `PatternForLikeValue.eval` (PatternForLikeValue.java:96-117) + `LikeOperatorValue.likeOperation` (LikeOperatorValue.java:93-99) is the spec: Java rewrites the SQL pattern into `^<regex>$`, compiles it with `Pattern.compile` and NO flags, and matches via `.find()`. This matcher must return what that composition would.
NEWLINE semantics — the observable consequences of "no flags":
- No DOTALL: `_` -> `.` and `%` -> `.*` do NOT match a line terminator. Java's line-terminator code points in default mode (java.util.regex.Pattern, "Line terminators") are `\n`, `\r`, U+0085 (NEL), U+2028 (LS) and U+2029 (PS). A terminator in the input can only be matched by a literal terminator in the pattern. So `'a\nb' LIKE 'a_b'` and `'a\nb' LIKE 'a%b'` are FALSE.
- No MULTILINE, so `^` only matches at index 0 — `.find()` on an `^...$` pattern degenerates to an anchored match.
- Default `$` matches at end of input OR when the remaining input is exactly one FINAL line terminator: "\n", "\r\n", "\r", U+0085, U+2028 or U+2029 — and `$` never matches BETWEEN the `\r` and `\n` of a final "\r\n" (java.util.regex.Pattern$Dollar). So `'abc\n' LIKE 'abc'` is TRUE, `'a' + U+2028 LIKE 'a'` is TRUE, and — because `.*` can match empty with `$` sitting before the trailing terminator — `'\n' LIKE '%'` is TRUE even though `%` cannot consume the `\n` itself.
ESCAPE semantics — Java's, exactly, and narrower than the SQL standard's. `PatternForLikeValue` builds its replacement table as exactly TWO escape entries on top of the metacharacter table:
.put(escapeChar + "_", "_") .put(escapeChar + "%", "%") .putAll(REPLACE_MAP)
so an escape rune is consumed as an escape ONLY when `_` or `%` follows it. In every other position — before an ordinary character, before a second escape rune, or dangling at the end of the pattern — no escape entry can match, and the rune is instead rewritten by the ordinary per-character rules. Three consequences, each of which differs from the more common "escape makes the next character literal" reading, and each pinned by a test:
- A DANGLING escape is not malformed and is not a no-match: it is the escape rune taken literally (or, if the escape rune is itself `%` or `_`, taken as that wildcard). Java's own corpus records this — `like.yamsql:92` runs `B2 NOT LIKE 'Z' ESCAPE 'Z'` and excludes the two `'Z'` rows, i.e. `'Z' LIKE 'Z' ESCAPE 'Z'` is TRUE. Java's comment there concedes the SQL standard would raise 22025 instead, but the pinned behaviour is the literal match.
- Escape before an ORDINARY character does not make that character literal — the escape rune itself is the literal and the next character is then read normally. `a\b` ESCAPE `\` matches `a\b`, not `ab`.
- There is no escaped-escape: `a\\b` ESCAPE `\` is two literal backslashes, not one.
The escape rune falling through to the ordinary rules is what makes an escape rune of `%` or `_` still act as a wildcard in those positions, which is why the fallthrough is a fallthrough and not an unconditional literal.
`values.sqlPatternToRegex` (PatternForLikeValue) is the same spec expressed as Java's regex translation. The two are cross-checked against each other by TestLikeMatch_CrossCheckSQLPatternToRegex in this package (an exhaustive ASCII pattern/subject/escape grid, evaluating the produced regex under Java's default-mode `.` and `$` semantics), and LikeMatch is independently fuzzed against a Java-semantics regex oracle by FuzzLikeMatch / FuzzLikeMatchEscape in `pkg/recordlayer/query/plan/cascades/predicates/comparisons_test.go`. Any divergence between them, or between either and Java, is a conformance bug.
func NameSplitCensus ¶
NameSplitCensus returns a snapshot of the counters and the debt witnesses.
func NestedResolvedPath ¶
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 authorities already do for a childful reference — `sortKeyFieldRef` renders `LEG.COL` (cascades_translator.go) and `deriveProjectionColumnDef`'s non-nested arm calls `ColumnNameValue` when `Child != nil` (cascades_generator.go) — so qualifying here makes the nested arm agree with its siblings rather than inventing a third 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 NoteFieldValueMint ¶
NoteFieldValueMint records one FieldValue construction. The gate is the FIRST statement: disabled, this is one atomic load and a return.
func NoteOrderingBridgeDotted ¶
NoteOrderingBridgeDotted records a bridge attempt in which at least one side carried a flat-dotted name. Gate first; disabled it is one atomic load.
func OrderingBridgeDottedCensus ¶
OrderingBridgeDottedCensus returns the attempt total and class vector.
func OrderingFieldPair ¶
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 ¶
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 ¶
func OrdinalSeedLegLayout(rc *RecordConstructorValue) (map[CorrelationIdentifier]OrdinalSeedLegWindow, *RecordType, []OrdinalSeedLegWindow)
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".
ITS ONE PRODUCTION CONSUMER IS GONE. It served an orientation check inside the three-quantifier NLJ arm, and both retired with RFC-235. The run list is kept because the question it answers is not derivable from the map — finalization replaces a box run's entry with a narrower sub-window, after which the map no longer states which windows tile the row — so a future consumer would have to rebuild exactly this. A caller returning here should say why the map cannot serve it.
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 ¶
OutputColumnName is the projection OUTPUT-name authority: the name that keys the emitted positional row's slot for a projected column (executeProjection's posNames) and therefore the name any downstream re-reader must use on the ordinal frontier — the upper-cased ALIAS when the column carries one, else the ProjectionColumnName rendering. It lives here so every site derives the name from ONE rule instead of a hand-synchronized copy — 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 ProjectionColumnName ¶
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 (executeProjection's posNames). 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 ¶
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 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 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 QualifierRecoveryCensus ¶
func QualifierRecoveryCensus() ([qualRecSiteCount][qualRecClassCount]int, [qualRecSiteCount][qualRecClassCount][]string)
QualifierRecoveryCensus returns a snapshot of the counters and witnesses.
func QualifierRecoveryWitnessCap ¶
func QualifierRecoveryWitnessCap() int
QualifierRecoveryWitnessCap exposes the cap so a harness can check saturation.
func QuantifiedRowShapesAgree ¶
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 ¶
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 RecordAccessorPathCall ¶
func RecordAccessorPathCall(class AccessorPathClass)
RecordAccessorPathCall counts one call's outcome. Callers must guard on LegIdentityCensusEnabled().
func RecordAccessorPathDottedWitness ¶
func RecordAccessorPathDottedWitness(name string)
RecordAccessorPathDottedWitness records the flat-dotted NAME that tripped the ratchet arm, so the producer can be found rather than guessed at. Callers must guard on LegIdentityCensusEnabled().
The name is exactly the string the guard refused to split, which is the whole point: it is the only artifact that distinguishes "a real nested path arrived lazy" from "a qualifier was concatenated onto a leaf".
func RecordDottedArmAnswer ¶
func RecordDottedArmAnswer(name string, owner CorrelationIdentifier)
RecordDottedArmAnswer records one name the executor's dotted arm answered on, with the OWNER correlation the reader held. Callers must guard on LegIdentityCensusEnabled().
First writer wins for the map, and a LATER, DIFFERENT owner for the same name is RECORDED as a collision rather than dropped. That is not tidiness: a name answered under two owners, one attributed and one not, would otherwise report as cleanly attributed and the second owner would never appear anywhere. The census's whole claim is per-name, so a name with two owners invalidates the claim for that name.
func RecordDottedLegQualifier ¶
func RecordDottedLegQualifier(site DottedLegSite, qual string, matchedAlias CorrelationIdentifier, matchedBinding string, lookup DottedLegLookup)
RecordDottedLegQualifier counts one qualifier-against-leg-table match. Callers must guard on LegIdentityCensusEnabled().
func RecordDottedRowTypeDerivation ¶
func RecordDottedRowTypeDerivation(fields []Field)
RecordDottedRowTypeDerivation counts ONE RecordType derivation by the generic record-constructor path, cut by whether the row it describes is the DOTTED `LEG.COL` shape. Callers must guard on LegIdentityCensusEnabled().
func RecordInnerScalarLegTitleAt ¶
func RecordInnerScalarLegTitleAt(producer InnerLegProducer, corr CorrelationIdentifier, title string)
RecordInnerScalarLegTitleAt registers one (correlation, title) pair minted for a correlated-scalar seed inner leg, naming the producer. Callers must guard on LegIdentityCensusEnabled().
func RecordLegIdentityComparison ¶
func RecordLegIdentityComparison(site LegIdentitySite, legName, corrName string)
RecordLegIdentityComparison records one leg-identity pair at a site: legName is the leg's stored text, corrName the counterparty correlation's own spelling.
Callers must guard on LegIdentityCensusEnabled() so the disabled path costs one atomic load and no argument evaluation.
func RecordLegIdentityConversion ¶
func RecordLegIdentityConversion(site LegIdentitySite, leg, corr CorrelationIdentifier, retiredVerdict bool)
RecordLegIdentityConversion is recordLegIdentityPair plus the acceptance test the conversion needs: retiredVerdict is what the predicate this site USED TO evaluate says about this same pair, and a disagreement with SameLeg is counted and witnessed.
Every converted site must use this rather than recordLegIdentityPair while the migration is open. Computing the retired predicate at the site costs a string compare inside the census gate — production never evaluates it — and it is what turns "the conversion is representation-only" from three inferences chained across separate zero counts into one measurement of the decision itself. The retired predicates are not uniform (two sites compared exact text, two upper-folded one side), so no single central rule could stand in for them; each site states its own, verbatim.
Callers must guard on LegIdentityCensusEnabled().
func RecordLegIdentityLeg ¶
func RecordLegIdentityLeg(leg RecordTypeLeg)
RecordLegIdentityLeg records a leg's two spellings against each other at the text-vs-identity divergence site. Every reader that walks a leg calls it, so the population is every leg any consumer looked at.
Callers must guard on LegIdentityCensusEnabled().
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 RecordNameSplit ¶
func RecordNameSplit(site NameSplitSite, class NameSplitClass, name string)
RecordNameSplit records one resolution decision at a splitting arm. `name` is the rendered field name the arm was handed; it is used only for the witness list of the debt bucket, so a regrowth arrives with the spelling that caused it rather than only a count.
func RecordQualifierRecovery ¶
func RecordQualifierRecovery(site QualifierRecoverySite, class QualifierRecoveryClass, name, identity string)
RecordQualifierRecovery records ONE resolution decision at a dark splitter.
`name` is the rendered name the site was handed and `identity` is the structured counterparty it had in hand (empty when it had none). Both go into the witness so a regrowth arrives with the pair that caused it — for DIVERGED in particular, the count alone cannot say which side is wrong.
func RecordSeedWindowLookup ¶
func RecordSeedWindowLookup(site SeedWindowSite, found bool)
RecordSeedWindowLookup is the common shape: found or not.
func RecordSeedWindowLookupOfKind ¶
func RecordSeedWindowLookupOfKind(site SeedWindowSite, found bool, kind LegKind)
RecordSeedWindowLookupOfKind is the kind-aware counterpart of RecordSeedWindowLookup, for the readers that dispatch on the window kind.
func RecordSeedWindowRead ¶
func RecordSeedWindowRead(site SeedWindowSite, class SeedWindowReadClass)
RecordSeedWindowRead counts one keyed read of a seed-window map. Callers must guard on LegIdentityCensusEnabled().
func RecordSelectResultMint ¶
func RecordSelectResultMint(site SelectResultMintSite, rv Value)
RecordSelectResultMint counts ONE select-result-value construction and registers its identity.
The gate is the FIRST statement and it returns: with the census off this site must cost one atomic load and nothing else. The shape spelling below is a Sprintf per select expression built, which is planning-path work nothing consumes when the census is disabled.
func ReportLegIdentityCensus ¶
ReportLegIdentityCensus dumps every site's counts and witnesses. It reports unconditionally — a narrowed corpus still has numbers worth seeing, it just has no floors to check.
func ResetAccessorPathCensus ¶
func ResetAccessorPathCensus()
ResetAccessorPathCensus clears the counters.
func ResetDottedLegQualifierCensus ¶
func ResetDottedLegQualifierCensus()
ResetDottedLegQualifierCensus clears the counters.
func ResetDottedRowTypeProducerCensus ¶
func ResetDottedRowTypeProducerCensus()
ResetDottedRowTypeProducerCensus clears the counters.
func ResetDottedWitnessAttribution ¶
func ResetDottedWitnessAttribution()
ResetDottedWitnessAttribution clears the census.
func ResetFieldValueMintCensus ¶
func ResetFieldValueMintCensus()
ResetFieldValueMintCensus clears the counters.
func ResetLegIdentityCensus ¶
func ResetLegIdentityCensus()
ResetLegIdentityCensus zeroes every site's counts and witnesses.
func ResetNameSplitCensus ¶
func ResetNameSplitCensus()
ResetNameSplitCensus clears the counters. For tests that measure one shape.
func ResetOrderingBridgeDottedCensus ¶
func ResetOrderingBridgeDottedCensus()
ResetOrderingBridgeDottedCensus clears the counters.
func ResetQualifierRecoveryCensus ¶
func ResetQualifierRecoveryCensus()
ResetQualifierRecoveryCensus clears the counters. For tests measuring one shape.
func ResetSeedWindowReaderCensus ¶
func ResetSeedWindowReaderCensus()
ResetSeedWindowReaderCensus clears the counters.
func ResetSelectResultMintCensus ¶
func ResetSelectResultMintCensus()
ResetSelectResultMintCensus clears the counters and the origin registry.
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 ¶
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 SeedWindowReaderCensus ¶
func SeedWindowReaderCensus() [seedWindowSiteCount][seedWindowReadClassCount]int
SeedWindowReaderCensus reports the per-site class matrix.
func SemanticEqualsUnderAliasMap ¶
SemanticEqualsUnderAliasMap reports whether two Values are equal up to the quantifier-alias correspondence in `aliases` — the bool, alias-map-keyed counterpart of EqualsWithoutChildren+children, for memo interning and relational EqualsWithoutChildren (RFC-040 040.2). Correlation-bearing leaf Values compare their alias through the map (an unmapped alias maps to itself, so identical aliases compare equal under the empty map); every other Value compares structurally via EqualsWithoutChildren and recurses children under the same map.
This is consistent with SemanticHashCode: when this returns true, the two values have equal SemanticHashCode (both alias-invariant on the leaf aliases). Distinct from the cascades ValueEquivalence path, which carries QueryPlanConstraints for match-candidate compensation; this is the constraint-free bool primitive the expression/memo layer needs.
func SemanticHashCode ¶
SemanticHashCode returns an ALIAS-INVARIANT structural hash of a Value: the contract (Java Correlated.semanticHashCode) is
SemanticEqualsUnderAliasMap(a, b, m) ⟹ SemanticHashCode(a) == SemanticHashCode(b)
for ANY alias map m — so the hash must NOT depend on specific quantifier-alias names. Correlation-bearing leaf Values (QuantifiedObjectValue, QuantifiedRecord, Object, ConstantObject, Exists, ScalarSubquery, UnmatchedAggregate, IndexEntryObject, JoinMerge) hash to a per-type tag with the alias EXCLUDED; value-bearing leaves (ConstantValue, BooleanValue, ParameterValue) fold their literal; structural Values fold a type tag + children.
Lives in the values package (RFC-040 040.1b relocation) so both expressions (for relational EqualsWithoutChildren/HashCodeWithoutChildren, 040.2) and cascades (memoEqual) can use it without an import cycle. Inert until those call sites switch to it.
func SetLegIdentityCensusEnabled ¶
func SetLegIdentityCensusEnabled(on bool)
SetLegIdentityCensusEnabled turns the census on or off. It is OFF in every production path and in every test but the corpus census pass; when off, each comparison pays one relaxed atomic load.
The gate matters more here than for the planner-side censuses: two of these sites are on the PER-ROW executor path, so an always-on counter would put a contended atomic increment in the row loop.
func StatesOrderingColumn ¶
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 ToFloat64 ¶
ToFloat64 reports whether v is numeric (int-like or float) and returns its float64 promotion. isFloat distinguishes native-float inputs from integral ones promoted here — comparison-time promotion uses it to prefer the int path when both sides are integral.
func TypeTerminatesOrderingClaim ¶
TypeTerminatesOrderingClaim reports whether a column of type t ends an ordering claim — i.e. whether its FDB tuple key order differs from the order CompareFloat64/compareOrdered impose. True for FLOAT and DOUBLE.
The predicate is deliberately POSITIVE ("prove it is a float") rather than negative ("prove it is safe"). A type we cannot identify returns false, so an unidentified column keeps whatever claim the producer would otherwise make. That is a knowing trade: the alternative — treating every untyped column as claim-terminating — silently deletes sort elimination everywhere a layout is absent, including paths where the column is provably an integer. The soundness that matters is enforced where the type system is actually engaged, which on the SQL path is everywhere a column comes from a table.
KNOWN CONSERVATISM, and it is a missed optimisation rather than a wrong answer. The predicate is keyed on the TYPE alone, so it cannot see the scan RANGE — and the two defects above are not reachable from every range.
The recoverable case is a range with a FINITE LOWER BOUND. Both defects are really about the NEGATIVE-NaN block, which packs below -Inf: it is the one that is physically FIRST and logically LAST, and it is what splits the NaN tie class across two disjoint ranges. A scan starting at a finite value can never reach it. The positive block remains reachable — a range open at the top runs past +Inf — but there it is harmless on both counts: positive NaN is physically LAST and CompareFloat64 ranks NaN GREATEST, so the orders agree, and with only one block in range the tie class is contiguous, so later columns stay ordered within it. Over such a scan the claim could soundly extend through the float column and on into the primary-key suffix; today it terminates anyway and the query materialises a sort it does not need.
Measured on rowdiff seed 3943842, and the measurement corrected the reasoning once already — do not restate this as "a bounded range excludes NaN". That seed reads `e BETWEEN 2.0 AND 5.0`, but only the LOWER bound is pushed into the index; the upper stays a residual predicate, so the scanned range is [2.0, +Inf] and does include the positive-NaN block. The finite LOWER bound is what makes it sound, not the BETWEEN.
Three sibling seeds look identical from the outside and are NOT this case: 3943193 and 3944227 are zero-valued float EQUALITIES, which genuinely span two signed-zero key blocks, and 3943308 is `d IS NOT NULL`, whose range covers the whole non-null domain and so reaches the negative-NaN block. Those three must keep their sort.
The range-aware refinement is UNBUILT, deliberately, and if it is ever built it goes HERE. Closing it needs the ComparisonRange threaded to this decision — the same shape of fix as EqualityPinsSinglePhysicalKeyOnColumn, which threads the COLUMN type to a decision that previously guessed from the operand — and it must land as the ONE authority both consumers already ask, never as a second copy in either. The planner asks it for sort elimination; the rowdiff harness's ordering axis asks it to decide whether a scan provides the order a sort re-imposes. A copy that knew about ranges in only one of them would put the two derivations back out of step, which is the exact drift these shared predicates exist to prevent.
That is also why the harness UNDER-REPORTS by construction here, and why that is correct rather than a gap in it. `d IS NOT NULL` and `e >= 2.0` plan the identical shape — a float leading key under an inequality — so a type-only predicate cannot separate the recoverable case from the unrecoverable one. The detector inherits this conservatism instead of growing its own range-aware rule, so `WHERE e >= 2.0 ORDER BY e, id` is recorded as a missed optimization at the place the rule lives rather than kept alive as a nightly red.
It is not built because, unlike the column-type fix, nothing about it is a soundness defect: it buys latency, not correctness.
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 ¶
ValueSize returns the total node count in v (v + all descendants). Counterpart to PredicateSize for the Value tree. Rule authors use this to gate expensive rewrites that would otherwise explode tree size.
func ValuesStructurallyEqual ¶
ValuesStructurallyEqual reports whether two Values are structurally equal: same concrete Go type, same metadata, and recursively equal children. Stronger than ExplainValue comparison which could theoretically collide on structurally different values that render the same string.
func WalkValue ¶
WalkValue applies visit to every node in v's subtree, pre-order. If visit returns false, descent into that node's children is skipped (siblings + ancestors continue). Rule authors use this for tree-wide searches — e.g. "does any sub-expression reference this correlation?" or "does this Value tree contain an aggregate?".
Safe on nil: returns immediately. Mirrors WalkPredicate over the Value side of the hierarchy.
Types ¶
type AccessorPathClass ¶
type AccessorPathClass int
AccessorPathClass is one call's outcome. These partition every call to AccessorNamePath.
const ( // AccessorPathOKAllBaked: a path was returned and EVERY accessor came from a // Resolved FieldPath. The names were read off resolved accessors, so an // ordinal identity existed for the whole path and the name domain was a // choice rather than a necessity. This is the population that RFC-187 §8 // could convert without needing anything new. AccessorPathOKAllBaked AccessorPathClass = iota // AccessorPathOKHasLazy: a path was returned but at least one accessor came // from a LAZY node, where the name is the only identity that exists. This is // the population that cannot be converted without resolve-at-mint. AccessorPathOKHasLazy // AccessorPathDeclineDotted is THE RATCHET ARM: a lazy Field containing '.'. // Declined rather than split. See the header for why zero and non-zero mean // opposite things. AccessorPathDeclineDotted // AccessorPathDeclinePureOrdinal: a resolved accessor with no name at all // (Field == ""), so there is nothing to compare in the name domain. This is // the one decline that is a pure consequence of the match side being // name-based — the value HAS an identity, and it is the comparison that // cannot use it. AccessorPathDeclinePureOrdinal // AccessorPathDeclineEmptyName: a lazy node with no name and no resolution — // no identity of any kind. AccessorPathDeclineEmptyName // AccessorPathDeclineNotAColumn: the walk reached a root with no accessors, // so the value is not a column reference. The ordinary negative. AccessorPathDeclineNotAColumn )
func (AccessorPathClass) String ¶
func (c AccessorPathClass) String() string
type AccessorPathGates ¶
AccessorPathGates are the populations this census refuses to let move silently. It is named Gates rather than Floors, as its siblings are, because the two arms guard OPPOSITE directions on different populations.
MinTotal guards VACUITY, on the denominator. A ceiling over zero observations passes perfectly while measuring nothing, and a green from an empty set is this repo's dominant false positive. Nothing else here may be read without it.
MaxDeclineDotted is the GROWTH ceiling on the ratchet arm (AccessorPathDeclineDotted), and growth is the ONLY alarm direction it has.
THE DIRECTION HERE INVERTED, and the history is kept because a guard whose expected value moved is exactly the one that gets silently relaxed instead. The arm carried 4 declines: two RENDERED EXPLAIN LABELS (`q$N.AID#0`) minted by RecordQueryInMemorySortPlan.HintOrdering re-entering a display string as an identity, and `N.SK` — a genuinely NESTED path (struct column `n`, field `sk`, from `GROUP BY n.sk`) the resolver FUSED into one flat Field, which is the real `addr.city` versus `T.city` ambiguity this guard was written for. The rendered ones died with the advertiser fix. `N.SK` then died too, at its PRODUCER: a nested-path GROUP BY key is now rejected before it reaches the planner.
So ZERO is the steady state, a collapse floor on this arm would be unsatisfiable, and the event to watch for is the arm coming BACK — by the lazy render returning, or by the nested-path GROUP BY rejection being relaxed without the resolver keeping the path segmented. The floor is not deleted so much as SUPERSEDED: MinTotal still catches the instrument dying, which is the thing a collapse floor on the arm would otherwise have been covering.
A nil *AccessorPathGates is a no-op, which is the shape a narrowed run needs for MinTotal — a whole-corpus population claim. The ceiling is exact under any filter (a subset cannot exceed the whole), so it survives narrowing and is checked whenever gates is non-nil; MaxDeclineDotted nil leaves it unchecked.
type AggregateEvalError ¶
type AggregateEvalError struct {
Message string
}
AggregateEvalError is returned by AggregateValue.Evaluate when an aggregate node is reached on the per-row scalar evaluation path — e.g. an aggregate used in WHERE (`WHERE COUNT(*) > 0`). Java rejects this shape at plan time ("unable to eval an aggregation function with eval()"); Go's planner does not yet (TODO: plan-time rejection of aggregate-in-scalar-context), so the misuse reaches row eval. It is genuinely reachable from user query data, so it must return an error rather than panic (RFC-087 residual-panic audit, gate #1). The executor maps this to SQLSTATE 42803 (grouping error).
func (*AggregateEvalError) Error ¶
func (e *AggregateEvalError) Error() string
type AggregateOp ¶
type AggregateOp int
AggregateOp identifies an aggregate function. Mirrors the subset of Java's `AggregateValue` that the embedded engine currently lowers to a Record Layer aggregate-index query.
const ( AggInvalid AggregateOp = iota // unassigned — rejects if ever evaluated AggCount // COUNT(expr) AggCountStar // COUNT(*) AggSum // SUM(expr) AggMin // MIN(expr) AggMax // MAX(expr) AggAvg // AVG(expr) — rejects at Evaluate, no streaming impl )
Enum of aggregate operators Go supports. Ordered to match Java's bi-map so serialised plans round-trip.
func (AggregateOp) Symbol ¶
func (op AggregateOp) Symbol() string
Symbol returns the canonical SQL function name.
type AggregateValue ¶
type AggregateValue struct {
Op AggregateOp
Operand Value // nil iff Op == AggCountStar
}
AggregateValue represents an aggregate function application — `COUNT(*)`, `SUM(col)`, `MIN(expr)`, etc. The Operand is the argument (nil for COUNT(*)); the Op identifies which aggregate.
AggregateValue does NOT implement per-row Evaluate — aggregates span rows and need an accumulator. Evaluate returns nil to make the ignore-of-row-context explicit; rule code identifies AggregateValues by type-assertion and routes them to the aggregate operator (hash-agg, streaming-agg, index-backed agg) at build time.
func NewAggregateValue ¶
func NewAggregateValue(op AggregateOp, operand Value) *AggregateValue
NewAggregateValue constructs an AggregateValue. Panics on inconsistent op/operand combos (AggCountStar with operand, non-CountStar without operand) — these are static programmer errors, not runtime data problems.
func (*AggregateValue) Children ¶
func (a *AggregateValue) Children() []Value
Children returns the operand as a single child (empty for COUNT(*)). Lets WalkValue traverse aggregate arguments.
func (*AggregateValue) Evaluate ¶
func (a *AggregateValue) Evaluate(any) (any, error)
Evaluate returns AggregateEvalError — aggregates are multi-row and have no single-row Evaluate semantics. Rule / plan code type-asserts AggregateValue and routes it to an accumulator instead of calling Evaluate. The misuse path (an aggregate in a per-row scalar position, e.g. WHERE COUNT(*) > 0) is reachable from user data, so it returns a typed error rather than panicking (RFC-087 residual-panic audit).
func (*AggregateValue) GetIndexTypeName ¶
func (a *AggregateValue) GetIndexTypeName() string
GetIndexTypeName returns the FDB index-type name that backs this aggregate when an aggregate index is available. Mirrors Java's `IndexableAggregateValue.getIndexTypeName()` (Java's interface marker; Go uses an accessor on AggregateValue itself).
The mapping:
AggCount → COUNT_NOT_NULL (counts non-null values)
AggCountStar → COUNT (counts all rows incl. NULL)
AggSum → SUM
AggMin → 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).
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 ¶
ExtendAliasMap returns an immutable extension. A legitimate pairing conflict reports compatible=false; malformed or foreign input is an error.
func NewAliasMap ¶
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.
type AndOrValue ¶
AndOrValue is the Value-layer AND/OR connector — binary boolean operator with Kleene three-valued logic semantics. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.AndOrValue`.
Java has parallel predicate-layer AndPredicate / OrPredicate (already ported); this Value-layer variant exists for cases where AND/OR appears in a NON-predicate context — typically SQL projections like `SELECT a AND b FROM t` where the connector itself is the row's emitted Value, not a filter.
Result type: NotNullBoolean when both operands are NOT NULL, else NullableBoolean (per SQL Kleene rules — TRUE OR NULL = TRUE, FALSE AND NULL = FALSE, but TRUE AND NULL = NULL).
Eval semantics (Kleene 3VL):
AND | TRUE FALSE NULL -----------|------------------- TRUE | TRUE FALSE NULL FALSE | FALSE FALSE FALSE NULL | NULL FALSE NULL OR | TRUE FALSE NULL -----------|------------------- TRUE | TRUE TRUE TRUE FALSE | TRUE FALSE NULL NULL | TRUE NULL NULL
Short-circuit: if the LEFT operand evaluates to the dominant value (FALSE for AND, TRUE for OR), the right operand is not evaluated. Mirrors Java's eval-side optimisation. The right is evaluated for non-dominant left values (including NULL).
Non-bool operand handling: if either operand evaluates to a non- bool / non-NULL value, eval returns nil (UNKNOWN — type-degraded).
func NewAndOrValue ¶
func NewAndOrValue(op AndOrOp, left, right Value) *AndOrValue
NewAndOrValue constructs an AND/OR Value.
func (*AndOrValue) Children ¶
func (v *AndOrValue) Children() []Value
Children returns [left, right].
func (*AndOrValue) Evaluate ¶
func (v *AndOrValue) Evaluate(evalCtx any) (any, error)
Evaluate computes the Kleene 3VL result with short-circuit.
func (*AndOrValue) Type ¶
func (v *AndOrValue) Type() Type
Type returns NotNullBoolean iff BOTH operands have NOT NULL boolean types, else NullableBoolean. Mirrors Java's AndOrValue.getResultType which OR-reduces operand nullabilities.
Rationale: when both operands are non-nullable booleans, the result is always TRUE or FALSE — never NULL. (NULL only enters the eval through a NULL operand, which can't happen with NOT NULL operand types.) The dispatch matches the conventional SQL type-inference for boolean connectors.
Falls back to NullableBoolean if either operand is missing / non-boolean / nullable.
func (*AndOrValue) WithChildren ¶
func (v *AndOrValue) WithChildren(newChildren []Value) *AndOrValue
WithChildren returns a fresh AndOrValue with the given children. Caller is responsible for passing exactly 2 children; less raises out-of-bounds at access time.
type ArithmeticDivisionByZeroError ¶
type ArithmeticDivisionByZeroError struct{}
ArithmeticDivisionByZeroError is returned by ArithmeticValue.Evaluate when division or modulo by zero is attempted. Callers (the executor) convert this to the appropriate SQL error.
func (*ArithmeticDivisionByZeroError) Error ¶
func (*ArithmeticDivisionByZeroError) Error() string
type ArithmeticOp ¶
type ArithmeticOp int
ArithmeticOp is a subset of SQL arithmetic — enough to build a non-trivial matcher.
const ( OpAdd ArithmeticOp = iota OpSub OpMul OpDiv OpMod )
func (ArithmeticOp) Symbol ¶
func (o ArithmeticOp) Symbol() string
Symbol returns the SQL-text form of the arithmetic operator. Exposed for callers that want to render the op without going through ExplainValue (e.g. error messages, plan diagnostics). Lower-case `symbol` continues to be the package-internal alias.
type ArithmeticOverflowError ¶
type ArithmeticOverflowError struct{}
ArithmeticOverflowError is returned by ArithmeticValue.Evaluate when integer arithmetic overflows. Callers (the executor) convert this to SQLSTATE 22003 NUMERIC_VALUE_OUT_OF_RANGE.
func (*ArithmeticOverflowError) Error ¶
func (*ArithmeticOverflowError) Error() string
type ArithmeticValue ¶
type ArithmeticValue struct {
Op ArithmeticOp
Left Value
Right Value
}
ArithmeticValue is a binary arithmetic over two child Values. Evaluate recurses left + right and applies the op with numeric promotion (float arithmetic when either operand is float64, else int64; mixed non-numeric operands are a ScalarTypeMismatchError). NULL on either side propagates (SQL semantics). Division by zero returns nil (UNKNOWN).
func (*ArithmeticValue) Children ¶
func (a *ArithmeticValue) Children() []Value
func (*ArithmeticValue) Name ¶
func (a *ArithmeticValue) Name() string
func (*ArithmeticValue) Type ¶
func (a *ArithmeticValue) Type() Type
Type returns the arithmetic result Type by numeric promotion of the operand types: DOUBLE if either operand is DOUBLE, else FLOAT if either is FLOAT, else 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.
type ArrayConstructorValue ¶
ArrayConstructorValue evaluates an N-element ARRAY[a, b, c, ...] SQL literal — gathers each child Value's evaluation into a `[]any` representing the array. Mirrors Java's `LightArrayConstructorValue` (the simple, non-protobuf-message variant of `AbstractArrayConstructorValue`).
All children must produce values compatible with the declared `ElementType`. Go does NOT enforce per-element type validation at construction — Java's `injectPromotions` chain handles type-coercion via `PromoteValue` wrappers; the planner is expected to pre-resolve children to compatible types before reaching this constructor. Mismatched child types surface at evaluation as nil-typed elements in the produced slice.
Result type: nullable Array(ElementType). Java's getResultType() returns `Type.Array(elementType)` (always non-nullable since the constructor produces a concrete array literal); Go matches by emitting `&ArrayType{Nullable: false, ElementType: ...}`.
Empty-array case: an array constructor with zero children produces an empty slice (NOT nil) — Java's eval likewise returns `ImmutableList.of()`. This distinguishes "empty array" from "NULL array" — important for SQL CARDINALITY / ARRAY_LENGTH operations where empty has length 0 and NULL has length NULL.
func NewArrayConstructorValue ¶
func NewArrayConstructorValue(elementType Type, elements []Value) *ArrayConstructorValue
NewArrayConstructorValue constructs an array literal from N element Values, declaring the array's element type. ElementType can be UnknownType when the planner hasn't yet resolved child types — eval still works, child evaluations flow through.
func (*ArrayConstructorValue) Children ¶
func (v *ArrayConstructorValue) Children() []Value
Children returns the element Values.
func (*ArrayConstructorValue) Evaluate ¶
func (v *ArrayConstructorValue) Evaluate(evalCtx any) (any, error)
Evaluate gathers each child's evaluation into a `[]any`.
Empty constructor returns an empty `[]any{}` (NOT nil) so callers can distinguish empty-array from NULL-array via `len(result) == 0 && result != nil`.
Nil child Values are tolerated — produce a nil element. Per Java, this is the same as a child evaluating to NULL.
func (*ArrayConstructorValue) Name ¶
func (*ArrayConstructorValue) Name() string
Name returns the SQL function name.
func (*ArrayConstructorValue) Type ¶
func (v *ArrayConstructorValue) Type() Type
Type returns Array(ElementType), non-nullable. Even an empty array constructor produces a non-nullable empty array — NULL arrays come from elsewhere (a column value of NULL, etc.), not from the constructor.
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 returns a fresh ArrayConstructorValue with new elements. Element type carries through unchanged — caller is responsible for ensuring new children's types are compatible.
type ArrayDistinctValue ¶
type ArrayDistinctValue struct {
Child Value
// Typ is the result Type — matches Child's Type for arrays.
// Defaults to UnknownType if not set.
Typ Type
}
ArrayDistinctValue is the SQL `ARRAY_DISTINCT` operator: yields the input array with duplicate elements removed (preserving the first-occurrence order of the original). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. ArrayDistinctValue`.
CONFORMANCE: matches Java's eval — returns the input list with `Stream.distinct()` applied (first-seen order). NULL input propagates to NULL.
Type matches the Child's array Type (Go assumes the Child produces an array — Java's constructor `Verify.verify(innerResultType.isArray())` enforces this; Go accepts a Value of any Type but the Evaluate degrades to nil if Child doesn't return a slice).
func NewArrayDistinctValue ¶
func NewArrayDistinctValue(child Value) *ArrayDistinctValue
NewArrayDistinctValue constructs the operator over the given child Value. Type defaults to UnknownType if not provided.
func (*ArrayDistinctValue) Children ¶
func (v *ArrayDistinctValue) Children() []Value
Children returns [Child].
func (*ArrayDistinctValue) Evaluate ¶
func (v *ArrayDistinctValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the deduped array (first-seen order). Returns nil if Child evaluates to nil or non-slice.
Element equality uses bytes.Equal for []byte and Go's == for other types (matching values.equalsAny semantics — see value_in.go for the byte-slice-safe contract).
func (*ArrayDistinctValue) Name ¶
func (*ArrayDistinctValue) Name() string
Name returns the debug-print kind.
func (*ArrayDistinctValue) Type ¶
func (v *ArrayDistinctValue) Type() Type
Type returns the result type (matches Child's type).
type ArrayType ¶
type ArrayType struct {
// Nullable reports whether the array column allows NULL.
Nullable bool
// ElementType is the type of the array's values. May be nil
// when type inference hasn't filled it in (typically transient
// during plan-time analysis; runtime arrays always have a
// concrete element type by the time they're evaluated).
ElementType Type
}
ArrayType is the Type impl for ordered collections. Mirrors Java's Array nested type. Carries an ElementType (the type of the array's values) plus a Nullable flag (whether the array column itself can be NULL).
Two ArrayType instances are Equal iff their Nullable + ElementType match. nil ElementType represents an array whose element type isn't inferred yet (e.g. an empty array literal pre-type-inference) and is equal only to another ArrayType with nil ElementType.
func NewArrayType ¶
NewArrayType constructs an ArrayType. nil elementType is allowed for the "type not yet inferred" case; callers can fill it in via WithElementType once inference produces a concrete type.
func (*ArrayType) Equals ¶
Equals implements Type. Structural — Nullable + ElementType.Equals. Two ArrayTypes both with nil ElementType are equal; one nil + one non-nil are not.
type BakedNameContextError ¶
BakedNameContextError reports a BAKED FieldValue (ordinal authoritative) evaluated against a NAME-keyed or unrecognized row context. 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 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 (*BooleanValue) Children ¶
func (*BooleanValue) Children() []Value
func (*BooleanValue) Name ¶
func (*BooleanValue) Name() string
func (*BooleanValue) Type ¶
func (b *BooleanValue) Type() Type
Type returns the boolean literal's Type — NotNullBoolean for concrete TRUE/FALSE; NullableBoolean when Value is nil (the SQL UNKNOWN-at-Value-layer case).
type BridgeDottedClass ¶
type BridgeDottedClass int
const ( // BridgeDottedAnsweredFalse: at least one side was flat-dotted and the bridge // reported NOT the same column. The suspect class. BridgeDottedAnsweredFalse BridgeDottedClass = iota // BridgeDottedAnsweredTrue: at least one side was flat-dotted and the bridge // matched anyway — two identical renderings. BridgeDottedAnsweredTrue )
func (BridgeDottedClass) String ¶
func (c BridgeDottedClass) String() string
type CardinalityValue ¶
type CardinalityValue struct {
Child Value
}
CardinalityValue is the SQL `CARDINALITY` operator: yields the number of elements in an array. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. CardinalityValue`.
CARDINALITY(arr) ↔ CardinalityValue{Child: arr}
CONFORMANCE: matches Java's eval — returns the array length as an integer. NULL array → NULL (Java: childResult == null ? null : size()).
The result Type is a nullable 32-bit INT — Java's `Type.primitiveType(Type.TypeCode.INT)` ("array indexes and sizes are 32-bit integers"), nullable because a NULL array yields NULL. The metadata layer reports this column as INTEGER.
Java's ctor asserts the child is array-typed (`SemanticException.check(childValue.getResultType().isArray(), INCOMPATIBLE_TYPE)`). In Go the array-type validation lives at the SQL walk site (expr.walkCardinality), the earliest point with the resolved argument Type and access to the SQLSTATE error codes — a non-array argument raises CANNOT_CONVERT_TYPE there, matching the yamsql. This constructor stays a permissive data builder so the tree-rewrite machinery (withChildren) can reconstruct the node without re-validating.
func NewCardinalityValue ¶
func NewCardinalityValue(child Value) *CardinalityValue
NewCardinalityValue constructs the operator over the given array-typed child Value. Array-type validation is performed at the walk site (see the type doc); this builder does not re-check.
func (*CardinalityValue) Children ¶
func (v *CardinalityValue) Children() []Value
Children returns [Child].
func (*CardinalityValue) Evaluate ¶
func (v *CardinalityValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the array length. Mirrors Java's eval: childResult == null ? null : ((List)childResult).size(). A NULL array (nil child result) yields NULL; an empty array yields 0; a populated array yields its element count. Returns int64 (the codebase's integer eval representation; the column metadata is INTEGER via Type()). A non-slice child result yields nil — Java would ClassCastException, but array-type validation at the walk site keeps the child array-typed, so this is an unreachable defensive guard, not a silent type-degrade.
func (*CardinalityValue) Name ¶
func (*CardinalityValue) Name() string
Name returns the debug-print kind.
func (*CardinalityValue) Type ¶
func (*CardinalityValue) Type() Type
Type returns nullable INT — Java's `Type.primitiveType(Type.TypeCode.INT)`. A NULL array makes the result NULL, so the type is nullable; the width is 32-bit INT (reported as INTEGER), not LONG.
type CastValue ¶
CastValue converts a child Value's result to a target Type. Go handles the trivial conversions our existing corpus needs: int ↔ string (via strconv-free formatting), bool ↔ int (false=0, true=1). Unknown conversions return nil (UNKNOWN) — extend the Evaluate switch when a corpus query needs a new pair.
func NewCastValue ¶
NewCastValue constructs a CastValue.
type CollateValue ¶
type CollateValue struct {
StringChild Value
LocaleChild Value // nil = use registry default locale
StrengthChild Value // nil = use registry default strength
}
CollateValue applies a locale-specific collation to a string, producing a sort-key BYTES blob suitable for use as part of an index key. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.CollateValue`.
SQL surface:
collate(name, 'en_US', 'PRIMARY')
↑ string ↑ locale ↑ strength
Locale and strength are optional — Java's grammar allows `collate(name)`, `collate(name, locale)`, or `collate(name, locale, strength)`.
Strength enum (mirrors java.text.Collator):
- PRIMARY: only base-letter differences matter ('a' = 'A', 'a' ≠ 'b').
- SECONDARY: + accent differences ('a' ≠ 'á', 'a' = 'A').
- TERTIARY: + case differences ('a' ≠ 'A').
- IDENTICAL: full Unicode normalisation.
Used in collation-aware sort + comparison: the produced BYTES blob is a normalised sort key — sorting / comparing the keys lexicographically reproduces locale-aware ordering.
Result type: NotNullBytes. Even when the input string is NULL, the produced sort key is a sentinel byte sequence (Java's behaviour); Go surfaces nil in that branch (no sentinel).
Eval is a placeholder: the collation machinery exists on the index side (pkg/recordlayer/collate_function_key_expression.go wires golang.org/x/text/collate) but is NOT wired into this Value's Evaluate. The Value-shape is reachable for parser / planner / serialisation work; a query that needs runtime COLLATE evaluation must wire that machinery through here first.
func NewCollateValue ¶
func NewCollateValue(stringChild, localeChild, strengthChild Value) *CollateValue
NewCollateValue constructs a collate-encoder. localeChild + strengthChild may be nil to indicate "use defaults".
func (*CollateValue) Children ¶
func (v *CollateValue) Children() []Value
Children returns [stringChild, localeChild?, strengthChild?] — optional children are skipped when nil. Mirrors Java's computeChildren ImmutableList.builder pattern.
func (*CollateValue) Evaluate ¶
func (*CollateValue) Evaluate(any) (any, error)
Evaluate is a placeholder — real eval needs golang.org/x/text/collate wiring. Returns nil per the existing placeholder pattern.
func (*CollateValue) WithChildren ¶
func (v *CollateValue) WithChildren(newChildren []Value) *CollateValue
WithChildren returns a fresh CollateValue with new children. Caller is responsible for passing the right number of children (1 / 2 / 3); the constructor reflects the count back into the optional fields.
type 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. `pkg/docscheck`'s `.Field` gate fires on composite-literal KEYS and on returned selectors; a display name smuggled through a returned struct FIELD is invisible to it. So the key type simply has nowhere to put one, 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 ¶
func (*ConditionSelectorValue) Name() string
Name returns the SQL function name.
func (*ConditionSelectorValue) Type ¶
func (*ConditionSelectorValue) Type() Type
Type returns NotNullInt — the selector returns an integer index.
Note: Java's getResultType() returns Type.primitiveType(INT) which is the *Java-level* type signature; the eval may return null at runtime when no implication matches. The Type accessor is the declared type, not the dynamic type. SQL's nullable wrapping happens at the consumer (PickValue) when interpreting the selector's nil-runtime-result.
func (*ConditionSelectorValue) WithChildren ¶
func (v *ConditionSelectorValue) WithChildren(newChildren []Value) *ConditionSelectorValue
WithChildren returns a fresh ConditionSelectorValue with the given implications substituted. Used by the simplification driver when child rewrites land on the implications.
type ConstantDeref ¶
type ConstantDeref interface {
// DereferenceConstant returns the value bound to (alias,
// constantID) at evaluation time, or nil if no binding exists.
DereferenceConstant(alias CorrelationIdentifier, constantID string) any
}
ConstantDeref is the optional EvaluationContext capability for dereferencing a ConstantObjectValue. Implementations look up the constant by (alias, constantID) in the planner's per-alias constant map.
Mirrors Java's EvaluationContext.dereferenceConstant.
type ConstantObjectValue ¶
type ConstantObjectValue struct {
Alias CorrelationIdentifier
ConstantID string
ResultType Type
}
ConstantObjectValue is a NAMED reference to a constant captured during planning. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. ConstantObjectValue`.
The constant value itself is stored in an EvaluationContext at execution time, keyed by (alias, constantId). At plan-time the Value carries only the placeholder reference + the bound Type; the actual value is dereferenced when Evaluate runs against an EvaluationContext.
Why a named placeholder instead of a literal: parameter binding, plan-cache reuse, and constant capture during query rewriting all need to defer the actual constant until execution-time. Plan-time rewrites operate on the placeholder; execution dereferences.
Type is whatever the planner determined at capture time — typically nullable to allow NULL constants.
CONFORMANCE NOTE: Java's eval consults EvaluationContext.dereferenceConstant + PromoteValue.isPromotionNeeded for type promotion when the runtime constant's type doesn't match the bound result type. Go's Evaluate matches Java 1:1: dereference the constant, then apply promoteConstant when the runtime type differs from ResultType.
func NewConstantObjectValue ¶
func NewConstantObjectValue(alias CorrelationIdentifier, constantID string, resultType Type) *ConstantObjectValue
NewConstantObjectValue constructs the placeholder.
func (*ConstantObjectValue) Children ¶
func (*ConstantObjectValue) Children() []Value
Children returns the empty slice — leaf.
func (*ConstantObjectValue) Evaluate ¶
func (v *ConstantObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate dereferences the constant via evalCtx's ConstantDeref capability. Returns nil if evalCtx doesn't implement ConstantDeref or if the binding is missing.
Matches Java's ConstantObjectValue.eval: after dereferencing, applies numeric type promotion when the runtime object's type doesn't match the bound ResultType. Relation-typed results are returned as-is (no promotion for structured stream types).
func (*ConstantObjectValue) GetCorrelatedTo ¶
func (v *ConstantObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the singleton set containing the alias — ConstantObjectValue depends on the alias's binding.
func (*ConstantObjectValue) Name ¶
func (*ConstantObjectValue) Name() string
Name returns the debug-print kind.
func (*ConstantObjectValue) Type ¶
func (v *ConstantObjectValue) Type() Type
Type returns the bound result type.
type ConstantValue ¶
ConstantValue is a literal. Evaluate returns Value verbatim.
Typ carries the literal's rich Type. NULL constants (`Value == nil`) keep Typ for the typed-NULL case (e.g. `CAST(NULL AS INT)`); the constructor / call sites set the canonical singleton appropriate for the literal's Go runtime type.
func (*ConstantValue) Children ¶
func (c *ConstantValue) Children() []Value
func (*ConstantValue) Name ¶
func (c *ConstantValue) Name() string
func (*ConstantValue) Type ¶
func (c *ConstantValue) Type() Type
Type returns the constant's rich Type. Nullability is derived from Value: nil Value → nullable (a typed NULL literal); non-nil Value → NOT NULL (the literal carries a concrete value, so by definition can't be NULL). Mirrors Java's `LiteralValue.computeReturnType` shape.
The Typ field's own nullability is overridden — callers shouldn't have to pre-compute the right NotNull / Nullable singleton; the presence/absence of Value is the authoritative signal.
type Correlated ¶
type Correlated interface {
// references. A "leaf" value (ConstantValue) returns an empty
// set. A FieldValue on Quantifier q returns {q}.
GetCorrelatedTo() map[CorrelationIdentifier]struct{}
}
Correlated is the interface Java's `Correlated<T>` maps to. A Correlated value knows which CorrelationIdentifiers it depends on, and can rebind them (used by TranslationMap rewrites). Correlation-bearing Values and Predicates implement it.
type CorrelationBinder ¶
type CorrelationBinder interface {
GetCorrelationBinding(id CorrelationIdentifier) (any, bool)
}
CorrelationBinder is an optional eval-context capability for resolving correlation bindings. When QuantifiedObjectValue.Evaluate is called with a context implementing this interface, it resolves the correlated row. Mirrors Java's EvaluationContext.getBinding(CORRELATION, alias).
type CorrelationIdentifier ¶
type CorrelationIdentifier struct {
// contains filtered or unexported fields
}
CorrelationIdentifier is an opaque alias for a Quantifier — two distinct Quantifiers get distinct IDs. Comparable by value (underlying string) so CorrelationIdentifiers can live in maps.
func 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 NamedCorrelationIdentifier ¶
func NamedCorrelationIdentifier(name string) CorrelationIdentifier
NamedCorrelationIdentifier wraps an explicit name (e.g. a SQL alias). Two NamedCorrelationIdentifiers with the same name are equal — unlike UniqueCorrelationIdentifier which always allocates.
func UniqueCorrelationIdentifier ¶
func UniqueCorrelationIdentifier() CorrelationIdentifier
UniqueCorrelationIdentifier generates a fresh CorrelationIdentifier with a monotonically-increasing suffix. Used when the analyzer needs to allocate a new Quantifier mid-rewrite. Java calls the equivalent `CorrelationIdentifier.uniqueID()`.
Format: "q$1", "q$2", ... — leading 'q' matches Java's convention so explain output diffs cleanly against Java's.
func UniqueUnmatchedID ¶
func UniqueUnmatchedID() CorrelationIdentifier
UniqueUnmatchedID generates a fresh CorrelationIdentifier for a new unmatched aggregate. Mirrors Java's UnmatchedAggregateValue.uniqueId().
func (CorrelationIdentifier) IsZero ¶
func (c CorrelationIdentifier) IsZero() bool
IsZero reports whether c is the zero-value CorrelationIdentifier. Useful for nil-checks without a pointer.
func (CorrelationIdentifier) Name ¶
func (c CorrelationIdentifier) Name() string
Name returns the underlying identifier string.
func (CorrelationIdentifier) String ¶
func (c CorrelationIdentifier) String() string
String implements fmt.Stringer.
type CosineDistanceRowNumberValue ¶
type CosineDistanceRowNumberValue struct {
WindowedValue
}
CosineDistanceRowNumberValue is the cosine-distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by cosine distance from a reference vector. More similar vectors (smaller cosine distance) get lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.CosineDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Cosine distance measures angular difference: 0 = identical direction, 1 = orthogonal, 2 = opposite.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewCosineDistanceRowNumberValue ¶
func NewCosineDistanceRowNumberValue(partitioningValues, argumentValues []Value) *CosineDistanceRowNumberValue
NewCosineDistanceRowNumberValue constructs a cosine-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*CosineDistanceRowNumberValue) Evaluate ¶
func (*CosineDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*CosineDistanceRowNumberValue) IsIndexOnly ¶
func (*CosineDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*CosineDistanceRowNumberValue) Name ¶
func (*CosineDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*CosineDistanceRowNumberValue) Type ¶
func (*CosineDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*CosineDistanceRowNumberValue) WithChildren ¶
func (v *CosineDistanceRowNumberValue) WithChildren(newChildren []Value) *CosineDistanceRowNumberValue
WithChildren returns a fresh CosineDistanceRowNumberValue with children re-split via SplitNewChildren.
type DerivedValue ¶
DerivedValue is a placeholder Value that wraps a list of children without computing a result. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.DerivedValue`.
Used by:
- The planner during plan rewrites that need to track child dependencies but don't yet know how to compute a result.
- Match-candidate compatibility checks that consult the derived-from-which-children property.
DerivedValue is "non-evaluable" — Evaluate panics. Pattern-match against it; don't try to run it at the per-row level.
func NewDerivedValue ¶
func NewDerivedValue(children []Value) *DerivedValue
NewDerivedValue constructs a DerivedValue with UnknownType.
func NewDerivedValueWithType ¶
func NewDerivedValueWithType(children []Value, resultType Type) *DerivedValue
NewDerivedValueWithType constructs a DerivedValue with the given result Type.
func (*DerivedValue) Children ¶
func (v *DerivedValue) Children() []Value
Children returns the wrapped children.
type DistanceOperator ¶
type DistanceOperator int
DistanceOperator enumerates the vector-distance metrics SQL can invoke as scalar functions over vector-typed columns. Mirrors Java's `DistanceValue.DistanceOperator` verbatim — the SQL infix notation matches Java's enum names lowered.
const ( // DistanceEuclidean is sqrt(sum((a_i - b_i)^2)) — L2 distance. DistanceEuclidean DistanceOperator = iota // DistanceEuclideanSquare is sum((a_i - b_i)^2) — squared L2, // avoids the sqrt for speed (same ordering as L2 for KNN). DistanceEuclideanSquare // DistanceCosine is 1 - (a·b)/(|a|·|b|) — angle-based; range [0, 2]. DistanceCosine // DistanceDotProduct is -(a·b) — negated dot product so smaller // values = MORE similar (matches the "distance" convention where // 0 = identical). DistanceDotProduct )
func (DistanceOperator) String ¶
func (op DistanceOperator) String() string
String returns the SQL function name (lowercase per Java's SQL grammar — `euclidean_distance` etc.).
type DistanceRowNumberValue ¶
type DistanceRowNumberValue struct {
WindowedValue
Metric DistanceOperator
EfSearch *int
IsReturningVectors *bool
}
DistanceRowNumberValue is the K-NN search Value: ROW_NUMBER() computed within an HNSW vector index traversal, ORDERED BY a specific distance metric. Mirrors Java's `EuclideanDistanceRowNumberValue` / `EuclideanSquareDistanceRowNumberValue` / `CosineDistanceRowNumberValue` / `DotProductDistanceRowNumberValue` — Java has FOUR concrete classes, one per metric.
The Go port UNIFIES the four into a single concrete type with a `Metric` field discriminator. The Java distinction matters because the K-NN match rule selects on the concrete class type; the Go unified design makes K-NN rules switch on Metric instead (a one-line `if v.Metric == DistanceCosine`-style check). Both expressions are equally matchable; the unified design avoids 4× class-per-metric duplication.
Used by the HNSW K-NN search-rewrite rule: when a query of the form
ROW_NUMBER() OVER (PARTITION BY ... ORDER BY <metric>(field, queryVec)) <= K
is detected, the planner rewrites it into a ScanIndex over the HNSW index with a DistanceRankValueComparison capturing K + queryVec; the resulting plan emits row-numbered candidates from the index's graph traversal directly. This Value is the post-rewrite shape — its eval is INDEX-ONLY (the ROW_NUMBER value is computed during the index search, not from the base record).
Result type: NotNullLong. ROW_NUMBER is always populated, 1-based.
The HNSW config (EfSearch + IsReturningVectors) carries through from the higher-order ROW_NUMBER form — same fields as RowNumberValue's HNSW knobs.
func NewDistanceRowNumberValue ¶
func NewDistanceRowNumberValue(metric DistanceOperator, partitioningValues, argumentValues []Value, efSearch *int, isReturningVectors *bool) *DistanceRowNumberValue
NewDistanceRowNumberValue constructs a metric-specific row-number value. partitioningValues are the OVER PARTITION BY columns; argumentValues typically contain the distance arguments (vector field + query vector) that the ORDER BY references.
func (*DistanceRowNumberValue) Evaluate ¶
func (*DistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (`_row_number` key) — same as base RowNumberValue. Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*DistanceRowNumberValue) IsIndexOnly ¶
func (*DistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — like base RowNumberValue, K-NN row-numbers are computed during HNSW index traversal and can't be reproduced from base record data alone.
func (*DistanceRowNumberValue) Name ¶
func (v *DistanceRowNumberValue) Name() string
Name returns a metric-specific function name matching Java's per-class naming convention:
euclidean_distance_row_number euclidean_square_distance_row_number cosine_distance_row_number dot_product_distance_row_number
func (*DistanceRowNumberValue) Type ¶
func (*DistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated.
func (*DistanceRowNumberValue) WithChildren ¶
func (v *DistanceRowNumberValue) WithChildren(newChildren []Value) *DistanceRowNumberValue
WithChildren returns a fresh DistanceRowNumberValue with split children — partition + argument lists rebuilt via SplitNewChildren, metric + HNSW config carry through unchanged.
type DistanceValue ¶
type DistanceValue struct {
Operator DistanceOperator
LeftChild Value
RightChild Value
}
DistanceValue computes a distance metric between two vector expressions. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.DistanceValue`.
SQL surface:
WHERE euclidean_distance(embedding, queryVec) < 0.5 ORDER BY cosine_distance(vec_field, target) ASC LIMIT 10
Used in similarity-search + nearest-neighbor queries — typically paired with HNSW vector indexes via the K-NN query rewrite that transforms `ROW_NUMBER() OVER (ORDER BY distance(...)) <= K` into a DistanceRankValueComparison + index-backed scan. The distance computation itself is a scalar Value evaluated per-row.
Result type: NotNullDouble. All distance metrics produce a non-NULL real number when both operands are non-NULL vectors.
Eval contract:
- LeftChild + RightChild evaluate to []float64 (vector representation in Go; Java uses RealVector).
- Mismatched-length vectors → eval returns nil (type-degraded).
- NULL vectors → Java throws RecordCoreException; Go returns nil (Go surfaces the error as nil per existing pattern; downstream rules can choose to reject earlier at planner level).
Note: eval is functional for `[]float64` operands — vector type support is gated on broader infrastructure (Type.Vector + binary vector encoding), but the metric math itself works directly on double slices for testability + plan-equivalence with Java.
func NewDistanceValue ¶
func NewDistanceValue(op DistanceOperator, left, right Value) *DistanceValue
NewDistanceValue constructs a distance computation.
func (*DistanceValue) Children ¶
func (v *DistanceValue) Children() []Value
Children returns [left, right].
func (*DistanceValue) Evaluate ¶
func (v *DistanceValue) Evaluate(evalCtx any) (any, error)
Evaluate computes the distance metric. Returns nil when either operand is NULL or when the operands aren't compatible vectors.
func (*DistanceValue) Name ¶
func (v *DistanceValue) Name() string
Name returns the SQL function name for this distance metric.
func (*DistanceValue) Type ¶
func (*DistanceValue) Type() Type
Type returns NotNullDouble — distance metrics produce non-NULL real numbers given non-NULL vector operands.
type DotProductDistanceRowNumberValue ¶
type DotProductDistanceRowNumberValue struct {
WindowedValue
}
DotProductDistanceRowNumberValue is the dot-product-distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by dot product distance from a reference vector. Vectors with larger dot products (more aligned) get lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.DotProductDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Dot product distance is the negative dot product: vectors with higher dot products (more similar) have smaller distances.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewDotProductDistanceRowNumberValue ¶
func NewDotProductDistanceRowNumberValue(partitioningValues, argumentValues []Value) *DotProductDistanceRowNumberValue
NewDotProductDistanceRowNumberValue constructs a dot-product-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*DotProductDistanceRowNumberValue) Evaluate ¶
func (*DotProductDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*DotProductDistanceRowNumberValue) IsIndexOnly ¶
func (*DotProductDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*DotProductDistanceRowNumberValue) Name ¶
func (*DotProductDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*DotProductDistanceRowNumberValue) Type ¶
func (*DotProductDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*DotProductDistanceRowNumberValue) WithChildren ¶
func (v *DotProductDistanceRowNumberValue) WithChildren(newChildren []Value) *DotProductDistanceRowNumberValue
WithChildren returns a fresh DotProductDistanceRowNumberValue with children re-split via SplitNewChildren.
type DottedLegClass ¶
type DottedLegClass int
DottedLegClass is one call's bucket. The six partition every call.
const ( // DottedLegMatchAliasIsQualifier: a leg matched and its stated Alias is // EXACTLY the qualifier text. The leg table can serve an identity; the // lookup still cannot, having none to offer. DottedLegMatchAliasIsQualifier DottedLegClass = iota // DottedLegMatchAliasDiffers: a leg matched by FOLDED text and its stated // Alias is not that text. Minting from the qualifier would forge an // identifier the leg disagrees with — this is the population that would make // a text→identifier mint wrong rather than merely redundant. DottedLegMatchAliasDiffers // DottedLegMatchNoAlias: a leg matched and states no identity at all. DottedLegMatchNoAlias // DottedLegMatchViaTableName: a leg matched on a qualifier that is NOT its // binding — the scan TABLE name, registered as a second addressing route so // `FROM PA AS "s"` still answers `PA."ID"` (the ordinal leg type's RecordName // contract). The identifier such a qualifier would mint is by DESIGN not the // quantifier's, so this population is the reason its map cannot be re-keyed // by identity even in principle: one of its two key kinds names a table, and // a table is not a quantifier. // // It is counted apart from MATCH-ALIAS-DIFFERS rather than folded into it // because the two look identical at the reader — a qualifier and a leg alias // that disagree — and mean opposite things. Folding them would have reported // a live contradiction where there is a documented feature, and the census // did exactly that before this class existed. DottedLegMatchViaTableName // DottedLegAmbiguousQualifier: the qualifier named MORE THAN ONE leg and the // layout map POISONED that key (`layouts[key] = nil`) so nothing bakes // through it. Two legs sharing an alias, or two legs scanning one table under // the table-name addressing route. // // It is a fifth thing, not a flavour of noMatch, and folding it into noMatch // is what this class fixes. The census recorded its call BEFORE the `lay == // nil` bail, and a poisoned key and an absent one are the same nil at that // point — so "no leg carried the qualifier" was reported for a qualifier // carried by two. The two mean opposite things about the leg table: absent is // a reference the table does not describe, ambiguous is a table that // describes it twice and refuses to choose. Only the second is a fact about // how much this channel is being asked to do. DottedLegAmbiguousQualifier // DottedLegNoMatch: no leg carried the qualifier. Not a name decision — the // reference falls through unbaked. DottedLegNoMatch )
func (DottedLegClass) String ¶
func (c DottedLegClass) String() string
type DottedLegLookup ¶
type DottedLegLookup int
DottedLegLookup is what the READER's own map read produced, before any question about the leg it found. It is threaded in rather than inferred from the matched leg, because two of its three values arrive at the reader as the same nil: a qualifier with no entry and a qualifier whose entry was POISONED for ambiguity are indistinguishable once the map read is over, and they mean opposite things.
const ( // DottedLegLookupMiss: the layout map/leg table has no entry for this // qualifier. DottedLegLookupMiss DottedLegLookup = iota // DottedLegLookupAmbiguous: an entry exists and is POISONED — two legs claim // the qualifier, so nothing may bake through it. DottedLegLookupAmbiguous // DottedLegLookupHit: exactly one leg carried the qualifier. DottedLegLookupHit )
type DottedLegQualifierFloors ¶
type DottedLegQualifierFloors struct {
Calls [dottedLegSiteCount]int
}
DottedLegQualifierFloors is the minimum population each site must report over a whole suite run.
Same reason as every floor on this path, and it bites harder here than usual: the findings this census produces are "the MATCH-ALIAS-DIFFERS population is empty" and "the MATCH-NO-ALIAS population is empty", and an unreached site prints both identically to a site measured clean. A site left at 0 is UNFLOORED and that is a statement about the corpus, not an omission.
type DottedLegSite ¶
type DottedLegSite int
DottedLegSite is one translator reader that matches a name-split qualifier against a leg table.
const ( // DottedLegSiteFlatColumnBake is query.bakeFlatRefsAgainstColumns' dotted // arm: qualifier → leg window over the flat output column list, leaf → // first match within the window. Its leg table comes from // expressionOutputLegs or from the wholeRowLegFor TEXT-BOUNDARY mint. DottedLegSiteFlatColumnBake DottedLegSite = iota // DottedLegSiteLegQOVBake is query.bakeDottedRefsToLegQOV's MULTI-ForEach // per-leg layout lookup: qualifier → the leg's own layout, leaf → an ordinal // in that leg's OWN column domain. Its layouts are keyed by upper-folded text // while each layout carries the quantifier's identity, so it is the same // held-apart namespace pair the seed windows had. DottedLegSiteLegQOVBake )
func (DottedLegSite) String ¶
func (s DottedLegSite) String() string
type DottedRowTypeProducerFloor ¶
DottedRowTypeProducerFloor carries the two populations this census refuses to let collapse silently. They are DIFFERENT claims and neither can stand in for the other.
Derivations floors the TOTAL traffic (dotted + plain) and guards the INSTRUMENT. A run reporting no derivations at all is reporting a broken counter, not a quiet corpus. `plain` is what floors it in practice: `RecordConstructorValue.Type()` is called by any query that constructs a record, and both full-corpus readings clear 100 by three orders of magnitude.
Dotted floors the FINDING, and it is the reason this struct has two fields. The finding is "DOTTED is not zero" — that `RecordConstructorValue.Type()` IS a producer of the `LEG.COL`-shaped row, refuting the producer-set claim RFC-212 §3.4 originally asserted rather than measured, and relocating the leg-table population to this path (§1.1, §3.5). Derivations cannot watch that: plain outnumbers dotted about 230:1 (157699 to 681), so DOTTED could return to zero and the total floor would still pass by three orders of magnitude. The finding was live, load-bearing and unasserted; this is the assertion.
ALARM DIRECTION ON Dotted: COLLAPSE, and it is that way round precisely because the expected value moved. The claim this census was built to test was DOTTED == 0; the measurement refuted it, so zero stopped being the steady state and a floor — not a hard zero — is what a refuted zero turns into. A return to zero now means either the corpus stopped reaching the dotted path or the discriminator broke, and in both cases §1.1's placement decision has quietly lost the evidence it rests on while the build stays green.
If a later change makes zero legitimate again — the dotted `LEG.COL` row retired, the executor's dotted arm gone — the direction INVERTS with it: the alarm becomes growth and the guard becomes a hard zero. Reconcile it with the new expected value; do not lower it to whatever the run produced, and do not delete it, which would leave the revival unwatched.
A nil floor, and equally a zero-valued one, is a NO-OP by construction: the shape a `-test.run`-narrowed corpus needs, where a whole-run population claim has nothing it can honestly decide.
type DottedWitnessFloors ¶
type DottedWitnessFloors struct {
// Observed floors the dotted-arm names. A partition over an empty observed
// population reads exactly like a decided one.
Observed int
// Minted floors the registrations. This is the direction the census's first
// round rested on and nothing checked: the NEITHER finding was only load
// bearing because the producers minted titles on that run, so the instrument
// was demonstrably live. A run minting ZERO reports NOT attributed for every
// name, vacuously, and looks identical to a real refutation.
Minted int
}
DottedWitnessFloors are the two populations that must be non-trivial for this census's finding to mean anything.
type EmptyValue ¶
type EmptyValue struct{}
EmptyValue represents an empty record (zero fields). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.EmptyValue`.
Used by:
- Default value for COUNT(*) over an empty set (returns 0; the empty record is the unit element for COUNT).
- Insert/Update/Delete operations that don't return a row but need a Value-shaped placeholder for the planner.
- Any rewrite that produces a "no-op" Value tree.
Type is the empty RecordType (no fields, non-null).
Evaluate returns nil (no fields → nothing to evaluate).
func NewEmptyValue ¶
func NewEmptyValue() *EmptyValue
NewEmptyValue returns the canonical EmptyValue. Callers can use this or the package-level `Empty` singleton interchangeably.
func (*EmptyValue) Children ¶
func (*EmptyValue) Children() []Value
Children returns the empty slice — leaf.
type EnumType ¶
type EnumType struct {
// EnumName is the enum's type identifier — empty string for
// anonymous enums (rare in real schemas but legal).
EnumName string
// Nullable reports whether the enum column allows NULL.
Nullable bool
// Values are the declared enum members in declared order.
Values []EnumValue
}
EnumType is the Type impl for SQL ENUM columns. Mirrors Java's Enum nested type. Carries an EnumName (the enum's type identifier) plus an ordered list of EnumValues.
Two EnumType instances are Equal iff their EnumName + Nullable match AND their Values slice is element-wise equal.
func NewEnumType ¶
NewEnumType constructs an EnumType. The Values slice is defensively copied. Panics on duplicate Name OR duplicate Number within Values — both are schema-level errors per Java + protobuf.
func (*EnumType) LookupValueByName ¶
LookupValueByName returns the enum value matching name plus a found flag. Empty string returns (zero, false).
func (*EnumType) LookupValueByNumber ¶
LookupValueByNumber returns the enum value matching number plus a found flag.
type EnumValue ¶
type EnumValue struct {
// Name is the enum member's identifier.
Name string
// Number is the declared ordinal (matches protobuf semantics —
// stable across schema evolution; renames are forbidden but
// repurposing a number is a hard breaking change).
Number int32
}
EnumValue is one member of an EnumType. Mirrors Java's Enum.EnumValue — a Name + Number pair where the Number is the declared ordinal (matches the protobuf enum-value semantics).
type EuclideanDistanceRowNumberValue ¶
type EuclideanDistanceRowNumberValue struct {
WindowedValue
}
EuclideanDistanceRowNumberValue is the Euclidean-distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by Euclidean distance from a reference vector. Closer vectors receive lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.EuclideanDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Euclidean distance is sqrt(sum((a_i - b_i)^2)) — the standard L2 distance.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewEuclideanDistanceRowNumberValue ¶
func NewEuclideanDistanceRowNumberValue(partitioningValues, argumentValues []Value) *EuclideanDistanceRowNumberValue
NewEuclideanDistanceRowNumberValue constructs a Euclidean-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*EuclideanDistanceRowNumberValue) Evaluate ¶
func (*EuclideanDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*EuclideanDistanceRowNumberValue) IsIndexOnly ¶
func (*EuclideanDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*EuclideanDistanceRowNumberValue) Name ¶
func (*EuclideanDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*EuclideanDistanceRowNumberValue) Type ¶
func (*EuclideanDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*EuclideanDistanceRowNumberValue) WithChildren ¶
func (v *EuclideanDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanDistanceRowNumberValue
WithChildren returns a fresh EuclideanDistanceRowNumberValue with children re-split via SplitNewChildren.
type EuclideanSquareDistanceRowNumberValue ¶
type EuclideanSquareDistanceRowNumberValue struct {
WindowedValue
}
EuclideanSquareDistanceRowNumberValue is the squared-Euclidean- distance K-NN ROW_NUMBER() window function. Assigns unique sequential row numbers (1-based) ordered by squared Euclidean distance from a reference vector. Closer vectors receive lower numbers.
Mirrors Java's com.apple.foundationdb.record.query.plan.cascades.values.EuclideanSquareDistanceRowNumberValue — a concrete WindowedValue + IndexOnlyValue subclass.
Squared Euclidean distance is sum((a_i - b_i)^2) — same ordering as L2 without the sqrt cost, making it computationally cheaper for nearest-neighbor searches where only relative ordering matters.
This value is index-only: the row number is computed during HNSW index traversal, not from base records.
Result type: NotNullLong.
func NewEuclideanSquareDistanceRowNumberValue ¶
func NewEuclideanSquareDistanceRowNumberValue(partitioningValues, argumentValues []Value) *EuclideanSquareDistanceRowNumberValue
NewEuclideanSquareDistanceRowNumberValue constructs a squared- Euclidean-distance row number value. partitioningValues are the PARTITION BY columns; argumentValues are the distance arguments (vector field + query vector).
func (*EuclideanSquareDistanceRowNumberValue) Evaluate ¶
func (*EuclideanSquareDistanceRowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern (_row_number key). Real execution wires the HNSW search graph; the harness exposes the per-row counter for testability.
func (*EuclideanSquareDistanceRowNumberValue) IsIndexOnly ¶
func (*EuclideanSquareDistanceRowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — K-NN row numbers are computed during HNSW index traversal and cannot be reproduced from base records.
func (*EuclideanSquareDistanceRowNumberValue) Name ¶
func (*EuclideanSquareDistanceRowNumberValue) Name() string
Name returns the value name matching Java's NAME constant.
func (*EuclideanSquareDistanceRowNumberValue) Type ¶
func (*EuclideanSquareDistanceRowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated, 1-based.
func (*EuclideanSquareDistanceRowNumberValue) WithChildren ¶
func (v *EuclideanSquareDistanceRowNumberValue) WithChildren(newChildren []Value) *EuclideanSquareDistanceRowNumberValue
WithChildren returns a fresh EuclideanSquareDistanceRowNumberValue with children re-split via SplitNewChildren.
type EvaluatesTo ¶
type EvaluatesTo int
EvaluatesTo discriminates the four supported evaluations.
const ( // EvaluatesToTrue is `x IS TRUE`. EvaluatesToTrue EvaluatesTo = iota // EvaluatesToFalse is `x IS FALSE`. EvaluatesToFalse // EvaluatesToNull is `x IS NULL`. EvaluatesToNull // EvaluatesToNotNull is `x IS NOT NULL`. EvaluatesToNotNull )
type EvaluatesToValue ¶
type EvaluatesToValue struct {
Child Value
Eval EvaluatesTo
}
EvaluatesToValue tests whether a child Value's runtime evaluation matches one of four boolean-shaped predicates: IS TRUE, IS FALSE, IS NULL, IS NOT NULL. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. EvaluatesToValue`.
x IS TRUE ↔ EvaluatesToValue{Child: x, Eval: EvaluatesToTrue}
x IS NULL ↔ EvaluatesToValue{Child: x, Eval: EvaluatesToNull}
Used by:
- SQL `IS [NOT] {NULL,TRUE,FALSE}` predicates lowered to the Value layer.
- Plan rewrites that need to pattern-match on these specific truth-value shapes.
Type is always non-null boolean (these predicates have a defined result for any operand — even NULL maps to TRUE/FALSE).
func NewEvaluatesToValue ¶
func NewEvaluatesToValue(child Value, eval EvaluatesTo) *EvaluatesToValue
NewEvaluatesToValue constructs the predicate Value.
func (*EvaluatesToValue) Children ¶
func (v *EvaluatesToValue) Children() []Value
Children returns the single child.
func (*EvaluatesToValue) Evaluate ¶
func (v *EvaluatesToValue) Evaluate(evalCtx any) (any, error)
Evaluate computes the predicate.
Rules:
- x IS TRUE: true iff x evaluates to bool true; false otherwise.
- x IS FALSE: true iff x evaluates to bool false; false otherwise.
- x IS NULL: true iff x evaluates to nil; false otherwise.
- x IS NOT NULL: true iff x evaluates to non-nil; false otherwise.
Type mismatches (non-bool x with IS TRUE / IS FALSE) return false — the runtime value isn't a boolean true / false, so the predicate is false (not UNKNOWN).
func (*EvaluatesToValue) Name ¶
func (*EvaluatesToValue) Name() string
Name returns the debug-print kind.
func (*EvaluatesToValue) Type ¶
func (*EvaluatesToValue) Type() Type
Type returns NotNullBoolean — these predicates always return a definite truth value (UNKNOWN propagation is handled by the IS [NOT] {NULL,TRUE,FALSE} semantics).
type 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) Type ¶
func (*ExistsValue) Type() Type
Type returns NotNullBoolean — EXISTS always has a definite truth value.
func (*ExistsValue) WithNewChild ¶
func (v *ExistsValue) WithNewChild(c Value) *ExistsValue
WithNewChild returns a copy of this ExistsValue over a rebased/translated child. Mirrors Java's ValueWithChild.withNewChild().
type 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 ExpressionFolder ¶
ExpressionFolder is the testable surface for plan-time constant folding of standalone Values. Implementations: DefaultFolder (production — composes SimplifyValue with EvaluateConstant), and any caller-provided test fake that returns canned answers without invoking real simplification.
Why an interface, not a free function: callers like `embedded.foldConstantProjections` need to be unit-testable without constructing a real catalog + Resolver + metadata. With an injected folder, the routing logic ("did we already fold this slot? is the slice big enough?") can be exercised against a fake folder that returns whatever the test wants. Per RFC-025 §"Closing the leaks".
Contract: Fold returns (foldedValue, true) when v is a row-context- independent Value whose evaluation produces a Go-native scalar that LiteralValue can faithfully re-wrap. Returns (nil, false) on a non-foldable input — a FieldValue, a ParameterValue, an AggregateValue, or any composite containing those. Nil v returns (nil, false) — the boundary so callers don't need to nil-guard.
func DefaultFolder ¶
func DefaultFolder() ExpressionFolder
DefaultFolder returns the production ExpressionFolder. Its Fold runs SimplifyValue first (so partial folds compose: `name + (1+2)` simplifies to `name + 3` even though the result isn't constant) and then EvaluateConstant for the all-constant case. Failure modes surface as ok=false, never panic.
type Field ¶
type Field struct {
// Name is the field's identifier. Empty string is legal and
// represents an anonymous field — `RECORD<INT, STRING>` produces
// fields with Name="" but distinct Ordinals.
Name string
// FieldType is the field's type. Never nil — anonymous /
// untyped fields use UnknownType.
FieldType Type
// Ordinal is the field's position in the record (0-based). It is the
// Java *ordinal* (Type.Record.computeFieldNameToOrdinal = list position),
// NOT the protobuf fieldIndex/tag. NewRecordType normalizes Ordinal to the
// slice position, so Fields[i].Ordinal == i; ordinal resolution reads the
// slice position directly (RecordType.FieldIndexUnique) for soundness even on
// a raw RecordType. Anonymous fields share Name="" but have distinct Ordinals.
Ordinal int
}
Field is one field of a RecordType. Mirrors Java's Record.Field — name + type + ordinal. The Ordinal carries the declared position for stable ordering across maps; two Fields with the same Name but different Ordinals are NOT equal.
type FieldMintClass ¶
type FieldMintClass int
FieldMintClass is one lazy mint's bucket. These partition the mints this census sees, and the partition is checked against an independent total.
const ( // FieldMintLazyBare: a lazy Field with a plain, undotted name. The ordinary // plan-time carrier — a match candidate or an ordering hint. FieldMintLazyBare FieldMintClass = iota // FieldMintLazyDotted: a lazy Field containing '.' but no '#'. Ambiguous // between a real nested path (addr.city) and an alias-qualified leaf // (T.city), which is the ambiguity AccessorNamePath refuses to resolve. FieldMintLazyDotted // FieldMintLazyExplainRendered: a lazy Field containing BOTH '.' and '#' — // the shape explainValueOrdinals produces and nothing else does. This is the // sharp class. A name is data the planner resolves; an Explain rendering is // output. Feeding output back in as identity is a layering violation, not // merely a missing ordinal, and it is the one class whose non-zero is a // defect rather than debt. FieldMintLazyExplainRendered // FieldMintLazyEmpty: a lazy Field with no name at all. FieldMintLazyEmpty // FieldMintBaked: Resolved is non-nil, so the node carries an ordinal // identity and its Field is display only — the state the whole migration is // moving toward. Counted so the lazy classes have something to be a fraction // OF. FieldMintBaked )
func ClassifyFieldMint ¶
func ClassifyFieldMint(field string, baked bool) FieldMintClass
ClassifyFieldMint is the pure classifier, split from the counter so it can be exercised without process-global state. A classification only reachable through a mutation is a classification no test can pin.
func (FieldMintClass) String ¶
func (c FieldMintClass) String() string
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 FieldValueMintGates ¶
FieldValueMintGates are the populations this census refuses to let move silently.
MinTotal guards VACUITY, against the INDEPENDENT denominator. A ceiling of zero over zero observed mints passes perfectly while measuring nothing; that green-from-an-empty-set is the failure this repo hits most.
MaxExplainRendered is the GROWTH ceiling on FieldMintLazyExplainRendered, the one class whose non-zero is a DEFECT rather than debt: a Field carrying both '.' and '#' is the shape explainValueOrdinals emits and nothing else does, so it is Explain OUTPUT fed back in as identity. Its whole measured population — 21,865 mints, all 64 captured origins on one line — came from RecordQueryInMemorySortPlan.HintOrdering minting a lazy FieldValue from SortKey.Field while SortKey.ValueExpr held the baked identity all along. That arm is gone; the expected value is 0, and there is no floor to pair with this ceiling because zero IS the steady state here.
MaxTotal is the RETIREMENT ceiling, and it is what a corpus sets once the lazy mint is gone from the tree rather than merely quiet. It supersedes MinTotal instead of sitting beside it: the two are opposite claims about the same population and a corpus asserts one or the other. Being a ceiling it survives narrowing, which a floor cannot — and a retirement is a fact about the TREE, so it must.
The PARTITION is checked unconditionally whenever gates is non-nil: a class vector that disagrees with the independently counted total means a mint took a path no arm classified, which is a bug in this census rather than a fact about the code — and it makes every number above it unreadable. It is exact under any filter, so it needs no floor to be honest.
A nil *fieldValueMintGates is a no-op, the shape a narrowed run needs for MinTotal. The ceilings and the partition survive narrowing (a subset cannot exceed the whole, and a sum of non-negative counters is exact under any filter), so all of them are checked whenever gates is non-nil.
type FirstOrDefaultStreamingValue ¶
FirstOrDefaultStreamingValue is the streaming variant of FirstOrDefaultValue. Returns the first element produced by its streaming child Value, or the default Value if the stream is empty. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.FirstOrDefaultStreamingValue`.
The child should implement StreamingValue. RangeValue returns []int64 (not []any), so it doesn't satisfy StreamingValue and is handled by an explicit type-switch fallback in Evaluate.
func NewFirstOrDefaultStreamingValue ¶
func NewFirstOrDefaultStreamingValue(childValue, onEmpty Value) *FirstOrDefaultStreamingValue
NewFirstOrDefaultStreamingValue constructs the streaming first- or-default. The childValue should implement StreamingValue or be a *RangeValue (adapted internally).
func (*FirstOrDefaultStreamingValue) Children ¶
func (v *FirstOrDefaultStreamingValue) Children() []Value
Children returns [childValue, onEmptyResultValue].
func (*FirstOrDefaultStreamingValue) Evaluate ¶
func (v *FirstOrDefaultStreamingValue) Evaluate(evalCtx any) (any, error)
Evaluate pulls the first element from the streaming child, or returns the default value if the stream is empty.
func (*FirstOrDefaultStreamingValue) Name ¶
func (*FirstOrDefaultStreamingValue) Name() string
Name returns the SQL function name (matches FirstOrDefaultValue).
func (*FirstOrDefaultStreamingValue) Type ¶
func (v *FirstOrDefaultStreamingValue) Type() Type
Type returns the child's type. The stream element type IS the result type (we pull one element, fall back to default which must be type-compatible).
func (*FirstOrDefaultStreamingValue) WithChildren ¶
func (v *FirstOrDefaultStreamingValue) WithChildren(newChildren []Value) *FirstOrDefaultStreamingValue
WithChildren returns a fresh FirstOrDefaultStreamingValue with the given children. Caller passes exactly 2 children (childValue, onEmptyResultValue).
type FirstOrDefaultValue ¶
type FirstOrDefaultValue struct {
Array Value
Default Value
// Typ is the result type — Java's constructor sets it to the
// array element type. Defaults to UnknownType.
Typ Type
}
FirstOrDefaultValue returns the first element of an array, OR a default value if the array is empty / NULL. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. FirstOrDefaultValue`.
FIRST_OR_DEFAULT(arr, default)
↔ FirstOrDefaultValue{Array: arr, Default: default}
Used by the planner for materializing scalar subquery results where the subquery may return zero rows.
CONFORMANCE: matches Java's eval semantics:
- NULL array → NULL (the default isn't returned for NULL).
- Empty array → Default's evaluated value.
- Non-empty array → first element.
Type is the array's element type (Java's constructor enforces the array.elementType == default.type invariant; Go accepts whatever type the caller provides).
func NewFirstOrDefaultValue ¶
func NewFirstOrDefaultValue(array, defaultVal Value, resultType Type) *FirstOrDefaultValue
NewFirstOrDefaultValue constructs the operator.
func (*FirstOrDefaultValue) Children ¶
func (v *FirstOrDefaultValue) Children() []Value
Children returns [Array, Default].
func (*FirstOrDefaultValue) Evaluate ¶
func (v *FirstOrDefaultValue) Evaluate(evalCtx any) (any, error)
Evaluate returns Array[0] OR Default.Evaluate when Array is empty.
Returns nil if:
- Array is nil-Value or evaluates to nil.
- Array doesn't evaluate to a slice.
func (*FirstOrDefaultValue) Name ¶
func (*FirstOrDefaultValue) Name() string
Name returns the debug-print kind.
func (*FirstOrDefaultValue) Type ¶
func (v *FirstOrDefaultValue) Type() Type
Type returns the bound result type.
type FromOrderedBytesValue ¶
type FromOrderedBytesValue struct {
Child Value
Direction OrderedBytesDirection
TargetType Type
}
FromOrderedBytesValue decodes an ordered-bytes blob (the output of ToOrderedBytesValue) back to the original typed value. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.FromOrderedBytesValue`.
The decoder needs the encoded direction (so it knows whether to undo the DESC inversion) and the target type (so it knows what Tuple element type to extract). Java's class carries both fields.
As the inverse of ToOrderedBytesValue, this Value typically appears in covering-index / index-only access plans where the planner has rewritten a SQL projection to read the encoded form from an index entry.
func NewFromOrderedBytesValue ¶
func NewFromOrderedBytesValue(child Value, direction OrderedBytesDirection, targetType Type) *FromOrderedBytesValue
NewFromOrderedBytesValue constructs the decoder.
func (*FromOrderedBytesValue) Children ¶
func (v *FromOrderedBytesValue) Children() []Value
Children returns the single child Value.
func (*FromOrderedBytesValue) Evaluate ¶
func (*FromOrderedBytesValue) Evaluate(any) (any, error)
Evaluate is currently a placeholder — returns nil. Real eval wires tuple.UnpackOrdered (the Go equivalent of Java's TupleOrdering.unpack). Same gating as ToOrderedBytesValue.
func (*FromOrderedBytesValue) Name ¶
func (*FromOrderedBytesValue) Name() string
Name returns the SQL function name.
func (*FromOrderedBytesValue) Type ¶
func (v *FromOrderedBytesValue) Type() Type
Type returns the target type — the decoded value's natural type. Note: Java's getResultType() returns the target type made nullable, since decoding may produce NULL for the NULL-sentinel byte sequence. Go mirrors that — wraps target in nullable.
type InOpValue ¶
InOpValue is the Value-layer SQL `IN` operator: tests whether a probe value matches any element of a list of candidate values. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades. values.InOpValue`.
probe IN (a, b, c) ↔ InOpValue{Probe: probe, List: [a, b, c]}
Why a Value-layer IN in addition to the predicate-layer `ComparisonPredicate{Type: ComparisonIn}`: rules that operate at the Value tree (e.g. fold a constant probe against a constant list) need a Value-shaped node. The predicate-side path is reserved for evaluation; the Value-side path is for plan rewrites.
Java's InOpValue carries an `inListValue` Value (typically LiteralValue wrapping a list, or a ListValue node), making it possible to express IN against dynamic lists. Go accepts a generic List Value field that can be a literal []any (for static IN-lists) or any other Value that evaluates to a slice at runtime.
Evaluate semantics — Kleene 3VL:
- probe IN (NULL, ...) where probe is non-NULL: TRUE if any non-NULL element matches, otherwise UNKNOWN (NULL propagation).
- NULL IN (anything): UNKNOWN.
- Empty list: FALSE (no match possible).
Type is always nullable boolean — IN can produce NULL via Kleene propagation.
func NewInOpValue ¶
NewInOpValue constructs an InOpValue.
Either Probe or List nil produces a Value that always evaluates to nil (UNKNOWN). Defensive — callers should construct with both operands set.
func (*InOpValue) Children ¶
Children returns probe + list. Lets WalkValue traverse both operands as a standard 2-child Value.
func (*InOpValue) Evaluate ¶
Evaluate computes probe IN list with SQL three-valued semantics.
Returns:
- true if probe matches any non-NULL element of the list.
- false if probe doesn't match any list element AND the list contains no NULLs.
- nil (UNKNOWN) if probe is NULL, OR probe doesn't match a non- NULL element AND the list contains a NULL (NULL propagation).
- nil if probe or list is nil-Value, or list doesn't evaluate to a slice.
equalsAny performs numeric coercion for mixed int/float comparisons, matching Java's Comparisons.evalComparison(EQUALS).
type IncarnationValue ¶
type IncarnationValue struct{}
IncarnationValue is a LEAF Value that returns the record store's incarnation number — an integer counter the store advances whenever its versionstamp prefix is "fresh" (e.g. after a tenant move / re-key). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IncarnationValue`.
SQL-callable as `get_versionstamp_incarnation()`. The underlying purpose is to let queries detect store-incarnation changes when processing versionstamp-keyed data — two versionstamps from different incarnations are not directly comparable, so a query that joins / dedups across versionstamp boundaries uses this to scope correctness.
Result type: INT (NOT NULL — every store has an incarnation).
Per Java's contract, eval requires a non-null FDBRecordStoreBase; Go accepts an evalCtx that exposes an "incarnation" key (the row-shape harness pattern shared with VersionValue), and otherwise returns nil. FDBRecordStore.GetIncarnation() exists on the store side, but no execution path threads a store into this Value's Evaluate — it is parser / planner / fuzz-reachable without a store-bound runtime evaluator, matching the non-evaluable placeholder pattern of ObjectValue / QueriedValue / CardinalityValue.
func NewIncarnationValue ¶
func NewIncarnationValue() *IncarnationValue
NewIncarnationValue constructs the singleton-shape leaf.
IncarnationValue carries no per-instance state; every constructed instance is semantically equal. Returning a freshly allocated pointer (rather than a package-level singleton) preserves the per-call allocation contract used throughout the cascades package — callers that compare via pointer-identity won't be confused by interned reuse.
func (*IncarnationValue) Children ¶
func (*IncarnationValue) Children() []Value
Children returns the empty slice — leaf, no operands.
func (*IncarnationValue) Evaluate ¶
func (*IncarnationValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the incarnation from the evalCtx if present. Mirrors VersionValue's row-shape harness pattern: when evalCtx is a `map[string]any` the evaluator looks up the "incarnation" key.
Returns nil if:
- evalCtx is nil.
- evalCtx is not a row-shape map.
- The map has no "incarnation" key.
Real store-bound evaluation lands when execution integration surfaces FDBRecordStore.GetIncarnation() through the eval context.
func (*IncarnationValue) Name ¶
func (*IncarnationValue) Name() string
Name returns the debug-print kind, matching Java's `get_versionstamp_incarnation` SQL function name.
func (*IncarnationValue) Type ¶
func (*IncarnationValue) Type() Type
Type returns NotNullInt — every record store has a non-null incarnation (zero is a valid initial value, not absence).
type 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 ¶
func (e *IncompatibleOrderingTypeError) Error() string
type IndexEntryObjectValue ¶
type IndexEntryObjectValue struct {
IndexEntryAlias CorrelationIdentifier
Source TupleSource
OrdinalPath []int
ResultType Type
}
IndexEntryObjectValue is a LEAF Value that references a specific position inside an IndexEntry's KEY or VALUE tuple, identified by an ordinal path (the Java-side "Dewey id"). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IndexEntryObjectValue`.
Used by covering-index plans + index-only access paths: when a query can be answered directly from the index entry's key/value tuples (without fetching the underlying record), this Value extracts a specific column from those tuples by ordinal walk.
Conceptually:
IndexEntryObjectValue(alias, KEY, [0]) — first KEY column
IndexEntryObjectValue(alias, KEY, [2]) — third KEY column
IndexEntryObjectValue(alias, VALUE, [0, 1]) — second sub-field
of first VALUE column
The alias identifies WHICH index-entry binding to read in the EvaluationContext (a query may join several indexed scans, each flowing its own IndexEntry).
Constraints (matches Java's Verify.verify in the constructor):
- resultType must be primitive, enum, or UUID — IndexEntry tuples can only hold leaf-type Tuple-encodable values; structs are extracted via separate FieldValue chains, not through ordinal paths.
- Go enforces this via planner-checked precondition rather than a runtime panic — Java's Verify would crash; we surface as a no-op-ready Value that evaluates to nil if the type contract is violated.
Eval contract:
- evalCtx must be a `map[CorrelationIdentifier]any` shape with a binding for `IndexEntryAlias`. The bound value is expected to expose `PrimaryKey() / IndexValues()` (the `*recordlayer.IndexEntry` shape) — typed as `IndexEntryReader` here to keep the values package free of the recordlayer dependency.
- On lookup miss, returns nil (matches the "non-evaluable yet" pattern of placeholder Values like ObjectValue / VersionValue).
func NewIndexEntryObjectValue ¶
func NewIndexEntryObjectValue(alias CorrelationIdentifier, source TupleSource, ordinalPath []int, resultType Type) *IndexEntryObjectValue
NewIndexEntryObjectValue constructs the leaf. Caller is responsible for the resultType-primitive-or-enum-or-UUID precondition; the constructor doesn't enforce because the Type-classification helpers (IsPrimitive / IsEnum / etc.) live alongside the planner pipeline and Go defers the check to caller (matches Java's Verify.verify-vs-runtime split).
func (*IndexEntryObjectValue) Children ¶
func (*IndexEntryObjectValue) Children() []Value
Children returns the empty slice — leaf, no operands.
func (*IndexEntryObjectValue) Evaluate ¶
func (v *IndexEntryObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate walks the ordinal path through the bound IndexEntry's KEY or VALUE tuple. Returns nil if:
- evalCtx is nil.
- evalCtx is not a `map[CorrelationIdentifier]any`.
- The map has no binding for IndexEntryAlias.
- The bound value isn't an IndexEntryReader.
- The ordinal walk runs off the end of the tuple.
func (*IndexEntryObjectValue) GetCorrelatedTo ¶
func (*IndexEntryObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the empty set — IndexEntryObjectValue matches Java's getCorrelatedToWithoutChildren contract which returns Set.of() (it deliberately doesn't surface the entry alias as a correlation, because the alias is a "binding-side" reference, not a dataflow correlation).
func (*IndexEntryObjectValue) Name ¶
func (*IndexEntryObjectValue) Name() string
Name returns the debug-print kind.
func (*IndexEntryObjectValue) Type ¶
func (v *IndexEntryObjectValue) Type() Type
Type returns the bound result type.
type IndexEntryReader ¶
type IndexEntryReader interface {
// PrimaryKey returns the KEY tuple of the index entry — the
// indexed-column tuple plus the trailing primary-key columns.
PrimaryKey() any
// IndexValues returns the VALUE tuple of the index entry — the
// payload tuple (typically empty for VALUE indexes; populated
// for KeyWithValue covering-index entries).
IndexValues() any
}
IndexEntryReader is the minimal interface IndexEntryObjectValue needs to walk an FDB index entry. The Go *recordlayer.IndexEntry type satisfies this contract via its PrimaryKey + IndexValues methods. Defined here (rather than imported from recordlayer) to keep the cycle-free dependency direction values → ø.
type IndexOnly ¶
IndexOnly is the Go-side counterpart to Java's `Value.IndexOnlyValue` interface marker. Any Value whose result can ONLY be produced by an index scan (vs a streaming aggregator over the base records) implements this marker.
Used by: RowNumberValue, DistanceRowNumberValue, IndexOnlyAggregateValue.
Planner / matcher code can type-assert against this to refuse to optimise paths that would require running the value over a base- record scan — they MUST be matched against an index, otherwise the plan fails to compile.
type IndexOnlyAggregateOp ¶
type IndexOnlyAggregateOp int
IndexOnlyAggregateOp enumerates the index-only aggregate operators — aggregations that MUST be backed by an aggregate index because they can't be evaluated by a streaming aggregator at runtime. Mirrors Java's `IndexOnlyAggregateValue.PhysicalOperator` (MAX_EVER_LONG / MIN_EVER_LONG).
const ( // IndexOnlyMaxEverLong is the running-max-since-time-zero // aggregate, backed by FDB's MAX_EVER_LONG index. Returns the // largest value ever seen across all writes to the indexed // column — even if the row has since been deleted. IndexOnlyMaxEverLong IndexOnlyAggregateOp = iota // IndexOnlyMinEverLong is the corresponding MIN_EVER aggregate. IndexOnlyMinEverLong )
func (IndexOnlyAggregateOp) String ¶
func (op IndexOnlyAggregateOp) String() string
String returns the canonical operator name (matches Java's PhysicalOperator enum names).
type IndexOnlyAggregateValue ¶
type IndexOnlyAggregateValue struct {
Op IndexOnlyAggregateOp
Child Value
}
IndexOnlyAggregateValue represents a compile-time aggregation that MUST be backed by an aggregate index — it cannot be evaluated by a streaming aggregator at runtime. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IndexOnlyAggregateValue`.
Java has two abstract subclasses (MaxEverValue, MinEverValue) per operator. The Go port unifies via an Op field — same matchability pattern as DistanceRowNumberValue.
At plan time, the planner must match this Value against an aggregate index of the corresponding type (MAX_EVER_LONG / MIN_EVER_LONG). If no matching index exists, the plan fails to compile — Java throws SemanticException; Go would surface the failure at the rule level (IsIndexOnly() returns true so the planner knows to refuse to optimise without an index).
Eval is a placeholder — IndexOnlyAggregateValue is non-evaluable by definition (Java's eval throws IllegalStateException; Go's surface returns nil per the existing pattern).
Implements the IndexableAggregate interface — GetIndexTypeName returns the operator name for index lookup.
func NewIndexOnlyAggregateValue ¶
func NewIndexOnlyAggregateValue(op IndexOnlyAggregateOp, child Value) *IndexOnlyAggregateValue
NewIndexOnlyAggregateValue constructs a compile-time aggregate of the given operator over child.
func (*IndexOnlyAggregateValue) Children ¶
func (v *IndexOnlyAggregateValue) Children() []Value
Children returns the single child Value.
func (*IndexOnlyAggregateValue) Evaluate ¶
func (*IndexOnlyAggregateValue) Evaluate(any) (any, error)
Evaluate is a placeholder — Java throws IllegalStateException since this aggregate is compile-time-only. Go surfaces nil per the placeholder pattern.
func (*IndexOnlyAggregateValue) GetIndexTypeName ¶
func (v *IndexOnlyAggregateValue) GetIndexTypeName() string
GetIndexTypeName returns the FDB index-type name backing this aggregate. Implements the IndexableAggregate interface so matchers + planner rules can pick aggregates eligible for index- scan lowering.
func (*IndexOnlyAggregateValue) IsIndexOnly ¶
func (*IndexOnlyAggregateValue) IsIndexOnly() bool
IsIndexOnly returns true — this aggregate MUST be backed by an index. Planner rules consult this to refuse to optimise without a matching index.
func (*IndexOnlyAggregateValue) IsNonEvaluable ¶
func (*IndexOnlyAggregateValue) IsNonEvaluable() bool
IsNonEvaluable returns true — IndexOnlyAggregateValue is compile-time-only by definition. Implements NonEvaluable.
func (*IndexOnlyAggregateValue) Name ¶
func (v *IndexOnlyAggregateValue) Name() string
Name returns the operator's canonical name.
func (*IndexOnlyAggregateValue) Type ¶
func (v *IndexOnlyAggregateValue) Type() Type
Type returns the child's type — Java's getResultType returns child.getResultType() unchanged.
func (*IndexOnlyAggregateValue) WithChildren ¶
func (v *IndexOnlyAggregateValue) WithChildren(newChildren []Value) *IndexOnlyAggregateValue
WithChildren returns a fresh IndexOnlyAggregateValue with the new child. Op carries through unchanged.
type IndexableAggregate ¶
IndexableAggregate is the Go-side counterpart to Java's IndexableAggregateValue interface. Any Value that has an index- backed aggregate form can implement this — currently only AggregateValue (when its Op has a non-empty index-type name).
Planner / matcher code can type-assert against this interface to pick aggregates eligible for index-scan lowering:
if iav, ok := v.(IndexableAggregate); ok && iav.GetIndexTypeName() != "" {
// can lower to index-aggregate scan
}
type IndexedValue ¶
type IndexedValue struct {
ResultType Type
}
IndexedValue is a leaf placeholder representing a column value bound to an indexed-key position. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.IndexedValue`.
Used by index-pushdown rules during pattern matching: a logical FieldValue can be matched against an IndexedValue placeholder to verify that the predicate's column corresponds to an indexed position in the candidate index.
IndexedValue is a "non-evaluable" Value — it represents a position in an index key, not a computed result. Calling Evaluate panics so misuse surfaces loudly.
func NewIndexedValue ¶
func NewIndexedValue(resultType Type) *IndexedValue
NewIndexedValue constructs an IndexedValue with the given result Type. Pass UnknownType when the position's type isn't yet resolved.
func (*IndexedValue) Children ¶
func (*IndexedValue) Children() []Value
Children returns the empty slice — leaf.
type 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 is clusteredOuterOrdinalSeed, serving the // GATED MULTI-TABLE outer. InnerLegProducerClusteredOuter InnerLegProducer = iota // InnerLegProducerSingleSource is scalarSubqueryOrdinalSeed, serving the // SINGLE-SOURCE outer (clusterArity == 1). InnerLegProducerSingleSource )
func (InnerLegProducer) String ¶
func (p InnerLegProducer) String() string
type InvalidArgumentError ¶
type InvalidArgumentError struct {
Message string
}
InvalidArgumentError is returned by a scalar function when an argument is outside the function's mathematical domain — currently SQRT of a negative number. The executor converts this to SQLSTATE 22023 INVALID_PARAMETER_VALUE. Distinct from ScalarTypeMismatchError (wrong argument *type*); this is a wrong argument *value* of the right type.
func (*InvalidArgumentError) Error ¶
func (e *InvalidArgumentError) Error() string
type InvalidCastError ¶
type InvalidCastError struct {
Message string
}
InvalidCastError is returned by CastValue.Evaluate when a cast is out of range or structurally invalid (NaN→INT, overflow, etc.). The executor converts this to SQLSTATE 22F3H INVALID_CAST.
func (*InvalidCastError) Error ¶
func (e *InvalidCastError) Error() string
type LeafValue ¶
type LeafValue interface {
Value
// RebaseLeaf returns a new Value that is the same as this one but
// with correlated identifiers updated to targetAlias. Returns this
// if there are no correlated identifiers to update.
//
// Ports Java's LeafValue.rebaseLeaf(CorrelationIdentifier).
RebaseLeaf(targetAlias CorrelationIdentifier) Value
}
LeafValue is the Go counterpart of Java's LeafValue interface — a scalar value type that has no children. LeafValues participate in translation/rebasing via RebaseLeaf, which returns a new Value with correlation identifiers updated to a target alias.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.values.LeafValue.
type LegCensusChannel ¶
type LegCensusChannel int32
LegCensusChannel is the namespace a site's recorded pairs live in.
It is set by whichever Record function the site calls and is never declared in a table, because a table is exactly what went wrong: the sites were DOCUMENTED as comparing identities while their instrument recorded text, and no mechanism noticed. A site that records in both namespaces reports LegChannelMixed, which the corpus gate treats as a failure — its numbers then describe neither comparison.
const ( // LegChannelNone is a site nothing recorded at. LegChannelNone LegCensusChannel = 0 // LegChannelText is a site whose pairs are two strings, compared as text. LegChannelText LegCensusChannel = 1 // LegChannelIdentity is a site whose pairs are two CorrelationIdentifiers, // classified the way SameLeg decides. LegChannelIdentity LegCensusChannel = 2 // LegChannelMixed is a site that recorded in both — an instrument that cannot // be read. LegChannelMixed LegCensusChannel = 3 )
func (LegCensusChannel) String ¶
func (c LegCensusChannel) String() string
String names the channel for report and failure text.
type LegIdentityCensus ¶
type LegIdentityCensus struct {
// Total is every leg/correlation pair the site examined.
Total int64
// ExactEqual is the pairs whose two spellings are byte-identical — the
// population on which an exact and a folding comparison cannot disagree.
ExactEqual int64
// FoldOnlyEqual is the pairs that fold equal but are NOT equal. This is the
// conversion delta, and it is the count that must be ZERO for a
// folding-to-exact conversion to be free. A nonzero value means a leg is
// stored under one spelling and looked up under another, which is a producer
// defect: the fix belongs at whichever site normalizes, not in the
// comparison.
FoldOnlyEqual int64
// Neither is the pairs that are different legs under either comparison — the
// scan traffic every lookup pays walking to its own leg.
Neither int64
// FoldOnlySamples holds up to legIdentitySampleCap distinct "legName vs
// corrName" witnesses from the FoldOnlyEqual population, so a nonzero count
// names the offending pair instead of merely reporting a number.
FoldOnlySamples []string
// Unstated is the pairs where at least one side is the ZERO
// CorrelationIdentifier. It exists only on the identity channel: SameLeg
// declines an unstated identifier unconditionally (SameLeg(zero, zero) used to
// be true, and two omissions agreeing is how a leg bound the wrong row), so
// such a pair is neither a match nor an ordinary miss — it is a leg whose
// identity was never sourced. Counting it apart keeps ExactEqual/FoldOnlyEqual/
// Neither meaning what they say on the identity channel.
//
// The TEXT channel has no equivalent bucket: there, "" is just a string, and a
// leg with no text is skipped by its producers before the comparison.
Unstated int64
// UnstatedSamples names the offending sides, same service as the other two
// witness sets — an unstated identity is diagnosable only by which side is
// blank and what the other one was.
UnstatedSamples []string
// NeitherSamples is the same service for the Neither population, and it is
// collected at the sites where Neither is DIAGNOSTIC rather than traffic
// (LegSiteNeitherSampled). At a genuine COMPARISON site Neither is the ordinary
// scan cost every lookup pays walking to its own leg — a large, per-row
// population whose witnesses say nothing and whose sampling would put a mutex
// in the row loop. At the identity-PAIR sites the pair is two spellings of ONE
// leg, so Neither means those two spellings name different things.
//
// This exists because it was needed: retyping the nested-loop join plan's leg
// identities reported Neither = 12 over ~80k firings, and a bare 12 cannot be
// diagnosed. That site is sampled for exactly that reason even though its
// Neither is NOT asserted to be zero — the diagnosis is the point, and the site
// whose number motivated the sampler was the one site the first form of it
// skipped. The rule: a site whose pair is two spellings of one leg names its
// witnesses, whether or not its zero is enforced.
NeitherSamples []string
// RetiredVerdictDivergent is the pairs on which the predicate the site USED TO
// evaluate disagrees with the identity predicate it evaluates NOW. It is the
// conversion delta measured DIRECTLY, and it is the only population that
// answers the question the conversion actually raises.
//
// The three zeros above do not answer it, and reasoning from them is what let a
// converted reader be reported clean. FoldOnlyEqual catches a match that became
// a decline only when the retired predicate was exact-on-text; two of these
// sites upper-FOLDED one side, so their retired predicate could match a pair
// this one declines for a reason no fold-only count sees. And a DECLINE that
// became a MATCH is invisible to every one of them — a leg whose identity is a
// lowercase machine mint matches itself exactly while the retired
// upper-folding predicate rejected it, and that pair lands in ExactEqual,
// indistinguishable from a pair both predicates accepted.
//
// Zero here means the conversion is representation-only ON THIS CORPUS, which
// is the claim the migration makes. A nonzero value names a shape whose row
// binding changed and must be justified as a FIX with a test, not measured
// away.
RetiredVerdictDivergent int64
// RetiredVerdictSamples names the divergent pairs, in the form
// "leg vs corr (retired=match|decline)", so a nonzero count says which
// direction flipped as well as where.
RetiredVerdictSamples []string
// Channel is which namespace the site recorded in — see LegCensusChannel. It
// is observed, not declared, so a site whose instrument drifts away from its
// comparison is reported instead of believed.
Channel LegCensusChannel
}
LegIdentityCensus is one site's comparison population.
func LegIdentityCensusOf ¶
func LegIdentityCensusOf(site LegIdentitySite) LegIdentityCensus
LegIdentityCensusOf returns a site's counts.
The absolute totals are a LOWER BOUND unless the census ran alone: these counters are package-scoped, so a sibling test planning or executing the same corpus in parallel contributes to them. The assertion the census exists to support is a ZERO (FoldOnlyEqual), and a zero over a sum of non-negative terms is exact however many extra passes contribute — a concurrent pass can only make it FAIL, never falsely pass. Reset before a pass and isolate that pass if the totals themselves are the artifact needed.
type LegIdentityExpectations ¶
type LegIdentityExpectations struct {
// Floors is the population each site must report over the UNFILTERED corpus.
// Dropped under a -test.run filter, which is why it cannot carry a zero: a
// guard that vanishes under narrowing cannot watch a revival.
Floors map[LegIdentitySite]int64
// DeclaredEmpty names sites this corpus MEASURED at zero although their
// recorders still stand, mapped to why. A DISPLACED reader is the case: the
// code is reachable in principle and this suite no longer routes through it.
//
// Checked in the STALE direction — a declared site reporting traffic FAILS,
// so the declaration cannot outlive the condition that made it honest. The
// check runs under a filter too, and safely: a narrowed run is a SUBSET, so
// it cannot exceed a population the whole suite measured at zero.
DeclaredEmpty map[LegIdentitySite]string
// Retired names sites whose recorder has NO production caller at all, mapped
// to why. Unlike DeclaredEmpty this is a fact about the TREE, so its failure
// text tells the reader that something came back rather than that a corpus
// moved.
Retired map[LegIdentitySite]string
}
LegIdentityExpectations is what one CORPUS expects of the census. It exists because a site can sit at zero for three different reasons and they need three different guards — a floor watches for COLLAPSE, and once zero is the steady state the alarm INVERTS to growth.
type LegIdentitySite ¶
type LegIdentitySite int
LegIdentitySite identifies one leg-identity comparison site.
const ( // LegSiteRowLegsBinder is the RUNTIME leg binder // (executor.rowLegsBinder.GetCorrelationBinding): it resolves a correlation // to its window within a merged row's own Type.Legs. Compares EXACTLY today. LegSiteRowLegsBinder LegIdentitySite = iota // LegSiteBuriedLegWindow is executor.buriedLegWindow: the sub-window of a // buried leg inside a clustered box span. Compares EXACTLY today. LegSiteBuriedLegWindow // LegSiteTextVsIdentity is not a comparison site but the DIVERGENCE census // between a leg's two spellings: its recorded pair is (RecordTypeLeg.Name, the // same leg's Alias.Name()), sampled at every reader that walks a leg. // // This is the count that decides whether retyping the readers from Name to // Alias is a behaviour change at all. Name and Alias are recorded // independently by the producers — several of which normalize one and not the // other (a window map keyed by an UPPER fold whose window carries the raw // correlation; a select whose sourceAliases entry need not match its // quantifier's alias) — so their agreement is an empirical fact, not a // structural one. Its zero is what makes the conversion representation-only // and the plan-shape golden untouched. // // It also subsumes the re-mint at executor.spansFromMergedLegs, which used to // manufacture a fresh identifier from the leg's text: that re-mint is exactly // the operation whose result this compares against the identity the producer // actually chose. LegSiteTextVsIdentity // LegSiteLeftOuterExistential is cascades.hoistLegRefsOntoMergedRow's drift // check: a leg absent from the derived windows but present in the merged // type's Legs is a LOUD failure. It compares through SameLeg (EXACT), and the // recorded pair is that comparison's own: the leg's identity against the // reference correlation's. Its retired predicate folded the reference before // comparing it to the leg's text, which is why the verdict rather than the pair // is what says whether the conversion moved this tripwire. // // Its absolute totals are a planning-time artifact, not a corpus fact: the // hoist runs inside a Cascades rule, so the memo may fire it once or many // times for the same query depending on exploration order. Only the RATIOS // (foldOnly == 0) carry meaning across runs. LegSiteLeftOuterExistential // LegSiteFinalizeSeedWindows is values.finalizeSeedWindows' buried-sub-window // derivation: "is this buried leg the box run's rightmost leaf?", decided // through SameLeg on the leaf's identity against the box window's. // // It was the last site held back from the conversion, on a justification that // was measured to be false: the two identifiers were said to be "legitimately // different — box quantifier vs leaf", when the sourceBinding convention is // exactly that for the rightmost leaf they are the SAME identifier. The red // that was cited as proof came from a test fixture hand-minting the box // correlation lowercase where the unnest/mixed producer mints it upper-folded. // Measured over the real-FDB corpus, the identity and text comparisons decide // identically on all 1311 pairs. The premise now has deterministic pins rather // than resting on a count, ONE PER PRODUCER of a box correlation: // TestBoxCorrelationIsItsRightmostLeafIdentity for the unnest/mixed mint (the // two identifiers agree, so the comparison MATCHES the rightmost leaf) and // TestBoxBoxBindingDeclinesAndStillFilesTheLeaf for the pristine gated-join // mint (legBinding's "$BOX" suffix makes them differ by design, so BOTH the // identity comparison and the retired text one decline, and the leaf // sub-window is filed beside the box run rather than replacing it). // // The map KEYS remain upper-FOLDED text — readers still arrive holding a string // — so this one site holds both namespaces at once, deliberately. LegSiteFinalizeSeedWindows // LegSiteSelectOutputLegs is the translator's expressionOutputLegs, recorded at // the PRODUCER rather than at a reader. // // It is the one site whose two spellings come from genuinely independent // sources — the leg's identity from its quantifier, its text from the select's // parallel sourceAliases slice — so nothing downstream guarantees they agree. // Recording it here rather than trusting a reader to walk these legs is what // keeps the text-vs-identity zero from resting on an unmeasured producer. LegSiteSelectOutputLegs // LegSiteNLJPlanAlias is the materialized nested-loop join's own leg // identifiers, recorded at the PLANNER where the plan is constructed. // // The plan used to hold these as strings, and the executor minted an // identifier from each at the plan boundary — so the leg identities on the // whole merge path were manufactured downstream of the quantifier that owned // them. They are threaded from the select's quantifiers now, and this site // records the substitution: the pair is the SOURCE-ALIAS text the plan used to // carry against the quantifier identifier it carries instead. // // The substitution is NOT purely representational, and the measurement is why // we know: over the FDB corpus the two disagree on 12 of ~80k firings (the 12 is // stable across runs, the denominator is not -- 79040 / 79960 / 80856 measured), and the // disagreement is total rather than a case variant — witnesses "q$N vs E". In // those the select's source-alias slice carries a RE-MINTED identifier while its // quantifier still carries the user alias, so the slice is the stale one and the // quantifier is the authority. The old pairing was internally inconsistent // there: the seed's QOVs were minted as ToUpper(alias) while the plan's leg // identity kept the raw alias, so a lowercase q$N became Q$N in the seed and // q$N in the plan, and values.SameLeg — exact — then bound neither. // TestReconstructFoldStep1Seed_CarriesTheThreadedIdentityVerbatim pins that. // // So the zero this site asserts is FoldOnlyEqual, not Neither. Fold-only is the // forgery population: a case-ONLY difference means one spelling is an upper fold // of the other, which is precisely how ToUpper manufactured a Q$N that could // forge a minted q$N leg. A wholly different name is a stale source alias, which // threading the quantifier is the fix for. LegSiteNLJPlanAlias // LegSiteOrdinalSlotInLegWindow is the translator's ordinalSlotInLegWindow: it // resolves a qualified column to its slot WITHIN the named leg's window, and its // decline is what keeps a qualified `B.ID` from flat-first-matching A's // same-named slot. Its counterparty is a correlation, so it compares through // SameLeg like every other Group-A reader; it used to compare the leg's text // against the UPPER fold of that correlation. // // This is the site where the instrument's blindness had consequences. Its census // recorded (leg text, correlation text) while its comparison evaluated the two // identities, so a minted leg read by its own UPPER Name scored an exact MATCH // in the census and a DECLINE in the code. Measured with the pair the comparison // actually evaluates, the real-FDB corpus reports 0 divergences over 105 // comparisons; the only such pairs anywhere are the deliberate negative controls // in the translator package's own fixture, where the decline is the assertion. LegSiteOrdinalSlotInLegWindow )
func LegIdentitySites ¶
func LegIdentitySites() []LegIdentitySite
LegIdentitySites returns every site, so a census pass can iterate without hard-coding the set.
func (LegIdentitySite) String ¶
func (s LegIdentitySite) String() string
String names the site for test failure messages.
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 )
type LegacyMapScalarFunction ¶
type LegacyMapScalarFunction uint8
LegacyMapScalarFunction is the compatibility evaluator operation used for INFORMATION_SCHEMA map filtering. Its deliberately smaller surface is catalogued beside the main Cascades capabilities, while the compatibility evaluator retains its distinct argument, carrier, and SQLSTATE semantics.
const ( LegacyMapScalarFunctionCoalesce LegacyMapScalarFunction LegacyMapScalarFunctionGreatest LegacyMapScalarFunctionLeast LegacyMapScalarFunctionYear LegacyMapScalarFunctionMonth LegacyMapScalarFunctionDay LegacyMapScalarFunctionHour LegacyMapScalarFunctionMinute LegacyMapScalarFunctionSecond LegacyMapScalarFunctionDayOfMonth LegacyMapScalarFunctionDayOfWeek LegacyMapScalarFunctionDayOfYear )
func LookupLegacyMapScalarFunction ¶
func LookupLegacyMapScalarFunction(name string) (LegacyMapScalarFunction, bool)
LookupLegacyMapScalarFunction returns the operation admitted by the legacy INFORMATION_SCHEMA map evaluator without widening that evaluator's surface.
type LikeOperatorValue ¶
LikeOperatorValue is the Value-layer SQL `LIKE` operator: tests whether a string value matches a SQL LIKE pattern. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. LikeOperatorValue`.
probe LIKE 'abc%' ↔ LikeOperatorValue{Probe: probe, Pattern: 'abc%'}
Why a Value-layer LIKE in addition to the predicate-layer ComparisonLike: rules that operate on the Value tree (e.g. fold a constant probe against a constant pattern, or extract a prefix for index-pushdown) need a Value-shaped node.
SQL LIKE wildcards:
- `%` matches zero or more characters
- `_` matches exactly one character
- other characters match literally
Delegates to the canonical LikeMatch helper (shared with the QueryPredicate-layer ComparisonLike). The matcher is pinned by FuzzLikeMatch / FuzzLikeMatchEscape against a Java-semantics regex oracle; the spec is Java's `PatternForLikeValue.eval` (PatternForLikeValue.java:96-117) + `LikeOperatorValue.likeOperation` (LikeOperatorValue.java:93-99).
Note: this Value-level LIKE carries no ESCAPE (escape rune = 0). ESCAPE support lives on the predicate layer (Comparison.Escape, predicates/comparisons.go) and in the shared LikeMatch helper — add the field here only if a Value-level ESCAPE consumer appears.
STRUCTURAL divergence from Java, asserted rather than silent: Java's tree is `LikeOperatorValue(src, PatternForLikeValue(pat, esc))` — the pattern child mints a REGEX string which likeOperation then regex-compiles. Go's tree keeps the RAW SQL pattern as the child and evaluates it with values.LikeMatch, which implements the composed mint+find semantics directly (the cross-check test proves the equivalence). Feeding a PatternForLikeValue child here would hand a regex string to the SQL-pattern matcher and silently return wrong rows, so Evaluate rejects that shape with an explicit error — an asserted bridge, never a silent fallback. If a Java-shaped plan import ever needs to evaluate that composition, unwrap the PatternForLikeValue and lower its raw pattern + escape instead.
Evaluate semantics — Kleene 3VL:
- non-NULL probe + non-NULL pattern: true if pattern matches, false otherwise.
- NULL probe OR NULL pattern: nil (UNKNOWN).
- Non-string probe: nil (type-degraded).
Type is always nullable boolean.
func NewLikeOperatorValue ¶
func NewLikeOperatorValue(probe, pattern Value) *LikeOperatorValue
NewLikeOperatorValue constructs the LIKE Value.
func (*LikeOperatorValue) Children ¶
func (v *LikeOperatorValue) Children() []Value
Children returns probe + pattern.
func (*LikeOperatorValue) Evaluate ¶
func (v *LikeOperatorValue) Evaluate(evalCtx any) (any, error)
Evaluate computes probe LIKE pattern.
func (*LikeOperatorValue) Name ¶
func (*LikeOperatorValue) Name() string
Name returns the debug-print kind.
func (*LikeOperatorValue) Type ¶
func (*LikeOperatorValue) Type() Type
Type is always nullable boolean (NULL propagation).
type NameSplitClass ¶
type NameSplitClass int
NameSplitClass is one call's bucket. The three partition every call.
const ( // NameSplitSegmented: the parser's segment triple decided this node's // qualification. No rendered name was sliced. NameSplitSegmented NameSplitClass = iota // NameSplitQualified: a dot was found in a rendered name and the bytes // before it became a qualifier. THE DEBT POPULATION — the only bucket in // which a quoted `"A.B"` and a qualified `A.B` are the same input. NameSplitQualified // NameSplitBare: the fallback ran and found no dot, so no qualifier was // manufactured. Not debt; counted so a clean arm is distinguishable from a // dark one. NameSplitBare )
func (NameSplitClass) String ¶
func (c NameSplitClass) String() string
type NameSplitFloors ¶
type NameSplitFloors struct {
// Calls is the minimum total calls (all three classes) per site.
Calls [nameSplitSiteCount]int
// Split is the minimum SPLIT population (splitBare + SPLIT-QUALIFIED) per
// site — the calls that actually entered a splitting arm, as opposed to the
// segmented calls that decided without one.
//
// It is a separate floor from Calls because at legQOVSegmentsOf the two
// diverge completely: 9 calls, 0 of them splits. A healthy Calls total there
// says the SEGMENTED arm is being reached and says nothing whatever about
// the arms this census's hard zero is a zero over.
//
// A ZERO ENTRY IS A DECLARATION, NOT AN ABSENT FLOOR, and it is checked as
// one: a site declared 0 whose split population is now non-zero FAILS, so
// the "watched, not proven" label cannot silently outlive the condition that
// made it honest. Declaring 0 means "this site's split arms are measured
// empty over this corpus, they are covered by a unit wiring pin instead, and
// the day the corpus starts driving them somebody re-reads this line."
Split [nameSplitSiteCount]int
}
NameSplitFloors is the minimum population each site must report, so that a site going DARK is a failure rather than a clean-looking zero.
type NameSplitSite ¶
type NameSplitSite int
NameSplitSite is one of the TWO LEG BAKERS' arms that can still recover a qualifier by slicing a rendered name. It is not an enumeration of every such site in Go — the dark siblings named in this file's header are outside this census's scope and outside its zeros.
const ( // NameSplitSiteLegQOVSegmentsOf is query.bakeDottedRefsToLegQOVWithRef's // segmentsOf: the root node consults the carrier's parse-tree triple when it // is Present, and every other node — and every root whose carrier states // nothing — falls back to the slice. // // This baker is where a misread is most consequential: unlike the flat baker // it has no exact-name precedence to resolve a quoted spelling first, so the // split is the FIRST thing it does. NameSplitSiteLegQOVSegmentsOf NameSplitSite = iota // NameSplitSiteFlatColumnBake is query.bakeFlatRefsAgainstColumns' dotted // arm, reached only after the exact-name first-match over the output columns // has already failed. Its segmented counterpart is bakeSegmentedColumnRef, // which is a different function rather than a branch here — so this site // reports segmented 0 by construction, and that zero is structural, not a // finding. NameSplitSiteFlatColumnBake )
func (NameSplitSite) String ¶
func (s NameSplitSite) String() string
type NonEvaluable ¶
NonEvaluable is the Go-side counterpart to Java's `Value.NonEvaluableValue` interface marker. Any Value that can't be evaluated at runtime (plan-time-only placeholders like AggregateValue, IndexOnlyAggregateValue) implements this marker.
Planner / matcher code can type-assert against this to refuse to pass non-evaluable Values to runtime evaluators.
Java's NonEvaluableValue is a true marker interface (no methods); the Go equivalent uses one method whose presence (and the implied `true` return) IS the marker.
type 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).
type NullValue ¶
type NullValue struct {
Typ Type // type NULL was cast to; UnknownType when unconstrained
}
NullValue is the SQL NULL literal — evaluates to nil regardless of context. Not collapsed into ConstantValue{Value: nil} because having a dedicated type lets rule matchers check for NULL specifically (without also matching `Value: nil` ConstantValues that happen to represent a NULL literal in a non-type-annotated way).
func NewNullValue ¶
NewNullValue constructs a NullValue of the given type.
type ObjectValue ¶
type ObjectValue struct {
Alias CorrelationIdentifier
ResultType Type
}
ObjectValue is a generic typed-object placeholder bound to a CorrelationIdentifier. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ObjectValue`.
Used by Java to represent "any object" in expression contexts — generic counterpart to QuantifiedObjectValue (which specifically represents a Quantifier's flowed object). ObjectValue is more general: used in non-quantifier contexts where the planner needs a typed placeholder bound to a specific alias.
Type is whatever the planner determined at capture time.
Non-evaluable: ObjectValue is a placeholder; specialized evaluation paths (quantifier dereferencing, etc.) handle it before reaching the per-row Eval contract. Evaluate returns nil to make the no-row-eval contract explicit.
func NewObjectValue ¶
func NewObjectValue(alias CorrelationIdentifier, resultType Type) *ObjectValue
NewObjectValue constructs a typed object placeholder bound to the given alias.
func (*ObjectValue) Children ¶
func (*ObjectValue) Children() []Value
Children returns the empty slice — leaf.
func (*ObjectValue) Evaluate ¶
func (*ObjectValue) Evaluate(any) (any, error)
Evaluate returns nil — ObjectValue is a placeholder. Specialized evaluation paths handle it before reaching per-row Eval.
func (*ObjectValue) GetCorrelatedTo ¶
func (v *ObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the singleton set containing the bound alias.
type OfTypeValue ¶
OfTypeValue is a runtime type guard: tests whether a child Value's runtime evaluation matches an expected Type. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.OfTypeValue`.
OfTypeValue{Child: x, ExpectedType: int} ↔ "is x a runtime int?"
Used by:
- Type-aware rule rewrites that want to gate transformations on a runtime-type assertion (e.g. an arithmetic rule that only fires when both operands are numeric at evaluation time).
- The planner's PartialMatch infrastructure (Java) — type guards factor into match-candidate compatibility checks.
Evaluate semantics:
- Returns true if the child's evaluated value matches ExpectedType.
- Returns nil (UNKNOWN) if the child evaluates to nil — NULL is compatible with any nullable type but Go conservatively reports UNKNOWN; extend the rule if nullable / non-nullable semantics ever matter to a consumer.
- Returns false otherwise.
Type is always nullable boolean (Kleene-3VL guarded).
The implementation is a Type-code match (TypeCodeBoolean == TypeCodeBoolean). It deliberately does NOT walk RecordType / ArrayType structurally — no consumer compares structured types here; extend the match if one appears.
func NewOfTypeValue ¶
func NewOfTypeValue(child Value, expectedType Type) *OfTypeValue
NewOfTypeValue constructs the type-guard Value.
func (*OfTypeValue) Children ¶
func (v *OfTypeValue) Children() []Value
Children returns the single child Value.
func (*OfTypeValue) Evaluate ¶
func (v *OfTypeValue) Evaluate(evalCtx any) (any, error)
Evaluate checks the child's runtime value against ExpectedType via TypeCode match. Returns nil if either operand is nil-shaped.
Go compares only TypeCodes — TypeCodeBoolean matches a runtime bool, TypeCodeLong matches a runtime int64, etc. Field- level structural comparison (e.g. RecordType field-set match) is not implemented; extend if a consumer compares structured types.
CONFORMANCE: matches Java's OfTypeValue.eval semantics:
- NULL probe → returns ExpectedType.IsNullable().
- Primitive-to-primitive: STRICT TypeCode match (Java's `type.nullable().equals(expectedType.nullable())` reduces to a TypeCode comparison since nullability is normalised on both sides).
Verified against Java's OfTypeValueTest: `OfType(42 (int), LONG)` returns FALSE in Java even though INT is promotable to LONG in other contexts. Go matches this strict primitive behavior.
Two Java branches NOT replicated (Go has no consumer that feeds this Value proto messages or non-primitive promotions):
- DynamicMessage probe → returns `expectedType.isRecord()`.
- Non-primitive cross-type promotion via PromoteValue. resolvePhysicalOperator (only triggers for non-primitive sources — records, arrays).
type OrderedBytesDirection ¶
type OrderedBytesDirection int
OrderedBytesDirection enumerates the four ordering modes Java's `TupleOrdering.Direction` supports — combinations of (ASC|DESC) × (NULLS_FIRST|NULLS_LAST). Mirrors Java's enum verbatim so plan hashes / explain output diff cleanly across language boundaries.
const ( // OrderedBytesAscNullsFirst sorts ascending; NULL sorts BEFORE // any non-null value (lowest). OrderedBytesAscNullsFirst OrderedBytesDirection = iota // OrderedBytesAscNullsLast sorts ascending; NULL sorts AFTER any // non-null value (highest). OrderedBytesAscNullsLast // OrderedBytesDescNullsFirst sorts descending; NULL sorts BEFORE // (which becomes "highest" under DESC, since the iteration is // reversed). OrderedBytesDescNullsFirst // OrderedBytesDescNullsLast sorts descending; NULL sorts AFTER. OrderedBytesDescNullsLast )
func (OrderedBytesDirection) IsAscending ¶
func (d OrderedBytesDirection) IsAscending() bool
IsAscending reports whether the direction encodes an ASC ordering. Used by ordering-property analysis to determine whether the produced bytes preserve or invert the underlying value's natural ordering.
func (OrderedBytesDirection) String ¶
func (d OrderedBytesDirection) String() string
String renders the direction for explain / debug print.
type 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
}
FieldPath is the multi-accessor path — Java's FieldValue.FieldPath (FieldValue.java:373): ONE FieldValue node holds a whole path, never chained nodes. IMMUTABLE after construction (replace-never-mutate): FieldValue copy sites share the pointer; WithSuffix returns a NEW path (Java :525-534). Single-accessor paths come from the resolver's construction binds and the seed machinery; multi-accessor paths are produced by the baked compose rule (fusing an inner path with an outer suffix). INVARIANT: a FieldPath carried by a FieldValue is NON-EMPTY — a zero-step path reads nothing and is not a meaningful accessor (Java's FieldPath.EMPTY exists only for prefix arithmetic Go doesn't port). Both constructors (newFieldPathOfSingle, WithSuffix) uphold it; Root()/Last() panic on a hand-built violation rather than tolerating it. 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 ¶
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 ¶
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 used to be minted from the map KEY instead — NamedCorrelationIdentifier of
// the upper-folded alias — with the QOV's correlation in scope at both
// construction sites. That kept Name == Alias.Name() trivially true, but by
// making the identity a function of the text rather than the other way round:
// 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 now this same identifier, so Alias is no longer one of two
// namespaces held apart — it is the only one. Every keyed reader was measured
// first, by a census built to answer exactly that question and retired with it:
// over the real-FDB corpus all 1400 lookups had a correlation in hand and the
// identity selected the same window the fold did, on every one; the two readers
// that had only text were unreachable by panic probe across the whole
// relational tree. That is a DATED POINT MEASUREMENT of a namespace that no
// longer exists, not a live claim.
//
// What stands in its place is the seed-window READER census
// (seed_window_reader_census.go), a STANDING instrument: it floors each of the
// five keyed readers so one going dark reds instead of printing a clean-looking
// zero, and it hard-zeros the two DECLINE classes that replaced the text
// lookups. The conversion's own evidence is history; the readers' continued
// exercise is checked on every suite run.
//
// What the key change buys is not tidiness. A text key merges 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 were one key while being two legs.
// SameLeg exists to refuse exactly that, and the map used to undo it.
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 ¶
ParameterBinder is an optional eval-context capability: when ParameterValue.Evaluate is called with a context that implements this interface, the parameter is resolved to its bound value. Otherwise Evaluate returns nil (SQL UNKNOWN), which is the safe default for plan-time evaluation where no bindings exist.
type ParameterObjectValue ¶
ParameterObjectValue represents a plan-cache parameter binding — a named placeholder whose value is supplied at execution time via the EvaluationContext. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ParameterObjectValue`.
Key fields:
- ParameterName: the parameter name (Java: parameterAlias stored as a string, not a CorrelationIdentifier).
- ResultType: the declared Type of the parameter.
Evaluate returns the parameter's value from the eval context's ParameterBinder capability, or nil when no binding exists.
Not correlated: ParameterObjectValue's getCorrelatedToWithoutChildren() returns the empty set in Java — parameter names are NOT CorrelationIdentifiers. The parameter's runtime value is resolved from the EvaluationContext, not from a quantifier binding.
func NewParameterObjectValue ¶
func NewParameterObjectValue(parameterName string, resultType Type) *ParameterObjectValue
NewParameterObjectValue constructs a ParameterObjectValue.
func (*ParameterObjectValue) Children ¶
func (*ParameterObjectValue) Children() []Value
Children returns the empty slice — leaf.
func (*ParameterObjectValue) Evaluate ¶
func (v *ParameterObjectValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the parameter's value from the eval context's ParameterBinder capability. Returns nil when the context doesn't implement ParameterBinder or when no binding exists.
Mirrors Java's ParameterObjectValue.eval which calls context.getBinding(parameterName).
func (*ParameterObjectValue) GetCorrelatedTo ¶
func (*ParameterObjectValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
GetCorrelatedTo returns the empty set — parameter names are NOT CorrelationIdentifiers. Matches Java's ParameterObjectValue.getCorrelatedToWithoutChildren() returning ImmutableSet.of().
func (*ParameterObjectValue) Name ¶
func (*ParameterObjectValue) Name() string
Name returns the debug-print kind.
func (*ParameterObjectValue) RebaseLeaf ¶
func (v *ParameterObjectValue) RebaseLeaf(_ CorrelationIdentifier) Value
RebaseLeaf returns this unchanged — ParameterObjectValue has no correlation to rebase. Mirrors Java's ParameterObjectValue.rebaseLeaf returning `this`.
func (*ParameterObjectValue) Type ¶
func (v *ParameterObjectValue) Type() Type
Type returns the declared result type. Parameter bindings can be NULL, so the result is forced to nullable.
type ParameterValue ¶
type ParameterValue struct {
Ordinal int // 1-based positional index; 0 ⇒ named parameter
ParamName string // populated when Ordinal == 0
Typ Type // UnknownType until upstream type inference fills it
}
ParameterValue is a placeholder for a prepared-statement parameter — `?` (positional, Ordinal>=1) or `:name` (named, Ordinal=0). Its concrete value is unknown at plan time, so Evaluate returns nil unless the eval context implements ParameterBinder. Treated as non-constant by IsConstantValue, so constant-fold rules decline to fire on `x = ?` / `x = :foo`.
Plan-cache keying: ExplainValue renders a parameter as `?N` / `:name`, which means `WHERE x = ?` and `WHERE x = ?` for two different bind-values share the same Explain string — the seam a future plan cache will key on.
Runtime evaluation goes through the ParameterBinder interface: an evalCtx that implements it (RowEvalContext.Binder) resolves the binding by ordinal/name; without a binder the value degrades to NULL — acceptable only for plan-time / explain-time evaluation.
func NewNamedParameterValue ¶
func NewNamedParameterValue(name string) *ParameterValue
NewNamedParameterValue constructs a named `:name` parameter.
func NewParameterValue ¶
func NewParameterValue(ordinal int) *ParameterValue
NewParameterValue constructs a positional `?` parameter (1-based).
func (*ParameterValue) Children ¶
func (*ParameterValue) Children() []Value
func (*ParameterValue) Name ¶
func (*ParameterValue) Name() string
func (*ParameterValue) Type ¶
func (p *ParameterValue) Type() Type
Type returns the parameter's rich Type. Parameter bindings can be NULL so the result is forced to nullable regardless of how the caller stored Typ.
type PatternForLikeValue ¶
PatternForLikeValue is the SQL `patternForLike(pattern, escape)` function — converts a SQL LIKE pattern (with `%` / `_` wildcards and an optional escape char) to a regex-form string, wrapped in `^...$`. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.PatternForLikeValue`.
This Value is part of Java's LIKE-operator surface: Java's `LikeOperatorValue.eval` consumes the regex string produced here via `java.util.regex.Pattern`. Our Go LikeOperatorValue does NOT consume the regex — it routes through the canonical `values.LikeMatch` matcher, which works DIRECTLY on the SQL pattern with `%` / `_` (no regex involvement). PatternForLikeValue is therefore a planner-side surface only in Go: SQL queries that reference `patternForLike(...)` lower to this Value, but the produced regex string isn't consumed by any Go runtime path.
We still port it because:
- It's a SQL-callable function that may appear in user queries (Java's grammar exposes `patternForLike` as a builtin).
- Plan-level equivalence with Java requires the same Value tree shape — even when the actual eval path differs.
- Direct Java → Go SQL plan ports won't fail with "unknown function" when this surface is reached.
Result type: NotNullString (the regex form is always a string).
Eval contract (matches Java):
- patternChild evaluates to a string. If NULL, eval returns NULL.
- escapeChild evaluates to a string OR NULL.
- NULL → standard transformation (no escape).
- exactly 1 UTF-16 code unit → escape-aware transformation (escape+`_` → literal `_`, escape+`%` → literal `%`). Java checks `escapeChar.length() == 1` (PatternForLikeValue.java:109), which counts UTF-16 units: any single BMP rune (<= U+FFFF) passes, an astral rune is TWO units and fails.
- other length → returns nil (Java throws SemanticException; Go defers to evaluator-side reporting). Documented as a planner-checked precondition.
The produced regex is JAVA-regex-shaped, for Java's evaluation semantics: `LikeOperatorValue.likeOperation` (LikeOperatorValue.java:93-99) compiles it with NO flags and runs `.find()`, so its `.` rejects Java's five line-terminator code points (`\n`, `\r`, U+0085, U+2028, U+2029 — MORE than Go regexp's default, which only excludes `\n`) and its default-mode `$` tolerates one final line terminator. Do NOT feed this string to Go `regexp` and expect Java's answer; `values.LikeMatch` implements the composed Java semantics directly, and TestLikeMatch_CrossCheckSQLPatternToRegex proves the two agree.
func NewPatternForLikeValue ¶
func NewPatternForLikeValue(pattern, escape Value) *PatternForLikeValue
NewPatternForLikeValue constructs the value with required pattern and optional escape children.
func (*PatternForLikeValue) Children ¶
func (v *PatternForLikeValue) Children() []Value
Children returns [pattern, escape].
func (*PatternForLikeValue) Evaluate ¶
func (v *PatternForLikeValue) Evaluate(evalCtx any) (any, error)
Evaluate produces the regex-form string with `^...$` anchors. Returns nil if the pattern is NULL or the escape is malformed.
func (*PatternForLikeValue) Name ¶
func (*PatternForLikeValue) Name() string
Name returns the SQL function name.
func (*PatternForLikeValue) Type ¶
func (*PatternForLikeValue) Type() Type
Type returns NotNullString.
type PickValue ¶
type PickValue struct {
Selector Value
Alternatives []Value
// Typ is the result type — Java resolves from alternative types.
// Defaults to UnknownType.
Typ Type
}
PickValue picks one of N alternative Values based on an integer selector. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.PickValue`.
PickValue{Selector: 1, Alternatives: [a, b, c]}.Evaluate(ctx)
↔ Alternatives[1].Evaluate(ctx) = b.Evaluate(ctx)
Used by the planner for case-style branching where the selector is computed at runtime (e.g. switching between alternative projection shapes based on row context).
CONFORMANCE: matches Java's eval — Selector evaluates to an integer; alternatives[selector] is then evaluated. NULL selector → NULL. Out-of-bounds selector returns nil (defensive; Java would throw IndexOutOfBoundsException — Go swallows for the row-eval contract).
Type is the bound result type (Java's constructor resolves it from the alternatives' types — promotion lattice merge).
func NewPickValue ¶
NewPickValue constructs the picker with selector + alternatives + result Type.
func (*PickValue) Children ¶
Children returns [Selector, alt0, alt1, ...].
Position-stable: nil entries are PRESERVED in the output (not filtered) so that the index returned by Selector.Evaluate stays aligned with the index into the children list. Filtering nils would silently shift later alternatives toward earlier positions — Evaluate would then index into a wrong slot. The caller's nil-handling lives in Evaluate (a nil-resolved alternative returns nil rather than dereferencing).
PickValue intentionally does NOT have a WithChildren method — the simplification driver doesn't rebuild PickValues. If a future caller needs to rewrite PickValue's children, the rebuild must use indexed assignment (NOT a fresh constructor over Children()) since Selector + Alternatives are position-coupled.
type PrimitiveType ¶
PrimitiveType is the Type impl for scalar types (INT, BOOLEAN, STRING, …). Two PrimitiveType values are Equal iff their Code + Nullable match.
func NewPrimitiveType ¶
func NewPrimitiveType(code TypeCode, nullable bool) *PrimitiveType
NewPrimitiveType constructs a PrimitiveType. Panics if code is a structured code (RECORD / ARRAY / ENUM / RELATION) — those have dedicated constructors (NewRecordType / NewArrayType / NewEnumType / NewRelationType). UNKNOWN / ANY / NONE / NULL are accepted because they're frequently useful as placeholder Types even though they're not "primitive" per IsPrimitive's sense.
func (*PrimitiveType) Equals ¶
func (p *PrimitiveType) Equals(other Type) bool
Equals implements Type. Structural — Code + Nullable.
func (*PrimitiveType) IsNullable ¶
func (p *PrimitiveType) IsNullable() bool
IsNullable implements Type.
func (*PrimitiveType) String ¶
func (p *PrimitiveType) String() string
String implements Type. Renders as "INT NOT NULL", "STRING NULL", …
type 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 ¶
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 (*PromoteValue) Children ¶
func (p *PromoteValue) Children() []Value
Children returns the single child as a one-element slice.
func (*PromoteValue) Evaluate ¶
func (p *PromoteValue) Evaluate(evalCtx any) (any, error)
Evaluate applies numeric width conversion and STRING → UUID (Java's PromoteValue.STRING_TO_UUID, `UUID.fromString`): a UUID column has no native proto/SQL primitive, so `uuid_col = '<uuid>'` arrives as a STRING comparand. Promoting it to UUID here parses the canonical string into a neutral 16-byte value ([16]byte, matching Java's java.util.UUID — no `tuple` import so `values` stays wire-agnostic). The scan-range packer turns that [16]byte into a `tuple.UUID` at the FDB wire boundary, so the equality probe hits the 0x30 index entry instead of packing a 0x02 string that never matches.
func (*PromoteValue) Type ¶
func (p *PromoteValue) Type() Type
Type returns the promotion target. Nullability is inherited from the child — promoting a NOT NULL value preserves NOT NULL.
type 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
type QualifierRecoveryClass ¶
type QualifierRecoveryClass int
QualifierRecoveryClass is one decision's bucket. The six partition every call.
const ( // QualRecCarried: a structured identity decided. No rendered name was sliced. QualRecCarried QualifierRecoveryClass = iota // QualRecAgreed: a qualifier was manufactured from text AND a structured // identity in hand agrees with it. THE CONVERSION-READY POPULATION. QualRecAgreed // QualRecDiverged: manufactured from text, identity in hand DISAGREES. A live // misread — asserted ZERO. QualRecDiverged // QualRecManufactured: manufactured from text with NO counterparty. THE HARD // DEBT — not convertible by a local edit. QualRecManufactured // QualRecLeafOnly: a dot was found, the leaf taken, the qualifier DISCARDED // because an ordinal or identity decides the read. Not debt. QualRecLeafOnly // QualRecBare: the split ran, no dot, nothing manufactured. QualRecBare // QualRecHeuristicDecline: a dot WAS found and the split was declined — but // by a HEURISTIC OVER THE RENDERING rather than by any structured fact. The // only instance is isPlainQualifiedColumnReference's rejection on `()`, // which reads a rendered aggregate/function label out of a string by looking // for parentheses in it. // // It is its own class and not folded into BARE, because the two are opposite // findings: bare means the site was handed a name with no qualifier in it, // while this means the site WAS handed a dotted name, had to decide whether // the dot was a qualifier boundary, and decided by inspecting punctuation. A // census that reported those together would show the site's riskiest // population as its cleanest. // // Structurally zero at the other five sites — none of them carries a // rendering heuristic — and that zero is construction, not a finding. QualRecHeuristicDecline )
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.
func (QualifierRecoveryClass) String ¶
func (c QualifierRecoveryClass) String() string
type QualifierRecoveryExpectations ¶
type QualifierRecoveryExpectations struct {
// Floors is the per-site population this corpus must report, or nil under a
// -test.run filter that makes the population meaningless.
Floors *QualifierRecoveryFloors
// AllowedDiverged is every DIVERGED witness this corpus's own test FIXTURES
// deliberately drive, per site.
//
// A corpus of SQL cannot need this: every one of its splits comes from a
// production producer, so any disagreement there is a defect and the zero is
// a bare zero. A corpus that calls package-private recorders with hand-built
// fixtures DOES need it — the fixtures that prove the DIVERGED bucket is
// REACHABLE necessarily fill it, and without them the census's one asserted
// zero would be a zero nothing had ever shown could be non-zero.
//
// The check is per-witness rather than a count tolerance, so a real
// divergence at a new spelling cannot hide inside a budget. The residual is
// stated rather than smoothed: a real divergence spelled EXACTLY like one of
// these is absorbed, because the witness set dedups by spelling — which is
// why the entries are listed individually with the fixture that drives each.
AllowedDiverged map[QualifierRecoverySite]map[string]struct{}
// RetiredSplit names the sites whose SPLITTING ARM IS GONE — not measured
// empty over this corpus, but structurally unreachable — so the alarm at them
// has INVERTED from collapse to REVIVAL: any split call is the arm coming
// back, and it fails.
//
// This is deliberately NOT the Floors.Split zero declaration, which says
// "measured empty here, covered by a unit pin instead". Two differences, and
// both matter:
//
// - A declaration is a statement about THIS CORPUS. A retirement is a
// statement about the TREE, so it holds over any population — including
// the empty one a -test.run filter leaves behind. Floors are dropped under
// a filter because a population floor describes the unfiltered suite; a
// retirement must not be, because skipping it is the one direction that
// fails open.
// - The failure text differs, and the text is the whole value of a stale
// guard: a declaration says "raise this floor", a retirement says "the arm
// you deleted is back".
//
// A site listed here is exempt from the Floors.Split zero-declaration check,
// so the two guards report the same event once, with the right words.
RetiredSplit [qualRecSiteCount]bool
}
QualifierRecoveryExpectations is what one CORPUS expects of the census. Two harnesses drive this instrument and they expect different things, so the expectations are a parameter rather than a constant.
type QualifierRecoveryFloors ¶
type QualifierRecoveryFloors struct {
// Calls is the minimum total calls (all six classes) per site.
Calls [qualRecSiteCount]int
// Split is the minimum SPLIT population per site — the calls that actually
// entered a splitting arm (AGREED + DIVERGED + MANUFACTURED + LEAF-ONLY +
// BARE), as opposed to CARRIED calls that decided without one.
//
// Separate from Calls because at a site whose carried channel does the work
// the two diverge completely: a healthy Calls total says the CARRIED arm is
// reached and says nothing whatever about the arms this census's zeros are
// zeros over.
//
// A ZERO ENTRY IS A DECLARATION, NOT AN ABSENT FLOOR, and it is CHECKED IN
// THE STALE DIRECTION: a site declared 0 whose split population is now
// NON-zero FAILS. The "watched, not proven" label cannot silently outlive the
// condition that made it honest. Declaring 0 means "this site's split arms
// are measured empty over this corpus, they are covered by a unit wiring pin
// instead, and the day the corpus starts driving them somebody re-reads this
// line."
Split [qualRecSiteCount]int
}
QualifierRecoveryFloors is the minimum population each site must report, so a site going DARK fails rather than reading as a clean zero.
type QualifierRecoverySite ¶
type QualifierRecoverySite int
QualifierRecoverySite is one of the four dark splitters named in 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 is query.recursiveRemapValues' dotted arm // (cascades_translator.go). STRICTLY THE WORST OF THE FOUR: it does not // manufacture a qualifier STRING to look up in a leg table, it manufactures // a CorrelationIdentifier directly out of the bytes before the FIRST dot and // hands it to a QuantifiedObjectValue. A misread here does not fail to // resolve — it resolves against a correlation that does not exist. // // Its own header already admits the break: the lazy dotted Field "spells // both the qualified B.ID and a QUOTED identifier containing a dot in the // same string". QualRecSiteRecursiveRemap QualifierRecoverySite = iota // QualRecSiteExistsSortSplit is query.splitQualifier (cascades_translator.go), // the EXISTS fold's LAST-dot split, recorded at its two callers // (sortKeySourceValue, resolveKeyName). Its own doc concedes the deeper // case: `A.B.C` is treated as qualifier `A.B`, column `C`. QualRecSiteExistsSortSplit // QualRecSiteDerivedUnnestSource is query.classifyDerivedUnnestArray's split // of the unnest body's source column (derived_unnest.go), whose manufactured // qualifier is compared against the base scan's alias/table name. QualRecSiteDerivedUnnestSource // QualRecSiteProjScopeClassify is embedded.classifyProjFieldValue // (logical_predicate.go): inner- vs outer-scoping of a projection field. The // parseColRef call is in the ELSE of a QuantifiedObjectValue check, so its // CARRIED class is that QOV branch and its split arm runs only where no // correlation was carried. QualRecSiteProjScopeClassify // QualRecSiteProjQualVsScan is embedded's projected-column qualifier check // (cascades_generator.go): a manufactured qualifier matched against the // scan's name/alias, raising ErrCodeUndefinedColumn on a mismatch. This one // decides an ERROR, which is the sharpest consequence in the family. QualRecSiteProjQualVsScan // QualRecSiteDisplayLabelStrip is embedded's display-label strip // (cascades_generator.go), guarded by the PARENTHESIS HEURISTIC in // isPlainQualifiedColumnReference — which rejects on `()` because // "parentheses identify the rendered aggregate/function label at issue". // That is a heuristic over a RENDERING, not a parse, and it is the reason // this site is counted even though both provenance and structured alias // source are now carried: it still splits the rendered internal datum key to // obtain the leaf, and the census verifies that rendering agrees with the // frozen source rather than whichever physical carrier now owns the Value. QualRecSiteDisplayLabelStrip )
func QualifierRecoverySites ¶
func QualifierRecoverySites() []QualifierRecoverySite
QualifierRecoverySites returns every site, for callers that walk them.
func (QualifierRecoverySite) String ¶
func (s QualifierRecoverySite) String() string
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 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 ¶
QueriedValue is a leaf placeholder representing the FROM-clause row context (the "what's been queried"). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.QueriedValue`.
Used by the planner during semantic resolution: a SELECT * projection lowers to QueriedValue + RecordConstructor over the queried record types' fields. The Value is non-evaluable — specialized planner rewrites resolve it to concrete Field / QuantifiedObject values before reaching the row-eval layer.
Go accepts an optional record-type-name list and a result Type. Both are advisory; the actual type comes from the queried record store's metadata at execution time.
func NewQueriedValue ¶
func NewQueriedValue(recordTypes []string, resultType Type) *QueriedValue
NewQueriedValue constructs the placeholder.
func (*QueriedValue) Children ¶
func (*QueriedValue) Children() []Value
Children returns the empty slice — leaf.
type RangeValue ¶
RangeValue is the SQL range(begin, end, step) table-valued function — produces a stream of LONG values from `beginInclusive` (default 0) up to but not including `endExclusive`, stepped by `step` (default 1). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RangeValue`.
Java's class is a STREAMING value (`StreamingValue` + `CreatesDynamicTypesValue`) — its primary eval path is `evalAsStream` which returns a `RecordCursor<QueryResult>`. The scalar `eval` method throws because per-row evaluation makes no sense for a table-function. Go mirrors this: Evaluate returns nil per the placeholder pattern, and a separate EvaluateAsStream method materialises the finite range as `[]int64` for testability.
Result type: a 1-column record with LONG-valued column "ID" — the row shape Java's currentRangeValue produces. Go exposes the element type (NotNullLong) directly via Type since record-typed returns are awkward without StreamingValue / record-type sub-shape support; consumers that care about the row shape can wrap in a RecordConstructorValue.
Cardinality is statically known when begin/end/step all evaluate to constants — useful for the cost model to estimate. Go exposes Cardinality() with the same `floorDiv(end-begin, step)` formula Java uses.
func NewRangeValue ¶
func NewRangeValue(begin, end, step Value) *RangeValue
NewRangeValue constructs a RangeValue. All three children are REQUIRED (Java's grammar lets begin and step default to 0 and 1 respectively, but those defaults are added at the parser level — the constructed Value carries explicit children).
func (*RangeValue) Cardinality ¶
func (r *RangeValue) Cardinality() (int64, bool)
Cardinality returns the static row count if all three children are constant-foldable to int64, else returns (-1, false).
Mirrors Java's getCardinalities — used by the cost model when the planner has a RangeValue table function in scope and wants to size operators above it.
func (*RangeValue) Children ¶
func (r *RangeValue) Children() []Value
Children returns [begin, end, step] in source order (matches Java's withChildren list ordering).
func (*RangeValue) Evaluate ¶
func (*RangeValue) Evaluate(any) (any, error)
Evaluate is a placeholder — RangeValue is a streaming Value; per-row eval makes no sense. Java throws IllegalStateException; Go surfaces nil per the existing placeholder pattern.
Use EvaluateAsStream for the materialised range expansion.
func (*RangeValue) EvaluateAsStream ¶
func (r *RangeValue) EvaluateAsStream(evalCtx any) []int64
EvaluateAsStream materialises the finite range as a slice of int64 elements: [begin, begin+step, begin+2*step, ...) up to but excluding `end`. Returns nil if any of the children evaluate to non-int64, or if the range is degenerate (step <= 0 with positive direction, etc.).
Real Java RangeValue produces a streaming RecordCursor — the finite materialisation here is for tests + cost-model cardinality estimation. Production execution would route through a streaming integration (gated on StreamingValue port).
func (*RangeValue) Type ¶
func (*RangeValue) Type() Type
Type returns NotNullLong — the element type of the produced range.
Note: Java's getResultType() returns Type.Record (a 1-column record with LONG-valued "ID"). Go exposes the element type directly because record-typed Type wrappers without proper StreamingValue support would force the seed to introduce the streaming infrastructure piecemeal. Wrapping in a RecordConstructorValue at the call site is the canonical way to produce the record-shaped row.
type RankValue ¶
type RankValue struct {
WindowedValue
}
RankValue is the SQL RANK() window function — assigns 1-based rank within each partition, sharing rank across ORDER BY ties (and skipping ranks accordingly: 1, 1, 3, 4, 4, 6). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RankValue`.
RANK has NO operand arguments — Java's grammar is `RANK() OVER (PARTITION BY ... ORDER BY ...)`; the windowing happens via the surrounding window definition. ArgumentValues is always empty (Java's constructor takes them but RANK's BuiltIn passes empty argumentValues at parse time).
Result type: NotNullLong. RANK over an empty partition still produces 1 for the first row; never NULL.
Eval: window-aware. Go accepts a row-shape evalCtx of
map[string]any{"_rank": int64(N)}
— the test harness pattern. Real execution wires a streaming-window accumulator that increments rank counters per partition; Go exposes the current rank via this side channel so window-tagged Values are testable without the full streaming framework.
func NewRankValue ¶
NewRankValue constructs a RANK() value with the given partitioning columns. Java's constructor takes (partitioning, argument) — RANK passes empty argumentValues. We expose only the partitioning parameter to match RANK()'s actual SQL surface.
func (*RankValue) Evaluate ¶
Evaluate returns the current rank from the row-shape harness pattern. The harness supplies the window-accumulator's current rank via the `_rank` key; in a real execution the rank is computed by the streaming window operator.
Returns nil if evalCtx is nil / non-map / has no `_rank` key — matches the placeholder-Value pattern used elsewhere in the package.
func (*RankValue) WithChildren ¶
WithChildren returns a new RankValue with the given children re-split via WindowedValue.SplitNewChildren. Java's withChildren reconstructs the partition+argument lists by position.
Per Java's RANK semantics, argument values should remain empty after withChildren — the partitioning columns are the only children RANK actually carries.
type RecordConstructorField ¶
RecordConstructorField pairs a field name with the Value that computes its contents. Named so the output has a struct shape downstream consumers (projections, aggregations) can address by name.
type RecordConstructorValue ¶
type RecordConstructorValue struct {
Fields []RecordConstructorField
// 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 appending a numeric suffix (_2, _3, ...) to later occurrences, matching SQL semantics where `SELECT a, a FROM T` produces columns a, a_2.
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. This is not a fallback for plan values — every constructor in a plan is stamped by FinalizePlan before the plan is cached. 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 type with no message form (MessageDescriptorFor returns *ProtoTypeError) also stays here rather than failing the query.
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 ¶
func (*RecordConstructorValue) Name() string
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
// 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.
//
// "Equals/Hash ignore it" is what this line used to say, and HASH NAMED
// NOTHING: there is no Hash method on RecordType, on Type, or anywhere in
// this file. A reader verifying the claim would have found no such method and
// moved on, which is the most durable way for an unchecked claim to read as
// checked. The channels the memo ACTUALLY keys a record type on are
// 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 — and the two
// memo sites that genuinely dispatch into Equals, 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 Name + Nullable match AND their Fields slice is element-wise equal (same length, each Field equals at the same index).
Anonymous records (no name) are common — `RECORD<INT, STRING>` produces a RecordType with Name="" and the corresponding Fields. Named records carry a schema-level table or struct name.
func NewRecordType ¶
func NewRecordType(name string, nullable bool, fields []Field) *RecordType
NewRecordType constructs a RecordType. The Fields slice is defensively copied; callers' modifications to their input slice won't affect the constructed type.
Panics on duplicate field names within Fields (anonymous fields with Name="" are exempt — they're disambiguated by Ordinal). Java errors at the same point with SemanticException; Go panics so callers get an immediate stack trace.
func OrdinalSeedLegWindows ¶
func OrdinalSeedLegWindows(rc *RecordConstructorValue) (map[CorrelationIdentifier]OrdinalSeedLegWindow, *RecordType)
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 (*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) 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 says whether this leg is a flat RUN of Width columns starting at
// Start, or a single NESTED slot at Start holding the leg's whole row.
//
// It is carried on the leg and not only on the seed window because the layout
// crosses two carriers: the planner's rebase authority reads
// OrdinalSeedLegWindow, and the executor's runtime binders read this table off
// the merged row type. A discriminator on one of the two is a discriminator
// the other has to infer.
//
// Excluded from identity exactly as the RecordType.Legs table that holds it
// already is — pinned by
// executor.TestLegColumnOwner_TheLegTableReachesNoMemoIdentity, over every
// channel the memo actually keys a record type on.
Kind LegKind
// Alias is the leg's IDENTITY: the CorrelationIdentifier of the quantifier
// whose row occupies [Start, Start+Width). It is the field every consumer
// asking "does this correlation name this leg?" must compare, through
// SameLeg — so that question has exactly one answer, arrived at the same way
// Java arrives at it (CorrelationIdentifier.equals is Objects.equals on the
// raw id; Java never case-folds an alias anywhere, and its runtime binding is
// keyed by the identifier object, not by text).
//
// It is SOURCED at construction, never re-minted from Name downstream: a
// re-mint is how a leg acquires a second spelling, and a second spelling is how
// a lookup silently binds the wrong row's slots.
//
// The producers split into two kinds, and the split is the honest statement of
// where this migration stands. Most CARRY the identifier: the executor's merges
// and rebases, the planner's leg-concat walk, the seed-window authority, and the
// translator's select-leg producer all thread the identifier their own
// quantifier or QuantifiedObjectValue already holds. A few MINT it at a
// documented TEXT BOUNDARY, because at those points no identifier exists to
// thread:
//
// - the logical layer's buried-leg bounds (query.buriedLegBounds) records its
// source's binding as a STRING. There is no quantifier to thread and the
// absence is STRUCTURAL, not an omission: a buried non-rightmost leaf of a
// clustered box has no quantifier at all — the box carries ONE, named by its
// rightmost leaf (the sourceBinding convention, stated at
// query.bakeLegType.bakeCorr). Only the seed rebake (CQ-53) creates
// per-leaf quantifiers, and that is what removes this mint;
// - the translator's whole-row leg (wholeRowLegFor) is reached holding a
// select-level layout KEY, also a string. Here a quantifier IS nearby, and
// threading it would be WRONG: these legs are consumed only by the
// DOTTED-text arm, whose counterparty is a qualifier parsed out of a column
// name, so a threaded correlation would be an identity no reader compares —
// and if that quantifier is a machine mint, it would make Name and Alias
// disagree on a leg whose readers still work in text. It retires with the
// dotted channel, not before it.
//
// Both mint from the only spelling that exists and set Name to that same string,
// so neither can make the two channels disagree. That is not merely local to
// each producer: both spellings come from sourceAlias/sourceBinding, which
// upper-fold at a single chokepoint, and the seed-window authority's own
// identities are correlations minted from that same fold. Measured, the
// text-vs-identity census reports Name == Alias.Name() on EVERY leg any reader
// walks over the real-FDB sqldriver corpus — divergences zero, which is the
// claim that matters and the one that does not depend on the population.
//
// The POPULATION is a dated point measurement and is deliberately given as a
// range: three full-suite runs on 2026-08-06 reported 39169, 39889 and
// 35029 — a spread of roughly 14%, on an unchanged tree. It is not stable
// run to run and must not be quoted as a fixed number: the memo may explore
// a rule once or many times for one query depending on exploration order,
// and this site is sampled inside readers that rules drive. Quote the RANGE
// or quote nothing; a single sample from this site has been wrong every time
// anyone has written one down. (This line previously read "every one of the 3320 legs",
// a single sample from a much smaller corpus, stated as if it were a
// standing fact; it was an order of magnitude low and nothing caught it,
// because prose carrying a number carries no instrument.)
//
// The STANDING instrument is LegSiteTextVsIdentity in leg_identity_census.go,
// asserted every full sqldriver run: its divergence counters are held at zero
// unconditionally, and its population is floored (not pinned) in
// legIdentityFloors so that COLLAPSE fails while drift does not.
Alias CorrelationIdentifier
// Name is the leg's binding as TEXT, conventionally UPPER.
//
// It is NOT the identity — Alias is. TWO readers still decide with it, and
// naming exactly those two is what makes this field's retirement a checkable
// condition rather than an aspiration. Both are DOTTED-TEXT readers: the
// qualifier reaches them as text — sliced out of a column-name string
// ("A.ID"), or carried as a parse-tree segment — so there is no correlation
// on the reader's side to key an identity lookup WITH. Neither converts by
// rewriting its comparison:
//
// - executor.rowSlotForLegColumn's dotted arm (`EqualFold(leg.Name, qual)`
// in executor/ordinal_join.go). MEASURED ZERO over the real-FDB sqldriver
// corpus, and this line is corrected rather than annotated because it is
// the third distinct number it has carried. It said "FOUR times" while
// listing THREE witnesses; it was corrected to "TWICE ... `C.CV` and
// `I.QTY`"; both are now stale. The producer that reached the arm was
// closed by RFC-212 §11.3's `unqualifiedScalarTitle`
// (scalar_subquery_seed.go:205-214), so nothing drives it today and the
// standing assertion in executor's leg-column provenance census
// (leg_column_provenance_census.go:552-564) now holds the arm at a HARD
// ZERO — with the alarm direction stated there as GROWTH, since a count
// means the producer came back.
//
// THE LESSON THIS LINE KEEPS RE-TEACHING: a prose number carries no
// instrument, so it rots silently while the assertion two files over
// stays correct. Read the census, not this sentence. The arm's SAFETY
// does not rest on the zero anyway — a flat exact match runs first and
// wins, and a manufactured qualifier naming no leg declines with no
// leaf-only fallback, both pinned by unit tests in the executor package.
// The READER is blocked at its PRODUCER, not at
// the comparison: the qualifier is split out of a column name a producer
// PACKED, and those producers are CQ-53's booked mints (the join rule's
// `corr + "." + field` and the translator's merged-QOV twin). They delete
// outright when the FlatMap inner binder gets Java's parent-chained
// per-alias bindings, and this reader retires with them — producer-first.
// - query.legWindowSlot, the translator's flat leg-window lookup (serving
// both bakeFlatRefsAgainstColumns' re-split arm and the segment-carrying
// caller). The dotted-leg qualifier census measures 102 calls over the
// same corpus: 98 matched a leg whose stated Alias IS the qualifier, 4
// matched nothing, and neither blocking class (MATCH-ALIAS-DIFFERS,
// MATCH-NO-ALIAS) appeared. (Dated point measurement, 2026-08-06, STABLE
// across two consecutive full-suite runs; was 106/98/8. The standing
// instrument is values.AssertDottedLegQualifierCensus, which asserts the
// two blocking classes at zero — that assertion, not the call count, is
// the retirement condition.) CQ-52 converted this reader's COUNTERPARTY —
// a qualifier now arrives as a parse-tree segment instead of a slice of a
// rendered name — and that fixes a different defect: it decides
// QUALIFICATION correctly (a quoted `"A.B"` is one leaf, not a reference
// to leg A), but a segment is still text. Its re-split arm survives the
// conversion for carriers that state no segments at all — including one
// class that structurally cannot; the open question about those is
// stated at the arm itself.
//
// The SEED-WINDOW map's KEYS were a third reader of this field and are GONE. That
// map is keyed by CorrelationIdentifier; finalizeSeedWindows files a
// sub-window under the buried leg's own identity and carries its Name as a
// LABEL for the merged leg table rather than as the address of anything. The
// conversion was measured first, per lookup, over the whole corpus — a DATED
// POINT MEASUREMENT, quoted as history: 1400 keyed reads, every one holding a
// correlation, the identity selecting the same window the fold did on every
// one, and the only two text-keyed readers unreachable by panic probe across
// the entire relational tree. The census that produced it retired with the
// namespace it measured; the STANDING instrument over those readers is
// seed_window_reader_census.go, which floors each one and hard-zeros the two
// declines that replaced the text lookups.
//
// Two further uses are not decisions and gate nothing. finalizeSeedWindows
// SKIPS a leg whose Name is empty — a test for the absence of a string, which
// selects no leg and resolves no reference — and CARRIES the Name into the
// merged leg table as that leg's display label. A label is what the dotted
// readers above match against; it is not itself a match.
//
// Every reader whose counterparty is a correlation goes through Alias — there
// are no exceptions left.
//
// CQ-52 HAS LANDED AND THIS FIELD SURVIVED IT. The contract this block used
// to state — "when the dotted channel's counterparty carries the parser's
// segments, those three readers go and this field goes with them" — was wrong
// in both halves. It counted FOUR consumers, but one was
// bakeDottedRefsToLegQOV's SINGLE-ForEach arm, since deleted as unreached,
// and another was that baker's MULTI-ForEach arm, which reads its own
// per-leg layout map and has never read this field. And segments alone were
// never sufficient: they decide whether a reference is qualified, not which
// quantifier the qualifier names.
//
// So the condition, restated against what is actually left: CQ-53's binder
// deletes the executor reader's producer; legWindowSlot converts when the
// resolver hands the baker the correlation it already held at mint time,
// rather than a segment; and this field goes when the last of the two does.
// Until then, a new comparison against Name is a regression, full stop.
//
// BOTH READERS SURVIVE, re-measured 2026-08-06 and STABLE across two
// consecutive full-suite runs, and the two are blocked for DIFFERENT reasons
// — which is why neither can be retired by finishing the other:
//
// - The EXECUTOR reader is blocked at its PRODUCER, and the producer is
// blocked on an executor widening. Its mint is the unnest-merge path's
// `leg + "." + col` (query.rebaseUnnestOuterLegPredicate). That mint
// cannot re-anchor by ordinal in isolation: it holds no layout parameter,
// and every one of its surviving call sites reaches it over a merged row
// built with qualified `LEG.COL` keys — so a positional bake against it
// strands. Three of the five sit in an explicit `!seedWindowed` /
// `!ordinalSeed` else-branch; the other two apply no seed test at all
// (one is the else of the chained-unnest check, one the plain non-chained
// merge), which makes them the name-keyed rebase's only domain rather
// than an unconverted arm of a seed decision. The ordinal twin
// already exists and is already selected wherever a windowed seed makes
// it correct. Making those seeds ordinal is a scope gate coupled to the
// executor's below-FOD hoist, the same binding-namespace widening the
// bare-untyped-QOV residue needs. The NLJ path is a structural template
// for the shape, not an exercised precedent: its ordinal re-anchor arm
// measures ZERO over the whole real-FDB corpus (the leg-local bake census
// reports its MergedReAnchor partition vacuous), so "as the NLJ path
// already does" describes code that does not run.
// - The TRANSLATOR reader (legWindowSlot) is blocked at the COMPARISON, not
// at its counterparty. The counterparty conversion has already happened
// for every parsed channel; a segment is still text, and this reader
// holds no CorrelationIdentifier to key an identity lookup with. One of
// its two key kinds names a TABLE rather than a quantifier
// (matchViaTableName, measured 1), so the map cannot be re-keyed by
// identity even in principle.
//
// The SPLIT population these bakers sit on is now instrumented
// (name_split_census.go) and reads SPLIT-QUALIFIED 0 at both arms over 11
// calls. Scope that to the TWO LEG BAKERS: the census's own header names four
// uninstrumented splitting siblings, so this is not a statement about
// re-splitting in Go. Within that scope it closes the question of whether a
// qualifier is still being MANUFACTURED from a rendered name at the bakers
// these two readers sit behind — it is not — without touching either
// blocker above, because manufacturing a qualifier and matching one against
// Name are different steps and only the first was ever a text-channel defect.
//
// Consumers whose counterparty is a correlation must use Alias. A comparison
// against Name is a text match dressed as an identity check, and text
// matching is what folds the deliberately case-DISJOINT alias namespaces
// together (user correlations are upper-folded at the semantic scope's
// registration chokepoint; UniqueCorrelationIdentifier mints the machine
// counter lowercase, so a quoted "q$5" must not be able to forge a
// planner-minted q$5 — see SameLeg).
Name string
Start int // its first slot within the carrying type
// Width is the leg's SLOT COUNT in the carrying type — not its column count,
// which is what this line used to say.
//
// The correction matters because every consumer already computes Start+Width
// as a slot RANGE into the carrying type's Fields (flat_map_cursor.go,
// executor/ordinal_join.go in three places, executor.go's concatLegPositionals,
// merged_leg_binding_census.go, the planner's leg-concat walk). For a
// LegKindFlatRun leg the two readings coincide and the old wording was
// harmless. For a LegKindNested leg they diverge: it occupies exactly ONE
// slot, so Width is 1 while the leg may have any number of columns, and every
// one of those range computations stays in-bounds and truthful only under the
// slot reading.
//
// The leg's COLUMN count is not lost. It is
// len(Fields[Start].FieldType.(*RecordType).Fields), and the seed window's Typ
// carries it directly. A consumer that wants the leg's columns must go through
// the type; under the kind discriminator each of them declines a nested leg
// rather than iterating it flat.
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 constructs a leg boundary: the quantifier identified by `alias` owns slots [start, start+width) of the carrying type's flat concat, `kind` says whether that range is a flat run of columns or a single slot holding the leg's whole row, and `name` is that binding's text for the dotted channel.
It exists to make the IDENTITY and the KIND unforgettable. A composite literal lets a producer state Name and omit Alias, and the result is not a compile error but a leg whose identity is the zero CorrelationIdentifier — which every reader then fails to bind, silently for a frontier-pinned reference (see executor.buriedLegWindow's comment for the per-reference-kind disposition). That is not hypothetical: deleting `Alias:` from two producers left the whole suite green.
The kind is here for exactly the same reason and it is the newer half of the argument: an omitted kind is LegKindUnset, and a producer that omits it is a producer that never decided. Both are POSITIONAL parameters so that omitting either is a compile error rather than a silent zero — that, and not the literal index, is what the parameter list buys.
A docscheck AST scan (TestRecordTypeLegIsConstructed) keeps the composite literal from coming back in non-test production code.
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 returns NotNullLong — the record-type discriminator is always present on a valid record.
type RegularTranslationMap ¶
type RegularTranslationMap struct {
// contains filtered or unexported fields
}
RegularTranslationMap is the immutable map-backed implementation (RegularTranslationMap.java:42-140). Build via NewTranslationMapBuilder.
func (*RegularTranslationMap) ApplyTranslationFunction ¶
func (t *RegularTranslationMap) ApplyTranslationFunction(sourceAlias CorrelationIdentifier, leafValue Value) Value
func (*RegularTranslationMap) ContainsSourceAlias ¶
func (t *RegularTranslationMap) ContainsSourceAlias(alias CorrelationIdentifier) bool
func (*RegularTranslationMap) DefinesOnlyIdentities ¶
func (t *RegularTranslationMap) DefinesOnlyIdentities() bool
type RelationType ¶
type RelationType struct {
// InnerType is the row type. nil for erased relations.
InnerType Type
}
RelationType is the type of a stream of rows — typically the result of SELECT, the materialised value of a CTE, or the type of a subquery. Mirrors Java's `Type.Relation`.
Always non-nullable: a relation is always defined as a stream of rows, even if that stream happens to be empty. NULL relations don't exist in the type system. WithNullability(true) on a RelationType panics.
InnerType is the type of each row in the stream — typically a RecordType. nil InnerType means "erased" — Java treats this as "the inner type was once known but has been intentionally dropped" (e.g. when crossing an API boundary that doesn't preserve it). Two erased relations compare equal regardless of what their inner types USED to be.
func NewRelationType ¶
func NewRelationType(inner Type) *RelationType
NewRelationType constructs a RelationType with the given inner row type. nil inner is allowed and produces an erased relation.
func (*RelationType) Code ¶
func (*RelationType) Code() TypeCode
Code implements Type — always TypeCodeRelation.
func (*RelationType) Equals ¶
func (r *RelationType) Equals(other Type) bool
Equals implements Type. Two RelationTypes are equal iff their inner types are structurally equal (or both erased).
func (*RelationType) IsErased ¶
func (r *RelationType) IsErased() bool
IsErased reports whether the relation has no concrete inner row type. Mirrors Java's Type.Erasable.isErased().
func (*RelationType) IsNullable ¶
func (*RelationType) IsNullable() bool
IsNullable implements Type — always false. RELATION is never nullable per Java's contract.
func (*RelationType) String ¶
func (r *RelationType) String() string
String implements Type. Renders as `RELATION<inner>` for typed relations and `RELATION<?>` for erased ones.
type 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 (e *ResolutionError) Code() ResolutionErrorCode
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 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) 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 RowNumberHighOrderValue ¶
RowNumberHighOrderValue is a partially-applied ROW_NUMBER() window function — a curried form that carries the optional HNSW configuration parameters (EfSearch + IsReturningVectors) ahead of the actual partition + argument values. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RowNumberHighOrderValue`.
Usage flow (matches Java's higher-order resolution):
- Parser encounters `ROW_NUMBER(ef_search: 100)` — this constructs a RowNumberHighOrderValue with the configuration baked in, but no partition or argument values yet.
- Higher-order Apply receives the partition + argument values (typically the OVER clause's PARTITION BY + ORDER BY columns).
- Apply produces a fully-configured RowNumberValue with all four pieces (partition, argument, ef_search, is_returning_vectors).
The high-order pattern lets configuration parameters be specified separately from the window specification — Java's `OPTIONS` clause supports `ROW_NUMBER(ef_search: 100) OVER (PARTITION BY ...)`.
LEAF Value: takes no children. The carried HNSW configuration is not Value-typed — it's static metadata.
Eval is a placeholder — the real Apply path lands when the parser + higher-order resolution machinery is in place. RowNumberHighOrderValue itself never produces row-numbered output; it produces a RowNumberValue when applied.
func NewRowNumberHighOrderValue ¶
func NewRowNumberHighOrderValue(efSearch *int, isReturningVectors *bool) *RowNumberHighOrderValue
NewRowNumberHighOrderValue constructs the curried form. Both configuration parameters are optional — nil means "use HNSW index defaults".
func (*RowNumberHighOrderValue) Apply ¶
func (h *RowNumberHighOrderValue) Apply(partitioningValues, argumentValues []Value) *RowNumberValue
Apply produces a fully-configured RowNumberValue from this curried form by attaching the partition + argument values.
The Java equivalent is `evalWithoutStore` returning a BuiltInFunction that, when called with partition+argument arguments, allocates the final RowNumberValue. Go expresses this directly with a method.
Configuration carries through verbatim — EfSearch + IsReturningVectors land in the resulting RowNumberValue's HNSW knobs.
func (*RowNumberHighOrderValue) Children ¶
func (*RowNumberHighOrderValue) Children() []Value
Children returns the empty slice — leaf Value.
func (*RowNumberHighOrderValue) Evaluate ¶
func (*RowNumberHighOrderValue) Evaluate(any) (any, error)
Evaluate is a placeholder — high-order values don't have a per-row eval. The Apply path lands when the higher-order resolution machinery wires in.
func (*RowNumberHighOrderValue) Name ¶
func (*RowNumberHighOrderValue) Name() string
Name returns the canonical higher-order function name.
func (*RowNumberHighOrderValue) Type ¶
func (*RowNumberHighOrderValue) Type() Type
Type returns UnknownType — high-order values don't have a direct runtime type until applied. Java's getResultType() inherits from the high-order superclass which doesn't pin a type.
type RowNumberValue ¶
type RowNumberValue struct {
WindowedValue
EfSearch *int // optional HNSW ef_search override
IsReturningVectors *bool // optional HNSW vector-payload toggle
}
RowNumberValue is the SQL ROW_NUMBER() window function — assigns a UNIQUE 1-based sequential number within each partition (no tie-sharing — distinct from RANK whose ties share a number). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.RowNumberValue`.
Per Java's contract, ROW_NUMBER is INDEX-ONLY (Java's class implements Value.IndexOnlyValue): the row number can only be produced during an HNSW index traversal — typically when the surrounding query is `ORDER BY <distance>` over a vector index. The query planner refuses to compute ROW_NUMBER without a suitable index. Go records this constraint in IsIndexOnly() (the analyzer / matchers can read it without importing a separate Value.IndexOnlyValue marker interface).
HNSW configuration parameters (from Java's `OPTIONS` clause):
- EfSearch: HNSW search-quality knob — higher values increase recall (accuracy) at the cost of performance. nil = use the index's default `ef_search`.
- IsReturningVectors: whether the index scan returns the actual vector payloads (true) or only distance + ID (false / nil = omit vectors, smaller transfer).
Both are optional pointers so a missing OPTION in the SQL surface remains representable as nil rather than a sentinel value.
Per the Java doc, ROW_NUMBER over distance(<vector>, queryVec) followed by `<= K` is the K-NN search pattern that gets transformed into a DistanceRankValueComparison + matched against HNSW indexes. Go implements that transform in predicates/distance_rank_transform.go (the port of Java's RowNumberValue.transformComparisonMaybe), with Java's four metric-specific classes unified into DistanceRowNumberValue (value_distance_row_number.go). This bare RowNumberValue is the PRE-transform shape the parser constructs.
Result type: NotNullLong (ROW_NUMBER is always populated, 1-based).
func NewRowNumberValue ¶
func NewRowNumberValue(partitioningValues, argumentValues []Value, efSearch *int, isReturningVectors *bool) *RowNumberValue
NewRowNumberValue constructs a ROW_NUMBER() value. partitioning values + argument values follow the Java contract (Java's argumentValues for the index-tied form is the distance argument list; bare ROW_NUMBER() takes empty arguments).
func (*RowNumberValue) Evaluate ¶
func (*RowNumberValue) Evaluate(evalCtx any) (any, error)
Evaluate returns the current row number from the row-shape harness pattern. The harness exposes the streaming-window operator's per-row row-number counter via the `_row_number` key.
Returns nil if evalCtx is nil / non-map / has no `_row_number` key — matches the placeholder-Value pattern.
func (*RowNumberValue) IsIndexOnly ¶
func (*RowNumberValue) IsIndexOnly() bool
IsIndexOnly returns true — ROW_NUMBER cannot be computed outside of an index scan (the row-number value is computed during the index's search-graph traversal, not from the base record). Java's equivalent is the IndexOnlyValue marker interface; Go uses an accessor.
Planner / matcher code should consult IsIndexOnly to refuse to optimise ROW_NUMBER paths that don't have a matching index available — Java's MatchCandidate-side validation does the same.
func (*RowNumberValue) Name ¶
func (*RowNumberValue) Name() string
Name returns the SQL function name.
func (*RowNumberValue) Type ¶
func (*RowNumberValue) Type() Type
Type returns NotNullLong — ROW_NUMBER is always populated.
func (*RowNumberValue) WithChildren ¶
func (r *RowNumberValue) WithChildren(newChildren []Value) *RowNumberValue
WithChildren returns a new RowNumberValue with the children re-split via WindowedValue.SplitNewChildren. Both partition + arg lists are reconstructed; the HNSW config carries through unchanged.
type 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):
- fold the argument types with Type.maximumType; a null fold is INCOMPATIBLE_TYPE → 22000.
- 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 ¶
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 rich result Type. Most scalar functions can return NULL on NULL input — the result is forced to nullable regardless of how the caller stored Typ.
type ScalarSubqueryValue ¶
type ScalarSubqueryValue struct {
Alias CorrelationIdentifier
// 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 returned by scalar functions (GREATEST, LEAST) when arguments have incompatible types. The executor converts this to SQLSTATE 22000 DATA_EXCEPTION.
func (*ScalarTypeMismatchError) Error ¶
func (e *ScalarTypeMismatchError) Error() string
type SeedWindowReadClass ¶
type SeedWindowReadClass int
SeedWindowReadClass is one read's bucket. The four partition every read.
const ( // SeedWindowHit: the reference's identity selected a window. SeedWindowHit SeedWindowReadClass = iota // SeedWindowMiss: no window is filed under that identity. Not an error at any // of these sites — a non-leg reference, or (at the survivor sites) the // ordinary case. SeedWindowMiss // SeedWindowQualifiedNoIdentity: a QUALIFIED reference arrived with no // correlation, so no window could be selected for it and it declined. HARD // ZERO. See the header for what a non-zero re-arms. SeedWindowQualifiedNoIdentity // SeedWindowChildlessBaked: a CHILDLESS source-relative baked read reached // the rebase walk's tail, so no window could be selected for it and the whole // wrap declined. HARD ZERO. See the header. SeedWindowChildlessBaked // SeedWindowNestedHit: the reference's identity selected a window whose Kind // is LegKindNested — i.e. the read took the FUSED two-step address rather // than flat offset arithmetic. // // IT IS A HIT, COUNTED SEPARATELY, and it exists to answer one question no // other number on this path can: is RFC-200's nested reader arm LIVE on this // corpus, or is it correct-but-unentered? Those two states print identically // everywhere else — 174 leg-local reads unchanged, EXPLAIN identical, // MergedReAnchor 0 — and RFC-200 §6 predicts explicitly that // existentialRebase GROWS because the newly-accepted firings' existPreds // rebase through it. A prediction with no instrument is a prediction nothing // can refute. // // A read counted here is NOT also counted as SeedWindowHit; the classes // partition. SeedWindowNestedHit )
func (SeedWindowReadClass) String ¶
func (c SeedWindowReadClass) String() string
type SeedWindowReaderFloors ¶
type SeedWindowReaderFloors struct {
// Reads is the per-site minimum, indexed by site. A zero entry means the site
// is not floored, which is a statement about the corpus and not an omission.
Reads [seedWindowSiteCount]int
// NestedHitMustBeZero asserts that NO read selects a NESTED window.
//
// IT IS A TRIPWIRE, NOT A DEFECT GATE, and the inversion is the whole point:
// a non-zero here is GOOD NEWS that requires ACTION. RFC-200's nested reader
// arm is correct, cross-agreement-pinned on both entries and unit-pinned on
// both arms, and no corpus query reaches it — a nested SUB-window is only
// selected by a reference to a leg buried INSIDE the merge. Gate (a)'s four
// mutation directions are therefore not writable, and the branch merged with
// that stated.
//
// Without this assertion, activation day changes nothing visible. Whoever
// produces a query whose reference reaches a buried leg would see a green
// suite, a printed NESTED-HIT that nobody diffs, and gate (a) left unwritten
// BY DEFAULT rather than by decision. This is what turns that day into a red
// test with the hand-over in its failure message.
//
// THE ROUTE TO THAT DAY IS NOT THE ONE THIS COMMENT USED TO NAME. It said
// "typing the 94 bare-QOV result values", which was a plan that has since
// been REFUTED by measurement: the population is 102 and it is 100% typed
// already — every declined leg carries a real RecordType (arity 1-3 on the
// FlatMap legs, 1-4 counting the NestedLoopJoin-legged ones) — and typing
// could not convert one of them in any case, because the leg walk that
// consumed them refused on values.IsPositionalMergeRC, which needs a *RecordConstructorValue that no
// QuantifiedObjectValue is at any typing. `bare` there meant identity
// PASS-THROUGH, never untyped.
//
// What would actually trip this tripwire is the SHAPE conversion: giving the
// declined leg an RC(_i: QOV(leg_i)) result value, so a reference can reach a
// leg inside the merge. That is a different change with a different risk
// surface, and it is booked separately.
NestedHitMustBeZero bool
}
SeedWindowReaderFloors is the minimum read count each site must report over a whole suite run.
Floored per SITE rather than in total, because the sites do not substitute for one another: a total floor stays satisfied with individual readers dark. That is the whole reason this instrument exists — the predecessor's deletion took away the only thing that could tell a silenced reader from a quiet corpus.
The asymmetry this used to cite is gone. The existential rebase carried an order of magnitude more traffic than the rest put together until RFC-235 retired the NLJ arm supplying it; it now reads 288 against 438 for the other four combined. Per-site flooring is if anything MORE necessary at comparable magnitudes, since no single site can carry a total.
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 is cascades.rebaseOuterLegValueOrdinal's // per-reference window lookup — the EXISTS-over-join ordinal rebase, keyed by // the reference's own QuantifiedObjectValue correlation. // // It WAS the corpus's heaviest reader by an order of magnitude. RFC-235 // retired the NLJ arm whose firings supplied most of that traffic, and it now // reads 288 against 438 for the other four combined — comparable, not // dominant. SeedWindowSiteExistentialRebase SeedWindowSite = iota // SeedWindowSiteBoxLegRef is query.rebaseLegRefsToBox's QOV-shaped arm, keyed // by the reference's own correlation. It is also where CHILDLESS-BAKED is // recorded: the same walk, one arm further down. SeedWindowSiteBoxLegRef // SeedWindowSiteBoxSurvivorQOV is that walk's post-verification: does any // leg-correlated QuantifiedObjectValue survive the rebase? Keyed by the // surviving QOV's own correlation. Its reads are overwhelmingly MISSES by // construction — a hit is a decline — so its population, not its outcome, is // what this census is watching. SeedWindowSiteBoxSurvivorQOV // SeedWindowSiteBoxSurvivorCorrelation is the wrap's correct-or-decline net // over a translated subquery's correlation set, keyed by each correlation in // that set. The smallest population of the five and the one most likely to go // dark unnoticed. SeedWindowSiteBoxSurvivorCorrelation // SeedWindowSiteGatheredGroupSlot is query.slotInGatheredSeed's qualified // arm — a group-by key or aggregate operand resolving to a flat seed slot. It // is where QUALIFIED-NO-IDENTITY is recorded. SeedWindowSiteGatheredGroupSlot )
func (SeedWindowSite) String ¶
func (s SeedWindowSite) String() string
type SelectResultMintCounters ¶
type SelectResultMintCounters struct {
// Calls counts every mint, per site.
Calls [SelectResultMintSiteCount]int
// TypedQOV / UntypedQOV split the QOV-shaped mints by whether they carry a
// real flowed type. UntypedQOV is the DIVERGENCE population — see the floors.
TypedQOV [SelectResultMintSiteCount]int
UntypedQOV [SelectResultMintSiteCount]int
// OtherRV counts a mint that is not a QOV at all.
OtherRV [SelectResultMintSiteCount]int
// Shapes records the distinct spellings per site, for the same reason the
// sibling censuses keep witnesses: a bucket that moves without a spelling
// change is a different event from one that gains a spelling.
Shapes [SelectResultMintSiteCount]map[string]int
}
SelectResultMintCounters is the census's state.
func SelectResultMintCensus ¶
func SelectResultMintCensus() SelectResultMintCounters
SelectResultMintCensus reports the counters.
type SelectResultMintFloors ¶
type SelectResultMintFloors struct {
Calls [SelectResultMintSiteCount]int
}
SelectResultMintFloors is the mint census's gate.
Calls is a FLOOR: a site going dark must be visible, because every zero recorded beside a dark site measures an absence of traffic rather than an absence of the shape. Zero means NOT FLOORED, which for a floor is the same assertion as a floor of zero.
THE UNTYPED-QOV FLOOR IS GONE, and its absence is the reconciliation. It floored a DIVERGENCE — an untyped QuantifiedObjectValue, which Java cannot build — so that the gap stayed counted while it stood, with the DROP as the failing direction because a shrinking count cannot be told from a darkening site. The gap is closed at the constructor: NewQuantifiedObjectValue requires an exact type, so an untyped QOV is unrepresentable and this site mints none. A floor pointing at an impossible population is unsatisfiable, and lowering it to zero would leave the retirement unwatched — so the direction INVERTS and the zero is asserted unconditionally in assertSelectResultMintCounters.
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 is the SQL translator's EXISTS-bearing select // builder, which mints NewQuantifiedObjectValue(outerQ.GetAlias()) — a bare // UNTYPED QuantifiedObjectValue — whenever no result override is supplied. // This is the site Java's GraphExpansion.java:401 types unconditionally. SelectResultMintExistsSelect SelectResultMintSite = iota SelectResultMintSiteCount )
func SelectResultMintOriginOf ¶
func SelectResultMintOriginOf(rv Value) (SelectResultMintSite, bool)
SelectResultMintOriginOf reports the site that MINTED rv, and whether any did. Callers must guard on LegIdentityCensusEnabled().
func (SelectResultMintSite) String ¶
func (s SelectResultMintSite) String() string
type SelfEqualsWithoutChildren ¶
SelfEqualsWithoutChildren lets a Value implement its own structural node-equality — the analogue of Java's per-type Value.equalsWithoutChildren. EqualsWithoutChildren's type switch can only enumerate Value implementations defined in THIS package; a Value defined elsewhere (e.g. expr.predicateValue, which would create an import cycle if referenced here) MUST implement this so the Cascades matcher can compare it instead of hitting the unhandled-type panic. Children() is still walked by ValuesStructurallyEqual, so a leaf Value (Children() empty) returns its full node identity here.
type SelfSemanticHash ¶
type SelfSemanticHash interface {
SemanticHashDiscriminator() uint64
}
SelfSemanticHash lets a Value implemented outside this package contribute its own discriminator to the semantic hash — the hash analog of SelfEqualsWithoutChildren (a type the writeSemanticHash switch can't reach would otherwise collide into the bare Name() bucket). The returned value MUST be derived from the same non-child attributes EqualsWithoutChildrenValue compares (and be alias-free), so the equal⟹same-hash memo invariant holds.
type SelfWithChildren ¶
SelfWithChildren lets a Value defined outside this package reconstruct itself with new children, so values.WithChildren (and Replace/RebaseValue, which build new trees bottom-up) can rewrite it without this package's type switch enumerating it. The WithChildren analogue of SelfEqualsWithoutChildren and SelfSemanticHash. The newChildren slice has the same length and order as the value's Children().
type StatementClock ¶
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 ¶
StreamingValue extends Value with streaming evaluation. Mirrors Java's StreamingValue interface — Values that can produce a stream of elements rather than a single scalar result.
type StrictRankLimitValue ¶
type StrictRankLimitValue struct {
K Value
}
StrictRankLimitValue computes the row cap of a STRICT distance-rank predicate `ROW_NUMBER() OVER (ORDER BY distance(...)) < K` whose K is a RUNTIME value (a bound parameter — RFC-156 parameterized vector rank limit). The number of admitted rows is max(0, K-1).
It exists so the runtime LIMIT that bounds an ordered vector stream never expresses the strict adjustment with general CHECKED subtraction. `K - 1` underflows at K = math.MinInt64 (the ONLY K where it can), which an ArithmeticValue surfaces as an ArithmeticOverflowError — aborting a query that semantically selects NO rows (ROW_NUMBER() ≥ 1 is never < a K ≤ 1). This value mirrors the executor's scan-side rank-cap guard exactly: K ≤ 1 ⇒ 0 (computed WITHOUT subtracting, so K = math.MinInt64 cannot wrap K-1 to a huge positive), else K - 1 (K ≥ 2 ⇒ no underflow). NULL K propagates.
func (*StrictRankLimitValue) Children ¶
func (v *StrictRankLimitValue) Children() []Value
func (*StrictRankLimitValue) EqualsWithoutChildrenValue ¶
func (v *StrictRankLimitValue) EqualsWithoutChildrenValue(other Value) bool
EqualsWithoutChildrenValue: the node has no own attributes beyond its child K (compared separately by ValuesStructurallyEqual's recursion), so two strict rank caps are node-equal iff they are the same concrete type.
func (*StrictRankLimitValue) Evaluate ¶
func (v *StrictRankLimitValue) Evaluate(evalCtx any) (any, error)
func (*StrictRankLimitValue) Name ¶
func (v *StrictRankLimitValue) Name() string
func (*StrictRankLimitValue) Type ¶
func (v *StrictRankLimitValue) Type() Type
func (*StrictRankLimitValue) WithChildren ¶
func (v *StrictRankLimitValue) WithChildren(newChildren []Value) Value
WithChildren rebuilds the node around a rebased K so RebaseValue's generic recursion never drops a correlated K (a bound-parameter ConstantObjectValue).
type SubscriptValue ¶
type SubscriptValue struct {
Source Value
Index Value
// Typ is the bound element type. Defaults to UnknownType.
Typ Type
}
SubscriptValue is the Value-layer SQL array subscript: yields the element of `Source` at `Index`. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.SubscriptValue`.
arr[1] ↔ SubscriptValue{Source: arr, Index: 1}
CONFORMANCE: Index is 1-BASED per SQL standard (Foundation Section 4.10.2). Java's eval explicitly says: "If n is the cardinality of A, then the ordinal position p of an element is an integer in the range 1 ≤ p ≤ n."
Out-of-bounds Index returns NULL (UNKNOWN) — Java DOES NOT raise an out-of-bound error, matches SQL semantics.
NULL propagation: NULL Index OR NULL Source → NULL result.
func NewSubscriptValue ¶
func NewSubscriptValue(source, index Value, resultType Type) *SubscriptValue
NewSubscriptValue constructs the subscript Value with the given source array Value, index Value, and result Type.
func (*SubscriptValue) Children ¶
func (v *SubscriptValue) Children() []Value
Children returns [Source, Index].
func (*SubscriptValue) Evaluate ¶
func (v *SubscriptValue) Evaluate(evalCtx any) (any, error)
Evaluate returns Source[Index-1] (1-based per SQL standard).
Returns nil (UNKNOWN) if:
- Source or Index is nil-Value or evaluates to nil
- Source doesn't evaluate to a slice ([]any)
- Index isn't an integer kind
- Index is out of bounds
func (*SubscriptValue) Name ¶
func (*SubscriptValue) Name() string
Name returns the debug-print kind.
func (*SubscriptValue) Type ¶
func (v *SubscriptValue) Type() Type
Type returns the bound element type.
type ThrowsValue ¶
type ThrowsValue struct {
ResultType Type
}
ThrowsValue is a leaf Value that panics if evaluated. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values. ThrowsValue`.
Used by the planner for "this code path should be unreachable" markers — a Value placeholder that signals a dead branch in the plan tree. If a planner bug causes the dead branch to actually execute, the panic surfaces immediately rather than silently returning nil.
Type is whatever the planner wants the placeholder to advertise (so type-checking passes through the dead branch).
func NewThrowsValue ¶
func NewThrowsValue(resultType Type) *ThrowsValue
NewThrowsValue constructs the placeholder with the given Type.
func (*ThrowsValue) Children ¶
func (*ThrowsValue) Children() []Value
Children returns the empty slice — leaf.
type ToOrderedBytesValue ¶
type ToOrderedBytesValue struct {
Child Value
Direction OrderedBytesDirection
}
ToOrderedBytesValue encodes its child Value's evaluation as a FoundationDB-compatible ordered-bytes blob suitable for use as part of an index key. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.ToOrderedBytesValue`.
Used by index-key construction: the planner lowers a SQL ORDER-BY-expression-as-index-prefix to a chain of ToOrderedBytes applications — each column's ordering direction baked into the produced bytes so a forward FDB scan over the index produces rows in the requested SQL order.
Java's eval calls `TupleOrdering.pack(Key.Evaluated.scalar(child), direction)` — packs the child as a 1-element FDB tuple, then applies direction-aware encoding (DESC inverts bits / reverses NULL placement). Go's direction-aware encoding exists on the index side (pkg/recordlayer/order_function_key_expression.go) but is NOT wired into this Value's Evaluate — eval returns nil per the non-evaluable placeholder pattern shared with VersionValue / IncarnationValue / ObjectValue.
Result type: NotNullBytes. Even when the child is NULL, the encoding produces a sentinel byte sequence, so the byte output is always populated.
func NewToOrderedBytesValue ¶
func NewToOrderedBytesValue(child Value, direction OrderedBytesDirection) *ToOrderedBytesValue
NewToOrderedBytesValue constructs the encoder.
func (*ToOrderedBytesValue) Children ¶
func (v *ToOrderedBytesValue) Children() []Value
Children returns the single child Value.
func (*ToOrderedBytesValue) CreateInverse ¶
func (v *ToOrderedBytesValue) CreateInverse(newChild Value, originalType Type) *FromOrderedBytesValue
CreateInverse returns the FromOrderedBytesValue that decodes the ordered-bytes form back to the original value. Java's createInverseValueMaybe always returns Optional.of — the encoding is always invertible. We expose the inverse as a method for matchers / rules that need to canonicalise To→From chains.
Per Java's signature, the inverse takes a NEW child (the ordered-bytes input the inverse decodes) and the ORIGINAL child's result type (so the inverse knows what type to decode to).
func (*ToOrderedBytesValue) Evaluate ¶
func (*ToOrderedBytesValue) Evaluate(any) (any, error)
Evaluate is currently a placeholder — returns nil. Real eval wires tuple.PackOrdered (the Go equivalent of Java's TupleOrdering.pack). The Value-shape is reachable for planner / matcher / serialisation work today; runtime integration lands when index-key-construction port reaches this branch.
func (*ToOrderedBytesValue) Name ¶
func (*ToOrderedBytesValue) Name() string
Name returns the SQL function name.
func (*ToOrderedBytesValue) Type ¶
func (*ToOrderedBytesValue) Type() Type
Type returns NotNullBytes — the encoder produces bytes regardless of input.
type TranslationFunction ¶
type TranslationFunction func(sourceAlias CorrelationIdentifier, leafValue Value) Value
TranslationFunction rewrites one correlation-bearing LEAF value bound to sourceAlias into its replacement — Java's TranslationMap.TranslationFunction (TranslationMap.java:79-98). The function owns the replacement's SHAPE (plain ofOrdinalNumber in the merge case — composition with enclosing references is the rebuild's job, never the function's).
type TranslationMap ¶
type TranslationMap interface {
ContainsSourceAlias(alias CorrelationIdentifier) bool
ApplyTranslationFunction(sourceAlias CorrelationIdentifier, leafValue Value) Value
// DefinesOnlyIdentities reports that applying the map is a no-op —
// TranslateCorrelations returns its input unchanged (pointer-stable).
DefinesOnlyIdentities() bool
}
TranslationMap is Java's TranslationMap interface: alias membership, per-leaf application, and the identity early-out.
type TranslationMapBuilder ¶
type TranslationMapBuilder struct {
// contains filtered or unexported fields
}
TranslationMapBuilder accumulates alias→function entries — RegularTranslationMap.Builder (RegularTranslationMap.java:145-228). Usage: NewTranslationMapBuilder().When(a).Then(fn).When(b).Then(fn2).Build().
func NewTranslationMapBuilder ¶
func NewTranslationMapBuilder() *TranslationMapBuilder
func (*TranslationMapBuilder) Build ¶
func (b *TranslationMapBuilder) Build() TranslationMap
Build snapshots the accumulated entries — the returned map is IMMUTABLE (Java's ImmutableMap.copyOf): further builder use cannot mutate a map already handed out (sharing b.fns let a built empty map stop defining only identities when the builder was reused).
func (*TranslationMapBuilder) When ¶
func (b *TranslationMapBuilder) When(alias CorrelationIdentifier) *TranslationMapWhen
type TranslationMapWhen ¶
type TranslationMapWhen struct {
// contains filtered or unexported fields
}
TranslationMapWhen is the intermediate of the .When(alias).Then(fn) pair.
func (*TranslationMapWhen) Then ¶
func (w *TranslationMapWhen) Then(fn TranslationFunction) *TranslationMapBuilder
Then registers the function for the pending alias. A duplicate alias is a caller bug — Java Verifies against it (RegularTranslationMap.java:204); loud here too, a silent overwrite would drop a rebase.
type TupleSource ¶
type TupleSource int
TupleSource enumerates the two tuple-bearing fields of an FDB IndexEntry — the index KEY (primary scan tuple) or the index VALUE (associated payload tuple). Mirrors Java's `IndexKeyValueToPartialRecord.TupleSource`.
const ( // TupleSourceKey selects the index entry's KEY tuple. TupleSourceKey TupleSource = iota // TupleSourceValue selects the index entry's VALUE tuple. TupleSourceValue // TupleSourceOther is the fallback used when an index entry has // neither KEY nor VALUE semantics for a given column (e.g. // extracting a deferred-fetch field from a non-covering index). TupleSourceOther )
func (TupleSource) String ¶
func (s TupleSource) String() string
String renders the tuple source for explain / debug print.
type Type ¶
type Type interface {
// Code returns this type's TypeCode.
Code() TypeCode
// IsNullable reports whether the type allows NULL values. SQL
// columns default to nullable; PRIMARY KEY columns and explicit
// NOT NULL columns are non-nullable.
IsNullable() bool
// Equals reports structural equality with other. Implementations
// MUST compare Code + Nullable AT MINIMUM; structured types
// extend the contract to compare child fields / element types.
Equals(other Type) bool
// String renders the type in SQL-ish form ("INT NOT NULL",
// "STRING NULL"). Used by EXPLAIN output.
String() string
}
Type is the rich type-system handle replacing ValueType. Carries the type code plus nullability; concrete impls add structure (RecordType.Fields, ArrayType.Element, …) as the port lands them.
Equals tests structural equality — two distinct PrimitiveType instances with the same Code + Nullable are equal. Pointer- equality is NOT a substitute (the helper constants below exist precisely so callers can share a canonical pointer per (code, nullable) pair when they need to).
var ( // NullableInt is INT NULL — INT column with no NOT NULL constraint. NullableInt Type = &PrimitiveType{TypeCode: TypeCodeInt, Nullable: true} // NotNullInt is INT NOT NULL — typical PRIMARY KEY column shape. NotNullInt Type = &PrimitiveType{TypeCode: TypeCodeInt, Nullable: false} // NullableLong is LONG NULL (BIGINT default). NullableLong Type = &PrimitiveType{TypeCode: TypeCodeLong, Nullable: true} // NotNullLong is LONG NOT NULL. NotNullLong Type = &PrimitiveType{TypeCode: TypeCodeLong, Nullable: false} // NullableFloat is FLOAT NULL. NullableFloat Type = &PrimitiveType{TypeCode: TypeCodeFloat, Nullable: true} // NotNullFloat is FLOAT NOT NULL. NotNullFloat Type = &PrimitiveType{TypeCode: TypeCodeFloat, Nullable: false} // NullableDouble is DOUBLE NULL. NullableDouble Type = &PrimitiveType{TypeCode: TypeCodeDouble, Nullable: true} // NotNullDouble is DOUBLE NOT NULL. NotNullDouble Type = &PrimitiveType{TypeCode: TypeCodeDouble, Nullable: false} // NullableString is STRING NULL (VARCHAR default). NullableString Type = &PrimitiveType{TypeCode: TypeCodeString, Nullable: true} // NotNullString is STRING NOT NULL. NotNullString Type = &PrimitiveType{TypeCode: TypeCodeString, Nullable: false} // NullableBoolean is BOOLEAN NULL. NullableBoolean Type = &PrimitiveType{TypeCode: TypeCodeBoolean, Nullable: true} // NotNullBoolean is BOOLEAN NOT NULL. NotNullBoolean Type = &PrimitiveType{TypeCode: TypeCodeBoolean, Nullable: false} // NullableBytes is BYTES NULL. NullableBytes Type = &PrimitiveType{TypeCode: TypeCodeBytes, Nullable: true} // NotNullBytes is BYTES NOT NULL. NotNullBytes Type = &PrimitiveType{TypeCode: TypeCodeBytes, Nullable: false} // NullableUuid is UUID NULL — 16-byte primitive, NOT a structured // type in fdb-relational's grammar (RelationalParser.g4 lists UUID // among primitiveType siblings). NullableUuid Type = &PrimitiveType{TypeCode: TypeCodeUuid, Nullable: true} // NotNullUuid is UUID NOT NULL. NotNullUuid Type = &PrimitiveType{TypeCode: TypeCodeUuid, Nullable: false} // NullableVersion is VERSION NULL — fdb-record-layer's 12-byte // FDBRecordVersion (10-byte global versionstamp + 2-byte local). NullableVersion Type = &PrimitiveType{TypeCode: TypeCodeVersion, Nullable: true} // NotNullVersion is VERSION NOT NULL. NotNullVersion Type = &PrimitiveType{TypeCode: TypeCodeVersion, Nullable: false} // NullableDate is DATE NULL. NullableDate Type = &PrimitiveType{TypeCode: TypeCodeDate, Nullable: true} // NotNullDate is DATE NOT NULL. NotNullDate Type = &PrimitiveType{TypeCode: TypeCodeDate, Nullable: false} // NullableTimestamp is TIMESTAMP NULL. NullableTimestamp Type = &PrimitiveType{TypeCode: TypeCodeTimestamp, Nullable: true} // NotNullTimestamp is TIMESTAMP NOT NULL. NotNullTimestamp Type = &PrimitiveType{TypeCode: TypeCodeTimestamp, Nullable: false} // NullType is the type of the NULL literal — always nullable // (a NULL is by definition not a value of a specific type, but // can be assigned to any nullable column). Distinct from // UnknownType: NULL has a concrete code, UNKNOWN doesn't. NullType Type = &PrimitiveType{TypeCode: TypeCodeNull, Nullable: true} // UnknownType is the placeholder for "type not yet inferred" — // used by Value impls that don't yet have a real type computed. UnknownType Type = &PrimitiveType{TypeCode: TypeCodeUnknown, Nullable: true} // NoneType is the type of the untyped empty array literal `[]`. // Identity-promotes to any ARRAY type without changing // nullability — when an empty array appears in a context that // expects ARRAY<T>, NONE adopts T as its element type. // Always non-nullable. Mirrors Java's `Type.NONE`. NoneType Type = &PrimitiveType{TypeCode: TypeCodeNone, Nullable: false} // AnyType is the universal supertype — every Type is assignable // to it. Used by quantifiers and pre-resolution placeholders // where a concrete type isn't known at construction. Always // nullable. Mirrors Java's `Type.ANY`. AnyType Type = &PrimitiveType{TypeCode: TypeCodeAny, Nullable: true} )
Canonical singletons for the most common (code, nullable) pairs. Callers that need to share a pointer (e.g. for fast equality checks via `==`) use these. Mirrors Java's Type.NULL / NONE / UUID_NULL_INSTANCE constants.
var ( // TypeUnknown is the placeholder for "type not yet inferred". // Maps to the canonical UnknownType singleton. TypeUnknown Type = UnknownType // 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 ¶
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 ¶
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 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 follows the value the row materializer can actually emit: optional/presence-bearing fields may be nil, while proto3 scalars, required fields, and flat repeated fields always have a value.
- 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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 )
func JavaAggregateResultCode ¶
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 ¶
IsNumeric reports whether tc is one of the numeric types (arithmetic + comparison promotion targets).
func (TypeCode) IsPrimitive ¶
IsPrimitive reports whether tc names a scalar (vs structured) type. Mirrors Java's `TypeCode.isPrimitive()`. Composite shapes (RECORD, ARRAY, RELATION) and the special placeholders (UNKNOWN, ANY, NONE, FUNCTION) all return false.
type TypeProtoRepository ¶
type TypeProtoRepository struct {
// contains filtered or unexported fields
}
TypeProtoRepository is the protobuf surface of a type repository: Java's TypeRepository.Builder plus the built TypeRepository, folded into one object because Go has no need for the two-phase split (Java's Builder exists to accumulate a FileDescriptorProto that is validated once; here the file is recompiled on demand and memoised).
It is Java's addTypeIfNeeded dedup: a Type already defined is never defined twice, and its descriptor is handed back from the cache. Safe for concurrent use — a single repository is shared by every row of a query, and rows are produced concurrently.
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.
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 ¶
NewUdfValue constructs a UDF call.
The Call function is REQUIRED for runtime evaluation; passing nil is allowed at construction time so the planner can build UDF call shapes before the implementation is wired (e.g. during analyser phase). A nil Call surfaces nil from Evaluate per the placeholder-Value contract.
func (*UdfValue) Children ¶
Children returns the Args list — UDF arguments are the only Value children.
func (*UdfValue) Evaluate ¶
Evaluate walks each arg's Evaluate and hands the resulting `[]any` to Call. Returns nil if Call is nil (placeholder mode).
func (*UdfValue) Name ¶
Name returns the UDF function name (used for debug print + planner equivalence keying).
func (*UdfValue) WithChildren ¶
WithChildren returns a new UdfValue with the given children substituted for Args. Function name, result type, and Call body carry through unchanged.
type UnboundEvalContextError ¶
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 ¶
func (e *UnboundScalarSubqueryError) Error() string
type UndeclaredStructFieldError ¶
UndeclaredStructFieldError reports a record constructor carrying a name the target struct does not declare.
func (*UndeclaredStructFieldError) Error ¶
func (e *UndeclaredStructFieldError) Error() string
type UnmatchedAggregateValue ¶
type UnmatchedAggregateValue struct {
UnmatchedID CorrelationIdentifier
}
UnmatchedAggregateValue is a non-evaluable marker value that stands for an aggregate expression not yet matched to a candidate during index matching. It carries a unique CorrelationIdentifier (the "unmatched ID") that links back to the original query aggregate via the GroupByMappings.unmatchedAggregatesMap.
During Compensation.Intersect, when an aggregate that was previously unmatched becomes matched (because a second index covers it), the replaceUnmatchedAggregateValues function replaces these markers with the actual translated aggregate value.
Ports Java's GroupByExpression.UnmatchedAggregateValue.
func NewUnmatchedAggregateValue ¶
func NewUnmatchedAggregateValue(id CorrelationIdentifier) *UnmatchedAggregateValue
func (*UnmatchedAggregateValue) Children ¶
func (*UnmatchedAggregateValue) Children() []Value
func (*UnmatchedAggregateValue) Evaluate ¶
func (*UnmatchedAggregateValue) Evaluate(_ any) (any, error)
func (*UnmatchedAggregateValue) GetCorrelatedTo ¶
func (v *UnmatchedAggregateValue) GetCorrelatedTo() map[CorrelationIdentifier]struct{}
func (*UnmatchedAggregateValue) IsNonEvaluable ¶
func (*UnmatchedAggregateValue) IsNonEvaluable() bool
func (*UnmatchedAggregateValue) Name ¶
func (*UnmatchedAggregateValue) Name() string
func (*UnmatchedAggregateValue) Type ¶
func (*UnmatchedAggregateValue) Type() Type
type Value ¶
type Value interface {
// Children returns the immediate sub-Values of this node.
// Leaf Values return an empty slice (never nil — keeps matcher
// code free of nil checks).
Children() []Value
// Type is the rich result Type of evaluating this Value
// (the legacy ValueType enum is retired; Type() returns the
// rich Type directly). Never nil —
// implementations return UnknownType when the type genuinely
// isn't known yet.
Type() Type
// Name is a debug string for error messages + explain output.
// Not part of the matcher DSL.
Name() string
// Evaluate produces the Go-native value this Value represents
// against an eval context. Leaf ConstantValue ignores the
// context; FieldValue looks up its column; ArithmeticValue
// recurses. The context is opaque (`any`) so different
// subsystems can pass their own row shape — tests use
// `map[string]any`.
//
// Returns (value, nil) on success — (nil, nil) is SQL NULL.
// (nil, err) signals a data-dependent runtime error (arithmetic
// overflow, division by zero, invalid cast, type mismatch);
// callers propagate it instead of recovering a panic.
Evaluate(evalCtx any) (any, error)
}
Value is the root of the Value hierarchy. Concrete Values implement Children / Type / Name / Evaluate; matchers downcast via type switches / type assertions on the concrete Go type.
Java equivalent: `Value extends Correlated<Value>, TreeLike<Value>, Typed, ...`. The initial port keeps Children + Type + Name + a simple Evaluate since those are the surfaces rules touch. The `Correlated.GetCorrelatedTo` contract is declared separately (see correlation.go) and implemented by those Values that reference a Quantifier; leaf values opt out.
func DeconstructRecord ¶
DeconstructRecord flattens a record-typed Value into its constituent field Values. Mirrors Java's `Values.deconstructRecord(Value)`.
Used by planner rules that need to look at individual field expressions inside a record-shaped Value:
For a RecordConstructorValue, returns the children Values directly (one per field). Pointer-stable: if the caller wants to rewrite a single field's Value, working with the flat list and re-constructing avoids deep cloning.
For any other record-typed Value (e.g. QuantifiedRecordValue, QueriedValue, RecordTypeValue when wrapping a record), returns FieldValue accessors keyed by the field name — one per record field. The caller can substitute or simplify these individually then re-construct.
Returns nil if v is nil or its Type isn't a record. The caller is expected to check via the returned slice's length (zero = not-record OR record with zero fields, either of which is a degenerate case).
func LiteralValue ¶
LiteralValue wraps a Go-native literal in the matching Value subtype: nil → NullValue, bool → BooleanValue, otherwise a ConstantValue. Typ defaults to TypeUnknown; the simplifier does not depend on the type tag today — it inspects the wrapped Value subtype.
func MapFieldValues ¶
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 ¶
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 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 ¶
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 resolves an admitted FieldValue's complete ordinal path on a replacement child and refuses any type/nullability drift.
func Replace ¶
Replace applies replacementFn to every node in the Value tree rooted at v, in pre-order (parent before children). If replacementFn returns nil, the entire subtree is removed (Replace returns nil). If replacementFn returns a different Value, that Value's children are then recursed. If replacementFn returns the same Value unchanged, children are recursed and the original node is kept unless a child was replaced.
Copy-on-write: a node's children list is only allocated when at least one child was actually replaced — identical subtrees reuse the original pointers.
Matches Java's `TreeLike.replace(UnaryOperator<T>)` semantics exactly: pre-order traversal, CoW, nil-propagation.
func ReplaceLeavesMaybe ¶
ReplaceLeavesMaybe applies replaceFn only to leaf nodes (Values with no children) in pre-order. Non-leaf nodes are traversed but not passed to replaceFn. Matches Java's `TreeLike.replaceLeavesMaybe(UnaryOperator<T>)`.
Returns nil if replaceFn returns nil for any leaf.
func ReplaceLeavesOnceMaybe ¶
ReplaceLeavesOnceMaybe is Java's TreeLike.replaceLeavesMaybe(op, visitNewLeaves=false): it applies replaceFn to leaf nodes, but does NOT re-apply it to leaves INTRODUCED by a replacement. After a leaf is replaced, every leaf of the replacement subtree is recorded (by pointer identity) and skipped on the subsequent re-descent.
This is the correct semantics for SELF-REFERENTIAL substitutions — e.g. TranslationMap substituting alias B with a value that itself references B (the source-anchored join RC anchors its right-leg columns to QOV(B), while the parent quantifier over the join is ALSO aliased B). Plain Replace / ReplaceLeavesMaybe re-descend into the replacement, re-match B, and loop forever. Tracking new leaves breaks the cycle exactly as Java does.
Returns nil if replaceFn returns nil for any (original) leaf.
func 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 ¶
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 ¶
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 SimplifyAll ¶
SimplifyAll batch-applies SimplifyValue to a list of Values. Mirrors Java's `Values.simplify(Iterable<Value>, ...)`.
Returns a fresh slice of the same length as the input. The pointer-equality short-circuit IS preserved: if no Value changed, the returned slice contains the original pointers. Callers can detect "no fold happened" via deep slice-pointer equality.
func SimplifyValue ¶
SimplifyValue is the standalone-Value counterpart to Simplify. Folds constant sub-trees in a Value (e.g. SELECT-list expressions or projection arguments that never reach a comparison and so never hit ComparisonConstantSimplifyRule).
Two-phase per node, post-order:
- Recurse into children — fold them first so partial folds work (e.g. `name + (1+2)` becomes `name + 3` in one pass).
- If the rebuilt node is fully constant per IsConstantValue, fold to a literal Value via LiteralValue (preserves the original Type so downstream type checks stay consistent).
Returns the input unchanged when nothing folds — pointer-equality stable so callers can cheaply check for "did anything happen?".
Why a free function rather than a CascadesRule: the rule framework targets QueryPredicate matchers; standalone Values have no surrounding predicate to match against. (Java models this as its ValueSimplificationRuleSet; Go's equivalent is this fold.)
Coverage: ArithmeticValue, CastValue, PromoteValue, ScalarFunctionValue, NotValue. Other composites (RecordConstructorValue, AggregateValue) are not folded — Aggregate inherently needs row context, RecordConstructor seldom appears in a fold-able position. Adding more shapes is mechanical when need arises (extend isFoldableComposite + simplifyChildren).
func SimplifyValueWithContext ¶
func SimplifyValueWithContext(v Value, ctx ValueSimplifyContext) Value
SimplifyValueWithContext applies context-aware simplification rules that SimplifyValue cannot handle. Ports Java's EliminateArithmeticValueWithConstantRule, FoldConstantRule, and LiftConstructorRule.
Call SimplifyValue first (context-free), then SimplifyValueWithContext on the result with the appropriate context.
func TranslateCorrelations ¶
func TranslateCorrelations(v Value, m TranslationMap) Value
TranslateCorrelations applies the map to every correlation-bearing leaf of v — Java's Value.translateCorrelations (Value.java:347-368): identity early-out, then replaceLeavesMaybe with visitNewLeaves=false (Go's ReplaceLeavesOnceMaybe — replacement leaves are never re-translated, the load-bearing semantics for self-referential substitutions). Rebuilds go through 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. WITH ORDINALITY is such a boundary: SQL names its two output slots with AS/AT aliases while the physical Explode carrier deliberately retains the private positional names _0/_1.
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 ¶
WithChildren is the exported entry point for reconstructing a Value with new children. Delegates to the unexported withChildren.
type ValueSimplifyContext ¶
type ValueSimplifyContext struct {
ConstantAliases map[CorrelationIdentifier]struct{}
IsRoot bool
}
ValueSimplifyContext carries context for context-aware value simplification. Matches Java's AbstractRuleCall fields: constantAliases + isRoot.
type VersionValue ¶
type VersionValue struct {
Child Value
}
VersionValue extracts the FDBRecordVersion (12-byte versionstamp + local) from a record. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.VersionValue`.
Used by VERSION-aware queries:
- SELECT version(record) FROM t
- WHERE version(record) > X (versionstamp range queries)
- ORDER BY version(record) (versionstamp-ordered scans)
The child Value must evaluate to a record-shaped object that carries a "version" field — typically a QuantifiedObjectValue flowing the queried record. Go extracts via map["version"] lookup on the standard row shape; a consumer that flows a typed FDBQueriedRecord must populate that entry.
Type is nullable VERSION (12-byte composite). NULL when the record's version is unknown / unset.
func NewVersionValue ¶
func NewVersionValue(child Value) *VersionValue
NewVersionValue constructs a VersionValue.
func (*VersionValue) Children ¶
func (v *VersionValue) Children() []Value
Children returns the single child Value.
func (*VersionValue) Evaluate ¶
func (v *VersionValue) Evaluate(evalCtx any) (any, error)
Evaluate extracts the version from the child's evaluated value. The child is expected to produce a map with a "version" key (the standard row-shape), or a struct with a similar accessor.
Returns nil if:
- Child is nil-shaped or evaluates to nil.
- The evaluated record has no version field.
- The version field is itself nil.
Returns the version (typically []byte or a 12-byte tuple) on success.
type 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 WindowedValue ¶
WindowedValue is the base shape for all SQL window-function values (RANK, ROW_NUMBER, DENSE_RANK, NTILE, percentile/lag/lead, etc.). Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.values.WindowedValue` (an abstract class; in Go we use embedding via a plain struct).
The shape is two parallel Value lists:
- PartitioningValues — the PARTITION BY columns. Rows that share the same tuple of these values form a single window-frame group; the windowed aggregate restarts per group.
- ArgumentValues — the function-specific arguments. RANK has no arguments (uses ORDER BY); NTILE has one (the bucket count); LAG / LEAD have 1-3 (offset, default, etc.).
Java's WindowedValue is abstract — concrete subclasses (RankValue, RowNumberValue, NTileValue, ...) supply the per-row evaluation semantics. The Go port keeps this as a plain struct embedded by concrete window types; the empty Evaluate contract matches the AggregateValue pattern (window functions can't eval per-row alone — they need the whole partition context).
**Per Java's constructor preconditions**: argumentValues must be non-empty for non-RANK window functions; the Go port mirrors this at construction. RANK's empty argumentValues is a special case handled by NewRankValue.
func NewWindowedValue ¶
func NewWindowedValue(partitioningValues, argumentValues []Value) *WindowedValue
NewWindowedValue constructs the embedded base. argumentValues may be empty (RANK / DENSE_RANK / ROW_NUMBER take no operand args — the windowing happens via ORDER BY); concrete subclasses with required operand args validate at their constructor.
func (*WindowedValue) Children ¶
func (w *WindowedValue) Children() []Value
Children returns partition + argument values concatenated. Mirrors Java's WindowedValue.computeChildren which builds ImmutableList<>.addAll(partitioning).addAll(argument).
func (*WindowedValue) Evaluate ¶
func (*WindowedValue) Evaluate(any) (any, error)
Evaluate returns nil — windowed aggregates can't eval per-row without a full partition context. Concrete subclasses MAY override to evaluate against a window-frame harness (see RankValue.Evaluate for the rank-tracking eval pattern).
func (*WindowedValue) SplitNewChildren ¶
func (w *WindowedValue) SplitNewChildren(newChildren []Value) (partition, argument []Value)
SplitNewChildren splits a flat newChildren slice back into (partition, argument) lists by position — matching Java's `splitNewChildren` helper that subclass `withChildren` implementations call to reconstruct the partition/arg split.
Length contract:
- Expected: len(newChildren) == len(PartitioningValues) + len(ArgumentValues). When the simplification driver passes newChildren = w.Children() this holds by construction.
- SHORT input (len(newChildren) < len(PartitioningValues)): n is clipped to len(newChildren), partition gets all of newChildren, argument is empty. Permissive — silently drops trailing partitioning slots.
- LONG input (len(newChildren) > len(PartitioningValues) + len(ArgumentValues)): the surplus goes into argument without bounds check. Permissive — caller's invariant to enforce.
Today's only callers are the per-subclass `WithChildren` implementations (RankValue, RowNumberValue, DistanceRowNumberValue), which receive exactly len(Children()) values from the planner, so the permissive-on-mismatch behaviour never bites in practice. New callers must pass an exactly-sized slice; otherwise either partition or argument silently truncates.
Source Files
¶
- accessor_name_path.go
- accessor_name_path_census.go
- alias_map.go
- coercion.go
- column_identity.go
- compare_ordered.go
- correlation.go
- dotted_leg_qualifier_census.go
- dotted_row_type_producer_census.go
- dotted_witness_attribution_census.go
- exact_type.go
- exact_type_intern.go
- field_value.go
- field_value_mint_census.go
- field_value_reanchor.go
- folder.go
- functional_dependency.go
- leaf_value.go
- leg_identity_census.go
- leg_identity_census_report.go
- like_match.go
- map_field_values.go
- name_split_census.go
- nullable_array_descriptor.go
- ordering_claim.go
- ordinal_binding.go
- ordinal_join_seed.go
- ordinal_layout.go
- ordinal_output_layout.go
- ordinal_seed_layout.go
- phase_root_translation.go
- primitive_accessors.go
- projection_alias_source.go
- proto_field_type.go
- proto_type.go
- pseudo_field.go
- pullup.go
- qov_source_layout.go
- qualifier_recovery_census.go
- rebase.go
- record_constructor_message.go
- replace.go
- required_bindings.go
- resolution_error.go
- scalar_function_catalog.go
- schubfach.go
- seed_window_reader_census.go
- select_result_mint_census.go
- semantic_equals.go
- semantic_hash.go
- simplifier_value.go
- struct_message.go
- translation_map.go
- type.go
- value_andor.go
- value_array_constructor.go
- value_array_distinct.go
- value_cardinality.go
- value_collate.go
- value_condition_selector.go
- value_constant_object.go
- value_correlation.go
- value_cosine_distance_row_number.go
- value_derived.go
- value_distance.go
- value_distance_row_number.go
- value_dot_product_distance_row_number.go
- value_empty.go
- value_euclidean_distance_row_number.go
- value_euclidean_square_distance_row_number.go
- value_evaluates_to.go
- value_exists.go
- value_first_or_default.go
- value_first_or_default_streaming.go
- value_in.go
- value_incarnation.go
- value_index_entry_object.go
- value_index_only_aggregate.go
- value_indexed.go
- value_like.go
- value_not.go
- value_object.go
- value_oftype.go
- value_ordered_bytes.go
- value_parameter_object.go
- value_pattern_for_like.go
- value_pick.go
- value_quantified_record.go
- value_queried.go
- value_range.go
- value_rank.go
- value_recordtype.go
- value_row_number.go
- value_row_number_high_order.go
- value_scalar_subquery.go
- value_strict_rank_limit.go
- value_subscript.go
- value_throws.go
- value_udf.go
- value_unmatched_aggregate.go
- value_version.go
- value_windowed.go
- values.go
- values_helpers.go