pub enum SqlPlan {
Show 51 variants
ConstantResult {
columns: Vec<String>,
values: Vec<SqlValue>,
volatile: bool,
},
Scan {
collection: String,
alias: Option<String>,
engine: EngineType,
filters: Vec<Filter>,
projection: Vec<Projection>,
sort_keys: Vec<SortKey>,
limit: Option<usize>,
offset: usize,
distinct: bool,
window_functions: Vec<WindowSpec>,
temporal: TemporalScope,
},
PointGet {
collection: String,
alias: Option<String>,
engine: EngineType,
key_column: String,
key_value: SqlValue,
projection: Vec<Projection>,
},
DocumentIndexLookup(DocumentIndexLookupPlan),
RangeScan(RangeScanPlan),
Insert(InsertPlan),
KvInsert(KvInsertPlan),
Upsert(UpsertPlan),
InsertSelect {
target: String,
source: Box<SqlPlan>,
column_map: Vec<(String, SqlExpr)>,
source_columns: Vec<(String, String)>,
},
Update {
collection: String,
engine: EngineType,
assignments: Vec<(String, SqlExpr)>,
filters: Vec<Filter>,
target_keys: Vec<SqlValue>,
returning: bool,
},
UpdateFrom {
collection: String,
engine: EngineType,
source: Box<SqlPlan>,
source_alias: String,
target_join_col: String,
source_join_col: String,
assignments: Vec<(String, SqlExpr)>,
target_filters: Vec<Filter>,
returning: bool,
},
Delete {
collection: String,
engine: EngineType,
filters: Vec<Filter>,
target_keys: Vec<SqlValue>,
},
Truncate {
collection: String,
engine: EngineType,
restart_identity: bool,
},
Join {
left: Box<SqlPlan>,
right: Box<SqlPlan>,
on: Vec<(String, String)>,
join_type: JoinType,
condition: Option<SqlExpr>,
limit: Option<usize>,
projection: Vec<Projection>,
filters: Vec<Filter>,
},
Aggregate {
input: Box<SqlPlan>,
group_by: Vec<SqlExpr>,
group_by_aliases: Vec<Option<String>>,
output_order: Vec<AggOutputSlot>,
aggregates: Vec<AggregateExpr>,
having: Vec<Filter>,
limit: usize,
grouping_sets: Option<Vec<Vec<usize>>>,
sort_keys: Vec<SortKey>,
},
TimeseriesScan(TimeseriesScanPlan),
TimeseriesIngest(TimeseriesIngestPlan),
VectorSearch {Show 13 fields
collection: String,
field: String,
query_vector: Vec<f32>,
top_k: usize,
ef_search: usize,
metric: DistanceMetric,
filters: Vec<Filter>,
array_prefilter: Option<ArrayPrefilter>,
ann_options: VectorAnnOptions,
skip_payload_fetch: bool,
payload_filters: Vec<SqlPayloadAtom>,
pk_prefilter: Option<Vec<SqlValue>>,
projection: Vec<Projection>,
},
MultiVectorSearch {
collection: String,
query_vector: Vec<f32>,
top_k: usize,
ef_search: usize,
projection: Vec<Projection>,
},
SparseSearch {
collection: String,
field: String,
query_entries: Vec<(u32, f32)>,
top_k: usize,
projection: Vec<Projection>,
},
TextSearch(TextSearchPlan),
HybridSearch(HybridSearchPlan),
HybridSearchTriple(HybridSearchTriplePlan),
SpatialScan {
collection: String,
field: String,
predicate: SpatialPredicate,
query_geometry: Geometry,
distance_meters: f64,
attribute_filters: Vec<Filter>,
limit: usize,
projection: Vec<Projection>,
},
Union {
inputs: Vec<SqlPlan>,
distinct: bool,
},
Intersect {
left: Box<SqlPlan>,
right: Box<SqlPlan>,
all: bool,
},
Except {
left: Box<SqlPlan>,
right: Box<SqlPlan>,
all: bool,
},
RecursiveScan(RecursiveScanPlan),
RecursiveValue(RecursiveValuePlan),
Cte(CtePlan),
Subquery {
input: Box<SqlPlan>,
filters: Vec<Filter>,
projection: Vec<Projection>,
window_functions: Vec<WindowSpec>,
sort_keys: Vec<SortKey>,
offset: usize,
distinct: bool,
limit: Option<usize>,
},
CreateArray(CreateArrayPlan),
DropArray {
name: String,
if_exists: bool,
},
AlterArray(AlterArrayPlan),
InsertArray(InsertArrayPlan),
DeleteArray(DeleteArrayPlan),
ArraySlice(ArraySlicePlan),
ArrayProject(ArrayProjectPlan),
ArrayAgg(ArrayAggPlan),
ArrayElementwise(ArrayElementwisePlan),
ArrayFlush {
name: String,
},
ArrayCompact {
name: String,
},
Merge(MergePlan),
LateralTopK(LateralTopKPlan),
LateralLoop(LateralLoopPlan),
VectorPrimaryInsert(VectorPrimaryInsertPlan),
VectorPrimaryDelete(VectorPrimaryDeletePlan),
VectorPrimaryTruncate(VectorPrimaryTruncatePlan),
VectorPrimaryUpdate(VectorPrimaryUpdatePlan),
CreateIndex(CreateIndexPlan),
DropIndex(DropIndexPlan),
}Expand description
The top-level plan produced by the SQL planner.
Variants§
ConstantResult
Query with no FROM clause: SELECT 1, SELECT ‘hello’ AS name, etc. Produces a single row with evaluated constant expressions.
Fields
Scan
Fields
engine: EngineTypeprojection: Vec<Projection>window_functions: Vec<WindowSpec>temporal: TemporalScopeBitemporal qualifier extracted from FOR SYSTEM_TIME /
FOR VALID_TIME. Default when the scan is current-state.
PointGet
Fields
engine: EngineTypeprojection: Vec<Projection>Resolved SELECT target list, for output-schema derivation.
DocumentIndexLookup(DocumentIndexLookupPlan)
Document fetch via a secondary index: equality predicate on an indexed field. The executor performs an index lookup to resolve matching document IDs, reads each document, and applies any remaining filters, projection, sort, and limit.
Emitted by document_schemaless::plan_scan /
document_strict::plan_scan when the WHERE clause contains a
single equality predicate on a Ready indexed field. Any
additional predicates fall through as post-filters.
RangeScan(RangeScanPlan)
Insert(InsertPlan)
KvInsert(KvInsertPlan)
KV INSERT: key and value are fundamentally separate.
Each entry is (key, value_columns).
Upsert(UpsertPlan)
UPSERT: insert or merge if document exists.
InsertSelect
Fields
column_map: Vec<(String, SqlExpr)>(target_column, source_expression), in target-column order,
each expression over a stored source row. A plain document scan
source is read as stored rows and shaped with this map.
Empty means passthrough: INSERT INTO t SELECT * FROM s copies
each source row unchanged. Non-empty means every target column is
materialized from the paired expression over the source row.
Update
Fields
engine: EngineTypeUpdateFrom
UPDATE target SET col = src.col2 FROM src WHERE target.id = src.id
Two-phase execution: read source, whose plan carries the WHERE
conjuncts over the source alone, then for each matched source row
that satisfies the join predicates against a target row, apply
assignments (which may reference source columns via qualified names
src.col).
join_predicates are equality pairs (target_col, source_col) extracted
from the WHERE clause linking the two tables. target_filters are
remaining WHERE predicates that reference only target.
Fields
engine: EngineTypesource: Box<SqlPlan>The FROM source: a Scan, Join, or other read plan, with every
WHERE conjunct that reads only the source as its filters.
source_alias: StringThe name the statement gives the source: its alias, else its
table name. Assignments read source columns as <alias>.<col>.
Delete
Truncate
Join
Fields
limit: Option<usize>None = no SQL LIMIT clause (output bounded downstream by the
memory byte budget, never silently truncated); Some(n) = explicit
LIMIT n (output capped at exactly n).
projection: Vec<Projection>Post-join projection: column names to keep (empty = all columns).
Aggregate
Fields
group_by_aliases: Vec<Option<String>>SELECT-list output alias for each GROUP BY key, parallel to
group_by. Some(alias) when the projection aliased the key
(SELECT k AS label ... GROUP BY k → Some("label")); None
when the projection has no explicit alias for that key, so the
output column name falls back to the raw grouped column name.
Empty when the plan was built without a projection in scope
(treated the same as all-None).
output_order: Vec<AggOutputSlot>SELECT-list interleaving of group_by keys and aggregates, in
output order. Empty when built without a projection in scope (see
AggOutputSlot) — output_schema falls back to group-keys-first.
aggregates: Vec<AggregateExpr>grouping_sets: Option<Vec<Vec<usize>>>When the GROUP BY contains ROLLUP/CUBE/GROUPING SETS, this field holds
the expansion. Each inner Vec<usize> is one grouping set — the indices
into group_by (the canonical key list) that are present (non-NULL)
for rows in that set. None = plain single-set GROUP BY.
TimeseriesScan(TimeseriesScanPlan)
TimeseriesIngest(TimeseriesIngestPlan)
VectorSearch
Fields
metric: DistanceMetricDistance metric requested by the query operator (<->, <=>, <#>).
Overrides the collection-default metric at search time.
array_prefilter: Option<ArrayPrefilter>Optional cross-engine prefilter: when set, the ND-array slice
runs first and its output cells’ surrogates form a bitmap that
gates the HNSW candidate set. Set by the planner when an
ORDER BY vector_distance(...) LIMIT k query is JOINed against
ARRAY_SLICE(...). The convert layer lowers this to
VectorOp::Search { inline_prefilter_plan: Some(ArrayOp::SurrogateBitmapScan) }.
ann_options: VectorAnnOptionsANN knobs parsed from the optional third JSON-string argument
to vector_distance(field, query, '{...}').
skip_payload_fetch: boolWhen true, the projection contains only the surrogate/PK column
and/or vector_distance(...) — no payload fields. The Data Plane
can skip the document-body fetch entirely for vector-primary
collections. Always false for non-vector-primary collections
(document body is the primary result).
payload_filters: Vec<SqlPayloadAtom>Predicates against payload-indexed columns on a vector-primary
collection. Each atom is Eq(field, value), In(field, values),
or Range(field, ...). The convert layer translates SqlValue →
nodedb_types::Value and emits them as
VectorOp::Search::payload_filters. The Data Plane intersects
the resulting bitmap with the HNSW candidate set via the
per-collection PayloadIndexSet::pre_filter.
pk_prefilter: Option<Vec<SqlValue>>Primary keys a top-level WHERE pk = v / pk IN (...) conjunct
names. The search ranks only those rows: the convert layer lowers
the keys to the candidate bitmap the index search honors. None:
no key restriction. Some(empty): no row is a candidate.
projection: Vec<Projection>Resolved SELECT target list, for output-schema derivation.
MultiVectorSearch
Fields
projection: Vec<Projection>Resolved SELECT target list, for output-schema derivation.
SparseSearch
Sparse-vector inverted-index search.
Produced by the planner when the leading ORDER BY expression is
sparse_score(field, '{dim: weight, ...}'). The query literal is
parsed into (dimension, weight) entries at plan time. The convert
layer lowers this to VectorOp::SparseSearch, which returns the
top_k documents with the highest dot-product score — matching the
DESC (similarity) ordering the SQL author wrote.
Fields
projection: Vec<Projection>Resolved SELECT target list, for output-schema derivation.
TextSearch(TextSearchPlan)
Full-text search: WHERE text_match(...) matches, or a
bm25_score(...) score scan over every row the filters admit.
HybridSearch(HybridSearchPlan)
HybridSearchTriple(HybridSearchTriplePlan)
Three-source hybrid search: vector + BM25 text + graph BFS, fused via weighted RRF.
Produced when the planner detects rrf_score(vector_distance(...), bm25_score(...), graph_score(...)) with three source arguments.
SpatialScan
Union
Intersect
Except
RecursiveScan(RecursiveScanPlan)
RecursiveValue(RecursiveValuePlan)
Value-generating recursive CTE (WITH RECURSIVE name(cols) AS (anchor UNION [ALL] step)).
Unlike RecursiveScan, this variant carries no collection reference — the anchor
row is produced entirely from literal expressions and each iteration applies the
step expressions to the previous row. The executor evaluates this iteratively
in the Data Plane without touching storage.
All expressions are stored as raw SQL text so they can be serialised across the
SPSC bridge without requiring SqlExpr to implement Serialize. The executor
parses them at execution time via the same lightweight expression evaluator used
by the procedural executor.
Cte(CtePlan)
Non-recursive CTE: execute each definition, then the outer query.
Subquery
Relational post-processing over a subquery/derived-table body whose leaf plan cannot absorb the outer query’s constraints.
Produced by CTE / derived-table inlining when the referenced body is not
a plain Scan (which carries its own filters/sort/limit/offset/distinct)
and the outer reference adds constraints the body has no slot for — an
ORDER BY, OFFSET, DISTINCT, or a LIMIT that must apply after a
reorder. Without this node those constraints were silently dropped,
returning the body’s unordered/unoffset/undeduplicated rows.
The Data Plane materializes input’s rows, then applies, in this order:
filter → offset → sort → distinct → project → limit — matching
QueryOp::ProviderScan semantics (which this lowers onto). Constraints
the body CAN absorb (e.g. an unordered LIMIT folded into a vector
search’s top_k, or a WHERE pushed into the engine as a post-filter)
are applied at the leaf during inlining and are NOT repeated here.
Fields
filters: Vec<Filter>Predicates applied to the materialized rows (outer WHERE that the
body leaf did not absorb).
projection: Vec<Projection>Outer projection (target list). Empty = inherit the body’s columns.
window_functions: Vec<WindowSpec>Window functions evaluated over the post-processed rows. Empty = none.
CreateArray(CreateArrayPlan)
CREATE ARRAY <name> DIMS (...) ATTRS (...) TILE_EXTENTS (...).
AST is engine-agnostic — the Origin converter builds the typed
nodedb_array::ArraySchema and persists the catalog row.
DropArray
DROP ARRAY [IF EXISTS] <name> — pure Control-Plane catalog
mutation. Per-core array store cleanup happens lazily.
AlterArray(AlterArrayPlan)
ALTER ARRAY <name> SET (audit_retain_ms = N, ...).
Double-Option semantics for each diff field:
None= key was absent from SET clause → field unchanged.Some(None)= key present with valueNULL→ field set to NULL.Some(Some(v))= key present with integer value → field set to v.
InsertArray(InsertArrayPlan)
INSERT INTO ARRAY <name> COORDS (...) VALUES (...) [, ...].
DeleteArray(DeleteArrayPlan)
DELETE FROM ARRAY <name> WHERE COORDS IN ((...), (...)).
ArraySlice(ArraySlicePlan)
SELECT * FROM ARRAY_SLICE(name, {dim:[lo,hi],..}, [attrs], limit).
ArrayProject(ArrayProjectPlan)
SELECT * FROM ARRAY_PROJECT(name, [attrs]).
ArrayAgg(ArrayAggPlan)
SELECT * FROM ARRAY_AGG(name, attr, reducer [, group_by_dim]).
ArrayElementwise(ArrayElementwisePlan)
SELECT * FROM ARRAY_ELEMENTWISE(left, right, op, attr).
ArrayFlush
SELECT ARRAY_FLUSH(name) — returns one row {result: BOOL}.
ArrayCompact
SELECT ARRAY_COMPACT(name) — returns one row {result: BOOL}.
Merge(MergePlan)
MERGE INTO target USING source ON ... WHEN ... THEN ...
Supported only for document_schemaless and document_strict engines.
The Data Plane handler evaluates WHEN arms in declaration order and
applies the first matching action to each joined or unmatched row.
LateralTopK(LateralTopKPlan)
LATERAL subquery that is equi-correlated and has ORDER BY + LIMIT k.
Emitted when the inner subquery has an equi-key correlation to the outer
table plus an ORDER BY ... LIMIT k clause. The Data Plane scans the
inner collection once per outer row applying the equi-filter, sorts by
inner_order_by, and retains at most inner_limit rows.
correlation_keys is (outer_col, inner_col) — the equi-join pairs
that correlate inner to outer.
LateralLoop(LateralLoopPlan)
General LATERAL subquery — per-outer-row correlated nested loop.
Emitted for LATERAL subqueries that cannot be rewritten as equi-join
hash joins or LateralTopK. The Control Plane drives execution: it
materialises outer rows, then for each row substitutes the correlation
values as additional filters on the inner plan and re-dispatches it.
Bounded by outer_row_cap; queries that exceed the cap receive a typed
SqlError::Unsupported before any data is returned.
VectorPrimaryInsert(VectorPrimaryInsertPlan)
INSERT / UPSERT into a vector-primary collection.
Emitted by the planner instead of the generic Insert / Upsert
variants when the target collection has primary = PrimaryEngine::Vector. A single row lowers to one of
VectorOp::DirectInsert / DirectInsertIfAbsent / DirectUpsert
per intent. Several rows lower to one VectorOp::DirectBatchWrite
page. Both bypass full-document MessagePack encoding.
VectorPrimaryDelete(VectorPrimaryDeletePlan)
DELETE on a vector-primary collection.
target_keys carries the primary keys when the WHERE clause is a
pure primary-key equality (or IN / OR of equalities). Otherwise
filters is evaluated against every sidecar row on the Data Plane.
VectorPrimaryTruncate(VectorPrimaryTruncatePlan)
TRUNCATE on a vector-primary collection.
Removes every row from the HNSW index and its payload sidecar.
VectorPrimaryUpdate(VectorPrimaryUpdatePlan)
UPDATE on a vector-primary collection.
new_vector is the literal the statement assigns to the vector
column, when it assigns one. Every other assignment stays in
assignments and patches the payload sidecar.
CreateIndex(CreateIndexPlan)
CREATE [UNIQUE] INDEX [IF NOT EXISTS] name ON collection (field)
Registers a secondary index on the named field of a document or KV collection. The executor backtracks existing rows into the index so it is immediately consistent.
DropIndex(DropIndexPlan)
DROP INDEX [IF EXISTS] name [ON collection]
Removes a secondary index from a collection. All index entries are erased and the index metadata is unregistered.
Implementations§
Source§impl SqlPlan
impl SqlPlan
Sourcepub fn cache_eligibility(&self) -> PlanCacheEligibility
pub fn cache_eligibility(&self) -> PlanCacheEligibility
Classify dependencies that are not represented by descriptor versions.
Document point operations resolve primary-key bytes to a surrogate while lowering. That binding can appear after an earlier miss without any schema-version change, so those physical tasks cannot be cached.
A plan holding a volatile call is DataDependent for the same reason:
the call was evaluated while the plan was built, so caching it would
replay one execution’s value into every later one.
Source§impl SqlPlan
impl SqlPlan
Sourcepub fn carries_search_cells(&self) -> bool
pub fn carries_search_cells(&self) -> bool
Whether this plan’s rows carry the search cells distance and
_surrogate.
The three variants here lower to the vector-hit row shape
(classify_hit_shape → HitShape::Vector, over VectorOp::Search | MultiSearch | SparseSearch | MultiVectorScoreSearch): the engine emits
{id: <surrogate>, distance, …} rows, and the post-process arm resolves
the surrogate to the user primary key.
Hybrid fusion rows (HybridSearch, HybridSearchTriple) classify as
HitShape::Hybrid and carry a doc_id plus a score alias instead, so
they are not search-cell plans.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for SqlPlan
impl RefUnwindSafe for SqlPlan
impl Send for SqlPlan
impl Sync for SqlPlan
impl Unpin for SqlPlan
impl UnsafeUnpin for SqlPlan
impl UnwindSafe for SqlPlan
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.