Skip to main content

nodedb_sql/engine_rules/
params.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Parameter structs passed into `EngineRules` methods.
4
5use crate::types::*;
6
7/// Parameters for planning an INSERT operation.
8pub struct InsertParams {
9    pub collection: String,
10    pub columns: Vec<String>,
11    /// Every declared DEFAULT already materialized and every literal already
12    /// coerced to its declared column type. An engine stores these as they
13    /// are; none re-reads the catalog's DEFAULT text.
14    pub rows: Vec<Vec<(String, SqlValue)>>,
15    /// Whether a DEFAULT materialized into `rows` was volatile. A plan that
16    /// carries one is never admitted to the plan cache.
17    pub volatile_defaults: bool,
18    /// `ON CONFLICT DO NOTHING` semantics: duplicate-PK rows are skipped
19    /// silently. `false` for plain `INSERT` (raises `unique_violation`).
20    pub if_absent: bool,
21    /// Raw column type strings from the catalog: `(column_name, type_str)`.
22    /// Used by columnar converters to reconstruct the exact `ColumnType` for
23    /// columns whose `SqlDataType` is ambiguous (e.g. both JSON and Bytes map
24    /// to `SqlDataType::Bytes`). Empty for engines that don't need it.
25    pub column_schema: Vec<(String, String)>,
26    /// Declared `PRIMARY KEY` column name (if any), from `CollectionInfo::primary_key`.
27    /// Used by the conversion layer to extract the document id from the
28    /// correct column instead of guessing at `id`/`document_id`/`key`.
29    pub primary_key: Option<String>,
30}
31
32/// Parameters for planning a SCAN operation.
33pub struct ScanParams {
34    pub collection: String,
35    pub alias: Option<String>,
36    pub filters: Vec<Filter>,
37    pub projection: Vec<Projection>,
38    pub sort_keys: Vec<SortKey>,
39    pub limit: Option<usize>,
40    pub offset: usize,
41    pub distinct: bool,
42    pub window_functions: Vec<WindowSpec>,
43    /// Secondary indexes available on the scan's collection. Document
44    /// engines consult this to rewrite equality-on-indexed-field into
45    /// [`SqlPlan::DocumentIndexLookup`]. Other engines ignore it today.
46    pub indexes: Vec<IndexSpec>,
47    /// Bitemporal qualifier propagated from `plan_sql`. Engines without
48    /// bitemporal storage support reject a non-default scope via
49    /// `SqlError::Unsupported` — silently ignoring it would return
50    /// current-state data when the user asked for history.
51    pub temporal: crate::temporal::TemporalScope,
52    /// Whether this collection was created with bitemporal storage. When
53    /// `true`, engines that support bitemporal reads route the scan
54    /// through versioned storage; when `false`, a non-default
55    /// [`Self::temporal`] is rejected.
56    pub bitemporal: bool,
57    /// Whether the collection has a retention policy with AUTO_TIER on. A
58    /// timeseries scan then carries the policy's tiers, so a raw read of a
59    /// range only the tiers hold is refused.
60    pub has_auto_tier: bool,
61}
62
63/// Parameters for planning a POINT GET operation.
64pub struct PointGetParams {
65    pub collection: String,
66    pub alias: Option<String>,
67    pub key_column: String,
68    pub key_value: SqlValue,
69    /// Resolved SELECT target list, propagated onto [`SqlPlan::PointGet`] so the
70    /// physical plan self-describes its output columns.
71    pub projection: Vec<Projection>,
72}
73
74/// Parameters for planning an UPDATE operation.
75pub struct UpdateParams {
76    pub collection: String,
77    pub assignments: Vec<(String, SqlExpr)>,
78    pub filters: Vec<Filter>,
79    pub target_keys: Vec<SqlValue>,
80    pub returning: bool,
81}
82
83/// Parameters for planning an `UPDATE target SET ... FROM src WHERE ...` operation.
84pub struct UpdateFromParams {
85    pub collection: String,
86    /// The FROM source plan (Scan, Join, …).
87    pub source: Box<SqlPlan>,
88    /// The name the statement gives the source. See
89    /// `SqlPlan::UpdateFrom::source_alias`.
90    pub source_alias: String,
91    /// Column in target used as the equi-join key.
92    pub target_join_col: String,
93    /// Column in source used as the equi-join key.
94    pub source_join_col: String,
95    /// SET assignments — RHS may reference source columns.
96    pub assignments: Vec<(String, SqlExpr)>,
97    /// Filters that apply only to the target.
98    pub target_filters: Vec<Filter>,
99    pub returning: bool,
100}
101
102/// Parameters for planning a DELETE operation.
103pub struct DeleteParams {
104    pub collection: String,
105    pub filters: Vec<Filter>,
106    pub target_keys: Vec<SqlValue>,
107}
108
109/// Parameters for planning a TRUNCATE operation.
110pub struct TruncateParams {
111    pub collection: String,
112    pub restart_identity: bool,
113}
114
115/// Parameters for planning an INSERT ... SELECT.
116pub struct InsertSelectParams {
117    /// The target collection.
118    pub collection: String,
119    /// The planned source SELECT.
120    pub source: Box<SqlPlan>,
121    /// `(target_column, source_row_expression)` in target-column order. See
122    /// `SqlPlan::InsertSelect::column_map`.
123    pub column_map: Vec<(String, SqlExpr)>,
124    /// `(target_column, source_output_column)` pairs. See
125    /// `SqlPlan::InsertSelect::source_columns`.
126    pub source_columns: Vec<(String, String)>,
127}
128
129/// Parameters for planning a MERGE operation.
130pub struct MergeParams {
131    pub collection: String,
132    pub source: Box<SqlPlan>,
133    pub target_join_col: String,
134    pub source_join_col: String,
135    pub source_alias: String,
136    pub clauses: Vec<crate::types::MergePlanClause>,
137    pub returning: bool,
138}
139
140/// Parameters for planning an UPSERT operation.
141pub struct UpsertParams {
142    pub collection: String,
143    pub columns: Vec<String>,
144    /// Defaults materialized and literals coerced, as in
145    /// `InsertParams::rows`.
146    pub rows: Vec<Vec<(String, SqlValue)>>,
147    /// Mirrors `InsertParams::volatile_defaults`.
148    pub volatile_defaults: bool,
149    /// `ON CONFLICT (...) DO UPDATE SET` assignments. Empty for plain
150    /// `UPSERT INTO ...`; populated when the caller is
151    /// `INSERT ... ON CONFLICT ... DO UPDATE SET`.
152    pub on_conflict_updates: Vec<(String, SqlExpr)>,
153    /// Raw column type strings from the catalog: `(column_name, type_str)`.
154    /// Mirrors `InsertParams::column_schema` — see that field for rationale.
155    pub column_schema: Vec<(String, String)>,
156    /// Declared `PRIMARY KEY` column name (if any). See `InsertParams::primary_key`.
157    pub primary_key: Option<String>,
158}
159
160/// Parameters for planning an AGGREGATE operation.
161pub struct AggregateParams {
162    pub collection: String,
163    pub alias: Option<String>,
164    pub filters: Vec<Filter>,
165    pub group_by: Vec<SqlExpr>,
166    pub aggregates: Vec<AggregateExpr>,
167    pub having: Vec<Filter>,
168    pub limit: usize,
169    /// The `time_bucket(...)` GROUP BY key, when `group_by` holds one.
170    pub time_bucket: Option<TimeBucketKey>,
171    /// ROLLUP / CUBE / GROUPING SETS expansion: each set holds the indices
172    /// into `group_by` present in that set. `None` for a plain GROUP BY.
173    pub grouping_sets: Option<Vec<Vec<usize>>>,
174    /// The collection's declared columns, for engines whose native
175    /// aggregation depends on column types.
176    pub columns: Vec<ColumnInfo>,
177    /// Whether HAVING computes an aggregate the SELECT list does not show.
178    pub hidden_aggregates: bool,
179    /// Whether the caller wraps the input rows in semi or anti joins below
180    /// the aggregate. The plan must then be an aggregate over an input plan.
181    pub input_joins: bool,
182    /// Whether the collection has auto-tiering enabled.
183    pub has_auto_tier: bool,
184    /// Whether this collection was created with bitemporal storage.
185    /// When `true`, the base scan inside the aggregate is allowed to
186    /// carry a non-default temporal scope.
187    pub bitemporal: bool,
188    /// System-time / valid-time scope to propagate into the underlying
189    /// scan so bitemporal aggregate queries project an as-of snapshot
190    /// before grouping.
191    pub temporal: crate::temporal::TemporalScope,
192}
193
194/// A `time_bucket(interval, column)` GROUP BY key.
195#[derive(Debug, Clone, Copy, PartialEq, Eq)]
196pub struct TimeBucketKey {
197    /// Index of the key in `AggregateParams::group_by`.
198    pub group_index: usize,
199    /// Bucket width in milliseconds. 0 when the interval is not a literal
200    /// the planner can read.
201    pub interval_ms: i64,
202}