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 DocumentIndexLookup {
47 collection: String,
48 alias: Option<String>,
49 engine: EngineType,
50 field: String,
52 value: SqlValue,
54 filters: Vec<Filter>,
56 projection: Vec<Projection>,
57 sort_keys: Vec<SortKey>,
58 limit: Option<usize>,
59 offset: usize,
60 distinct: bool,
61 window_functions: Vec<WindowSpec>,
62 case_insensitive: bool,
65 },
66 RangeScan {
67 collection: String,
68 field: String,
69 lower: Option<SqlValue>,
70 upper: Option<SqlValue>,
71 limit: usize,
72 },
73
74 Insert {
76 collection: String,
77 engine: EngineType,
78 rows: Vec<Vec<(String, SqlValue)>>,
79 column_defaults: Vec<(String, String)>,
82 },
83 KvInsert {
86 collection: String,
87 entries: Vec<(SqlValue, Vec<(String, SqlValue)>)>,
88 ttl_secs: u64,
90 },
91 Upsert {
93 collection: String,
94 engine: EngineType,
95 rows: Vec<Vec<(String, SqlValue)>>,
96 column_defaults: Vec<(String, String)>,
97 on_conflict_updates: Vec<(String, SqlExpr)>,
102 },
103 InsertSelect {
104 target: String,
105 source: Box<SqlPlan>,
106 limit: usize,
107 },
108 Update {
109 collection: String,
110 engine: EngineType,
111 assignments: Vec<(String, SqlExpr)>,
112 filters: Vec<Filter>,
113 target_keys: Vec<SqlValue>,
114 returning: bool,
115 },
116 Delete {
117 collection: String,
118 engine: EngineType,
119 filters: Vec<Filter>,
120 target_keys: Vec<SqlValue>,
121 },
122 Truncate {
123 collection: String,
124 restart_identity: bool,
125 },
126
127 Join {
129 left: Box<SqlPlan>,
130 right: Box<SqlPlan>,
131 on: Vec<(String, String)>,
132 join_type: JoinType,
133 condition: Option<SqlExpr>,
134 limit: usize,
135 projection: Vec<Projection>,
137 filters: Vec<Filter>,
139 },
140
141 Aggregate {
143 input: Box<SqlPlan>,
144 group_by: Vec<SqlExpr>,
145 aggregates: Vec<AggregateExpr>,
146 having: Vec<Filter>,
147 limit: usize,
148 },
149
150 TimeseriesScan {
152 collection: String,
153 time_range: (i64, i64),
154 bucket_interval_ms: i64,
155 group_by: Vec<String>,
156 aggregates: Vec<AggregateExpr>,
157 filters: Vec<Filter>,
158 projection: Vec<Projection>,
159 gap_fill: String,
160 limit: usize,
161 tiered: bool,
162 },
163 TimeseriesIngest {
164 collection: String,
165 rows: Vec<Vec<(String, SqlValue)>>,
166 },
167
168 VectorSearch {
170 collection: String,
171 field: String,
172 query_vector: Vec<f32>,
173 top_k: usize,
174 ef_search: usize,
175 filters: Vec<Filter>,
176 },
177 MultiVectorSearch {
178 collection: String,
179 query_vector: Vec<f32>,
180 top_k: usize,
181 ef_search: usize,
182 },
183 TextSearch {
184 collection: String,
185 query: String,
186 top_k: usize,
187 fuzzy: bool,
188 filters: Vec<Filter>,
189 },
190 HybridSearch {
191 collection: String,
192 query_vector: Vec<f32>,
193 query_text: String,
194 top_k: usize,
195 ef_search: usize,
196 vector_weight: f32,
197 fuzzy: bool,
198 },
199 SpatialScan {
200 collection: String,
201 field: String,
202 predicate: SpatialPredicate,
203 query_geometry: Vec<u8>,
204 distance_meters: f64,
205 attribute_filters: Vec<Filter>,
206 limit: usize,
207 projection: Vec<Projection>,
208 },
209
210 Union {
212 inputs: Vec<SqlPlan>,
213 distinct: bool,
214 },
215 Intersect {
216 left: Box<SqlPlan>,
217 right: Box<SqlPlan>,
218 all: bool,
219 },
220 Except {
221 left: Box<SqlPlan>,
222 right: Box<SqlPlan>,
223 all: bool,
224 },
225 RecursiveScan {
226 collection: String,
227 base_filters: Vec<Filter>,
228 recursive_filters: Vec<Filter>,
229 join_link: Option<(String, String)>,
234 max_iterations: usize,
235 distinct: bool,
236 limit: usize,
237 },
238
239 Cte {
241 definitions: Vec<(String, SqlPlan)>,
243 outer: Box<SqlPlan>,
245 },
246}
247
248#[derive(Debug, Clone, Copy, PartialEq, Eq)]
250pub enum EngineType {
251 DocumentSchemaless,
252 DocumentStrict,
253 KeyValue,
254 Columnar,
255 Timeseries,
256 Spatial,
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq)]
261pub enum JoinType {
262 Inner,
263 Left,
264 Right,
265 Full,
266 Semi,
267 Anti,
268 Cross,
269}
270
271impl JoinType {
272 pub fn as_str(&self) -> &'static str {
273 match self {
274 Self::Inner => "inner",
275 Self::Left => "left",
276 Self::Right => "right",
277 Self::Full => "full",
278 Self::Semi => "semi",
279 Self::Anti => "anti",
280 Self::Cross => "cross",
281 }
282 }
283}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq)]
287pub enum SpatialPredicate {
288 DWithin,
289 Contains,
290 Intersects,
291 Within,
292}
293
294#[derive(Debug, Clone)]
296pub struct Filter {
297 pub expr: FilterExpr,
298}
299
300#[derive(Debug, Clone)]
302pub enum FilterExpr {
303 Comparison {
304 field: String,
305 op: CompareOp,
306 value: SqlValue,
307 },
308 Like {
309 field: String,
310 pattern: String,
311 },
312 InList {
313 field: String,
314 values: Vec<SqlValue>,
315 },
316 Between {
317 field: String,
318 low: SqlValue,
319 high: SqlValue,
320 },
321 IsNull {
322 field: String,
323 },
324 IsNotNull {
325 field: String,
326 },
327 And(Vec<Filter>),
328 Or(Vec<Filter>),
329 Not(Box<Filter>),
330 Expr(SqlExpr),
332}
333
334#[derive(Debug, Clone, Copy, PartialEq, Eq)]
336pub enum CompareOp {
337 Eq,
338 Ne,
339 Gt,
340 Ge,
341 Lt,
342 Le,
343}
344
345#[derive(Debug, Clone)]
347pub enum Projection {
348 Column(String),
350 Star,
352 QualifiedStar(String),
354 Computed { expr: SqlExpr, alias: String },
356}
357
358#[derive(Debug, Clone)]
360pub struct SortKey {
361 pub expr: SqlExpr,
362 pub ascending: bool,
363 pub nulls_first: bool,
364}
365
366#[derive(Debug, Clone)]
368pub struct AggregateExpr {
369 pub function: String,
370 pub args: Vec<SqlExpr>,
371 pub alias: String,
372 pub distinct: bool,
373}
374
375#[derive(Debug, Clone)]
377pub struct WindowSpec {
378 pub function: String,
379 pub args: Vec<SqlExpr>,
380 pub partition_by: Vec<SqlExpr>,
381 pub order_by: Vec<SortKey>,
382 pub alias: String,
383}
384
385#[derive(Debug, Clone, PartialEq)]
387pub enum SqlValue {
388 Int(i64),
389 Float(f64),
390 String(String),
391 Bool(bool),
392 Null,
393 Bytes(Vec<u8>),
394 Array(Vec<SqlValue>),
395}
396
397#[derive(Debug, Clone)]
399pub enum SqlExpr {
400 Column { table: Option<String>, name: String },
402 Literal(SqlValue),
404 BinaryOp {
406 left: Box<SqlExpr>,
407 op: BinaryOp,
408 right: Box<SqlExpr>,
409 },
410 UnaryOp { op: UnaryOp, expr: Box<SqlExpr> },
412 Function {
414 name: String,
415 args: Vec<SqlExpr>,
416 distinct: bool,
417 },
418 Case {
420 operand: Option<Box<SqlExpr>>,
421 when_then: Vec<(SqlExpr, SqlExpr)>,
422 else_expr: Option<Box<SqlExpr>>,
423 },
424 Cast { expr: Box<SqlExpr>, to_type: String },
426 Subquery(Box<SqlPlan>),
428 Wildcard,
430 IsNull { expr: Box<SqlExpr>, negated: bool },
432 InList {
434 expr: Box<SqlExpr>,
435 list: Vec<SqlExpr>,
436 negated: bool,
437 },
438 Between {
440 expr: Box<SqlExpr>,
441 low: Box<SqlExpr>,
442 high: Box<SqlExpr>,
443 negated: bool,
444 },
445 Like {
447 expr: Box<SqlExpr>,
448 pattern: Box<SqlExpr>,
449 negated: bool,
450 },
451 ArrayLiteral(Vec<SqlExpr>),
453}
454
455#[derive(Debug, Clone, Copy, PartialEq, Eq)]
457pub enum BinaryOp {
458 Add,
460 Sub,
461 Mul,
462 Div,
463 Mod,
464 Eq,
466 Ne,
467 Gt,
468 Ge,
469 Lt,
470 Le,
471 And,
473 Or,
474 Concat,
476}
477
478#[derive(Debug, Clone, Copy, PartialEq, Eq)]
480pub enum UnaryOp {
481 Neg,
482 Not,
483}
484
485#[derive(Debug, Clone, PartialEq, Eq)]
487pub enum SqlDataType {
488 Int64,
489 Float64,
490 String,
491 Bool,
492 Bytes,
493 Timestamp,
494 Decimal,
495 Uuid,
496 Vector(usize),
497 Geometry,
498}
499
500pub use crate::catalog::{SqlCatalog, SqlCatalogError};
506
507#[derive(Debug, Clone)]
509pub struct CollectionInfo {
510 pub name: String,
511 pub engine: EngineType,
512 pub columns: Vec<ColumnInfo>,
513 pub primary_key: Option<String>,
514 pub has_auto_tier: bool,
515 pub indexes: Vec<IndexSpec>,
520}
521
522#[derive(Debug, Clone)]
524pub struct IndexSpec {
525 pub name: String,
526 pub field: String,
529 pub unique: bool,
530 pub case_insensitive: bool,
531 pub state: IndexState,
533 pub predicate: Option<String>,
539}
540
541#[derive(Debug, Clone, Copy, PartialEq, Eq)]
544pub enum IndexState {
545 Building,
546 Ready,
547}
548
549#[derive(Debug, Clone)]
551pub struct ColumnInfo {
552 pub name: String,
553 pub data_type: SqlDataType,
554 pub nullable: bool,
555 pub is_primary_key: bool,
556 pub default: Option<String>,
558}