1#![allow(clippy::too_many_arguments)]
6
7use crate::fts_types::FtsQuery;
8use crate::temporal::TemporalScope;
9use crate::types::SqlPlan;
10use crate::types::filter::Filter;
11use crate::types::plan::{
12 ArrayPrefilter, KvInsertIntent, MergePlanClause, VectorAnnOptions, VectorPrimaryRow,
13};
14use crate::types::query::{
15 AggregateExpr, EngineType, JoinType, Projection, SortKey, SpatialPredicate, WindowSpec,
16};
17use crate::types_array::{
18 ArrayAttrAst, ArrayBinaryOpAst, ArrayCellOrderAst, ArrayCoordLiteral, ArrayDimAst,
19 ArrayInsertRow, ArrayReducerAst, ArraySliceAst, ArrayTileOrderAst,
20};
21use crate::types_expr::{SqlExpr, SqlPayloadAtom, SqlValue};
22use nodedb_types::PayloadIndexKind;
23use nodedb_types::VectorQuantization;
24use nodedb_types::vector_distance::DistanceMetric;
25
26pub trait PlanVisitor {
29 type Output;
31 type Error;
33
34 fn constant_result(
36 &mut self,
37 columns: &[String],
38 values: &[SqlValue],
39 ) -> Result<Self::Output, Self::Error>;
40
41 fn scan(
43 &mut self,
44 collection: &str,
45 alias: Option<&str>,
46 engine: EngineType,
47 filters: &[Filter],
48 projection: &[Projection],
49 sort_keys: &[SortKey],
50 limit: Option<usize>,
51 offset: usize,
52 distinct: bool,
53 window_functions: &[WindowSpec],
54 temporal: &TemporalScope,
55 ) -> Result<Self::Output, Self::Error>;
56
57 fn point_get(
59 &mut self,
60 collection: &str,
61 alias: Option<&str>,
62 engine: EngineType,
63 key_column: &str,
64 key_value: &SqlValue,
65 ) -> Result<Self::Output, Self::Error>;
66
67 fn document_index_lookup(
69 &mut self,
70 collection: &str,
71 alias: Option<&str>,
72 engine: EngineType,
73 field: &str,
74 value: &SqlValue,
75 filters: &[Filter],
76 projection: &[Projection],
77 sort_keys: &[SortKey],
78 limit: Option<usize>,
79 offset: usize,
80 distinct: bool,
81 window_functions: &[WindowSpec],
82 case_insensitive: bool,
83 temporal: &TemporalScope,
84 ) -> Result<Self::Output, Self::Error>;
85
86 fn range_scan(
88 &mut self,
89 collection: &str,
90 field: &str,
91 lower: Option<&SqlValue>,
92 upper: Option<&SqlValue>,
93 limit: usize,
94 ) -> Result<Self::Output, Self::Error>;
95
96 fn insert(
98 &mut self,
99 collection: &str,
100 engine: EngineType,
101 rows: &[Vec<(String, SqlValue)>],
102 column_defaults: &[(String, String)],
103 if_absent: bool,
104 column_schema: &[(String, String)],
105 ) -> Result<Self::Output, Self::Error>;
106
107 fn kv_insert(
109 &mut self,
110 collection: &str,
111 entries: &[(SqlValue, Vec<(String, SqlValue)>)],
112 ttl_secs: u64,
113 intent: KvInsertIntent,
114 on_conflict_updates: &[(String, SqlExpr)],
115 ) -> Result<Self::Output, Self::Error>;
116
117 fn upsert(
119 &mut self,
120 collection: &str,
121 engine: EngineType,
122 rows: &[Vec<(String, SqlValue)>],
123 column_defaults: &[(String, String)],
124 on_conflict_updates: &[(String, SqlExpr)],
125 column_schema: &[(String, String)],
126 ) -> Result<Self::Output, Self::Error>;
127
128 fn insert_select(
130 &mut self,
131 target: &str,
132 source: &SqlPlan,
133 limit: usize,
134 ) -> Result<Self::Output, Self::Error>;
135
136 fn update(
138 &mut self,
139 collection: &str,
140 engine: EngineType,
141 assignments: &[(String, SqlExpr)],
142 filters: &[Filter],
143 target_keys: &[SqlValue],
144 returning: bool,
145 ) -> Result<Self::Output, Self::Error>;
146
147 fn update_from(
149 &mut self,
150 collection: &str,
151 engine: EngineType,
152 source: &SqlPlan,
153 target_join_col: &str,
154 source_join_col: &str,
155 assignments: &[(String, SqlExpr)],
156 target_filters: &[Filter],
157 returning: bool,
158 ) -> Result<Self::Output, Self::Error>;
159
160 fn delete(
162 &mut self,
163 collection: &str,
164 engine: EngineType,
165 filters: &[Filter],
166 target_keys: &[SqlValue],
167 ) -> Result<Self::Output, Self::Error>;
168
169 fn truncate(
171 &mut self,
172 collection: &str,
173 restart_identity: bool,
174 ) -> Result<Self::Output, Self::Error>;
175
176 fn join(
178 &mut self,
179 left: &SqlPlan,
180 right: &SqlPlan,
181 on: &[(String, String)],
182 join_type: JoinType,
183 condition: Option<&SqlExpr>,
184 limit: usize,
185 projection: &[Projection],
186 filters: &[Filter],
187 ) -> Result<Self::Output, Self::Error>;
188
189 fn aggregate(
191 &mut self,
192 input: &SqlPlan,
193 group_by: &[SqlExpr],
194 aggregates: &[AggregateExpr],
195 having: &[Filter],
196 limit: usize,
197 grouping_sets: Option<&[Vec<usize>]>,
198 sort_keys: &[SortKey],
199 ) -> Result<Self::Output, Self::Error>;
200
201 fn timeseries_scan(
203 &mut self,
204 collection: &str,
205 time_range: (i64, i64),
206 bucket_interval_ms: i64,
207 group_by: &[String],
208 aggregates: &[AggregateExpr],
209 filters: &[Filter],
210 projection: &[Projection],
211 gap_fill: &str,
212 limit: usize,
213 tiered: bool,
214 temporal: &TemporalScope,
215 ) -> Result<Self::Output, Self::Error>;
216
217 fn timeseries_ingest(
219 &mut self,
220 collection: &str,
221 rows: &[Vec<(String, SqlValue)>],
222 ) -> Result<Self::Output, Self::Error>;
223
224 fn vector_search(
226 &mut self,
227 collection: &str,
228 field: &str,
229 query_vector: &[f32],
230 top_k: usize,
231 ef_search: usize,
232 metric: DistanceMetric,
233 filters: &[Filter],
234 array_prefilter: Option<&ArrayPrefilter>,
235 ann_options: &VectorAnnOptions,
236 skip_payload_fetch: bool,
237 payload_filters: &[SqlPayloadAtom],
238 ) -> Result<Self::Output, Self::Error>;
239
240 fn multi_vector_search(
242 &mut self,
243 collection: &str,
244 query_vector: &[f32],
245 top_k: usize,
246 ef_search: usize,
247 ) -> Result<Self::Output, Self::Error>;
248
249 fn text_search(
251 &mut self,
252 collection: &str,
253 query: &FtsQuery,
254 top_k: usize,
255 filters: &[Filter],
256 score_alias: Option<&str>,
257 ) -> Result<Self::Output, Self::Error>;
258
259 fn hybrid_search(
261 &mut self,
262 collection: &str,
263 query_vector: &[f32],
264 query_text: &str,
265 top_k: usize,
266 ef_search: usize,
267 vector_weight: f32,
268 fuzzy: bool,
269 score_alias: Option<&str>,
270 ) -> Result<Self::Output, Self::Error>;
271
272 fn hybrid_search_triple(
274 &mut self,
275 collection: &str,
276 query_vector: &[f32],
277 query_text: &str,
278 graph_seed_id: &str,
279 graph_depth: usize,
280 graph_edge_label: Option<&str>,
281 top_k: usize,
282 ef_search: usize,
283 fuzzy: bool,
284 rrf_k: (f64, f64, f64),
285 score_alias: Option<&str>,
286 ) -> Result<Self::Output, Self::Error>;
287
288 fn spatial_scan(
290 &mut self,
291 collection: &str,
292 field: &str,
293 predicate: &SpatialPredicate,
294 query_geometry: &nodedb_types::geometry::Geometry,
295 distance_meters: f64,
296 attribute_filters: &[Filter],
297 limit: usize,
298 projection: &[Projection],
299 ) -> Result<Self::Output, Self::Error>;
300
301 fn union(&mut self, inputs: &[SqlPlan], distinct: bool) -> Result<Self::Output, Self::Error>;
303
304 fn intersect(
306 &mut self,
307 left: &SqlPlan,
308 right: &SqlPlan,
309 all: bool,
310 ) -> Result<Self::Output, Self::Error>;
311
312 fn except(
314 &mut self,
315 left: &SqlPlan,
316 right: &SqlPlan,
317 all: bool,
318 ) -> Result<Self::Output, Self::Error>;
319
320 fn recursive_scan(
322 &mut self,
323 collection: &str,
324 base_filters: &[Filter],
325 recursive_filters: &[Filter],
326 join_link: Option<&(String, String)>,
327 max_iterations: usize,
328 distinct: bool,
329 limit: usize,
330 ) -> Result<Self::Output, Self::Error>;
331
332 fn recursive_value(
334 &mut self,
335 cte_name: &str,
336 columns: &[String],
337 init_exprs: &[String],
338 step_exprs: &[String],
339 condition: Option<&str>,
340 max_depth: usize,
341 distinct: bool,
342 ) -> Result<Self::Output, Self::Error>;
343
344 fn cte(
346 &mut self,
347 definitions: &[(String, SqlPlan)],
348 outer: &SqlPlan,
349 ) -> Result<Self::Output, Self::Error>;
350
351 fn create_array(
353 &mut self,
354 name: &str,
355 dims: &[ArrayDimAst],
356 attrs: &[ArrayAttrAst],
357 tile_extents: &[i64],
358 cell_order: ArrayCellOrderAst,
359 tile_order: ArrayTileOrderAst,
360 prefix_bits: u8,
361 audit_retain_ms: Option<u64>,
362 minimum_audit_retain_ms: Option<u64>,
363 ) -> Result<Self::Output, Self::Error>;
364
365 fn drop_array(&mut self, name: &str, if_exists: bool) -> Result<Self::Output, Self::Error>;
367
368 fn alter_array(
370 &mut self,
371 name: &str,
372 audit_retain_ms: Option<Option<i64>>,
373 minimum_audit_retain_ms: Option<u64>,
374 ) -> Result<Self::Output, Self::Error>;
375
376 fn insert_array(
378 &mut self,
379 name: &str,
380 rows: &[ArrayInsertRow],
381 ) -> Result<Self::Output, Self::Error>;
382
383 fn delete_array(
385 &mut self,
386 name: &str,
387 coords: &[Vec<ArrayCoordLiteral>],
388 ) -> Result<Self::Output, Self::Error>;
389
390 fn array_slice(
392 &mut self,
393 name: &str,
394 slice: &ArraySliceAst,
395 attr_projection: &[String],
396 limit: u32,
397 temporal: &TemporalScope,
398 ) -> Result<Self::Output, Self::Error>;
399
400 fn array_project(
402 &mut self,
403 name: &str,
404 attr_projection: &[String],
405 ) -> Result<Self::Output, Self::Error>;
406
407 fn array_agg(
409 &mut self,
410 name: &str,
411 attr: &str,
412 reducer: &ArrayReducerAst,
413 group_by_dim: Option<&str>,
414 temporal: &TemporalScope,
415 ) -> Result<Self::Output, Self::Error>;
416
417 fn array_elementwise(
419 &mut self,
420 left: &str,
421 right: &str,
422 op: ArrayBinaryOpAst,
423 attr: &str,
424 ) -> Result<Self::Output, Self::Error>;
425
426 fn array_flush(&mut self, name: &str) -> Result<Self::Output, Self::Error>;
428
429 fn array_compact(&mut self, name: &str) -> Result<Self::Output, Self::Error>;
431
432 fn merge(
434 &mut self,
435 target: &str,
436 engine: EngineType,
437 source: &SqlPlan,
438 target_join_col: &str,
439 source_join_col: &str,
440 source_alias: &str,
441 clauses: &[MergePlanClause],
442 returning: bool,
443 ) -> Result<Self::Output, Self::Error>;
444
445 fn lateral_top_k(
447 &mut self,
448 outer: &SqlPlan,
449 outer_alias: Option<&str>,
450 inner_collection: &str,
451 inner_filters: &[Filter],
452 inner_order_by: &[SortKey],
453 inner_limit: usize,
454 correlation_keys: &[(String, String)],
455 lateral_alias: &str,
456 projection: &[Projection],
457 left_join: bool,
458 ) -> Result<Self::Output, Self::Error>;
459
460 fn lateral_loop(
462 &mut self,
463 outer: &SqlPlan,
464 outer_alias: Option<&str>,
465 inner: &SqlPlan,
466 correlation_predicates: &[(String, String)],
467 lateral_alias: &str,
468 projection: &[Projection],
469 outer_row_cap: usize,
470 left_join: bool,
471 ) -> Result<Self::Output, Self::Error>;
472
473 fn vector_primary_insert(
475 &mut self,
476 collection: &str,
477 field: &str,
478 quantization: &VectorQuantization,
479 storage_dtype: &nodedb_types::VectorStorageDtype,
480 payload_indexes: &[(String, PayloadIndexKind)],
481 rows: &[VectorPrimaryRow],
482 ) -> Result<Self::Output, Self::Error>;
483
484 fn create_index(
486 &mut self,
487 index_name: Option<&str>,
488 collection: &str,
489 field: &str,
490 unique: bool,
491 if_not_exists: bool,
492 case_insensitive: bool,
493 ) -> Result<Self::Output, Self::Error>;
494
495 fn drop_index(
497 &mut self,
498 index_name: &str,
499 collection: Option<&str>,
500 if_exists: bool,
501 ) -> Result<Self::Output, Self::Error>;
502}