Documentation
¶
Overview ¶
Package executor bridges RecordQueryPlan trees (Cascades planner output) and the FDBRecordStore scanning API to produce RecordCursor[QueryResult] streams. Mirrors Java's RecordQueryPlan.executePlan dispatching to FDBRecordStoreBase.scanRecords.
The executor is a standalone visitor (not a method on RecordQueryPlan) to avoid circular dependencies between the plans package and the recordlayer package.
Index ¶
- Constants
- Variables
- func EvaluateScalarSubquery(ctx context.Context, plan plans.RecordQueryPlan, ...) (any, error)
- func ExecutePlan(ctx context.Context, plan plans.RecordQueryPlan, ...) (recordlayer.RecordCursor[QueryResult], error)
- func OptimizeCoveringIndexScans(plan plans.RecordQueryPlan) plans.RecordQueryPlan
- func SetNameModelOracle(v bool)
- type AggregateTypeMismatchError
- type ColumnDef
- type EvaluationContext
- func (ec *EvaluationContext) BindParameter(ordinal int, name string) (any, bool)
- func (ec *EvaluationContext) GetBinding(id values.CorrelationIdentifier) (any, bool)
- func (ec *EvaluationContext) GetCorrelationBinding(id values.CorrelationIdentifier) (any, bool)
- func (ec *EvaluationContext) GetOrCreateTempTable(id values.CorrelationIdentifier, st *recordlayer.ExecuteState) *TempTable
- func (ec *EvaluationContext) RowContext(datum map[string]any) *values.RowEvalContext
- func (ec *EvaluationContext) RowContextPositional(pos values.OrdinalRow) *values.RowEvalContext
- func (ec *EvaluationContext) RowContextStrict(datum map[string]any) *values.RowEvalContext
- func (ec *EvaluationContext) WithBinding(id values.CorrelationIdentifier, val any) *EvaluationContext
- func (ec *EvaluationContext) WithParams(params []any) *EvaluationContext
- func (ec *EvaluationContext) WithScalarSubqueries(results map[values.CorrelationIdentifier]any) *EvaluationContext
- type MaterializationLimitExceededError
- type NumericRangeOverflowError
- type PositionalRow
- type QueryResult
- func CollectAll(ctx context.Context, cursor recordlayer.RecordCursor[QueryResult]) ([]QueryResult, error)
- func CollectAllBounded(ctx context.Context, cursor recordlayer.RecordCursor[QueryResult], ...) ([]QueryResult, error)
- func FromStoredRecord(rec *recordlayer.FDBStoredRecord[proto.Message]) QueryResult
- type RecordLayerResultSet
- func (rs *RecordLayerResultSet) Boolean(columnIndex int) (bool, error)
- func (rs *RecordLayerResultSet) BooleanByName(name string) (bool, error)
- func (rs *RecordLayerResultSet) Bytes(columnIndex int) ([]byte, error)
- func (rs *RecordLayerResultSet) BytesByName(name string) ([]byte, error)
- func (rs *RecordLayerResultSet) Close() error
- func (rs *RecordLayerResultSet) Continuation() (api.Continuation, error)
- func (rs *RecordLayerResultSet) Double(columnIndex int) (float64, error)
- func (rs *RecordLayerResultSet) Err() error
- func (rs *RecordLayerResultSet) Float(columnIndex int) (float32, error)
- func (rs *RecordLayerResultSet) GetContinuation() recordlayer.RecordCursorContinuation
- func (rs *RecordLayerResultSet) GetNoNextReason() recordlayer.NoNextReason
- func (rs *RecordLayerResultSet) Long(columnIndex int) (int64, error)
- func (rs *RecordLayerResultSet) LongByName(name string) (int64, error)
- func (rs *RecordLayerResultSet) MetaData() api.ResultSetMetaData
- func (rs *RecordLayerResultSet) Next() bool
- func (rs *RecordLayerResultSet) Object(columnIndex int) (any, error)
- func (rs *RecordLayerResultSet) ObjectByName(name string) (any, error)
- func (rs *RecordLayerResultSet) String(columnIndex int) (string, error)
- func (rs *RecordLayerResultSet) StringByName(name string) (string, error)
- func (rs *RecordLayerResultSet) WasNull() bool
- type RecursiveCTEDepthExceededError
- type SortBufferExceededError
- type SumOverflowError
- type TempTable
Constants ¶
const DefaultMaxSortBufferRows = 5_000_000
DefaultMaxSortBufferRows is the maximum number of rows the in-memory sort cursor will materialize before returning an error. Prevents OOM on queries that sort unbounded result sets without LIMIT. Override per cursor via the maxBuf field.
Variables ¶
var DisablePositionalEmission bool
DisablePositionalEmission, when true, stops the row-birth sites — the oracle REGISTRY: FromStoredRecord, the covering-index cursor, and the RFC-173 Slice 2 ordinal-join births (nljCursor pairBinder/evaluateBound emission sites, flatMapCursor.computeResultLegs) — from emitting the RFC-173 PositionalRow, recreating the pre-Slice-1 NAME model end-to-end: no positional row is born, so the frontier gates (`qr.Positional != nil`) never fire and every producer/consumer runs name resolution + name emission, exactly the pre-flip world. Every NEW positional birth site MUST gate on this flag and be added to this list (the §4 standing obligation). It exists for ONE purpose: the §5 dual-window corpus DIFFERENTIAL (ordinal result == name result row-for-row across the corpus, with enumerated carve-outs), which needs the name model as a live oracle during the dual-representation window (retired with the map side in Slice 4). It is NOT a resolution fallback — reviewer's no-name-fallback rule governs resolution; this suppresses EMISSION, in test builds only. Default false; production pays one bool read per scanned row. Tests that flip it must own the whole test binary phase (no concurrent queries in the other mode).
var StrictReferenceCheck bool
StrictReferenceCheck, when true, makes filter/projection cursors evaluate QueryResult.Complete rows through a Strict RowEvalContext, so a reference to a name absent from the (complete) row is reported via values.ReportUnresolvedReference instead of silently yielding NULL. It is the RFC-048 W1 invariant's master switch: default false (production is untouched and pays nothing), turned on by tests to prove no code path emits an unresolved reference. Set it once at test start, before any query runs.
Functions ¶
func EvaluateScalarSubquery ¶
func EvaluateScalarSubquery( ctx context.Context, plan plans.RecordQueryPlan, store *recordlayer.FDBRecordStore, evalCtx *EvaluationContext, props recordlayer.ExecuteProperties, ) (any, error)
EvaluateScalarSubquery executes a scalar subquery plan and returns its single scalar result. SQL standard semantics:
- Exactly one column (else error)
- At most one row (else 21000 cardinality violation)
- Zero rows → nil (SQL NULL)
Used by the Cascades executor to pre-evaluate uncorrelated scalar subqueries before running the outer plan.
func ExecutePlan ¶
func ExecutePlan( ctx context.Context, plan plans.RecordQueryPlan, store *recordlayer.FDBRecordStore, evalCtx *EvaluationContext, continuation []byte, props recordlayer.ExecuteProperties, ) (recordlayer.RecordCursor[QueryResult], error)
ExecutePlan executes a RecordQueryPlan tree against a store, returning a cursor over the results. Recursive — child plans are executed first, then the parent operator is applied.
func OptimizeCoveringIndexScans ¶
func OptimizeCoveringIndexScans(plan plans.RecordQueryPlan) plans.RecordQueryPlan
NOT YET WIRED INTO THE QUERY PIPELINE.
OptimizeCoveringIndexScans walks a physical plan tree and marks index scans as covering when the plan above them only references columns available from the index. This is a post-extraction optimization pass that avoids the per-row LoadRecord() call.
STATUS: skeleton only. The filter cases collect referenced columns but do NOT recurse into children — the most common covering scenario (Filter → IndexScan) is not yet handled. The skeleton compiles and passes tests but produces no optimization. Wire this in after implementing recursive plan-tree walking with column reference propagation.
The optimization is conservative: it only fires when ALL referenced columns in filters and projections above the index scan are present in the index's column list. If any column is missing, the scan stays non-covering (correctness over performance).
func SetNameModelOracle ¶
func SetNameModelOracle(v bool)
SetNameModelOracle flips BOTH §5 name-model oracle globals together: DisablePositionalEmission (suppresses the positional row at every birth site) and values.OracleBakedNameFallback (lets BAKED FieldValues — RFC-173 S2+ eager ordinal nodes, whose name reads are otherwise loud errors — resolve by display name against the name-keyed rows the suppression leaves behind). The two flags share ONE meaning — "the process is running the pre-RFC-173 name model" — so this setter is the only sanctioned write site (review hardening: no harness can flip one without the other). Test-only; callers own the whole test-binary phase. Retires with the name map in Slice 4.
Types ¶
type AggregateTypeMismatchError ¶
type AggregateTypeMismatchError struct {
Message string
}
AggregateTypeMismatchError is returned when MIN or MAX is applied to a non-numeric column. Java's fdb-relational rejects this with "VerifyException: unable to encapsulate aggregate operation due to type mismatch(es)" — the function registry only installs numeric MIN/MAX overloads.
func (*AggregateTypeMismatchError) Error ¶
func (e *AggregateTypeMismatchError) Error() string
type ColumnDef ¶
type ColumnDef struct {
Name string // key for datum map lookup
Label string // display name (alias); empty means use Name
TypeName string // JDBC type name: BIGINT, STRING, DOUBLE, etc.
Nullable int // api.ColumnNoNulls / ColumnNullable / ColumnNullableUnknown
}
ColumnDef describes one column in the result set.
type EvaluationContext ¶
type EvaluationContext struct {
// contains filtered or unexported fields
}
EvaluationContext holds runtime bindings for plan execution: parameter values, correlation bindings (for correlated subqueries), scalar subquery results, and any mutable state that plan nodes share. Mirrors Java's EvaluationContext.
func EmptyEvaluationContext ¶
func EmptyEvaluationContext() *EvaluationContext
EmptyEvaluationContext returns a context with no bindings.
func (*EvaluationContext) BindParameter ¶
func (ec *EvaluationContext) BindParameter(ordinal int, name string) (any, bool)
BindParameter implements values.ParameterBinder. Ordinal is 1-based; named parameters are not yet supported.
func (*EvaluationContext) GetBinding ¶
func (ec *EvaluationContext) GetBinding(id values.CorrelationIdentifier) (any, bool)
GetBinding retrieves a correlation binding.
func (*EvaluationContext) GetCorrelationBinding ¶
func (ec *EvaluationContext) GetCorrelationBinding(id values.CorrelationIdentifier) (any, bool)
GetCorrelationBinding implements values.CorrelationBinder so that QuantifiedObjectValue can resolve correlated rows during scan comparison evaluation in the FlatMap execution path.
func (*EvaluationContext) GetOrCreateTempTable ¶
func (ec *EvaluationContext) GetOrCreateTempTable(id values.CorrelationIdentifier, st *recordlayer.ExecuteState) *TempTable
GetOrCreateTempTable returns the TempTable at the given alias, creating one if it doesn't exist. Mutates ec.bindings directly (intentional — temp tables are shared mutable state across the execution, not copy-on-write like WithBinding). Callers must ensure this is called on the root context, not on a WithBinding copy.
st is the statement's ExecuteState (RFC-130) charged when a temp table is freshly created here; an already-bound temp table keeps its original state (it was minted with the same statement's state). Callers pass props.State.
func (*EvaluationContext) RowContext ¶
func (ec *EvaluationContext) RowContext(datum map[string]any) *values.RowEvalContext
RowContext returns a RowEvalContext combining a datum map with this context's parameter bindings and scalar subquery results. Used when evaluating expressions that mix field references, prepared-statement parameters, and scalar subquery references.
func (*EvaluationContext) RowContextPositional ¶
func (ec *EvaluationContext) RowContextPositional(pos values.OrdinalRow) *values.RowEvalContext
RowContextPositional returns a RowEvalContext whose authoritative row is the RFC-173 Slice 1 ordinal-model positional row (resolved by ordinal, no name-map fallback), combined with this context's parameter bindings, correlation bindings, and scalar subquery results. Use it on the non-join frontier when a param / scalar subquery / outer correlation is in play; when none is, flow the bare OrdinalRow directly. An outer correlation resolves via Correlations first; only the (unbound) frontier quantifier reference falls to the positional row.
func (*EvaluationContext) RowContextStrict ¶
func (ec *EvaluationContext) RowContextStrict(datum map[string]any) *values.RowEvalContext
RowContextStrict is RowContext with the RFC-048 W1 unresolved-reference check armed. Use it only for rows whose key set is complete (QueryResult .Complete) — see RowEvalContext.Strict. Callers gate on StrictReferenceCheck so production keeps the cheaper bare-map fast path.
func (*EvaluationContext) WithBinding ¶
func (ec *EvaluationContext) WithBinding(id values.CorrelationIdentifier, val any) *EvaluationContext
WithBinding returns a shallow copy with an additional binding.
func (*EvaluationContext) WithParams ¶
func (ec *EvaluationContext) WithParams(params []any) *EvaluationContext
WithParams returns a copy with prepared-statement parameter bindings. Params is 0-indexed; ParameterValue ordinals are 1-based.
func (*EvaluationContext) WithScalarSubqueries ¶
func (ec *EvaluationContext) WithScalarSubqueries(results map[values.CorrelationIdentifier]any) *EvaluationContext
WithScalarSubqueries returns a copy with pre-evaluated scalar subquery results bound by correlation alias.
type MaterializationLimitExceededError ¶
MaterializationLimitExceededError is returned when an operator tries to buffer more rows in memory than the configured materialization limit.
func (*MaterializationLimitExceededError) Error ¶
func (e *MaterializationLimitExceededError) Error() string
type NumericRangeOverflowError ¶
func (*NumericRangeOverflowError) Error ¶
func (e *NumericRangeOverflowError) Error() string
type PositionalRow ¶
type PositionalRow struct {
// Type gives each slot its name and type; Slots[i] is the value of the field
// at ordinal i. len(Slots) == len(Type.Fields) for a well-formed row.
Type *values.RecordType
Slots []any
}
PositionalRow is the RFC-173 P2 typed positional runtime row: field values indexed by ORDINAL, paired with the RecordType that names and types each slot. It is the ordinal-model counterpart to the legacy name-keyed map[string]any (QueryResult.Datum).
During the migration it is emitted ALONGSIDE the name-keyed map (dark/dual), with a field-for-field shadow assert (a later P2 increment), until the ordinal model becomes authoritative in Slice 1+ and the name map is retired. Positional access (Slots[ordinal]) mirrors Java's MessageHelpers.getFieldValueForFieldOrdinals; name access resolves the ordinal via RecordType.FieldIndex (P1's sound list-position lookup), so the two representations agree by construction on a well-formed row — that agreement is what the shadow assert pins.
func NewPositionalRow ¶
func NewPositionalRow(typ *values.RecordType) *PositionalRow
NewPositionalRow builds a row for typ with every slot nil (SQL NULL). Slots is sized to the field count so Get/Set are position-safe. A nil typ yields an empty row (zero slots).
func (*PositionalRow) Get ¶
func (r *PositionalRow) Get(ordinal int) (any, bool)
Get returns the value at the given ordinal plus an in-range flag. Nil-safe.
func (*PositionalRow) GetByName ¶
func (r *PositionalRow) GetByName(name string) (any, bool)
GetByName resolves name -> ordinal via the row's RecordType (FieldIndex, P1's sound list-position lookup) then reads that slot. This is the bridge the P2 shadow assert uses to compare positional access against the legacy name-keyed map[string]any. Returns (nil, false) for an unknown name, an anonymous field (empty name never matches), or a nil row/type.
func (*PositionalRow) Set ¶
func (r *PositionalRow) Set(ordinal int, v any) bool
Set writes v at the given ordinal, returning false (no-op) if out of range.
func (*PositionalRow) TypeNames ¶
func (r *PositionalRow) TypeNames() []string
TypeNames returns the row type's column names in ordinal order — diagnostics for values.OrdinalResolutionError (via an optional-interface assertion), so a loud resolution miss reports what the row actually carried.
type QueryResult ¶
type QueryResult struct {
Datum any
// Positional is the RFC-173 ordinal-model sibling of Datum: the same row as
// a typed PositionalRow (field values indexed by ordinal). Non-nil marks the
// row as being on the NON-JOIN FRONTIER (scans, covering scans, projection/
// map over the frontier emit it; join producers mergeRows/qualifyOuterRow do
// NOT), and since Slice 1 it is what FieldValue resolution READS there —
// authoritative, by ordinal, loud on a miss. The name-keyed Datum is still
// emitted alongside for coexistence (downstream name-model consumers, final
// materialization) until Slice 4 retires it; a shadow test pins that the two
// mirror each other field-for-field.
Positional *PositionalRow
Record *recordlayer.FDBStoredRecord[proto.Message]
PrimaryKey tuple.Tuple
// Complete marks a computed/synthetic row whose Datum key set is
// authoritative — every legal column is present (nil-valued for SQL NULL),
// with no proto-style optional-field omissions. Set by aggregate output
// (finalizeGroup/emptyScalarResult). Consumers use it to enable the RFC-048
// W1 strict unresolved-reference check: against such a row, a referenced
// name that is absent is a bug, not a NULL. Raw stored-record rows
// (FromStoredRecord) leave it false, because they legitimately omit unset
// optional fields.
Complete bool
}
QueryResult is the row type flowing through plan execution cursors. Wraps a datum (the computed/flowed row), an optional stored record (when the row originated from a scan), and an optional primary key. Mirrors Java's QueryResult.
func CollectAll ¶
func CollectAll(ctx context.Context, cursor recordlayer.RecordCursor[QueryResult]) ([]QueryResult, error)
CollectAll drains a cursor into a slice.
func CollectAllBounded ¶
func CollectAllBounded(ctx context.Context, cursor recordlayer.RecordCursor[QueryResult], st *recordlayer.ExecuteState, limit int, opName string) ([]QueryResult, error)
CollectAllBounded drains a cursor into a slice through an accounted boundedBuffer (RFC-130): every row is charged against the statement-wide memory byte budget (st) AND counted against the row-count materialization limit, so a missed accumulation site is impossible — the buffer cannot exist without the accountant. st is the always-present statement ExecuteState (props.State); a nil/zero-limit st makes the byte charge a no-op while the row-count cap still applies. Returns MaterializationLimitExceededError on the row cap and MemoryLimitExceededError (→ 54F01) on the byte budget.
func FromStoredRecord ¶
func FromStoredRecord(rec *recordlayer.FDBStoredRecord[proto.Message]) QueryResult
FromStoredRecord builds a QueryResult from a stored record. The datum is set to a map[string]any extracted from the proto message's fields, keyed by UPPER-case field name (matching the identifier folding convention).
type RecordLayerResultSet ¶
type RecordLayerResultSet struct {
// contains filtered or unexported fields
}
RecordLayerResultSet wraps a RecordCursor[QueryResult] and implements api.ResultSet. Mirrors Java's RecordLayerResultSet: Next() advances the cursor, typed accessors read from the current row's datum map.
Column metadata is provided at construction time (derived from the plan's result type or the schema catalog). Column accessors are 1-indexed per JDBC convention.
func NewRecordLayerResultSet ¶
func NewRecordLayerResultSet( ctx context.Context, cursor recordlayer.RecordCursor[QueryResult], columns []ColumnDef, ) *RecordLayerResultSet
NewRecordLayerResultSet constructs a ResultSet from an executor cursor and column definitions.
func (*RecordLayerResultSet) Boolean ¶
func (rs *RecordLayerResultSet) Boolean(columnIndex int) (bool, error)
func (*RecordLayerResultSet) BooleanByName ¶
func (rs *RecordLayerResultSet) BooleanByName(name string) (bool, error)
func (*RecordLayerResultSet) Bytes ¶
func (rs *RecordLayerResultSet) Bytes(columnIndex int) ([]byte, error)
func (*RecordLayerResultSet) BytesByName ¶
func (rs *RecordLayerResultSet) BytesByName(name string) ([]byte, error)
func (*RecordLayerResultSet) Close ¶
func (rs *RecordLayerResultSet) Close() error
func (*RecordLayerResultSet) Continuation ¶
func (rs *RecordLayerResultSet) Continuation() (api.Continuation, error)
func (*RecordLayerResultSet) Double ¶
func (rs *RecordLayerResultSet) Double(columnIndex int) (float64, error)
func (*RecordLayerResultSet) Err ¶
func (rs *RecordLayerResultSet) Err() error
func (*RecordLayerResultSet) Float ¶
func (rs *RecordLayerResultSet) Float(columnIndex int) (float32, error)
func (*RecordLayerResultSet) GetContinuation ¶
func (rs *RecordLayerResultSet) GetContinuation() recordlayer.RecordCursorContinuation
GetContinuation returns the raw cursor continuation from the last Next() call. Used by the paginating execution loop to resume across FDB transactions.
func (*RecordLayerResultSet) GetNoNextReason ¶
func (rs *RecordLayerResultSet) GetNoNextReason() recordlayer.NoNextReason
GetNoNextReason returns the NoNextReason from the last Next() call. This is the AUTHORITATIVE exhaustion signal (SourceExhausted ⇔ end-of-results), and distinguishes a non-terminal out-of-band stop (scan/time/byte limit) from a clean ReturnLimitReached/exhaustion when the continuation has nil bytes — see RFC-127 (Java carries noNextReason as a first-class field for exactly this; its nil-byte START continuation is otherwise ambiguous with end).
func (*RecordLayerResultSet) Long ¶
func (rs *RecordLayerResultSet) Long(columnIndex int) (int64, error)
func (*RecordLayerResultSet) LongByName ¶
func (rs *RecordLayerResultSet) LongByName(name string) (int64, error)
func (*RecordLayerResultSet) MetaData ¶
func (rs *RecordLayerResultSet) MetaData() api.ResultSetMetaData
func (*RecordLayerResultSet) Next ¶
func (rs *RecordLayerResultSet) Next() bool
func (*RecordLayerResultSet) Object ¶
func (rs *RecordLayerResultSet) Object(columnIndex int) (any, error)
func (*RecordLayerResultSet) ObjectByName ¶
func (rs *RecordLayerResultSet) ObjectByName(name string) (any, error)
func (*RecordLayerResultSet) String ¶
func (rs *RecordLayerResultSet) String(columnIndex int) (string, error)
func (*RecordLayerResultSet) StringByName ¶
func (rs *RecordLayerResultSet) StringByName(name string) (string, error)
func (*RecordLayerResultSet) WasNull ¶
func (rs *RecordLayerResultSet) WasNull() bool
type RecursiveCTEDepthExceededError ¶
type RecursiveCTEDepthExceededError struct {
MaxDepth int
}
func (*RecursiveCTEDepthExceededError) Error ¶
func (e *RecursiveCTEDepthExceededError) Error() string
type SortBufferExceededError ¶
SortBufferExceededError is returned when an in-memory sort materializes more rows than the configured limit. Prevents OOM on unbounded ORDER BY without LIMIT.
func (*SortBufferExceededError) Error ¶
func (e *SortBufferExceededError) Error() string
type SumOverflowError ¶
type SumOverflowError struct{}
func (*SumOverflowError) Error ¶
func (*SumOverflowError) Error() string
type TempTable ¶
type TempTable struct {
// contains filtered or unexported fields
}
TempTable is an in-memory list of QueryResult used by TempTableInsertPlan and TempTableScanPlan. Mirrors Java's com.apple.foundationdb.record.TempTable.
RFC-130: a TempTable is a cardinality-growing buffer — the recursive-CTE per-level working set (ping-ponged scan/insert tables) and the TempTableInsertPlan target both accumulate into it, separate from the CollectAllBounded per-level materialization. It carries the statement's always-present *ExecuteState (st) and charges each appended row's byte estimate in Add. The pre-existing sync.Mutex is defensive (the zero- goroutine executor invariant makes it currently moot); charging under the lock is correct regardless — if the executor ever goes concurrent the pinned package_invariant_test fires and ChargeMemory moves to atomic.
func NewTempTable ¶
func NewTempTable() *TempTable
NewTempTable creates an empty temp table with no memory budget. Used by internal call sites that have no statement ExecuteState in scope (and by tests); production statement paths use NewTempTableWithState so the statement-wide memory budget covers the temp-table working set.
func NewTempTableWithState ¶
func NewTempTableWithState(st *recordlayer.ExecuteState) *TempTable
NewTempTableWithState creates an empty temp table that charges its rows against the supplied statement ExecuteState (RFC-130). st is the always- present statement state; a nil/zero-limit st makes the charge a no-op.
func (*TempTable) Add ¶
func (tt *TempTable) Add(qr QueryResult) error
Add appends a QueryResult to the temp table, charging its byte estimate against the statement memory budget first (RFC-130). On a budget breach the row is NOT appended and the *MemoryLimitExceededError is returned.
func (*TempTable) Clear ¶
func (tt *TempTable) Clear()
Clear removes all entries from the temp table.
func (*TempTable) GetList ¶
func (tt *TempTable) GetList() []QueryResult
GetList returns a snapshot of the temp table contents.
func (*TempTable) ReplaceList ¶
func (tt *TempTable) ReplaceList(rows []QueryResult)
ReplaceList replaces the temp-table contents with rows that have ALREADY been charged against the statement memory budget — it does NOT re-charge. Used by the recursive-CTE DISTINCT path, which filters the rows the recursive plan already inserted (and charged via Add) down to the non-duplicate subset; re-charging them through Add would double-count the same resident rows. memUsed is monotonic, so the rows dropped by the filter stay charged (a conservative ceiling) — that is intentional and correct.