1#[derive(Debug, Clone)]
8pub enum SqlPlan {
9 ConstantResult {
13 columns: Vec<String>,
14 values: Vec<SqlValue>,
15 },
16
17 Scan {
19 collection: String,
20 alias: Option<String>,
21 engine: EngineType,
22 filters: Vec<Filter>,
23 projection: Vec<Projection>,
24 sort_keys: Vec<SortKey>,
25 limit: Option<usize>,
26 offset: usize,
27 distinct: bool,
28 window_functions: Vec<WindowSpec>,
29 },
30 PointGet {
31 collection: String,
32 alias: Option<String>,
33 engine: EngineType,
34 key_column: String,
35 key_value: SqlValue,
36 },
37 RangeScan {
38 collection: String,
39 field: String,
40 lower: Option<SqlValue>,
41 upper: Option<SqlValue>,
42 limit: usize,
43 },
44
45 Insert {
47 collection: String,
48 engine: EngineType,
49 rows: Vec<Vec<(String, SqlValue)>>,
50 column_defaults: Vec<(String, String)>,
53 },
54 KvInsert {
57 collection: String,
58 entries: Vec<(SqlValue, Vec<(String, SqlValue)>)>,
59 ttl_secs: u64,
61 },
62 Upsert {
64 collection: String,
65 engine: EngineType,
66 rows: Vec<Vec<(String, SqlValue)>>,
67 column_defaults: Vec<(String, String)>,
68 on_conflict_updates: Vec<(String, SqlExpr)>,
73 },
74 InsertSelect {
75 target: String,
76 source: Box<SqlPlan>,
77 limit: usize,
78 },
79 Update {
80 collection: String,
81 engine: EngineType,
82 assignments: Vec<(String, SqlExpr)>,
83 filters: Vec<Filter>,
84 target_keys: Vec<SqlValue>,
85 returning: bool,
86 },
87 Delete {
88 collection: String,
89 engine: EngineType,
90 filters: Vec<Filter>,
91 target_keys: Vec<SqlValue>,
92 },
93 Truncate {
94 collection: String,
95 restart_identity: bool,
96 },
97
98 Join {
100 left: Box<SqlPlan>,
101 right: Box<SqlPlan>,
102 on: Vec<(String, String)>,
103 join_type: JoinType,
104 condition: Option<SqlExpr>,
105 limit: usize,
106 projection: Vec<Projection>,
108 filters: Vec<Filter>,
110 },
111
112 Aggregate {
114 input: Box<SqlPlan>,
115 group_by: Vec<SqlExpr>,
116 aggregates: Vec<AggregateExpr>,
117 having: Vec<Filter>,
118 limit: usize,
119 },
120
121 TimeseriesScan {
123 collection: String,
124 time_range: (i64, i64),
125 bucket_interval_ms: i64,
126 group_by: Vec<String>,
127 aggregates: Vec<AggregateExpr>,
128 filters: Vec<Filter>,
129 projection: Vec<Projection>,
130 gap_fill: String,
131 limit: usize,
132 tiered: bool,
133 },
134 TimeseriesIngest {
135 collection: String,
136 rows: Vec<Vec<(String, SqlValue)>>,
137 },
138
139 VectorSearch {
141 collection: String,
142 field: String,
143 query_vector: Vec<f32>,
144 top_k: usize,
145 ef_search: usize,
146 filters: Vec<Filter>,
147 },
148 MultiVectorSearch {
149 collection: String,
150 query_vector: Vec<f32>,
151 top_k: usize,
152 ef_search: usize,
153 },
154 TextSearch {
155 collection: String,
156 query: String,
157 top_k: usize,
158 fuzzy: bool,
159 filters: Vec<Filter>,
160 },
161 HybridSearch {
162 collection: String,
163 query_vector: Vec<f32>,
164 query_text: String,
165 top_k: usize,
166 ef_search: usize,
167 vector_weight: f32,
168 fuzzy: bool,
169 },
170 SpatialScan {
171 collection: String,
172 field: String,
173 predicate: SpatialPredicate,
174 query_geometry: Vec<u8>,
175 distance_meters: f64,
176 attribute_filters: Vec<Filter>,
177 limit: usize,
178 projection: Vec<Projection>,
179 },
180
181 Union {
183 inputs: Vec<SqlPlan>,
184 distinct: bool,
185 },
186 Intersect {
187 left: Box<SqlPlan>,
188 right: Box<SqlPlan>,
189 all: bool,
190 },
191 Except {
192 left: Box<SqlPlan>,
193 right: Box<SqlPlan>,
194 all: bool,
195 },
196 RecursiveScan {
197 collection: String,
198 base_filters: Vec<Filter>,
199 recursive_filters: Vec<Filter>,
200 max_iterations: usize,
201 distinct: bool,
202 limit: usize,
203 },
204
205 Cte {
207 definitions: Vec<(String, SqlPlan)>,
209 outer: Box<SqlPlan>,
211 },
212}
213
214#[derive(Debug, Clone, Copy, PartialEq, Eq)]
216pub enum EngineType {
217 DocumentSchemaless,
218 DocumentStrict,
219 KeyValue,
220 Columnar,
221 Timeseries,
222 Spatial,
223}
224
225#[derive(Debug, Clone, Copy, PartialEq, Eq)]
227pub enum JoinType {
228 Inner,
229 Left,
230 Right,
231 Full,
232 Semi,
233 Anti,
234 Cross,
235}
236
237impl JoinType {
238 pub fn as_str(&self) -> &'static str {
239 match self {
240 Self::Inner => "inner",
241 Self::Left => "left",
242 Self::Right => "right",
243 Self::Full => "full",
244 Self::Semi => "semi",
245 Self::Anti => "anti",
246 Self::Cross => "cross",
247 }
248 }
249}
250
251#[derive(Debug, Clone, Copy, PartialEq, Eq)]
253pub enum SpatialPredicate {
254 DWithin,
255 Contains,
256 Intersects,
257 Within,
258}
259
260#[derive(Debug, Clone)]
262pub struct Filter {
263 pub expr: FilterExpr,
264}
265
266#[derive(Debug, Clone)]
268pub enum FilterExpr {
269 Comparison {
270 field: String,
271 op: CompareOp,
272 value: SqlValue,
273 },
274 Like {
275 field: String,
276 pattern: String,
277 },
278 InList {
279 field: String,
280 values: Vec<SqlValue>,
281 },
282 Between {
283 field: String,
284 low: SqlValue,
285 high: SqlValue,
286 },
287 IsNull {
288 field: String,
289 },
290 IsNotNull {
291 field: String,
292 },
293 And(Vec<Filter>),
294 Or(Vec<Filter>),
295 Not(Box<Filter>),
296 Expr(SqlExpr),
298}
299
300#[derive(Debug, Clone, Copy, PartialEq, Eq)]
302pub enum CompareOp {
303 Eq,
304 Ne,
305 Gt,
306 Ge,
307 Lt,
308 Le,
309}
310
311#[derive(Debug, Clone)]
313pub enum Projection {
314 Column(String),
316 Star,
318 QualifiedStar(String),
320 Computed { expr: SqlExpr, alias: String },
322}
323
324#[derive(Debug, Clone)]
326pub struct SortKey {
327 pub expr: SqlExpr,
328 pub ascending: bool,
329 pub nulls_first: bool,
330}
331
332#[derive(Debug, Clone)]
334pub struct AggregateExpr {
335 pub function: String,
336 pub args: Vec<SqlExpr>,
337 pub alias: String,
338 pub distinct: bool,
339}
340
341#[derive(Debug, Clone)]
343pub struct WindowSpec {
344 pub function: String,
345 pub args: Vec<SqlExpr>,
346 pub partition_by: Vec<SqlExpr>,
347 pub order_by: Vec<SortKey>,
348 pub alias: String,
349}
350
351#[derive(Debug, Clone, PartialEq)]
353pub enum SqlValue {
354 Int(i64),
355 Float(f64),
356 String(String),
357 Bool(bool),
358 Null,
359 Bytes(Vec<u8>),
360 Array(Vec<SqlValue>),
361}
362
363#[derive(Debug, Clone)]
365pub enum SqlExpr {
366 Column { table: Option<String>, name: String },
368 Literal(SqlValue),
370 BinaryOp {
372 left: Box<SqlExpr>,
373 op: BinaryOp,
374 right: Box<SqlExpr>,
375 },
376 UnaryOp { op: UnaryOp, expr: Box<SqlExpr> },
378 Function {
380 name: String,
381 args: Vec<SqlExpr>,
382 distinct: bool,
383 },
384 Case {
386 operand: Option<Box<SqlExpr>>,
387 when_then: Vec<(SqlExpr, SqlExpr)>,
388 else_expr: Option<Box<SqlExpr>>,
389 },
390 Cast { expr: Box<SqlExpr>, to_type: String },
392 Subquery(Box<SqlPlan>),
394 Wildcard,
396 IsNull { expr: Box<SqlExpr>, negated: bool },
398 InList {
400 expr: Box<SqlExpr>,
401 list: Vec<SqlExpr>,
402 negated: bool,
403 },
404 Between {
406 expr: Box<SqlExpr>,
407 low: Box<SqlExpr>,
408 high: Box<SqlExpr>,
409 negated: bool,
410 },
411 Like {
413 expr: Box<SqlExpr>,
414 pattern: Box<SqlExpr>,
415 negated: bool,
416 },
417 ArrayLiteral(Vec<SqlExpr>),
419}
420
421#[derive(Debug, Clone, Copy, PartialEq, Eq)]
423pub enum BinaryOp {
424 Add,
426 Sub,
427 Mul,
428 Div,
429 Mod,
430 Eq,
432 Ne,
433 Gt,
434 Ge,
435 Lt,
436 Le,
437 And,
439 Or,
440 Concat,
442}
443
444#[derive(Debug, Clone, Copy, PartialEq, Eq)]
446pub enum UnaryOp {
447 Neg,
448 Not,
449}
450
451#[derive(Debug, Clone, PartialEq, Eq)]
453pub enum SqlDataType {
454 Int64,
455 Float64,
456 String,
457 Bool,
458 Bytes,
459 Timestamp,
460 Decimal,
461 Uuid,
462 Vector(usize),
463 Geometry,
464}
465
466pub use crate::catalog::{SqlCatalog, SqlCatalogError};
472
473#[derive(Debug, Clone)]
475pub struct CollectionInfo {
476 pub name: String,
477 pub engine: EngineType,
478 pub columns: Vec<ColumnInfo>,
479 pub primary_key: Option<String>,
480 pub has_auto_tier: bool,
481}
482
483#[derive(Debug, Clone)]
485pub struct ColumnInfo {
486 pub name: String,
487 pub data_type: SqlDataType,
488 pub nullable: bool,
489 pub is_primary_key: bool,
490 pub default: Option<String>,
492}