Documentation
¶
Overview ¶
derivations_evaluator.go — evaluates DerivationsProperty for physical plan wrapper expressions. Mirrors Java's DerivationsProperty.DerivationsVisitor.
The evaluator walks the expression tree bottom-up, computing properties.Derivations for each node. For each wrapper type it computes what the result values and local values are by inlining child result values into the current node's value expressions (decorrelation).
Go extension — no Java equivalent.
Wraps RecordQueryInMemorySortPlan as a RelationalExpression for the Cascades Memo. Java has no physical sort operator; this is a Go-only fallback for ORDER BY without a supporting index.
Go extension — no Java equivalent.
Java's RemoveSortRule (ImplementSortRule in Go) eliminates sorts via index ordering or fails. This rule provides an in-memory fallback: when no index can satisfy the ORDER BY, materialize and sort.
Registered alongside ImplementSortRule. Both match LogicalSortExpression. Cost model ensures index-based elimination is preferred — the in-memory sort only wins when it's the sole alternative.
Index ¶
- Constants
- Variables
- func AddPartialMatchForCandidate(ref *expressions.Reference, candidate MatchCandidate, match PartialMatch) bool
- func AdjustMatches(rootRef *expressions.Reference)
- func AdjustPartialMatchesForRef(ref *expressions.Reference)
- func AllAttributesExcept(except ...*properties.ExpressionProperty) []*properties.ExpressionProperty
- func AreAllBindingsFixed(bindings []OrderingBinding) bool
- func ComputeDerivations(expr expressions.RelationalExpression) *properties.Derivations
- func CreateScansForMatches(accesses []Vectored[*SingleMatchedAccess], _ PlanContext) map[PartialMatch]plans.RecordQueryPlan
- func CrossProduct[T any](lists [][]T) [][]T
- func DataAccessForMatchPartition(requestedOrderings []*RequestedOrdering, partialMatches []PartialMatch, ...) []expressions.RelationalExpression
- func ExplainPhysicalPlan(expr expressions.RelationalExpression) string
- func FireExpressionRule(rule ExpressionRule, ref *expressions.Reference) []expressions.RelationalExpression
- func FireExpressionRuleWithMemo(rule ExpressionRule, ref *expressions.Reference, ctx PlanContext, memo *Memo) []expressions.RelationalExpression
- func FireImplementationRule(rule ImplementationRule, ref *expressions.Reference, ...) []expressions.RelationalExpression
- func FireImplementationRuleWithContext(rule ImplementationRule, ref *expressions.Reference, ctx PlanContext, ...) []expressions.RelationalExpression
- func FireRule(rule CascadesRule, in any) []any
- func Get[T any](cm *ConstraintMap, ref *expressions.Reference, key *PlannerConstraint[T]) (T, bool)
- func GetPhysicalFetchFromPartialRecordPlan(expr expressions.RelationalExpression) *plans.RecordQueryFetchFromPartialRecordPlan
- func GetPhysicalMultiIntersectionPlan(expr expressions.RelationalExpression) *plans.RecordQueryMultiIntersectionOnValuesPlan
- func HasMultipleFixedBindings(bindings []OrderingBinding) bool
- func IsPhysicalAggregateIndex(expr expressions.RelationalExpression) bool
- func IsPhysicalDefaultOnEmpty(expr expressions.RelationalExpression) bool
- func IsPhysicalDelete(expr expressions.RelationalExpression) bool
- func IsPhysicalDistinct(expr expressions.RelationalExpression) bool
- func IsPhysicalFetchFromPartialRecord(expr expressions.RelationalExpression) bool
- func IsPhysicalFilter(expr expressions.RelationalExpression) bool
- func IsPhysicalFirstOrDefault(expr expressions.RelationalExpression) bool
- func IsPhysicalFlatMap(expr expressions.RelationalExpression) bool
- func IsPhysicalInJoin(expr expressions.RelationalExpression) bool
- func IsPhysicalInUnion(expr expressions.RelationalExpression) bool
- func IsPhysicalIndexScan(expr expressions.RelationalExpression) bool
- func IsPhysicalInsert(expr expressions.RelationalExpression) bool
- func IsPhysicalIntersection(expr expressions.RelationalExpression) bool
- func IsPhysicalLimit(expr expressions.RelationalExpression) bool
- func IsPhysicalMap(expr expressions.RelationalExpression) bool
- func IsPhysicalMergeSortUnion(expr expressions.RelationalExpression) bool
- func IsPhysicalMultiIntersection(expr expressions.RelationalExpression) bool
- func IsPhysicalNestedLoopJoin(expr expressions.RelationalExpression) bool
- func IsPhysicalPredicatesFilter(expr expressions.RelationalExpression) bool
- func IsPhysicalRecursiveDfsJoin(expr expressions.RelationalExpression) bool
- func IsPhysicalRecursiveLevelUnion(expr expressions.RelationalExpression) bool
- func IsPhysicalStreamingAgg(expr expressions.RelationalExpression) bool
- func IsPhysicalUnorderedUnion(expr expressions.RelationalExpression) bool
- func IsPhysicalUpdate(expr expressions.RelationalExpression) bool
- func NestPullUp(pm PartialMatch, pullUp *PullUp, candidateAlias values.CorrelationIdentifier) (rootOfMatchPullUp *PullUp, currentPullUp *PullUp)
- func NewPhysicalDefaultOnEmptyWrapper(plan *plans.RecordQueryDefaultOnEmptyPlan, innerQuant expressions.Quantifier) *physicalDefaultOnEmptyWrapper
- func NewPhysicalDeleteWrapper(plan *plans.RecordQueryDeletePlan, innerQuant expressions.Quantifier) *physicalDeleteWrapper
- func NewPhysicalDistinctWrapper(plan *plans.RecordQueryDistinctPlan, innerQuant expressions.Quantifier) *physicalDistinctWrapper
- func NewPhysicalFetchFromPartialRecordWrapper(plan *plans.RecordQueryFetchFromPartialRecordPlan, ...) *physicalFetchFromPartialRecordWrapper
- func NewPhysicalFilterWrapper(plan *plans.RecordQueryFilterPlan, innerQuant expressions.Quantifier) *physicalFilterWrapper
- func NewPhysicalFirstOrDefaultWrapper(plan *plans.RecordQueryFirstOrDefaultPlan, innerQuant expressions.Quantifier) *physicalFirstOrDefaultWrapper
- func NewPhysicalInJoinWrapper(plan *plans.RecordQueryInJoinPlan, innerQuant expressions.Quantifier) *physicalInJoinWrapper
- func NewPhysicalInUnionWrapper(plan *plans.RecordQueryInUnionPlan, innerQuant expressions.Quantifier) *physicalInUnionWrapper
- func NewPhysicalInsertWrapper(plan *plans.RecordQueryInsertPlan, innerQuant expressions.Quantifier) *physicalInsertWrapper
- func NewPhysicalIntersectionWrapper(plan *plans.RecordQueryIntersectionPlan, innerQuants []expressions.Quantifier) *physicalIntersectionWrapper
- func NewPhysicalMapWrapper(plan *plans.RecordQueryMapPlan, innerQuant expressions.Quantifier) *physicalMapWrapper
- func NewPhysicalMergeSortUnionWrapper(plan *plans.RecordQueryMergeSortUnionPlan, ...) *physicalMergeSortUnionWrapper
- func NewPhysicalMultiIntersectionWrapper(plan *plans.RecordQueryMultiIntersectionOnValuesPlan, ...) *physicalMultiIntersectionWrapper
- func NewPhysicalPredicatesFilterWrapper(plan *plans.RecordQueryPredicatesFilterPlan, innerQuant expressions.Quantifier) *physicalPredicatesFilterWrapper
- func NewPhysicalProjectionWrapper(plan *plans.RecordQueryProjectionPlan, innerQuant expressions.Quantifier) *physicalProjectionWrapper
- func NewPhysicalTypeFilterWrapper(plan *plans.RecordQueryTypeFilterPlan, innerQuant expressions.Quantifier) *physicalTypeFilterWrapper
- func NewPhysicalUnionWrapper(plan *plans.RecordQueryUnionPlan, innerQuants []expressions.Quantifier) *physicalUnionWrapper
- func NewPhysicalUnorderedUnionWrapper(plan *plans.RecordQueryUnorderedUnionPlan, ...) *physicalUnorderedUnionWrapper
- func NewPhysicalUpdateWrapper(plan *plans.RecordQueryUpdatePlan, innerQuant expressions.Quantifier) *physicalUpdateWrapper
- func NewPhysicalValuesWrapper(plan *plans.RecordQueryValuesPlan) *physicalValuesWrapper
- func NewPlanningCostModelLess(stats properties.StatisticsProvider) func(a, b expressions.RelationalExpression) bool
- func NewPlanningCostModelLessWithContext(stats properties.StatisticsProvider, ctx PlanContext) func(a, b expressions.RelationalExpression) bool
- func NormalizeDNF(pred predicates.QueryPredicate, sizeLimit int) (predicates.QueryPredicate, bool)
- func OrderingAliases(groupingAliases []values.CorrelationIdentifier, ...) []values.CorrelationIdentifier
- func PhysicalIndexScanName(expr expressions.RelationalExpression) string
- func PlanningCostModelLess(a, b expressions.RelationalExpression) bool
- func RegisteredRuleNames() []string
- func ResolveComparisonDirection(parts []ProvidedOrderingPart) bool
- func RewritingCostModelLess(a, b expressions.RelationalExpression) bool
- func SatisfiesAnyRequestedOrderings(pm PartialMatch, requestedOrderings []*RequestedOrdering) ([]*RequestedOrdering, *ScanDirection)
- func Set[T any](cm *ConstraintMap, ref *expressions.Reference, key *PlannerConstraint[T], ...)
- func Simplify(pred predicates.QueryPredicate, rules []CascadesRule) predicates.QueryPredicate
- func ValidatePlanInvariants(plan plans.RecordQueryPlan) error
- type AdjustedBuilder
- func (b *AdjustedBuilder) Build() *AdjustedMatchInfo
- func (b *AdjustedBuilder) GetGroupByMappings() *GroupByMappings
- func (b *AdjustedBuilder) GetMatchedOrderingParts() []*MatchedOrderingPart
- func (b *AdjustedBuilder) GetMaxMatchMap() *MaxMatchMap
- func (b *AdjustedBuilder) SetGroupByMappings(g *GroupByMappings) *AdjustedBuilder
- func (b *AdjustedBuilder) SetMatchedOrderingParts(parts []*MatchedOrderingPart) *AdjustedBuilder
- func (b *AdjustedBuilder) SetMaxMatchMap(m *MaxMatchMap) *AdjustedBuilder
- type AdjustedMatchInfo
- func (a *AdjustedMatchInfo) GetGroupByMappings() *GroupByMappings
- func (a *AdjustedMatchInfo) GetMatchedOrderingParts() []*MatchedOrderingPart
- func (a *AdjustedMatchInfo) GetMaxMatchMap() *MaxMatchMap
- func (a *AdjustedMatchInfo) GetRegularMatchInfo() *RegularMatchInfo
- func (a *AdjustedMatchInfo) GetUnderlying() MatchInfo
- func (a *AdjustedMatchInfo) IsAdjusted() bool
- func (a *AdjustedMatchInfo) IsRegular() bool
- type AggregateDataAccessRule
- type AggregateIndexMatchCandidate
- func (c *AggregateIndexMatchCandidate) CandidateName() string
- func (c *AggregateIndexMatchCandidate) ComputeBoundParameterPrefixMap(bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange) map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (c *AggregateIndexMatchCandidate) GetAggColumn() string
- func (c *AggregateIndexMatchCandidate) GetAggFunction() expressions.AggregateFunction
- func (c *AggregateIndexMatchCandidate) GetColumnNames() []string
- func (c *AggregateIndexMatchCandidate) GetRecordTypes() []string
- func (c *AggregateIndexMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
- func (c *AggregateIndexMatchCandidate) GetTraversal() *Traversal
- func (c *AggregateIndexMatchCandidate) IsUnique() bool
- func (c *AggregateIndexMatchCandidate) MatchesGroupBy(gb *expressions.GroupByExpression) bool
- func (c *AggregateIndexMatchCandidate) MatchesSingleAggregateOf(gb *expressions.GroupByExpression, aggIndex int) bool
- func (c *AggregateIndexMatchCandidate) ToScanPlan(prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, ...) plans.RecordQueryPlan
- type AliasMap
- func (m *AliasMap) Compose(other *AliasMap) *AliasMap
- func (m *AliasMap) ContainsMapping(source, target values.CorrelationIdentifier) bool
- func (m *AliasMap) ContainsSource(source values.CorrelationIdentifier) bool
- func (m *AliasMap) ContainsTarget(target values.CorrelationIdentifier) bool
- func (m *AliasMap) Derived(additions *AliasMap) *AliasMap
- func (m *AliasMap) ForwardMap() values.AliasMap
- func (m *AliasMap) GetSource(target values.CorrelationIdentifier) values.CorrelationIdentifier
- func (m *AliasMap) GetTarget(source values.CorrelationIdentifier) values.CorrelationIdentifier
- func (m *AliasMap) GetTargetOrEmpty(source values.CorrelationIdentifier) (values.CorrelationIdentifier, bool)
- func (m *AliasMap) IsEmpty() bool
- func (m *AliasMap) IsIdentity() bool
- func (m *AliasMap) Size() int
- func (m *AliasMap) Sources() []values.CorrelationIdentifier
- type AliasMapBuilder
- type AliasMapValueEquivalence
- type AndAbsorbOrRule
- type AndConstantSimplifyRule
- type AndDedupRule
- type AndFlattenRule
- type BiMap
- func NewBiMap[K comparable, V comparable]() *BiMap[K, V]
- func NewBiMapFromMap[K comparable, V comparable](m map[K]V) *BiMap[K, V]
- func NewBiMapWith[K any, V any](keyStr func(K) string, valStr func(V) string) *BiMap[K, V]
- func NewCorrValueBiMap() *BiMap[values.CorrelationIdentifier, values.Value]
- func NewValueBiMap() *BiMap[values.Value, values.Value]
- func (b *BiMap[K, V]) Copy() *BiMap[K, V]
- func (b *BiMap[K, V]) Get(key K) (V, bool)
- func (b *BiMap[K, V]) GetInverse(value V) (K, bool)
- func (b *BiMap[K, V]) Len() int
- func (b *BiMap[K, V]) Put(key K, value V)
- func (b *BiMap[K, V]) PutAll(other *BiMap[K, V])
- func (b *BiMap[K, V]) Range(fn func(key K, value V) bool)
- type BitSet
- func (b *BitSet) And(other *BitSet) *BitSet
- func (b *BitSet) Cardinality() int
- func (b *BitSet) Equal(other *BitSet) bool
- func (b *BitSet) Get(pos int) bool
- func (b *BitSet) IsSubsetOf(other *BitSet) bool
- func (b *BitSet) Or(other *BitSet) *BitSet
- func (b *BitSet) Set(pos int)
- func (b *BitSet) String() string
- type CascadesRule
- type ComparisonConstantSimplifyRule
- type CompensatedResult
- type Compensation
- type ConstrainedBoolean
- type ConstraintMap
- type CrossProductIterator
- type DeMorganRule
- type DecorrelateValuesRule
- type DistinctMergeRule
- type DistinctOverGroupByElimRule
- type DistinctOverSortElimRule
- type DistinctOverUnionDedupRule
- type Distinctness
- type EliminateNullOnEmptyRule
- type ExploreExprTask
- type ExploreGroupTask
- type ExpressionMatchAdjuster
- type ExpressionMatcher
- type ExpressionRule
- func BatchAExpressionRules() []ExpressionRule
- func DMLImplementationRules() []ExpressionRule
- func DefaultExpressionRules() []ExpressionRule
- func LookupRule(name string) ExpressionRule
- func MatchingRules() []ExpressionRule
- func PlanningExplorationRules() []ExpressionRule
- func RegisterRule(name string, r ExpressionRule) ExpressionRule
- func RewritingRules() []ExpressionRule
- type ExpressionRuleCall
- func (c *ExpressionRuleCall) CostModel() func(a, b expressions.RelationalExpression) bool
- func (c *ExpressionRuleCall) GetRequestedOrderings() []*RequestedOrdering
- func (c *ExpressionRuleCall) MemoizeExpression(expr expressions.RelationalExpression) *expressions.Reference
- func (c *ExpressionRuleCall) Yield(expr expressions.RelationalExpression) bool
- func (c *ExpressionRuleCall) Yielded() []expressions.RelationalExpression
- type FilterDedupPredicatesRule
- type FilterDropTruePredicatesRule
- type FilterMergeRule
- type FinalizeExpressionsRule
- type ForMatchCompensation
- func (c *ForMatchCompensation) Apply(expr expressions.RelationalExpression, translationMapFunc TranslationMapFunc) expressions.RelationalExpression
- func (c *ForMatchCompensation) ApplyAllNeeded(expr expressions.RelationalExpression, translationMapFunc TranslationMapFunc) expressions.RelationalExpression
- func (c *ForMatchCompensation) ApplyFinal(expr expressions.RelationalExpression, translationMapFunc TranslationMapFunc) expressions.RelationalExpression
- func (c *ForMatchCompensation) CanBeDeferred() bool
- func (c *ForMatchCompensation) Derived(impossible bool, predicateCompensationMap *PredicateCompensationMap, ...) *ForMatchCompensation
- func (c *ForMatchCompensation) GetChildCompensation() Compensation
- func (c *ForMatchCompensation) GetCompensatedAliases() map[values.CorrelationIdentifier]struct{}
- func (c *ForMatchCompensation) GetGroupByMappings() *GroupByMappings
- func (c *ForMatchCompensation) GetMatchedForEachAlias() values.CorrelationIdentifier
- func (c *ForMatchCompensation) GetMatchedQuantifiers() []expressions.Quantifier
- func (c *ForMatchCompensation) GetPredicateCompensationMap() *PredicateCompensationMap
- func (c *ForMatchCompensation) GetResultCompensationFunction() *ResultCompensationFunction
- func (c *ForMatchCompensation) GetUnmatchedForEachQuantifiers() []expressions.Quantifier
- func (c *ForMatchCompensation) GetUnmatchedQuantifiers() []expressions.Quantifier
- func (c *ForMatchCompensation) Intersect(other *ForMatchCompensation) Compensation
- func (c *ForMatchCompensation) IsFinalNeeded() bool
- func (c *ForMatchCompensation) IsImpossible() bool
- func (c *ForMatchCompensation) IsNeeded() bool
- func (c *ForMatchCompensation) IsNeededForFiltering() bool
- func (c *ForMatchCompensation) String() string
- func (c *ForMatchCompensation) Union(other *ForMatchCompensation) Compensation
- type GraphExpansion
- func (g *GraphExpansion) GetPlaceholders() []*predicates.Placeholder
- func (g *GraphExpansion) GetPredicates() []predicates.QueryPredicate
- func (g *GraphExpansion) GetQuantifiers() []expressions.Quantifier
- func (g *GraphExpansion) GetResultColumns() []GraphExpansionColumn
- func (g *GraphExpansion) Seal() *SealedGraphExpansion
- type GraphExpansionBuilder
- func (b *GraphExpansionBuilder) AddColumn(name string, value values.Value) *GraphExpansionBuilder
- func (b *GraphExpansionBuilder) AddPlaceholder(p *predicates.Placeholder) *GraphExpansionBuilder
- func (b *GraphExpansionBuilder) AddPredicate(pred predicates.QueryPredicate) *GraphExpansionBuilder
- func (b *GraphExpansionBuilder) AddQuantifier(q expressions.Quantifier) *GraphExpansionBuilder
- func (b *GraphExpansionBuilder) Build() *GraphExpansion
- type GraphExpansionColumn
- type GroupByMappings
- type ImplementDeleteRule
- type ImplementDistinctFinalRule
- type ImplementDistinctUnionRule
- type ImplementExplodeRule
- type ImplementFilterRule
- type ImplementInJoinRule
- type ImplementInMemorySortRule
- type ImplementInUnionRule
- type ImplementInsertRule
- type ImplementIntersectionRule
- type ImplementLimitRule
- type ImplementNestedLoopJoinRule
- type ImplementProjectionFinalRule
- type ImplementProjectionRule
- type ImplementRecursiveDfsJoinRule
- type ImplementRecursiveLevelUnionRule
- type ImplementSimpleSelectRule
- type ImplementSortRule
- type ImplementStreamingAggregationRule
- type ImplementTableFunctionRule
- type ImplementTempTableInsertRule
- type ImplementTempTableScanRule
- type ImplementTypeFilterRule
- type ImplementUnionRule
- type ImplementUniqueRule
- type ImplementUnorderedUnionRule
- type ImplementUpdateRule
- type ImplementValuesRule
- type ImplementationRule
- type ImplementationRuleCall
- func (c *ImplementationRuleCall) GetRequestedOrderings() []*RequestedOrdering
- func (c *ImplementationRuleCall) IsConstraintOnly() bool
- func (c *ImplementationRuleCall) MemoizeFinalExpression(expr expressions.RelationalExpression) *expressions.Reference
- func (c *ImplementationRuleCall) MemoizeFinalExpressionsFromOther(source *expressions.Reference, exprs []expressions.RelationalExpression) *expressions.Reference
- func (c *ImplementationRuleCall) PushConstraint(childRef *expressions.Reference, orderings []*RequestedOrdering)
- func (c *ImplementationRuleCall) Yield(expr expressions.RelationalExpression)
- func (c *ImplementationRuleCall) YieldFinalExpression(expr expressions.RelationalExpression)
- type InComparisonToExplodeRule
- type InParameterSource
- type InSource
- type InValuesSource
- type IndexDef
- type IndexDefWithColumnFunctions
- type InitiatePlannerPhaseTask
- type IntersectionInfo
- func IntersectionInfoOfImpossibleAccess(ordering *RichOrdering, comp Compensation) *IntersectionInfo
- func IntersectionInfoOfIntersection(ordering *RichOrdering, comp Compensation, ...) *IntersectionInfo
- func IntersectionInfoOfSingleAccess(ordering *RichOrdering, comp Compensation, ...) *IntersectionInfo
- func NewIntersectionInfo(ordering *RichOrdering, comp Compensation, ...) *IntersectionInfo
- type IntersectionMergeRule
- type IntersectionResult
- type IntersectionSingletonElimRule
- type IntersectorFunc
- type LimitMergeRule
- type MappingKey
- type MappingKind
- type MatchCandidate
- type MatchInfo
- type MatchIntermediateRule
- type MatchLeafRule
- type MatchPartition
- type MatchedOrderingPart
- func (m *MatchedOrderingPart) Demote() *MatchedOrderingPart
- func (m *MatchedOrderingPart) GetComparisonRange() *predicates.ComparisonRange
- func (m *MatchedOrderingPart) GetComparisonRangeType() predicates.ComparisonRangeType
- func (m *MatchedOrderingPart) GetMatchedSortOrder() MatchedSortOrder
- func (m *MatchedOrderingPart) GetParameterId() values.CorrelationIdentifier
- func (m *MatchedOrderingPart) GetValue() values.Value
- func (m *MatchedOrderingPart) String() string
- type MatchedSortOrder
- func (s MatchedSortOrder) ArrowIndicator() string
- func (s MatchedSortOrder) IsAnyAscending() bool
- func (s MatchedSortOrder) IsAnyDescending() bool
- func (s MatchedSortOrder) IsCounterflowNulls() bool
- func (s MatchedSortOrder) IsDirectional() bool
- func (s MatchedSortOrder) String() string
- func (s MatchedSortOrder) ToProvidedSortOrder(isReverse bool) ProvidedSortOrder
- type MaxMatchMap
- func ComputeMaxMatchMap(queryValue values.Value, candidateValue values.Value, ...) *MaxMatchMap
- func ComputeMaxMatchMapWithEquivalence(queryValue values.Value, candidateValue values.Value, ...) *MaxMatchMap
- func NewMaxMatchMap(mapping map[values.Value]values.Value, queryValue values.Value, ...) *MaxMatchMap
- func (m *MaxMatchMap) AdjustMaybe(upperCandidateAlias values.CorrelationIdentifier, ...) (*MaxMatchMap, bool)
- func (m *MaxMatchMap) GetCandidateValue() values.Value
- func (m *MaxMatchMap) GetMap() map[values.Value]values.Value
- func (m *MaxMatchMap) GetQueryValue() values.Value
- func (m *MaxMatchMap) PullUpMaybe(queryAlias values.CorrelationIdentifier, ...) (*RegularTranslationMap, bool)
- func (m *MaxMatchMap) Size() int
- func (m *MaxMatchMap) TranslateQueryValueMaybe(candidateAlias values.CorrelationIdentifier) values.Value
- type Memo
- func (m *Memo) AddExpression(ref *expressions.Reference, expr expressions.RelationalExpression)
- func (m *Memo) AliasAwareDedups() int
- func (m *Memo) ContainsReference(ref *expressions.Reference) bool
- func (m *Memo) Integrate(ref *expressions.Reference, expr expressions.RelationalExpression)
- func (m *Memo) MemoizeExpression(expr expressions.RelationalExpression) *expressions.Reference
- func (m *Memo) MemoizeExpressions(exprs []expressions.RelationalExpression) *expressions.Reference
- func (m *Memo) MergeArmHits() int
- func (m *Memo) MergeCount() int
- func (m *Memo) NextMergeAlias() values.CorrelationIdentifier
- func (m *Memo) RecordMergeArmHit()
- func (m *Memo) References() map[*expressions.Reference]struct{}
- func (m *Memo) RegisterReference(ref *expressions.Reference)
- func (m *Memo) Root() *expressions.Reference
- func (m *Memo) TotalMembers() int
- type MergeFetchIntoCoveringIndexRule
- type MergeProjectionAndFetchRule
- type NoOpFilterRule
- type NoOpLimitElimRule
- type NormalizePredicatesRule
- type NotComparisonRewriteRule
- type NotConstantSimplifyRule
- type OptimizeGroupTask
- type OptimizeInputsTask
- type OrAbsorbAndRule
- type OrConstantSimplifyRule
- type OrDedupRule
- type OrFlattenRule
- type OrderedIndexScanRule
- type OrderedPrimaryScanRule
- type OrderingBinding
- type OrderingBindingKind
- type OrderingMergeKind
- type OrderingPartsComputer
- type PartialMatch
- type PartialMatchImpl
- func (p *PartialMatchImpl) CompensateCompleteMatch(unificationPullUp *PullUp, candidateTopAlias values.CorrelationIdentifier) Compensation
- func (p *PartialMatchImpl) CompensationCanBeDeferred() bool
- func (p *PartialMatchImpl) GetBoundAliasMap() *AliasMap
- func (p *PartialMatchImpl) GetBoundParameterPrefixMap() map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (p *PartialMatchImpl) GetBoundSargableAliases() map[values.CorrelationIdentifier]struct{}
- func (p *PartialMatchImpl) GetCandidateRef() *expressions.Reference
- func (p *PartialMatchImpl) GetCompensatedAliases() map[values.CorrelationIdentifier]struct{}
- func (p *PartialMatchImpl) GetMatchCandidate() MatchCandidate
- func (p *PartialMatchImpl) GetMatchInfo() MatchInfo
- func (p *PartialMatchImpl) GetMatchedQuantifiers() []expressions.Quantifier
- func (p *PartialMatchImpl) GetQueryExpression() expressions.RelationalExpression
- func (p *PartialMatchImpl) GetQueryRef() *expressions.Reference
- func (p *PartialMatchImpl) GetRegularMatchInfo() *RegularMatchInfo
- func (p *PartialMatchImpl) GetUnmatchedQuantifiers() []expressions.Quantifier
- func (p *PartialMatchImpl) PullUp(candidateAlias values.CorrelationIdentifier) *PullUp
- func (p *PartialMatchImpl) String() string
- type PartitionBinarySelectRule
- type PartitionSelectRule
- type PlanContext
- type PlanPartition
- func FilterPlanPartitions(partitions []*PlanPartition, pred func(*PlanPartition) bool) []*PlanPartition
- func NewPlanPartition(partitionProps properties.PropertyMap, ...) *PlanPartition
- func RollUpPlanPartitions(partitions []*PlanPartition, ...) []*PlanPartition
- func SelectMinCostPartition(partitions []*PlanPartition) *PlanPartition
- func ToPlanPartitions(ref *expressions.Reference) []*PlanPartition
- func WhereDistinct(partitions []*PlanPartition) []*PlanPartition
- func WhereOrdered(partitions []*PlanPartition) []*PlanPartition
- func WhereStored(partitions []*PlanPartition) []*PlanPartition
- func (p *PlanPartition) GetExpressionPropertyValue(expr expressions.RelationalExpression, prop *properties.ExpressionProperty) any
- func (p *PlanPartition) GetExpressions() []expressions.RelationalExpression
- func (p *PlanPartition) GetOrdering() properties.Ordering
- func (p *PlanPartition) GetPartitionPropertiesMap() properties.PropertyMap
- func (p *PlanPartition) GetPartitionPropertyValue(prop *properties.ExpressionProperty) any
- func (p *PlanPartition) GetPlans() []plans.RecordQueryPlan
- func (p *PlanPartition) HasPrimaryKey() bool
- func (p *PlanPartition) IsDistinct() bool
- func (p *PlanPartition) IsStoredRecord() bool
- type PlanPropertiesMap
- func (m *PlanPropertiesMap) Add(w physicalPlanExpression)
- func (m *PlanPropertiesMap) All() map[expressions.RelationalExpression]properties.PropertyMap
- func (m *PlanPropertiesMap) Expressions() []expressions.RelationalExpression
- func (m *PlanPropertiesMap) GetProperties(expr expressions.RelationalExpression) properties.PropertyMap
- type Planner
- func (p *Planner) BestMember(ref *expressions.Reference) expressions.RelationalExpression
- func (p *Planner) HasBestMember(ref *expressions.Reference) bool
- func (p *Planner) Memo() *Memo
- func (p *Planner) Plan(rootRef *expressions.Reference) (expressions.RelationalExpression, int, error)
- func (p *Planner) Statistics() properties.StatisticsProvider
- func (p *Planner) WithCostModel(less func(a, b expressions.RelationalExpression) bool) *Planner
- func (p *Planner) WithImplementationRules(rules []ImplementationRule) *Planner
- func (p *Planner) WithMaxTasks(n int) *Planner
- func (p *Planner) WithPlanningExpressionRules(rules []ExpressionRule) *Planner
- func (p *Planner) WithStatistics(stats properties.StatisticsProvider) *Planner
- type PlannerConfiguration
- type PlannerConstraint
- type PlannerPhase
- type PredicateCompensation
- type PredicateCompensationFunc
- type PredicateCompensationMap
- func (m *PredicateCompensationMap) Amend(unmatchedAggregateMap *BiMap[values.CorrelationIdentifier, values.Value], ...) *PredicateCompensationMap
- func (m *PredicateCompensationMap) ApplyCompensations(tm TranslationMap) []predicates.QueryPredicate
- func (m *PredicateCompensationMap) Entries() ([]predicates.QueryPredicate, []PredicateCompensationFunc)
- func (m *PredicateCompensationMap) Get(key predicates.QueryPredicate) PredicateCompensationFunc
- func (m *PredicateCompensationMap) IsEmpty() bool
- func (m *PredicateCompensationMap) Len() int
- type PredicateMap
- type PredicateMapBuilder
- type PredicateMapping
- func (m *PredicateMapping) GetCandidatePredicate() predicates.QueryPredicate
- func (m *PredicateMapping) GetComparisonRange() *predicates.ComparisonRange
- func (m *PredicateMapping) GetConstraint() *QueryPlanConstraint
- func (m *PredicateMapping) GetMappingKey() MappingKey
- func (m *PredicateMapping) GetMappingKind() MappingKind
- func (m *PredicateMapping) GetOriginalQueryPredicate() predicates.QueryPredicate
- func (m *PredicateMapping) GetParameterAlias() *values.CorrelationIdentifier
- func (m *PredicateMapping) GetPredicateCompensation() PredicateCompensation
- func (m *PredicateMapping) GetTranslatedQueryPredicate() predicates.QueryPredicate
- func (m *PredicateMapping) ToBuilder() *PredicateMappingBuilder
- func (m *PredicateMapping) WithTranslatedQueryPredicate(translated predicates.QueryPredicate) *PredicateMapping
- type PredicateMappingBuilder
- func (b *PredicateMappingBuilder) Build() *PredicateMapping
- func (b *PredicateMappingBuilder) SetComparisonRange(cr *predicates.ComparisonRange) *PredicateMappingBuilder
- func (b *PredicateMappingBuilder) SetConstraint(c *QueryPlanConstraint) *PredicateMappingBuilder
- func (b *PredicateMappingBuilder) SetParameterAlias(alias values.CorrelationIdentifier) *PredicateMappingBuilder
- func (b *PredicateMappingBuilder) SetPredicateCompensation(c PredicateCompensation) *PredicateMappingBuilder
- func (b *PredicateMappingBuilder) SetSargable(alias values.CorrelationIdentifier, cr *predicates.ComparisonRange) *PredicateMappingBuilder
- func (b *PredicateMappingBuilder) SetTranslatedQueryPredicate(p predicates.QueryPredicate) *PredicateMappingBuilder
- type PredicateMultiMap
- func (m *PredicateMultiMap) Entries() []struct{ ... }
- func (m *PredicateMultiMap) Get(pred predicates.QueryPredicate) []*PredicateMapping
- func (m *PredicateMultiMap) KeySet() []predicates.QueryPredicate
- func (m *PredicateMultiMap) PredicateCount() int
- func (m *PredicateMultiMap) Size() int
- func (m *PredicateMultiMap) Values() []*PredicateMapping
- type PredicateMultiMapBuilder
- func (b *PredicateMultiMapBuilder) Build() *PredicateMultiMap
- func (b *PredicateMultiMapBuilder) BuildMaybe() *PredicateMultiMap
- func (b *PredicateMultiMapBuilder) Put(queryPredicate predicates.QueryPredicate, mapping *PredicateMapping) bool
- func (b *PredicateMultiMapBuilder) PutAll(other *PredicateMultiMap) bool
- func (b *PredicateMultiMapBuilder) PutAllMappings(queryPredicate predicates.QueryPredicate, mappings []*PredicateMapping) bool
- type PredicatePushDownRule
- type PredicateToLogicalUnionRule
- type PrimaryScanMatchCandidate
- func (c *PrimaryScanMatchCandidate) CandidateName() string
- func (c *PrimaryScanMatchCandidate) ComputeBoundParameterPrefixMap(bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange) map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (c *PrimaryScanMatchCandidate) GetAvailableRecordTypes() []string
- func (c *PrimaryScanMatchCandidate) GetBaseType() values.Type
- func (c *PrimaryScanMatchCandidate) GetColumnNames() []string
- func (c *PrimaryScanMatchCandidate) GetPrimaryKeyValues() []values.Value
- func (c *PrimaryScanMatchCandidate) GetRecordTypes() []string
- func (c *PrimaryScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
- func (c *PrimaryScanMatchCandidate) GetTraversal() *Traversal
- func (c *PrimaryScanMatchCandidate) IsUnique() bool
- func (c *PrimaryScanMatchCandidate) String() string
- func (c *PrimaryScanMatchCandidate) ToScanPlan(prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, ...) plans.RecordQueryPlan
- type PrimaryScanRule
- type ProjectionElimRule
- type ProjectionMergeRule
- type ProvidedOrderingPart
- type ProvidedSortOrder
- func (s ProvidedSortOrder) IsAnyAscending() bool
- func (s ProvidedSortOrder) IsAnyDescending() bool
- func (p ProvidedSortOrder) IsCompatibleWithRequestedSortOrder(req RequestedSortOrder) bool
- func (s ProvidedSortOrder) IsCounterflowNulls() bool
- func (s ProvidedSortOrder) IsDirectional() bool
- func (s ProvidedSortOrder) ToRequestedSortOrder() RequestedSortOrder
- type PullCommonFilterAboveIntersectionRule
- type PullCommonFilterAboveUnionRule
- type PullFilterAboveDistinctRule
- type PullUp
- func (p *PullUp) GetCandidateAlias() values.CorrelationIdentifier
- func (p *PullUp) GetParent() *PullUp
- func (p *PullUp) GetPullThroughValue() values.Value
- func (p *PullUp) GetRangedOverAliases() map[values.CorrelationIdentifier]struct{}
- func (p *PullUp) GetRoot() *PullUp
- func (p *PullUp) IsRoot() bool
- func (p *PullUp) PullUpValueMaybe(v values.Value) values.Value
- func (p *PullUp) PullUpValueMaybeWithEquivalence(v values.Value, ve ValueEquivalence) values.Value
- type PushDistinctBelowFilterRule
- type PushDistinctThroughFetchRule
- type PushFilterBelowJoinRule
- type PushFilterThroughDistinctRule
- type PushFilterThroughFetchRule
- type PushFilterThroughGroupByRule
- type PushFilterThroughIntersectionRule
- type PushFilterThroughTypeFilterRule
- type PushFilterThroughUnionRule
- type PushInJoinThroughFetchRule
- type PushInUnionThroughFetchRule
- type PushIntersectionThroughFetchRule
- type PushLimitThroughProjectionRule
- type PushLimitThroughUnionRule
- type PushMapThroughFetchRule
- type PushReferencedFieldsThroughDistinctRule
- type PushReferencedFieldsThroughFilterRule
- type PushReferencedFieldsThroughSelectRule
- type PushReferencedFieldsThroughUniqueRule
- type PushRequestedOrderingThroughDeleteRule
- type PushRequestedOrderingThroughDistinctRule
- type PushRequestedOrderingThroughFilterRule
- type PushRequestedOrderingThroughGroupByRule
- type PushRequestedOrderingThroughInLikeSelectRule
- type PushRequestedOrderingThroughInsertRule
- type PushRequestedOrderingThroughProjectionRule
- type PushRequestedOrderingThroughRecursiveUnionRule
- type PushRequestedOrderingThroughSelectExistentialRule
- type PushRequestedOrderingThroughSelectRule
- type PushRequestedOrderingThroughSortRule
- type PushRequestedOrderingThroughTempTableInsertRule
- type PushRequestedOrderingThroughUnionRule
- type PushRequestedOrderingThroughUniqueRule
- type PushRequestedOrderingThroughUpdateRule
- type PushTypeFilterBelowFilterRule
- type PushUnionThroughFetchRule
- type PushUnorderedUnionThroughFetchRule
- type QueryPlanConstraint
- type QueryPredicateSimplificationRule
- type ReferencedFields
- type RegularMatchInfo
- func (r *RegularMatchInfo) GetAdditionalPlanConstraint() *QueryPlanConstraint
- func (r *RegularMatchInfo) GetBindingAliasMap() *AliasMap
- func (r *RegularMatchInfo) GetChildPartialMatchMaybe(alias values.CorrelationIdentifier) PartialMatch
- func (r *RegularMatchInfo) GetGroupByMappings() *GroupByMappings
- func (r *RegularMatchInfo) GetMatchedOrderingParts() []*MatchedOrderingPart
- func (r *RegularMatchInfo) GetMaxMatchMap() *MaxMatchMap
- func (r *RegularMatchInfo) GetParameterBindingMap() map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (r *RegularMatchInfo) GetPredicateMap() *PredicateMultiMap
- func (r *RegularMatchInfo) GetRegularMatchInfo() *RegularMatchInfo
- func (r *RegularMatchInfo) GetRollUpToGroupingValues() []values.Value
- func (r *RegularMatchInfo) IsAdjusted() bool
- func (r *RegularMatchInfo) IsRegular() bool
- func (r *RegularMatchInfo) SetChildPartialMatch(alias values.CorrelationIdentifier, pm PartialMatch)
- type RegularTranslationMap
- func (m *RegularTranslationMap) ApplyTranslationFunction(sourceAlias values.CorrelationIdentifier, leafValue values.LeafValue) values.Value
- func (m *RegularTranslationMap) ContainsSourceAlias(sourceAlias values.CorrelationIdentifier) bool
- func (m *RegularTranslationMap) DefinesOnlyIdentities() bool
- func (m *RegularTranslationMap) GetAliasMap() (*AliasMap, bool)
- func (m *RegularTranslationMap) GetTargetAlias(sourceAlias values.CorrelationIdentifier) (values.CorrelationIdentifier, bool)
- type RemoveProjectionRule
- type RemoveRangeOneRule
- type RequestedOrdering
- func (o *RequestedOrdering) Exhaustive() *RequestedOrdering
- func (o *RequestedOrdering) GetDistinctness() Distinctness
- func (o *RequestedOrdering) GetParts() []RequestedOrderingPart
- func (o *RequestedOrdering) GetValueRequestedSortOrderMap() map[values.Value]RequestedSortOrder
- func (o *RequestedOrdering) IsDistinct() bool
- func (o *RequestedOrdering) IsExhaustive() bool
- func (o *RequestedOrdering) IsPreserve() bool
- func (o *RequestedOrdering) PushDownThroughValue(resultValue values.Value, upperAlias values.CorrelationIdentifier) *RequestedOrdering
- func (o *RequestedOrdering) Size() int
- type RequestedOrderingPart
- type RequestedSortOrder
- type ResultCompensationFunction
- func (f *ResultCompensationFunction) Amend(unmatchedAggregateMap *BiMap[values.CorrelationIdentifier, values.Value], ...) *ResultCompensationFunction
- func (f *ResultCompensationFunction) ApplyCompensationForResult(tm TranslationMap) values.Value
- func (f *ResultCompensationFunction) IsImpossible() bool
- func (f *ResultCompensationFunction) IsNeeded() bool
- type RewriteOuterJoinRule
- type RichOrdering
- func ConcatOrderings(outer, inner *RichOrdering) *RichOrdering
- func CreateUnionOrdering(o *RichOrdering) *RichOrdering
- func EmptyOrdering() *RichOrdering
- func MergeOrderings(a, b *RichOrdering) *RichOrdering
- func MergeOrderingsForIntersection(a, b *RichOrdering) *RichOrdering
- func MergeOrderingsForUnion(a, b *RichOrdering) *RichOrdering
- func NewRichOrdering(bindingMap map[values.Value][]OrderingBinding, keys []values.Value, ...) *RichOrdering
- func NewRichOrderingWithDeps(bindingMap map[values.Value][]OrderingBinding, keys []values.Value, ...) *RichOrdering
- func (o *RichOrdering) DirectionalOrderingParts(keyValues []values.Value, requested *RequestedOrdering, ...) []ProvidedOrderingPart
- func (o *RichOrdering) EnumerateCompatibleRequestedOrderings(requested *RequestedOrdering) [][]RequestedOrderingPart
- func (o *RichOrdering) EnumerateSatisfyingComparisonKeyValues(requested *RequestedOrdering) [][]values.Value
- func (o *RichOrdering) GetBindingMap() map[values.Value][]OrderingBinding
- func (o *RichOrdering) GetEqualityBoundValues() map[values.Value]struct{}
- func (o *RichOrdering) GetKeys() []values.Value
- func (o *RichOrdering) GetOrderingKeys() []values.Value
- func (o *RichOrdering) IsDistinct() bool
- func (o *RichOrdering) IsSingularNonFixedValue(v values.Value) bool
- func (o *RichOrdering) OrderingSet() *combinatorics.PartiallyOrderedSet[string]
- func (o *RichOrdering) PullUp(mapping map[string]values.Value) *RichOrdering
- func (o *RichOrdering) PullUpThroughValue(resultValue values.Value, alias values.CorrelationIdentifier) *RichOrdering
- func (o *RichOrdering) PushDown(mapping map[string]values.Value) *RichOrdering
- func (o *RichOrdering) PushDownThroughValue(resultValue values.Value, upperAlias values.CorrelationIdentifier) *RichOrdering
- func (o *RichOrdering) Satisfies(requested *RequestedOrdering) bool
- func (o *RichOrdering) SatisfiesGroupingValues(groupingValues map[string]struct{}) bool
- func (o *RichOrdering) ValueForKey(key string) values.Value
- type RichOrderingHinter
- type RuleCall
- type ScanDirection
- type ScanWithFetchMatchCandidate
- type SealedGraphExpansion
- func (s *SealedGraphExpansion) BuildSelect() *expressions.SelectExpression
- func (s *SealedGraphExpansion) BuildSelectWithResultValue(resultValue values.Value) *expressions.SelectExpression
- func (s *SealedGraphExpansion) GetPlaceholders() []*predicates.Placeholder
- func (s *SealedGraphExpansion) GetPredicates() []predicates.QueryPredicate
- func (s *SealedGraphExpansion) GetQuantifiers() []expressions.Quantifier
- func (s *SealedGraphExpansion) GetResultColumns() []GraphExpansionColumn
- func (s *SealedGraphExpansion) GetResultValue() values.Value
- type SelectMergeRule
- type SingleMatchedAccess
- func (s *SingleMatchedAccess) GetCandidateTopAlias() values.CorrelationIdentifier
- func (s *SingleMatchedAccess) GetCompensation() Compensation
- func (s *SingleMatchedAccess) GetPartialMatch() PartialMatch
- func (s *SingleMatchedAccess) GetPulledUpGroupByMappingsForOrdering() *GroupByMappings
- func (s *SingleMatchedAccess) GetSatisfyingRequestedOrderings() []*RequestedOrdering
- func (s *SingleMatchedAccess) GetTopToTopTranslationMap() TranslationMap
- func (s *SingleMatchedAccess) IsReverseScanOrder() bool
- func (s *SingleMatchedAccess) String() string
- type SinkLimitIntoVectorScanRule
- type SortConstantKeysElimRule
- type SortDedupKeysRule
- type SortMergeRule
- type SortedInParameterSource
- type SortedInValuesSource
- type SplitSelectExtractIndependentQuantifiersRule
- type StreamingAggFromIndexRule
- type Task
- type TempTable
- type TransformExprTask
- type TransformImplTask
- type TranslationFunction
- type TranslationMap
- type TranslationMapBuilder
- func (b *TranslationMapBuilder) Build() *RegularTranslationMap
- func (b *TranslationMapBuilder) Compose(other *RegularTranslationMap) *TranslationMapBuilder
- func (b *TranslationMapBuilder) When(sourceAlias values.CorrelationIdentifier) *TranslationMapWhen
- func (b *TranslationMapBuilder) WhenAny(sourceAliases []values.CorrelationIdentifier) *TranslationMapWhenAny
- type TranslationMapFunc
- type TranslationMapWhen
- type TranslationMapWhenAny
- type Traversal
- func (t *Traversal) FindReferencingExpressions(childRefs []*expressions.Reference) map[*expressions.Reference][]expressions.RelationalExpression
- func (t *Traversal) GetLeafReferences() []*expressions.Reference
- func (t *Traversal) GetParentRefPairs(childRef *expressions.Reference) []refExprPair
- func (t *Traversal) GetRootReference() *expressions.Reference
- type TypeFilterMergeRule
- type TypeFilterRedundantOverScanRule
- type UnionMergeRule
- type UnionSingletonElimRule
- type UnplannableIndexOnlyResidualError
- type UnsortedSortElimRule
- type ValueEquivalence
- type ValueIndexLikeMatchCandidate
- type ValueIndexScanMatchCandidate
- func (c *ValueIndexScanMatchCandidate) CandidateName() string
- func (c *ValueIndexScanMatchCandidate) ColumnValue(i int, base values.Value) values.Value
- func (c *ValueIndexScanMatchCandidate) ComputeBoundParameterPrefixMap(bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange) map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (c *ValueIndexScanMatchCandidate) ComputeMatchedOrderingParts(matchInfo MatchInfo, sortParameterIDs []values.CorrelationIdentifier, ...) []*MatchedOrderingPart
- func (c *ValueIndexScanMatchCandidate) CreatesDuplicates() bool
- func (c *ValueIndexScanMatchCandidate) GetBaseType() values.Type
- func (c *ValueIndexScanMatchCandidate) GetColumnNames() []string
- func (c *ValueIndexScanMatchCandidate) GetColumnSize() int
- func (c *ValueIndexScanMatchCandidate) GetRecordTypes() []string
- func (c *ValueIndexScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
- func (c *ValueIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
- func (c *ValueIndexScanMatchCandidate) GetTraversal() *Traversal
- func (c *ValueIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey() bool
- func (c *ValueIndexScanMatchCandidate) IsUnique() bool
- func (c *ValueIndexScanMatchCandidate) PushValueThroughFetch(value values.Value, sourceAlias values.CorrelationIdentifier, ...) (values.Value, bool)
- func (c *ValueIndexScanMatchCandidate) ToScanPlan(prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, ...) plans.RecordQueryPlan
- type ValuePredicateConstantFoldRule
- type VectorIndexScanMatchCandidate
- func (c *VectorIndexScanMatchCandidate) CandidateName() string
- func (c *VectorIndexScanMatchCandidate) ComputeBoundParameterPrefixMap(bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange) map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (c *VectorIndexScanMatchCandidate) CreatesDuplicates() bool
- func (c *VectorIndexScanMatchCandidate) EmitsOrderedStream() bool
- func (c *VectorIndexScanMatchCandidate) GetBaseType() values.Type
- func (c *VectorIndexScanMatchCandidate) GetColumnNames() []string
- func (c *VectorIndexScanMatchCandidate) GetColumnSize() int
- func (c *VectorIndexScanMatchCandidate) GetOrderingAliases() []values.CorrelationIdentifier
- func (c *VectorIndexScanMatchCandidate) GetPrimaryKeyValues() []values.Value
- func (c *VectorIndexScanMatchCandidate) GetRecordTypes() []string
- func (c *VectorIndexScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
- func (c *VectorIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
- func (c *VectorIndexScanMatchCandidate) GetTraversal() *Traversal
- func (c *VectorIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey() bool
- func (c *VectorIndexScanMatchCandidate) IsUnique() bool
- func (c *VectorIndexScanMatchCandidate) String() string
- func (c *VectorIndexScanMatchCandidate) ToScanPlan(prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, _ bool) plans.RecordQueryPlan
- type Vectored
- type WindowedIndexScanMatchCandidate
- func (c *WindowedIndexScanMatchCandidate) CandidateName() string
- func (c *WindowedIndexScanMatchCandidate) ComputeBoundParameterPrefixMap(bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange) map[values.CorrelationIdentifier]*predicates.ComparisonRange
- func (c *WindowedIndexScanMatchCandidate) CreatesDuplicates() bool
- func (c *WindowedIndexScanMatchCandidate) GetBaseType() values.Type
- func (c *WindowedIndexScanMatchCandidate) GetColumnNames() []string
- func (c *WindowedIndexScanMatchCandidate) GetColumnSize() int
- func (c *WindowedIndexScanMatchCandidate) GetGroupingAliases() []values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetIndexKeyValues() []values.Value
- func (c *WindowedIndexScanMatchCandidate) GetOrderingAliases() []values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetPrimaryKeyAliases() []values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetPrimaryKeyValues() []values.Value
- func (c *WindowedIndexScanMatchCandidate) GetRankAlias() values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetRecordTypes() []string
- func (c *WindowedIndexScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetScoreAlias() values.CorrelationIdentifier
- func (c *WindowedIndexScanMatchCandidate) GetTraversal() *Traversal
- func (c *WindowedIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey() bool
- func (c *WindowedIndexScanMatchCandidate) IsUnique() bool
- func (c *WindowedIndexScanMatchCandidate) PushValueThroughFetch(value values.Value, sourceAlias values.CorrelationIdentifier, ...) (values.Value, bool)
- func (c *WindowedIndexScanMatchCandidate) String() string
- func (c *WindowedIndexScanMatchCandidate) ToScanPlan(prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, ...) plans.RecordQueryPlan
- type WithBaseQuantifierMatchCandidate
- type WithPrimaryKeyMatchCandidate
Constants ¶
const CardinalityUnknown int64 = -1
CardinalityUnknown is the sentinel value for unknown cardinality, mirroring Java's Cardinality.unknownCardinality().
const DefaultMaxNumConjuncts = 9
DefaultMaxNumConjuncts is the maximum number of OR-predicate conjuncts that PredicateToLogicalUnionRule will attempt to convert to DNF. Beyond this limit, the combinatorial explosion of DNF terms is too expensive. Java's default is 9 (510 combinations).
const FunctionKindCardinality = "cardinality"
FunctionKindCardinality is the columnFunctions entry marking a key column as CARDINALITY(field). Matches the "cardinality" function-key name on the record-layer side so the bridge is name-stable across the two layers.
Variables ¶
var ErrPlannerCapHit = plannerErr("planner: MaxTasks cap hit before convergence")
ErrPlannerCapHit signals that Plan exited via the MaxTasks cap rather than convergence. Callers should treat this as a non-termination indicator and report.
var ReferencedFieldsConstraintKey = &PlannerConstraint[*ReferencedFields]{name: "referencedFields"}
ReferencedFieldsConstraintKey is the constraint key for referenced fields. Pushed top-down by PushReferencedFieldsThrough* rules to inform downstream operators which columns/fields are actually needed. Ports Java's ReferencedFieldsConstraint.REFERENCED_FIELDS.
var RequestedOrderingConstraintKey = &PlannerConstraint[[]*RequestedOrdering]{name: "requestedOrdering"}
RequestedOrderingConstraintKey is the constraint key for requested orderings.
Functions ¶
func AddPartialMatchForCandidate ¶
func AddPartialMatchForCandidate( ref *expressions.Reference, candidate MatchCandidate, match PartialMatch, ) bool
AddPartialMatchForCandidate stores a PartialMatch for the given MatchCandidate on the Reference. Typed wrapper around Reference.AddPartialMatch. Mirrors Java's Reference.addPartialMatchForCandidate.
Content dedup: Reference.AddPartialMatch dedups only by pointer identity, but the matching rules (and the AdjustMatch absorption loop) re-fire many times during PLANNING exploration, each minting a fresh PartialMatch pointer for the SAME logical match. For a given (queryExpression, candidateRef) the binding is deterministic — the same predicates bind the same placeholders — so that pair uniquely identifies the match. Without content dedup these duplicates accumulate unbounded (a 2-index query reached 200+ matches), skewing MaximumCoverageMatches and tripping the intersection match cap. Drop a new match whose (queryExpression, candidateRef) already exists.
func AdjustMatches ¶
func AdjustMatches(rootRef *expressions.Reference)
AdjustMatches walks all References reachable from rootRef and, for every existing PartialMatch, attempts to absorb candidate-side-only expressions one level up from the matched candidate ref. On success, a new PartialMatch with AdjustedMatchInfo is stored on the same query Reference but pointing to the parent candidate Reference.
This is the Go equivalent of Java's AdjustMatchRule, which fires on PartialMatches via a TransformPartialMatch task. In Go, AdjustMatches is called explicitly after MatchLeafRule and MatchIntermediateRule have run, rather than being scheduled as a rule (see also AdjustPartialMatchesForRef at the data-access consumption boundary).
Ports Java's com.apple.foundationdb.record.query.plan.cascades.rules.AdjustMatchRule.
func AdjustPartialMatchesForRef ¶
func AdjustPartialMatchesForRef(ref *expressions.Reference)
AdjustPartialMatchesForRef runs the AdjustMatchRule absorption loop on a single Reference's partial matches until stable. Each round attempts to absorb a candidate-side parent expression (SelectExpression → MatchableSortExpression) onto each existing PartialMatch, producing adjusted matches that carry e.g. matched ordering parts.
This is the per-ref unit of Java's event-driven AdjustMatchRule. It is invoked both by the bottom-up AdjustMatches walk (for REWRITING-phase matches) AND by pushDataAccessTasks just before it consumes a ref's matches — PLANNING-phase matches are seeded during exploration, after the phase-start AdjustMatches walk, so they must be adjusted at consumption time or their ordering parts (needed to satisfy a requested ordering and eliminate an in-memory sort) are never computed.
func AllAttributesExcept ¶
func AllAttributesExcept(except ...*properties.ExpressionProperty) []*properties.ExpressionProperty
AllAttributesExcept returns plan properties excluding the specified ones.
func AreAllBindingsFixed ¶
func AreAllBindingsFixed(bindings []OrderingBinding) bool
AreAllBindingsFixed returns true if all bindings are fixed (equality-bound).
func ComputeDerivations ¶
func ComputeDerivations(expr expressions.RelationalExpression) *properties.Derivations
ComputeDerivations evaluates the derivations property for a physical plan wrapper expression. Dispatches on the concrete wrapper type, matching Java's DerivationsVisitor per-plan methods.
Exported for use by plan_properties.go and tests.
func CreateScansForMatches ¶
func CreateScansForMatches( accesses []Vectored[*SingleMatchedAccess], _ PlanContext, ) map[PartialMatch]plans.RecordQueryPlan
CreateScansForMatches converts each SingleMatchedAccess into a physical scan plan by calling MatchCandidate.ToScanPlan with the bound parameter prefix and reverse flag.
Returns a map from PartialMatch to RecordQueryPlan. The map uses the PartialMatch identity (pointer equality) as key.
Ports Java's AbstractDataAccessRule.createScansForMatches.
func CrossProduct ¶
func CrossProduct[T any](lists [][]T) [][]T
CrossProduct computes the Cartesian product of N lists. Each list provides alternatives for one "dimension"; the result is every combination of picking one element from each list.
For input [[a, b], [x, y]], returns [[a, x], [a, y], [b, x], [b, y]]. Empty input returns nil. Any empty inner list makes the product empty.
Mirrors Java's CrossProduct.crossProduct utility.
func DataAccessForMatchPartition ¶
func DataAccessForMatchPartition( requestedOrderings []*RequestedOrdering, partialMatches []PartialMatch, ctx PlanContext, intersector IntersectorFunc, ) []expressions.RelationalExpression
DataAccessForMatchPartition orchestrates data access planning from a collection of PartialMatches. This is the main entry point that concrete rules call.
Steps:
- Compute maximum-coverage matches (with Pareto filtering)
- Create scan plans for each viable match
- For single match: wrap as expression with compensation
- For multiple matches: try intersections via the provided intersector callback
The intersector is a function parameter so concrete rules can provide their own intersection logic (replaces Java's abstract createIntersectionAndCompensation method).
Ports Java's AbstractDataAccessRule.dataAccessForMatchPartition.
func ExplainPhysicalPlan ¶
func ExplainPhysicalPlan(expr expressions.RelationalExpression) string
ExplainPhysicalPlan returns the Explain() string for a physical-plan expression, or empty string if the expression is not a physical plan.
func FireExpressionRule ¶
func FireExpressionRule(rule ExpressionRule, ref *expressions.Reference) []expressions.RelationalExpression
FireExpressionRule is a standalone driver for testing ExpressionRules. Matches the rule's pattern against every member of `ref` and invokes OnMatch for each successful match. Yields are inserted into `ref` via the ExpressionRuleCall's Reference; the returned slice is the rule's intent (Yielded()).
Production rule driving lives in the planner's task stack (unified_tasks.go); this helper is the testable entry point — same pattern as FireRule for predicate/value rules.
func FireExpressionRuleWithMemo ¶
func FireExpressionRuleWithMemo(rule ExpressionRule, ref *expressions.Reference, ctx PlanContext, memo *Memo) []expressions.RelationalExpression
FireExpressionRuleWithMemo is like FireExpressionRule but passes a PlanContext and Memo to the rule call, enabling cross-Reference memoization when running inside the Planner.
func FireImplementationRule ¶
func FireImplementationRule(rule ImplementationRule, ref *expressions.Reference, constraints ...*ConstraintMap) []expressions.RelationalExpression
FireImplementationRule runs an ImplementationRule against a Reference, matching each member and collecting yielded expressions. Returns the yielded expressions (also inserted into ref.Members).
func FireImplementationRuleWithContext ¶
func FireImplementationRuleWithContext(rule ImplementationRule, ref *expressions.Reference, ctx PlanContext, memo *Memo, constraints ...*ConstraintMap) []expressions.RelationalExpression
FireImplementationRuleWithContext is like FireImplementationRule but threads a PlanContext through to the rule call. The planner uses this to provide PK / match-candidate info to rules that need it.
func FireRule ¶
func FireRule(rule CascadesRule, in any) []any
FireRule drives a predicate/value rule once against `in`: run `rule.Matcher()`, and for every successful match invoke `rule.OnMatch`. Returns the aggregate list of yielded replacements across all matches. Used by rule unit tests; production predicate simplification runs through Simplify's fixpoint loop (simplifier.go), and planner rules through the task stack (unified_tasks.go).
func Get ¶
func Get[T any](cm *ConstraintMap, ref *expressions.Reference, key *PlannerConstraint[T]) (T, bool)
Get retrieves the constraint value for a Reference + key combination.
func GetPhysicalFetchFromPartialRecordPlan ¶
func GetPhysicalFetchFromPartialRecordPlan(expr expressions.RelationalExpression) *plans.RecordQueryFetchFromPartialRecordPlan
GetPhysicalFetchFromPartialRecordPlan returns the underlying plan if expr is a physicalFetchFromPartialRecordWrapper, nil otherwise.
func GetPhysicalMultiIntersectionPlan ¶
func GetPhysicalMultiIntersectionPlan(expr expressions.RelationalExpression) *plans.RecordQueryMultiIntersectionOnValuesPlan
GetPhysicalMultiIntersectionPlan returns the underlying RecordQueryMultiIntersectionOnValuesPlan if expr is a physicalMultiIntersectionWrapper, nil otherwise.
func HasMultipleFixedBindings ¶
func HasMultipleFixedBindings(bindings []OrderingBinding) bool
HasMultipleFixedBindings returns true if there are 2+ fixed bindings.
func IsPhysicalAggregateIndex ¶
func IsPhysicalAggregateIndex(expr expressions.RelationalExpression) bool
IsPhysicalAggregateIndex reports whether the expression is an aggregate index scan wrapper.
func IsPhysicalDefaultOnEmpty ¶
func IsPhysicalDefaultOnEmpty(expr expressions.RelationalExpression) bool
IsPhysicalDefaultOnEmpty reports whether the given expression is a physicalDefaultOnEmptyWrapper.
func IsPhysicalDelete ¶
func IsPhysicalDelete(expr expressions.RelationalExpression) bool
IsPhysicalDelete reports whether the given RelationalExpression is a physicalDeleteWrapper.
func IsPhysicalDistinct ¶
func IsPhysicalDistinct(expr expressions.RelationalExpression) bool
IsPhysicalDistinct reports whether the given RelationalExpression is a physicalDistinctWrapper.
func IsPhysicalFetchFromPartialRecord ¶
func IsPhysicalFetchFromPartialRecord(expr expressions.RelationalExpression) bool
IsPhysicalFetchFromPartialRecord reports whether the given RelationalExpression is a physicalFetchFromPartialRecordWrapper.
func IsPhysicalFilter ¶
func IsPhysicalFilter(expr expressions.RelationalExpression) bool
IsPhysicalFilter reports whether the given RelationalExpression is a physical filter wrapper (either legacy or predicates-based).
func IsPhysicalFirstOrDefault ¶
func IsPhysicalFirstOrDefault(expr expressions.RelationalExpression) bool
IsPhysicalFirstOrDefault reports whether the given expression is a physicalFirstOrDefaultWrapper.
func IsPhysicalFlatMap ¶
func IsPhysicalFlatMap(expr expressions.RelationalExpression) bool
IsPhysicalFlatMap reports whether expr is a physicalFlatMapWrapper.
func IsPhysicalInJoin ¶
func IsPhysicalInJoin(expr expressions.RelationalExpression) bool
IsPhysicalInJoin reports whether the given expression is a physicalInJoinWrapper.
func IsPhysicalInUnion ¶
func IsPhysicalInUnion(expr expressions.RelationalExpression) bool
IsPhysicalInUnion reports whether the given expression is a physicalInUnionWrapper.
func IsPhysicalIndexScan ¶
func IsPhysicalIndexScan(expr expressions.RelationalExpression) bool
IsPhysicalIndexScan reports whether the given RelationalExpression is a physicalIndexScanWrapper. Exported so external test packages can identify index scan plans without depending on the unexported type.
func IsPhysicalInsert ¶
func IsPhysicalInsert(expr expressions.RelationalExpression) bool
IsPhysicalInsert reports whether the given RelationalExpression is a physicalInsertWrapper.
func IsPhysicalIntersection ¶
func IsPhysicalIntersection(expr expressions.RelationalExpression) bool
IsPhysicalIntersection reports whether the given RelationalExpression is a physicalIntersectionWrapper.
func IsPhysicalLimit ¶
func IsPhysicalLimit(expr expressions.RelationalExpression) bool
IsPhysicalLimit reports whether the given RelationalExpression is a physicalLimitWrapper.
func IsPhysicalMap ¶
func IsPhysicalMap(expr expressions.RelationalExpression) bool
IsPhysicalMap reports whether the given expression is a physicalMapWrapper.
func IsPhysicalMergeSortUnion ¶
func IsPhysicalMergeSortUnion(expr expressions.RelationalExpression) bool
IsPhysicalMergeSortUnion reports whether the given expression is a physicalMergeSortUnionWrapper.
func IsPhysicalMultiIntersection ¶
func IsPhysicalMultiIntersection(expr expressions.RelationalExpression) bool
IsPhysicalMultiIntersection reports whether the given RelationalExpression is a physicalMultiIntersectionWrapper.
func IsPhysicalNestedLoopJoin ¶
func IsPhysicalNestedLoopJoin(expr expressions.RelationalExpression) bool
IsPhysicalNestedLoopJoin reports whether the given RelationalExpression is a physicalNestedLoopJoinWrapper.
func IsPhysicalPredicatesFilter ¶
func IsPhysicalPredicatesFilter(expr expressions.RelationalExpression) bool
IsPhysicalPredicatesFilter reports whether the given expression is a physicalPredicatesFilterWrapper.
func IsPhysicalRecursiveDfsJoin ¶
func IsPhysicalRecursiveDfsJoin(expr expressions.RelationalExpression) bool
IsPhysicalRecursiveDfsJoin reports whether the given RelationalExpression is a physicalRecursiveDfsJoinWrapper.
func IsPhysicalRecursiveLevelUnion ¶
func IsPhysicalRecursiveLevelUnion(expr expressions.RelationalExpression) bool
IsPhysicalRecursiveLevelUnion reports whether the given RelationalExpression is a physicalRecursiveLevelUnionWrapper.
func IsPhysicalStreamingAgg ¶
func IsPhysicalStreamingAgg(expr expressions.RelationalExpression) bool
IsPhysicalStreamingAgg reports whether the given RelationalExpression is a physicalStreamingAggWrapper.
func IsPhysicalUnorderedUnion ¶
func IsPhysicalUnorderedUnion(expr expressions.RelationalExpression) bool
IsPhysicalUnorderedUnion reports whether the given expression is a physicalUnorderedUnionWrapper.
func IsPhysicalUpdate ¶
func IsPhysicalUpdate(expr expressions.RelationalExpression) bool
IsPhysicalUpdate reports whether the given RelationalExpression is a physicalUpdateWrapper.
func NestPullUp ¶
func NestPullUp( pm PartialMatch, pullUp *PullUp, candidateAlias values.CorrelationIdentifier, ) (rootOfMatchPullUp *PullUp, currentPullUp *PullUp)
NestPullUp walks through the candidate reference chain to build a nested PullUp chain. For each level, it visits the candidate expression to determine the pull-through value. If the match info is adjusted (wrapping another), it descends through the adjustment chain.
Returns (rootOfMatchPullUp, currentPullUp). rootOfMatchPullUp is the first MatchPullUp level created (the topmost match-specific pullup).
Ports Java's PartialMatch.nestPullUp.
func NewPhysicalDefaultOnEmptyWrapper ¶
func NewPhysicalDefaultOnEmptyWrapper( plan *plans.RecordQueryDefaultOnEmptyPlan, innerQuant expressions.Quantifier, ) *physicalDefaultOnEmptyWrapper
func NewPhysicalDeleteWrapper ¶
func NewPhysicalDeleteWrapper(plan *plans.RecordQueryDeletePlan, innerQuant expressions.Quantifier) *physicalDeleteWrapper
NewPhysicalDeleteWrapper constructs the wrapper.
func NewPhysicalDistinctWrapper ¶
func NewPhysicalDistinctWrapper(plan *plans.RecordQueryDistinctPlan, innerQuant expressions.Quantifier) *physicalDistinctWrapper
NewPhysicalDistinctWrapper constructs the wrapper.
func NewPhysicalFetchFromPartialRecordWrapper ¶
func NewPhysicalFetchFromPartialRecordWrapper( plan *plans.RecordQueryFetchFromPartialRecordPlan, innerQuant expressions.Quantifier, ) *physicalFetchFromPartialRecordWrapper
NewPhysicalFetchFromPartialRecordWrapper constructs the wrapper.
func NewPhysicalFilterWrapper ¶
func NewPhysicalFilterWrapper(plan *plans.RecordQueryFilterPlan, innerQuant expressions.Quantifier) *physicalFilterWrapper
NewPhysicalFilterWrapper constructs the wrapper. innerQuant must range over a Reference holding the wrapped inner physical plan.
func NewPhysicalFirstOrDefaultWrapper ¶
func NewPhysicalFirstOrDefaultWrapper( plan *plans.RecordQueryFirstOrDefaultPlan, innerQuant expressions.Quantifier, ) *physicalFirstOrDefaultWrapper
func NewPhysicalInJoinWrapper ¶
func NewPhysicalInJoinWrapper( plan *plans.RecordQueryInJoinPlan, innerQuant expressions.Quantifier, ) *physicalInJoinWrapper
func NewPhysicalInUnionWrapper ¶
func NewPhysicalInUnionWrapper( plan *plans.RecordQueryInUnionPlan, innerQuant expressions.Quantifier, ) *physicalInUnionWrapper
func NewPhysicalInsertWrapper ¶
func NewPhysicalInsertWrapper(plan *plans.RecordQueryInsertPlan, innerQuant expressions.Quantifier) *physicalInsertWrapper
NewPhysicalInsertWrapper constructs the wrapper.
func NewPhysicalIntersectionWrapper ¶
func NewPhysicalIntersectionWrapper(plan *plans.RecordQueryIntersectionPlan, innerQuants []expressions.Quantifier) *physicalIntersectionWrapper
NewPhysicalIntersectionWrapper constructs the wrapper.
func NewPhysicalMapWrapper ¶
func NewPhysicalMapWrapper( plan *plans.RecordQueryMapPlan, innerQuant expressions.Quantifier, ) *physicalMapWrapper
func NewPhysicalMergeSortUnionWrapper ¶
func NewPhysicalMergeSortUnionWrapper( plan *plans.RecordQueryMergeSortUnionPlan, innerQuants []expressions.Quantifier, ) *physicalMergeSortUnionWrapper
func NewPhysicalMultiIntersectionWrapper ¶
func NewPhysicalMultiIntersectionWrapper( plan *plans.RecordQueryMultiIntersectionOnValuesPlan, innerQuants []expressions.Quantifier, ) *physicalMultiIntersectionWrapper
func NewPhysicalPredicatesFilterWrapper ¶
func NewPhysicalPredicatesFilterWrapper( plan *plans.RecordQueryPredicatesFilterPlan, innerQuant expressions.Quantifier, ) *physicalPredicatesFilterWrapper
func NewPhysicalProjectionWrapper ¶
func NewPhysicalProjectionWrapper(plan *plans.RecordQueryProjectionPlan, innerQuant expressions.Quantifier) *physicalProjectionWrapper
func NewPhysicalTypeFilterWrapper ¶
func NewPhysicalTypeFilterWrapper(plan *plans.RecordQueryTypeFilterPlan, innerQuant expressions.Quantifier) *physicalTypeFilterWrapper
NewPhysicalTypeFilterWrapper constructs the wrapper.
func NewPhysicalUnionWrapper ¶
func NewPhysicalUnionWrapper(plan *plans.RecordQueryUnionPlan, innerQuants []expressions.Quantifier) *physicalUnionWrapper
NewPhysicalUnionWrapper constructs the wrapper.
func NewPhysicalUnorderedUnionWrapper ¶
func NewPhysicalUnorderedUnionWrapper( plan *plans.RecordQueryUnorderedUnionPlan, innerQuants []expressions.Quantifier, ) *physicalUnorderedUnionWrapper
func NewPhysicalUpdateWrapper ¶
func NewPhysicalUpdateWrapper(plan *plans.RecordQueryUpdatePlan, innerQuant expressions.Quantifier) *physicalUpdateWrapper
NewPhysicalUpdateWrapper constructs the wrapper.
func NewPhysicalValuesWrapper ¶
func NewPhysicalValuesWrapper(plan *plans.RecordQueryValuesPlan) *physicalValuesWrapper
func NewPlanningCostModelLess ¶
func NewPlanningCostModelLess(stats properties.StatisticsProvider) func(a, b expressions.RelationalExpression) bool
NewPlanningCostModelLess returns a stats-aware cost model comparator with no PlanContext (index metadata for cardinality/unmatched-field criteria is resolved conservatively). Prefer NewPlanningCostModelLessWithContext.
func NewPlanningCostModelLessWithContext ¶
func NewPlanningCostModelLessWithContext(stats properties.StatisticsProvider, ctx PlanContext) func(a, b expressions.RelationalExpression) bool
NewPlanningCostModelLessWithContext returns a stats-aware cost model comparator. The returned function uses real record counts (via stats) for cardinality estimation and resolves index/primary-key metadata via ctx so the criterion-#2 (provable max cardinality) and criterion-#12 (unmatched index fields) properties are computed faithfully from the CONCRETE plan tree (RFC-069). Pass nil stats for default (LeafScanCardinality); pass nil ctx to resolve index metadata conservatively (treat indexes as non-unique).
func NormalizeDNF ¶
func NormalizeDNF(pred predicates.QueryPredicate, sizeLimit int) (predicates.QueryPredicate, bool)
NormalizeDNF converts a predicate to disjunctive normal form (DNF). Returns (result, true) if a transformation was applied, or (original, false) if the predicate is already in DNF or the normalised form would exceed sizeLimit.
DNF: the outer connective is OR, each child is either a leaf or an AND of leaves. The transformation distributes AND over OR:
A AND (B OR C) -> (A AND B) OR (A AND C)
Mirrors Java's BooleanPredicateNormalizer with Mode.DNF.
func OrderingAliases ¶
func OrderingAliases( groupingAliases []values.CorrelationIdentifier, scoreAlias values.CorrelationIdentifier, primaryKeyAliases []values.CorrelationIdentifier, ) []values.CorrelationIdentifier
OrderingAliases is a package-level helper that computes the ordering alias list for a windowed index: grouping + [score] + primaryKey. Ports Java's WindowedIndexScanMatchCandidate.orderingAliases().
func PhysicalIndexScanName ¶
func PhysicalIndexScanName(expr expressions.RelationalExpression) string
PhysicalIndexScanName returns the index name if expr is a physicalIndexScanWrapper or a physicalFetchFromPartialRecordWrapper whose inner plan is an index plan. Returns empty string otherwise.
func PlanningCostModelLess ¶
func PlanningCostModelLess(a, b expressions.RelationalExpression) bool
PlanningCostModelLess is the Java-aligned multi-criteria plan comparator. Mirrors Java's PlanningCostModel.compare() from fdb-record-layer-core.
Returns true if a is strictly preferred over b. The comparison uses ordered tie-breaking criteria matching Java's priority:
- Physical plan beats non-physical
- Max cardinality of all data accesses (lower wins)
- Fewer normalized residual predicates
- Fewer data access operators (scan + index + covering)
- Recursive CTE tie-breaker (DFS > level-based)
- IN-plan penalty (penalize if IN-values aren't SARGs)
- Primary scan vs index-scan-with-fetch (prefer primary)
- Type filter count (fewer = better)
- Type filter depth (deeper = better)
- Index fetch metrics (fewer non-covering + fetch = better)
- Distinct depth (deeper = better)
- Unmatched index field count (fewer = better)
- IN-join source count (more = better)
- MAP + PredicatesFilter count (fewer = better)
- Streaming aggregation beats hash aggregation
- Scalar cost fallback (EstimateCost)
- Plan hash deterministic tie-break
func RegisteredRuleNames ¶
func RegisteredRuleNames() []string
RegisteredRuleNames returns a sorted list of registered rule names. Useful for tests that want to iterate the registry deterministically.
func ResolveComparisonDirection ¶
func ResolveComparisonDirection(parts []ProvidedOrderingPart) bool
ResolveComparisonDirection examines the comparison ordering parts and determines if the comparison is reverse (all descending). Returns true if all directional parts are descending. Mirrors Java's RecordQuerySetPlan.resolveComparisonDirection.
func RewritingCostModelLess ¶
func RewritingCostModelLess(a, b expressions.RelationalExpression) bool
RewritingCostModelLess is the Java-aligned cost model for the REWRITING phase. Mirrors Java's RewritingCostModel.compare():
- Fewer SelectExpressions
- Fewer TableFunctionExpressions
- Fewer normalized residual predicate conjuncts (CNF full-size)
- More predicates at deeper levels (push predicates down)
- Semantic hash tiebreak
func SatisfiesAnyRequestedOrderings ¶
func SatisfiesAnyRequestedOrderings( pm PartialMatch, requestedOrderings []*RequestedOrdering, ) ([]*RequestedOrdering, *ScanDirection)
SatisfiesAnyRequestedOrderings filters requestedOrderings to those satisfied by the partial match. Returns the satisfied orderings and the scan direction, or nil if none are satisfied.
Ports Java's AbstractDataAccessRule.satisfiesAnyRequestedOrderings.
func Set ¶
func Set[T any](cm *ConstraintMap, ref *expressions.Reference, key *PlannerConstraint[T], value T)
Set stores a constraint value for a Reference + key combination.
func Simplify ¶
func Simplify(pred predicates.QueryPredicate, rules []CascadesRule) predicates.QueryPredicate
Simplify iterates the rules on `pred` until no rule produces a rewrite, then returns the final form. Each iteration applies every rule in order; if ANY rule yields, the result replaces `pred` and the loop restarts from the top (fixpoint convergence). Descends into child predicates after the top-level stabilises.
Termination invariants for the rule sets this driver runs:
- DefaultSimplifyRules — each rule strictly reduces the tree (folds a constant or drops an identity / absorbed child), and there's a finite number of constants / identities to collapse.
- NormalizationRules — adds DeMorganRule, which strictly INCREASES the node count (NOT distributed across N children adds N-1 NOTs). DeMorganRule terminates via NOT-depth monotone decrease: each application moves every NOT one level closer to leaves, leaves are finitely deep, leaves eventually hit NotComparisonRewriteRule and disappear (or stop matching).
Not safe against cyclic-rewrite rule sets — real Cascades uses a memo to detect cycles. The rule sets this driver runs are termination-proven per above so no cycle is possible.
func ValidatePlanInvariants ¶
func ValidatePlanInvariants(plan plans.RecordQueryPlan) error
ValidatePlanInvariants checks RFC-164 WS-2 structural invariants on a fully extracted physical plan tree. It is a cheap, always-on backstop — run in the no-FDB plan harness, the production generator, and a fuzz target — that makes a whole class of malformed plans un-shippable rather than hunting them one PR at a time.
It has TWO detectors for a relink that dropped a child:
- Empty-children: a non-leaf plan with zero children. A unary operator whose inner was left nil (the IN-LIMIT bug) has its nil masked by GetChildren (which returns empty for a nil inner), so it masquerades as a leaf. Comparing against the fixed set of genuinely-childless plan types unmasks it.
- Nil-in-slice: a fixed-arity operator (NLJ, FlatMap, recursive joins/unions) returns a length-N slice whose dropped child is a nil ELEMENT rather than a shorter slice; the per-child nil check below catches that.
It walks the PLAN tree, not the expression tree: the malformation lives in the eagerly-materialized plan SNAPSHOT, while the live expression member (the wrapper's quantifier) still points at a healthy reference — so an expression-tree walk traverses the healthy edge and never reaches the break.
Types ¶
type AdjustedBuilder ¶
type AdjustedBuilder struct {
// contains filtered or unexported fields
}
AdjustedBuilder builds an AdjustedMatchInfo from an underlying MatchInfo, allowing selective override of ordering parts, max match map, and group-by mappings.
Ports Java's MatchInfo.AdjustedBuilder.
func NewAdjustedBuilder ¶
func NewAdjustedBuilder(mi MatchInfo) *AdjustedBuilder
NewAdjustedBuilder creates an AdjustedBuilder pre-seeded with the given MatchInfo's current values. Equivalent to Java's MatchInfo.adjustedBuilder() default method.
func (*AdjustedBuilder) Build ¶
func (b *AdjustedBuilder) Build() *AdjustedMatchInfo
Build constructs the AdjustedMatchInfo.
func (*AdjustedBuilder) GetGroupByMappings ¶
func (b *AdjustedBuilder) GetGroupByMappings() *GroupByMappings
GetGroupByMappings returns the builder's current group-by mappings.
func (*AdjustedBuilder) GetMatchedOrderingParts ¶
func (b *AdjustedBuilder) GetMatchedOrderingParts() []*MatchedOrderingPart
GetMatchedOrderingParts returns the builder's current ordering parts.
func (*AdjustedBuilder) GetMaxMatchMap ¶
func (b *AdjustedBuilder) GetMaxMatchMap() *MaxMatchMap
GetMaxMatchMap returns the builder's current max match map.
func (*AdjustedBuilder) SetGroupByMappings ¶
func (b *AdjustedBuilder) SetGroupByMappings(g *GroupByMappings) *AdjustedBuilder
SetGroupByMappings overrides the group-by mappings.
func (*AdjustedBuilder) SetMatchedOrderingParts ¶
func (b *AdjustedBuilder) SetMatchedOrderingParts(parts []*MatchedOrderingPart) *AdjustedBuilder
SetMatchedOrderingParts overrides the ordering parts.
func (*AdjustedBuilder) SetMaxMatchMap ¶
func (b *AdjustedBuilder) SetMaxMatchMap(m *MaxMatchMap) *AdjustedBuilder
SetMaxMatchMap overrides the max match map.
type AdjustedMatchInfo ¶
type AdjustedMatchInfo struct {
// contains filtered or unexported fields
}
AdjustedMatchInfo wraps an underlying MatchInfo with adjusted ordering parts, max match map, and/or group-by mappings. Created by the AdjustMatchRule when an existing match is refined by walking up the Traversal on the candidate side.
Ports Java's MatchInfo.AdjustedMatchInfo.
func NewAdjustedMatchInfo ¶
func NewAdjustedMatchInfo( underlying MatchInfo, matchedOrderingParts []*MatchedOrderingPart, maxMatchMap *MaxMatchMap, groupByMappings *GroupByMappings, ) *AdjustedMatchInfo
NewAdjustedMatchInfo constructs an AdjustedMatchInfo.
func (*AdjustedMatchInfo) GetGroupByMappings ¶
func (a *AdjustedMatchInfo) GetGroupByMappings() *GroupByMappings
GetGroupByMappings returns the adjusted group-by mappings.
func (*AdjustedMatchInfo) GetMatchedOrderingParts ¶
func (a *AdjustedMatchInfo) GetMatchedOrderingParts() []*MatchedOrderingPart
GetMatchedOrderingParts returns the adjusted ordering parts.
func (*AdjustedMatchInfo) GetMaxMatchMap ¶
func (a *AdjustedMatchInfo) GetMaxMatchMap() *MaxMatchMap
GetMaxMatchMap returns the adjusted max match map.
func (*AdjustedMatchInfo) GetRegularMatchInfo ¶
func (a *AdjustedMatchInfo) GetRegularMatchInfo() *RegularMatchInfo
GetRegularMatchInfo delegates to the underlying MatchInfo.
func (*AdjustedMatchInfo) GetUnderlying ¶
func (a *AdjustedMatchInfo) GetUnderlying() MatchInfo
GetUnderlying returns the wrapped MatchInfo.
func (*AdjustedMatchInfo) IsAdjusted ¶
func (a *AdjustedMatchInfo) IsAdjusted() bool
IsAdjusted returns true -- AdjustedMatchInfo is always adjusted.
func (*AdjustedMatchInfo) IsRegular ¶
func (a *AdjustedMatchInfo) IsRegular() bool
IsRegular returns false -- AdjustedMatchInfo is not regular.
type AggregateDataAccessRule ¶
type AggregateDataAccessRule struct {
// contains filtered or unexported fields
}
AggregateDataAccessRule matches a GroupByExpression against aggregate index candidates (SUM, COUNT, etc.). When a match is found, the rule directly produces an index scan that reads pre-computed aggregates from the aggregate index — no runtime aggregation needed.
GroupBy(keys=[k1], aggs=[SUM(col)], inner=Scan) → IndexScan(aggregate_index) [when aggregate index matches]
For single-aggregate queries, one AggregateIndexMatchCandidate covers the entire GroupBy and produces a direct index scan.
For multi-aggregate queries (e.g. SUM(a), COUNT(*)), each aggregate is served by a separate aggregate index. The rule intersects them via RecordQueryMultiIntersectionOnValuesPlan: all streams are ordered by the same grouping columns (comparison key), and the result row picks grouping values from any stream (they're identical) plus each aggregate from its respective stream.
Mirrors Java's AggregateDataAccessRule including createIntersectionAndCompensation().
func NewAggregateDataAccessRule ¶
func NewAggregateDataAccessRule() *AggregateDataAccessRule
func (*AggregateDataAccessRule) Matcher ¶
func (r *AggregateDataAccessRule) Matcher() matching.BindingMatcher
func (*AggregateDataAccessRule) OnMatch ¶
func (r *AggregateDataAccessRule) OnMatch(call *ExpressionRuleCall)
type AggregateIndexMatchCandidate ¶
type AggregateIndexMatchCandidate struct {
// contains filtered or unexported fields
}
AggregateIndexMatchCandidate represents a pre-computed aggregate index in FDB (e.g., SUM, COUNT, MAX_EVER_LONG, MIN_EVER_LONG). Such indexes maintain running aggregates grouped by a set of key columns. A query like "SELECT region, SUM(amount) FROM t GROUP BY region" can be answered directly from a SUM index on (region, amount) without scanning any data rows.
Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.AggregateIndexMatchCandidate`, carrying the surface AggregateDataAccessRule consumes.
func NewAggregateIndexMatchCandidate ¶
func NewAggregateIndexMatchCandidate( indexName string, recordTypes []string, groupCols []string, aggFunction expressions.AggregateFunction, aggColumn string, ) *AggregateIndexMatchCandidate
NewAggregateIndexMatchCandidate creates a candidate for an aggregate index. groupCols are the grouping key columns; aggFunction + aggColumn describe the pre-computed aggregate.
func (*AggregateIndexMatchCandidate) CandidateName ¶
func (c *AggregateIndexMatchCandidate) CandidateName() string
func (*AggregateIndexMatchCandidate) ComputeBoundParameterPrefixMap ¶
func (c *AggregateIndexMatchCandidate) ComputeBoundParameterPrefixMap( bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange, ) map[values.CorrelationIdentifier]*predicates.ComparisonRange
func (*AggregateIndexMatchCandidate) GetAggColumn ¶
func (c *AggregateIndexMatchCandidate) GetAggColumn() string
func (*AggregateIndexMatchCandidate) GetAggFunction ¶
func (c *AggregateIndexMatchCandidate) GetAggFunction() expressions.AggregateFunction
func (*AggregateIndexMatchCandidate) GetColumnNames ¶
func (c *AggregateIndexMatchCandidate) GetColumnNames() []string
func (*AggregateIndexMatchCandidate) GetRecordTypes ¶
func (c *AggregateIndexMatchCandidate) GetRecordTypes() []string
func (*AggregateIndexMatchCandidate) GetSargableAliases ¶
func (c *AggregateIndexMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
func (*AggregateIndexMatchCandidate) GetTraversal ¶
func (c *AggregateIndexMatchCandidate) GetTraversal() *Traversal
GetTraversal returns the Traversal of this candidate's expression tree, built lazily on first access via ExpandValueIndex (using the grouping columns as the index columns). The traversal is stable once computed (sync.Once).
func (*AggregateIndexMatchCandidate) IsUnique ¶
func (c *AggregateIndexMatchCandidate) IsUnique() bool
func (*AggregateIndexMatchCandidate) MatchesGroupBy ¶
func (c *AggregateIndexMatchCandidate) MatchesGroupBy(gb *expressions.GroupByExpression) bool
MatchesGroupBy reports whether this aggregate index can directly satisfy the given GroupByExpression. Returns true when:
- The grouping keys match the index's groupCols
- The GroupBy has exactly one aggregate that matches the index's function + column
func (*AggregateIndexMatchCandidate) MatchesSingleAggregateOf ¶
func (c *AggregateIndexMatchCandidate) MatchesSingleAggregateOf(gb *expressions.GroupByExpression, aggIndex int) bool
MatchesSingleAggregateOf reports whether this candidate's grouping keys match gb's grouping keys AND this candidate covers the aggregate at index aggIndex in gb's aggregate list. Used by the multi-aggregate intersection path: each candidate covers one aggregate while all share the same grouping columns.
func (*AggregateIndexMatchCandidate) ToScanPlan ¶
func (c *AggregateIndexMatchCandidate) ToScanPlan( prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, reverse bool, ) plans.RecordQueryPlan
type AliasMap ¶
type AliasMap struct {
// contains filtered or unexported fields
}
AliasMap is an immutable bidirectional mapping between CorrelationIdentifiers. Used during graph traversal to track which alias on the "left" side corresponds to which alias on the "right" side when comparing or rebasing expressions.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.AliasMap.
Key use cases:
- Subquery decorrelation: rebasing correlated references when pulling a subquery out of its enclosing context.
- Expression equivalence: determining if two sub-graphs are semantically equal under an alias mapping.
- Push/pull rules: translating alias references when moving operators across quantifier boundaries.
func AliasMapOfAliases ¶
func AliasMapOfAliases(source, target values.CorrelationIdentifier) *AliasMap
AliasMapOfAliases creates a single-entry alias map.
func EmptyAliasMap ¶
func EmptyAliasMap() *AliasMap
EmptyAliasMap returns the shared empty alias map.
func (*AliasMap) Compose ¶
Compose creates a new AliasMap where each source maps to the target of the target in `other`. If this maps A→B and other maps B→C, the result maps A→C.
func (*AliasMap) ContainsMapping ¶
func (m *AliasMap) ContainsMapping(source, target values.CorrelationIdentifier) bool
ContainsMapping reports whether source maps to target.
func (*AliasMap) ContainsSource ¶
func (m *AliasMap) ContainsSource(source values.CorrelationIdentifier) bool
ContainsSource reports whether source is mapped.
func (*AliasMap) ContainsTarget ¶
func (m *AliasMap) ContainsTarget(target values.CorrelationIdentifier) bool
ContainsTarget reports whether target is mapped.
func (*AliasMap) Derived ¶
Derived creates a new AliasMap that extends this one with additional mappings. Existing mappings are preserved; new mappings that conflict with existing ones are skipped.
func (*AliasMap) ForwardMap ¶
ForwardMap returns the forward (source→target) map suitable for passing to values.RebaseValue. This is the bridge between the cascades-level AliasMap and the values-level rebase infrastructure.
func (*AliasMap) GetSource ¶
func (m *AliasMap) GetSource(target values.CorrelationIdentifier) values.CorrelationIdentifier
GetSource returns the source for the given target, or the target itself if not mapped (identity fallback).
func (*AliasMap) GetTarget ¶
func (m *AliasMap) GetTarget(source values.CorrelationIdentifier) values.CorrelationIdentifier
GetTarget returns the target for the given source, or the source itself if not mapped (identity fallback).
func (*AliasMap) GetTargetOrEmpty ¶
func (m *AliasMap) GetTargetOrEmpty(source values.CorrelationIdentifier) (values.CorrelationIdentifier, bool)
GetTargetOrEmpty returns the target for the given source, or empty if not mapped. Unlike GetTarget, does NOT fall back to identity.
func (*AliasMap) IsIdentity ¶
IsIdentity reports whether all mappings are identity (source==target) or the map is empty.
func (*AliasMap) Sources ¶
func (m *AliasMap) Sources() []values.CorrelationIdentifier
Sources returns all source aliases.
type AliasMapBuilder ¶
type AliasMapBuilder struct {
// contains filtered or unexported fields
}
AliasMapBuilder constructs an AliasMap incrementally.
func NewAliasMapBuilder ¶
func NewAliasMapBuilder() *AliasMapBuilder
NewAliasMapBuilder creates an empty builder.
func (*AliasMapBuilder) Build ¶
func (b *AliasMapBuilder) Build() *AliasMap
Build creates an immutable AliasMap from the builder's state.
func (*AliasMapBuilder) Put ¶
func (b *AliasMapBuilder) Put(source, target values.CorrelationIdentifier) bool
Put adds a source→target mapping. Returns false if either source or target is already mapped (would create an inconsistent bi-map).
func (*AliasMapBuilder) PutAll ¶
func (b *AliasMapBuilder) PutAll(other *AliasMap)
PutAll copies all entries from other into this builder. Each entry is added via Put; conflicts (source or target already mapped) are silently skipped to match Java's Builder.putAll semantics.
Ports Java's AliasMap.Builder.putAll.
type AliasMapValueEquivalence ¶
type AliasMapValueEquivalence struct {
// contains filtered or unexported fields
}
AliasMapValueEquivalence maps QuantifiedObjectValues via an AliasMap to enable cross-scope value comparison. Two values are equal if they are both QuantifiedObjectValues and their aliases are mapped in the AliasMap.
Ports Java's ValueEquivalence.AliasMapBackedValueEquivalence.
func NewAliasMapValueEquivalence ¶
func NewAliasMapValueEquivalence(am *AliasMap) *AliasMapValueEquivalence
NewAliasMapValueEquivalence creates a ValueEquivalence backed by the given AliasMap.
func (*AliasMapValueEquivalence) IsDefinedEqual ¶
func (e *AliasMapValueEquivalence) IsDefinedEqual(left, right values.Value) ConstrainedBoolean
IsDefinedEqual checks if two values are QuantifiedObjectValues with aliases mapped in the underlying AliasMap.
func (*AliasMapValueEquivalence) IsDefinedEqualAlias ¶
func (e *AliasMapValueEquivalence) IsDefinedEqualAlias(left, right values.CorrelationIdentifier) ConstrainedBoolean
IsDefinedEqualAlias checks if two correlation identifiers are mapped in the underlying AliasMap.
type AndAbsorbOrRule ¶
type AndAbsorbOrRule struct {
// contains filtered or unexported fields
}
AndAbsorbOrRule: inside an AND, any OR child that contains a sibling is redundant — drop it. `AND(p, OR(p, q))` → `AND(p)` → `p` once the constant-fold rules collapse the unary AND.
func NewAndAbsorbOrRule ¶
func NewAndAbsorbOrRule() *AndAbsorbOrRule
NewAndAbsorbOrRule constructs the rule.
func (*AndAbsorbOrRule) Matcher ¶
func (r *AndAbsorbOrRule) Matcher() matching.BindingMatcher
func (*AndAbsorbOrRule) OnMatch ¶
func (r *AndAbsorbOrRule) OnMatch(call *RuleCall)
type AndConstantSimplifyRule ¶
type AndConstantSimplifyRule struct {
// contains filtered or unexported fields
}
AndConstantSimplifyRule matches an AndPredicate and folds constant children per Kleene AND identities.
func NewAndConstantSimplifyRule ¶
func NewAndConstantSimplifyRule() *AndConstantSimplifyRule
NewAndConstantSimplifyRule constructs the rule.
func (*AndConstantSimplifyRule) Matcher ¶
func (r *AndConstantSimplifyRule) Matcher() matching.BindingMatcher
func (*AndConstantSimplifyRule) OnMatch ¶
func (r *AndConstantSimplifyRule) OnMatch(call *RuleCall)
type AndDedupRule ¶
type AndDedupRule struct {
// contains filtered or unexported fields
}
AndDedupRule removes structurally-equal duplicate children from an AndPredicate. `AND(p, p, q, p)` → `AND(p, q)`. Mirrors Java `PredicateSimplification`'s dedup pass.
func (*AndDedupRule) Matcher ¶
func (r *AndDedupRule) Matcher() matching.BindingMatcher
func (*AndDedupRule) OnMatch ¶
func (r *AndDedupRule) OnMatch(call *RuleCall)
type AndFlattenRule ¶
type AndFlattenRule struct {
// contains filtered or unexported fields
}
AndFlattenRule normalises nested AndPredicates: `AND(AND(a, b), c)` → `AND(a, b, c)`. Mirrors Java's associative-flatten in `ValueSimplificationRuleSet`. Runs before the constant-simplify pass so the simplifier sees a flat list of operands.
func NewAndFlattenRule ¶
func NewAndFlattenRule() *AndFlattenRule
NewAndFlattenRule constructs the rule.
func (*AndFlattenRule) Matcher ¶
func (r *AndFlattenRule) Matcher() matching.BindingMatcher
func (*AndFlattenRule) OnMatch ¶
func (r *AndFlattenRule) OnMatch(call *RuleCall)
type BiMap ¶
BiMap is a bidirectional map: every key maps to exactly one value, and every value maps to exactly one key. Mirrors Guava's ImmutableBiMap used in Java's GroupByMappings and related matching infrastructure.
Unlike Go's built-in maps which use pointer identity for interface keys, BiMap uses configurable stringifier functions to determine equality — matching Java's equals()/hashCode() semantics.
func NewBiMap ¶
func NewBiMap[K comparable, V comparable]() *BiMap[K, V]
NewBiMap creates an empty BiMap for comparable types using fmt.Sprintf as the stringifier. This preserves backward compatibility for simple types like string, int, etc.
func NewBiMapFromMap ¶
func NewBiMapFromMap[K comparable, V comparable](m map[K]V) *BiMap[K, V]
NewBiMapFromMap creates a BiMap from a regular map. Panics if the map contains duplicate values (violating the bijection constraint).
func NewBiMapWith ¶
NewBiMapWith creates an empty BiMap with the given stringifier functions for keys and values.
func NewCorrValueBiMap ¶
func NewCorrValueBiMap() *BiMap[values.CorrelationIdentifier, values.Value]
NewCorrValueBiMap creates a BiMap[values.CorrelationIdentifier, values.Value] using Name() for correlation identifiers and ExplainValue for values.
func NewValueBiMap ¶
NewValueBiMap creates a BiMap[values.Value, values.Value] using ExplainValue for structural equality — the standard representation used throughout the codebase for plan equality and hashing.
func (*BiMap[K, V]) GetInverse ¶
GetInverse returns the key for the given value and whether it was found.
func (*BiMap[K, V]) Put ¶
func (b *BiMap[K, V]) Put(key K, value V)
Put inserts a key-value pair. Panics if the value already maps to a different key (bijection constraint).
type BitSet ¶
type BitSet struct {
// contains filtered or unexported fields
}
BitSet is a simple bit set backed by a map, providing the subset of java.util.BitSet operations needed by the intersection sieve logic.
func (*BitSet) Cardinality ¶
Cardinality returns the number of set bits.
func (*BitSet) IsSubsetOf ¶
IsSubsetOf reports whether every bit in b is also set in other.
type CascadesRule ¶
type CascadesRule interface {
// Matcher returns the pattern this rule fires on. The planner
// walks every expression in the memo, runs every rule's
// matcher against it, and invokes OnMatch on successful
// bindings.
Matcher() matching.BindingMatcher
// OnMatch is the rule body. It reads call.Bindings to retrieve
// the matched expression shape and calls call.Yield for each
// replacement it produces. Zero yields is legal — the rule
// simply declined to fire for this match.
OnMatch(call *RuleCall)
}
CascadesRule is the transform interface. Concrete rules implement Matcher + OnMatch. Rule authors compose the matcher using the combinators in combinators.go + the Instance/AnyValue/Arithmetic matchers in matcher.go.
func DefaultSimplifyRules ¶
func DefaultSimplifyRules() []CascadesRule
DefaultSimplifyRules returns the canonical simplification rule set. Callers pass this to Simplify for a typical "flatten + constant-fold + identity-drop" pass. Order matters: flattens run first so the constant-fold rules see a flat operand list; then Comparison constants fold; then Not resolves; then the And/Or identity-drop + absorbing-element rules.
Rules NOT included (intentional):
- De Morgan NOT-distribution (`NOT(AND(a,b))` → `OR(NOT a, NOT b)`). Kleene-safe but NODE-INCREASING (N-ary AND becomes N-element OR plus N NOTs), so it doesn't fit the strict-reduction termination invariant DefaultSimplifyRules guarantees. Java applies De Morgan as a separate `BooleanNormalizer` pre-CNF pass; we mirror this via the explicit `NormalizationRules()` rule set (which prepends `NewDeMorganRule()` before the default set).
- Tautology / contradiction folds that require NOT-NULL metadata (`x = x` → TRUE iff x is NOT NULL). Waits on Type nullability tracking.
func NormalizationRules ¶
func NormalizationRules() []CascadesRule
NormalizationRules is the rule set to use when De Morgan distribution + nested-NOT push-down are desired in addition to the default simplification pass. Java's BooleanNormalizer applies these as a separate pre-CNF normalisation; callers wanting the same effect compose `Simplify(pred, NormalizationRules())` with the existing Simplify driver.
Order matters:
- DeMorganRule comes BEFORE the default rules so the AND/OR boundaries surface for the constant-fold / identity-drop follow-on passes.
- DefaultSimplifyRules then collapses the resulting AND/OR/NOT leaves further (NotComparisonRewriteRule turns NOT(=) into <>, NotConstantSimplifyRule double-negates, etc.).
type ComparisonConstantSimplifyRule ¶
type ComparisonConstantSimplifyRule struct {
// contains filtered or unexported fields
}
ComparisonConstantSimplifyRule folds a ComparisonPredicate whose operand is a ConstantValue — both sides of the comparison are known at plan time, so the predicate evaluates to a constant. Mirrors Java's `ValueSimplificationRuleSet` constant-predicate short-circuits.
Example: `5 = 3` → `FALSE`, `7 > 2` → `TRUE`, `NULL = 1` → `UNKNOWN`. Only fires when both sides are known-constant Values — leaf constants or all-constant composites folded via EvaluateConstant (see constantLiteral / values.IsConstantValue) — i.e. Values whose result is reproducible without an eval context.
func NewComparisonConstantSimplifyRule ¶
func NewComparisonConstantSimplifyRule() *ComparisonConstantSimplifyRule
NewComparisonConstantSimplifyRule constructs the rule.
func (*ComparisonConstantSimplifyRule) Matcher ¶
func (r *ComparisonConstantSimplifyRule) Matcher() matching.BindingMatcher
func (*ComparisonConstantSimplifyRule) OnMatch ¶
func (r *ComparisonConstantSimplifyRule) OnMatch(call *RuleCall)
type CompensatedResult ¶
type CompensatedResult struct {
Impossible bool
ResultCompensationFn *ResultCompensationFunction
GroupByMappings *GroupByMappings
}
CompensatedResult bundles the results of computing result compensation for a partial match. Ports Java's Compensation.CompensatedResult.
func ComputeResultCompensation ¶
func ComputeResultCompensation(pm PartialMatch, rootOfMatchPullUp *PullUp) *CompensatedResult
ComputeResultCompensation computes the result compensation for the top operation's partial match. Ports Java's Compensation.computeResultCompensation.
type Compensation ¶
type Compensation interface {
// IsNeeded reports whether this compensation must be applied.
// Returns false only for NoCompensation.
IsNeeded() bool
// IsImpossible reports whether this compensation cannot be applied.
// Returns true only for ImpossibleCompensation or a ForMatch with
// impossible=true.
IsImpossible() bool
// IsNeededForFiltering reports whether this compensation needs to
// be applied for correct filtering. This matters when a caller cares
// about the correct set of rows but not the result shape (e.g.
// EXISTS predicates).
IsNeededForFiltering() bool
// IsFinalNeeded reports whether final (result-shape) compensation
// must be applied when this compensation is at the top of a
// compensation chain.
IsFinalNeeded() bool
// CanBeDeferred reports whether this compensation can be combined
// with subsequent compensations further up the matched DAG or
// whether it must be applied at the exact position that created it.
CanBeDeferred() bool
}
Compensation is the byproduct of expression DAG matching. When a query subgraph Q matches a materialized data set M (e.g. an index), M may subsume Q but produce extraneous records. A Compensation corrects for that by applying post-operations such as filtering, distinct-ing, or reshaping results.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.Compensation.
ForMatchCompensation implements Intersect, Union, and Apply. applyFinal requires memoizer infrastructure (not yet ported).
var ( // NoCompensation indicates that no additional operators need to be // injected to compensate for a match. Equivalent to Java's // Compensation.NO_COMPENSATION. NoCompensation Compensation = noCompensation{} // ImpossibleCompensation indicates that compensation is needed but // cannot be computed. It is the identity element for the // intersection monoid on compensations. Equivalent to Java's // Compensation.IMPOSSIBLE_COMPENSATION. ImpossibleCompensation Compensation = impossibleCompensation{} )
func IntersectCompensations ¶
func IntersectCompensations(compensations []Compensation) Compensation
IntersectCompensations folds a slice of Compensations via the intersection monoid. The identity element is ImpossibleCompensation. Ports Java's `compensations.stream().reduce(impossibleCompensation, Compensation::intersect)`.
func UnionCompensations ¶
func UnionCompensations(compensations []Compensation) Compensation
UnionCompensations folds a slice of Compensations via union. The identity element is NoCompensation.
type ConstrainedBoolean ¶
type ConstrainedBoolean struct {
Value bool
Constraint *QueryPlanConstraint
}
ConstrainedBoolean is a boolean result that may carry an optional QueryPlanConstraint. Ports Java's ConstrainedBoolean.
func AlwaysTrue ¶
func AlwaysTrue() ConstrainedBoolean
AlwaysTrue returns a ConstrainedBoolean that is unconditionally true.
func FalseValue ¶
func FalseValue() ConstrainedBoolean
FalseValue returns a ConstrainedBoolean that is false.
func TrueWithConstraint ¶
func TrueWithConstraint(c *QueryPlanConstraint) ConstrainedBoolean
TrueWithConstraint returns a ConstrainedBoolean that is true only if the given constraint holds.
func ValueSemanticEquals ¶
func ValueSemanticEquals(a, b values.Value, veq ValueEquivalence) ConstrainedBoolean
ValueSemanticEquals compares two Values for semantic equality using the given ValueEquivalence for cross-scope comparisons. Returns a ConstrainedBoolean that may carry a QueryPlanConstraint.
The algorithm:
- Pointer equality → always true.
- EqualsWithoutChildren + recursive child comparison via ValueSemanticEquals (composing constraints).
- If structural comparison fails, falls back to valueEquivalence.IsDefinedEqual (axiom-based equality).
Ports Java's Value.semanticEquals(other, ValueEquivalence).
func (ConstrainedBoolean) ComposeWithOther ¶
func (cb ConstrainedBoolean) ComposeWithOther(other ConstrainedBoolean) ConstrainedBoolean
ComposeWithOther composes this ConstrainedBoolean with another via AND semantics: if either is false, the result is false. If both are true, constraints are merged. Ports Java's ConstrainedBoolean.composeWithOther().
func (ConstrainedBoolean) Filter ¶
func (cb ConstrainedBoolean) Filter(fn func() ConstrainedBoolean) ConstrainedBoolean
Filter returns false if the ConstrainedBoolean is false; otherwise returns the result of evaluating the predicate fn. Ports Java's ConstrainedBoolean.filter().
func (ConstrainedBoolean) IsFalse ¶
func (cb ConstrainedBoolean) IsFalse() bool
IsFalse reports whether the boolean value is false. Ports Java's ConstrainedBoolean.isFalse().
func (ConstrainedBoolean) IsTrue ¶
func (cb ConstrainedBoolean) IsTrue() bool
IsTrue reports whether the boolean value is true (regardless of constraint). Ports Java's ConstrainedBoolean.isTrue().
type ConstraintMap ¶
type ConstraintMap struct {
// contains filtered or unexported fields
}
ConstraintMap holds constraints per Reference. Rules read constraints from the map and push new constraints for child References.
func NewConstraintMap ¶
func NewConstraintMap() *ConstraintMap
NewConstraintMap creates an empty constraint map.
type CrossProductIterator ¶
type CrossProductIterator[T any] struct { // contains filtered or unexported fields }
CrossProductIterator lazily enumerates the Cartesian product with support for skipping entire subtrees. When an incremental merge fails at depth d, Skip(d) advances past all combinations sharing the same prefix up to position d.
func NewCrossProductIterator ¶
func NewCrossProductIterator[T any](lists [][]T) *CrossProductIterator[T]
func (*CrossProductIterator[T]) HasNext ¶
func (it *CrossProductIterator[T]) HasNext() bool
func (*CrossProductIterator[T]) Next ¶
func (it *CrossProductIterator[T]) Next() []T
func (*CrossProductIterator[T]) Skip ¶
func (it *CrossProductIterator[T]) Skip(depth int)
Skip advances past all combinations sharing the same prefix up to position (depth-1). Equivalent to incrementing indices[depth-1] and resetting all deeper positions.
type DeMorganRule ¶
type DeMorganRule struct {
// contains filtered or unexported fields
}
DeMorganRule applies De Morgan's law to push a NOT past an AND or OR boundary:
NOT(AND(a, b, c)) ≡ OR (NOT a, NOT b, NOT c) NOT(OR (a, b, c)) ≡ AND(NOT a, NOT b, NOT c)
Mirrors Java's `DeMorgansTheoremRule`. Kleene-safe: each child term is independently negated and the major is swapped, preserving 3VL semantics. Reducing-after-fold: subsequent NotConstantSimplifyRule + AndConstantSimplifyRule passes can collapse the negated tree further (`NOT TRUE` → FALSE, `OR(FALSE, FALSE)` → FALSE, etc.).
**Not part of DefaultSimplifyRules.** Java applies De Morgan as a separate normalisation pass (`BooleanNormalizer`); the DefaultSimplifyRules set runs only constant-fold + identity-drop + absorbing-element + leaf-NOT-rewrite. Use NormalizationRules() (or build a custom rule list) when De Morgan is desired.
func (*DeMorganRule) Matcher ¶
func (r *DeMorganRule) Matcher() matching.BindingMatcher
func (*DeMorganRule) OnMatch ¶
func (r *DeMorganRule) OnMatch(call *RuleCall)
type DecorrelateValuesRule ¶
type DecorrelateValuesRule struct {
// contains filtered or unexported fields
}
DecorrelateValuesRule is an exploration rule that inlines "values boxes" into the parent SelectExpression. A values box is a quantifier over a SelectExpression whose result value is constant (uncorrelated to its own child quantifier) — typically produced by parameterized function inlining or constant subqueries.
Pattern:
SelectExpression( ForEach(alias=A) → Ref[SelectExpression(constResult, [ForEach → valuesSource], [])], ForEach(alias=B) → Ref[other], predicates referencing A )
Rewrite: replace references to alias A with the constant result value from the values box, remove the values box quantifier.
SelectExpression( ForEach(alias=B) → Ref[other], predicates with A→constResult substitution )
Ports Java's DecorrelateValuesRule (ExplorationCascadesRule).
func NewDecorrelateValuesRule ¶
func NewDecorrelateValuesRule() *DecorrelateValuesRule
func (*DecorrelateValuesRule) Matcher ¶
func (r *DecorrelateValuesRule) Matcher() matching.BindingMatcher
func (*DecorrelateValuesRule) OnMatch ¶
func (r *DecorrelateValuesRule) OnMatch(call *ExpressionRuleCall)
type DistinctMergeRule ¶
type DistinctMergeRule struct {
// contains filtered or unexported fields
}
DistinctMergeRule collapses LogicalDistinct(LogicalDistinct(X)) into a single LogicalDistinct(X) — DISTINCT is idempotent.
Java equivalent: there's no dedicated rule (the Cascades cost model would naturally prefer the single-Distinct shape); Go applies the uncontroversial static rewrite directly.
func NewDistinctMergeRule ¶
func NewDistinctMergeRule() *DistinctMergeRule
NewDistinctMergeRule constructs the rule with its pattern matcher pre-built.
func (*DistinctMergeRule) Matcher ¶
func (r *DistinctMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*DistinctMergeRule) OnMatch ¶
func (r *DistinctMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch examines the matched LogicalDistinct; if its inner is also a LogicalDistinct, yields a single LogicalDistinct over the inner-of- inner. Otherwise, declines.
type DistinctOverGroupByElimRule ¶
type DistinctOverGroupByElimRule struct {
// contains filtered or unexported fields
}
DistinctOverGroupByElimRule eliminates a LogicalDistinct that sits directly over a GroupByExpression. GROUP BY already produces at most one row per unique combination of grouping keys — DISTINCT on top is a no-op.
Distinct(GroupBy(keys, aggs, X)) → GroupBy(keys, aggs, X)
Java equivalent: part of RemoveRedundantDistinctRule family.
func NewDistinctOverGroupByElimRule ¶
func NewDistinctOverGroupByElimRule() *DistinctOverGroupByElimRule
func (*DistinctOverGroupByElimRule) Matcher ¶
func (r *DistinctOverGroupByElimRule) Matcher() matching.BindingMatcher
func (*DistinctOverGroupByElimRule) OnMatch ¶
func (r *DistinctOverGroupByElimRule) OnMatch(call *ExpressionRuleCall)
type DistinctOverSortElimRule ¶
type DistinctOverSortElimRule struct {
// contains filtered or unexported fields
}
DistinctOverSortElimRule eliminates a LogicalSort that sits directly under a LogicalDistinct.
Distinct(Sort([k1, k2, ...], X)) → Distinct(X)
SQL semantic justification: DISTINCT operates on a row-set (unordered); the inner Sort's ordering is lost the moment Distinct dedupes. So the inner sort is wasted work.
Edge case — Sort([]) (Unsorted): the inner is a no-op anyway. UnsortedSortElim handles it independently. This rule firing on that case is harmless (yields Distinct(unsorted's inner) = same thing UnsortedSortElim would have produced post-merge).
Termination: yields Distinct(sort.GetInner()) — REUSES the inner Sort's Quantifier (and therefore its Reference pointer). Second fire of the rule on the same input member produces a structurally- identical Distinct (same children-Reference pointers), so Reference.Insert's sameChildReferences dedup absorbs it.
Java equivalent: emerges from cost preference for cheaper plans. Seed implements directly so the optimiser produces the concretely-cheaper logical tree before B4 cost lands.
func NewDistinctOverSortElimRule ¶
func NewDistinctOverSortElimRule() *DistinctOverSortElimRule
NewDistinctOverSortElimRule constructs the rule.
func (*DistinctOverSortElimRule) Matcher ¶
func (r *DistinctOverSortElimRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*DistinctOverSortElimRule) OnMatch ¶
func (r *DistinctOverSortElimRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalSortExpression. Yields Distinct over the sort's inner Quantifier directly (NOT a fresh wrap — see Termination note).
type DistinctOverUnionDedupRule ¶
type DistinctOverUnionDedupRule struct {
// contains filtered or unexported fields
}
DistinctOverUnionDedupRule removes structurally-equivalent siblings from a LogicalUnion that sits inside a LogicalDistinct.
Distinct(Union(A, B, A')) where A SemanticEquals A' → Distinct(Union(A, B))
Soundness: the outer Distinct dedupes the FULL row stream, so any duplicate rows contributed by equivalent siblings get squashed. Producing them in the first place is wasted work. SQL-equivalent: DISTINCT(UNION ALL of equivalent operands) = DISTINCT(union of distinct ones).
Why we don't apply this directly to bare LogicalUnion (without an outer Distinct): UNION ALL semantics PRESERVE duplicates. Removing equivalent siblings would silently change row counts.
Termination: the rule yields a Distinct wrapping a Quantifier over a FRESH Reference holding the deduped Union. The fresh Reference would defeat the sameChildReferences pointer-identity dedup, but Reference.Insert's SemanticEquals fallback (post-680e664a) catches the structural equivalence and absorbs the second yield. Without that fallback, this rule non-terminates — the original revert in c789c211 documents the failure.
func NewDistinctOverUnionDedupRule ¶
func NewDistinctOverUnionDedupRule() *DistinctOverUnionDedupRule
NewDistinctOverUnionDedupRule constructs the rule.
func (*DistinctOverUnionDedupRule) Matcher ¶
func (r *DistinctOverUnionDedupRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*DistinctOverUnionDedupRule) OnMatch ¶
func (r *DistinctOverUnionDedupRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner is a LogicalUnion with at least one pair of structurally-equivalent siblings.
type Distinctness ¶
type Distinctness int
Distinctness specifies whether ordered records should be distinct.
const ( DistinctnessDistinct Distinctness = iota DistinctnessNotDistinct DistinctnessPreserveDistinctness )
type EliminateNullOnEmptyRule ¶
type EliminateNullOnEmptyRule struct {
// contains filtered or unexported fields
}
EliminateNullOnEmptyRule drops the null-on-empty flag from a SelectExpression's ForEach quantifier when some predicate of the surrounding SELECT PROVABLY REJECTS the null tuple that the null-on-empty quantifier would inject at that quantifier's alias.
Ports Java's EliminateNullOnEmptyRule (#4186), which REPLACED the buggy PullUpNullOnEmptyRule. PullUp's "positional-predicate-equality heuristic" (predicates.equals(otherPredicates)) was wrong with predicates that ACCEPT the injected null tuple (`… WHERE x IS NULL` over a null-on-empty leg) — it assumed the null tuple is always rejected. The correct test is semantic: substitute a typed NullValue at the quantifier's alias, constant-fold the predicate, and the quantifier is eligible iff the fold is FALSE or NULL (both filter the row out).
Per-alias: a null-rejecting predicate over alias A eliminates A's null-on-empty flag while leaving a null-ACCEPTING sibling (`B IS NULL`) over alias B intact.
Reachability note (RFC-144 §1.2): `ForEachNullOnEmptyQuantifier` has no SQL producer in Go today (outer joins use the materialized NLJ; FirstOrDefault uses a streaming Value, not a null-on-empty quantifier). This rule is Java-parity / latent-rule hygiene: IF a null-on-empty producer is wired later (or a synthetic path hits it) it is correct, and Go matches Java's rule set.
func NewEliminateNullOnEmptyRule ¶
func NewEliminateNullOnEmptyRule() *EliminateNullOnEmptyRule
NewEliminateNullOnEmptyRule constructs the rule.
func (*EliminateNullOnEmptyRule) Matcher ¶
func (r *EliminateNullOnEmptyRule) Matcher() matching.BindingMatcher
func (*EliminateNullOnEmptyRule) OnMatch ¶
func (r *EliminateNullOnEmptyRule) OnMatch(call *ExpressionRuleCall)
type ExploreExprTask ¶
type ExploreExprTask struct {
Phase PlannerPhase
Ref *expressions.Reference
Expr expressions.RelationalExpression
}
ExploreExprTask pushes rule-transform tasks and child-exploration tasks for a single (group, expression) pair. Mirrors Java's AbstractExploreExpression.
func (*ExploreExprTask) Run ¶
func (t *ExploreExprTask) Run(p *Planner)
type ExploreGroupTask ¶
type ExploreGroupTask struct {
Phase PlannerPhase
Ref *expressions.Reference
}
ExploreGroupTask explores a Reference within a phase. If the Reference's stage is behind the phase's target, it calls advancePlannerStage to transition. Then pushes exploration tasks for all members. Mirrors Java's CascadesPlanner.ExploreGroup.
func (*ExploreGroupTask) Run ¶
func (t *ExploreGroupTask) Run(p *Planner)
type ExpressionMatchAdjuster ¶
type ExpressionMatchAdjuster interface {
// AdjustMatch attempts to refine the given PartialMatch by
// absorbing this expression on the candidate side. Returns a new
// MatchInfo on success, or nil if the expression cannot be
// absorbed.
AdjustMatch(pm PartialMatch) MatchInfo
}
ExpressionMatchAdjuster is an optional interface that a RelationalExpression can implement to support match adjustment. When the AdjustMatches pass encounters a candidate expression that implements this interface, it calls AdjustMatch to produce a refined MatchInfo wrapping the existing PartialMatch's MatchInfo.
In Java, this is the default method RelationalExpression.adjustMatch(PartialMatch) which returns Optional.empty(). Concrete overrides exist on MatchableSortExpression and SelectExpression.
type ExpressionMatcher ¶
type ExpressionMatcher[T expressions.RelationalExpression] struct { // contains filtered or unexported fields }
ExpressionMatcher type-asserts a candidate against a specific RelationalExpression concrete type T and binds the host on match. Counterpart to the existing `predicateMatcher[T]` for QueryPredicate rules — same shape, different type bound.
Used by RelationalExpression-shaped rules (FilterMergeRule, PushFilterThroughDistinctRule, and the rest of the rule_*.go files).
func NewExpressionMatcher ¶
func NewExpressionMatcher[T expressions.RelationalExpression](rootType string) *ExpressionMatcher[T]
NewExpressionMatcher constructs a typed matcher for the given RelationalExpression subtype. Each call returns a distinct allocation so pointer-identity comparisons stay distinct across rule instances.
func (*ExpressionMatcher[T]) BindMatches ¶
func (m *ExpressionMatcher[T]) BindMatches(outer *matching.PlannerBindings, in any) []*matching.PlannerBindings
BindMatches type-asserts `in` to T; on success binds m → in in the outer bindings and returns one new binding set. On failure returns nil.
func (*ExpressionMatcher[T]) RootType ¶
func (m *ExpressionMatcher[T]) RootType() string
RootType returns the rule's debug-friendly root identifier.
type ExpressionRule ¶
type ExpressionRule interface {
Matcher() matching.BindingMatcher
OnMatch(call *ExpressionRuleCall)
}
ExpressionRule is the transform interface for RelationalExpression- shaped rules. Counterpart to CascadesRule for the QueryPredicate / Value-shaped rules. Each impl provides:
- Matcher: pattern the rule fires on (typically an ExpressionMatcher for the rule's root expression type).
- OnMatch: rule body — reads call.Bindings via Get[T] / Get and calls call.Yield(replacement) for each rewritten expression.
func BatchAExpressionRules ¶
func BatchAExpressionRules() []ExpressionRule
BatchAExpressionRules returns the physical-implementation rules (PrimaryScanRule, ImplementFilterRule, etc.). These fire during the PLANNING phase via WithPlanningExpressionRules. They yield to InsertFinal so their results land in FinalMembers.
Matches Java's PlanningRuleSet.IMPLEMENTATION_RULES.
func DMLImplementationRules ¶
func DMLImplementationRules() []ExpressionRule
DMLImplementationRules returns the DML-side implementation rules (ImplementInsertRule, ImplementDeleteRule). Mirrors Java's per-DML implementation rule set.
Compose with: append(rules, DMLImplementationRules()...) when the planner needs to physical-implement DML expressions (INSERT / DELETE / UPDATE).
All 3 DML implement rules now ported (Insert / Delete / Update). Per-row transform application for Update happens at execution time, not rule-fire time — transforms pass through unchanged.
func DefaultExpressionRules ¶
func DefaultExpressionRules() []ExpressionRule
DefaultExpressionRules returns the REWRITING-phase exploration rule set the optimiser fires by default: uncontroversial logical-to-logical rewrites that don't need cost-aware decisions (the physical-implementation rules live in BatchAExpressionRules / DefaultImplementationRules, PLANNING phase). Order matters within an exploration round: merge-rules run first (collapse nested operators of the same kind), then no-op-elimination rules run on the merged shapes. Order across rounds doesn't matter because the task-stack driver re-fires every rule against newly-yielded members until the group saturates.
**Alias rebasing caveat**: every Push*Through* and Pull*Above* rule in this set moves a Filter (or TypeFilter) across a Quantifier boundary without rewriting the moved operator's internal alias references — predicates and Values inside the moved operator keep referencing the ORIGINAL quantifier's alias (no TranslationMap rebase at the move site). Harmless for row-set semantics (no evaluator resolves the moved predicates through those aliases), but a rule that inspects correlation structure (GetCorrelatedToWithoutChildren) on a pushed predicate sees the stale alias. Correlation-aware logic must not consume pushed/pulled predicates without a TranslationMap rebase (translation_map.go) first.
**ProjectionMergeRule's soundness contract**: the merge `Projection(P1) over Projection(P2) over X → Projection(P1) over X` is sound only because LogicalProjectionExpression's GetResultValue() passes the inner row through (projection is a pure side channel). If projection ever narrows the row shape (materialized projections), P1's Values may reference computed columns that only exist in P2's output — at that point the rule needs a column-substitution rewrite path or it must leave the default set. See ProjectionMergeRule's own doc for the per-rule discussion.
Each call returns a fresh slice — callers may mutate freely. Each element is a fresh rule instance — see NewXxxRule constructors for the per-call allocation contract.
func LookupRule ¶
func LookupRule(name string) ExpressionRule
LookupRule returns the rule registered under `name`, or nil if not found.
func MatchingRules ¶
func MatchingRules() []ExpressionRule
MatchingRules returns the matching rules that seed the partial-match infrastructure. These fire during the EXPLORE phase alongside expression rules but serve a different purpose: they establish PartialMatch instances between the query graph and MatchCandidate traversals, which are then consumed by implementation rules to produce index-scan plans.
Mirrors Java's PlanningRuleSet.MATCHING_RULES:
- MatchLeafRule: seeds leaf-to-leaf matches
- MatchIntermediateRule: composes child matches into parent matches
Compose with: append(DefaultExpressionRules(), MatchingRules()...)
func PlanningExplorationRules ¶
func PlanningExplorationRules() []ExpressionRule
PlanningExplorationRules returns the exploration rules that re-fire during the PLANNING phase after advancePlannerStage clears EXPLORE artifacts. These re-derive logical alternatives from the promoted canonical seed. Mirrors Java's PlanningRuleSet.EXPLORATION_RULES.
func RegisterRule ¶
func RegisterRule(name string, r ExpressionRule) ExpressionRule
RegisterRule adds the rule to the package-level registry under `name`. Returns the rule unchanged so callers can inline the register call:
var myRule = RegisterRule("MyRule", &MyRule{...})
Panics on duplicate name — registry collision is a programmer error, not runtime data.
func RewritingRules ¶
func RewritingRules() []ExpressionRule
RewritingRules returns the exploration rules for the REWRITING phase. Mirrors Java's RewritingRuleSet.EXPLORATION_RULES:
- QueryPredicateSimplificationRule: constant-fold predicate values
- PredicatePushDownRule: push predicates into child quantifiers
- DecorrelateValuesRule: inline constant value boxes
These rules are NOT part of DefaultExpressionRules — they target the REWRITING phase, which runs before the main PLANNING phase to normalise the expression tree. The planner driver composes rule sets as needed.
type ExpressionRuleCall ¶
type ExpressionRuleCall struct {
Bindings *matching.PlannerBindings
Reference *expressions.Reference
Context PlanContext
Constraints *ConstraintMap
// Stats is the planner's table-cardinality provider, threaded so a
// rule's internal cost comparisons (e.g. selecting the best physical
// join child) use REAL cardinalities rather than the default
// LeafScanCardinality. Nil on test/utility firing paths — CostModel()
// falls back to the default-stats comparator. Without this, the NLJ
// rule's findBestValidPhysicalExpr ranks join children with every table at
// LeafScanCardinality, so child selection ties and commits to the
// FROM-clause order instead of the cost-optimal one (RFC-041).
Stats properties.StatisticsProvider
// contains filtered or unexported fields
}
ExpressionRuleCall is the rule-invocation context used by RelationalExpression-shaped rules. Counterpart to the existing RuleCall (which targets QueryPredicate / Value rules) — split per type so each rule shape gets a strongly-typed Yield.
Ports the consulted surface of Java's `com.apple.foundationdb.record.query.plan.cascades.CascadesRuleCall` (Java's class also covers partial-match yields, planner-phase plumbing, and traversal-state hooks). Go exposes:
- Bindings: the pattern matcher's results, keyed by matcher identity (already provided by `matching.PlannerBindings`).
- Reference: the memo group whose member fired the rule. Yields append to this Reference; the dedup happens via Reference.Insert.
- Context: the PlanContext (planner config + match candidates).
- Memo: the Memo for cross-Reference memoization (nil when running outside the Planner, e.g. in standalone tests).
- Yield(expr): insert a new equivalent expression into the Reference.
- MemoizeExpression(expr): find-or-create a Reference for a sub-expression via the Memo. Falls back to InitialOf when no Memo is present.
- Yielded(): the list of expressions yielded so far. Tests + the planner's traversal driver consume this.
Java's flavoured yields (exploratory / final / plan / unknown) map onto the single Yield here: the task-stack driver installs a per-phase yield function (yieldFn — nil during exploration, so Yield goes to Reference.Insert; both InsertFinal and Insert during PLANNING; see unified_tasks.go and expression_rule_adapter.go), and the data-access path routes by physicality via the planner's yieldUnknown.
func NewExpressionRuleCall ¶
func NewExpressionRuleCall(ref *expressions.Reference, bindings *matching.PlannerBindings, ctx PlanContext) *ExpressionRuleCall
NewExpressionRuleCall builds a rule-call against a Reference + an already-computed binding set. Context defaults to EmptyPlanContext if nil — convenient for tests that don't depend on planner config.
func NewExpressionRuleCallWithMemo ¶
func NewExpressionRuleCallWithMemo(ref *expressions.Reference, bindings *matching.PlannerBindings, ctx PlanContext, memo *Memo) *ExpressionRuleCall
NewExpressionRuleCallWithMemo builds a rule-call with a Memo for cross-Reference memoization. Used by the Planner's ApplyRulesTask.
func (*ExpressionRuleCall) CostModel ¶
func (c *ExpressionRuleCall) CostModel() func(a, b expressions.RelationalExpression) bool
CostModel returns the comparator a rule should use for internal best-plan selection: stats-aware when the planner threaded statistics, else the default-stats comparator.
func (*ExpressionRuleCall) GetRequestedOrderings ¶
func (c *ExpressionRuleCall) GetRequestedOrderings() []*RequestedOrdering
GetRequestedOrderings returns the requested orderings for this Reference from the constraint map, if available. Returns nil if no ordering constraint is set or no constraint map is present.
func (*ExpressionRuleCall) MemoizeExpression ¶
func (c *ExpressionRuleCall) MemoizeExpression(expr expressions.RelationalExpression) *expressions.Reference
MemoizeExpression finds or creates a Reference for a sub-expression. When a Memo is present (running inside the Planner), this checks if an existing Reference already holds a structurally-equivalent expression and returns it — enabling cross-Reference sharing. Without a Memo (standalone rule testing), falls back to expressions.InitialOf(expr).
The current call's Reference (the one the rule is yielding into) is excluded from reuse to prevent self-referential cycles. This mirrors Java's guard: `Verify.verify(existingReference != this.root)`.
Rules should use this instead of expressions.InitialOf when creating child References for yielded expressions. This is how the Cascades planner avoids redundant exploration of shared sub-trees.
func (*ExpressionRuleCall) Yield ¶
func (c *ExpressionRuleCall) Yield(expr expressions.RelationalExpression) bool
Yield inserts `expr` into the Reference's equivalence class. Returns true if the expression was a new member, false if Reference.Insert detected a duplicate (matching EqualsWithoutChildren under empty alias map). yieldedExps records the call regardless — the rule's intent was to yield, even if dedup absorbed the result.
func (*ExpressionRuleCall) Yielded ¶
func (c *ExpressionRuleCall) Yielded() []expressions.RelationalExpression
Yielded returns the expressions the rule has yielded so far, including duplicates that Reference.Insert filtered. Useful for rule-firing tests that want to assert on the rule's output without reaching into the Reference's member list.
type FilterDedupPredicatesRule ¶
type FilterDedupPredicatesRule struct {
// contains filtered or unexported fields
}
FilterDedupPredicatesRule removes structurally-duplicate predicates from a LogicalFilter's predicate list.
Filter([P, Q, P], X) → Filter([P, Q], X)
SQL semantics: WHERE P AND Q AND P = WHERE P AND Q (idempotent AND). The duplicate adds no row-rejection power.
Soundness via Explain text: two predicates compare equal iff their Explain() rendering matches. Same bridge as the existing `valueNamesEqual` helper in the predicates package.
Termination: yields Filter with deduped list, REUSING the inner Quantifier. Pointer-identity dedup absorbs second fire.
Composes with FilterMergeRule (which can leave duplicates after flattening nested Filters) and AndDedupRule (which dedupes inside an AND predicate at the predicate-tree level — different layer).
func NewFilterDedupPredicatesRule ¶
func NewFilterDedupPredicatesRule() *FilterDedupPredicatesRule
NewFilterDedupPredicatesRule constructs the rule.
func (*FilterDedupPredicatesRule) Matcher ¶
func (r *FilterDedupPredicatesRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*FilterDedupPredicatesRule) OnMatch ¶
func (r *FilterDedupPredicatesRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the predicate list contains at least one Explain-equal duplicate pair.
type FilterDropTruePredicatesRule ¶
type FilterDropTruePredicatesRule struct {
// contains filtered or unexported fields
}
FilterDropTruePredicatesRule drops TriTrue ConstantPredicates from a LogicalFilter's predicate list (without eliminating the filter itself). Composes naturally with FilterMergeRule (which can leave trivial TRUE conjuncts after merging) and NoOpFilterRule (which then eliminates the filter if ALL predicates are TRUE).
Pattern:
Filter([..., TriTrue-ConstantPredicate, ...]) over X → Filter([... without TriTrue ...]) over X
Yields the new Filter only if at least one TriTrue predicate is dropped — otherwise declines.
If dropping leaves the predicate list empty, the rule still fires; NoOpFilterRule will then eliminate the now-trivial Filter on a subsequent exploration round.
func NewFilterDropTruePredicatesRule ¶
func NewFilterDropTruePredicatesRule() *FilterDropTruePredicatesRule
NewFilterDropTruePredicatesRule constructs the rule.
func (*FilterDropTruePredicatesRule) Matcher ¶
func (r *FilterDropTruePredicatesRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*FilterDropTruePredicatesRule) OnMatch ¶
func (r *FilterDropTruePredicatesRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when at least one predicate is TriTrue.
type FilterMergeRule ¶
type FilterMergeRule struct {
// contains filtered or unexported fields
}
FilterMergeRule consolidates a LogicalFilter whose inner Quantifier ranges over another LogicalFilter into a single LogicalFilter with both predicate lists concatenated. SQL-equivalent: WHERE p1 AND p2 AND p3 ... regardless of whether the parser nested the conjuncts.
Pattern:
LogicalFilter([p_outer...])
inner: ForEachQuantifier → Reference holding LogicalFilter([p_inner...])
inner: ForEachQuantifier → Reference holding any RelationalExpression X
Rewrite:
LogicalFilter([p_outer..., p_inner...]) inner: ForEachQuantifier → Reference holding X
Java equivalent: LogicalFilterMergeRule (or the equivalent SimplifyFilterRule) in `cascades/rules/`.
func NewFilterMergeRule ¶
func NewFilterMergeRule() *FilterMergeRule
NewFilterMergeRule constructs the rule with its pattern matcher pre-built (avoids per-call allocation in the planner driver).
func (*FilterMergeRule) Matcher ¶
func (r *FilterMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*FilterMergeRule) OnMatch ¶
func (r *FilterMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch examines the matched LogicalFilter; if its inner Quantifier's Reference holds another LogicalFilter, yields a single merged LogicalFilter. Otherwise, declines (zero yields).
type FinalizeExpressionsRule ¶
type FinalizeExpressionsRule struct {
// contains filtered or unexported fields
}
FinalizeExpressionsRule is a REWRITING-phase ImplementationRule that promotes any exploratory expression to a final expression. This is how the REWRITING phase marks its canonical output for OptimizeGroup to select the best, and for advancePlannerStage to promote as the PLANNING seed.
Mirrors Java's FinalizeExpressionsRule.
func NewFinalizeExpressionsRule ¶
func NewFinalizeExpressionsRule() *FinalizeExpressionsRule
func (*FinalizeExpressionsRule) Matcher ¶
func (r *FinalizeExpressionsRule) Matcher() matching.BindingMatcher
func (*FinalizeExpressionsRule) OnMatch ¶
func (r *FinalizeExpressionsRule) OnMatch(call *ImplementationRuleCall)
type ForMatchCompensation ¶
type ForMatchCompensation struct {
// contains filtered or unexported fields
}
ForMatchCompensation is the primary compensation implementation for matches based on query predicates. It tracks matched/unmatched quantifiers, predicate compensation, result compensation, and group-by mappings.
Ports Java's Compensation.ForMatch (which implements Compensation.WithSelectCompensation).
func DerivedCompensation ¶
func DerivedCompensation( parent Compensation, impossible bool, predicateCompensationMap *PredicateCompensationMap, matchedQuantifiers []expressions.Quantifier, unmatchedQuantifiers []expressions.Quantifier, compensatedAliases map[values.CorrelationIdentifier]struct{}, resultCompensationFn *ResultCompensationFunction, groupByMappings *GroupByMappings, ) *ForMatchCompensation
DerivedCompensation creates a new ForMatchCompensation with `parent` as its child compensation. This is the package-level equivalent of Java's Compensation.derived() default method, usable with any Compensation (not just ForMatchCompensation).
func NewForMatchCompensation ¶
func NewForMatchCompensation( impossible bool, childCompensation Compensation, predicateCompensationMap *PredicateCompensationMap, matchedQuantifiers []expressions.Quantifier, unmatchedQuantifiers []expressions.Quantifier, compensatedAliases map[values.CorrelationIdentifier]struct{}, resultCompensationFn *ResultCompensationFunction, groupByMappings *GroupByMappings, ) *ForMatchCompensation
NewForMatchCompensation constructs a ForMatchCompensation.
Mirrors Java's Compensation.ForMatch constructor. All collection fields are defensively copied.
func (*ForMatchCompensation) Apply ¶
func (c *ForMatchCompensation) Apply( expr expressions.RelationalExpression, translationMapFunc TranslationMapFunc, ) expressions.RelationalExpression
Apply applies this compensation to a relational expression by wrapping it with residual predicate filters. Returns the original expression if no compensation is needed.
translationMapFunc, given the realized base-quantifier alias, yields a TranslationMap that rebases compensated predicates from the candidate's top alias to the realized alias. The realized base quantifier is created with the matched query-side ForEach alias (matchedForEachAlias) — exactly as Java does — so the compensation expression flows under the SAME alias the surrounding query graph already correlates to. Allocating a fresh alias here instead orphans the access from outer correlations (the outer join's reference to the matched source no longer resolves), which is how a dual-correlation join collapsed to Fetch(<nil>) and returned 0 rows.
Ports Java's Compensation.ForMatch.apply — full implementation including the else-branch (multi-join compensation with unmatched ForEach quantifiers pulled up into a new SelectExpression).
func (*ForMatchCompensation) ApplyAllNeeded ¶
func (c *ForMatchCompensation) ApplyAllNeeded( expr expressions.RelationalExpression, translationMapFunc TranslationMapFunc, ) expressions.RelationalExpression
ApplyAllNeeded applies both filter compensation (Apply) and result compensation (ApplyFinal) as needed. This is the primary entry point for applying compensation to a plan expression.
Ports Java's Compensation.applyAllNeededCompensations.
func (*ForMatchCompensation) ApplyFinal ¶
func (c *ForMatchCompensation) ApplyFinal( expr expressions.RelationalExpression, translationMapFunc TranslationMapFunc, ) expressions.RelationalExpression
ApplyFinal applies the result (shape) compensation by wrapping the expression in a SelectExpression with the translated result value. Returns the original expression if no result compensation is needed.
Ports Java's Compensation.WithSelectCompensation.applyFinal which uses GraphExpansion.builder().addQuantifier(base).build() .buildSelectWithResultValue(resultValue).
func (*ForMatchCompensation) CanBeDeferred ¶
func (c *ForMatchCompensation) CanBeDeferred() bool
CanBeDeferred reports whether this compensation can be combined with subsequent compensations further up the graph. Mirrors Java's Compensation.canBeDeferred() default (always returns true).
func (*ForMatchCompensation) Derived ¶
func (c *ForMatchCompensation) Derived( impossible bool, predicateCompensationMap *PredicateCompensationMap, matchedQuantifiers []expressions.Quantifier, unmatchedQuantifiers []expressions.Quantifier, compensatedAliases map[values.CorrelationIdentifier]struct{}, resultCompensationFn *ResultCompensationFunction, groupByMappings *GroupByMappings, ) *ForMatchCompensation
Derived creates a new ForMatchCompensation with this compensation as its child. This mirrors Java's Compensation.derived() default method.
func (*ForMatchCompensation) GetChildCompensation ¶
func (c *ForMatchCompensation) GetChildCompensation() Compensation
GetChildCompensation returns the child (inner) compensation.
func (*ForMatchCompensation) GetCompensatedAliases ¶
func (c *ForMatchCompensation) GetCompensatedAliases() map[values.CorrelationIdentifier]struct{}
GetCompensatedAliases returns the set of aliases this compensation is responsible for. When applied, the caller can be assured that the match replacement plus this compensation can replace the quantifiers identified by these aliases.
func (*ForMatchCompensation) GetGroupByMappings ¶
func (c *ForMatchCompensation) GetGroupByMappings() *GroupByMappings
GetGroupByMappings returns the group-by mappings.
func (*ForMatchCompensation) GetMatchedForEachAlias ¶
func (c *ForMatchCompensation) GetMatchedForEachAlias() values.CorrelationIdentifier
GetMatchedForEachAlias returns the single ForEach quantifier alias among the matched quantifiers. Java uses this as the target for the matchedToRealizedTranslationMap. Ports Java's getMatchedForEachAlias.
func (*ForMatchCompensation) GetMatchedQuantifiers ¶
func (c *ForMatchCompensation) GetMatchedQuantifiers() []expressions.Quantifier
GetMatchedQuantifiers returns the set of quantifiers that were matched during matching.
func (*ForMatchCompensation) GetPredicateCompensationMap ¶
func (c *ForMatchCompensation) GetPredicateCompensationMap() *PredicateCompensationMap
GetPredicateCompensationMap returns the predicate compensation map.
func (*ForMatchCompensation) GetResultCompensationFunction ¶
func (c *ForMatchCompensation) GetResultCompensationFunction() *ResultCompensationFunction
GetResultCompensationFunction returns the result compensation function.
func (*ForMatchCompensation) GetUnmatchedForEachQuantifiers ¶
func (c *ForMatchCompensation) GetUnmatchedForEachQuantifiers() []expressions.Quantifier
GetUnmatchedForEachQuantifiers returns the subset of unmatched quantifiers that are ForEach quantifiers. The result is lazily computed and cached.
Mirrors Java's ForMatch.computeUnmatchedForEachQuantifiers() with Suppliers.memoize.
func (*ForMatchCompensation) GetUnmatchedQuantifiers ¶
func (c *ForMatchCompensation) GetUnmatchedQuantifiers() []expressions.Quantifier
GetUnmatchedQuantifiers returns the set of quantifiers that were NOT matched during matching.
func (*ForMatchCompensation) Intersect ¶
func (c *ForMatchCompensation) Intersect(other *ForMatchCompensation) Compensation
Intersect combines this compensation with another by keeping only predicates that appear in both (common residuals for index intersections). Returns ImpossibleCompensation if the intersection is infeasible.
Ports Java's Compensation.WithSelectCompensation.intersect.
func (*ForMatchCompensation) IsFinalNeeded ¶
func (c *ForMatchCompensation) IsFinalNeeded() bool
IsFinalNeeded reports whether final result-shape compensation is needed. Mirrors Java's WithSelectCompensation.isFinalNeeded() default method.
func (*ForMatchCompensation) IsImpossible ¶
func (c *ForMatchCompensation) IsImpossible() bool
IsImpossible reports whether this compensation is infeasible.
func (*ForMatchCompensation) IsNeeded ¶
func (c *ForMatchCompensation) IsNeeded() bool
IsNeeded reports whether this compensation must be applied. Mirrors Java's WithSelectCompensation.isNeeded() default method.
func (*ForMatchCompensation) IsNeededForFiltering ¶
func (c *ForMatchCompensation) IsNeededForFiltering() bool
IsNeededForFiltering reports whether this compensation needs to be applied for correct filtering. Mirrors Java's WithSelectCompensation.isNeededForFiltering() default method.
func (*ForMatchCompensation) String ¶
func (c *ForMatchCompensation) String() string
String returns a human-readable representation of this compensation. Mirrors Java's ForMatch.toString().
func (*ForMatchCompensation) Union ¶
func (c *ForMatchCompensation) Union(other *ForMatchCompensation) Compensation
Union combines this compensation with another by merging predicate maps from both sides. Used when multiple partial matches combine their compensations (e.g. union of data access matches).
Ports Java's Compensation.WithSelectCompensation.union.
type GraphExpansion ¶
type GraphExpansion struct {
// contains filtered or unexported fields
}
GraphExpansion accumulates index-expansion components (result columns, predicates, quantifiers, placeholders) before they are sealed and built into a SelectExpression. Mirrors Java's `com.apple.foundationdb.record.query.plan.cascades.GraphExpansion`.
Think of it as a builder for SelectExpression that also supports merging multiple expansions and inspecting intermediate state. The fundamental difference from a regular builder is that it exposes getters and additive merge semantics.
func EmptyGraphExpansion ¶
func EmptyGraphExpansion() *GraphExpansion
EmptyGraphExpansion returns a zero-valued expansion with all slices initialized (non-nil but empty). Equivalent to Java's `GraphExpansion.empty()`.
func MergeGraphExpansions ¶
func MergeGraphExpansions(expansions ...*GraphExpansion) *GraphExpansion
MergeGraphExpansions combines multiple expansions by concatenating their result columns, predicates, quantifiers, and placeholders. Equivalent to Java's `GraphExpansion.ofOthers(...)`.
func NewGraphExpansion ¶
func NewGraphExpansion( columns []GraphExpansionColumn, preds []predicates.QueryPredicate, quants []expressions.Quantifier, phs []*predicates.Placeholder, ) *GraphExpansion
NewGraphExpansion constructs a GraphExpansion from explicit slices. All slices are defensively copied. Equivalent to Java's `GraphExpansion.of(...)`.
func (*GraphExpansion) GetPlaceholders ¶
func (g *GraphExpansion) GetPlaceholders() []*predicates.Placeholder
GetPlaceholders returns the placeholder list.
func (*GraphExpansion) GetPredicates ¶
func (g *GraphExpansion) GetPredicates() []predicates.QueryPredicate
GetPredicates returns the predicate list.
func (*GraphExpansion) GetQuantifiers ¶
func (g *GraphExpansion) GetQuantifiers() []expressions.Quantifier
GetQuantifiers returns the quantifier list.
func (*GraphExpansion) GetResultColumns ¶
func (g *GraphExpansion) GetResultColumns() []GraphExpansionColumn
GetResultColumns returns the result column list.
func (*GraphExpansion) Seal ¶
func (g *GraphExpansion) Seal() *SealedGraphExpansion
Seal deduplicates placeholders and returns an immutable SealedGraphExpansion. Mirrors Java's `GraphExpansion.seal()`.
Placeholder deduplication:
- Group by ParameterAlias — placeholders with the same alias are collapsed (ranges merged).
- Among the unique-by-alias placeholders, identify those whose Values are semantically equal (by structural comparison). Replace all duplicates-by-value with the first representative.
The resulting SealedGraphExpansion carries deduplicated predicates, the original quantifiers, deduplicated placeholders, and a result value built from the columns.
type GraphExpansionBuilder ¶
type GraphExpansionBuilder struct {
// contains filtered or unexported fields
}
GraphExpansionBuilder accumulates graph expansion components incrementally. Mirrors Java's `GraphExpansion.Builder`.
func NewGraphExpansionBuilder ¶
func NewGraphExpansionBuilder() *GraphExpansionBuilder
NewGraphExpansionBuilder returns an empty builder.
func (*GraphExpansionBuilder) AddColumn ¶
func (b *GraphExpansionBuilder) AddColumn(name string, value values.Value) *GraphExpansionBuilder
AddColumn appends a named result column.
func (*GraphExpansionBuilder) AddPlaceholder ¶
func (b *GraphExpansionBuilder) AddPlaceholder(p *predicates.Placeholder) *GraphExpansionBuilder
AddPlaceholder appends a placeholder.
func (*GraphExpansionBuilder) AddPredicate ¶
func (b *GraphExpansionBuilder) AddPredicate(pred predicates.QueryPredicate) *GraphExpansionBuilder
AddPredicate appends a predicate.
func (*GraphExpansionBuilder) AddQuantifier ¶
func (b *GraphExpansionBuilder) AddQuantifier(q expressions.Quantifier) *GraphExpansionBuilder
AddQuantifier appends a quantifier.
func (*GraphExpansionBuilder) Build ¶
func (b *GraphExpansionBuilder) Build() *GraphExpansion
Build produces a GraphExpansion from the accumulated state.
type GraphExpansionColumn ¶
GraphExpansionColumn pairs a column name with the Value that computes its contents. Mirrors Java's Column<? extends Value> in the context of GraphExpansion — simplified since Go doesn't have Java's typed Field wrapper. An empty Name represents an unnamed/anonymous column.
type GroupByMappings ¶
type GroupByMappings struct {
// contains filtered or unexported fields
}
GroupByMappings tracks matched groupings, matched aggregates, and unmatched aggregates during aggregate index matching. It is a data holder with immutable semantics — all maps are defensively copied at construction time.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.GroupByMappings.
Fields:
- matchedGroupingsMap: query grouping Value -> candidate grouping Value (bijective)
- matchedAggregatesMap: query aggregate Value -> candidate aggregate Value (bijective)
- unmatchedAggregatesMap: CorrelationIdentifier -> query aggregate Value not yet matched (bijective)
func AdjustGroupByMappings ¶
func AdjustGroupByMappings( gbm *GroupByMappings, candidateAlias values.CorrelationIdentifier, candidateResultValue values.Value, ) *GroupByMappings
AdjustGroupByMappings pulls up the GroupByMappings through a candidate expression. For each matched grouping/aggregate value pair, pulls up the candidate-side value through the candidate expression's result value.
Ports Java's MatchInfo.adjustGroupByMappings.
func EmptyGroupByMappings ¶
func EmptyGroupByMappings() *GroupByMappings
EmptyGroupByMappings returns a GroupByMappings with all three maps empty. Mirrors Java's GroupByMappings.empty().
func NewGroupByMappings ¶
func NewGroupByMappings( matchedGroupingsMap *BiMap[values.Value, values.Value], matchedAggregatesMap *BiMap[values.Value, values.Value], unmatchedAggregatesMap *BiMap[values.CorrelationIdentifier, values.Value], ) *GroupByMappings
NewGroupByMappings creates a GroupByMappings from the three maps. All maps are defensively copied so mutations to the originals don't affect this instance. Mirrors Java's GroupByMappings.of().
func (*GroupByMappings) MatchedAggregatesMap ¶
MatchedAggregatesMap returns the bidirectional map from query aggregate Values to candidate aggregate Values.
func (*GroupByMappings) MatchedGroupingsMap ¶
MatchedGroupingsMap returns the bidirectional map from query grouping Values to candidate grouping Values.
func (*GroupByMappings) UnmatchedAggregatesMap ¶
func (g *GroupByMappings) UnmatchedAggregatesMap() *BiMap[values.CorrelationIdentifier, values.Value]
UnmatchedAggregatesMap returns the bidirectional map from CorrelationIdentifiers to query aggregate Values that don't have a candidate match.
type ImplementDeleteRule ¶
type ImplementDeleteRule struct {
// contains filtered or unexported fields
}
ImplementDeleteRule implements a logical DeleteExpression as a physical RecordQueryDeletePlan, gated on the inner Reference having at least one physical-plan member.
Delete(target, inner-with-physical-member) → DeletePlan(target, inner-physical)
Same gating pattern as the other Implement rules. Java's ImplementDeleteRule consults StoredRecordProperty for partition dispatch; Go always emits.
func NewImplementDeleteRule ¶
func NewImplementDeleteRule() *ImplementDeleteRule
NewImplementDeleteRule constructs the rule.
func (*ImplementDeleteRule) Matcher ¶
func (r *ImplementDeleteRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementDeleteRule) OnMatch ¶
func (r *ImplementDeleteRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires on every DeleteExpression with a physical inner.
type ImplementDistinctFinalRule ¶
type ImplementDistinctFinalRule struct {
// contains filtered or unexported fields
}
Go extension: Java's fdb-relational 4.11.1.0 rejects SELECT DISTINCT for most query shapes; Go supports it broadly via this rule and the hash-distinct executor.
ImplementDistinctFinalRule is the PLANNING-phase rule for LogicalDistinctExpression. Ports Java's ImplementDistinctRule (ImplementationCascadesRule<LogicalDistinctExpression>).
For each physical FinalMember, the rule checks two sources of distinctness information:
- Physical-level DistinctRecordsProperty — per-member, matching Java's ImplementDistinctRule 1:1. A scan on a unique index, an identity-mapping MapPlan, etc. propagate distinctness through the property system.
- Logical-level PK/unique-index column coverage — Go extension, fallback. If the projected columns cover a primary key or unique index, ALL physical plans are guaranteed distinct (equivalent to Java's "strictlySorted" path where all partition members get elided).
When either check passes, the Distinct operator is elided and the inner plan is yielded directly. Otherwise, the inner is wrapped with RecordQueryDistinctPlan.
This rule subsumes the former DistinctOnUniqueElimRule (which ran during EXPLORE). Moving the elimination check to PLANNING matches Java's architecture: ImplementDistinctRule is an ImplementationCascadesRule, not an exploration rule.
func NewImplementDistinctFinalRule ¶
func NewImplementDistinctFinalRule() *ImplementDistinctFinalRule
func (*ImplementDistinctFinalRule) Matcher ¶
func (r *ImplementDistinctFinalRule) Matcher() matching.BindingMatcher
func (*ImplementDistinctFinalRule) OnMatch ¶
func (r *ImplementDistinctFinalRule) OnMatch(call *ImplementationRuleCall)
type ImplementDistinctUnionRule ¶
type ImplementDistinctUnionRule struct {
// contains filtered or unexported fields
}
ImplementDistinctUnionRule implements Distinct(Union(legs...)) as a merge-sorted union plan. It matches LogicalDistinctExpression over LogicalUnionExpression, finds compatible orderings across all union legs, and creates a RecordQueryMergeSortUnionPlan with deduplication.
Ports Java's ImplementDistinctUnionRule. The full algorithm:
- Get requested orderings from planner constraints
- For each cross-product combo of per-leg plan partitions: a. Verify common primary key across all legs b. Extract ordering from each leg's partition c. Incrementally merge orderings (bail on incompatibility) d. Verify PK values are covered by merged ordering e. Enumerate comparison keys satisfying the requested ordering f. Create MergeSortUnionPlan with comparison keys
func NewImplementDistinctUnionRule ¶
func NewImplementDistinctUnionRule() *ImplementDistinctUnionRule
func (*ImplementDistinctUnionRule) Matcher ¶
func (r *ImplementDistinctUnionRule) Matcher() matching.BindingMatcher
func (*ImplementDistinctUnionRule) OnMatch ¶
func (r *ImplementDistinctUnionRule) OnMatch(call *ImplementationRuleCall)
type ImplementExplodeRule ¶
type ImplementExplodeRule struct {
// contains filtered or unexported fields
}
ImplementExplodeRule converts an ExplodeExpression into a physical RecordQueryExplodePlan. Direct translation — the collection Value passes through unchanged.
Mirrors Java's ImplementExplodeRule.
func NewImplementExplodeRule ¶
func NewImplementExplodeRule() *ImplementExplodeRule
func (*ImplementExplodeRule) Matcher ¶
func (r *ImplementExplodeRule) Matcher() matching.BindingMatcher
func (*ImplementExplodeRule) OnMatch ¶
func (r *ImplementExplodeRule) OnMatch(call *ExpressionRuleCall)
type ImplementFilterRule ¶
type ImplementFilterRule struct {
// contains filtered or unexported fields
}
ImplementFilterRule implements a logical LogicalFilterExpression as a physical RecordQueryPredicatesFilterPlan, provided the inner Quantifier's Reference contains at least one physical-plan member.
Filter([P], inner-with-physical-member) → PredicatesFilterPlan([P], inner-physical, innerAlias)
Matches Java's ImplementFilterRule which creates RecordQueryPredicatesFilterPlan with a physical quantifier morphed from the logical inner quantifier, preserving the alias. The alias is critical for correlated predicates: the executor binds the current row under innerAlias so QOV-based predicates can resolve.
The "with-physical-member" guard ensures the rule fires only AFTER the inner has been implemented (i.e. PrimaryScanRule or another implement rule has yielded a physical wrapper into the inner's Reference). This avoids producing partial physical plans that reference still-logical inner trees.
func NewImplementFilterRule ¶
func NewImplementFilterRule() *ImplementFilterRule
NewImplementFilterRule constructs the rule.
func (*ImplementFilterRule) Matcher ¶
func (r *ImplementFilterRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementFilterRule) OnMatch ¶
func (r *ImplementFilterRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires on every LogicalFilterExpression. Walks the inner Reference for any physical-plan member; if found, yields a FilterPlan wrapper over a fresh Reference holding that physical inner.
type ImplementInJoinRule ¶
type ImplementInJoinRule struct {
// contains filtered or unexported fields
}
ImplementInJoinRule implements a SELECT over ExplodeExpressions (UNNEST of IN-lists) and a correlated inner plan as a right-deep chain of RecordQueryInJoinPlans.
Ports Java's ImplementInJoinRule. The rule examines the inner plan's RichOrdering to match explode aliases to equality-bound ordering keys. For each FixedBinding in the ordering, the comparison's GetCorrelatedTo() identifies the explode alias. Matched explodes become sorted IN-sources placed outermost in the InJoin chain, exploiting the inner plan's index ordering. Unmatched explodes use default (unsorted) quantifier order.
func NewImplementInJoinRule ¶
func NewImplementInJoinRule() *ImplementInJoinRule
func (*ImplementInJoinRule) Matcher ¶
func (r *ImplementInJoinRule) Matcher() matching.BindingMatcher
func (*ImplementInJoinRule) OnMatch ¶
func (r *ImplementInJoinRule) OnMatch(call *ImplementationRuleCall)
type ImplementInMemorySortRule ¶
type ImplementInMemorySortRule struct {
// contains filtered or unexported fields
}
ImplementInMemorySortRule yields a RecordQueryInMemorySortPlan for any LogicalSortExpression whose inner Reference has a physical plan. Unlike ImplementSortRule (Java-ported), this does NOT check whether the inner ordering already satisfies the sort — it unconditionally wraps. The cost model ensures this plan loses to index-based elimination when both are available.
func NewImplementInMemorySortRule ¶
func NewImplementInMemorySortRule() *ImplementInMemorySortRule
func (*ImplementInMemorySortRule) GetRequestedOrderings ¶
func (r *ImplementInMemorySortRule) GetRequestedOrderings( _ expressions.RelationalExpression, ) []*RequestedOrdering
func (*ImplementInMemorySortRule) Matcher ¶
func (r *ImplementInMemorySortRule) Matcher() matching.BindingMatcher
func (*ImplementInMemorySortRule) OnMatch ¶
func (r *ImplementInMemorySortRule) OnMatch(call *ImplementationRuleCall)
type ImplementInUnionRule ¶
type ImplementInUnionRule struct {
// contains filtered or unexported fields
}
ImplementInUnionRule implements a SELECT over ExplodeExpressions as a RecordQueryInUnionPlan — the inner plan is executed once per IN value and results are merge-sorted by comparison keys.
Ports Java's ImplementInUnionRule. The rule adjusts the inner plan's ordering bindings: fixed bindings referencing explode aliases are promoted to directional (sorted) bindings, enabling merge-sorted output. Comparison keys are derived from the adjusted ordering.
func NewImplementInUnionRule ¶
func NewImplementInUnionRule() *ImplementInUnionRule
func (*ImplementInUnionRule) Matcher ¶
func (r *ImplementInUnionRule) Matcher() matching.BindingMatcher
func (*ImplementInUnionRule) OnMatch ¶
func (r *ImplementInUnionRule) OnMatch(call *ImplementationRuleCall)
type ImplementInsertRule ¶
type ImplementInsertRule struct {
// contains filtered or unexported fields
}
ImplementInsertRule implements a logical InsertExpression as a physical RecordQueryInsertPlan, gated on the inner Reference having at least one physical-plan member.
Insert(target, type, inner-with-physical-member) → InsertPlan(target, type, inner-physical)
Same gating pattern as Implement{Filter,Sort,Distinct,TypeFilter}.
Java's ImplementInsertRule consults PlanPartition properties for dispatch; Go always emits the simple INSERT plan. Per-row transforms (UPSERT, ON CONFLICT, etc.) are not implemented.
func NewImplementInsertRule ¶
func NewImplementInsertRule() *ImplementInsertRule
NewImplementInsertRule constructs the rule.
func (*ImplementInsertRule) Matcher ¶
func (r *ImplementInsertRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementInsertRule) OnMatch ¶
func (r *ImplementInsertRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires on every InsertExpression with a physical inner.
type ImplementIntersectionRule ¶
type ImplementIntersectionRule struct {
// contains filtered or unexported fields
}
ImplementIntersectionRule implements a logical LogicalIntersectionExpression as a physical RecordQueryIntersectionPlan, gated on EVERY child Reference having at least one physical-plan member.
Intersection(child0-with-physical, child1-with-physical, ...) → IntersectionPlan(child0-physical, child1-physical, ...)
Per-child gating: same as ImplementUnionRule — partial physical- implementation produces an invalid mixed-hierarchy plan tree.
The comparisonKeyValues from the logical Intersection carry through unchanged into the physical plan — the row-equality key is independent of which physical operator emits the rows.
Java has multiple Intersection variants (ordered, unordered, primary-key-based, value-based); this rule always emits the generic RecordQueryIntersectionPlan (the primary-key-keyed cross-candidate intersection is built separately by the data-access path — WithPrimaryKeyIntersector, planner.go).
func NewImplementIntersectionRule ¶
func NewImplementIntersectionRule() *ImplementIntersectionRule
NewImplementIntersectionRule constructs the rule.
func (*ImplementIntersectionRule) Matcher ¶
func (r *ImplementIntersectionRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementIntersectionRule) OnMatch ¶
func (r *ImplementIntersectionRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when EVERY child Quantifier ranges over a Reference with at least one physical-plan member.
type ImplementLimitRule ¶
type ImplementLimitRule struct {
// contains filtered or unexported fields
}
ImplementLimitRule converts a LogicalLimitExpression into a physical RecordQueryLimitPlan. LIMIT/OFFSET is a pure pass-through that caps the row count — it applies to whatever physical plan the inner produces.
Go-only extension: Java doesn't support LIMIT in SQL; it uses ExecuteProperties.setReturnedRowLimit() at the JDBC layer.
func NewImplementLimitRule ¶
func NewImplementLimitRule() *ImplementLimitRule
func (*ImplementLimitRule) Matcher ¶
func (r *ImplementLimitRule) Matcher() matching.BindingMatcher
func (*ImplementLimitRule) OnMatch ¶
func (r *ImplementLimitRule) OnMatch(call *ExpressionRuleCall)
type ImplementNestedLoopJoinRule ¶
type ImplementNestedLoopJoinRule struct {
// contains filtered or unexported fields
}
ImplementNestedLoopJoinRule implements a SelectExpression with exactly 2 quantifiers (a binary join) as a physical nested-loop join plan. The left (first) quantifier becomes the outer and the right (second) becomes the inner.
Select(predicates, [Q_left, Q_right]) → NestedLoopJoin(outer=physical(Q_left), inner=physical(Q_right), predicates)
This is the simplest and most general join implementation — it works for all join shapes without requiring sorted input or hash tables. Cost model: O(N_outer × N_inner) with predicate filtering.
Mirrors Java's `ImplementNestedLoopJoinRule`.
func NewImplementNestedLoopJoinRule ¶
func NewImplementNestedLoopJoinRule() *ImplementNestedLoopJoinRule
func (*ImplementNestedLoopJoinRule) Matcher ¶
func (r *ImplementNestedLoopJoinRule) Matcher() matching.BindingMatcher
func (*ImplementNestedLoopJoinRule) OnMatch ¶
func (r *ImplementNestedLoopJoinRule) OnMatch(call *ExpressionRuleCall)
type ImplementProjectionFinalRule ¶
type ImplementProjectionFinalRule struct {
// contains filtered or unexported fields
}
ImplementProjectionFinalRule is the PLANNING-phase counterpart of ImplementProjectionRule. It fires after the inner has been finalized (children are physical plans), producing a physical projection wrapper.
func NewImplementProjectionFinalRule ¶
func NewImplementProjectionFinalRule() *ImplementProjectionFinalRule
func (*ImplementProjectionFinalRule) Matcher ¶
func (r *ImplementProjectionFinalRule) Matcher() matching.BindingMatcher
func (*ImplementProjectionFinalRule) OnMatch ¶
func (r *ImplementProjectionFinalRule) OnMatch(call *ImplementationRuleCall)
type ImplementProjectionRule ¶
type ImplementProjectionRule struct {
// contains filtered or unexported fields
}
ImplementProjectionRule implements a logical LogicalProjectionExpression as a physical RecordQueryProjectionPlan, gated on the inner Reference having at least one physical-plan member.
func NewImplementProjectionRule ¶
func NewImplementProjectionRule() *ImplementProjectionRule
func (*ImplementProjectionRule) Matcher ¶
func (r *ImplementProjectionRule) Matcher() matching.BindingMatcher
func (*ImplementProjectionRule) OnMatch ¶
func (r *ImplementProjectionRule) OnMatch(call *ExpressionRuleCall)
type ImplementRecursiveDfsJoinRule ¶
type ImplementRecursiveDfsJoinRule struct {
// contains filtered or unexported fields
}
ImplementRecursiveDfsJoinRule converts a RecursiveUnionExpression (where DFS traversal is allowed) into a physical RecordQueryRecursiveDfsJoinPlan.
Pattern:
RecursiveUnion(initial_state, recursive_state) where dfsAllowed() → RecursiveDfsJoin(physical(initial), physical(recursive), priorCorrelation, strategy)
The initial-state leg must already have a physical plan (yielded by prior TempTableInsert → inner plan implement rules). The recursive leg similarly must have a physical plan available.
Mirrors Java's ImplementRecursiveDfsJoinRule.
func NewImplementRecursiveDfsJoinRule ¶
func NewImplementRecursiveDfsJoinRule() *ImplementRecursiveDfsJoinRule
func (*ImplementRecursiveDfsJoinRule) Matcher ¶
func (r *ImplementRecursiveDfsJoinRule) Matcher() matching.BindingMatcher
func (*ImplementRecursiveDfsJoinRule) OnMatch ¶
func (r *ImplementRecursiveDfsJoinRule) OnMatch(call *ExpressionRuleCall)
type ImplementRecursiveLevelUnionRule ¶
type ImplementRecursiveLevelUnionRule struct {
// contains filtered or unexported fields
}
ImplementRecursiveLevelUnionRule converts a RecursiveUnionExpression (where level-order traversal is allowed) into a physical RecordQueryRecursiveLevelUnionPlan.
Pattern:
RecursiveUnion(initial_state, recursive_state) where levelAllowed() → RecursiveLevelUnion(physical(initial), physical(recursive), scanAlias, insertAlias)
Both legs must already have physical plans available (yielded by prior TempTableInsert → inner plan implement rules).
Mirrors Java's ImplementRecursiveLevelUnionRule.
func NewImplementRecursiveLevelUnionRule ¶
func NewImplementRecursiveLevelUnionRule() *ImplementRecursiveLevelUnionRule
func (*ImplementRecursiveLevelUnionRule) Matcher ¶
func (r *ImplementRecursiveLevelUnionRule) Matcher() matching.BindingMatcher
func (*ImplementRecursiveLevelUnionRule) OnMatch ¶
func (r *ImplementRecursiveLevelUnionRule) OnMatch(call *ExpressionRuleCall)
type ImplementSimpleSelectRule ¶
type ImplementSimpleSelectRule struct {
// contains filtered or unexported fields
}
ImplementSimpleSelectRule implements a SelectExpression with a single quantifier (no joins) as a combination of physical plans:
- RecordQueryPredicatesFilterPlan for WHERE predicates
- RecordQueryMapPlan for non-trivial result values (projections)
Ports Java's ImplementSimpleSelectRule. Only fires on single-quantifier SELECTs; multi-quantifier SELECTs (joins) are handled by other rules.
func NewImplementSimpleSelectRule ¶
func NewImplementSimpleSelectRule() *ImplementSimpleSelectRule
func (*ImplementSimpleSelectRule) Matcher ¶
func (r *ImplementSimpleSelectRule) Matcher() matching.BindingMatcher
func (*ImplementSimpleSelectRule) OnMatch ¶
func (r *ImplementSimpleSelectRule) OnMatch(call *ImplementationRuleCall)
type ImplementSortRule ¶
type ImplementSortRule struct {
// contains filtered or unexported fields
}
ImplementSortRule removes a logical LogicalSortExpression when the inner plan already satisfies the requested ordering. This is Java's RemoveSortRule pattern: sort is a constraint, not a physical operator.
During PLANNING's top-down pass, the sort expression's requested ordering is pushed as a constraint to the inner reference (via GetRequestedOrderings). During the bottom-up pass, this rule checks if the inner partition's ordering satisfies the request, and if so, yields the inner plans directly (removing the sort).
Ports Java's RemoveSortRule (ImplementationCascadesRule).
func NewImplementSortRule ¶
func NewImplementSortRule() *ImplementSortRule
func (*ImplementSortRule) GetRequestedOrderings ¶
func (r *ImplementSortRule) GetRequestedOrderings( expr expressions.RelationalExpression, ) []*RequestedOrdering
func (*ImplementSortRule) Matcher ¶
func (r *ImplementSortRule) Matcher() matching.BindingMatcher
func (*ImplementSortRule) OnMatch ¶
func (r *ImplementSortRule) OnMatch(call *ImplementationRuleCall)
type ImplementStreamingAggregationRule ¶
type ImplementStreamingAggregationRule struct {
// contains filtered or unexported fields
}
ImplementStreamingAggregationRule implements a GroupByExpression as a physical RecordQueryStreamingAggregationPlan when the inner Reference has at least one member whose ordering satisfies the grouping keys.
GroupBy(keys=[k1, k2], aggs=[...], inner) → StreamingAggPlan(inner-physical) [when inner ordered by k1, k2, ...]
The streaming aggregation is the cheapest aggregation strategy when the input is already sorted — it processes rows in one pass with O(1) memory per group. When the inner is NOT ordered, this rule does not fire; a future hash-aggregation rule would handle that case.
Java equivalent: ImplementStreamingAggregationRule in the OPTIMIZE phase, which requires OrderingProperty satisfaction.
func NewImplementStreamingAggregationRule ¶
func NewImplementStreamingAggregationRule() *ImplementStreamingAggregationRule
func (*ImplementStreamingAggregationRule) Matcher ¶
func (r *ImplementStreamingAggregationRule) Matcher() matching.BindingMatcher
func (*ImplementStreamingAggregationRule) OnMatch ¶
func (r *ImplementStreamingAggregationRule) OnMatch(call *ExpressionRuleCall)
type ImplementTableFunctionRule ¶
type ImplementTableFunctionRule struct {
// contains filtered or unexported fields
}
ImplementTableFunctionRule converts a TableFunctionExpression into a physical RecordQueryTableFunctionPlan. Direct translation — the streaming Value passes through unchanged.
Mirrors Java's ImplementTableFunctionRule.
func NewImplementTableFunctionRule ¶
func NewImplementTableFunctionRule() *ImplementTableFunctionRule
func (*ImplementTableFunctionRule) Matcher ¶
func (r *ImplementTableFunctionRule) Matcher() matching.BindingMatcher
func (*ImplementTableFunctionRule) OnMatch ¶
func (r *ImplementTableFunctionRule) OnMatch(call *ExpressionRuleCall)
type ImplementTempTableInsertRule ¶
type ImplementTempTableInsertRule struct {
// contains filtered or unexported fields
}
ImplementTempTableInsertRule converts a TempTableInsertExpression to a physical TempTableInsertPlan. Requires the inner reference to already contain a physical plan. Mirrors Java's ImplementTempTableInsertRule.
func NewImplementTempTableInsertRule ¶
func NewImplementTempTableInsertRule() *ImplementTempTableInsertRule
func (*ImplementTempTableInsertRule) Matcher ¶
func (r *ImplementTempTableInsertRule) Matcher() matching.BindingMatcher
func (*ImplementTempTableInsertRule) OnMatch ¶
func (r *ImplementTempTableInsertRule) OnMatch(call *ExpressionRuleCall)
type ImplementTempTableScanRule ¶
type ImplementTempTableScanRule struct {
// contains filtered or unexported fields
}
ImplementTempTableScanRule converts a TempTableScanExpression to a physical TempTableScanPlan. Mirrors Java's ImplementTempTableScanRule.
func NewImplementTempTableScanRule ¶
func NewImplementTempTableScanRule() *ImplementTempTableScanRule
func (*ImplementTempTableScanRule) Matcher ¶
func (r *ImplementTempTableScanRule) Matcher() matching.BindingMatcher
func (*ImplementTempTableScanRule) OnMatch ¶
func (r *ImplementTempTableScanRule) OnMatch(call *ExpressionRuleCall)
type ImplementTypeFilterRule ¶
type ImplementTypeFilterRule struct {
// contains filtered or unexported fields
}
ImplementTypeFilterRule implements a logical LogicalTypeFilterExpression as a physical RecordQueryTypeFilterPlan, gated on the inner Reference having at least one physical-plan member.
TypeFilter([T1, T2], inner-with-physical-member) → TypeFilterPlan([T1, T2], inner-physical)
Same gating pattern as Implement{Filter,Sort,Distinct}.
Java's ImplementTypeFilterRule consults PlanPartition properties to filter only over partitions producing stored records (not covering-index partitions); Go always emits the simple type-filter.
func NewImplementTypeFilterRule ¶
func NewImplementTypeFilterRule() *ImplementTypeFilterRule
NewImplementTypeFilterRule constructs the rule.
func (*ImplementTypeFilterRule) Matcher ¶
func (r *ImplementTypeFilterRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementTypeFilterRule) OnMatch ¶
func (r *ImplementTypeFilterRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires on every LogicalTypeFilterExpression with a physical inner.
type ImplementUnionRule ¶
type ImplementUnionRule struct {
// contains filtered or unexported fields
}
ImplementUnionRule implements a logical LogicalUnionExpression as a physical RecordQueryUnionPlan, gated on EVERY child Reference having at least one physical-plan member.
Union(child0-with-physical, child1-with-physical, ...) → UnionPlan(child0-physical, child1-physical, ...)
Per-child gating: unlike single-inner Implement rules, Union requires ALL children to be physical-implemented before yielding — partial physical-implementation produces an invalid mixed- hierarchy plan tree.
Java has multiple Union variants (key-expression vs values, dedup vs no-dedup); this rule always emits RecordQueryUnionPlan (UNION ALL, no dedup) — the dedup / ordered variants come from their own rules (ImplementDistinctUnionRule, ImplementUnorderedUnionRule, ImplementInUnionRule).
func NewImplementUnionRule ¶
func NewImplementUnionRule() *ImplementUnionRule
NewImplementUnionRule constructs the rule.
func (*ImplementUnionRule) Matcher ¶
func (r *ImplementUnionRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementUnionRule) OnMatch ¶
func (r *ImplementUnionRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when EVERY child Quantifier ranges over a Reference with at least one physical-plan member.
type ImplementUniqueRule ¶
type ImplementUniqueRule struct {
// contains filtered or unexported fields
}
ImplementUniqueRule implements LogicalUniqueExpression by absorbing it when the inner Reference's plans are already distinct (with a primary key). If the inner plans produce distinct records, the Unique operator is a no-op and we yield the inner plans directly.
Ports Java's ImplementUniqueRule.
func NewImplementUniqueRule ¶
func NewImplementUniqueRule() *ImplementUniqueRule
func (*ImplementUniqueRule) Matcher ¶
func (r *ImplementUniqueRule) Matcher() matching.BindingMatcher
func (*ImplementUniqueRule) OnMatch ¶
func (r *ImplementUniqueRule) OnMatch(call *ImplementationRuleCall)
type ImplementUnorderedUnionRule ¶
type ImplementUnorderedUnionRule struct {
// contains filtered or unexported fields
}
ImplementUnorderedUnionRule implements LogicalUnionExpression as a RecordQueryUnorderedUnionPlan. It extracts physical plans from each child Reference's plan partitions and creates a concatenating union plan over them.
Ports Java's ImplementUnorderedUnionRule.
func NewImplementUnorderedUnionRule ¶
func NewImplementUnorderedUnionRule() *ImplementUnorderedUnionRule
func (*ImplementUnorderedUnionRule) Matcher ¶
func (r *ImplementUnorderedUnionRule) Matcher() matching.BindingMatcher
func (*ImplementUnorderedUnionRule) OnMatch ¶
func (r *ImplementUnorderedUnionRule) OnMatch(call *ImplementationRuleCall)
type ImplementUpdateRule ¶
type ImplementUpdateRule struct {
// contains filtered or unexported fields
}
ImplementUpdateRule implements a logical UpdateExpression as a physical RecordQueryUpdatePlan, gated on the inner Reference having at least one physical-plan member.
Update(target, [transforms], inner-with-physical-member) → UpdatePlan(target, [transforms], inner-physical)
Per-row transform application happens at execution time (not rule-fire time) — transforms pass through unchanged. The rule structure is identical to ImplementInsert/Delete; the transforms-evaluation gating is in the executor, not the rule.
Java's ImplementUpdateRule consults StoredRecordProperty for dispatch; Go always emits.
func NewImplementUpdateRule ¶
func NewImplementUpdateRule() *ImplementUpdateRule
NewImplementUpdateRule constructs the rule.
func (*ImplementUpdateRule) Matcher ¶
func (r *ImplementUpdateRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ImplementUpdateRule) OnMatch ¶
func (r *ImplementUpdateRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires on every UpdateExpression with a physical inner.
type ImplementValuesRule ¶
type ImplementValuesRule struct {
// contains filtered or unexported fields
}
ImplementValuesRule implements a logical LogicalValuesExpression as a physical RecordQueryValuesPlan. Trivial leaf rule — no inner to gate on.
func NewImplementValuesRule ¶
func NewImplementValuesRule() *ImplementValuesRule
func (*ImplementValuesRule) Matcher ¶
func (r *ImplementValuesRule) Matcher() matching.BindingMatcher
func (*ImplementValuesRule) OnMatch ¶
func (r *ImplementValuesRule) OnMatch(call *ExpressionRuleCall)
type ImplementationRule ¶
type ImplementationRule interface {
Matcher() matching.BindingMatcher
OnMatch(call *ImplementationRuleCall)
}
ImplementationRule is a rule that runs during PhasePlanning. Like ExpressionRule, it yields expressions into Members via ref.Insert(). It operates on expression partitions and creates physical plan alternatives.
Ports Java's ImplementationCascadesRule.
func AsImplementationRule ¶
func AsImplementationRule(rule ExpressionRule) ImplementationRule
AsImplementationRule adapts an ExpressionRule to run as an ImplementationRule during the PLANNING phase. The wrapped rule's Yield() inserts into Members (via the ImplementationRuleCall) alongside exploration rules. MemoizeExpression uses the planner's Memo when available.
This lets the physical-implementation ExpressionRules (BatchAExpressionRules) run inside the PLANNING phase's ImplementationRule driver without rewriting each rule.
func DefaultImplementationRules ¶
func DefaultImplementationRules() []ImplementationRule
DefaultImplementationRules returns the ImplementationRules for the PLANNING phase.
func GoExtensionImplementationRules ¶
func GoExtensionImplementationRules() []ImplementationRule
GoExtensionImplementationRules returns implementation rules that have no Java equivalent. These extend the Cascades planner with in-memory post-processing operators (RFC-001). Registered separately so the boundary between Java-ported and Go-extension rules is explicit.
type ImplementationRuleCall ¶
type ImplementationRuleCall struct {
Bindings *matching.PlannerBindings
Reference *expressions.Reference
Context PlanContext
Constraints *ConstraintMap
// contains filtered or unexported fields
}
ImplementationRuleCall provides the restricted API that ImplementationRules are allowed to use. It extends the base RuleCall with Memoizer and Yield operations.
Ports Java's ImplementationCascadesRuleCall.
func (*ImplementationRuleCall) GetRequestedOrderings ¶
func (c *ImplementationRuleCall) GetRequestedOrderings() []*RequestedOrdering
GetRequestedOrderings returns the requested orderings for this Reference, if set by a parent rule. Returns nil if no ordering constraint is set.
func (*ImplementationRuleCall) IsConstraintOnly ¶
func (c *ImplementationRuleCall) IsConstraintOnly() bool
IsConstraintOnly returns true when the rule is firing during the top-down constraint-propagation pass (PLANNING Phase 1). Rules that only push constraints should check this and skip implementation work.
func (*ImplementationRuleCall) MemoizeFinalExpression ¶
func (c *ImplementationRuleCall) MemoizeFinalExpression( expr expressions.RelationalExpression, ) *expressions.Reference
MemoizeFinalExpression creates a new Reference with a single expression member.
func (*ImplementationRuleCall) MemoizeFinalExpressionsFromOther ¶
func (c *ImplementationRuleCall) MemoizeFinalExpressionsFromOther( source *expressions.Reference, exprs []expressions.RelationalExpression, ) *expressions.Reference
MemoizeFinalExpressionsFromOther creates a new Reference containing only the specified expressions (which must already be members of `source`). The new Reference holds them as final members — disentangled from the shared DAG.
Ports Java's FinalMemoizer.memoizeFinalExpressionsFromOther.
func (*ImplementationRuleCall) PushConstraint ¶
func (c *ImplementationRuleCall) PushConstraint( childRef *expressions.Reference, orderings []*RequestedOrdering, )
PushConstraint pushes a constraint value to a child Reference.
func (*ImplementationRuleCall) Yield ¶
func (c *ImplementationRuleCall) Yield(expr expressions.RelationalExpression)
Yield records a final expression to be inserted into the Reference's final members after the rule completes.
func (*ImplementationRuleCall) YieldFinalExpression ¶
func (c *ImplementationRuleCall) YieldFinalExpression(expr expressions.RelationalExpression)
YieldFinalExpression is an alias for Yield — matches Java's FinalYields.yieldFinalExpression naming.
type InComparisonToExplodeRule ¶
type InComparisonToExplodeRule struct {
// contains filtered or unexported fields
}
InComparisonToExplodeRule rewrites a LogicalFilterExpression whose predicate list contains a ComparisonPredicate with ComparisonIn.
Single-element IN → simple equality (no union):
Filter([col IN (v1), ...other...], inner) → Filter([col = v1, ...other...], inner)
Multi-element IN → SelectExpression with ExplodeExpression:
Filter([col IN (v1, v2, v3), ...other...], inner)
→ SelectExpression(
resultValue = QOV(innerAlias),
quantifiers = [
ForEach(Filter([col = QOV(explodeAlias), ...other...], inner)),
ForEach(Explode([v1, v2, v3])),
],
predicates = [],
)
Mirrors Java's InComparisonToExplodeRule. The ImplementInJoinRule (PLANNING phase) handles this SelectExpression shape and produces InJoinPlan or InUnionPlan. The inner LogicalFilterExpression's equality predicate (col = QOV(explodeAlias)) is matched by the index-matching infrastructure, which creates an index scan with the column equality-bound to the explode alias. ImplementInJoinRule detects this correlation via the inner plan's RichOrdering.
Guards:
- At least one ComparisonIn predicate.
- The IN-list Operand must evaluate (without row context) to a non-empty []any.
- The filter must have an inner Quantifier (no bare filter).
func NewInComparisonToExplodeRule ¶
func NewInComparisonToExplodeRule() *InComparisonToExplodeRule
func (*InComparisonToExplodeRule) Matcher ¶
func (r *InComparisonToExplodeRule) Matcher() matching.BindingMatcher
func (*InComparisonToExplodeRule) OnMatch ¶
func (r *InComparisonToExplodeRule) OnMatch(call *ExpressionRuleCall)
type InParameterSource ¶
type InParameterSource struct {
// contains filtered or unexported fields
}
InParameterSource provides values from a named parameter or correlation.
func NewInParameterSource ¶
func NewInParameterSource(bindingName, parameterName string) *InParameterSource
func (*InParameterSource) GetBindingName ¶
func (s *InParameterSource) GetBindingName() string
func (*InParameterSource) GetParameterName ¶
func (s *InParameterSource) GetParameterName() string
func (*InParameterSource) IsReverse ¶
func (s *InParameterSource) IsReverse() bool
func (*InParameterSource) IsSorted ¶
func (s *InParameterSource) IsSorted() bool
type InSource ¶
InSource is the abstraction for a source of values used in IN-join and IN-union plans. Each source provides a binding name and can produce a list of values at execution time.
Ports Java's InSource hierarchy: InValuesSource, InParameterSource, InComparandSource, and their sorted variants.
type InValuesSource ¶
type InValuesSource struct {
// contains filtered or unexported fields
}
InValuesSource provides an explicit list of values.
func NewInValuesSource ¶
func NewInValuesSource(bindingName string, vals []any) *InValuesSource
func (*InValuesSource) GetBindingName ¶
func (s *InValuesSource) GetBindingName() string
func (*InValuesSource) GetValues ¶
func (s *InValuesSource) GetValues() []any
func (*InValuesSource) IsReverse ¶
func (s *InValuesSource) IsReverse() bool
func (*InValuesSource) IsSorted ¶
func (s *InValuesSource) IsSorted() bool
type IndexDef ¶
type IndexDef interface {
IndexName() string
IndexColumnNames() []string
IndexRecordTypes() []string
IndexIsUnique() bool
IndexPrimaryKeyColumns() []string
}
IndexDef describes a secondary index for PlanContext construction. This is an adapter interface so the cascades package doesn't depend on the recordlayer package directly (avoiding import cycles).
type IndexDefWithColumnFunctions ¶
IndexDefWithColumnFunctions is an optional extension of IndexDef for indexes whose key columns are not all bare fields. IndexColumnFunctions returns a slice parallel to IndexColumnNames: entry i is the function wrapping the i-th column ("" for a plain field, FunctionKindCardinality for a CARDINALITY() column). A nil/empty return means every column is a plain field. Defs that don't implement this interface are treated as all-plain-field.
type InitiatePlannerPhaseTask ¶
type InitiatePlannerPhaseTask struct {
Phase PlannerPhase
RootRef *expressions.Reference
}
InitiatePlannerPhaseTask starts a planner phase. Pushed once per phase. LIFO ordering ensures: ExploreGroup fires first, then OptimizeGroup, then the next phase's InitiatePlannerPhaseTask. Mirrors Java's CascadesPlanner.InitiatePlannerPhase.
func (*InitiatePlannerPhaseTask) Run ¶
func (t *InitiatePlannerPhaseTask) Run(p *Planner)
type IntersectionInfo ¶
type IntersectionInfo struct {
// contains filtered or unexported fields
}
IntersectionInfo tracks the state of a single data access within the intersection sieve. It carries the access's ordering, compensation, participating expressions, and an estimated max cardinality.
Ports Java's AbstractDataAccessRule.IntersectionInfo.
func IntersectionInfoOfImpossibleAccess ¶
func IntersectionInfoOfImpossibleAccess( ordering *RichOrdering, comp Compensation, ) *IntersectionInfo
IntersectionInfoOfImpossibleAccess creates an IntersectionInfo for an impossible access (no expressions, unknown cardinality). Mirrors Java's IntersectionInfo.ofImpossibleAccess().
func IntersectionInfoOfIntersection ¶
func IntersectionInfoOfIntersection( ordering *RichOrdering, comp Compensation, exprs []expressions.RelationalExpression, ) *IntersectionInfo
IntersectionInfoOfIntersection creates an IntersectionInfo for a computed intersection (multiple expressions, unknown cardinality). Mirrors Java's IntersectionInfo.ofIntersection().
func IntersectionInfoOfSingleAccess ¶
func IntersectionInfoOfSingleAccess( ordering *RichOrdering, comp Compensation, expr expressions.RelationalExpression, maxCard int64, ) *IntersectionInfo
IntersectionInfoOfSingleAccess creates an IntersectionInfo for a single data access (one expression). Mirrors Java's IntersectionInfo.ofSingleAccess().
func NewIntersectionInfo ¶
func NewIntersectionInfo( ordering *RichOrdering, comp Compensation, exprs []expressions.RelationalExpression, maxCard int64, ) *IntersectionInfo
NewIntersectionInfo creates an IntersectionInfo with all fields.
func (*IntersectionInfo) EvictExpressions ¶
func (i *IntersectionInfo) EvictExpressions()
EvictExpressions clears the expressions list. Mirrors Java's IntersectionInfo.evictExpressions().
func (*IntersectionInfo) GetCompensation ¶
func (i *IntersectionInfo) GetCompensation() Compensation
GetCompensation returns the compensation for this access.
func (*IntersectionInfo) GetExpressions ¶
func (i *IntersectionInfo) GetExpressions() []expressions.RelationalExpression
GetExpressions returns the participating expressions.
func (*IntersectionInfo) GetMaxCardinality ¶
func (i *IntersectionInfo) GetMaxCardinality() int64
GetMaxCardinality returns the estimated max cardinality. Returns CardinalityUnknown (-1) if unknown.
func (*IntersectionInfo) GetOrdering ¶
func (i *IntersectionInfo) GetOrdering() *RichOrdering
GetOrdering returns the ordering for this access.
type IntersectionMergeRule ¶
type IntersectionMergeRule struct {
// contains filtered or unexported fields
}
IntersectionMergeRule flattens nested LogicalIntersection expressions, mirroring UnionMergeRule for the intersection operator. The inner intersection's children are promoted into the outer's child list.
Intersection(A, Intersection(B, C), D) [keys=K] → Intersection(A, B, C, D) [keys=K]
SQL-equivalent: bag-intersection is associative.
Constraint: the inner Intersection's comparisonKeyValues MUST match the outer's. Different keys means the inner's intersection is computed under a different equality contract; flattening would silently change semantics. Different-keys case declines.
'Match' here is by Explain-text equality of the corresponding keys — the same conservative textual bridge as LogicalProjectionExpression.EqualsWithoutChildren (different-keys cases decline, so semantics are never merged; values.SemanticEquals exists, but switching dedup/match semantics to it needs its own review cycle).
func NewIntersectionMergeRule ¶
func NewIntersectionMergeRule() *IntersectionMergeRule
NewIntersectionMergeRule constructs the rule.
func (*IntersectionMergeRule) Matcher ¶
func (r *IntersectionMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*IntersectionMergeRule) OnMatch ¶
func (r *IntersectionMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when at least one child Quantifier ranges over another Intersection AND every such inner Intersection has matching comparisonKeyValues.
type IntersectionResult ¶
type IntersectionResult struct {
// contains filtered or unexported fields
}
IntersectionResult captures the result of attempting to intersect multiple data accesses. When viable, it carries a common ordering, a compensation, and the participating expressions.
Ports Java's AbstractDataAccessRule.IntersectionResult.
func NewIntersectionResult ¶
func NewIntersectionResult( ordering *RichOrdering, comp Compensation, exprs []expressions.RelationalExpression, ) *IntersectionResult
NewIntersectionResult creates an IntersectionResult. When commonOrdering is nil the expressions slice must be empty (mirrors Java's Verify.verify precondition).
func NoViableIntersection ¶
func NoViableIntersection() *IntersectionResult
NoViableIntersection returns an IntersectionResult that indicates no viable intersection was found. Mirrors Java's IntersectionResult.noViableIntersection().
func (*IntersectionResult) GetCommonOrdering ¶
func (r *IntersectionResult) GetCommonOrdering() *RichOrdering
GetCommonOrdering returns the common intersection ordering. Panics if the intersection is not viable.
func (*IntersectionResult) GetCompensation ¶
func (r *IntersectionResult) GetCompensation() Compensation
GetCompensation returns the compensation for this intersection.
func (*IntersectionResult) GetExpressions ¶
func (r *IntersectionResult) GetExpressions() []expressions.RelationalExpression
GetExpressions returns the participating expressions.
func (*IntersectionResult) IsViable ¶
func (r *IntersectionResult) IsViable() bool
IsViable reports whether this result represents a viable intersection (i.e. a common ordering was found). Mirrors Java's IntersectionResult.hasViableIntersection().
func (*IntersectionResult) String ¶
func (r *IntersectionResult) String() string
String returns a human-readable representation. Mirrors Java's IntersectionResult.toString().
type IntersectionSingletonElimRule ¶
type IntersectionSingletonElimRule struct {
// contains filtered or unexported fields
}
IntersectionSingletonElimRule eliminates a LogicalIntersection with exactly one child — INTERSECTION of a single input is just that input.
Intersection([Q]) → inner of Q
func NewIntersectionSingletonElimRule ¶
func NewIntersectionSingletonElimRule() *IntersectionSingletonElimRule
NewIntersectionSingletonElimRule constructs the rule.
func (*IntersectionSingletonElimRule) Matcher ¶
func (r *IntersectionSingletonElimRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*IntersectionSingletonElimRule) OnMatch ¶
func (r *IntersectionSingletonElimRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the intersection has exactly one child.
type IntersectorFunc ¶
type IntersectorFunc func( accesses []Vectored[*SingleMatchedAccess], requestedOrderings []*RequestedOrdering, ) *IntersectionResult
IntersectorFunc is the function type for computing intersections of multiple data accesses. Concrete rules provide their own intersection logic through this callback, replacing Java's abstract method createIntersectionAndCompensation.
func WithPrimaryKeyIntersector ¶
func WithPrimaryKeyIntersector(ctx PlanContext) IntersectorFunc
WithPrimaryKeyIntersector returns an IntersectorFunc that creates physical intersection plans from pairs of compatible partial matches using the primary key as the comparison key.
Creates RecordQueryIntersectionPlan directly (physical, not logical) wrapped in PhysicalIntersectionWrapper. This avoids the task cascade that would occur if LogicalIntersectionExpression were inserted and then explored — fresh child References trigger re-exploration loops.
type LimitMergeRule ¶
type LimitMergeRule struct {
// contains filtered or unexported fields
}
LimitMergeRule consolidates nested LIMIT expressions into one.
Pattern:
LogicalLimit(limitOuter, offsetOuter)
inner → LogicalLimit(limitInner, offsetInner)
inner → X
Rewrite:
LogicalLimit(effectiveLimit, effectiveOffset) inner → X
Semantics: LIMIT a OFFSET b over LIMIT c OFFSET d
The inner produces at most c rows starting at d. The outer then skips b of those and takes a. Combined offset = d + b (skip d from source, then b more). Combined limit = min(a, c - b) — can't take more than inner produces minus what outer skips of the inner result. If c - b <= 0, the combined limit is 0 (no rows).
func NewLimitMergeRule ¶
func NewLimitMergeRule() *LimitMergeRule
func (*LimitMergeRule) Matcher ¶
func (r *LimitMergeRule) Matcher() matching.BindingMatcher
func (*LimitMergeRule) OnMatch ¶
func (r *LimitMergeRule) OnMatch(call *ExpressionRuleCall)
type MappingKey ¶
type MappingKey struct {
// contains filtered or unexported fields
}
MappingKey captures the relationship between query predicate and candidate predicate. Ports Java's PredicateMultiMap.PredicateMapping.MappingKey.
func NewMappingKey ¶
func NewMappingKey( originalQueryPredicate predicates.QueryPredicate, candidatePredicate predicates.QueryPredicate, mappingKind MappingKind, ) MappingKey
NewMappingKey constructs a MappingKey.
func (MappingKey) GetCandidatePredicate ¶
func (k MappingKey) GetCandidatePredicate() predicates.QueryPredicate
GetCandidatePredicate returns the candidate predicate.
func (MappingKey) GetMappingKind ¶
func (k MappingKey) GetMappingKind() MappingKind
GetMappingKind returns the mapping kind.
func (MappingKey) GetOriginalQueryPredicate ¶
func (k MappingKey) GetOriginalQueryPredicate() predicates.QueryPredicate
GetOriginalQueryPredicate returns the original query predicate.
type MappingKind ¶
type MappingKind int
MappingKind discriminates the kind of predicate mapping. Ports Java's PredicateMultiMap.PredicateMapping.MappingKind.
const ( // MappingRegularImpliesCandidate means the query predicate // directly implies the candidate predicate. MappingRegularImpliesCandidate MappingKind = iota // MappingOrTermImpliesCandidate means the query predicate is // one term of an OR that implies the candidate predicate. MappingOrTermImpliesCandidate )
func (MappingKind) String ¶
func (k MappingKind) String() string
String returns a human-readable name for the MappingKind.
type MatchCandidate ¶
type MatchCandidate interface {
// CandidateName returns the candidate's identifier (typically the
// index name, or "primary" for the PK scan).
CandidateName() string
// GetTraversal returns the Traversal of this candidate's expression
// tree, used by matching rules (MatchLeafRule, MatchIntermediateRule)
// to walk the candidate structure. The traversal must be stable once
// computed. Returns nil if the candidate has no expression tree
// (a candidate that does not support traversal-based matching).
//
// Ports Java's MatchCandidate.getTraversal().
GetTraversal() *Traversal
// GetColumnNames returns the ordered column-name list (one per
// index key column, parallel to GetSargableAliases). Used by rules
// to match ComparisonPredicate field references against the index's
// key columns.
GetColumnNames() []string
// GetSargableAliases returns the ordered list of parameter
// identifiers (one per index key column, left-to-right) that can
// be bound by predicate matching. The order determines the index
// key prefix discipline: N equality-bound parameters followed by
// at most one inequality-bound parameter form a valid scan prefix.
GetSargableAliases() []values.CorrelationIdentifier
// GetRecordTypes returns which record types this candidate covers.
GetRecordTypes() []string
// IsUnique reports whether the candidate's key uniquely identifies
// a record (unique index or primary key).
IsUnique() bool
// ComputeBoundParameterPrefixMap computes the valid index-scan
// prefix from a parameter→ComparisonRange binding map. Returns the
// longest prefix of sargable parameters that satisfies the index
// scan discipline (N equalities + optional trailing inequality).
ComputeBoundParameterPrefixMap(
bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange,
) map[values.CorrelationIdentifier]*predicates.ComparisonRange
// ToScanPlan converts a successful match into a physical index
// scan plan. Called with the prefix map from
// ComputeBoundParameterPrefixMap + reverse flag.
ToScanPlan(
prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange,
reverse bool,
) plans.RecordQueryPlan
}
MatchCandidate represents a scan candidate — typically a secondary index or the primary-key scan. During the EXPLORE phase, the planner matches query predicates against each candidate's sargable parameters; during OPTIMIZE it converts successful matches into physical index-scan plans.
Ports the core surface of Java's `com.apple.foundationdb.record.query.plan.cascades.MatchCandidate`.
func GetPartialMatchCandidatesTyped ¶
func GetPartialMatchCandidatesTyped( ref *expressions.Reference, ) []MatchCandidate
GetPartialMatchCandidatesTyped returns all MatchCandidates that have partial matches on the Reference. Typed wrapper around Reference.GetPartialMatchCandidates.
type MatchInfo ¶
type MatchInfo interface {
// GetMatchedOrderingParts returns the ordering parts matched by
// this match info.
GetMatchedOrderingParts() []*MatchedOrderingPart
// GetMaxMatchMap returns the maximum match map between query and
// candidate value subtrees.
GetMaxMatchMap() *MaxMatchMap
// IsAdjusted reports whether this MatchInfo was produced by
// adjusting (wrapping) another MatchInfo.
IsAdjusted() bool
// IsRegular reports whether this MatchInfo is a direct
// (non-adjusted) match.
IsRegular() bool
// GetRegularMatchInfo returns the underlying RegularMatchInfo.
// For a RegularMatchInfo, it returns itself. For an
// AdjustedMatchInfo, it delegates to the underlying MatchInfo.
GetRegularMatchInfo() *RegularMatchInfo
// GetGroupByMappings returns the group-by mappings captured
// during matching.
GetGroupByMappings() *GroupByMappings
}
MatchInfo represents the result of matching one expression against an expression from a MatchCandidate.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.MatchInfo.
type MatchIntermediateRule ¶
type MatchIntermediateRule struct {
// contains filtered or unexported fields
}
MatchIntermediateRule is the Cascades rule that matches non-leaf query expressions (those with quantifiers) against candidate expressions by composing child PartialMatches. For every query expression with at least one quantifier, the rule:
- Collects the child References from the expression's quantifiers.
- Finds which MatchCandidates have PartialMatches on those child References (seeded by MatchLeafRule or earlier MatchIntermediateRule firings).
- For each such candidate, walks upward through the candidate's Traversal to find parent expressions that reference the candidate-side References from those PartialMatches.
- Attempts a structural match between the query expression and each candidate parent expression, verifying that every quantifier pair is backed by a child PartialMatch.
- On match, creates a new composite PartialMatch and stores it on the query Reference.
This rule propagates matches upward from leaves, enabling multi-level expression trees to be matched against candidate (index) expression trees. It prepares AdjustMatchRule and physical-implementation rules to produce index-scan plans.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.rules.MatchIntermediateRule. Go uses ordered quantifier matching (query[i] <-> candidate[i]) rather than Java's full graph-matching enumeration via RelationalExpression.match(). This handles the common case (same quantifier count, same order); extend to the full combinatorial matcher if a candidate shape ever needs permuted matching.
func NewMatchIntermediateRule ¶
func NewMatchIntermediateRule() *MatchIntermediateRule
NewMatchIntermediateRule constructs a MatchIntermediateRule.
func (*MatchIntermediateRule) Matcher ¶
func (r *MatchIntermediateRule) Matcher() matching.BindingMatcher
Matcher returns the binding matcher. Matches any RelationalExpression (the non-leaf check is inside OnMatch). Mirrors Java's MatchIntermediateRule which returns Optional.empty() from getRootOperator().
func (*MatchIntermediateRule) OnMatch ¶
func (r *MatchIntermediateRule) OnMatch(call *ExpressionRuleCall)
OnMatch implements the intermediate matching logic. It collects child References, finds candidates with child PartialMatches, walks upward through each candidate's Traversal, and attempts structural matching at each candidate parent expression.
type MatchLeafRule ¶
type MatchLeafRule struct {
// contains filtered or unexported fields
}
MatchLeafRule is the Cascades rule that seeds the partial-match infrastructure by matching query leaf expressions against candidate leaf expressions. For every query expression with zero quantifiers, the rule iterates all MatchCandidates from the PlanContext, walks each candidate's Traversal to find its leaf References, and attempts a structural match (EqualsWithoutChildren) between the query leaf and each candidate leaf. On match, a PartialMatch is created and stored on the query Reference.
This rule seeds the memoisation structure for partial matches kept on Reference. It prepares further rules such as MatchIntermediateRule and AdjustMatchRule.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.rules.MatchLeafRule.
func NewMatchLeafRule ¶
func NewMatchLeafRule() *MatchLeafRule
NewMatchLeafRule constructs a MatchLeafRule.
func (*MatchLeafRule) Matcher ¶
func (r *MatchLeafRule) Matcher() matching.BindingMatcher
Matcher returns the binding matcher. Matches any RelationalExpression (the leaf check is performed inside OnMatch). This mirrors Java's MatchLeafRule which returns Optional.empty() from getRootOperator() so it fires on all expression types.
func (*MatchLeafRule) OnMatch ¶
func (r *MatchLeafRule) OnMatch(call *ExpressionRuleCall)
OnMatch iterates all MatchCandidates, finds leaf references in each candidate's Traversal, and attempts a structural match between the query expression and each candidate leaf expression.
type MatchPartition ¶
type MatchPartition struct {
// contains filtered or unexported fields
}
MatchPartition groups PartialMatch instances for a specific expression and reference. Simple container.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.MatchPartition.
func NewMatchPartition ¶
func NewMatchPartition(matches []PartialMatch) *MatchPartition
NewMatchPartition constructs a MatchPartition from the given matches. The slice is defensively copied.
func (*MatchPartition) GetPartialMatches ¶
func (p *MatchPartition) GetPartialMatches() []PartialMatch
GetPartialMatches returns the partial matches in this partition.
type MatchedOrderingPart ¶
type MatchedOrderingPart struct {
// contains filtered or unexported fields
}
MatchedOrderingPart is an OrderingPart that has been bound by a comparison during graph matching. It stores the parameter identifier, the value being ordered, the comparison range that was matched (equality/inequality/empty), and the matched sort direction.
Mirrors Java's OrderingPart.MatchedOrderingPart.
func NewMatchedOrderingPart ¶
func NewMatchedOrderingPart( parameterId values.CorrelationIdentifier, value values.Value, comparisonRange *predicates.ComparisonRange, matchedSortOrder MatchedSortOrder, ) *MatchedOrderingPart
NewMatchedOrderingPart creates a MatchedOrderingPart. If comparisonRange is nil, it defaults to the empty (universe) range. Mirrors Java's MatchedOrderingPart.of() factory.
func (*MatchedOrderingPart) Demote ¶
func (m *MatchedOrderingPart) Demote() *MatchedOrderingPart
Demote converts an equality-bound ordering part to an empty (universe) range, preserving the parameter ID, value, and sort order. Panics if the comparison range is not an equality range. Returns a new MatchedOrderingPart (immutable pattern).
This is used during ordering satisfaction when an equality-bound prefix part can be "demoted" to allow sorting on later parts.
func (*MatchedOrderingPart) GetComparisonRange ¶
func (m *MatchedOrderingPart) GetComparisonRange() *predicates.ComparisonRange
GetComparisonRange returns the comparison range.
func (*MatchedOrderingPart) GetComparisonRangeType ¶
func (m *MatchedOrderingPart) GetComparisonRangeType() predicates.ComparisonRangeType
GetComparisonRangeType delegates to the comparison range's GetRangeType.
func (*MatchedOrderingPart) GetMatchedSortOrder ¶
func (m *MatchedOrderingPart) GetMatchedSortOrder() MatchedSortOrder
GetMatchedSortOrder returns the matched sort direction.
func (*MatchedOrderingPart) GetParameterId ¶
func (m *MatchedOrderingPart) GetParameterId() values.CorrelationIdentifier
GetParameterId returns the correlation identifier for this ordering part in the match candidate.
func (*MatchedOrderingPart) GetValue ¶
func (m *MatchedOrderingPart) GetValue() values.Value
GetValue returns the value being ordered by.
func (*MatchedOrderingPart) String ¶
func (m *MatchedOrderingPart) String() string
String returns a human-readable representation.
type MatchedSortOrder ¶
type MatchedSortOrder int
MatchedSortOrder represents the sort direction assigned during index matching. Mirrors Java's OrderingPart.MatchedSortOrder. All values are directional (IsDirectional always returns true).
The naming "ascending" / "descending" is conventional: ascending becomes actual ascending with a forward scan; with a reverse scan it flips. The only semantic invariant is that ascending and descending are polar opposites.
const ( MatchedSortOrderAscending MatchedSortOrder = iota MatchedSortOrderDescending MatchedSortOrderAscendingNullsLast MatchedSortOrderDescendingNullsFirst )
func (MatchedSortOrder) ArrowIndicator ¶
func (s MatchedSortOrder) ArrowIndicator() string
ArrowIndicator returns a directional arrow for pretty-printing, matching Java's getArrowIndicator(). Uses the same Unicode arrows as ProvidedSortOrder for the corresponding direction.
func (MatchedSortOrder) IsAnyAscending ¶
func (s MatchedSortOrder) IsAnyAscending() bool
IsAnyAscending reports whether this sort order is any ascending variant.
func (MatchedSortOrder) IsAnyDescending ¶
func (s MatchedSortOrder) IsAnyDescending() bool
IsAnyDescending reports whether this sort order is any descending variant.
func (MatchedSortOrder) IsCounterflowNulls ¶
func (s MatchedSortOrder) IsCounterflowNulls() bool
IsCounterflowNulls reports whether the NULL placement runs against the natural tuple order for this direction (ASC_NULLS_LAST / DESC_NULLS_FIRST). Mirrors Java TupleOrdering.Direction.isCounterflowNulls() via MatchedSortOrder's Direction.
func (MatchedSortOrder) IsDirectional ¶
func (s MatchedSortOrder) IsDirectional() bool
IsDirectional returns true. All MatchedSortOrder values are directional by definition (unlike ProvidedSortOrder which has FIXED and CHOOSE).
func (MatchedSortOrder) String ¶
func (s MatchedSortOrder) String() string
String returns a human-readable label for the sort order.
func (MatchedSortOrder) ToProvidedSortOrder ¶
func (s MatchedSortOrder) ToProvidedSortOrder(isReverse bool) ProvidedSortOrder
ToProvidedSortOrder maps this matched sort order to the corresponding ProvidedSortOrder. When isReverse is true, the direction is flipped (ascending becomes descending, etc.).
The mapping is by direction (Java's Direction enum), not by Go constant name. Both enums use the same iota ordering that maps to the same underlying Direction values.
type MaxMatchMap ¶
type MaxMatchMap struct {
// contains filtered or unexported fields
}
MaxMatchMap represents the maximum matching between query and candidate Value subtrees. Each entry maps a query sub-value to a candidate sub-value (keyed by ExplainValue for structural equality, matching Java's BiMap approach).
Ports Java's com.apple.foundationdb.record.query.plan.cascades.values.translation.MaxMatchMap.
func ComputeMaxMatchMap ¶
func ComputeMaxMatchMap( queryValue values.Value, candidateValue values.Value, rangedOverAliases map[values.CorrelationIdentifier]struct{}, ) *MaxMatchMap
ComputeMaxMatchMap creates a MaxMatchMap by finding the maximum matching between query and candidate value trees.
Ports Java's MaxMatchMap.compute.
func ComputeMaxMatchMapWithEquivalence ¶
func ComputeMaxMatchMapWithEquivalence( queryValue values.Value, candidateValue values.Value, rangedOverAliases map[values.CorrelationIdentifier]struct{}, valueEquivalence ValueEquivalence, ) *MaxMatchMap
ComputeMaxMatchMapWithEquivalence is like ComputeMaxMatchMap but accepts an optional ValueEquivalence for cross-alias matching. When structural equality fails, the ValueEquivalence is consulted to determine whether two values should be considered equal.
Ports Java's MaxMatchMap.compute(queryValue, candidateValue, rangedOverAliases, valueEquivalence).
func NewMaxMatchMap ¶
func NewMaxMatchMap( mapping map[values.Value]values.Value, queryValue values.Value, candidateValue values.Value, ) *MaxMatchMap
NewMaxMatchMap constructs a MaxMatchMap from a pre-built mapping. The mapping is defensively copied. Retained for backwards compatibility with existing call sites.
func (*MaxMatchMap) AdjustMaybe ¶
func (m *MaxMatchMap) AdjustMaybe( upperCandidateAlias values.CorrelationIdentifier, upperCandidateResultValue values.Value, rangedOverAliases map[values.CorrelationIdentifier]struct{}, ) (*MaxMatchMap, bool)
AdjustMaybe adjusts this MaxMatchMap through an upper candidate level. It translates the query value through upperCandidateAlias, then re-computes a MaxMatchMap against upperCandidateResultValue.
Returns (adjustedMap, true) on success, (nil, false) on failure.
Ports Java's MaxMatchMap.adjustMaybe.
func (*MaxMatchMap) GetCandidateValue ¶
func (m *MaxMatchMap) GetCandidateValue() values.Value
GetCandidateValue returns the root candidate value.
func (*MaxMatchMap) GetMap ¶
func (m *MaxMatchMap) GetMap() map[values.Value]values.Value
GetMap returns the value-to-value mapping in the legacy format (map[values.Value]values.Value). This is the query→candidate direction.
func (*MaxMatchMap) GetQueryValue ¶
func (m *MaxMatchMap) GetQueryValue() values.Value
GetQueryValue returns the root query value.
func (*MaxMatchMap) PullUpMaybe ¶
func (m *MaxMatchMap) PullUpMaybe( queryAlias values.CorrelationIdentifier, candidateAlias values.CorrelationIdentifier, ) (*RegularTranslationMap, bool)
PullUpMaybe creates a TranslationMap that translates queryAlias references to the query value expressed through candidateAlias.
Returns (translationMap, true) on success, (nil, false) on failure.
Ports Java's MaxMatchMap.pullUpMaybe.
func (*MaxMatchMap) Size ¶
func (m *MaxMatchMap) Size() int
Size returns the number of entries in the mapping.
func (*MaxMatchMap) TranslateQueryValueMaybe ¶
func (m *MaxMatchMap) TranslateQueryValueMaybe( candidateAlias values.CorrelationIdentifier, ) values.Value
TranslateQueryValueMaybe translates the query value so that it can be expressed in terms of candidateAlias.
For the identity case (query == candidate structurally, single mapping entry), returns a QuantifiedObjectValue(candidateAlias).
For non-identity mappings, uses values.Replace to substitute each mapped query subtree with a pulled-up reference through candidateAlias, then validates that no rangedOverAliases remain in the result.
Returns nil if the translation fails.
Ports Java's MaxMatchMap.translateQueryValueMaybe.
type Memo ¶
type Memo struct {
// contains filtered or unexported fields
}
Memo is the central memoization structure for the Cascades planner. It tracks all References in the plan DAG and enables cross-Reference equivalence-class sharing: when two rules independently derive structurally-equivalent sub-expressions, the Memo routes them into the same Reference so the planner explores/optimizes that sub-tree only once.
Ports the memoization behaviour from Java's CascadesRuleCall + Traversal. Java uses a MutableNetwork<Reference, ReferencePath> to track the DAG topology; Go uses flat index maps for the same purpose.
Lifecycle:
- Created via NewMemo(rootRef) at planner construction time.
- Rules call MemoizeExpression(expr) to find-or-create a Reference for a sub-expression. Returns an existing Reference when the expr (or a structural equivalent) is already memoized.
- The Planner's EXPLORE phase populates the Memo as rules fire.
Thread safety: single-threaded (same as Java's planner).
func NewMemo ¶
func NewMemo(root *expressions.Reference) *Memo
NewMemo constructs a Memo rooted at `root` and indexes the full DAG reachable from it. If root is nil, returns an empty Memo.
func (*Memo) AddExpression ¶
func (m *Memo) AddExpression(ref *expressions.Reference, expr expressions.RelationalExpression)
AddExpression registers a new expression into the Memo's index within an existing Reference. Call this after Reference.Insert succeeds to keep the Memo's topology index up to date.
func (*Memo) AliasAwareDedups ¶
AliasAwareDedups sums, over every Reference in the memo, the extra dedup the alias-aware interning tier performed (Reference.AliasAwareDedups) — the "shadow" of the merge re-enumeration's shared-sub-product collapse. The RFC-173 Slice-3 shadow-delta pin asserts this equals the member-count delta between alias-aware interning and the alias-identity baseline.
func (*Memo) ContainsReference ¶
func (m *Memo) ContainsReference(ref *expressions.Reference) bool
ContainsReference reports whether the Memo has indexed `ref`.
func (*Memo) Integrate ¶
func (m *Memo) Integrate(ref *expressions.Reference, expr expressions.RelationalExpression)
Integrate is the cross-group merge entry point, called when a rule yields an expression into ref during REWRITING. It either:
- discovers that a structurally-equivalent member already lives in a DIFFERENT Reference and merges the two groups, or
- records ref as a parent of expr's child References in the topology index (so future lookups can find this parent).
After the initial step it drains the recursive bottom-up worklist: a merge can make the merged group's parents duplicates of one another, which must themselves merge (the paper's recursive integration).
func (*Memo) MemoizeExpression ¶
func (m *Memo) MemoizeExpression(expr expressions.RelationalExpression) *expressions.Reference
MemoizeExpression is the core memoization entry point. Given an expression, it either:
- finds an existing Reference in the Memo that already contains a structurally-equivalent expression (same node info under EqualsWithoutChildren + same child References by pointer), and returns that Reference; or
- creates a new single-member Reference for the expression, registers it in the Memo, and returns the new Reference.
This is how cross-Reference sharing works: two rules that independently produce the same sub-expression get back the SAME Reference, avoiding redundant exploration.
Mirrors Java's CascadesRuleCall.memoizeExploratoryExpressions.
func (*Memo) MemoizeExpressions ¶
func (m *Memo) MemoizeExpressions(exprs []expressions.RelationalExpression) *expressions.Reference
MemoizeExpressions memoizes multiple expressions into a single Reference. If an existing Reference contains ALL of the given expressions (or structural equivalents), returns that Reference. Otherwise creates a new Reference holding all expressions.
Used when a rule produces multiple equivalent alternatives for the same sub-tree.
func (*Memo) MergeArmHits ¶
MergeArmHits returns how many times PartitionSelectRule took the anchored re-enumeration arm (the name-model dispatch). The RFC-173 Slice-3 dispatch-authority pin asserts this is 0 on an ordinal-seeded corpus.
func (*Memo) MergeCount ¶
MergeCount returns the number of cross-group merges performed so far (RFC-037). Used by tests to assert the merge optimization fires.
func (*Memo) NextMergeAlias ¶
func (m *Memo) NextMergeAlias() values.CorrelationIdentifier
NextMergeAlias returns a per-plan deterministic, collision-PROOF quantifier alias for a PartitionSelectRule merge sub-join (RFC-077 7.5).
The alias embeds a double-quote ("). That is the one character no parsed SQL identifier can ever contain: the lexer's delimited-identifier rule is DOUBLE_QUOTE_ID: '"' ~'"'+ '"' (RelationalLexer.g4) — a quoted identifier is any run of NON-quote characters between quotes, so the quotes are stripped and the resulting name can never include a ". A bare "$m"-prefix is NOT safe on its own: a user could write a quoted alias `AS "$m1"`, which parses to the name "$m1" and would collide with this merge quantifier, corrupting alias-keyed binding/rebasing in a multi-way join. (This collision class also affects UniqueCorrelationIdentifier's "q$N" — `AS "q$1"` — a pre-existing, separate hardening item; here we make the merge alias uncollidable outright.)
The per-Memo ordinal makes the alias deterministic across plannings of the same query (for a stable plan hash) while still differing per merge occurrence, so equivalent sub-products intern via the alias-aware Reference.Insert tier, not via a stable string. The alias is internal — never re-lexed as SQL; it only appears as a correlation key (rebasing, NLJ source alias, Explain). See mergeAliasCounter.
func (*Memo) RecordMergeArmHit ¶
func (m *Memo) RecordMergeArmHit()
RecordMergeArmHit increments the anchored-arm counter. Called by PartitionSelectRule when it takes the parentIsMerge (name-model) re-enumeration dispatch. No-op when the memo is nil (standalone rule tests run without a Memo).
func (*Memo) References ¶
func (m *Memo) References() map[*expressions.Reference]struct{}
References returns all References known to the Memo. The returned map is read-only; callers must not mutate it.
func (*Memo) RegisterReference ¶
func (m *Memo) RegisterReference(ref *expressions.Reference)
RegisterReference adds a Reference (and its sub-tree) to the Memo's index without performing memoization lookup. Used when a rule creates a Reference that is known-fresh (e.g. the root at construction time, or a Reference already checked by MemoizeExpression).
func (*Memo) Root ¶
func (m *Memo) Root() *expressions.Reference
Root returns the root Reference of the Memo.
func (*Memo) TotalMembers ¶
TotalMembers sums the exploratory + final member count over every canonical Reference in the memo. With the alias-aware interning tier live this is the deduped population; the shadow-delta pin re-plans with the tier disabled to recover the alias-identity population. The difference EXCEEDS AliasAwareDedups (the direct dedups): each collapsed merge sub-product would otherwise re-explode, so one direct dedup saves several downstream members (cascade).
type MergeFetchIntoCoveringIndexRule ¶
type MergeFetchIntoCoveringIndexRule struct {
// contains filtered or unexported fields
}
MergeFetchIntoCoveringIndexRule eliminates a FetchFromPartialRecordPlan when its inner is a covering index scan. If the index provides all needed columns (the fetch is redundant), the rule yields just the inner index scan plan directly.
Pattern:
Fetch(CoveringIndexScan) → IndexScan
In Go, covering index scans are physicalIndexScanWrappers whose TranslateValueFunction can translate all required values. The rule fires when the fetch wraps an index scan directly (no intermediate filter or distinct).
Mirrors Java's `MergeFetchIntoCoveringIndexRule`.
Note: currently unreachable in the production pipeline because wrapScanPlanWithCoverage strips the Fetch at construction time for covering indexes (returning a bare physicalIndexScanWrapper with covering=true). This rule exists for completeness and would fire if a Fetch(covering-index) structure were produced by a different path (e.g., manual plan construction or future rule rewrites).
func NewMergeFetchIntoCoveringIndexRule ¶
func NewMergeFetchIntoCoveringIndexRule() *MergeFetchIntoCoveringIndexRule
func (*MergeFetchIntoCoveringIndexRule) Matcher ¶
func (r *MergeFetchIntoCoveringIndexRule) Matcher() matching.BindingMatcher
func (*MergeFetchIntoCoveringIndexRule) OnMatch ¶
func (r *MergeFetchIntoCoveringIndexRule) OnMatch(call *ImplementationRuleCall)
type MergeProjectionAndFetchRule ¶
type MergeProjectionAndFetchRule struct {
// contains filtered or unexported fields
}
MergeProjectionAndFetchRule removes both a LogicalProjectionExpression and a FetchFromPartialRecordPlan when all projected values are available in the partial record (index entry) before the fetch.
If every projected value can be pushed through the fetch (translated from the full-record domain to the partial-record domain), then neither the projection nor the fetch is needed: the fetch's inner (covering index scan) already provides all necessary data.
Before:
Projection(Fetch(inner))
After (when all values pushable):
inner
Mirrors Java's MergeProjectionAndFetchRule.
func NewMergeProjectionAndFetchRule ¶
func NewMergeProjectionAndFetchRule() *MergeProjectionAndFetchRule
func (*MergeProjectionAndFetchRule) Matcher ¶
func (r *MergeProjectionAndFetchRule) Matcher() matching.BindingMatcher
func (*MergeProjectionAndFetchRule) OnMatch ¶
func (r *MergeProjectionAndFetchRule) OnMatch(call *ImplementationRuleCall)
type NoOpFilterRule ¶
type NoOpFilterRule struct {
// contains filtered or unexported fields
}
NoOpFilterRule eliminates a LogicalFilter whose predicate list is empty OR whose predicates all evaluate (under the constant fold) to a tri-state TRUE. The replacement is the inner Quantifier's expression — the filter is a row-by-row identity at that point.
Two firing conditions, both equivalent SQL no-ops:
- Empty predicate list — comes up after FilterMergeRule + a follow-on rule that folds out tautologies, leaving an empty conjunction.
- All predicates are ConstantPredicate(TriTrue) — the trivial `WHERE TRUE` shape.
Yields the inner expression directly, NOT a fresh wrapper. The memo dedup absorbs duplicate inserts via Reference.Insert.
func NewNoOpFilterRule ¶
func NewNoOpFilterRule() *NoOpFilterRule
NewNoOpFilterRule constructs the rule.
func (*NoOpFilterRule) Matcher ¶
func (r *NoOpFilterRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*NoOpFilterRule) OnMatch ¶
func (r *NoOpFilterRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the filter is a no-op.
type NoOpLimitElimRule ¶
type NoOpLimitElimRule struct {
// contains filtered or unexported fields
}
NoOpLimitElimRule eliminates a LIMIT that has no effect. A LIMIT with limit < 0 (no cap) AND offset == 0 (no skip) is a pure pass-through — the inner expression is equivalent.
Pattern:
LogicalLimit(limit<0, offset=0) inner → X
Rewrite: X
func NewNoOpLimitElimRule ¶
func NewNoOpLimitElimRule() *NoOpLimitElimRule
func (*NoOpLimitElimRule) Matcher ¶
func (r *NoOpLimitElimRule) Matcher() matching.BindingMatcher
func (*NoOpLimitElimRule) OnMatch ¶
func (r *NoOpLimitElimRule) OnMatch(call *ExpressionRuleCall)
type NormalizePredicatesRule ¶
type NormalizePredicatesRule struct {
// contains filtered or unexported fields
}
NormalizePredicatesRule converts the predicates of a SelectExpression into conjunctive normal form (CNF) — AND of ORs. The normalised predicates are set as the new predicate list on a freshly yielded SelectExpression (quantifiers are rebuilt with new aliases pointing at the same References).
Ports Java's NormalizePredicatesRule which is the precursor to PredicateToLogicalUnionRule. The CNF form makes each OR clause independently matchable by index-pushdown rules, enabling OR-to- UNION transformations.
Algorithm:
- AND all predicates together.
- Run CNF normalization (distribute OR over AND).
- If the result is already in CNF, bail (nothing to do).
- Extract the top-level AND conjuncts as the new predicate list.
- Yield a new SelectExpression with rebuilt quantifiers.
The normalizer respects a complexity threshold (cnfSizeLimit) to avoid exponential blow-up from deeply nested OR/AND trees. If the normalised form would exceed the limit, the rule produces no yield.
Mirrors Java's BooleanPredicateNormalizer in CNF mode with a default size limit of 1,000,000.
func NewNormalizePredicatesRule ¶
func NewNormalizePredicatesRule() *NormalizePredicatesRule
func (*NormalizePredicatesRule) Matcher ¶
func (r *NormalizePredicatesRule) Matcher() matching.BindingMatcher
func (*NormalizePredicatesRule) OnMatch ¶
func (r *NormalizePredicatesRule) OnMatch(call *ExpressionRuleCall)
type NotComparisonRewriteRule ¶
type NotComparisonRewriteRule struct {
// contains filtered or unexported fields
}
NotComparisonRewriteRule pushes a NOT past a ComparisonPredicate whose comparison type has a direct negation: `NOT(x = 5)` → `x <> 5`, `NOT(x IS NULL)` → `x IS NOT NULL`. Leaves `NOT(x IN (...))` and `NOT(x STARTS_WITH 'pre')` alone — those have no direct-negation comparison type.
Mirrors Java's predicate-simplification passes that push NOT down to leaves so downstream index-pushdown rules see a canonical leaf-level predicate and don't have to also handle NOT wrappers.
func NewNotComparisonRewriteRule ¶
func NewNotComparisonRewriteRule() *NotComparisonRewriteRule
NewNotComparisonRewriteRule constructs the rule.
func (*NotComparisonRewriteRule) Matcher ¶
func (r *NotComparisonRewriteRule) Matcher() matching.BindingMatcher
func (*NotComparisonRewriteRule) OnMatch ¶
func (r *NotComparisonRewriteRule) OnMatch(call *RuleCall)
type NotConstantSimplifyRule ¶
type NotConstantSimplifyRule struct {
// contains filtered or unexported fields
}
NotConstantSimplifyRule folds NOT over a constant child per Kleene NOT (NOT TRUE=FALSE, NOT FALSE=TRUE, NOT UNKNOWN=UNKNOWN). Also fires on NOT NOT x → x (double-negation elimination).
func NewNotConstantSimplifyRule ¶
func NewNotConstantSimplifyRule() *NotConstantSimplifyRule
NewNotConstantSimplifyRule constructs the rule.
func (*NotConstantSimplifyRule) Matcher ¶
func (r *NotConstantSimplifyRule) Matcher() matching.BindingMatcher
func (*NotConstantSimplifyRule) OnMatch ¶
func (r *NotConstantSimplifyRule) OnMatch(call *RuleCall)
type OptimizeGroupTask ¶
type OptimizeGroupTask struct {
Phase PlannerPhase
Ref *expressions.Reference
}
OptimizeGroupTask picks the best final expression and prunes losers. Mirrors Java's CascadesPlanner.OptimizeGroup.
func (*OptimizeGroupTask) Run ¶
func (t *OptimizeGroupTask) Run(p *Planner)
type OptimizeInputsTask ¶
type OptimizeInputsTask struct {
Phase PlannerPhase
Ref *expressions.Reference
Expr expressions.RelationalExpression
}
OptimizeInputsTask pushes OptimizeGroup for each child quantifier. Mirrors Java's CascadesPlanner.OptimizeInputs.
func (*OptimizeInputsTask) Run ¶
func (t *OptimizeInputsTask) Run(p *Planner)
type OrAbsorbAndRule ¶
type OrAbsorbAndRule struct {
// contains filtered or unexported fields
}
OrAbsorbAndRule: mirror. Inside an OR, any AND child that contains a sibling is redundant — drop it. `OR(p, AND(p, q))` → `OR(p)` → `p`.
func NewOrAbsorbAndRule ¶
func NewOrAbsorbAndRule() *OrAbsorbAndRule
NewOrAbsorbAndRule constructs the rule.
func (*OrAbsorbAndRule) Matcher ¶
func (r *OrAbsorbAndRule) Matcher() matching.BindingMatcher
func (*OrAbsorbAndRule) OnMatch ¶
func (r *OrAbsorbAndRule) OnMatch(call *RuleCall)
type OrConstantSimplifyRule ¶
type OrConstantSimplifyRule struct {
// contains filtered or unexported fields
}
OrConstantSimplifyRule matches an OrPredicate and folds constant children per Kleene OR identities.
func NewOrConstantSimplifyRule ¶
func NewOrConstantSimplifyRule() *OrConstantSimplifyRule
NewOrConstantSimplifyRule constructs the rule.
func (*OrConstantSimplifyRule) Matcher ¶
func (r *OrConstantSimplifyRule) Matcher() matching.BindingMatcher
func (*OrConstantSimplifyRule) OnMatch ¶
func (r *OrConstantSimplifyRule) OnMatch(call *RuleCall)
type OrDedupRule ¶
type OrDedupRule struct {
// contains filtered or unexported fields
}
OrDedupRule: mirror of AndDedupRule.
func (*OrDedupRule) Matcher ¶
func (r *OrDedupRule) Matcher() matching.BindingMatcher
func (*OrDedupRule) OnMatch ¶
func (r *OrDedupRule) OnMatch(call *RuleCall)
type OrFlattenRule ¶
type OrFlattenRule struct {
// contains filtered or unexported fields
}
OrFlattenRule: mirror of AndFlattenRule for OR.
func NewOrFlattenRule ¶
func NewOrFlattenRule() *OrFlattenRule
NewOrFlattenRule constructs the rule.
func (*OrFlattenRule) Matcher ¶
func (r *OrFlattenRule) Matcher() matching.BindingMatcher
func (*OrFlattenRule) OnMatch ¶
func (r *OrFlattenRule) OnMatch(call *RuleCall)
type OrderedIndexScanRule ¶
type OrderedIndexScanRule struct {
// contains filtered or unexported fields
}
OrderedIndexScanRule matches a LogicalSort over a FullUnorderedScan (no filter in between) and produces an index scan when an index's column order provides the requested sort ordering. The index scan has no predicate bounds — it scans the full index but in the index's key order, eliminating the sort.
Sort([col1 ASC, col2 ASC]) over FullUnorderedScan → IndexScan(full-range, index on (col1, col2, ...))
This complements ImplementIndexScanRule (which requires a Filter). When both a predicate and ordering are requested, PushFilterThroughSort moves the filter below the sort, and ImplementIndexScanRule handles the Filter(Scan) shape. This rule covers the pure ORDER BY case.
func NewOrderedIndexScanRule ¶
func NewOrderedIndexScanRule() *OrderedIndexScanRule
func (*OrderedIndexScanRule) Matcher ¶
func (r *OrderedIndexScanRule) Matcher() matching.BindingMatcher
func (*OrderedIndexScanRule) OnMatch ¶
func (r *OrderedIndexScanRule) OnMatch(call *ExpressionRuleCall)
type OrderedPrimaryScanRule ¶
type OrderedPrimaryScanRule struct {
// contains filtered or unexported fields
}
OrderedPrimaryScanRule matches Sort over FullUnorderedScan and produces a primary scan when the sort keys match the PK columns. For DESC, a reverse primary scan is produced.
Sort([pk ASC/DESC]) over FullUnorderedScan → Scan(reverse=DESC)
Complements OrderedIndexScanRule which handles secondary indexes.
func NewOrderedPrimaryScanRule ¶
func NewOrderedPrimaryScanRule() *OrderedPrimaryScanRule
func (*OrderedPrimaryScanRule) Matcher ¶
func (r *OrderedPrimaryScanRule) Matcher() matching.BindingMatcher
func (*OrderedPrimaryScanRule) OnMatch ¶
func (r *OrderedPrimaryScanRule) OnMatch(call *ExpressionRuleCall)
type OrderingBinding ¶
type OrderingBinding struct {
// contains filtered or unexported fields
}
OrderingBinding represents a binding in the ordering: either a fixed comparison binding or a directional sort binding. Mirrors Java's Ordering.Binding.
func ChooseBinding ¶
func ChooseBinding() OrderingBinding
ChooseBinding creates a binding where the sort order will be chosen during enumeration.
func FixedBinding ¶
func FixedBinding(comparison any) OrderingBinding
FixedBinding creates a fixed (equality-bound) ordering binding.
func SingleFixedBinding ¶
func SingleFixedBinding(bindings []OrderingBinding) OrderingBinding
FixedBinding returns the single fixed binding from the list. Panics if there isn't exactly one.
func SortedBinding ¶
func SortedBinding(sortOrder ProvidedSortOrder) OrderingBinding
SortedBinding creates a sorted ordering binding.
func (OrderingBinding) GetComparison ¶
func (b OrderingBinding) GetComparison() any
func (OrderingBinding) GetSortOrder ¶
func (b OrderingBinding) GetSortOrder() ProvidedSortOrder
func (OrderingBinding) IsChoose ¶
func (b OrderingBinding) IsChoose() bool
func (OrderingBinding) IsFixed ¶
func (b OrderingBinding) IsFixed() bool
func (OrderingBinding) IsSorted ¶
func (b OrderingBinding) IsSorted() bool
type OrderingBindingKind ¶
type OrderingBindingKind int
const ( OrderingBindingSorted OrderingBindingKind = iota OrderingBindingFixed OrderingBindingChoose )
type OrderingMergeKind ¶
type OrderingMergeKind int
OrderingMergeKind determines the semantics of merging two orderings.
const ( OrderingMergeUnion OrderingMergeKind = iota OrderingMergeIntersection )
type OrderingPartsComputer ¶
type OrderingPartsComputer interface {
// ComputeMatchedOrderingParts computes matched ordering parts from
// this candidate's structure, the existing match info, the sort
// parameter IDs, and the reverse flag. Returns a list of
// MatchedOrderingParts describing the order of the outgoing data
// stream.
ComputeMatchedOrderingParts(
matchInfo MatchInfo,
sortParameterIDs []values.CorrelationIdentifier,
isReverse bool,
) []*MatchedOrderingPart
}
OrderingPartsComputer is an optional interface that MatchCandidate implementations can satisfy to provide ordering-part computation for MatchableSortExpression adjustment. It is optional rather than part of the MatchCandidate interface because only order-providing candidates implement it (ValueIndexScanMatchCandidate today; the caller below falls back for the rest).
Ports the computeMatchedOrderingParts method from Java's MatchCandidate / ValueIndexLikeMatchCandidate.
type PartialMatch ¶
type PartialMatch interface {
GetMatchCandidate() MatchCandidate
GetMatchInfo() MatchInfo
GetBoundAliasMap() *AliasMap
GetQueryRef() *expressions.Reference
GetQueryExpression() expressions.RelationalExpression
GetCandidateRef() *expressions.Reference
GetRegularMatchInfo() *RegularMatchInfo
}
PartialMatch is forward-declared -- full definition will live in partial_match.go. Using an interface to avoid circular dependencies.
func GetPartialMatchesForCandidate ¶
func GetPartialMatchesForCandidate( ref *expressions.Reference, candidate MatchCandidate, ) []PartialMatch
GetPartialMatchesForCandidate returns all PartialMatches stored on the Reference for the given MatchCandidate. Typed wrapper around Reference.GetPartialMatchesFor. Mirrors Java's Reference.getPartialMatchesForCandidate.
func GetPartialMatchesForExpression ¶
func GetPartialMatchesForExpression( ref *expressions.Reference, expr expressions.RelationalExpression, ) []PartialMatch
GetPartialMatchesForExpression returns all PartialMatches stored on the Reference whose query expression matches the given expression (identity comparison, matching Java's == check in Reference.getPartialMatchesForExpression).
type PartialMatchImpl ¶
type PartialMatchImpl struct {
// contains filtered or unexported fields
}
PartialMatchImpl is the concrete implementation of PartialMatch. Links a query-side Reference/Expression to a candidate-side Reference via MatchInfo, establishing that the query subgraph rooted at queryRef is result-equivalent to the candidate subgraph rooted at candidateRef under the bindings in boundAliasMap (modulo compensation).
Ports Java's com.apple.foundationdb.record.query.plan.cascades.PartialMatch.
func NewPartialMatch ¶
func NewPartialMatch( boundAliasMap *AliasMap, matchCandidate MatchCandidate, queryRef *expressions.Reference, queryExpression expressions.RelationalExpression, candidateRef *expressions.Reference, matchInfo MatchInfo, ) *PartialMatchImpl
NewPartialMatch constructs a PartialMatchImpl with all six core fields. Mirrors Java's PartialMatch constructor.
func (*PartialMatchImpl) CompensateCompleteMatch ¶
func (p *PartialMatchImpl) CompensateCompleteMatch( unificationPullUp *PullUp, candidateTopAlias values.CorrelationIdentifier, ) Compensation
CompensateCompleteMatch computes compensation for a complete match. Computes child compensation (union of matched quantifier compensations), predicate compensation (residual filters), and result compensation.
Ports Java's PartialMatch.compensateCompleteMatch + SelectExpression.compensate (full predicate compensation computation).
func (*PartialMatchImpl) CompensationCanBeDeferred ¶
func (p *PartialMatchImpl) CompensationCanBeDeferred() bool
CompensationCanBeDeferred reports whether compensation for this match can be deferred to a higher level. Returns false if any unmatched quantifier is ForEach (affects cardinality). Ports Java's PartialMatch.compensationCanBeDeferred().
func (*PartialMatchImpl) GetBoundAliasMap ¶
func (p *PartialMatchImpl) GetBoundAliasMap() *AliasMap
GetBoundAliasMap returns the alias map of all bound correlated references. Mirrors Java's PartialMatch.getBoundAliasMap().
func (*PartialMatchImpl) GetBoundParameterPrefixMap ¶
func (p *PartialMatchImpl) GetBoundParameterPrefixMap() map[values.CorrelationIdentifier]*predicates.ComparisonRange
GetBoundParameterPrefixMap returns the parameter binding map from the match info. Ports Java's PartialMatch.getBoundParameterPrefixMap().
func (*PartialMatchImpl) GetBoundSargableAliases ¶
func (p *PartialMatchImpl) GetBoundSargableAliases() map[values.CorrelationIdentifier]struct{}
GetBoundSargableAliases returns the sargable aliases that have non-empty parameter bindings. Ports Java's PartialMatch.getBoundSargableAliases.
func (*PartialMatchImpl) GetCandidateRef ¶
func (p *PartialMatchImpl) GetCandidateRef() *expressions.Reference
GetCandidateRef returns the expression reference on the match candidate side. Mirrors Java's PartialMatch.getCandidateRef().
func (*PartialMatchImpl) GetCompensatedAliases ¶
func (p *PartialMatchImpl) GetCompensatedAliases() map[values.CorrelationIdentifier]struct{}
GetCompensatedAliases returns the set of quantifier aliases that this partial match compensates for. Ports Java's PartialMatch.getCompensatedAliases.
func (*PartialMatchImpl) GetMatchCandidate ¶
func (p *PartialMatchImpl) GetMatchCandidate() MatchCandidate
GetMatchCandidate returns the match candidate this partial match was established against. Satisfies the PartialMatch interface.
func (*PartialMatchImpl) GetMatchInfo ¶
func (p *PartialMatchImpl) GetMatchInfo() MatchInfo
GetMatchInfo returns the match information. Satisfies the PartialMatch interface.
func (*PartialMatchImpl) GetMatchedQuantifiers ¶
func (p *PartialMatchImpl) GetMatchedQuantifiers() []expressions.Quantifier
GetMatchedQuantifiers returns the query expression's quantifiers that have child partial matches in the match info. Ports Java's PartialMatch.getMatchedQuantifiers().
func (*PartialMatchImpl) GetQueryExpression ¶
func (p *PartialMatchImpl) GetQueryExpression() expressions.RelationalExpression
GetQueryExpression returns the expression on the query graph side. Mirrors Java's PartialMatch.getQueryExpression().
func (*PartialMatchImpl) GetQueryRef ¶
func (p *PartialMatchImpl) GetQueryRef() *expressions.Reference
GetQueryRef returns the expression reference on the query graph side. Mirrors Java's PartialMatch.getQueryRef().
func (*PartialMatchImpl) GetRegularMatchInfo ¶
func (p *PartialMatchImpl) GetRegularMatchInfo() *RegularMatchInfo
GetRegularMatchInfo delegates to matchInfo.GetRegularMatchInfo(). Mirrors Java's PartialMatch.getRegularMatchInfo().
func (*PartialMatchImpl) GetUnmatchedQuantifiers ¶
func (p *PartialMatchImpl) GetUnmatchedQuantifiers() []expressions.Quantifier
GetUnmatchedQuantifiers returns the query expression's quantifiers that do NOT have child partial matches. Ports Java's PartialMatch.getUnmatchedQuantifiers().
func (*PartialMatchImpl) PullUp ¶
func (p *PartialMatchImpl) PullUp(candidateAlias values.CorrelationIdentifier) *PullUp
PullUp computes the PullUp chain for this partial match from the candidate side. The rangedOverAliases are the candidate-side quantifier aliases (targets in the binding alias map). Ports Java's PartialMatch.pullUp(candidateAlias). PullUp creates the PullUp for this match from the MaxMatchMap's candidate value and the binding alias map's target aliases. Java's PartialMatch.pullUp delegates to nestPullUp which walks through the candidate expression hierarchy; the flat construction is equivalent for non-adjusted matches (the common case).
func (*PartialMatchImpl) String ¶
func (p *PartialMatchImpl) String() string
String returns "ExprTypeName[CandidateName]", mirroring Java's PartialMatch.toString(). Uses the Go type name of the query expression (without package prefix) as the expression type name.
type PartitionBinarySelectRule ¶
type PartitionBinarySelectRule struct {
// contains filtered or unexported fields
}
PartitionBinarySelectRule handles the special case of a SelectExpression with exactly 2 quantifiers. It rearranges predicates so that each predicate is evaluated at its leftmost possible position, creating sub-SelectExpressions that absorb predicates that can be pushed down.
For each ordering (left, right) and (right, left), the rule attempts to push predicates toward the "left" side (which will become the outer of a nested loop join). Join predicates (referencing both sides) go to the right side (inner), since the left must be planned first. This creates a correlation from right to left, forcing the right side to be planned as the inner of a nested-loop join.
Three cases:
- One leg is correlated to the other — the correlated-to leg must be planned as the outer. The rule only produces the valid ordering.
- No correlation but join predicates — predicates are pushed to one side, creating a new correlation. Both orderings are explored.
- Completely independent — predicates go to whichever side they correlate to. Both orderings are explored (producing equivalent results).
The rule fires twice per pair of quantifiers (once for each assignment of left/right), since it matches quantifiers via exactlyInAnyOrder. Go implements this by iterating over both orderings explicitly.
Ports Java's PartitionBinarySelectRule (ExplorationCascadesRule).
func NewPartitionBinarySelectRule ¶
func NewPartitionBinarySelectRule() *PartitionBinarySelectRule
func (*PartitionBinarySelectRule) Matcher ¶
func (r *PartitionBinarySelectRule) Matcher() matching.BindingMatcher
func (*PartitionBinarySelectRule) OnMatch ¶
func (r *PartitionBinarySelectRule) OnMatch(call *ExpressionRuleCall)
type PartitionSelectRule ¶
type PartitionSelectRule struct {
// contains filtered or unexported fields
}
PartitionSelectRule splits a SelectExpression with N >= 3 quantifiers into two levels: a lower SelectExpression containing a subset of the quantifiers (the "lower" partition) and an upper SelectExpression containing the remaining quantifiers plus a new ForEach quantifier over the lower Select. Predicates are classified by their correlations and distributed to the level where they can be evaluated earliest.
This is the core of join enumeration in the Cascades optimizer: if a query has FROM a, b, c WHERE a.x = b.x AND b.y = c.y, this rule partitions the quantifiers into connected components (a,b and b,c share predicates so they form one component — or the rule explores every possible bipartition and lets cost decide).
The rule fires once per distinct bipartition of the quantifier set. Each firing produces at most one yield — the upper SelectExpression. Convergence is guaranteed because each yielded expression has strictly fewer quantifiers at the top level than the input.
Ports Java's PartitionSelectRule (ExplorationCascadesRule).
func NewPartitionSelectRule ¶
func NewPartitionSelectRule() *PartitionSelectRule
func (*PartitionSelectRule) Matcher ¶
func (r *PartitionSelectRule) Matcher() matching.BindingMatcher
func (*PartitionSelectRule) OnMatch ¶
func (r *PartitionSelectRule) OnMatch(call *ExpressionRuleCall)
type PlanContext ¶
type PlanContext interface {
// GetPlannerConfiguration returns the planner's configuration —
// flag bag that controls per-feature planning behaviour (use
// covering indexes, allow filter-pushdown, etc.).
GetPlannerConfiguration() PlannerConfiguration
// GetMatchCandidates returns the set of match candidates available
// for index-pushdown rules — one per index plus the primary scan,
// built by plan_context_builder.go from the store's metadata.
// EmptyPlanContext returns none (rule unit tests).
GetMatchCandidates() []MatchCandidate
// GetPrimaryKeyColumns returns the primary key column names for
// a given record type. Returns nil if the record type has no
// explicit PK (defaults to synthetic PK).
GetPrimaryKeyColumns(recordType string) []string
}
PlanContext is the planner's context object — passed to every CascadesRule.OnMatch invocation, holds the static metadata about a record store the rule needs (planner config, available match candidates such as indexes, etc.).
Ports the surface of Java's `com.apple.foundationdb.record.query.plan.cascades.PlanContext`: PlannerConfiguration mirrors the consulted subset of Java's `RecordQueryPlannerConfiguration`, and MatchCandidate the per-candidate (typically per-index) metadata.
func EmptyPlanContext ¶
func EmptyPlanContext() PlanContext
EmptyPlanContext returns the no-info PlanContext singleton. Equivalent to Java's `PlanContext.emptyContext()`.
func NewPlanContextFromIndexDefs ¶
func NewPlanContextFromIndexDefs(defs []IndexDef) PlanContext
NewPlanContextFromIndexDefs builds a PlanContext with one ValueIndexScanMatchCandidate per index definition. Column names are upper-cased for SQL-convention case-insensitive matching (FieldValue.Field is upper-cased by the SQL resolver).
func NewPlanContextFromMatchCandidates ¶
func NewPlanContextFromMatchCandidates(candidates []MatchCandidate) PlanContext
NewPlanContextFromMatchCandidates builds a PlanContext from pre-built MatchCandidates. Use this when you have a mix of ValueIndexScan and AggregateIndex candidates.
type PlanPartition ¶
type PlanPartition struct {
// contains filtered or unexported fields
}
PlanPartition groups physical-plan wrapper expressions that share common partitioning property values. Ports Java's PlanPartition.
func FilterPlanPartitions ¶
func FilterPlanPartitions(partitions []*PlanPartition, pred func(*PlanPartition) bool) []*PlanPartition
FilterPlanPartitions returns partitions that satisfy the predicate. Ports Java's PlanPartitionMatchers.filterPlanPartitions.
func NewPlanPartition ¶
func NewPlanPartition( partitionProps properties.PropertyMap, exprProps map[expressions.RelationalExpression]properties.PropertyMap, ) *PlanPartition
NewPlanPartition creates a partition from property maps.
func RollUpPlanPartitions ¶
func RollUpPlanPartitions(partitions []*PlanPartition, interestingProps ...*properties.ExpressionProperty) []*PlanPartition
RollUpPlanPartitions merges partitions by retaining only the specified interesting properties as partition keys.
func SelectMinCostPartition ¶
func SelectMinCostPartition(partitions []*PlanPartition) *PlanPartition
SelectMinCostPartition returns the partition whose first expression has the lowest estimated cost. Ties broken by first occurrence. Returns nil if partitions is empty. Ports Java's ExpressionPartitionMatchers.argmin (simplified).
func ToPlanPartitions ¶
func ToPlanPartitions(ref *expressions.Reference) []*PlanPartition
ToPlanPartitions computes plan partitions for a Reference by reading the pre-computed PlanPropertiesMap (set during PLANNING phase).
func WhereDistinct ¶
func WhereDistinct(partitions []*PlanPartition) []*PlanPartition
WhereDistinct returns partitions where DistinctRecords is true.
func WhereOrdered ¶
func WhereOrdered(partitions []*PlanPartition) []*PlanPartition
WhereOrdered returns partitions that have a known ordering.
func WhereStored ¶
func WhereStored(partitions []*PlanPartition) []*PlanPartition
WhereStored returns partitions where StoredRecord is true.
func (*PlanPartition) GetExpressionPropertyValue ¶
func (p *PlanPartition) GetExpressionPropertyValue( expr expressions.RelationalExpression, prop *properties.ExpressionProperty, ) any
GetExpressionPropertyValue returns a per-expression property value.
func (*PlanPartition) GetExpressions ¶
func (p *PlanPartition) GetExpressions() []expressions.RelationalExpression
GetExpressions returns the wrapper expressions in this partition.
func (*PlanPartition) GetOrdering ¶
func (p *PlanPartition) GetOrdering() properties.Ordering
GetOrdering returns the Ordering from the first expression in this partition. Per-expression property — not a partitioning dimension. For precise ordering, use GetExpressionPropertyValue on individual expressions.
func (*PlanPartition) GetPartitionPropertiesMap ¶
func (p *PlanPartition) GetPartitionPropertiesMap() properties.PropertyMap
GetPartitionPropertiesMap returns the full partitioning property map.
func (*PlanPartition) GetPartitionPropertyValue ¶
func (p *PlanPartition) GetPartitionPropertyValue(prop *properties.ExpressionProperty) any
GetPartitionPropertyValue returns the partitioning property value for partitioning properties (DistinctRecords, StoredRecord). For non-partitioning properties (Ordering, PrimaryKey), returns the value from the first expression.
func (*PlanPartition) GetPlans ¶
func (p *PlanPartition) GetPlans() []plans.RecordQueryPlan
GetPlans returns the underlying RecordQueryPlans, in the same order as GetExpressions. plans[i] corresponds to exprs[i].
func (*PlanPartition) HasPrimaryKey ¶
func (p *PlanPartition) HasPrimaryKey() bool
HasPrimaryKey returns true if ANY expression in this partition has a non-nil PrimaryKey property. Per-expression property — not a partitioning dimension.
func (*PlanPartition) IsDistinct ¶
func (p *PlanPartition) IsDistinct() bool
IsDistinct returns true if the partition's DistinctRecords is true.
func (*PlanPartition) IsStoredRecord ¶
func (p *PlanPartition) IsStoredRecord() bool
IsStoredRecord returns true if the partition's StoredRecord is true.
type PlanPropertiesMap ¶
type PlanPropertiesMap struct {
// contains filtered or unexported fields
}
PlanPropertiesMap stores computed property values for each physical-plan wrapper expression in a Reference's final members.
func GetRefPlanPropertiesMap ¶
func GetRefPlanPropertiesMap(ref *expressions.Reference) *PlanPropertiesMap
GetRefPlanPropertiesMap retrieves the PlanPropertiesMap from a Reference, or nil if not yet computed.
func NewPlanPropertiesMap ¶
func NewPlanPropertiesMap() *PlanPropertiesMap
NewPlanPropertiesMap creates a new empty properties map.
func (*PlanPropertiesMap) Add ¶
func (m *PlanPropertiesMap) Add(w physicalPlanExpression)
Add computes and stores properties for the given physical wrapper.
func (*PlanPropertiesMap) All ¶
func (m *PlanPropertiesMap) All() map[expressions.RelationalExpression]properties.PropertyMap
All returns the full underlying map. Callers that need deterministic iteration should use Expressions() and GetProperties() instead.
func (*PlanPropertiesMap) Expressions ¶
func (m *PlanPropertiesMap) Expressions() []expressions.RelationalExpression
Expressions returns all wrapper expressions in insertion order.
func (*PlanPropertiesMap) GetProperties ¶
func (m *PlanPropertiesMap) GetProperties(expr expressions.RelationalExpression) properties.PropertyMap
GetProperties returns the computed properties for a wrapper expression.
type Planner ¶
type Planner struct {
// MaxTasks caps the total tasks executed before the planner
// gives up (returns the partial result). Defaults to 100_000.
// Hitting the cap is a strong signal of a non-terminating rule —
// callers should report.
MaxTasks int
// contains filtered or unexported fields
}
Planner is the task-stack driven cascades planner.
The Java equivalent is `CascadesPlanner` — a task-stack driver over two phases (REWRITING → PLANNING) that explores the expression DAG bottom-up (leaves fire rules first, ancestors after), tracks per-Reference exploration rounds for convergence, and fires rules at per-(group, expression, rule) task granularity. Plan() drives both phases and extracts the cost-cheapest plan via properties.ExtractBestPlanFromSelector.
Convergence: a Reference whose member set stops growing is committed (Reference.CommitExploration); the stack drains; the planner returns. A hard cap (MaxTasks) prevents pathological non-termination from rule-yielding-fresh-members loops; default 100_000.
The planner is single-threaded (Java's is too).
func NewPlanner ¶
func NewPlanner(rules []ExpressionRule, ctx PlanContext) *Planner
NewPlanner builds a planner with the given rule set + context. Pass DefaultExpressionRules() for the standard rule set.
Pass nil ctx to use the empty PlanContext.
func (*Planner) BestMember ¶
func (p *Planner) BestMember(ref *expressions.Reference) expressions.RelationalExpression
BestMember returns the OPTIMIZE-chosen best member for `ref`, or nil if the Reference wasn't optimized. Delegates to the per-properties winner map (NoProperties = cheapest overall).
func (*Planner) HasBestMember ¶
func (p *Planner) HasBestMember(ref *expressions.Reference) bool
HasBestMember reports whether a winner exists for `ref`.
func (*Planner) Memo ¶
Memo returns the planner's Memo structure. Available after Plan has been called (returns nil before that).
func (*Planner) Plan ¶
func (p *Planner) Plan(rootRef *expressions.Reference) (expressions.RelationalExpression, int, error)
Plan runs the unified two-phase REWRITING → PLANNING pipeline and returns the cost-cheapest extracted plan tree.
Pushes InitiatePlannerPhaseTask{PhaseRewriting} which chains to PhasePlanning via the unified task types (ExploreGroupTask, TransformExprTask, TransformImplTask, OptimizeGroupTask, OptimizeInputsTask). After the stack drains, extracts the best plan via properties.ExtractBestPlanFromSelector.
Returns:
- plan: the extracted RelationalExpression; nil if rootRef is empty.
- tasks: total tasks executed across both phases.
- err: nil on success; ErrPlannerCapHit if EXPLORE hit MaxTasks (no OPTIMIZE attempted); extraction error otherwise.
func (*Planner) Statistics ¶
func (p *Planner) Statistics() properties.StatisticsProvider
Statistics returns the planner's statistics provider, or nil if none set.
func (*Planner) WithCostModel ¶
func (p *Planner) WithCostModel(less func(a, b expressions.RelationalExpression) bool) *Planner
WithCostModel sets the comparator used by OptimizeGroupTask. Use RewritingCostModelLess for the REWRITING phase, PlanningCostModelLess for the PLANNING phase. Matches Java's per-phase cost model. Returns p.
func (*Planner) WithImplementationRules ¶
func (p *Planner) WithImplementationRules(rules []ImplementationRule) *Planner
WithImplementationRules adds rules for PhasePlanning. These run after the REWRITING phase converges. Returns p for chaining.
func (*Planner) WithMaxTasks ¶
WithMaxTasks overrides the task cap. Returns p for chaining.
func (*Planner) WithPlanningExpressionRules ¶
func (p *Planner) WithPlanningExpressionRules(rules []ExpressionRule) *Planner
WithPlanningExpressionRules adds ExpressionRules that fire during PLANNING's bottom-up implementation pass. Unlike EXPLORE-phase expression rules (which yield to members via Insert), these yield to finalMembers via InsertFinal: physical scan/filter/agg wrappers are produced during PLANNING, where constraint and ordering information is available. Production passes BatchAExpressionRules.
func (*Planner) WithStatistics ¶
func (p *Planner) WithStatistics(stats properties.StatisticsProvider) *Planner
WithStatistics sets the table-level cardinality statistics for the cost model. Stats flow through EstimateCost and HintCost to give scan/index wrappers real cardinality instead of the default 1e6 constant. Replaces the cost model — call after WithCostModel if both are used.
type PlannerConfiguration ¶
type PlannerConfiguration struct {
// AllowDuplicateProjections — when true, a projection can carry
// the same Value twice (a SQL planner concession; the executor
// handles the duplicate emission). False by default; matches
// Java's `RecordQueryPlannerConfiguration.allowDuplicateProjections`.
AllowDuplicateProjections bool
// AttemptFailedInJoinAsUnionMaxSize controls when InUnionRule falls
// back from InJoin to InUnion. Java default is 0 (no fallback).
AttemptFailedInJoinAsUnionMaxSize int
// ShouldJoinRightDeep — when true, PartitionSelectRule only
// produces right-deep join trees (the upper partition has exactly
// 1 quantifier). This reduces join enumeration combinatorics at the
// cost of excluding bushy plans. Mirrors Java's
// RecordQueryPlannerConfiguration.shouldJoinRightDeep().
ShouldJoinRightDeep bool
// ShouldDeferCrossProducts — when true, PartitionSelectRule only
// partitions along independent quantifier boundaries (cross-product
// splits). Partitions that would split connected components are
// deferred until the components are individually partitioned into
// smaller pieces. Mirrors Java's
// RecordQueryPlannerConfiguration.shouldDeferCrossProducts().
ShouldDeferCrossProducts bool
}
PlannerConfiguration mirrors the subset of Java's `RecordQueryPlannerConfiguration` that rules actually consult. As further config-driven rules port, fields land here in step with their consumers.
func DefaultPlannerConfiguration ¶
func DefaultPlannerConfiguration() PlannerConfiguration
DefaultPlannerConfiguration mirrors Java's `RecordQueryPlannerConfiguration.defaultPlannerConfiguration()`.
type PlannerConstraint ¶
type PlannerConstraint[T any] struct { // contains filtered or unexported fields }
PlannerConstraint is a typed key for constraints that flow between rules during the PLANNING phase. Rules read constraints set by their parent and push constraints to child References.
Ports Java's PlannerConstraint.
type PlannerPhase ¶
type PlannerPhase int
PlannerPhase drives the multi-phase planning lifecycle. Java's CascadesPlanner runs REWRITING first (exploration rules, RewritingCostModel), then PLANNING (implementation rules, PlanningCostModel). Each phase has its own rule set and cost model.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.PlannerPhase.
const ( PhaseRewriting PlannerPhase = iota PhasePlanning )
func (PlannerPhase) HasNextPhase ¶
func (p PlannerPhase) HasNextPhase() bool
HasNextPhase reports whether there is a subsequent phase.
func (PlannerPhase) NextPhase ¶
func (p PlannerPhase) NextPhase() PlannerPhase
NextPhase returns the phase that follows this one. PhasePlanning is terminal (panics if called).
func (PlannerPhase) String ¶
func (p PlannerPhase) String() string
func (PlannerPhase) TargetStage ¶
func (p PlannerPhase) TargetStage() expressions.PlannerStage
TargetStage returns the PlannerStage that References should reach after this phase completes. Mirrors Java's PlannerPhase.getTargetPlannerStage().
type PredicateCompensation ¶
type PredicateCompensation func( partialMatch PartialMatch, boundParameterPrefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, pullUp *PullUp, ) PredicateCompensationFunc
PredicateCompensation is the functional interface for computing a PredicateCompensationFunction from a partial match context. Ports Java's PredicateMultiMap.PredicateCompensation.
func DefaultPredicateCompensation ¶
func DefaultPredicateCompensation() PredicateCompensation
DefaultPredicateCompensation returns a PredicateCompensation that always yields no compensation needed. This is the default used by Java's PredicateMapping.Builder.
type PredicateCompensationFunc ¶
type PredicateCompensationFunc interface {
IsNeeded() bool
IsImpossible() bool
// Amend recreates the compensation function with updated aggregate
// value mappings. Used during intersection of compensations when
// aggregates are finalized. Returns a new function (or self if
// no change needed).
//
// unmatchedAggregateMap: BiMap of unmatched aggregate aliases → values
// amendedMatchedAggregateMap: mapping of old values → new values
//
// Ports Java's PredicateCompensationFunction.amend.
Amend(
unmatchedAggregateMap *BiMap[values.CorrelationIdentifier, values.Value],
amendedMatchedAggregateMap map[values.Value]values.Value,
) PredicateCompensationFunc
// ApplyCompensationForPredicate applies this compensation by
// translating correlation references via the translation map and
// returning the set of predicates that must be injected above the
// matched candidate scan.
//
// Ports Java's PredicateCompensationFunction.applyCompensationForPredicate.
ApplyCompensationForPredicate(translationMap TranslationMap) []predicates.QueryPredicate
}
PredicateCompensationFunc represents the result of computing predicate compensation — whether compensation is needed, impossible, or what predicates to apply. Ports Java's PredicateMultiMap.PredicateCompensationFunction.
func ImpossiblePredicateCompensation ¶
func ImpossiblePredicateCompensation() PredicateCompensationFunc
ImpossiblePredicateCompensation returns a PredicateCompensationFunc indicating compensation is needed but impossible.
func NoPredicateCompensationNeeded ¶
func NoPredicateCompensationNeeded() PredicateCompensationFunc
NoPredicateCompensationNeeded returns a PredicateCompensationFunc indicating no compensation is required.
func OfPredicateCompensation ¶
func OfPredicateCompensation(pred predicates.QueryPredicate, shouldSimplifyValues bool) PredicateCompensationFunc
OfPredicateCompensation creates a PredicateCompensationFunc that wraps a query predicate. When applied, it translates the predicate through the translation map and returns it for injection as a residual filter. Ports Java's PredicateCompensationFunction.ofPredicate.
type PredicateCompensationMap ¶
type PredicateCompensationMap struct {
// contains filtered or unexported fields
}
PredicateCompensationMap maps query predicates to compensation functions using identity-based keying (pointer equality). Ports Java's LinkedIdentityMap<QueryPredicate, PredicateCompensationFunction>.
func EmptyPredicateCompensationMap ¶
func EmptyPredicateCompensationMap() *PredicateCompensationMap
EmptyPredicateCompensationMap returns an empty predicate compensation map.
func NewPredicateCompensationMap ¶
func NewPredicateCompensationMap(keys []predicates.QueryPredicate, vals []PredicateCompensationFunc) *PredicateCompensationMap
NewPredicateCompensationMap creates a PredicateCompensationMap from parallel slices of predicates and compensation functions.
func StubPredicateCompensationMap ¶
func StubPredicateCompensationMap(n int) *PredicateCompensationMap
StubPredicateCompensationMap creates a PredicateCompensationMap with N no-op entries. Used by tests that need a non-empty map to drive IsNeeded/IsNeededForFiltering without real predicate content.
func (*PredicateCompensationMap) Amend ¶
func (m *PredicateCompensationMap) Amend( unmatchedAggregateMap *BiMap[values.CorrelationIdentifier, values.Value], amendedMatchedAggregateMap map[values.Value]values.Value, ) *PredicateCompensationMap
Amend creates a new PredicateCompensationMap with all compensation functions amended. Ports the amend loop in Java's Compensation.ForMatch.intersect.
func (*PredicateCompensationMap) ApplyCompensations ¶
func (m *PredicateCompensationMap) ApplyCompensations(tm TranslationMap) []predicates.QueryPredicate
ApplyCompensations applies all compensation functions in this map via the given translation map and returns the collected residual predicates. Ports the iteration in Java's ForMatch.apply().
func (*PredicateCompensationMap) Entries ¶
func (m *PredicateCompensationMap) Entries() ([]predicates.QueryPredicate, []PredicateCompensationFunc)
Entries returns the predicate→compensation pairs in insertion order.
func (*PredicateCompensationMap) Get ¶
func (m *PredicateCompensationMap) Get(key predicates.QueryPredicate) PredicateCompensationFunc
Get returns the compensation function for the given predicate key using identity (pointer) comparison. Returns nil if not found. Mirrors Java's LinkedIdentityMap.get().
func (*PredicateCompensationMap) IsEmpty ¶
func (m *PredicateCompensationMap) IsEmpty() bool
IsEmpty reports whether the map has no entries.
func (*PredicateCompensationMap) Len ¶
func (m *PredicateCompensationMap) Len() int
Len returns the number of entries in the map.
type PredicateMap ¶
type PredicateMap struct {
PredicateMultiMap
}
PredicateMap is a PredicateMultiMap that enforces the constraint that each query predicate maps to at most one candidate predicate mapping. Ports Java's PredicateMap.
func EmptyPredicateMap ¶
func EmptyPredicateMap() *PredicateMap
EmptyPredicateMap returns an empty PredicateMap.
func (*PredicateMap) GetMappingOptional ¶
func (m *PredicateMap) GetMappingOptional(pred predicates.QueryPredicate) (*PredicateMapping, bool)
GetMappingOptional returns the single mapping for the given predicate, or nil/false if the predicate has no mapping or has more than one. Mirrors Java's PredicateMap.getMappingOptional().
type PredicateMapBuilder ¶
type PredicateMapBuilder struct {
PredicateMultiMapBuilder
}
PredicateMapBuilder builds a PredicateMap, enforcing uniqueness. Ports Java's PredicateMap.Builder.
func NewPredicateMapBuilder ¶
func NewPredicateMapBuilder() *PredicateMapBuilder
NewPredicateMapBuilder creates a new empty PredicateMapBuilder.
func (*PredicateMapBuilder) Build ¶
func (b *PredicateMapBuilder) Build() *PredicateMap
Build constructs the PredicateMap. Panics if there are conflicts or non-unique mappings.
func (*PredicateMapBuilder) BuildMaybe ¶
func (b *PredicateMapBuilder) BuildMaybe() *PredicateMap
BuildMaybe constructs the PredicateMap, returning nil if there are conflicts or non-unique mappings.
type PredicateMapping ¶
type PredicateMapping struct {
// contains filtered or unexported fields
}
PredicateMapping maps a query predicate to a candidate predicate along with associated compensation, parameter binding, comparison range, constraint, and translated predicate.
Ports Java's PredicateMultiMap.PredicateMapping.
func (*PredicateMapping) GetCandidatePredicate ¶
func (m *PredicateMapping) GetCandidatePredicate() predicates.QueryPredicate
GetCandidatePredicate returns the candidate predicate.
func (*PredicateMapping) GetComparisonRange ¶
func (m *PredicateMapping) GetComparisonRange() *predicates.ComparisonRange
GetComparisonRange returns the comparison range, or nil if none.
func (*PredicateMapping) GetConstraint ¶
func (m *PredicateMapping) GetConstraint() *QueryPlanConstraint
GetConstraint returns the query plan constraint.
func (*PredicateMapping) GetMappingKey ¶
func (m *PredicateMapping) GetMappingKey() MappingKey
GetMappingKey returns the full mapping key.
func (*PredicateMapping) GetMappingKind ¶
func (m *PredicateMapping) GetMappingKind() MappingKind
GetMappingKind returns the mapping kind.
func (*PredicateMapping) GetOriginalQueryPredicate ¶
func (m *PredicateMapping) GetOriginalQueryPredicate() predicates.QueryPredicate
GetOriginalQueryPredicate returns the original query predicate.
func (*PredicateMapping) GetParameterAlias ¶
func (m *PredicateMapping) GetParameterAlias() *values.CorrelationIdentifier
GetParameterAlias returns the parameter alias, or nil if none.
func (*PredicateMapping) GetPredicateCompensation ¶
func (m *PredicateMapping) GetPredicateCompensation() PredicateCompensation
GetPredicateCompensation returns the predicate compensation function.
func (*PredicateMapping) GetTranslatedQueryPredicate ¶
func (m *PredicateMapping) GetTranslatedQueryPredicate() predicates.QueryPredicate
GetTranslatedQueryPredicate returns the translated query predicate.
func (*PredicateMapping) ToBuilder ¶
func (m *PredicateMapping) ToBuilder() *PredicateMappingBuilder
ToBuilder returns a PredicateMappingBuilder pre-seeded with this mapping's values. Mirrors Java's PredicateMapping.toBuilder().
func (*PredicateMapping) WithTranslatedQueryPredicate ¶
func (m *PredicateMapping) WithTranslatedQueryPredicate(translated predicates.QueryPredicate) *PredicateMapping
WithTranslatedQueryPredicate returns a copy of this mapping with the translated query predicate replaced. Mirrors Java's PredicateMapping.withTranslatedQueryPredicate().
type PredicateMappingBuilder ¶
type PredicateMappingBuilder struct {
// contains filtered or unexported fields
}
PredicateMappingBuilder builds a PredicateMapping. Ports Java's PredicateMultiMap.PredicateMapping.Builder.
func OrTermMappingBuilder ¶
func OrTermMappingBuilder( originalQueryPredicate predicates.QueryPredicate, translatedQueryPredicate predicates.QueryPredicate, candidatePredicate predicates.QueryPredicate, ) *PredicateMappingBuilder
OrTermMappingBuilder creates a PredicateMappingBuilder for an OR-term mapping. Mirrors Java's PredicateMapping.orTermMappingBuilder().
func RegularMappingBuilder ¶
func RegularMappingBuilder( originalQueryPredicate predicates.QueryPredicate, translatedQueryPredicate predicates.QueryPredicate, candidatePredicate predicates.QueryPredicate, ) *PredicateMappingBuilder
RegularMappingBuilder creates a PredicateMappingBuilder for a regular (non-OR-term) mapping. Mirrors Java's PredicateMapping.regularMappingBuilder().
func (*PredicateMappingBuilder) Build ¶
func (b *PredicateMappingBuilder) Build() *PredicateMapping
Build constructs the PredicateMapping.
func (*PredicateMappingBuilder) SetComparisonRange ¶
func (b *PredicateMappingBuilder) SetComparisonRange(cr *predicates.ComparisonRange) *PredicateMappingBuilder
SetComparisonRange sets the comparison range.
func (*PredicateMappingBuilder) SetConstraint ¶
func (b *PredicateMappingBuilder) SetConstraint(c *QueryPlanConstraint) *PredicateMappingBuilder
SetConstraint sets the query plan constraint.
func (*PredicateMappingBuilder) SetParameterAlias ¶
func (b *PredicateMappingBuilder) SetParameterAlias(alias values.CorrelationIdentifier) *PredicateMappingBuilder
SetParameterAlias sets the parameter alias.
func (*PredicateMappingBuilder) SetPredicateCompensation ¶
func (b *PredicateMappingBuilder) SetPredicateCompensation(c PredicateCompensation) *PredicateMappingBuilder
SetPredicateCompensation sets the predicate compensation function.
func (*PredicateMappingBuilder) SetSargable ¶
func (b *PredicateMappingBuilder) SetSargable( alias values.CorrelationIdentifier, cr *predicates.ComparisonRange, ) *PredicateMappingBuilder
SetSargable sets both the parameter alias and comparison range. Mirrors Java's Builder.setSargable().
func (*PredicateMappingBuilder) SetTranslatedQueryPredicate ¶
func (b *PredicateMappingBuilder) SetTranslatedQueryPredicate(p predicates.QueryPredicate) *PredicateMappingBuilder
SetTranslatedQueryPredicate sets the translated query predicate.
type PredicateMultiMap ¶
type PredicateMultiMap struct {
// contains filtered or unexported fields
}
PredicateMultiMap maps query predicates to sets of candidate predicate mappings. Uses identity-based keying (pointer equality) for predicates, matching Java's LinkedIdentityMap semantics.
The zero value is a valid, empty PredicateMultiMap.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.PredicateMultiMap.
func (*PredicateMultiMap) Entries ¶
func (m *PredicateMultiMap) Entries() []struct { Predicate predicates.QueryPredicate Mapping *PredicateMapping }
Entries returns all (predicate, mapping) pairs in insertion order. Each predicate may appear once; each entry may have multiple mappings.
func (*PredicateMultiMap) Get ¶
func (m *PredicateMultiMap) Get(pred predicates.QueryPredicate) []*PredicateMapping
Get returns the mappings for the given query predicate, or nil if the predicate is not in the map. Uses identity (pointer) equality.
func (*PredicateMultiMap) KeySet ¶
func (m *PredicateMultiMap) KeySet() []predicates.QueryPredicate
KeySet returns the distinct query predicates in insertion order.
func (*PredicateMultiMap) PredicateCount ¶
func (m *PredicateMultiMap) PredicateCount() int
PredicateCount returns the number of distinct predicates in the map.
func (*PredicateMultiMap) Size ¶
func (m *PredicateMultiMap) Size() int
Size returns the total number of mappings across all predicates.
func (*PredicateMultiMap) Values ¶
func (m *PredicateMultiMap) Values() []*PredicateMapping
Values returns all mappings across all predicates, in insertion order.
type PredicateMultiMapBuilder ¶
type PredicateMultiMapBuilder struct {
// contains filtered or unexported fields
}
PredicateMultiMapBuilder builds a PredicateMultiMap. Ports Java's PredicateMultiMap.Builder.
func NewPredicateMultiMapBuilder ¶
func NewPredicateMultiMapBuilder() *PredicateMultiMapBuilder
NewPredicateMultiMapBuilder creates a new empty builder.
func (*PredicateMultiMapBuilder) Build ¶
func (b *PredicateMultiMapBuilder) Build() *PredicateMultiMap
Build constructs the PredicateMultiMap. Panics if there are conflicts (a candidate predicate mapped from multiple query predicates). Mirrors Java's Builder.build().
func (*PredicateMultiMapBuilder) BuildMaybe ¶
func (b *PredicateMultiMapBuilder) BuildMaybe() *PredicateMultiMap
BuildMaybe constructs the PredicateMultiMap, returning nil if there are conflicts. Mirrors Java's Builder.buildMaybe().
func (*PredicateMultiMapBuilder) Put ¶
func (b *PredicateMultiMapBuilder) Put( queryPredicate predicates.QueryPredicate, mapping *PredicateMapping, ) bool
Put adds a mapping for the given query predicate. Returns true if the mapping was actually added (not a duplicate).
func (*PredicateMultiMapBuilder) PutAll ¶
func (b *PredicateMultiMapBuilder) PutAll(other *PredicateMultiMap) bool
PutAll adds all entries from an existing PredicateMultiMap. Returns true if any mapping was added.
func (*PredicateMultiMapBuilder) PutAllMappings ¶
func (b *PredicateMultiMapBuilder) PutAllMappings( queryPredicate predicates.QueryPredicate, mappings []*PredicateMapping, ) bool
PutAllMappings adds all mappings for a single query predicate. Returns true if any mapping was added.
type PredicatePushDownRule ¶
type PredicatePushDownRule struct {
// contains filtered or unexported fields
}
PredicatePushDownRule pushes predicates from an outer SelectExpression into its child quantifiers when the predicate only references a single child's aliases. This is the generic predicate push-down rule intended for the REWRITING phase — it handles arbitrary SelectExpression shapes, unlike the specific Push*Through* rules which target Filter/Projection/Sort/etc.
Algorithm:
- Match SelectExpression.
- For each ForEach quantifier, identify predicates that can be pushed — those whose correlation set has no overlap with any OTHER quantifier's alias.
- For each pushable-predicate + quantifier pair, visit the child expression through the quantifier's Reference and create a new expression with the predicate absorbed or pushed through.
- Build a new outer SelectExpression with the remaining (non-pushed) predicates and the rewritten quantifiers.
Existential quantifiers are handled correctly: the per-quantifier loop skips non-ForEach quantifiers, so predicates are only pushed into ForEach children. Existential siblings remain untouched. Matches Java's behavior (no global existential guard).
Convergence: each firing strictly reduces the set of pushable predicates in the outer SelectExpression. A SelectExpression with no pushable predicates causes zero yields.
Ports Java's PredicatePushDownRule (ExplorationCascadesRule, 444 LOC).
func NewPredicatePushDownRule ¶
func NewPredicatePushDownRule() *PredicatePushDownRule
func (*PredicatePushDownRule) Matcher ¶
func (r *PredicatePushDownRule) Matcher() matching.BindingMatcher
func (*PredicatePushDownRule) OnMatch ¶
func (r *PredicatePushDownRule) OnMatch(call *ExpressionRuleCall)
type PredicateToLogicalUnionRule ¶
type PredicateToLogicalUnionRule struct {
// contains filtered or unexported fields
}
PredicateToLogicalUnionRule transforms a SelectExpression whose predicates (in CNF after NormalizePredicatesRule) contain OR terms into a DISTINCT(UNION(SELECT leg1, SELECT leg2, ...)) structure. Each union leg corresponds to one DNF term, enabling each leg to use a different index for evaluation.
The core transformation:
SELECT WHERE A AND B AND (C1 OR C2) AND (D1 OR D2)
becomes:
DISTINCT(UNION( UNIQUE(SELECT WHERE A AND B AND C1 AND D1), UNIQUE(SELECT WHERE A AND B AND C1 AND D2), UNIQUE(SELECT WHERE A AND B AND C2 AND D1), UNIQUE(SELECT WHERE A AND B AND C2 AND D2), ))
Each UNIQUE deduplicates per-leg by primary key; DISTINCT deduplicates across legs. The fixed predicates (A, B) are repeated in every leg.
Guards:
- Only fires on SelectExpressions with exactly 1 ForEach quantifier.
- Skips SelectExpressions with Existential quantifiers.
- Requires at least one non-leaf, non-atomic OR predicate.
- Respects DefaultMaxNumConjuncts to avoid combinatorial explosion.
Convergence: the output is Distinct(Union(...)), not a SelectExpression, so the rule cannot re-fire on its own output.
Ports Java's PredicateToLogicalUnionRule (a match-partition rule) as a Go ExpressionRule operating on SelectExpressions. The Go planner fires expression rules in the EXPLORE phase rather than as match-partition triggers — architecturally equivalent when combined with NormalizePredicatesRule.
func NewPredicateToLogicalUnionRule ¶
func NewPredicateToLogicalUnionRule() *PredicateToLogicalUnionRule
NewPredicateToLogicalUnionRule constructs the rule.
func (*PredicateToLogicalUnionRule) Matcher ¶
func (r *PredicateToLogicalUnionRule) Matcher() matching.BindingMatcher
func (*PredicateToLogicalUnionRule) OnMatch ¶
func (r *PredicateToLogicalUnionRule) OnMatch(call *ExpressionRuleCall)
type PrimaryScanMatchCandidate ¶
type PrimaryScanMatchCandidate struct {
// contains filtered or unexported fields
}
PrimaryScanMatchCandidate represents a match candidate backed by the primary key scan. The primary scan is always unique (the PK uniquely identifies every record).
In Java, PrimaryScanMatchCandidate implements MatchCandidate, ValueIndexLikeMatchCandidate, and WithPrimaryKeyMatchCandidate. The Go port implements MatchCandidate, WithPrimaryKeyMatchCandidate, and WithBaseQuantifierMatchCandidate.
Key distinction from ValueIndexScanMatchCandidate: the primary scan has separate "available" vs "queried" record types. Available types are all types in the store; queried types are the subset the query needs. When they differ, a TypeFilterPlan wraps the scan.
func NewPrimaryScanMatchCandidate ¶
func NewPrimaryScanMatchCandidate( traversal *Traversal, parameters []values.CorrelationIdentifier, availableRecordTypes []string, queriedRecordTypes []string, primaryKeyColumns []string, baseType values.Type, ) *PrimaryScanMatchCandidate
NewPrimaryScanMatchCandidate constructs a primary-scan match candidate.
- traversal: the Traversal of this candidate's expression tree (may be nil if not yet computed; GetTraversal will build it lazily).
- parameters: sargable aliases, one per PK column.
- availableRecordTypes: all record types in the store.
- queriedRecordTypes: the subset of types the query needs.
- primaryKeyColumns: the PK column names in order.
- baseType: the record type of the scan output.
func (*PrimaryScanMatchCandidate) CandidateName ¶
func (c *PrimaryScanMatchCandidate) CandidateName() string
CandidateName returns "primary(type1,type2,...)" using the available record types. Mirrors Java's PrimaryScanMatchCandidate.getName().
func (*PrimaryScanMatchCandidate) ComputeBoundParameterPrefixMap ¶
func (c *PrimaryScanMatchCandidate) ComputeBoundParameterPrefixMap( bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange, ) map[values.CorrelationIdentifier]*predicates.ComparisonRange
ComputeBoundParameterPrefixMap walks the sargable aliases in order and collects the longest prefix satisfying index scan discipline: N equalities + optional trailing inequality.
Identical to ValueIndexScanMatchCandidate.ComputeBoundParameterPrefixMap — mirrors Java's default MatchCandidate.computeBoundParameterPrefixMap.
func (*PrimaryScanMatchCandidate) GetAvailableRecordTypes ¶
func (c *PrimaryScanMatchCandidate) GetAvailableRecordTypes() []string
GetAvailableRecordTypes returns all record types available in the store. Mirrors Java's PrimaryScanMatchCandidate.getAvailableRecordTypes().
func (*PrimaryScanMatchCandidate) GetBaseType ¶
func (c *PrimaryScanMatchCandidate) GetBaseType() values.Type
GetBaseType returns the base record type. Implements WithBaseQuantifierMatchCandidate.
func (*PrimaryScanMatchCandidate) GetColumnNames ¶
func (c *PrimaryScanMatchCandidate) GetColumnNames() []string
GetColumnNames returns the primary key column names.
func (*PrimaryScanMatchCandidate) GetPrimaryKeyValues ¶
func (c *PrimaryScanMatchCandidate) GetPrimaryKeyValues() []values.Value
GetPrimaryKeyValues returns the primary key as a list of Values. Lazily computed from primaryKeyColumns. Returns nil if there are no PK columns. Implements WithPrimaryKeyMatchCandidate.
func (*PrimaryScanMatchCandidate) GetRecordTypes ¶
func (c *PrimaryScanMatchCandidate) GetRecordTypes() []string
GetRecordTypes returns the queried record type names. This matches Go's MatchCandidate.GetRecordTypes() contract and Java's getQueriedRecordTypeNames().
func (*PrimaryScanMatchCandidate) GetSargableAliases ¶
func (c *PrimaryScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
GetSargableAliases returns the ordered parameter list (one per PK column).
func (*PrimaryScanMatchCandidate) GetTraversal ¶
func (c *PrimaryScanMatchCandidate) GetTraversal() *Traversal
GetTraversal returns the Traversal of this candidate's expression tree, built lazily on first access via ExpandValueIndex. The traversal is stable once computed (sync.Once).
func (*PrimaryScanMatchCandidate) IsUnique ¶
func (c *PrimaryScanMatchCandidate) IsUnique() bool
IsUnique returns true — the primary key is always unique.
func (*PrimaryScanMatchCandidate) String ¶
func (c *PrimaryScanMatchCandidate) String() string
String returns a human-readable label for debugging. Mirrors Java's PrimaryScanMatchCandidate.toString().
func (*PrimaryScanMatchCandidate) ToScanPlan ¶
func (c *PrimaryScanMatchCandidate) ToScanPlan( prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, reverse bool, ) plans.RecordQueryPlan
ToScanPlan converts the matched prefix into a physical plan. If the queried record types are a strict subset of the available types (and the PK does not begin with a record-type discriminator), the scan is wrapped in a TypeFilterPlan.
Mirrors Java's PrimaryScanMatchCandidate.toEquivalentPlan(): extracts ComparisonRanges from the prefix map in PK column order and embeds them as ScanComparisons in the RecordQueryScanPlan.
type PrimaryScanRule ¶
type PrimaryScanRule struct {
// contains filtered or unexported fields
}
PrimaryScanRule implements a logical FullUnorderedScanExpression as a physical RecordQueryScanPlan.
FullUnorderedScan({records}, type) → Scan({records}, type, false)
"Implements" rules in Cascades go from logical to physical. The rule output is YIELDED into the same Reference as the logical input, so the Reference holds BOTH alternatives — the logical and the physical — and downstream rule chains operate on whichever members they pattern-match; cost extraction picks the physical (the logical has no Execute path).
The rule yields a `*plans.RecordQueryScanPlan` wrapped in a `physicalScanWrapper` (the plan/expression hierarchies are separate in Go — see physical_wrapper.go).
Java equivalent: `PrimaryScanRule`. This rule is the unindexed fallback; sargable primary-key access goes through PrimaryScanMatchCandidate on the data-access path (primary_scan_match_candidate.go).
func NewPrimaryScanRule ¶
func NewPrimaryScanRule() *PrimaryScanRule
NewPrimaryScanRule constructs the rule.
func (*PrimaryScanRule) Matcher ¶
func (r *PrimaryScanRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PrimaryScanRule) OnMatch ¶
func (r *PrimaryScanRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires on every FullUnorderedScanExpression and yields a RecordQueryScanPlan over the same record types.
type ProjectionElimRule ¶
type ProjectionElimRule struct {
// contains filtered or unexported fields
}
ProjectionElimRule eliminates a LogicalProjection whose projection list is exactly the inner Quantifier's flowed object value — i.e. `SELECT * FROM t` shapes that survive parsing but represent no computation.
Pattern:
Projection([QOV(alias)]) over QuantifierForEach(alias) over X → X
Detection: the projection list has exactly one Value, and that Value is a QuantifiedObjectValue whose CorrelationIdentifier matches the inner Quantifier's alias.
Java equivalent: the planner doesn't have a dedicated rule for this; the Memo cost model would naturally prefer the single-X member over the wrapped-in-Projection version. Seed implements it directly so the optimiser produces a concretely-simpler tree.
func NewProjectionElimRule ¶
func NewProjectionElimRule() *ProjectionElimRule
NewProjectionElimRule constructs the rule.
func (*ProjectionElimRule) Matcher ¶
func (r *ProjectionElimRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ProjectionElimRule) OnMatch ¶
func (r *ProjectionElimRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the projection is an identity over the inner quantifier; yields the inner expression directly.
type ProjectionMergeRule ¶
type ProjectionMergeRule struct {
// contains filtered or unexported fields
}
ProjectionMergeRule collapses two nested LogicalProjections into one.
Projection(P1) over Projection(P2) over X → Projection(P1) over X
The outer projection list P1 wins outright — it specifies exactly the columns the caller wants. The inner projection list P2 was already a "narrowing" pass; doing both ends up materialising columns the outer doesn't need only to throw them away.
Soundness contract: Values inside P1 are FieldValue references against the inner projection's flow, and LogicalProjection's GetResultValue returns the inner quantifier's flowed object value (the projection list is a side channel; rows pass through). So a FieldValue inside P1 logically resolves against the same row shape whether the inner projection is present or not — collapsing is safe. If projection ever narrows the row shape, this rule needs a column-substitution rewrite (see the caveat on DefaultExpressionRules).
This is more aggressive than Java's planner (which lets the cost model + cardinality estimates decide): no dedicated Java rule exists — the Memo's cost preference for fewer Projection operators emerges from physical plan choice (a fetch-only plan with the wider column list is cheaper than two stacked Projection operators). Go gets the same shape via this static rewrite.
func NewProjectionMergeRule ¶
func NewProjectionMergeRule() *ProjectionMergeRule
NewProjectionMergeRule constructs the rule.
func (*ProjectionMergeRule) Matcher ¶
func (r *ProjectionMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*ProjectionMergeRule) OnMatch ¶
func (r *ProjectionMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over another LogicalProjection; yields a flat projection wrapping the inner's inner.
type ProvidedOrderingPart ¶
type ProvidedOrderingPart struct {
Value values.Value
SortOrder ProvidedSortOrder
}
ProvidedOrderingPart is a (Value, ProvidedSortOrder) pair for a provided ordering element.
func AdjustFixedBindings ¶
func AdjustFixedBindings(parts []ProvidedOrderingPart, isReverse bool) []ProvidedOrderingPart
AdjustFixedBindings adjusts the sort order of FIXED ordering parts to match the resolved comparison direction. If the comparison is reverse, fixed parts get descending; otherwise ascending. Mirrors Java's RecordQuerySetPlan.adjustFixedBindings.
type ProvidedSortOrder ¶
type ProvidedSortOrder int
ProvidedSortOrder represents the sort direction (and NULL placement) of a provided ordering part. Mirrors Java's OrderingPart.ProvidedSortOrder — exactly 6 constants, each directional value mapping to a TupleOrdering.Direction:
Ascending -> ASC_NULLS_FIRST (counterflow=false) Descending -> DESC_NULLS_LAST (counterflow=false) AscendingNullsLast -> ASC_NULLS_LAST (counterflow=true) DescendingNullsFirst -> DESC_NULLS_FIRST (counterflow=true) Fixed / Choose -> non-directional
const ( ProvidedSortOrderAscending ProvidedSortOrder = iota ProvidedSortOrderDescending ProvidedSortOrderAscendingNullsLast ProvidedSortOrderDescendingNullsFirst ProvidedSortOrderFixed ProvidedSortOrderChoose )
func SortOrderOf ¶
func SortOrderOf(bindings []OrderingBinding) ProvidedSortOrder
SortOrder returns the aggregate sort order of a value's bindings. If all bindings are sorted with the same direction, returns that direction. If mixed or all fixed, returns ProvidedSortOrderFixed.
func (ProvidedSortOrder) IsAnyAscending ¶
func (s ProvidedSortOrder) IsAnyAscending() bool
IsAnyAscending reports whether this is an ascending direction (nulls first or last). Mirrors Java SortOrder.isAnyAscending().
func (ProvidedSortOrder) IsAnyDescending ¶
func (s ProvidedSortOrder) IsAnyDescending() bool
func (ProvidedSortOrder) IsCompatibleWithRequestedSortOrder ¶
func (p ProvidedSortOrder) IsCompatibleWithRequestedSortOrder(req RequestedSortOrder) bool
IsCompatibleWithRequestedSortOrder checks if a provided sort order is compatible with a requested sort order. Ports Java OrderingPart.ProvidedSortOrder.isCompatibleWithRequestedSortOrder (OrderingPart.java:322-332) exactly:
- ANY request, or a CHOOSE/FIXED provided order, is always compatible (and these early-returns must come BEFORE the counterflow check, since IsCounterflowNulls is only meaningful for directional values);
- otherwise the NULL placement must agree (counterflow-nulls equality);
- and the direction (ascending-ness) must agree, compared via IsAnyAscending on BOTH sides (so e.g. ASC_NULLS_LAST provided is compatible with an ASC_NULLS_LAST request, not just plain ASCENDING).
This is the gate that keeps a forward (ASC_NULLS_FIRST) scan from satisfying an `ORDER BY x ASC NULLS LAST` (ASC_NULLS_LAST) request, so the sort is not wrongly elided.
func (ProvidedSortOrder) IsCounterflowNulls ¶
func (s ProvidedSortOrder) IsCounterflowNulls() bool
IsCounterflowNulls reports whether the NULL placement runs against the natural tuple order for this direction. Mirrors Java TupleOrdering.Direction.isCounterflowNulls(). Only valid for directional values.
func (ProvidedSortOrder) IsDirectional ¶
func (s ProvidedSortOrder) IsDirectional() bool
func (ProvidedSortOrder) ToRequestedSortOrder ¶
func (s ProvidedSortOrder) ToRequestedSortOrder() RequestedSortOrder
ToRequestedSortOrder maps a provided sort order to the requested sort order with the same TupleOrdering.Direction (preserving NULL placement), mirroring Java ProvidedSortOrder.toRequestedSortOrder() (a by-Direction map, not a collapse to the natural order).
type PullCommonFilterAboveIntersectionRule ¶
type PullCommonFilterAboveIntersectionRule struct {
// contains filtered or unexported fields
}
PullCommonFilterAboveIntersectionRule combines an Intersection whose every child is a LogicalFilter with the SAME predicate list into a single Filter above the Intersection. The reverse direction of PushFilterThroughIntersection.
Intersection(Filter([P], A), Filter([P], B), ..., keys=K) → Filter([P], Intersection(A, B, ..., keys=K))
Soundness: filter and bag-intersection commute under row admittance. `(A passing P) ∩ (B passing P)` = `(A ∩ B) passing P`. The comparison-key list K is preserved exactly.
Optimization: collapsing N filters into 1 reduces operator count. Useful when downstream rules (e.g. predicate folding) can do more with one combined Filter than N independent ones.
func NewPullCommonFilterAboveIntersectionRule ¶
func NewPullCommonFilterAboveIntersectionRule() *PullCommonFilterAboveIntersectionRule
NewPullCommonFilterAboveIntersectionRule constructs the rule.
func (*PullCommonFilterAboveIntersectionRule) Matcher ¶
func (r *PullCommonFilterAboveIntersectionRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PullCommonFilterAboveIntersectionRule) OnMatch ¶
func (r *PullCommonFilterAboveIntersectionRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when every child Quantifier ranges over a Filter AND every Filter has the SAME predicate list (Explain-equal).
type PullCommonFilterAboveUnionRule ¶
type PullCommonFilterAboveUnionRule struct {
// contains filtered or unexported fields
}
PullCommonFilterAboveUnionRule combines a Union whose every child is a LogicalFilter with the SAME predicate list into a single Filter above the Union. The reverse of PushFilterThroughUnion.
Union(Filter([P], A), Filter([P], B), ...) → Filter([P], Union(A, B, ...))
Soundness: Union(Filter(P, A), Filter(P, B)) admits the same rows as Filter(P, Union(A, B)) — distributivity of filter over union. All children must share the SAME predicate list (compared by Explain text); a mixed-predicate set can't be pulled in one step.
Optimization argument: collapsing N filters into 1 reduces the memo's operator count and gives downstream rules a single Filter to optimise rather than N independent ones.
Termination via SemanticEquals fallback (the rule produces a fresh-Reference Union, then wraps with Filter; both new wrappers dedup against equivalent existing alternatives).
func NewPullCommonFilterAboveUnionRule ¶
func NewPullCommonFilterAboveUnionRule() *PullCommonFilterAboveUnionRule
NewPullCommonFilterAboveUnionRule constructs the rule.
func (*PullCommonFilterAboveUnionRule) Matcher ¶
func (r *PullCommonFilterAboveUnionRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PullCommonFilterAboveUnionRule) OnMatch ¶
func (r *PullCommonFilterAboveUnionRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when every child Quantifier ranges over a Filter AND every Filter has the SAME predicate list (Explain-equal).
type PullFilterAboveDistinctRule ¶
type PullFilterAboveDistinctRule struct {
// contains filtered or unexported fields
}
PullFilterAboveDistinctRule pulls a LogicalFilter ABOVE a LogicalDistinct — the inverse direction of PushFilterThroughDistinctRule.
Distinct(Filter(P, X)) → Filter(P, Distinct(X))
Soundness: same row set either side. Filter narrows by P; Distinct dedupes. Both compositions admit "DISTINCT rows of X passing P".
Why we keep BOTH this AND PushFilterThroughDistinct: the two shapes coexist in the memo as alternatives. Cost-model extraction picks the cheaper. Without cost, both stay; exploration terminates because Reference.Insert's SemanticEquals fallback absorbs structurally-equivalent re-yields after the first round.
Optimization argument: filtering AFTER dedup means evaluating P on fewer rows (Distinct pre-shrinks the set) — the inverse trade-off from PushFilterThroughDistinct. Which is cheaper depends on dedup-vs-filter cost; the cost model picks.
func NewPullFilterAboveDistinctRule ¶
func NewPullFilterAboveDistinctRule() *PullFilterAboveDistinctRule
NewPullFilterAboveDistinctRule constructs the rule.
func (*PullFilterAboveDistinctRule) Matcher ¶
func (r *PullFilterAboveDistinctRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PullFilterAboveDistinctRule) OnMatch ¶
func (r *PullFilterAboveDistinctRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalFilterExpression.
type PullUp ¶
type PullUp struct {
// contains filtered or unexported fields
}
PullUp tracks how values are translated as matching walks up through expression boundaries. Each PullUp level represents one candidate expression in the match path, carrying the candidate alias and the "pull-through" value (the result value of that expression). The chain is walked bottom-up when pulling up values from a match's inner scope to the top-level candidate scope.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.values.translation.PullUp.
func ForMatch ¶
func ForMatch( parent *PullUp, candidateAlias values.CorrelationIdentifier, candidateExpression expressions.RelationalExpression, ) *PullUp
ForMatch creates a PullUp for the match case by visiting the candidate expression to determine the pull-through value and ranged-over aliases.
Ports Java's PullUp.forMatch + PullUpVisitor.visit.
func ForUnification ¶
func ForUnification( candidateAlias values.CorrelationIdentifier, pullThroughValue values.Value, rangedOverAliases map[values.CorrelationIdentifier]struct{}, ) *PullUp
ForUnification creates a PullUp for the unification case (no parent). Ports Java's PullUp.forUnification.
func NewPullUp ¶
func NewPullUp( parent *PullUp, candidateAlias values.CorrelationIdentifier, pullThroughValue values.Value, rangedOverAliases map[values.CorrelationIdentifier]struct{}, ) *PullUp
NewPullUp constructs a PullUp level.
func (*PullUp) GetCandidateAlias ¶
func (p *PullUp) GetCandidateAlias() values.CorrelationIdentifier
func (*PullUp) GetPullThroughValue ¶
func (*PullUp) GetRangedOverAliases ¶
func (p *PullUp) GetRangedOverAliases() map[values.CorrelationIdentifier]struct{}
func (*PullUp) PullUpValueMaybe ¶
PullUpValueMaybe translates a Value from the match scope to the top-level candidate scope by walking up the PullUp chain. At each level, it computes a MaxMatchMap between the current value and the pull-through value, then translates via the candidate alias.
Returns nil if the value cannot be pulled up at any level.
Ports Java's PullUp.pullUpValueMaybe.
func (*PullUp) PullUpValueMaybeWithEquivalence ¶
PullUpValueMaybeWithEquivalence is like PullUpValueMaybe but accepts a ValueEquivalence for cross-alias matching during MaxMatchMap computation. Ports Java's overload that threads ValueEquivalence.
type PushDistinctBelowFilterRule ¶
type PushDistinctBelowFilterRule struct {
// contains filtered or unexported fields
}
PushDistinctBelowFilterRule moves a physical RecordQueryUnorderedPrimaryKeyDistinctPlan below a RecordQueryPredicatesFilterPlan. This ensures generated plans match the form produced by Java's heuristic planner (distinct below filter).
Pattern:
Distinct(Filter([P], inner)) → Filter([P'], Distinct(inner))
Predicates P are rebased from the old filter quantifier alias to the new quantifier over the distinct plan.
Mirrors Java's `PushDistinctBelowFilterRule`.
func NewPushDistinctBelowFilterRule ¶
func NewPushDistinctBelowFilterRule() *PushDistinctBelowFilterRule
func (*PushDistinctBelowFilterRule) Matcher ¶
func (r *PushDistinctBelowFilterRule) Matcher() matching.BindingMatcher
func (*PushDistinctBelowFilterRule) OnMatch ¶
func (r *PushDistinctBelowFilterRule) OnMatch(call *ImplementationRuleCall)
type PushDistinctThroughFetchRule ¶
type PushDistinctThroughFetchRule struct {
// contains filtered or unexported fields
}
PushDistinctThroughFetchRule pushes a physical RecordQueryUnorderedPrimaryKeyDistinctPlan through a RecordQueryFetchFromPartialRecordPlan to reduce the number of records before the (expensive) fetch.
Pattern:
Distinct(Fetch(inner)) → Fetch(Distinct(inner))
The distinct can operate on partial records (index entries carry the PK needed for deduplication), so pushing it below the fetch avoids fetching duplicates.
Mirrors Java's `PushDistinctThroughFetchRule`.
func NewPushDistinctThroughFetchRule ¶
func NewPushDistinctThroughFetchRule() *PushDistinctThroughFetchRule
func (*PushDistinctThroughFetchRule) Matcher ¶
func (r *PushDistinctThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushDistinctThroughFetchRule) OnMatch ¶
func (r *PushDistinctThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushFilterBelowJoinRule ¶
type PushFilterBelowJoinRule struct {
// contains filtered or unexported fields
}
PushFilterBelowJoinRule pushes filter predicates below a join (SelectExpression with 2 ForEach quantifiers) when a predicate references columns from only one side of the join.
Filter([a.name='foo', a.id=b.aid], Select(rv, [qA, qB], [jpreds]))
→ Filter([a.id=b.aid], Select(rv, [qA', qB], [jpreds]))
where qA' = ForEach(Filter([a.name='foo'], A))
A predicate is pushable to side i when every FieldValue in its tree is qualified with sourceAliases[i] and does not reference sourceAliases[j] (j != i). Predicates that reference both sides, or that have no FieldValue references at all, are kept on the filter above the join (conservative).
The rule only fires on INNER joins (JoinInner). LEFT OUTER and CROSS joins have different NULL-preservation semantics that make predicate pushdown unsound without additional analysis.
Soundness: for inner joins, Filter(P, Join(A, B)) and Join(Filter(P, A), B) produce the same result set when P only references A — the filter's admittance decision is independent of B's rows.
Optimization argument: filtering before the join reduces the number of rows the join processes, which is typically O(n*m) becoming O(filtered_n * m).
func NewPushFilterBelowJoinRule ¶
func NewPushFilterBelowJoinRule() *PushFilterBelowJoinRule
NewPushFilterBelowJoinRule constructs the rule.
func (*PushFilterBelowJoinRule) Matcher ¶
func (r *PushFilterBelowJoinRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PushFilterBelowJoinRule) OnMatch ¶
func (r *PushFilterBelowJoinRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the pattern matches a LogicalFilterExpression.
type PushFilterThroughDistinctRule ¶
type PushFilterThroughDistinctRule struct {
// contains filtered or unexported fields
}
PushFilterThroughDistinctRule pushes a LogicalFilter under a LogicalDistinct.
Filter(P, Distinct(X)) → Distinct(Filter(P, X))
Soundness: the inner Distinct doesn't reshape rows (its GetResultValue is the inner's flowed object value), so FieldValue references inside P resolve against the same row shape on both sides of the rewrite. Output row sets are equal because both forms yield "DISTINCT rows of X that satisfy P".
Optimization argument: filtering BEFORE dedup is faster — the dedup runs over fewer rows. Eliminated rows can never become duplicates after-the-fact.
Termination: the rule yields a Distinct wrapping a Quantifier over a fresh Reference holding the new Filter. The fresh Reference would defeat the sameChildReferences pointer-identity dedup, but Reference.Insert's SemanticEquals fallback (post-680e664a) catches the structural equivalence and absorbs the second yield.
Java equivalent: emerges from cost preference for cheaper plans.
func NewPushFilterThroughDistinctRule ¶
func NewPushFilterThroughDistinctRule() *PushFilterThroughDistinctRule
NewPushFilterThroughDistinctRule constructs the rule.
func (*PushFilterThroughDistinctRule) Matcher ¶
func (r *PushFilterThroughDistinctRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PushFilterThroughDistinctRule) OnMatch ¶
func (r *PushFilterThroughDistinctRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalDistinctExpression.
type PushFilterThroughFetchRule ¶
type PushFilterThroughFetchRule struct {
// contains filtered or unexported fields
}
PushFilterThroughFetchRule pushes predicates that can be evaluated on partial records (index entries) underneath a FetchFromPartialRecordPlan. This filters out non-matching records before the expensive fetch.
A predicate is pushable iff all its leaf values can be translated from the full-record domain to the partial-record (index) domain via the fetch's TranslateValueFunction.
Three cases:
- No predicates pushable → return (no yield)
- All predicates pushable → Fetch(Filter(pushed, inner))
- Some pushable, some residual → Filter(residual, Fetch(Filter(pushed, inner)))
Mirrors Java's `PushFilterThroughFetchRule`.
func NewPushFilterThroughFetchRule ¶
func NewPushFilterThroughFetchRule() *PushFilterThroughFetchRule
func (*PushFilterThroughFetchRule) Matcher ¶
func (r *PushFilterThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushFilterThroughFetchRule) OnMatch ¶
func (r *PushFilterThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushFilterThroughGroupByRule ¶
type PushFilterThroughGroupByRule struct {
// contains filtered or unexported fields
}
PushFilterThroughGroupByRule pushes predicates from a LogicalFilter below a GroupByExpression when those predicates reference only the grouping keys. Supports partial pushdown: pushable predicates move below GroupBy; residual predicates stay as a filter above.
Filter([P1, P2], GroupBy(keys, aggs, X)) → Filter([P2], GroupBy(keys, aggs, Filter([P1], X))) [P1 on keys, P2 not] → GroupBy(keys, aggs, Filter([P1, P2], X)) [all on keys]
Soundness: if a predicate references only grouping-key columns, filtering before aggregation produces the same groups — rows eliminated by the predicate wouldn't contribute to any group that survives it.
Java equivalent: PushPredicateThroughGroupByRule.
func NewPushFilterThroughGroupByRule ¶
func NewPushFilterThroughGroupByRule() *PushFilterThroughGroupByRule
func (*PushFilterThroughGroupByRule) Matcher ¶
func (r *PushFilterThroughGroupByRule) Matcher() matching.BindingMatcher
func (*PushFilterThroughGroupByRule) OnMatch ¶
func (r *PushFilterThroughGroupByRule) OnMatch(call *ExpressionRuleCall)
type PushFilterThroughIntersectionRule ¶
type PushFilterThroughIntersectionRule struct {
// contains filtered or unexported fields
}
PushFilterThroughIntersectionRule distributes a LogicalFilter over a LogicalIntersection's children.
Filter(P, Intersection(A, B, ..., [keys=K])) → Intersection(Filter(P, A), Filter(P, B), ..., [keys=K])
Soundness: row-set equivalence — filter commutes with intersection. `rows in (A ∩ B) passing P` equals `(A passing P) ∩ (B passing P)`. The comparison-key list K is preserved exactly; the keys are about HOW the intersection compares rows, not which rows it admits.
Optimization argument: same as the Union variant — distributing the filter into each operand gives downstream pushdown rules a chance to push the predicate into each operand's scan / index.
Note: produces a structurally LARGER tree (N filters instead of 1). The benefit comes from follow-on rules. Same termination contract as PushFilterThroughDistinct: Reference.Insert's SemanticEquals fallback (commit 680e664a) absorbs the structurally-equivalent re-yield on subsequent fires.
func NewPushFilterThroughIntersectionRule ¶
func NewPushFilterThroughIntersectionRule() *PushFilterThroughIntersectionRule
NewPushFilterThroughIntersectionRule constructs the rule.
func (*PushFilterThroughIntersectionRule) Matcher ¶
func (r *PushFilterThroughIntersectionRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PushFilterThroughIntersectionRule) OnMatch ¶
func (r *PushFilterThroughIntersectionRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalIntersectionExpression with at least one child.
type PushFilterThroughTypeFilterRule ¶
type PushFilterThroughTypeFilterRule struct {
// contains filtered or unexported fields
}
PushFilterThroughTypeFilterRule pushes a LogicalFilter under a LogicalTypeFilter.
Filter(P, TypeFilter([T], X)) → TypeFilter([T], Filter(P, X))
Soundness: TypeFilter doesn't reshape rows (its GetResultValue is the inner's flowed object value). FieldValue references inside P resolve against the same row shape on both sides. The TypeFilter admits only rows of the listed types; the Filter admits only rows satisfying P. Composing the two predicates is commutative for row admittance — same output rows.
Optimization argument: TypeFilter is typically cheap (record-type dispatch). Filter is potentially expensive (predicate evaluation). Putting Filter "lower" in the tree gives the downstream data-access / implementation rules a chance to push the predicate INTO the scan itself (e.g. into a covering-index range scan).
func NewPushFilterThroughTypeFilterRule ¶
func NewPushFilterThroughTypeFilterRule() *PushFilterThroughTypeFilterRule
NewPushFilterThroughTypeFilterRule constructs the rule.
func (*PushFilterThroughTypeFilterRule) Matcher ¶
func (r *PushFilterThroughTypeFilterRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PushFilterThroughTypeFilterRule) OnMatch ¶
func (r *PushFilterThroughTypeFilterRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalTypeFilterExpression.
type PushFilterThroughUnionRule ¶
type PushFilterThroughUnionRule struct {
// contains filtered or unexported fields
}
PushFilterThroughUnionRule distributes a LogicalFilter over a LogicalUnion's children — the classic distribution rewrite.
Filter(P, Union(A, B, ...)) → Union(Filter(P, A), Filter(P, B), ...)
Soundness: row-set equivalence — filtering the union is the same as filtering each operand and unioning the results. Holds for UNION ALL semantics (which our LogicalUnionExpression represents); also remains sound under UNION DISTINCT (Distinct over the result) because the dedup commutes with filter and union.
Optimization argument: distributing the filter into each operand gives the downstream data-access / implementation rules a chance to push the predicate INTO each operand's scan / index — a much bigger win than filtering the unioned stream once.
Note: this rule produces a structurally LARGER tree (N filters instead of 1). The benefit comes from follow-on rules; without downstream pushdown, the rewrite is a wash. That is safe because (a) the SemanticEquals fallback in Reference.Insert means re-firing on the same input is dedup'd, and (b) the larger memo is exactly what cost-driven extraction needs to compare alternatives.
func NewPushFilterThroughUnionRule ¶
func NewPushFilterThroughUnionRule() *PushFilterThroughUnionRule
NewPushFilterThroughUnionRule constructs the rule.
func (*PushFilterThroughUnionRule) Matcher ¶
func (r *PushFilterThroughUnionRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PushFilterThroughUnionRule) OnMatch ¶
func (r *PushFilterThroughUnionRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalUnionExpression with at least one child.
type PushInJoinThroughFetchRule ¶
type PushInJoinThroughFetchRule struct {
// contains filtered or unexported fields
}
PushInJoinThroughFetchRule pushes a RecordQueryInJoinPlan through a FetchFromPartialRecordPlan. The InJoin runs on the partial/index records (cheaper), and the Fetch is lifted to the top.
Before:
InJoin(Fetch(inner))
After:
Fetch(InJoin(inner))
Go collapses Java's 3 InJoin subclasses (InValuesJoin, InParameterJoin, InComparandJoin) into a single RecordQueryInJoinPlan, so only one rule instance is needed (Java instantiates this rule twice).
Mirrors Java's PushInJoinThroughFetchRule.
func NewPushInJoinThroughFetchRule ¶
func NewPushInJoinThroughFetchRule() *PushInJoinThroughFetchRule
func (*PushInJoinThroughFetchRule) Matcher ¶
func (r *PushInJoinThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushInJoinThroughFetchRule) OnMatch ¶
func (r *PushInJoinThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushInUnionThroughFetchRule ¶
type PushInUnionThroughFetchRule struct {
// contains filtered or unexported fields
}
PushInUnionThroughFetchRule handles the InUnion case. Java: PushSetOperationThroughFetchRule<RecordQueryInUnionOnValuesPlan>.
func NewPushInUnionThroughFetchRule ¶
func NewPushInUnionThroughFetchRule() *PushInUnionThroughFetchRule
func (*PushInUnionThroughFetchRule) Matcher ¶
func (r *PushInUnionThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushInUnionThroughFetchRule) OnMatch ¶
func (r *PushInUnionThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushIntersectionThroughFetchRule ¶
type PushIntersectionThroughFetchRule struct {
// contains filtered or unexported fields
}
PushIntersectionThroughFetchRule handles the Intersection case.
func NewPushIntersectionThroughFetchRule ¶
func NewPushIntersectionThroughFetchRule() *PushIntersectionThroughFetchRule
func (*PushIntersectionThroughFetchRule) Matcher ¶
func (r *PushIntersectionThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushIntersectionThroughFetchRule) OnMatch ¶
func (r *PushIntersectionThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushLimitThroughProjectionRule ¶
type PushLimitThroughProjectionRule struct {
// contains filtered or unexported fields
}
PushLimitThroughProjectionRule pushes a LIMIT below a Projection. LogicalProjection is a pure row pass-through (row shape unchanged; the projection list is a side channel) so the LIMIT can safely move below it — reduces the number of rows the projection processes.
Pattern:
LogicalLimit(limit, offset)
inner → LogicalProjection(values)
inner → X
Rewrite:
LogicalProjection(values)
inner → LogicalLimit(limit, offset)
inner → X
func NewPushLimitThroughProjectionRule ¶
func NewPushLimitThroughProjectionRule() *PushLimitThroughProjectionRule
func (*PushLimitThroughProjectionRule) Matcher ¶
func (r *PushLimitThroughProjectionRule) Matcher() matching.BindingMatcher
func (*PushLimitThroughProjectionRule) OnMatch ¶
func (r *PushLimitThroughProjectionRule) OnMatch(call *ExpressionRuleCall)
type PushLimitThroughUnionRule ¶
type PushLimitThroughUnionRule struct {
// contains filtered or unexported fields
}
PushLimitThroughUnionRule pushes a LIMIT into each branch of a UNION ALL. Each branch needs at most (limit + offset) rows since the outer LIMIT will pick from the union output. The outer LIMIT remains in place — it still needs to enforce the final cardinality.
Pattern:
LogicalLimit(limit, offset) inner → LogicalUnion(q1, q2, …)
Rewrite:
LogicalLimit(limit, offset)
inner → LogicalUnion(
LIMIT(limit+offset, 0, q1.inner),
LIMIT(limit+offset, 0, q2.inner),
…)
The branch limit is limit+offset because the outer LIMIT may skip 'offset' rows before taking 'limit' rows.
func NewPushLimitThroughUnionRule ¶
func NewPushLimitThroughUnionRule() *PushLimitThroughUnionRule
func (*PushLimitThroughUnionRule) Matcher ¶
func (r *PushLimitThroughUnionRule) Matcher() matching.BindingMatcher
func (*PushLimitThroughUnionRule) OnMatch ¶
func (r *PushLimitThroughUnionRule) OnMatch(call *ExpressionRuleCall)
type PushMapThroughFetchRule ¶
type PushMapThroughFetchRule struct {
// contains filtered or unexported fields
}
PushMapThroughFetchRule pushes a map expression through a FetchFromPartialRecordPlan when all values referenced by the map's result value can be translated to the partial-record (index) domain. This eliminates the fetch entirely — the map runs directly on the covering index scan.
Pattern:
Map(resultValue, Fetch(inner)) → Map(translatedResultValue, inner)
The fetch is completely eliminated because the map reshapes the output in a way that detaches downstream data flow from the full record.
Mirrors Java's `PushMapThroughFetchRule`.
func NewPushMapThroughFetchRule ¶
func NewPushMapThroughFetchRule() *PushMapThroughFetchRule
func (*PushMapThroughFetchRule) Matcher ¶
func (r *PushMapThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushMapThroughFetchRule) OnMatch ¶
func (r *PushMapThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushReferencedFieldsThroughDistinctRule ¶
type PushReferencedFieldsThroughDistinctRule struct {
// contains filtered or unexported fields
}
PushReferencedFieldsThroughDistinctRule pushes referenced-field constraints through LogicalDistinctExpression (transparent pass-through).
Ports Java's PushReferencedFieldsThroughDistinctRule.
func NewPushReferencedFieldsThroughDistinctRule ¶
func NewPushReferencedFieldsThroughDistinctRule() *PushReferencedFieldsThroughDistinctRule
func (PushReferencedFieldsThroughDistinctRule) IsPreOrder ¶
func (PushReferencedFieldsThroughDistinctRule) IsPreOrder() bool
func (*PushReferencedFieldsThroughDistinctRule) Matcher ¶
func (r *PushReferencedFieldsThroughDistinctRule) Matcher() matching.BindingMatcher
func (*PushReferencedFieldsThroughDistinctRule) OnMatch ¶
func (r *PushReferencedFieldsThroughDistinctRule) OnMatch(call *ImplementationRuleCall)
type PushReferencedFieldsThroughFilterRule ¶
type PushReferencedFieldsThroughFilterRule struct {
// contains filtered or unexported fields
}
PushReferencedFieldsThroughFilterRule pushes referenced-field constraints through LogicalFilterExpression. Extracts FieldValues from the filter's predicates, unions them with any incoming constraint, and pushes the result to the child Reference.
Ports Java's PushReferencedFieldsThroughFilterRule.
func NewPushReferencedFieldsThroughFilterRule ¶
func NewPushReferencedFieldsThroughFilterRule() *PushReferencedFieldsThroughFilterRule
func (PushReferencedFieldsThroughFilterRule) IsPreOrder ¶
func (PushReferencedFieldsThroughFilterRule) IsPreOrder() bool
func (*PushReferencedFieldsThroughFilterRule) Matcher ¶
func (r *PushReferencedFieldsThroughFilterRule) Matcher() matching.BindingMatcher
func (*PushReferencedFieldsThroughFilterRule) OnMatch ¶
func (r *PushReferencedFieldsThroughFilterRule) OnMatch(call *ImplementationRuleCall)
type PushReferencedFieldsThroughSelectRule ¶
type PushReferencedFieldsThroughSelectRule struct {
// contains filtered or unexported fields
}
PushReferencedFieldsThroughSelectRule pushes referenced-field constraints through SelectExpression. Extracts FieldValues from predicates and the result value, unions with incoming constraint, and pushes to all child References.
Ports Java's PushReferencedFieldsThroughSelectRule.
func NewPushReferencedFieldsThroughSelectRule ¶
func NewPushReferencedFieldsThroughSelectRule() *PushReferencedFieldsThroughSelectRule
func (PushReferencedFieldsThroughSelectRule) IsPreOrder ¶
func (PushReferencedFieldsThroughSelectRule) IsPreOrder() bool
func (*PushReferencedFieldsThroughSelectRule) Matcher ¶
func (r *PushReferencedFieldsThroughSelectRule) Matcher() matching.BindingMatcher
func (*PushReferencedFieldsThroughSelectRule) OnMatch ¶
func (r *PushReferencedFieldsThroughSelectRule) OnMatch(call *ImplementationRuleCall)
type PushReferencedFieldsThroughUniqueRule ¶
type PushReferencedFieldsThroughUniqueRule struct {
// contains filtered or unexported fields
}
PushReferencedFieldsThroughUniqueRule pushes referenced-field constraints through LogicalUniqueExpression (transparent pass-through).
Ports Java's PushReferencedFieldsThroughUniqueRule.
func NewPushReferencedFieldsThroughUniqueRule ¶
func NewPushReferencedFieldsThroughUniqueRule() *PushReferencedFieldsThroughUniqueRule
func (PushReferencedFieldsThroughUniqueRule) IsPreOrder ¶
func (PushReferencedFieldsThroughUniqueRule) IsPreOrder() bool
func (*PushReferencedFieldsThroughUniqueRule) Matcher ¶
func (r *PushReferencedFieldsThroughUniqueRule) Matcher() matching.BindingMatcher
func (*PushReferencedFieldsThroughUniqueRule) OnMatch ¶
func (r *PushReferencedFieldsThroughUniqueRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughDeleteRule ¶
type PushRequestedOrderingThroughDeleteRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughDeleteRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through a DeleteExpression. Delete passes through rows unchanged (it only removes them from the store), so the requested ordering passes through unchanged to the child Reference.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op — ImplementDeleteRule handles the actual delete implementation.
Ports Java's PushRequestedOrderingThroughDeleteRule.
func NewPushRequestedOrderingThroughDeleteRule ¶
func NewPushRequestedOrderingThroughDeleteRule() *PushRequestedOrderingThroughDeleteRule
func (PushRequestedOrderingThroughDeleteRule) IsPreOrder ¶
func (PushRequestedOrderingThroughDeleteRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughDeleteRule) Matcher ¶
func (r *PushRequestedOrderingThroughDeleteRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughDeleteRule) OnMatch ¶
func (r *PushRequestedOrderingThroughDeleteRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughDistinctRule ¶
type PushRequestedOrderingThroughDistinctRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughDistinctRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through a LogicalDistinctExpression. Distinct preserves row order, so the requested ordering passes through unchanged to the child Reference.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op — ImplementDistinctFinalRule handles the actual distinct implementation.
Ports Java's PushRequestedOrderingThroughDistinctRule.
func NewPushRequestedOrderingThroughDistinctRule ¶
func NewPushRequestedOrderingThroughDistinctRule() *PushRequestedOrderingThroughDistinctRule
func (PushRequestedOrderingThroughDistinctRule) IsPreOrder ¶
func (PushRequestedOrderingThroughDistinctRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughDistinctRule) Matcher ¶
func (r *PushRequestedOrderingThroughDistinctRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughDistinctRule) OnMatch ¶
func (r *PushRequestedOrderingThroughDistinctRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughFilterRule ¶
type PushRequestedOrderingThroughFilterRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughFilterRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through a LogicalFilterExpression. Filtering removes rows but does not reorder them, so the requested ordering passes through unchanged to the child Reference.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op — ImplementFilterRule / ImplementSimpleSelectRule handle the actual filter implementation.
Ports Java's PushRequestedOrderingThroughSelectRule (for the single-source filter case — Go's LogicalFilterExpression maps to Java's SelectExpression with a single ForEach quantifier and predicates only).
func NewPushRequestedOrderingThroughFilterRule ¶
func NewPushRequestedOrderingThroughFilterRule() *PushRequestedOrderingThroughFilterRule
func (PushRequestedOrderingThroughFilterRule) IsPreOrder ¶
func (PushRequestedOrderingThroughFilterRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughFilterRule) Matcher ¶
func (r *PushRequestedOrderingThroughFilterRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughFilterRule) OnMatch ¶
func (r *PushRequestedOrderingThroughFilterRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughGroupByRule ¶
type PushRequestedOrderingThroughGroupByRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughGroupByRule is a PLANNING-phase ImplementationRule that synthesizes compatible orderings from a RequestedOrdering constraint and a GroupByExpression's grouping keys, then pushes the synthesized ordering to the child Reference.
GroupBy is NOT ordering-transparent — the pushed ordering must cover all grouping keys (for streaming aggregation) while respecting the requested ordering's key prefix (for the outer ORDER BY). The rule synthesizes the ordering as:
- Each requested ordering part that matches a grouping key (by field name, case-insensitive) retains its sort direction.
- Remaining grouping keys not in the request are appended with ANY sort order (direction doesn't matter for streaming aggregation — they just need to be contiguous).
If any requested ordering part does NOT match a grouping key, the ordering is incompatible and is not pushed. If there are no grouping keys (scalar aggregation), a preserve ordering is pushed — scalar aggregation produces 0-1 rows, so any ordering is trivially satisfied.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op.
Ports Java's PushRequestedOrderingThroughGroupByRule.
func NewPushRequestedOrderingThroughGroupByRule ¶
func NewPushRequestedOrderingThroughGroupByRule() *PushRequestedOrderingThroughGroupByRule
func (PushRequestedOrderingThroughGroupByRule) IsPreOrder ¶
func (PushRequestedOrderingThroughGroupByRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughGroupByRule) Matcher ¶
func (r *PushRequestedOrderingThroughGroupByRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughGroupByRule) OnMatch ¶
func (r *PushRequestedOrderingThroughGroupByRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughInLikeSelectRule ¶
type PushRequestedOrderingThroughInLikeSelectRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughInLikeSelectRule is a PLANNING-phase ImplementationRule that pushes RequestedOrdering constraints through a SelectExpression that represents an IN-like pattern — a SELECT over one or more ExplodeExpressions (UNNEST of IN-lists) plus exactly one non-explode inner quantifier.
The rule validates the IN-like shape (explode count + 1 == total quantifiers, inner is correlated to all explodes, result is a QuantifiedObjectValue referencing the inner alias) and pushes the requested orderings verbatim to the inner quantifier's child Reference. This applies to both in-joins and in-unions.
Ports Java's PushRequestedOrderingThroughInLikeSelectRule.
func NewPushRequestedOrderingThroughInLikeSelectRule ¶
func NewPushRequestedOrderingThroughInLikeSelectRule() *PushRequestedOrderingThroughInLikeSelectRule
func (PushRequestedOrderingThroughInLikeSelectRule) IsPreOrder ¶
func (PushRequestedOrderingThroughInLikeSelectRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughInLikeSelectRule) Matcher ¶
func (r *PushRequestedOrderingThroughInLikeSelectRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughInLikeSelectRule) OnMatch ¶
func (r *PushRequestedOrderingThroughInLikeSelectRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughInsertRule ¶
type PushRequestedOrderingThroughInsertRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughInsertRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through an InsertExpression. Insert passes through rows unchanged (it writes them to the store and emits them for downstream counting/projection), so the requested ordering passes through unchanged to the child Reference.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op -- ImplementInsertRule handles the actual insert implementation.
Ports Java's PushRequestedOrderingThroughInsertRule.
func NewPushRequestedOrderingThroughInsertRule ¶
func NewPushRequestedOrderingThroughInsertRule() *PushRequestedOrderingThroughInsertRule
func (PushRequestedOrderingThroughInsertRule) IsPreOrder ¶
func (PushRequestedOrderingThroughInsertRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughInsertRule) Matcher ¶
func (r *PushRequestedOrderingThroughInsertRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughInsertRule) OnMatch ¶
func (r *PushRequestedOrderingThroughInsertRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughProjectionRule ¶
type PushRequestedOrderingThroughProjectionRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughProjectionRule is a PLANNING-phase ImplementationRule that translates a RequestedOrdering constraint through a LogicalProjectionExpression's value mapping and pushes the translated ordering to the child Reference.
Projection is NOT ordering-transparent — sort keys reference post-projection column aliases which must be translated to their pre-projection source expressions via PushDownThroughValue. If all keys translate, the translated ordering is pushed to the child; if any key fails to translate, nothing is pushed.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op.
Ports Java's PushRequestedOrderingThroughSelectRule (for the projection case).
func NewPushRequestedOrderingThroughProjectionRule ¶
func NewPushRequestedOrderingThroughProjectionRule() *PushRequestedOrderingThroughProjectionRule
func (PushRequestedOrderingThroughProjectionRule) IsPreOrder ¶
func (PushRequestedOrderingThroughProjectionRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughProjectionRule) Matcher ¶
func (r *PushRequestedOrderingThroughProjectionRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughProjectionRule) OnMatch ¶
func (r *PushRequestedOrderingThroughProjectionRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughRecursiveUnionRule ¶
type PushRequestedOrderingThroughRecursiveUnionRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughRecursiveUnionRule is a PLANNING-phase ImplementationRule that pushes a RequestedOrdering constraint through a RecursiveUnionExpression. Currently, it only allows pushing preserve-type orderings to both the initial and recursive legs.
Ports Java's PushRequestedOrderingThroughRecursiveUnionRule.
func NewPushRequestedOrderingThroughRecursiveUnionRule ¶
func NewPushRequestedOrderingThroughRecursiveUnionRule() *PushRequestedOrderingThroughRecursiveUnionRule
func (PushRequestedOrderingThroughRecursiveUnionRule) IsPreOrder ¶
func (PushRequestedOrderingThroughRecursiveUnionRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughRecursiveUnionRule) Matcher ¶
func (r *PushRequestedOrderingThroughRecursiveUnionRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughRecursiveUnionRule) OnMatch ¶
func (r *PushRequestedOrderingThroughRecursiveUnionRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughSelectExistentialRule ¶
type PushRequestedOrderingThroughSelectExistentialRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughSelectExistentialRule is a PLANNING-phase ImplementationRule that pushes a preserve RequestedOrdering to the child of an existential quantifier within a SelectExpression.
Existential quantifiers (EXISTS subqueries) don't need specific orderings — they only check for the existence of at least one row. This rule unconditionally pushes preserve ordering to their child Reference so downstream rules know the ordering is unconstrained.
Ports Java's PushRequestedOrderingThroughSelectExistentialRule.
func NewPushRequestedOrderingThroughSelectExistentialRule ¶
func NewPushRequestedOrderingThroughSelectExistentialRule() *PushRequestedOrderingThroughSelectExistentialRule
func (PushRequestedOrderingThroughSelectExistentialRule) IsPreOrder ¶
func (PushRequestedOrderingThroughSelectExistentialRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughSelectExistentialRule) Matcher ¶
func (r *PushRequestedOrderingThroughSelectExistentialRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughSelectExistentialRule) OnMatch ¶
func (r *PushRequestedOrderingThroughSelectExistentialRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughSelectRule ¶
type PushRequestedOrderingThroughSelectRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughSelectRule is a PLANNING-phase ImplementationRule that pushes RequestedOrdering constraints through a SelectExpression with a single ForEach quantifier. Ordering parts are translated through the SELECT's result value (projection) so they reference the inner quantifier's columns.
For preserve orderings, preserve is pushed through unchanged. For concrete orderings, PushDownThroughValue translates each ordering part through the projection.
Ports Java's PushRequestedOrderingThroughSelectRule.
func NewPushRequestedOrderingThroughSelectRule ¶
func NewPushRequestedOrderingThroughSelectRule() *PushRequestedOrderingThroughSelectRule
func (PushRequestedOrderingThroughSelectRule) IsPreOrder ¶
func (PushRequestedOrderingThroughSelectRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughSelectRule) Matcher ¶
func (r *PushRequestedOrderingThroughSelectRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughSelectRule) OnMatch ¶
func (r *PushRequestedOrderingThroughSelectRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughSortRule ¶
type PushRequestedOrderingThroughSortRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughSortRule is a PLANNING-phase ImplementationRule that reads a LogicalSortExpression's sort keys and pushes them as a RequestedOrdering constraint to the child Reference. The sort expression is the SOURCE of ordering constraints — this rule creates the initial constraint that transparent rules (Distinct, Unique, Delete) then propagate further.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op — ImplementSortRule handles the actual sort elimination / implementation.
Ports Java's PushRequestedOrderingThroughSortRule.
func NewPushRequestedOrderingThroughSortRule ¶
func NewPushRequestedOrderingThroughSortRule() *PushRequestedOrderingThroughSortRule
func (PushRequestedOrderingThroughSortRule) IsPreOrder ¶
func (PushRequestedOrderingThroughSortRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughSortRule) Matcher ¶
func (r *PushRequestedOrderingThroughSortRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughSortRule) OnMatch ¶
func (r *PushRequestedOrderingThroughSortRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughTempTableInsertRule ¶
type PushRequestedOrderingThroughTempTableInsertRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughTempTableInsertRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through a TempTableInsertExpression. TempTableInsert passes through rows into a temp table -- sorting below produces the same final order as sorting above -- so the requested ordering passes through unchanged to the child Reference.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op -- ImplementTempTableInsertRule handles the actual insert implementation.
Ports Java's PushRequestedOrderingThroughInsertTempTableRule.
func NewPushRequestedOrderingThroughTempTableInsertRule ¶
func NewPushRequestedOrderingThroughTempTableInsertRule() *PushRequestedOrderingThroughTempTableInsertRule
func (PushRequestedOrderingThroughTempTableInsertRule) IsPreOrder ¶
func (PushRequestedOrderingThroughTempTableInsertRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughTempTableInsertRule) Matcher ¶
func (r *PushRequestedOrderingThroughTempTableInsertRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughTempTableInsertRule) OnMatch ¶
func (r *PushRequestedOrderingThroughTempTableInsertRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughUnionRule ¶
type PushRequestedOrderingThroughUnionRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughUnionRule is a PLANNING-phase ImplementationRule that pushes a RequestedOrdering constraint through a LogicalUnionExpression to all of its child branch References.
For a union to produce ordered output, all branches must be independently ordered — a merge-union above combines the sorted streams. The first branch receives exhaustive orderings (all satisfying plans are needed to enumerate merge-compatible options); remaining branches receive the orderings as-is (they'll be specifically requested by the union implementation rule).
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op.
Ports Java's PushRequestedOrderingThroughUnionRule.
func NewPushRequestedOrderingThroughUnionRule ¶
func NewPushRequestedOrderingThroughUnionRule() *PushRequestedOrderingThroughUnionRule
func (PushRequestedOrderingThroughUnionRule) IsPreOrder ¶
func (PushRequestedOrderingThroughUnionRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughUnionRule) Matcher ¶
func (r *PushRequestedOrderingThroughUnionRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughUnionRule) OnMatch ¶
func (r *PushRequestedOrderingThroughUnionRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughUniqueRule ¶
type PushRequestedOrderingThroughUniqueRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughUniqueRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through a LogicalUniqueExpression. Unique (PK deduplication) preserves row order, so the requested ordering passes through unchanged to the child Reference.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op — ImplementUniqueRule handles the actual unique implementation.
Ports Java's PushRequestedOrderingThroughUniqueRule.
func NewPushRequestedOrderingThroughUniqueRule ¶
func NewPushRequestedOrderingThroughUniqueRule() *PushRequestedOrderingThroughUniqueRule
func (PushRequestedOrderingThroughUniqueRule) IsPreOrder ¶
func (PushRequestedOrderingThroughUniqueRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughUniqueRule) Matcher ¶
func (r *PushRequestedOrderingThroughUniqueRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughUniqueRule) OnMatch ¶
func (r *PushRequestedOrderingThroughUniqueRule) OnMatch(call *ImplementationRuleCall)
type PushRequestedOrderingThroughUpdateRule ¶
type PushRequestedOrderingThroughUpdateRule struct {
// contains filtered or unexported fields
}
PushRequestedOrderingThroughUpdateRule is a PLANNING-phase ImplementationRule that propagates a RequestedOrdering constraint through an UpdateExpression. Update passes through rows unchanged (it applies transforms and emits them for downstream counting/projection), so the requested ordering passes through unchanged to the child Reference.
Java's version translates orderings through makeComputationValue (a RecordConstructor with old/new columns). Go's UpdateExpression does not yet model that structure -- GetResultValue returns the inner's flowed object value directly -- so the pass-through is correct for Go's current expression model.
This rule fires during the top-down constraint-propagation pass (constraintOnly=true). During the bottom-up implementation pass (constraintOnly=false) it is a no-op -- ImplementUpdateRule handles the actual update implementation.
Ports Java's PushRequestedOrderingThroughUpdateRule.
func NewPushRequestedOrderingThroughUpdateRule ¶
func NewPushRequestedOrderingThroughUpdateRule() *PushRequestedOrderingThroughUpdateRule
func (PushRequestedOrderingThroughUpdateRule) IsPreOrder ¶
func (PushRequestedOrderingThroughUpdateRule) IsPreOrder() bool
func (*PushRequestedOrderingThroughUpdateRule) Matcher ¶
func (r *PushRequestedOrderingThroughUpdateRule) Matcher() matching.BindingMatcher
func (*PushRequestedOrderingThroughUpdateRule) OnMatch ¶
func (r *PushRequestedOrderingThroughUpdateRule) OnMatch(call *ImplementationRuleCall)
type PushTypeFilterBelowFilterRule ¶
type PushTypeFilterBelowFilterRule struct {
// contains filtered or unexported fields
}
PushTypeFilterBelowFilterRule pushes a LogicalTypeFilter under a LogicalFilter — the inverse of PushFilterThroughTypeFilterRule.
TypeFilter([T], Filter(P, X)) → Filter(P, TypeFilter([T], X))
Soundness: filter and type-filter commute under row admittance. Either order yields "rows of type-set T that satisfy P".
Optimization argument: TypeFilter is cheap (record-type dispatch). Pushing it CLOSER to the leaf means Filter operates on fewer rows (only T-typed rows reach the Filter). Wins when Filter's predicate is expensive.
Why we keep BOTH this AND PushFilterThroughTypeFilterRule: the two shapes coexist in the memo as alternatives. Cost-model extraction picks the cheaper one. Without cost, both shapes stay; exploration terminates because Reference.Insert's SemanticEquals fallback absorbs structurally-equivalent re-yields after the first round of rule firing.
Java equivalent: PushTypeFilterBelowFilterRule.
func NewPushTypeFilterBelowFilterRule ¶
func NewPushTypeFilterBelowFilterRule() *PushTypeFilterBelowFilterRule
NewPushTypeFilterBelowFilterRule constructs the rule.
func (*PushTypeFilterBelowFilterRule) Matcher ¶
func (r *PushTypeFilterBelowFilterRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*PushTypeFilterBelowFilterRule) OnMatch ¶
func (r *PushTypeFilterBelowFilterRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a LogicalFilterExpression.
type PushUnionThroughFetchRule ¶
type PushUnionThroughFetchRule struct {
// contains filtered or unexported fields
}
PushUnionThroughFetchRule handles the Union case.
func NewPushUnionThroughFetchRule ¶
func NewPushUnionThroughFetchRule() *PushUnionThroughFetchRule
func (*PushUnionThroughFetchRule) Matcher ¶
func (r *PushUnionThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushUnionThroughFetchRule) OnMatch ¶
func (r *PushUnionThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type PushUnorderedUnionThroughFetchRule ¶
type PushUnorderedUnionThroughFetchRule struct {
// contains filtered or unexported fields
}
PushUnorderedUnionThroughFetchRule handles the UnorderedUnion case. Java: PushSetOperationThroughFetchRule<RecordQueryUnorderedUnionPlan>.
func NewPushUnorderedUnionThroughFetchRule ¶
func NewPushUnorderedUnionThroughFetchRule() *PushUnorderedUnionThroughFetchRule
func (*PushUnorderedUnionThroughFetchRule) Matcher ¶
func (r *PushUnorderedUnionThroughFetchRule) Matcher() matching.BindingMatcher
func (*PushUnorderedUnionThroughFetchRule) OnMatch ¶
func (r *PushUnorderedUnionThroughFetchRule) OnMatch(call *ImplementationRuleCall)
type QueryPlanConstraint ¶
type QueryPlanConstraint struct {
// contains filtered or unexported fields
}
QueryPlanConstraint captures assumptions under which a plan match is valid. Wraps a QueryPredicate that must evaluate to true for the match to be applicable.
Ports Java's com.apple.foundationdb.record.query.plan.QueryPlanConstraint.
func NewQueryPlanConstraint ¶
func NewQueryPlanConstraint(pred predicates.QueryPredicate) *QueryPlanConstraint
NewQueryPlanConstraint creates a constraint from a predicate.
func Tautology ¶
func Tautology() *QueryPlanConstraint
Tautology returns a constraint that is always satisfied.
func (*QueryPlanConstraint) GetPredicate ¶
func (c *QueryPlanConstraint) GetPredicate() predicates.QueryPredicate
GetPredicate returns the underlying predicate.
func (*QueryPlanConstraint) IsConstrained ¶
func (c *QueryPlanConstraint) IsConstrained() bool
IsConstrained reports whether this constraint is non-trivial.
func (*QueryPlanConstraint) IsTautology ¶
func (c *QueryPlanConstraint) IsTautology() bool
IsTautology reports whether this constraint is always satisfied.
type QueryPredicateSimplificationRule ¶
type QueryPredicateSimplificationRule struct {
// contains filtered or unexported fields
}
QueryPredicateSimplificationRule applies predicate simplification to a SelectExpression. Runs the predicate simplifier (predicates.SimplifyPredicateValues) on each predicate in the SelectExpression's predicate list and yields a new SelectExpression if any predicate changed.
Go's simplifier engine (SimplifyPredicateValues) walks the predicate tree and constant-folds Value operands — e.g. `name = 1+2` becomes `name = 3`. This is the Go equivalent of Java's ConstantFoldingRuleSet applied through Simplification.optimize.
Convergence: if no predicates changed (pointer-identity check), the rule does not yield. Constant-folding is idempotent, so repeated application converges in one step.
Ports Java's QueryPredicateSimplificationRule (ExplorationCascadesRule, 128 LOC).
func NewQueryPredicateSimplificationRule ¶
func NewQueryPredicateSimplificationRule() *QueryPredicateSimplificationRule
func (*QueryPredicateSimplificationRule) Matcher ¶
func (r *QueryPredicateSimplificationRule) Matcher() matching.BindingMatcher
func (*QueryPredicateSimplificationRule) OnMatch ¶
func (r *QueryPredicateSimplificationRule) OnMatch(call *ExpressionRuleCall)
type ReferencedFields ¶
type ReferencedFields struct {
// contains filtered or unexported fields
}
ReferencedFields tracks which FieldValues are referenced by upstream operators (predicates, projections, ordering). Pushed top-down via PushReferencedFieldsThrough* rules so downstream operators can prune columns not needed by the query.
Ports Java's ReferencedFieldsConstraint.ReferencedFields.
func EmptyReferencedFields ¶
func EmptyReferencedFields() *ReferencedFields
EmptyReferencedFields returns an empty field set.
func FieldValuesFromValue ¶
func FieldValuesFromValue(v values.Value) *ReferencedFields
FieldValuesFromValue extracts FieldValue names from a Value tree.
func NewReferencedFields ¶
func NewReferencedFields(fields map[string]struct{}) *ReferencedFields
NewReferencedFields creates a ReferencedFields from a set of field names.
func (*ReferencedFields) Contains ¶
func (r *ReferencedFields) Contains(field string) bool
Contains reports whether the given field name is referenced.
func (*ReferencedFields) Fields ¶
func (r *ReferencedFields) Fields() map[string]struct{}
Fields returns the referenced field names.
func (*ReferencedFields) IsEmpty ¶
func (r *ReferencedFields) IsEmpty() bool
IsEmpty reports whether no fields are referenced.
func (*ReferencedFields) Size ¶
func (r *ReferencedFields) Size() int
Size returns the number of referenced fields.
func (*ReferencedFields) Union ¶
func (r *ReferencedFields) Union(other *ReferencedFields) *ReferencedFields
Union returns a new ReferencedFields containing all fields from both this and other.
type RegularMatchInfo ¶
type RegularMatchInfo struct {
// contains filtered or unexported fields
}
RegularMatchInfo is the primary implementation of MatchInfo, representing a direct match between two expressions.
Ports Java's MatchInfo.RegularMatchInfo.
func NewRegularMatchInfo ¶
func NewRegularMatchInfo( parameterBindingMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, bindingAliasMap *AliasMap, predicateMap *PredicateMultiMap, matchedOrderingParts []*MatchedOrderingPart, maxMatchMap *MaxMatchMap, groupByMappings *GroupByMappings, rollUpToGroupingValues []values.Value, additionalPlanConstraint *QueryPlanConstraint, ) *RegularMatchInfo
NewRegularMatchInfo constructs a RegularMatchInfo. All collection fields are defensively copied.
func (*RegularMatchInfo) GetAdditionalPlanConstraint ¶
func (r *RegularMatchInfo) GetAdditionalPlanConstraint() *QueryPlanConstraint
GetAdditionalPlanConstraint returns the additional plan constraint.
func (*RegularMatchInfo) GetBindingAliasMap ¶
func (r *RegularMatchInfo) GetBindingAliasMap() *AliasMap
GetBindingAliasMap returns the alias map used for binding.
func (*RegularMatchInfo) GetChildPartialMatchMaybe ¶
func (r *RegularMatchInfo) GetChildPartialMatchMaybe(alias values.CorrelationIdentifier) PartialMatch
IsAdjusted returns false -- RegularMatchInfo is not adjusted. GetChildPartialMatchMaybe returns the child PartialMatch for the given quantifier alias, or nil if no child match exists for that alias. Ports Java's RegularMatchInfo.getChildPartialMatchMaybe.
func (*RegularMatchInfo) GetGroupByMappings ¶
func (r *RegularMatchInfo) GetGroupByMappings() *GroupByMappings
GetGroupByMappings returns the group-by mappings.
func (*RegularMatchInfo) GetMatchedOrderingParts ¶
func (r *RegularMatchInfo) GetMatchedOrderingParts() []*MatchedOrderingPart
GetMatchedOrderingParts returns the matched ordering parts.
func (*RegularMatchInfo) GetMaxMatchMap ¶
func (r *RegularMatchInfo) GetMaxMatchMap() *MaxMatchMap
GetMaxMatchMap returns the maximum match map.
func (*RegularMatchInfo) GetParameterBindingMap ¶
func (r *RegularMatchInfo) GetParameterBindingMap() map[values.CorrelationIdentifier]*predicates.ComparisonRange
GetParameterBindingMap returns the parameter binding map.
func (*RegularMatchInfo) GetPredicateMap ¶
func (r *RegularMatchInfo) GetPredicateMap() *PredicateMultiMap
GetPredicateMap returns the predicate multi-map.
func (*RegularMatchInfo) GetRegularMatchInfo ¶
func (r *RegularMatchInfo) GetRegularMatchInfo() *RegularMatchInfo
GetRegularMatchInfo returns itself.
func (*RegularMatchInfo) GetRollUpToGroupingValues ¶
func (r *RegularMatchInfo) GetRollUpToGroupingValues() []values.Value
GetRollUpToGroupingValues returns the roll-up-to-grouping values, or nil if not applicable.
func (*RegularMatchInfo) IsAdjusted ¶
func (r *RegularMatchInfo) IsAdjusted() bool
func (*RegularMatchInfo) IsRegular ¶
func (r *RegularMatchInfo) IsRegular() bool
IsRegular returns true -- RegularMatchInfo is a regular match.
func (*RegularMatchInfo) SetChildPartialMatch ¶
func (r *RegularMatchInfo) SetChildPartialMatch(alias values.CorrelationIdentifier, pm PartialMatch)
SetChildPartialMatch sets the child PartialMatch for a quantifier alias. Called by MatchIntermediateRule when building composite matches.
type RegularTranslationMap ¶
type RegularTranslationMap struct {
// contains filtered or unexported fields
}
RegularTranslationMap is the standard implementation of TranslationMap backed by a map from source aliases to translation functions.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.values.translation.RegularTranslationMap.
func ComposeTranslationMaps ¶
func ComposeTranslationMaps(maps ...*RegularTranslationMap) *RegularTranslationMap
ComposeTranslationMaps creates a new RegularTranslationMap by composing multiple translation maps. Each source alias must be unique across all maps; panics on conflict.
Ports Java's RegularTranslationMap.compose.
func EmptyTranslationMap ¶
func EmptyTranslationMap() *RegularTranslationMap
EmptyTranslationMap returns a shared empty translation map. Ports Java's TranslationMap.empty() / RegularTranslationMap.empty().
func RebaseWithAliasMap ¶
func RebaseWithAliasMap(am *AliasMap) *RegularTranslationMap
RebaseWithAliasMap creates a RegularTranslationMap from an AliasMap where each source-to-target mapping generates a translation function that calls RebaseLeaf on the leaf value with the target alias.
Ports Java's TranslationMap.rebaseWithAliasMap / RegularTranslationMap.rebaseWithAliasMap.
func TranslationMapOfAliases ¶
func TranslationMapOfAliases(source, target values.CorrelationIdentifier) *RegularTranslationMap
TranslationMapOfAliases creates a RegularTranslationMap that translates a single source alias to a target alias by rebasing leaf values. Equivalent to RebaseWithAliasMap(AliasMapOfAliases(source, target)).
Ports Java's TranslationMap.ofAliases / RegularTranslationMap.ofAliases.
func (*RegularTranslationMap) ApplyTranslationFunction ¶
func (m *RegularTranslationMap) ApplyTranslationFunction(sourceAlias values.CorrelationIdentifier, leafValue values.LeafValue) values.Value
ApplyTranslationFunction applies the translation function for the given source alias to the leaf value. Panics if no translation function exists for sourceAlias.
func (*RegularTranslationMap) ContainsSourceAlias ¶
func (m *RegularTranslationMap) ContainsSourceAlias(sourceAlias values.CorrelationIdentifier) bool
ContainsSourceAlias reports whether this map has a translation for the given source alias.
func (*RegularTranslationMap) DefinesOnlyIdentities ¶
func (m *RegularTranslationMap) DefinesOnlyIdentities() bool
DefinesOnlyIdentities reports whether all mappings are identity mappings. An empty function map with an identity (or absent) alias map is considered identity-only.
Ports Java's RegularTranslationMap.definesOnlyIdentities.
func (*RegularTranslationMap) GetAliasMap ¶
func (m *RegularTranslationMap) GetAliasMap() (*AliasMap, bool)
GetAliasMap returns the underlying AliasMap if this translation map was created from one. Returns (nil, false) for plain translation maps without an alias map.
func (*RegularTranslationMap) GetTargetAlias ¶
func (m *RegularTranslationMap) GetTargetAlias(sourceAlias values.CorrelationIdentifier) (values.CorrelationIdentifier, bool)
GetTargetAlias returns the target alias for the given source alias by consulting the underlying AliasMap. Returns (zero, false) if there is no AliasMap or the source is not mapped.
type RemoveProjectionRule ¶
type RemoveProjectionRule struct {
// contains filtered or unexported fields
}
RemoveProjectionRule removes a LogicalProjectionExpression when the inner is already a physical plan (not a fetch). The projection is unnecessary because the inner plan already produces the correct row shape. The rule simply yields the inner plan, dropping the projection wrapper.
Mirrors Java's RemoveProjectionRule.
func NewRemoveProjectionRule ¶
func NewRemoveProjectionRule() *RemoveProjectionRule
func (*RemoveProjectionRule) Matcher ¶
func (r *RemoveProjectionRule) Matcher() matching.BindingMatcher
func (*RemoveProjectionRule) OnMatch ¶
func (r *RemoveProjectionRule) OnMatch(call *ImplementationRuleCall)
type RemoveRangeOneRule ¶
type RemoveRangeOneRule struct {
// contains filtered or unexported fields
}
RemoveRangeOneRule eliminates a redundant LIMIT 1 when the inner expression is guaranteed to produce at most one row.
Pattern:
LogicalLimit(limit=1, offset=0) inner → X [where X has cardinality ≤ 1]
Rewrite: X
The inner expression is considered at-most-one-row when its estimated cardinality is ≤ 1.0 (via properties.EstimateCardinality). This covers unique-index equality scans, scalar subquery results, LogicalValuesExpression (single-row constant source), and the zero-row empty-scan sentinel.
func NewRemoveRangeOneRule ¶
func NewRemoveRangeOneRule() *RemoveRangeOneRule
func (*RemoveRangeOneRule) Matcher ¶
func (r *RemoveRangeOneRule) Matcher() matching.BindingMatcher
func (*RemoveRangeOneRule) OnMatch ¶
func (r *RemoveRangeOneRule) OnMatch(call *ExpressionRuleCall)
type RequestedOrdering ¶
type RequestedOrdering struct {
// contains filtered or unexported fields
}
RequestedOrdering captures a desired sort order for a query's output. Used to communicate ordering requirements upward (toward sources) during planning. Mirrors Java's RequestedOrdering.
func NewRequestedOrdering ¶
func NewRequestedOrdering(parts []RequestedOrderingPart, d Distinctness, exhaustive bool) *RequestedOrdering
NewRequestedOrdering creates a new RequestedOrdering.
func PreserveOrdering ¶
func PreserveOrdering() *RequestedOrdering
Preserve returns a RequestedOrdering that preserves the incoming order.
func (*RequestedOrdering) Exhaustive ¶
func (o *RequestedOrdering) Exhaustive() *RequestedOrdering
Exhaustive returns a copy of this ordering with exhaustive=true. If already exhaustive, returns the receiver unchanged. Ports Java's RequestedOrdering.exhaustive().
func (*RequestedOrdering) GetDistinctness ¶
func (o *RequestedOrdering) GetDistinctness() Distinctness
GetDistinctness returns the distinctness constraint.
func (*RequestedOrdering) GetParts ¶
func (o *RequestedOrdering) GetParts() []RequestedOrderingPart
GetParts returns the ordering parts.
func (*RequestedOrdering) GetValueRequestedSortOrderMap ¶
func (o *RequestedOrdering) GetValueRequestedSortOrderMap() map[values.Value]RequestedSortOrder
GetValueRequestedSortOrderMap returns a map from Value to its requested sort order.
func (*RequestedOrdering) IsDistinct ¶
func (o *RequestedOrdering) IsDistinct() bool
IsDistinct returns true if the ordering requires distinct records.
func (*RequestedOrdering) IsExhaustive ¶
func (o *RequestedOrdering) IsExhaustive() bool
IsExhaustive returns true if we want all satisfying plans, not just the best.
func (*RequestedOrdering) IsPreserve ¶
func (o *RequestedOrdering) IsPreserve() bool
IsPreserve returns true if this ordering requests preservation of the existing order (empty parts).
func (*RequestedOrdering) PushDownThroughValue ¶
func (o *RequestedOrdering) PushDownThroughValue(resultValue values.Value, upperAlias values.CorrelationIdentifier) *RequestedOrdering
PushDownThroughValue translates this requested ordering's keys through a result value, expressing them in terms of the result value's inputs. Each ordering part's value is pushed down; sort orders are preserved. Parts that cannot be pushed down are dropped. If all parts are dropped, returns a preserve ordering.
Ports Java's RequestedOrdering.pushDown(Value, CorrelationIdentifier, EvaluationContext, AliasMap, Set<CorrelationIdentifier>).
func (*RequestedOrdering) Size ¶
func (o *RequestedOrdering) Size() int
Size returns the number of ordering parts.
type RequestedOrderingPart ¶
type RequestedOrderingPart struct {
Value values.Value
SortOrder RequestedSortOrder
}
RequestedOrderingPart is a (Value, RequestedSortOrder) pair specifying one element of a requested ordering. Mirrors Java's OrderingPart.RequestedOrderingPart.
type RequestedSortOrder ¶
type RequestedSortOrder int
RequestedSortOrder specifies the desired sort direction (and NULL placement) for one ordering part. Mirrors Java's OrderingPart.RequestedSortOrder, where each directional value maps to a TupleOrdering.Direction:
Ascending -> ASC_NULLS_FIRST (ascending, nulls first; counterflow=false) Descending -> DESC_NULLS_LAST (descending, nulls last; counterflow=false) AscendingNullsLast -> ASC_NULLS_LAST (ascending, nulls last; counterflow=true) DescendingNullsFirst -> DESC_NULLS_FIRST (descending, nulls first; counterflow=true)
"Counterflow nulls" means the requested NULL placement runs against the natural FDB tuple order for that direction (ASC defaults nulls-first, DESC defaults nulls-last). This is the property Java's ProvidedSortOrder.isCompatibleWithRequestedSortOrder gates on.
const ( RequestedSortOrderAny RequestedSortOrder = iota RequestedSortOrderAscending RequestedSortOrderDescending RequestedSortOrderAscendingNullsLast RequestedSortOrderDescendingNullsFirst )
func (RequestedSortOrder) IsAnyAscending ¶
func (s RequestedSortOrder) IsAnyAscending() bool
IsAnyAscending reports whether this is an ascending direction (nulls first or last). Mirrors Java SortOrder.isAnyAscending().
func (RequestedSortOrder) IsAnyDescending ¶
func (s RequestedSortOrder) IsAnyDescending() bool
IsAnyDescending reports whether this is a descending direction (nulls first or last). Mirrors Java SortOrder.isAnyDescending().
func (RequestedSortOrder) IsCounterflowNulls ¶
func (s RequestedSortOrder) IsCounterflowNulls() bool
IsCounterflowNulls reports whether the requested NULL placement runs against the natural tuple order for this direction. Mirrors Java TupleOrdering.Direction.isCounterflowNulls(). Only valid for directional values (Java verifies isDirectional first).
func (RequestedSortOrder) IsDirectional ¶
func (s RequestedSortOrder) IsDirectional() bool
type ResultCompensationFunction ¶
type ResultCompensationFunction struct {
// contains filtered or unexported fields
}
ResultCompensationFunction handles final result shape transformation. Ports Java's PredicateMultiMap.ResultCompensationFunction.
func NewImpossibleResultCompensation ¶
func NewImpossibleResultCompensation() *ResultCompensationFunction
NewImpossibleResultCompensation creates a ResultCompensationFunction that is both needed and impossible.
func NewResultCompensationFunction ¶
func NewResultCompensationFunction(needed bool) *ResultCompensationFunction
NewResultCompensationFunction creates a ResultCompensationFunction.
func NoResultCompensation ¶
func NoResultCompensation() *ResultCompensationFunction
NoResultCompensation returns a ResultCompensationFunction that indicates no result compensation is needed. Mirrors Java's ResultCompensationFunction.noCompensationNeeded().
func ResultCompensationOfValue ¶
func ResultCompensationOfValue(v values.Value) *ResultCompensationFunction
ResultCompensationOfValue creates a ResultCompensationFunction from a result Value. When applied, it translates the value through the translation map. Ports Java's ResultCompensationFunction.ofValue.
func (*ResultCompensationFunction) Amend ¶
func (f *ResultCompensationFunction) Amend( unmatchedAggregateMap *BiMap[values.CorrelationIdentifier, values.Value], amendedMatchedAggregateMap map[values.Value]values.Value, ) *ResultCompensationFunction
Amend recreates the result compensation function with updated aggregate value mappings. Ports Java's ResultCompensationFunction.amend.
func (*ResultCompensationFunction) ApplyCompensationForResult ¶
func (f *ResultCompensationFunction) ApplyCompensationForResult(tm TranslationMap) values.Value
ApplyCompensationForResult applies this compensation by translating the result value through the translation map. Returns the compensated result value. Ports Java's ResultCompensationFunction.applyCompensationForResult.
func (*ResultCompensationFunction) IsImpossible ¶
func (f *ResultCompensationFunction) IsImpossible() bool
IsImpossible reports whether result compensation is impossible.
func (*ResultCompensationFunction) IsNeeded ¶
func (f *ResultCompensationFunction) IsNeeded() bool
IsNeeded reports whether result compensation must be applied.
type RewriteOuterJoinRule ¶
type RewriteOuterJoinRule struct {
// contains filtered or unexported fields
}
RewriteOuterJoinRule canonicalizes a LEFT OUTER join SelectExpression into the nested form Java uses (rules/RewriteOuterJoinRule.java + expressions/OuterJoin Expression.java): the ON-predicates are pushed BELOW the null-extension boundary into a correlated null-supplying inner SELECT, and the join becomes an INNER SelectExpression over the preserved leg plus a NULL-on-empty quantifier carrying the outer-join semantics.
Go encodes an outer join as a flat 2-quantifier SelectExpression with joinType=JoinLeftOuter and the ON-predicates in the top-level predicate list (the translator keeps WHERE *above* the join for LEFT OUTER, so every predicate here is an ON-predicate). Java's RewriteOuterJoinRule matches an OuterJoinExpression; Go matches the LEFT-OUTER SelectExpression directly, since Go carries outer-join on the flag rather than a dedicated logical box. That is the only deviation from a 1:1 port, forced by Go's representation.
Why this is needed (RFC-150 Phase-2b Piece 2): without it, neither PartitionBinarySelectRule nor PushFilterBelowJoinRule fires (both guard on JoinInner), so no leg becomes correlated, and the data-access FlatMap path (yieldGeneralFlatMap) never produces a correlated LEFT-OUTER FlatMap. This rule creates the correlation Java's single path relies on — it is what let the former Go-only tryFlatMapPlan (a hand-rolled inner-pushed-residual shortcut) be retired: the correlated LEFT-OUTER FlatMap now emerges from the standard data-access path.
Correctness (the LEFT-OUTER axis): the ON-predicates MUST filter the inner stream BEFORE the empty→NULL extension. Folding them into innerSelect (below the NULL-on-empty quantifier) does exactly that — applying an ON-predicate above the FlatMap, after the NULL row is injected, would drop that row and silently degrade LEFT OUTER into INNER. The outer SelectExpression carries NO predicates, so there is nothing left to apply above the join. Mirrors Java RewriteOuterJoinRule.
func NewRewriteOuterJoinRule ¶
func NewRewriteOuterJoinRule() *RewriteOuterJoinRule
NewRewriteOuterJoinRule constructs the rule.
func (*RewriteOuterJoinRule) Matcher ¶
func (r *RewriteOuterJoinRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*RewriteOuterJoinRule) OnMatch ¶
func (r *RewriteOuterJoinRule) OnMatch(call *ExpressionRuleCall)
OnMatch rewrites a LEFT OUTER SelectExpression into the INNER + null-on-empty form.
type RichOrdering ¶
type RichOrdering struct {
// contains filtered or unexported fields
}
RichOrdering captures a provided ordering as a binding map (Value → []OrderingBinding) plus a partially ordered set of value keys and a distinctness flag.
The ordering set is a PartiallyOrderedSet[string] keyed by ExplainValue(v). A reverse map resolves keys back to values.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.Ordering.
func ConcatOrderings ¶
func ConcatOrderings(outer, inner *RichOrdering) *RichOrdering
ConcatOrderings concatenates two orderings using proper partial-order semantics. The maximum elements of the left ordering become dependencies of the minimum elements of the right ordering (for non-fixed keys).
func CreateUnionOrdering ¶
func CreateUnionOrdering(o *RichOrdering) *RichOrdering
CreateUnionOrdering creates a RichOrdering from a single provided ordering, treating all sorted bindings as union-compatible. Used as the starting point for union-merge in ImplementDistinctUnionRule.
func EmptyOrdering ¶
func EmptyOrdering() *RichOrdering
EmptyOrdering returns an ordering with no keys.
func MergeOrderings ¶
func MergeOrderings(a, b *RichOrdering) *RichOrdering
MergeOrderings merges two orderings (union semantics, backward-compat alias).
func MergeOrderingsForIntersection ¶
func MergeOrderingsForIntersection(a, b *RichOrdering) *RichOrdering
MergeOrderingsForIntersection merges two orderings with intersection semantics.
func MergeOrderingsForUnion ¶
func MergeOrderingsForUnion(a, b *RichOrdering) *RichOrdering
MergeOrderingsForUnion merges two orderings with union semantics. Uses the full EligibleSet-based merge algorithm from Java.
func NewRichOrdering ¶
func NewRichOrdering( bindingMap map[values.Value][]OrderingBinding, keys []values.Value, distinct bool, ) *RichOrdering
NewRichOrdering creates a new ordering from bindings, key sequence, and distinctness. The ordering set is a total order matching the key sequence.
func NewRichOrderingWithDeps ¶
func NewRichOrderingWithDeps( bindingMap map[values.Value][]OrderingBinding, keys []values.Value, deps combinatorics.SetMultimap[string], distinct bool, ) *RichOrdering
NewRichOrderingWithDeps creates an ordering with explicit dependency edges in the ordering set.
func (*RichOrdering) DirectionalOrderingParts ¶
func (o *RichOrdering) DirectionalOrderingParts( keyValues []values.Value, requested *RequestedOrdering, fixedOrder ProvidedSortOrder, ) []ProvidedOrderingPart
DirectionalOrderingParts creates ProvidedOrderingParts from a key sequence with sort directions from the binding map. Fixed keys get the provided fixedOrder direction.
func (*RichOrdering) EnumerateCompatibleRequestedOrderings ¶
func (o *RichOrdering) EnumerateCompatibleRequestedOrderings( requested *RequestedOrdering, ) [][]RequestedOrderingPart
EnumerateCompatibleRequestedOrderings enumerates all valid orderings of the full ordering set that are compatible with the requested ordering prefix. Each result is a full-length sequence of RequestedOrderingParts (one per key in the ordering set).
func (*RichOrdering) EnumerateSatisfyingComparisonKeyValues ¶
func (o *RichOrdering) EnumerateSatisfyingComparisonKeyValues( requested *RequestedOrdering, ) [][]values.Value
EnumerateSatisfyingComparisonKeyValues enumerates the comparison key sequences from this ordering that satisfy the requested ordering. Uses TopologicalSort.satisfyingPermutations on the partial order to find all valid orderings.
func (*RichOrdering) GetBindingMap ¶
func (o *RichOrdering) GetBindingMap() map[values.Value][]OrderingBinding
GetBindingMap returns the binding map.
func (*RichOrdering) GetEqualityBoundValues ¶
func (o *RichOrdering) GetEqualityBoundValues() map[values.Value]struct{}
GetEqualityBoundValues returns the set of values that have at least one fixed (equality-bound) binding. Matches Java's Ordering.getEqualityBoundValues() which uses Multimaps.filterValues(Binding::isFixed).keySet().
func (*RichOrdering) GetKeys ¶
func (o *RichOrdering) GetKeys() []values.Value
GetKeys returns the ordering keys in sequence.
func (*RichOrdering) GetOrderingKeys ¶
func (o *RichOrdering) GetOrderingKeys() []values.Value
GetOrderingKeys returns the non-equality-bound ordering keys (those that contribute to the sort order). Mirrors Java's Ordering.getOrderingSet().getSet() filtered to the keys list.
func (*RichOrdering) IsDistinct ¶
func (o *RichOrdering) IsDistinct() bool
IsDistinct returns whether the ordering guarantees distinct output.
func (*RichOrdering) IsSingularNonFixedValue ¶
func (o *RichOrdering) IsSingularNonFixedValue(v values.Value) bool
IsSingularNonFixedValue returns true if the value has exactly one binding and that binding is not fixed (sorted or choose).
func (*RichOrdering) OrderingSet ¶
func (o *RichOrdering) OrderingSet() *combinatorics.PartiallyOrderedSet[string]
OrderingSet returns the partially ordered set of value keys.
func (*RichOrdering) PullUp ¶
func (o *RichOrdering) PullUp(mapping map[string]values.Value) *RichOrdering
PullUp translates this ordering through a string-keyed value mapping. For each ordering key, if the mapping contains a replacement (keyed by ExplainValue string), the key is renamed. Bindings are preserved. Keys not in the mapping are dropped.
This is the simpler of two pull-up paths:
- PullUp(mapping): string-keyed FieldValue-to-FieldValue renaming. Used by projection rules and callers that build an explicit rename map.
- PullUpThroughValue(resultValue, alias): full Value-tree-aware pull-up via values.PullUpValue. Handles RecordConstructorValue decomposition and passthrough (QOV/ObjectValue) semantics. Used by callers that have a result-value structure rather than a flat rename map.
Both paths produce correct results for their use cases. Callers should prefer PullUpThroughValue when the result value is available, as it handles nested value structures (e.g. record constructors) that a flat string map cannot represent.
func (*RichOrdering) PullUpThroughValue ¶
func (o *RichOrdering) PullUpThroughValue(resultValue values.Value, alias values.CorrelationIdentifier) *RichOrdering
PullUpThroughValue translates this ordering through a result value. For each ordering key, uses Value.PullUpValue to compute the pulled-up key. Bindings are preserved. Keys that cannot be pulled up are dropped.
Ports Java's Ordering.pullUp(Value, EvaluationContext, AliasMap, Set<CorrelationIdentifier>) using the direct algorithmic pullUp from values.PullUpValue.
func (*RichOrdering) PushDown ¶
func (o *RichOrdering) PushDown(mapping map[string]values.Value) *RichOrdering
PushDown is the inverse of PullUp — translates ordering keys back through a reverse mapping.
func (*RichOrdering) PushDownThroughValue ¶
func (o *RichOrdering) PushDownThroughValue(resultValue values.Value, upperAlias values.CorrelationIdentifier) *RichOrdering
PushDownThroughValue translates this ordering's keys from output space back to input space through a result value. For each ordering key, uses Value.PushDownValue to compute the pushed-down key. Bindings are preserved. Keys that cannot be pushed down are dropped.
Ports Java's Ordering.pushDown(Value, EvaluationContext, AliasMap, Set<CorrelationIdentifier>).
func (*RichOrdering) Satisfies ¶
func (o *RichOrdering) Satisfies(requested *RequestedOrdering) bool
Satisfies checks whether this provided ordering satisfies the given requested ordering. Uses the partial order to enumerate valid permutations that match the request prefix.
func (*RichOrdering) SatisfiesGroupingValues ¶
func (o *RichOrdering) SatisfiesGroupingValues(groupingValues map[string]struct{}) bool
SatisfiesGroupingValues checks whether the given set of values can form a valid prefix of some topological ordering of this ordering set.
func (*RichOrdering) ValueForKey ¶
func (o *RichOrdering) ValueForKey(key string) values.Value
ValueForKey resolves a string key back to its Value.
type RichOrderingHinter ¶
type RichOrderingHinter interface {
HintRichOrdering() *RichOrdering
}
RichOrderingHinter is the optional interface a wrapper implements to provide full ordering info with bindings. Falls back to converting from HintOrdering if not implemented.
type RuleCall ¶
type RuleCall struct {
// Bindings is the PlannerBindings the rule's matcher built up
// during BindMatches. Rule bodies use Get[T] / Get to retrieve
// matched values.
Bindings *matching.PlannerBindings
// contains filtered or unexported fields
}
RuleCall is the context a CascadesRule receives on every match. OnMatch reads bindings and appends replacement expressions via Yield.
type ScanDirection ¶
type ScanDirection int
ScanDirection indicates whether an access scans forward, reverse, or both. Ports Java's AbstractDataAccessRule.ScanDirection.
const ( ScanDirectionForward ScanDirection = iota ScanDirectionReverse ScanDirectionBoth )
func SatisfiesRequestedOrdering ¶
func SatisfiesRequestedOrdering(pm PartialMatch, ro *RequestedOrdering) *ScanDirection
SatisfiesRequestedOrdering checks if a PartialMatch's matched ordering parts satisfy a RequestedOrdering. Returns the scan direction needed, or nil if the ordering is not satisfied.
Ports Java's AbstractDataAccessRule.satisfiesRequestedOrdering.
type ScanWithFetchMatchCandidate ¶
type ScanWithFetchMatchCandidate interface {
MatchCandidate
// PushValueThroughFetch attempts to translate a value from the
// full-record domain (correlated to sourceAlias) to the
// index-entry domain (correlated to targetAlias). Returns the
// translated value and true on success; nil and false if the
// value cannot be expressed using only the index entry's columns.
//
// Ports Java's ScanWithFetchMatchCandidate.pushValueThroughFetch.
PushValueThroughFetch(
value values.Value,
sourceAlias values.CorrelationIdentifier,
targetAlias values.CorrelationIdentifier,
) (values.Value, bool)
}
ScanWithFetchMatchCandidate is the interface for match candidates that support the covering-index-to-fetch pattern. When an index scan covers enough columns, the fetch can be deferred; when it doesn't, a FetchFromPartialRecordPlan wraps the scan.
The key method is PushValueThroughFetch, which attempts to translate a single Value from the full-record domain (correlated to sourceAlias) to the index-entry domain (correlated to targetAlias). If translation succeeds, the value can be evaluated on the partial/covering record without a full fetch.
Ports Java's `com.apple.foundationdb.record.query.plan.cascades.ScanWithFetchMatchCandidate`.
type SealedGraphExpansion ¶
type SealedGraphExpansion struct {
// contains filtered or unexported fields
}
SealedGraphExpansion is an immutable, deduplicated version of GraphExpansion. Created by Seal(). Used to (repeatedly) build SelectExpressions. Mirrors Java's `GraphExpansion.Sealed`.
func (*SealedGraphExpansion) BuildSelect ¶
func (s *SealedGraphExpansion) BuildSelect() *expressions.SelectExpression
BuildSelect creates a SelectExpression using the sealed columns' RecordConstructorValue as the result value. Mirrors Java's `Sealed.buildSelect()`.
func (*SealedGraphExpansion) BuildSelectWithResultValue ¶
func (s *SealedGraphExpansion) BuildSelectWithResultValue(resultValue values.Value) *expressions.SelectExpression
BuildSelectWithResultValue creates a SelectExpression with an externally-provided result value. The sealed expansion must have no result columns (panics otherwise, matching Java's `Verify.verify(resultColumns.isEmpty())`). Mirrors Java's `Sealed.buildSelectWithResultValue(resultValue)`.
func (*SealedGraphExpansion) GetPlaceholders ¶
func (s *SealedGraphExpansion) GetPlaceholders() []*predicates.Placeholder
GetPlaceholders returns the sealed placeholder list.
func (*SealedGraphExpansion) GetPredicates ¶
func (s *SealedGraphExpansion) GetPredicates() []predicates.QueryPredicate
GetPredicates returns the sealed predicate list.
func (*SealedGraphExpansion) GetQuantifiers ¶
func (s *SealedGraphExpansion) GetQuantifiers() []expressions.Quantifier
GetQuantifiers returns the sealed quantifier list.
func (*SealedGraphExpansion) GetResultColumns ¶
func (s *SealedGraphExpansion) GetResultColumns() []GraphExpansionColumn
GetResultColumns returns the sealed result columns.
func (*SealedGraphExpansion) GetResultValue ¶
func (s *SealedGraphExpansion) GetResultValue() values.Value
GetResultValue returns the RecordConstructorValue built from the result columns during sealing. Nil if there were no columns.
type SelectMergeRule ¶
type SelectMergeRule struct {
// contains filtered or unexported fields
}
SelectMergeRule merges nested Select/Filter expressions into a single, flatter SelectExpression. When a SelectExpression has a ForEach quantifier whose child Reference holds a LogicalFilterExpression or another SelectExpression, this rule pulls up the child's quantifiers and predicates into the parent.
Pattern (LogicalFilter child):
SelectExpression( ForEach(alias=A) → Ref[LogicalFilter(preds, ForEach(alias=B) → Ref[scan])], ...other quantifiers..., outerPreds )
Rewrite:
SelectExpression( ForEach(alias=B) → Ref[scan], ...other quantifiers..., rebase(outerPreds, A→B) + preds )
Pattern (SelectExpression child):
SelectExpression( ForEach(alias=A) → Ref[SelectExpression([q1,q2,...], childPreds, childResult)], ...other quantifiers..., outerPreds )
Rewrite:
SelectExpression( q1, q2, ..., ...other quantifiers..., rebase(outerPreds, A→childResult) + rebase(childPreds) + outerPreds )
Ports Java's SelectMergeRule (ImplementationCascadesRule). Placed in EXPLORE as an ExpressionRule because Go's PLANNING phase does not support multi-round implementation. Functionally equivalent: the merged Select is explored + matched + implemented normally.
Convergence: each firing strictly reduces nesting depth. A flat Select with no mergeable children causes zero yields.
func NewSelectMergeRule ¶
func NewSelectMergeRule() *SelectMergeRule
func (*SelectMergeRule) Matcher ¶
func (r *SelectMergeRule) Matcher() matching.BindingMatcher
func (*SelectMergeRule) OnMatch ¶
func (r *SelectMergeRule) OnMatch(call *ExpressionRuleCall)
type SingleMatchedAccess ¶
type SingleMatchedAccess struct {
// contains filtered or unexported fields
}
SingleMatchedAccess wraps a PartialMatch with its computed Compensation and metadata about how it can be used for data access. It is a value object produced during the prepareMatchesAndCompensations phase of AbstractDataAccessRule.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.rules.AbstractDataAccessRule.SingleMatchedAccess.
func NewSingleMatchedAccess ¶
func NewSingleMatchedAccess( partialMatch PartialMatch, compensation Compensation, candidateTopAlias values.CorrelationIdentifier, reverseScanOrder bool, topToTopTranslationMap TranslationMap, satisfyingRequestedOrderings []*RequestedOrdering, ) *SingleMatchedAccess
NewSingleMatchedAccess constructs a SingleMatchedAccess. The satisfyingRequestedOrderings slice is defensively copied.
Mirrors Java's SingleMatchedAccess constructor.
func PrepareMatchesAndCompensations ¶
func PrepareMatchesAndCompensations( partialMatches []PartialMatch, requestedOrderings []*RequestedOrdering, _ PlanContext, ) []*SingleMatchedAccess
PrepareMatchesAndCompensations compensates and sorts partial matches by coverage (descending bound predicate count). For each PartialMatch:
- assigns a unique candidateTopAlias
- computes compensation via CompensateCompleteMatch
- computes satisfying orderings via SatisfiesAnyRequestedOrderings
- creates a forward-scan SingleMatchedAccess with empty translation
Returns the accesses sorted by coverage (highest first).
Ports Java's AbstractDataAccessRule.prepareMatchesAndCompensations.
func (*SingleMatchedAccess) GetCandidateTopAlias ¶
func (s *SingleMatchedAccess) GetCandidateTopAlias() values.CorrelationIdentifier
GetCandidateTopAlias returns the correlation identifier for the candidate's top-level quantifier.
func (*SingleMatchedAccess) GetCompensation ¶
func (s *SingleMatchedAccess) GetCompensation() Compensation
GetCompensation returns the compensation computed for this match.
func (*SingleMatchedAccess) GetPartialMatch ¶
func (s *SingleMatchedAccess) GetPartialMatch() PartialMatch
GetPartialMatch returns the partial match this access was derived from.
func (*SingleMatchedAccess) GetPulledUpGroupByMappingsForOrdering ¶
func (s *SingleMatchedAccess) GetPulledUpGroupByMappingsForOrdering() *GroupByMappings
GetPulledUpGroupByMappingsForOrdering returns the pulled-up group-by mappings, lazily computed on first access. Mirrors Java's getPulledUpGroupByMappingsForOrdering().
func (*SingleMatchedAccess) GetSatisfyingRequestedOrderings ¶
func (s *SingleMatchedAccess) GetSatisfyingRequestedOrderings() []*RequestedOrdering
GetSatisfyingRequestedOrderings returns the set of requested orderings that this access satisfies.
func (*SingleMatchedAccess) GetTopToTopTranslationMap ¶
func (s *SingleMatchedAccess) GetTopToTopTranslationMap() TranslationMap
GetTopToTopTranslationMap returns the translation map between query and candidate top-level aliases.
func (*SingleMatchedAccess) IsReverseScanOrder ¶
func (s *SingleMatchedAccess) IsReverseScanOrder() bool
IsReverseScanOrder reports whether the scan should be in reverse order.
func (*SingleMatchedAccess) String ¶
func (s *SingleMatchedAccess) String() string
String returns a human-readable representation mirroring Java's SingleMatchedAccess.toString(). Note: Java's label for reverseScanOrder is inverted (true -> "forward", false -> "reverse"); we match that exactly.
type SinkLimitIntoVectorScanRule ¶
type SinkLimitIntoVectorScanRule struct {
// contains filtered or unexported fields
}
SinkLimitIntoVectorScanRule folds a Limit(k) that sits DIRECTLY above a distance-ordered VectorIndexScan (RFC-156 Phase B) back into the scan's self-limiting top-k mode — restoring the legacy one-shot search(k) fast path for the no-residual and partition-only cases, byte-for-byte.
Pattern:
Limit(k) → VectorIndexScan(ordered) → VectorIndexScan(self-limit k)
The rule fires ONLY when the Limit is directly above the ordered vector scan with NO intervening row-dropping / order-disturbing operator (i.e. no residual Filter). When a residual Filter intervenes the rule does NOT fire, and the scan must stream its re-ranked horizon so the Filter+Limit collect the true k nearest MATCHING rows — the whole point of the Phase B fix.
This is the decoupled "sink" half of the Cascades match-then-implement split (Graefe 1995): the match candidate emits ONE canonical ordered-stream form (it never sinks k and never introspects residuals); this rule, and only this rule, folds k into the scan when it is provably safe to do so.
Modeled on MergeFetchIntoCoveringIndexRule (a physical→physical ImplementationRule that yields the inner leaf in place of its wrapper when a structural condition holds).
func NewSinkLimitIntoVectorScanRule ¶
func NewSinkLimitIntoVectorScanRule() *SinkLimitIntoVectorScanRule
func (*SinkLimitIntoVectorScanRule) Matcher ¶
func (r *SinkLimitIntoVectorScanRule) Matcher() matching.BindingMatcher
func (*SinkLimitIntoVectorScanRule) OnMatch ¶
func (r *SinkLimitIntoVectorScanRule) OnMatch(call *ImplementationRuleCall)
type SortConstantKeysElimRule ¶
type SortConstantKeysElimRule struct {
// contains filtered or unexported fields
}
SortConstantKeysElimRule eliminates a LogicalSort whose every key is a row-independent constant.
Sort([ConstantValue(42), ConstantValue('x')], X) → X
SQL semantic: ORDER BY 42 sorts rows by a value that's the same for every row — the resulting order is undefined / arbitrary. Same for ORDER BY 'x', BY TRUE, BY NULL. Stripping the sort doesn't change result-set semantics; it just removes wasted work.
Soundness: IsConstantValue answers "this Value's Evaluate is independent of the row context" — exactly the property we need for "all rows would sort to the same key". When every sort key has IsConstantValue=true, the sort produces no ordering refinement.
Termination: yields the inner expression directly (no new wrapper). Pointer-identity dedup on second fire — the inner is the same expression object as before.
Edge case — empty sort: Sort([]) is the Unsorted form, which UnsortedSortElim handles independently. Letting both rules fire is harmless (UnsortedSortElim hits first; this rule's emptiness check declines).
func NewSortConstantKeysElimRule ¶
func NewSortConstantKeysElimRule() *SortConstantKeysElimRule
NewSortConstantKeysElimRule constructs the rule.
func (*SortConstantKeysElimRule) Matcher ¶
func (r *SortConstantKeysElimRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*SortConstantKeysElimRule) OnMatch ¶
func (r *SortConstantKeysElimRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the sort has at least one key AND every key's Value is row-context-independent (IsConstantValue=true).
type SortDedupKeysRule ¶
type SortDedupKeysRule struct {
// contains filtered or unexported fields
}
SortDedupKeysRule removes structurally-duplicate sort keys from a LogicalSort.
Sort([k1, k2, k1, k3], X) → Sort([k1, k2, k3], X)
SQL semantics: ORDER BY a, b, a is equivalent to ORDER BY a, b — the second `a` adds no ordering refinement (rows already in a-order remain in a-order regardless of subsequent keys repeating).
Sort keys are compared by Explain text (the same textual bridge as LogicalSortExpression.EqualsWithoutChildren), so "duplicate key" is decided structurally. Reverse flag matters: a key with the same Value but different Reverse is NOT a duplicate (different ordering direction).
Termination: yields Sort with the deduped key list, REUSING the inner Quantifier. Pointer-identity dedup absorbs second fire.
func NewSortDedupKeysRule ¶
func NewSortDedupKeysRule() *SortDedupKeysRule
NewSortDedupKeysRule constructs the rule.
func (*SortDedupKeysRule) Matcher ¶
func (r *SortDedupKeysRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*SortDedupKeysRule) OnMatch ¶
func (r *SortDedupKeysRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the sort key list contains at least one duplicate-by-Value-and-Reverse pair.
type SortMergeRule ¶
type SortMergeRule struct {
// contains filtered or unexported fields
}
SortMergeRule eliminates a wasted inner sort when its result is immediately re-sorted by an outer LogicalSortExpression.
Sort([k1, k2, ...]) over Sort([j1, j2, ...]) over X → Sort([k1, k2, ...]) over X
The outer sort fully determines the final order — the inner sort's work is discarded the moment the outer re-orders. Eliminating the inner sort never changes the result rows OR their final order; it only saves the wasted intermediate ordering work.
Edge cases:
- If the outer sort is unsorted (Sort([])), the rewrite would destroy the inner's ordering. Decline in that case — the UnsortedSortElim rule handles unsorted Sorts on its own pass by eliminating them from outer-side inputs.
- If the inner sort is unsorted (Sort([])), the rule still fires: dropping a no-op intermediate is cheap and structurally cleaner. (Technically UnsortedSortElim would also have caught the inner by itself — but having both rules cooperate is fine.)
Java equivalent: emerges from cost preference for fewer operators. Seed implements directly so the optimiser's logical phase produces a concretely-cleaner tree before B4 cost lands.
func NewSortMergeRule ¶
func NewSortMergeRule() *SortMergeRule
NewSortMergeRule constructs the rule.
func (*SortMergeRule) Matcher ¶
func (r *SortMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*SortMergeRule) OnMatch ¶
func (r *SortMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over another LogicalSort AND the outer is non-empty (otherwise the rewrite would destroy the inner's ordering — see doc comment).
type SortedInParameterSource ¶
type SortedInParameterSource struct {
// contains filtered or unexported fields
}
SortedInParameterSource is like InParameterSource but sorted.
func NewSortedInParameterSource ¶
func NewSortedInParameterSource(bindingName, parameterName string, reverse bool) *SortedInParameterSource
func (*SortedInParameterSource) GetBindingName ¶
func (s *SortedInParameterSource) GetBindingName() string
func (*SortedInParameterSource) GetParameterName ¶
func (s *SortedInParameterSource) GetParameterName() string
func (*SortedInParameterSource) IsReverse ¶
func (s *SortedInParameterSource) IsReverse() bool
func (*SortedInParameterSource) IsSorted ¶
func (s *SortedInParameterSource) IsSorted() bool
type SortedInValuesSource ¶
type SortedInValuesSource struct {
// contains filtered or unexported fields
}
SortedInValuesSource is like InValuesSource but indicates the values are sorted (ascending or descending).
func NewSortedInValuesSource ¶
func NewSortedInValuesSource(bindingName string, vals []any, reverse bool) *SortedInValuesSource
func (*SortedInValuesSource) GetBindingName ¶
func (s *SortedInValuesSource) GetBindingName() string
func (*SortedInValuesSource) GetValues ¶
func (s *SortedInValuesSource) GetValues() []any
func (*SortedInValuesSource) IsReverse ¶
func (s *SortedInValuesSource) IsReverse() bool
func (*SortedInValuesSource) IsSorted ¶
func (s *SortedInValuesSource) IsSorted() bool
type SplitSelectExtractIndependentQuantifiersRule ¶
type SplitSelectExtractIndependentQuantifiersRule struct {
// contains filtered or unexported fields
}
SplitSelectExtractIndependentQuantifiersRule splits a SelectExpression into two when one or more ForEach quantifiers ranging over ExplodeExpressions are fully independent — not correlated to any other quantifier in the SelectExpression.
The independent quantifiers are extracted into an outer SelectExpression; the correlated quantifiers remain in the inner. This is safe and often beneficial because the extracted quantifiers range over ExplodeExpressions (bounded cardinality), so the outer cross-product is small. Star-join optimisations benefit from this partitioning.
Ports Java's SplitSelectExtractIndependentQuantifiersRule (184 LOC).
Algorithm:
- Match a SelectExpression with at least one ForEach quantifier ranging over an ExplodeExpression.
- Build a PartiallyOrderedSet of all quantifier aliases, with dependency edges derived from correlation analysis (quantifier A depends on alias B if A's inner expression is correlated to B).
- Compute the eligible set — aliases with no dependencies (in-degree zero in the partial order). Only explode-backed ForEach quantifiers that are eligible are candidates for extraction.
- Partition quantifiers into lower (non-eligible or non-explode) and upper (eligible explode). Both partitions must be non-empty, and the lower must contain at least one ForEach.
- Guard: skip if the SelectExpression is "simple" — no predicates and the result value doesn't reference any explode alias.
- Yield: lower quantifiers + all predicates go into the inner SelectExpression; the outer gets the upper quantifiers plus a new ForEach over the inner, with the inner's flowed-object value as its result.
Convergence: each firing strictly reduces the number of quantifiers in the inner SelectExpression. The isSimpleSelect guard prevents infinite expansion when the result is already trivially structured.
func NewSplitSelectExtractIndependentQuantifiersRule ¶
func NewSplitSelectExtractIndependentQuantifiersRule() *SplitSelectExtractIndependentQuantifiersRule
func (*SplitSelectExtractIndependentQuantifiersRule) Matcher ¶
func (r *SplitSelectExtractIndependentQuantifiersRule) Matcher() matching.BindingMatcher
func (*SplitSelectExtractIndependentQuantifiersRule) OnMatch ¶
func (r *SplitSelectExtractIndependentQuantifiersRule) OnMatch(call *ExpressionRuleCall)
type StreamingAggFromIndexRule ¶
type StreamingAggFromIndexRule struct {
// contains filtered or unexported fields
}
StreamingAggFromIndexRule directly converts a GroupByExpression into a streaming aggregation over an ordered index scan when an index's leading columns cover the grouping keys. This fires even without an explicit Sort expression in the tree — the index ordering is sufficient.
GroupBy(keys=[k1, k2], aggs=[...], FullScan) → StreamingAgg(IndexScan(full-range, index on (k1, k2, ...)))
Without this rule, the planner would need Sort(keys, Scan) below the GroupBy for the streaming agg path to trigger. This rule closes the gap for queries like "SELECT region, COUNT(*) FROM t GROUP BY region" where the user doesn't specify ORDER BY but an index on (region) exists.
func NewStreamingAggFromIndexRule ¶
func NewStreamingAggFromIndexRule() *StreamingAggFromIndexRule
func (*StreamingAggFromIndexRule) Matcher ¶
func (r *StreamingAggFromIndexRule) Matcher() matching.BindingMatcher
func (*StreamingAggFromIndexRule) OnMatch ¶
func (r *StreamingAggFromIndexRule) OnMatch(call *ExpressionRuleCall)
type Task ¶
type Task interface {
Run(p *Planner)
}
Task is the task-stack driver's unit of work. Tasks are Run against the planner; they may push more tasks.
type TempTable ¶
type TempTable struct {
// contains filtered or unexported fields
}
TempTable is a mutable in-memory buffer used as intermediate storage for recursive CTE evaluation. Thread-safe.
func NewTempTable ¶
func NewTempTable() *TempTable
type TransformExprTask ¶
type TransformExprTask struct {
Phase PlannerPhase
Ref *expressions.Reference
Expr expressions.RelationalExpression
Rule ExpressionRule
}
TransformExprTask fires a single ExpressionRule on a (group, expression) pair. Yields go to exploratory members (ref.Insert). Mirrors Java's TransformExpression for ExplorationCascadesRule.
func (*TransformExprTask) Run ¶
func (t *TransformExprTask) Run(p *Planner)
type TransformImplTask ¶
type TransformImplTask struct {
Phase PlannerPhase
Ref *expressions.Reference
Expr expressions.RelationalExpression
Rule ImplementationRule
}
TransformImplTask fires a single ImplementationRule on a (group, expression) pair. Yields go to final members (ref.InsertFinal). Mirrors Java's TransformExpression for ImplementationCascadesRule.
func (*TransformImplTask) Run ¶
func (t *TransformImplTask) Run(p *Planner)
type TranslationFunction ¶
type TranslationFunction func(sourceAlias values.CorrelationIdentifier, leafValue values.LeafValue) values.Value
TranslationFunction is the function type used to specify the translation to take place when a leaf value with a particular source alias is encountered.
Ports Java's TranslationMap.TranslationFunction functional interface.
type TranslationMap ¶
type TranslationMap interface {
// ContainsSourceAlias reports whether this map has a translation
// for the given source alias.
ContainsSourceAlias(sourceAlias values.CorrelationIdentifier) bool
// GetTargetAlias returns the target alias for the given source
// alias. Returns (target, true) if the mapping exists, or
// (zero, false) if not.
GetTargetAlias(sourceAlias values.CorrelationIdentifier) (values.CorrelationIdentifier, bool)
// ApplyTranslationFunction applies the translation function for
// the given source alias to the leaf value. Panics if no
// translation exists for sourceAlias (callers must check
// ContainsSourceAlias first).
//
// Ports Java's TranslationMap.applyTranslationFunction.
ApplyTranslationFunction(sourceAlias values.CorrelationIdentifier, leafValue values.LeafValue) values.Value
// GetAliasMap returns the underlying AliasMap if this translation
// map is alias-based. Returns (aliasMap, true) when available, or
// (nil, false) for translation maps that are not backed by an
// AliasMap.
GetAliasMap() (*AliasMap, bool)
// DefinesOnlyIdentities reports whether all mappings in this
// translation map are identity mappings (source == target with
// identity translation function). An empty map is considered
// identity-only.
DefinesOnlyIdentities() bool
}
TranslationMap is a map-like interface used to specify translations of correlation references within a Value tree. When a plan rule rewrites an expression and correlation identifiers change, a TranslationMap tells the rewriter how to map each old (source) alias to a new (target) alias and what function to apply to leaf values referencing that alias.
Ports Java's com.apple.foundationdb.record.query.plan.cascades.values.translation.TranslationMap.
type TranslationMapBuilder ¶
type TranslationMapBuilder struct {
// contains filtered or unexported fields
}
TranslationMapBuilder constructs a RegularTranslationMap incrementally using a fluent When/Then API.
Ports Java's RegularTranslationMap.Builder.
func NewTranslationMapBuilder ¶
func NewTranslationMapBuilder() *TranslationMapBuilder
NewTranslationMapBuilder creates an empty builder.
func (*TranslationMapBuilder) Build ¶
func (b *TranslationMapBuilder) Build() *RegularTranslationMap
Build creates an immutable RegularTranslationMap from the builder's current state. If the function map is empty, returns the shared empty translation map.
Ports Java's RegularTranslationMap.Builder.build.
func (*TranslationMapBuilder) Compose ¶
func (b *TranslationMapBuilder) Compose(other *RegularTranslationMap) *TranslationMapBuilder
Compose merges another RegularTranslationMap into this builder. Panics if any source alias in other already exists in the builder.
Ports Java's RegularTranslationMap.Builder.compose.
func (*TranslationMapBuilder) When ¶
func (b *TranslationMapBuilder) When(sourceAlias values.CorrelationIdentifier) *TranslationMapWhen
When starts a When/Then chain for the given source alias. Returns a TranslationMapWhen that must be completed with Then.
Ports Java's RegularTranslationMap.Builder.when.
func (*TranslationMapBuilder) WhenAny ¶
func (b *TranslationMapBuilder) WhenAny(sourceAliases []values.CorrelationIdentifier) *TranslationMapWhenAny
WhenAny starts a WhenAny/Then chain for multiple source aliases. The translation function will be applied to all of them.
Ports Java's RegularTranslationMap.Builder.whenAny.
type TranslationMapFunc ¶
type TranslationMapFunc func(realizedAlias values.CorrelationIdentifier) TranslationMap
TranslationMapFunc maps a realized base-quantifier alias to a TranslationMap that rebases compensated predicates/result values from the candidate's top alias to that realized alias. Ports Java's Function<CorrelationIdentifier, TranslationMap> passed to Compensation.apply / applyFinal / applyAllNeededCompensations (AbstractDataAccessRule: realizedAlias -> TranslationMap.ofAliases(candidateTopAlias, realizedAlias)).
type TranslationMapWhen ¶
type TranslationMapWhen struct {
// contains filtered or unexported fields
}
TranslationMapWhen is an intermediate builder step that captures the source alias for a When/Then chain.
Ports Java's RegularTranslationMap.Builder.When inner class.
func (*TranslationMapWhen) Then ¶
func (w *TranslationMapWhen) Then(fn TranslationFunction) *TranslationMapBuilder
Then completes the When/Then chain by specifying the translation function for the source alias.
type TranslationMapWhenAny ¶
type TranslationMapWhenAny struct {
// contains filtered or unexported fields
}
TranslationMapWhenAny is an intermediate builder step that captures multiple source aliases for a WhenAny/Then chain.
Ports Java's RegularTranslationMap.Builder.WhenAny inner class.
func (*TranslationMapWhenAny) Then ¶
func (w *TranslationMapWhenAny) Then(fn TranslationFunction) *TranslationMapBuilder
Then completes the WhenAny/Then chain by applying the same translation function to all source aliases.
type Traversal ¶
type Traversal struct {
// contains filtered or unexported fields
}
Traversal is a pre-computed walk of an expression DAG rooted at a Reference. It indexes expressions by their References for efficient lookup during the matching phase.
Ports the core surface of Java's `com.apple.foundationdb.record.query.plan.cascades.Traversal`. Java uses a Guava MutableNetwork<Reference, ReferencePath>; the Go version uses maps and slices for the same semantics without the external dependency. The traversal is immutable after construction — callers must not mutate the underlying expression DAG.
func ExpandValueIndex ¶
func ExpandValueIndex(candidate MatchCandidate) *Traversal
ExpandValueIndex builds a Traversal from an index definition, producing a candidate expression tree with Placeholder predicates for each index column. The resulting Traversal is used by matching rules to match query predicates against index columns.
The output structure matches Java's ValueIndexExpansionVisitor:
MatchableSortExpression(sortParamIDs, isReverse=false,
SelectExpression(resultValue,
[ForEach(FullUnorderedScanExpression(recordTypes))],
[Placeholder(param0, FieldValue("col0")),
Placeholder(param1, FieldValue("col1")),
...]))
Go's simpler index column model (flat list of column names) replaces Java's KeyExpression visitor walk, but the output Traversal structure is identical.
func ExpandVectorIndex ¶
func ExpandVectorIndex(c *VectorIndexScanMatchCandidate) *Traversal
ExpandVectorIndex builds the match-candidate Traversal for a VECTOR (HNSW) index. Unlike ExpandValueIndex (one FieldValue placeholder per column), the vector expansion splits the index columns at the partition/vector boundary:
- each partition (key) column → an ordinary Placeholder(FieldValue(col)), which binds the equality prefix that selects the HNSW partition;
- the single vector (value) column → one *distance placeholder* whose value is the metric-specific DistanceRowNumberValue(partitionFields, [vecField]). The query's QUALIFY ROW_NUMBER() OVER(... ORDER BY <distance>) predicate lowers (transformComparisonMaybe) to exactly that value, so it binds by structural match.
Ports Java's VectorIndexExpansionVisitor.expand / createDistanceValuePlaceholder.
func NewTraversal ¶
func NewTraversal(rootRef *expressions.Reference) *Traversal
NewTraversal builds a Traversal by walking the expression DAG from rootRef using a recursive DFS, visiting each Reference at most once.
Mirrors Java's `Traversal.withRoot` + `collectNetwork`.
func (*Traversal) FindReferencingExpressions ¶
func (t *Traversal) FindReferencingExpressions( childRefs []*expressions.Reference, ) map[*expressions.Reference][]expressions.RelationalExpression
FindReferencingExpressions returns a map from Reference to the set of expressions that reference any of the given child References through their quantifiers. Used by MatchIntermediateRule to walk upward from already-matched leaves.
For each childRef in the input, looks up its parents in the childToParents index and collects all parent (ref, expr) pairs. Deduplicates: if the same (ref, expr) pair appears for multiple childRefs, only includes it once.
func (*Traversal) GetLeafReferences ¶
func (t *Traversal) GetLeafReferences() []*expressions.Reference
GetLeafReferences returns references that contain at least one leaf expression (an expression with zero quantifiers). Used by MatchLeafRule to find the bottom of the candidate's expression tree.
func (*Traversal) GetParentRefPairs ¶
func (t *Traversal) GetParentRefPairs(childRef *expressions.Reference) []refExprPair
GetParentRefPairs returns all (parentRef, parentExpr) pairs that reference the given child Reference via a quantifier. Mirrors Java's Traversal.getParentRefPaths (outEdges in the network).
func (*Traversal) GetRootReference ¶
func (t *Traversal) GetRootReference() *expressions.Reference
GetRootReference returns the root reference of the traversal.
type TypeFilterMergeRule ¶
type TypeFilterMergeRule struct {
// contains filtered or unexported fields
}
TypeFilterMergeRule consolidates two nested LogicalTypeFilter expressions into a single one with the INTERSECTION of their record-type sets.
TypeFilter([T_outer...]) over TypeFilter([T_inner...]) over X → TypeFilter([T_outer ∩ T_inner]) over X
SQL-equivalent: nested type narrowing is the same as one narrowing to the intersection. If the intersection is empty the rule still fires — downstream rules will fold the empty-type-filter into a no-row-emission no-op.
Java equivalent: the planner would naturally derive this via the type-narrowing rules. Go implements it directly as a static rewrite.
func NewTypeFilterMergeRule ¶
func NewTypeFilterMergeRule() *TypeFilterMergeRule
NewTypeFilterMergeRule constructs the rule.
func (*TypeFilterMergeRule) Matcher ¶
func (r *TypeFilterMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*TypeFilterMergeRule) OnMatch ¶
func (r *TypeFilterMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner is also a LogicalTypeFilter; yields a single TypeFilter with the intersection of the type sets.
type TypeFilterRedundantOverScanRule ¶
type TypeFilterRedundantOverScanRule struct {
// contains filtered or unexported fields
}
TypeFilterRedundantOverScanRule eliminates a LogicalTypeFilter whose record-type allow-set is a SUPERSET of (or equal to) the inner FullUnorderedScan's record-type set — the filter rejects nothing.
TypeFilter([A, B, C], Scan(A, B)) → Scan(A, B) TypeFilter([A], Scan(A)) → Scan(A) TypeFilter([B], Scan(A, B)) → no change (B is a strict subset)
Why this matters: convertScan emits a single-record-type Scan, and an upstream `TypeFilter` is sometimes layered on by callers that don't know the scan was already narrowed to that type. Without this rule the planner would carry the redundant operator to the physical phase for the cost model to discount; the rewrite is a pure simplification (no information lost).
Java equivalent: handled implicitly by the cost preference for fewer operators. Go implements it directly because the static rewrite is trivially safe and produces a concretely-simpler plan tree.
func NewTypeFilterRedundantOverScanRule ¶
func NewTypeFilterRedundantOverScanRule() *TypeFilterRedundantOverScanRule
NewTypeFilterRedundantOverScanRule constructs the rule.
func (*TypeFilterRedundantOverScanRule) Matcher ¶
func (r *TypeFilterRedundantOverScanRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*TypeFilterRedundantOverScanRule) OnMatch ¶
func (r *TypeFilterRedundantOverScanRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the inner Quantifier ranges over a FullUnorderedScanExpression AND every type in the scan's set is allowed by the type-filter (i.e. scan ⊆ filter).
type UnionMergeRule ¶
type UnionMergeRule struct {
// contains filtered or unexported fields
}
UnionMergeRule flattens a LogicalUnion whose any child Quantifier ranges over another LogicalUnion. The flattened result has all inner-Union children promoted to siblings of the outer-Union's other children.
Union(A, Union(B, C), D) → Union(A, B, C, D)
SQL-equivalent: UNION ALL is associative, so chained nested UNION ALL collapses without semantic change. Java's planner would derive this via cost preference for fewer operator nodes; Go implements it directly.
Fires once per OnMatch — the first inner-Union child triggers a rewrite that promotes ALL inner-Union children at once. If multiple children are themselves Unions, repeated rule fires (driven by the planner's iteration loop) collapse them in turn.
func NewUnionMergeRule ¶
func NewUnionMergeRule() *UnionMergeRule
NewUnionMergeRule constructs the rule.
func (*UnionMergeRule) Matcher ¶
func (r *UnionMergeRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*UnionMergeRule) OnMatch ¶
func (r *UnionMergeRule) OnMatch(call *ExpressionRuleCall)
OnMatch examines each child Quantifier; if any ranges over a LogicalUnion, yields a flattened Union with that inner-Union's children promoted in place. Yields nothing if no child is a Union.
type UnionSingletonElimRule ¶
type UnionSingletonElimRule struct {
// contains filtered or unexported fields
}
UnionSingletonElimRule eliminates a LogicalUnion with exactly one child — UNION ALL of a single input is just that input.
Union([Q]) → inner of Q
func NewUnionSingletonElimRule ¶
func NewUnionSingletonElimRule() *UnionSingletonElimRule
NewUnionSingletonElimRule constructs the rule.
func (*UnionSingletonElimRule) Matcher ¶
func (r *UnionSingletonElimRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*UnionSingletonElimRule) OnMatch ¶
func (r *UnionSingletonElimRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the union has exactly one child.
type UnplannableIndexOnlyResidualError ¶
type UnplannableIndexOnlyResidualError struct {
// Predicate is the offending predicate's string form, for diagnostics.
Predicate string
}
UnplannableIndexOnlyResidualError reports that the only physical plan the planner could produce evaluates an index-only predicate (e.g. a vector K-NN DistanceRank over a DistanceRowNumberValue) as a residual filter over a base scan. Such a predicate can ONLY be produced by an index scan that binds it; as a residual it is not evaluable (Comparison.EvalAgainst would panic). This means no index could serve the predicate — e.g. a `QUALIFY ... ORDER BY cosine_distance(...)` against an index declared with a different metric, or a distance query on a column with no vector index — so the query is not plannable, exactly as Java leaves it (its single Compensation path stamps the match impossible). The query must fail to plan rather than build a plan that panics at execution.
func (*UnplannableIndexOnlyResidualError) Error ¶
func (e *UnplannableIndexOnlyResidualError) Error() string
type UnsortedSortElimRule ¶
type UnsortedSortElimRule struct {
// contains filtered or unexported fields
}
UnsortedSortElimRule eliminates a LogicalSort whose sort-key list is empty (the no-op sort produced by UnsortedLogicalSortExpression or by query rewrites that drop all sort keys).
Pattern:
LogicalSort([]) over X → X
This is the sort analogue of NoOpFilterRule. A sort with no keys preserves order — equivalent to no sort at all.
Java equivalent: not a dedicated rule, but the planner's cost model would naturally prefer the un-wrapped X over the no-op-Sort wrapper. Go implements it directly.
func NewUnsortedSortElimRule ¶
func NewUnsortedSortElimRule() *UnsortedSortElimRule
NewUnsortedSortElimRule constructs the rule.
func (*UnsortedSortElimRule) Matcher ¶
func (r *UnsortedSortElimRule) Matcher() matching.BindingMatcher
Matcher returns the pattern.
func (*UnsortedSortElimRule) OnMatch ¶
func (r *UnsortedSortElimRule) OnMatch(call *ExpressionRuleCall)
OnMatch fires when the sort is unsorted (empty key list).
type ValueEquivalence ¶
type ValueEquivalence interface {
// IsDefinedEqual reports whether two values are axiomatically equal
// under this equivalence. Returns a ConstrainedBoolean that may
// carry a QueryPlanConstraint (the equality holds only if the
// constraint is satisfied at plan execution time).
IsDefinedEqual(left, right values.Value) ConstrainedBoolean
// IsDefinedEqualAlias reports whether two correlation identifiers
// are axiomatically equal under this equivalence.
IsDefinedEqualAlias(left, right values.CorrelationIdentifier) ConstrainedBoolean
}
ValueEquivalence defines axiomatic equality relationships between Values beyond structural equality. Structural equality (Value.semanticEquals) compares two values within the same scope. ValueEquivalence enables cross-scope comparisons by declaring that certain values are considered equal under a mapping (e.g., two QuantifiedObjectValues are equal if their aliases are mapped via an AliasMap).
Ports Java's com.apple.foundationdb.record.query.plan.cascades.ValueEquivalence.
func EmptyValueEquivalence ¶
func EmptyValueEquivalence() ValueEquivalence
EmptyValueEquivalence returns a ValueEquivalence where no values are considered equal. Ports Java's ValueEquivalence.empty().
type ValueIndexLikeMatchCandidate ¶
type ValueIndexLikeMatchCandidate interface {
MatchCandidate
// GetBaseType returns the base record type for this candidate.
// Ports Java's WithBaseQuantifierMatchCandidate.getBaseType().
GetBaseType() values.Type
// GetColumnSize returns the number of key columns in the index
// (or primary key). Ports Java's MatchCandidate.getColumnSize().
GetColumnSize() int
// CreatesDuplicates reports whether the index can produce
// duplicate entries per record (e.g., a fan-out/repeated-field
// index). Ports Java's MatchCandidate.createsDuplicates().
CreatesDuplicates() bool
// HasAndOrderedByRecordTypeKey reports whether the index key
// starts with the record type key, partitioning the index by
// record type. Ports Java's
// MatchCandidate.hasAndOrderedByRecordTypeKey().
HasAndOrderedByRecordTypeKey() bool
// GetSargableAliasesRequiredForBinding returns the set of
// sargable parameter aliases that MUST be bound for this
// candidate to be valid. For example, if the index starts with
// a record type key, the first alias is required.
// Ports Java's MatchCandidate.getSargableAliasesRequiredForBinding().
GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
}
ValueIndexLikeMatchCandidate is the interface for match candidates defined over value-based index-like data structures — secondary value indexes (ValueIndexScanMatchCandidate) and the primary scan (PrimaryScanMatchCandidate).
Java's ValueIndexLikeMatchCandidate provides default implementations for computeMatchedOrderingParts and computeOrderingFromScanComparisons. In Go these are not embedded as defaults (Go has no default methods); they live in the OrderingPartsComputer interface and package-level functions respectively. This interface captures the structural contract — implementors carry a base type and column-level metadata beyond what the base MatchCandidate requires.
Ports Java's `com.apple.foundationdb.record.query.plan.cascades.ValueIndexLikeMatchCandidate`.
type ValueIndexScanMatchCandidate ¶
type ValueIndexScanMatchCandidate struct {
// contains filtered or unexported fields
}
ValueIndexScanMatchCandidate represents a secondary index as a match candidate. Each index key column has a corresponding sargable alias; predicate matching binds comparisons to these aliases to determine which prefix of the index key can be used for a scan.
Ports the consumed surface of Java's `ValueIndexScanMatchCandidate`: the candidate expression Traversal (built lazily), key-column names + sargable aliases, per-column function bridges (CARDINALITY), and duplicate-creation tracking. Java additionally materializes index-value Values and ordering alias lists on the candidate; Go derives ordering from the column list at match-adjustment time (matched_ordering_part.go) instead.
func NewValueIndexScanMatchCandidate ¶
func NewValueIndexScanMatchCandidate( indexName string, recordTypes []string, columnNames []string, sargableAliases []values.CorrelationIdentifier, flowedType values.Type, unique bool, pkColumnNames []string, ) *ValueIndexScanMatchCandidate
NewValueIndexScanMatchCandidate constructs a match candidate for a secondary index. columnNames and sargableAliases must be parallel slices in index key column order (left-to-right): columnNames[i] is the field name for the i-th key column, sargableAliases[i] is the correlation identifier used for predicate binding.
func NewValueIndexScanMatchCandidateWithFunctions ¶
func NewValueIndexScanMatchCandidateWithFunctions( indexName string, recordTypes []string, columnNames []string, columnFunctions []string, sargableAliases []values.CorrelationIdentifier, flowedType values.Type, unique bool, pkColumnNames []string, ) *ValueIndexScanMatchCandidate
NewValueIndexScanMatchCandidateWithFunctions is NewValueIndexScanMatchCandidate plus a parallel columnFunctions slice (see the struct field). Pass nil columnFunctions for an all-plain-field index. A non-empty columnFunctions[i] (FunctionKindCardinality) makes the i-th column's match Value CardinalityValue(FieldValue(col)) so a CARDINALITY() predicate/sort binds.
func (*ValueIndexScanMatchCandidate) CandidateName ¶
func (c *ValueIndexScanMatchCandidate) CandidateName() string
CandidateName returns the index name.
func (*ValueIndexScanMatchCandidate) ColumnValue ¶
ColumnValue returns the match Value for the i-th index key column over the given base (the QuantifiedObjectValue of the index's record source). For a plain field this is FieldValue(base, col); for a CARDINALITY()-keyed column it is CardinalityValue(FieldValue(base, col)). This is the single source of truth the predicate-placeholder expansion AND the ordered-index-scan sort matching both consult, so a CARDINALITY() query value binds to the index by Value-tree equality (Java: the match candidate carries the column's Value).
func (*ValueIndexScanMatchCandidate) ComputeBoundParameterPrefixMap ¶
func (c *ValueIndexScanMatchCandidate) ComputeBoundParameterPrefixMap( bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange, ) map[values.CorrelationIdentifier]*predicates.ComparisonRange
ComputeBoundParameterPrefixMap walks the sargable aliases in order and collects the longest prefix that satisfies index scan discipline:
- N equality-bound parameters (any number, including 0)
- followed by at most ONE inequality-bound parameter
- stops at the first unbound (empty) parameter or after the first inequality
Mirrors Java's default `MatchCandidate.computeBoundParameterPrefixMap`.
func (*ValueIndexScanMatchCandidate) ComputeMatchedOrderingParts ¶
func (c *ValueIndexScanMatchCandidate) ComputeMatchedOrderingParts( matchInfo MatchInfo, sortParameterIDs []values.CorrelationIdentifier, isReverse bool, ) []*MatchedOrderingPart
ComputeMatchedOrderingParts computes ordering parts for each index column, using bound comparison ranges from the match info. Ports Java's ValueIndexLikeMatchCandidate.computeMatchedOrderingParts.
func (*ValueIndexScanMatchCandidate) CreatesDuplicates ¶
func (c *ValueIndexScanMatchCandidate) CreatesDuplicates() bool
CreatesDuplicates reports whether the index can produce duplicate entries per record (fan-out / repeated-field indexes). Implements ValueIndexLikeMatchCandidate.
func (*ValueIndexScanMatchCandidate) GetBaseType ¶
func (c *ValueIndexScanMatchCandidate) GetBaseType() values.Type
GetBaseType returns the base record type for this candidate. Implements ValueIndexLikeMatchCandidate.
func (*ValueIndexScanMatchCandidate) GetColumnNames ¶
func (c *ValueIndexScanMatchCandidate) GetColumnNames() []string
GetColumnNames returns the ordered column-name list (one per index key column, parallel to GetSargableAliases).
func (*ValueIndexScanMatchCandidate) GetColumnSize ¶
func (c *ValueIndexScanMatchCandidate) GetColumnSize() int
GetColumnSize returns the number of key columns in the index. Implements ValueIndexLikeMatchCandidate.
func (*ValueIndexScanMatchCandidate) GetRecordTypes ¶
func (c *ValueIndexScanMatchCandidate) GetRecordTypes() []string
GetRecordTypes returns which record types this index covers.
func (*ValueIndexScanMatchCandidate) GetSargableAliases ¶
func (c *ValueIndexScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
GetSargableAliases returns the ordered parameter list (one per index key column).
func (*ValueIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding ¶
func (c *ValueIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
GetSargableAliasesRequiredForBinding returns the set of sargable aliases that must be bound for the candidate to be valid. For standard value indexes, no aliases are required (the default). Implements ValueIndexLikeMatchCandidate.
func (*ValueIndexScanMatchCandidate) GetTraversal ¶
func (c *ValueIndexScanMatchCandidate) GetTraversal() *Traversal
GetTraversal returns the Traversal of this candidate's expression tree, built lazily on first access via ExpandValueIndex. The traversal is stable once computed (sync.Once). Ports Java's ValueIndexScanMatchCandidate.getTraversal().
func (*ValueIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey ¶
func (c *ValueIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey() bool
HasAndOrderedByRecordTypeKey reports whether the index key starts with the record type key. For standard value indexes this is false; only indexes explicitly prefixed by recordType() return true. Implements ValueIndexLikeMatchCandidate.
func (*ValueIndexScanMatchCandidate) IsUnique ¶
func (c *ValueIndexScanMatchCandidate) IsUnique() bool
IsUnique reports whether the index enforces uniqueness.
func (*ValueIndexScanMatchCandidate) PushValueThroughFetch ¶
func (c *ValueIndexScanMatchCandidate) PushValueThroughFetch( value values.Value, sourceAlias values.CorrelationIdentifier, targetAlias values.CorrelationIdentifier, ) (values.Value, bool)
PushValueThroughFetch attempts to translate a value from the full-record domain to the index-entry domain. Returns the translated value and true on success; nil and false otherwise. Implements ScanWithFetchMatchCandidate.
func (*ValueIndexScanMatchCandidate) ToScanPlan ¶
func (c *ValueIndexScanMatchCandidate) ToScanPlan( prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, reverse bool, ) plans.RecordQueryPlan
ToScanPlan converts the matched prefix into a physical plan. The plan is wrapped in a FetchFromPartialRecordPlan with a TranslateValueFunction that can translate FieldValues referencing covered index columns. This enables push-through rules (C-6) to push filters/maps below the fetch when they reference covered columns.
Matches Java's ScanWithFetchMatchCandidate architecture where every index scan is wrapped in a Fetch that carries the translation function.
type ValuePredicateConstantFoldRule ¶
type ValuePredicateConstantFoldRule struct {
// contains filtered or unexported fields
}
ValuePredicateConstantFoldRule unwraps a ValuePredicate whose Value folds to a constant bool / null at plan time:
ValuePredicate{Value: ConstantValue(true)} → ConstantPredicate(TriTrue)
ValuePredicate{Value: ConstantValue(false)} → ConstantPredicate(TriFalse)
ValuePredicate{Value: NullValue} → ConstantPredicate(TriUnknown)
ValuePredicate{Value: BooleanValue(true)} → ConstantPredicate(TriTrue)
ValuePredicate{Value: BooleanValue(nil)} → ConstantPredicate(TriUnknown)
Mirrors Java's `ConstantFoldingValuePredicateRule`. Without this rule, SimplifyPredicateValues collapses the Value tree but leaves the ValuePredicate wrapper — `(true AND something)` stays `AND(VP(true), something)` instead of folding to just `something` via the AndConstantSimplifyRule pass.
The rule fires AFTER SimplifyPredicateValues has run (or after other rules have folded the Value). It only operates on Values that IsConstantValue + EvaluateConstant accept; non-constant Values (FieldValue, ArithmeticValue with non-constant children) leave the wrapper alone.
Type-degraded inputs (Value evaluates to a non-bool literal — e.g. `ConstantValue(int64(1))` wrapped in ValuePredicate) fold to TriUnknown, matching ValuePredicate.Eval's runtime degradation behaviour. This prevents the wrapper surviving past simplification when the embedded executor would also report UNKNOWN at runtime.
func NewValuePredicateConstantFoldRule ¶
func NewValuePredicateConstantFoldRule() *ValuePredicateConstantFoldRule
NewValuePredicateConstantFoldRule constructs the rule.
func (*ValuePredicateConstantFoldRule) Matcher ¶
func (r *ValuePredicateConstantFoldRule) Matcher() matching.BindingMatcher
func (*ValuePredicateConstantFoldRule) OnMatch ¶
func (r *ValuePredicateConstantFoldRule) OnMatch(call *RuleCall)
type VectorIndexScanMatchCandidate ¶
type VectorIndexScanMatchCandidate struct {
// contains filtered or unexported fields
}
VectorIndexScanMatchCandidate represents a vector similarity search index as a match candidate. Recognises K-nearest-neighbour queries driven by distance-based ranking predicates and maps them to a vector index scan.
Key differences from ValueIndexScanMatchCandidate:
- Carries ordering aliases separately from sargable parameters (vector indexes have a different binding discipline).
- Sargable aliases include partition key columns; a subset (parametersRequiredForBinding) must be bound.
- The scan plan it produces uses a vector distance comparison.
Ports Java's `com.apple.foundationdb.record.query.plan.cascades.VectorIndexScanMatchCandidate`.
func NewVectorIndexScanMatchCandidate ¶
func NewVectorIndexScanMatchCandidate( indexName string, recordTypes []string, columnNames []string, partitionCount int, metric values.DistanceOperator, flowedType values.Type, unique bool, primaryKeyColumns []string, ) *VectorIndexScanMatchCandidate
NewVectorIndexScanMatchCandidate constructs a match candidate for a vector similarity search index. columnNames are all index columns in key order (partition columns followed by the single vector column); partitionCount is the KeyWithValue split point; metric selects the distance function. The sargable aliases (one per partition column + one distance alias) and the required-for-binding set (the index-only distance alias) are minted here, mirroring Java's VectorIndexExpansionVisitor.
func (*VectorIndexScanMatchCandidate) CandidateName ¶
func (c *VectorIndexScanMatchCandidate) CandidateName() string
CandidateName returns the index name.
func (*VectorIndexScanMatchCandidate) ComputeBoundParameterPrefixMap ¶
func (c *VectorIndexScanMatchCandidate) ComputeBoundParameterPrefixMap( bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange, ) map[values.CorrelationIdentifier]*predicates.ComparisonRange
ComputeBoundParameterPrefixMap collects the bound partition-prefix equality run plus the index-only DistanceRank binding. Unlike a value index, the two are kept separate: Java's toVectorIndexScanComparisons separates the distance rank by TYPE (instanceof DistanceRankValueComparison), never by prefix position, so the distance binding must survive even on a PARTIAL partition prefix (a multi-partition fan-out query). See RFC-046.
func (*VectorIndexScanMatchCandidate) CreatesDuplicates ¶
func (c *VectorIndexScanMatchCandidate) CreatesDuplicates() bool
CreatesDuplicates reports whether the index can produce duplicate entries per record.
func (*VectorIndexScanMatchCandidate) EmitsOrderedStream ¶
func (c *VectorIndexScanMatchCandidate) EmitsOrderedStream() bool
EmitsOrderedStream reports whether this candidate's ToScanPlan emits the VBASE distance-ordered (non-self-limiting) form — true for an un-partitioned index (global rank, RFC-156 Phase B). Such a scan must NOT be folded into a primary-key intersection: the residual composes as a Filter ABOVE the ordered stream (Limit → Filter → ordered scan), not as an intersection arm (which would reintroduce the predicate-subset-of-global-top-k wrong answer).
func (*VectorIndexScanMatchCandidate) GetBaseType ¶
func (c *VectorIndexScanMatchCandidate) GetBaseType() values.Type
GetBaseType returns the base record type.
func (*VectorIndexScanMatchCandidate) GetColumnNames ¶
func (c *VectorIndexScanMatchCandidate) GetColumnNames() []string
GetColumnNames returns the ordered column-name list.
func (*VectorIndexScanMatchCandidate) GetColumnSize ¶
func (c *VectorIndexScanMatchCandidate) GetColumnSize() int
GetColumnSize returns the number of key columns.
func (*VectorIndexScanMatchCandidate) GetOrderingAliases ¶
func (c *VectorIndexScanMatchCandidate) GetOrderingAliases() []values.CorrelationIdentifier
GetOrderingAliases returns the ordering aliases.
func (*VectorIndexScanMatchCandidate) GetPrimaryKeyValues ¶
func (c *VectorIndexScanMatchCandidate) GetPrimaryKeyValues() []values.Value
GetPrimaryKeyValues returns the primary key as a list of Values. Lazily computed. Returns nil if no PK columns.
func (*VectorIndexScanMatchCandidate) GetRecordTypes ¶
func (c *VectorIndexScanMatchCandidate) GetRecordTypes() []string
GetRecordTypes returns the record types this index covers.
func (*VectorIndexScanMatchCandidate) GetSargableAliases ¶
func (c *VectorIndexScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
GetSargableAliases returns the sargable parameter aliases. Ports Java's VectorIndexScanMatchCandidate.getSargableAliases().
func (*VectorIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding ¶
func (c *VectorIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
GetSargableAliasesRequiredForBinding returns the parameter aliases that must be bound for the candidate to be valid.
func (*VectorIndexScanMatchCandidate) GetTraversal ¶
func (c *VectorIndexScanMatchCandidate) GetTraversal() *Traversal
GetTraversal returns the Traversal of this candidate's expression tree, built lazily on first access.
func (*VectorIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey ¶
func (c *VectorIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey() bool
HasAndOrderedByRecordTypeKey reports whether the index key starts with the record type key. Always false for vector indexes.
func (*VectorIndexScanMatchCandidate) IsUnique ¶
func (c *VectorIndexScanMatchCandidate) IsUnique() bool
IsUnique reports whether the index enforces uniqueness.
func (*VectorIndexScanMatchCandidate) String ¶
func (c *VectorIndexScanMatchCandidate) String() string
String returns a human-readable label for debugging. Mirrors Java's VectorIndexScanMatchCandidate.toString().
func (*VectorIndexScanMatchCandidate) ToScanPlan ¶
func (c *VectorIndexScanMatchCandidate) ToScanPlan( prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, _ bool, ) plans.RecordQueryPlan
ToScanPlan converts the matched bindings into a vector (BY_DISTANCE) scan plan. It separates the partition-key equality bindings (which form the HNSW partition prefix) from the single DistanceRank binding (which carries the query vector + k + ef_search). Ports Java's VectorIndexScanMatchCandidate.toEquivalentPlan / toVectorIndexScanComparisons.
type Vectored ¶
Vectored pairs a value with its position index. Used by the bit-sieve intersection logic to track which element came from which position in the original list.
Ports Java's AbstractDataAccessRule.Vectored<T>.
func MaximumCoverageMatches ¶
func MaximumCoverageMatches( partialMatches []PartialMatch, requestedOrderings []*RequestedOrdering, ctx PlanContext, ) []Vectored[*SingleMatchedAccess]
MaximumCoverageMatches eliminates PartialMatches whose coverage is entirely contained in other matches from the same MatchCandidate, then wraps survivors in Vectored with ascending position indices.
The Pareto filtering logic (findContainingAccess) prunes dominated matches: if match A from candidate C binds {x, y, z} and match B from the same candidate C binds {x, y}, then B is dominated by A (A covers everything B covers plus more) and B is pruned.
Ports Java's AbstractDataAccessRule.maximumCoverageMatches.
func NewVectored ¶
NewVectored creates a Vectored with the given value and position.
type WindowedIndexScanMatchCandidate ¶
type WindowedIndexScanMatchCandidate struct {
// contains filtered or unexported fields
}
WindowedIndexScanMatchCandidate represents a windowed (rank / leaderboard / time-series) index as a match candidate. Such indexes partition data by grouping keys, then order by a score within each group. Queries that bind the group columns and constrain the rank can be answered directly via a BY_RANK index scan.
Key differences from ValueIndexScanMatchCandidate:
- Carries separate grouping aliases, a score alias, a rank alias, and primary key aliases. The sargable set is groupingAliases + [rankAlias]; the ordering set is groupingAliases + [scoreAlias] + primaryKeyAliases.
- computeMatchedOrderingParts has special-case logic: when the current parameter is the scoreAlias, the comparison range is taken from the rankAlias binding instead, because binding rank by equality also determines the score.
- computeOrderingFromScanComparisons treats the score ordinal specially — the score column is fixed with an opaque equality binding rather than the scan comparison.
- Implements ScanWithFetchMatchCandidate (covering-index push-through).
Ports Java's `com.apple.foundationdb.record.query.plan.cascades.WindowedIndexScanMatchCandidate`.
func NewWindowedIndexScanMatchCandidate ¶
func NewWindowedIndexScanMatchCandidate( indexName string, recordTypes []string, columnNames []string, groupingAliases []values.CorrelationIdentifier, scoreAlias values.CorrelationIdentifier, rankAlias values.CorrelationIdentifier, primaryKeyAliases []values.CorrelationIdentifier, indexKeyValues []values.Value, flowedType values.Type, unique bool, primaryKeyColumns []string, ) *WindowedIndexScanMatchCandidate
NewWindowedIndexScanMatchCandidate constructs a match candidate for a windowed (rank) index.
func (*WindowedIndexScanMatchCandidate) CandidateName ¶
func (c *WindowedIndexScanMatchCandidate) CandidateName() string
CandidateName returns the index name.
func (*WindowedIndexScanMatchCandidate) ComputeBoundParameterPrefixMap ¶
func (c *WindowedIndexScanMatchCandidate) ComputeBoundParameterPrefixMap( bindings map[values.CorrelationIdentifier]*predicates.ComparisonRange, ) map[values.CorrelationIdentifier]*predicates.ComparisonRange
ComputeBoundParameterPrefixMap walks the sargable aliases and collects the longest prefix satisfying index scan discipline.
func (*WindowedIndexScanMatchCandidate) CreatesDuplicates ¶
func (c *WindowedIndexScanMatchCandidate) CreatesDuplicates() bool
CreatesDuplicates reports whether the index can produce duplicate entries per record.
func (*WindowedIndexScanMatchCandidate) GetBaseType ¶
func (c *WindowedIndexScanMatchCandidate) GetBaseType() values.Type
GetBaseType returns the base record type.
func (*WindowedIndexScanMatchCandidate) GetColumnNames ¶
func (c *WindowedIndexScanMatchCandidate) GetColumnNames() []string
GetColumnNames returns the ordered column-name list.
func (*WindowedIndexScanMatchCandidate) GetColumnSize ¶
func (c *WindowedIndexScanMatchCandidate) GetColumnSize() int
GetColumnSize returns the number of key columns.
func (*WindowedIndexScanMatchCandidate) GetGroupingAliases ¶
func (c *WindowedIndexScanMatchCandidate) GetGroupingAliases() []values.CorrelationIdentifier
GetGroupingAliases returns the grouping aliases.
func (*WindowedIndexScanMatchCandidate) GetIndexKeyValues ¶
func (c *WindowedIndexScanMatchCandidate) GetIndexKeyValues() []values.Value
GetIndexKeyValues returns the index key Values.
func (*WindowedIndexScanMatchCandidate) GetOrderingAliases ¶
func (c *WindowedIndexScanMatchCandidate) GetOrderingAliases() []values.CorrelationIdentifier
GetOrderingAliases returns groupingAliases + [scoreAlias] + primaryKeyAliases. Ports Java's orderingAliases() static helper.
func (*WindowedIndexScanMatchCandidate) GetPrimaryKeyAliases ¶
func (c *WindowedIndexScanMatchCandidate) GetPrimaryKeyAliases() []values.CorrelationIdentifier
GetPrimaryKeyAliases returns the primary key aliases.
func (*WindowedIndexScanMatchCandidate) GetPrimaryKeyValues ¶
func (c *WindowedIndexScanMatchCandidate) GetPrimaryKeyValues() []values.Value
GetPrimaryKeyValues returns the primary key as a list of Values. Lazily computed. Returns nil if no PK columns.
func (*WindowedIndexScanMatchCandidate) GetRankAlias ¶
func (c *WindowedIndexScanMatchCandidate) GetRankAlias() values.CorrelationIdentifier
GetRankAlias returns the rank alias.
func (*WindowedIndexScanMatchCandidate) GetRecordTypes ¶
func (c *WindowedIndexScanMatchCandidate) GetRecordTypes() []string
GetRecordTypes returns the record types this index covers.
func (*WindowedIndexScanMatchCandidate) GetSargableAliases ¶
func (c *WindowedIndexScanMatchCandidate) GetSargableAliases() []values.CorrelationIdentifier
GetSargableAliases returns groupingAliases + [rankAlias]. Ports Java's WindowedIndexScanMatchCandidate.getSargableAliases().
func (*WindowedIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding ¶
func (c *WindowedIndexScanMatchCandidate) GetSargableAliasesRequiredForBinding() []values.CorrelationIdentifier
GetSargableAliasesRequiredForBinding returns nil — windowed indexes do not require any specific aliases to be bound.
func (*WindowedIndexScanMatchCandidate) GetScoreAlias ¶
func (c *WindowedIndexScanMatchCandidate) GetScoreAlias() values.CorrelationIdentifier
GetScoreAlias returns the score alias.
func (*WindowedIndexScanMatchCandidate) GetTraversal ¶
func (c *WindowedIndexScanMatchCandidate) GetTraversal() *Traversal
GetTraversal returns the Traversal of this candidate's expression tree, built lazily on first access.
func (*WindowedIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey ¶
func (c *WindowedIndexScanMatchCandidate) HasAndOrderedByRecordTypeKey() bool
HasAndOrderedByRecordTypeKey reports whether the index key starts with the record type key. Always false for windowed indexes.
func (*WindowedIndexScanMatchCandidate) IsUnique ¶
func (c *WindowedIndexScanMatchCandidate) IsUnique() bool
IsUnique reports whether the index enforces uniqueness.
func (*WindowedIndexScanMatchCandidate) PushValueThroughFetch ¶
func (c *WindowedIndexScanMatchCandidate) PushValueThroughFetch( value values.Value, sourceAlias values.CorrelationIdentifier, targetAlias values.CorrelationIdentifier, ) (values.Value, bool)
PushValueThroughFetch attempts to translate a value from the full-record domain to the index-entry domain. Returns the translated value and true on success; nil and false otherwise. Implements ScanWithFetchMatchCandidate.
func (*WindowedIndexScanMatchCandidate) String ¶
func (c *WindowedIndexScanMatchCandidate) String() string
String returns a human-readable label for debugging. Mirrors Java's WindowedIndexScanMatchCandidate.toString().
func (*WindowedIndexScanMatchCandidate) ToScanPlan ¶
func (c *WindowedIndexScanMatchCandidate) ToScanPlan( prefixMap map[values.CorrelationIdentifier]*predicates.ComparisonRange, reverse bool, ) plans.RecordQueryPlan
ToScanPlan converts the matched prefix into a physical plan. Produces a RecordQueryIndexPlan (BY_RANK scan) wrapped in a FetchFromPartialRecordPlan.
Ports Java's WindowedIndexScanMatchCandidate.toEquivalentPlan().
type WithBaseQuantifierMatchCandidate ¶
type WithBaseQuantifierMatchCandidate interface {
MatchCandidate
// GetBaseType returns the base record type for this candidate.
GetBaseType() values.Type
}
WithBaseQuantifierMatchCandidate is a MatchCandidate defined using a base quantifier (i.e., not a true join index). Ports Java's `com.apple.foundationdb.record.query.plan.cascades.WithBaseQuantifierMatchCandidate`.
type WithPrimaryKeyMatchCandidate ¶
type WithPrimaryKeyMatchCandidate interface {
MatchCandidate
// GetPrimaryKeyValues returns the primary key values for this
// candidate, or nil if the primary key cannot be computed.
// Ports Java's getPrimaryKeyValuesMaybe() — nil corresponds to
// Optional.empty().
GetPrimaryKeyValues() []values.Value
}
WithPrimaryKeyMatchCandidate is a MatchCandidate that uses a primary key to identify a record. Ports Java's `com.apple.foundationdb.record.query.plan.cascades.WithPrimaryKeyMatchCandidate`.
Source Files
¶
- abstract_data_access_rule.go
- aggregate_index_candidate.go
- alias_map.go
- bimap.go
- compensation.go
- cost_formulas.go
- cross_product.go
- data_access_types.go
- default_rules.go
- derivations_evaluator.go
- expression_matcher.go
- expression_partition.go
- expression_rule_adapter.go
- expression_rule_call.go
- graph_expansion.go
- group_by_mappings.go
- implementation_rule.go
- in_source.go
- index_expansion.go
- intersector_primary_key.go
- match_candidate_index.go
- match_candidate_interfaces.go
- match_info.go
- match_max_match_map.go
- match_partition.go
- matched_ordering_part.go
- max_match_map.go
- memo.go
- memo_merge.go
- ordering_part.go
- partial_match.go
- partial_match_ref.go
- physical_default_on_empty_wrapper.go
- physical_explode_wrapper.go
- physical_fetch_from_partial_record_wrapper.go
- physical_first_or_default_wrapper.go
- physical_flat_map_wrapper.go
- physical_in_join_wrapper.go
- physical_in_memory_sort_wrapper.go
- physical_in_union_wrapper.go
- physical_limit_wrapper.go
- physical_map_wrapper.go
- physical_merge_sort_union_wrapper.go
- physical_multi_intersection_wrapper.go
- physical_nested_loop_join_wrapper.go
- physical_predicates_filter_wrapper.go
- physical_recursive_dfs_join_wrapper.go
- physical_recursive_level_union_wrapper.go
- physical_streaming_agg_wrapper.go
- physical_table_function_wrapper.go
- physical_temp_table_insert_wrapper.go
- physical_temp_table_scan_wrapper.go
- physical_unordered_union_wrapper.go
- physical_vector_index_scan_wrapper.go
- physical_wrapper.go
- plan_context.go
- plan_context_builder.go
- plan_executability.go
- plan_invariants.go
- plan_properties.go
- planner.go
- planner_constraint.go
- planner_phase.go
- planning_cost_model.go
- predicate_multi_map.go
- preorder_rule.go
- primary_scan_match_candidate.go
- pullup.go
- referenced_fields.go
- requested_ordering.go
- rfc173_positional_merge.go
- rfc173_w4left_existential.go
- rich_ordering.go
- rule.go
- rule_adjust_match.go
- rule_aggregate_data_access.go
- rule_decorrelate_values.go
- rule_demorgan.go
- rule_distinct_merge.go
- rule_distinct_over_groupby_elim.go
- rule_distinct_over_sort_elim.go
- rule_distinct_over_union_dedup.go
- rule_eliminate_null_on_empty.go
- rule_filter_dedup_predicates.go
- rule_filter_drop_true.go
- rule_filter_merge.go
- rule_finalize_expressions.go
- rule_implement_delete.go
- rule_implement_distinct_final.go
- rule_implement_distinct_union.go
- rule_implement_explode.go
- rule_implement_filter.go
- rule_implement_in_join.go
- rule_implement_in_memory_sort.go
- rule_implement_in_union.go
- rule_implement_insert.go
- rule_implement_intersection.go
- rule_implement_limit.go
- rule_implement_nested_loop_join.go
- rule_implement_projection.go
- rule_implement_projection_final.go
- rule_implement_recursive_dfs_join.go
- rule_implement_recursive_level_union.go
- rule_implement_simple_select.go
- rule_implement_sort.go
- rule_implement_streaming_agg.go
- rule_implement_table_function.go
- rule_implement_temp_table_insert.go
- rule_implement_temp_table_scan.go
- rule_implement_typefilter.go
- rule_implement_union.go
- rule_implement_unique.go
- rule_implement_unordered_union.go
- rule_implement_update.go
- rule_implement_values.go
- rule_in_to_explode.go
- rule_intersection_merge.go
- rule_limit_merge.go
- rule_match_intermediate.go
- rule_match_leaf.go
- rule_merge_fetch_into_covering_index.go
- rule_merge_projection_and_fetch.go
- rule_noop_filter.go
- rule_noop_limit_elim.go
- rule_normalize_predicates.go
- rule_ordered_index_scan.go
- rule_ordered_primary_scan.go
- rule_partition_binary_select.go
- rule_partition_select.go
- rule_predicate_push_down.go
- rule_predicate_to_logical_union.go
- rule_primary_scan.go
- rule_projection_elim.go
- rule_projection_merge.go
- rule_pull_common_filter_above_intersection.go
- rule_pull_common_filter_above_union.go
- rule_pull_filter_above_distinct.go
- rule_push_distinct_below_filter.go
- rule_push_distinct_through_fetch.go
- rule_push_filter_below_join.go
- rule_push_filter_through_distinct.go
- rule_push_filter_through_fetch.go
- rule_push_filter_through_groupby.go
- rule_push_filter_through_intersection.go
- rule_push_filter_through_typefilter.go
- rule_push_filter_through_union.go
- rule_push_in_join_through_fetch.go
- rule_push_limit_through_projection.go
- rule_push_limit_through_union.go
- rule_push_map_through_fetch.go
- rule_push_referenced_fields.go
- rule_push_requested_ordering_through_delete.go
- rule_push_requested_ordering_through_distinct.go
- rule_push_requested_ordering_through_filter.go
- rule_push_requested_ordering_through_groupby.go
- rule_push_requested_ordering_through_in_like_select.go
- rule_push_requested_ordering_through_insert.go
- rule_push_requested_ordering_through_projection.go
- rule_push_requested_ordering_through_recursive_union.go
- rule_push_requested_ordering_through_select.go
- rule_push_requested_ordering_through_select_existential.go
- rule_push_requested_ordering_through_sort.go
- rule_push_requested_ordering_through_temp_table_insert.go
- rule_push_requested_ordering_through_union.go
- rule_push_requested_ordering_through_unique.go
- rule_push_requested_ordering_through_update.go
- rule_push_set_operation_through_fetch.go
- rule_push_typefilter_below_filter.go
- rule_query_predicate_simplification.go
- rule_registry.go
- rule_remove_projection.go
- rule_remove_range_one.go
- rule_rewrite_outer_join.go
- rule_select_merge.go
- rule_set_op_singleton.go
- rule_simplify.go
- rule_sink_limit_into_vector_scan.go
- rule_sort_constant_keys_elim.go
- rule_sort_dedup_keys.go
- rule_sort_merge.go
- rule_split_select_extract_independent.go
- rule_streaming_agg_from_index.go
- rule_type_filter_merge.go
- rule_type_filter_redundant.go
- rule_union_merge.go
- rule_unsorted_sort_elim.go
- rule_value_predicate_fold.go
- scan_match_helpers.go
- set_plan_helpers.go
- simplifier.go
- single_matched_access.go
- string_util.go
- temp_table.go
- translation_map.go
- traversal.go
- unified_tasks.go
- value_equivalence.go
- value_semantic_equals.go
- vector_index_expansion.go
- vector_index_match_candidate.go
- windowed_index_match_candidate.go
- winner_lookup.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package expressions ports the Cascades-side relational expression hierarchy from Java's `com.apple.foundationdb.record.query.plan.cascades.expressions`.
|
Package expressions ports the Cascades-side relational expression hierarchy from Java's `com.apple.foundationdb.record.query.plan.cascades.expressions`. |
|
Package properties — Cardinality and Cardinalities types.
|
Package properties — Cardinality and Cardinalities types. |
|
Package values is the Value-tier of the Go Cascades planner port — scalar / row-context expressions that compose into predicates, projections, and join keys.
|
Package values is the Value-tier of the Go Cascades planner port — scalar / row-context expressions that compose into predicates, projections, and join keys. |