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}