1use super::trait_def::PlanVisitor;
4use crate::types::SqlPlan;
5
6pub fn dispatch<V: PlanVisitor>(visitor: &mut V, plan: &SqlPlan) -> Result<V::Output, V::Error> {
7 match plan {
8 SqlPlan::ConstantResult { columns, values } => visitor.constant_result(columns, values),
9 SqlPlan::Scan {
10 collection,
11 alias,
12 engine,
13 filters,
14 projection,
15 sort_keys,
16 limit,
17 offset,
18 distinct,
19 window_functions,
20 temporal,
21 } => visitor.scan(
22 collection,
23 alias.as_deref(),
24 *engine,
25 filters,
26 projection,
27 sort_keys,
28 *limit,
29 *offset,
30 *distinct,
31 window_functions,
32 temporal,
33 ),
34 SqlPlan::PointGet {
35 collection,
36 alias,
37 engine,
38 key_column,
39 key_value,
40 } => visitor.point_get(collection, alias.as_deref(), *engine, key_column, key_value),
41 SqlPlan::DocumentIndexLookup {
42 collection,
43 alias,
44 engine,
45 field,
46 value,
47 filters,
48 projection,
49 sort_keys,
50 limit,
51 offset,
52 distinct,
53 window_functions,
54 case_insensitive,
55 temporal,
56 } => visitor.document_index_lookup(
57 collection,
58 alias.as_deref(),
59 *engine,
60 field,
61 value,
62 filters,
63 projection,
64 sort_keys,
65 *limit,
66 *offset,
67 *distinct,
68 window_functions,
69 *case_insensitive,
70 temporal,
71 ),
72 SqlPlan::RangeScan {
73 collection,
74 field,
75 lower,
76 upper,
77 limit,
78 } => visitor.range_scan(collection, field, lower.as_ref(), upper.as_ref(), *limit),
79 SqlPlan::Insert {
80 collection,
81 engine,
82 rows,
83 column_defaults,
84 if_absent,
85 column_schema,
86 } => visitor.insert(
87 collection,
88 *engine,
89 rows,
90 column_defaults,
91 *if_absent,
92 column_schema,
93 ),
94 SqlPlan::KvInsert {
95 collection,
96 entries,
97 ttl_secs,
98 intent,
99 on_conflict_updates,
100 } => visitor.kv_insert(collection, entries, *ttl_secs, *intent, on_conflict_updates),
101 SqlPlan::Upsert {
102 collection,
103 engine,
104 rows,
105 column_defaults,
106 on_conflict_updates,
107 column_schema,
108 } => visitor.upsert(
109 collection,
110 *engine,
111 rows,
112 column_defaults,
113 on_conflict_updates,
114 column_schema,
115 ),
116 SqlPlan::InsertSelect {
117 target,
118 source,
119 limit,
120 } => visitor.insert_select(target, source, *limit),
121 SqlPlan::Update {
122 collection,
123 engine,
124 assignments,
125 filters,
126 target_keys,
127 returning,
128 } => visitor.update(
129 collection,
130 *engine,
131 assignments,
132 filters,
133 target_keys,
134 *returning,
135 ),
136 SqlPlan::UpdateFrom {
137 collection,
138 engine,
139 source,
140 target_join_col,
141 source_join_col,
142 assignments,
143 target_filters,
144 returning,
145 } => visitor.update_from(
146 collection,
147 *engine,
148 source,
149 target_join_col,
150 source_join_col,
151 assignments,
152 target_filters,
153 *returning,
154 ),
155 SqlPlan::Delete {
156 collection,
157 engine,
158 filters,
159 target_keys,
160 } => visitor.delete(collection, *engine, filters, target_keys),
161 SqlPlan::Truncate {
162 collection,
163 restart_identity,
164 } => visitor.truncate(collection, *restart_identity),
165 SqlPlan::Join {
166 left,
167 right,
168 on,
169 join_type,
170 condition,
171 limit,
172 projection,
173 filters,
174 } => visitor.join(
175 left,
176 right,
177 on,
178 *join_type,
179 condition.as_ref(),
180 *limit,
181 projection,
182 filters,
183 ),
184 SqlPlan::Aggregate {
185 input,
186 group_by,
187 aggregates,
188 having,
189 limit,
190 grouping_sets,
191 sort_keys,
192 } => visitor.aggregate(
193 input,
194 group_by,
195 aggregates,
196 having,
197 *limit,
198 grouping_sets.as_deref(),
199 sort_keys,
200 ),
201 SqlPlan::TimeseriesScan {
202 collection,
203 time_range,
204 bucket_interval_ms,
205 group_by,
206 aggregates,
207 filters,
208 projection,
209 gap_fill,
210 limit,
211 tiered,
212 temporal,
213 } => visitor.timeseries_scan(
214 collection,
215 *time_range,
216 *bucket_interval_ms,
217 group_by,
218 aggregates,
219 filters,
220 projection,
221 gap_fill,
222 *limit,
223 *tiered,
224 temporal,
225 ),
226 SqlPlan::TimeseriesIngest { collection, rows } => {
227 visitor.timeseries_ingest(collection, rows)
228 }
229 SqlPlan::VectorSearch {
230 collection,
231 field,
232 query_vector,
233 top_k,
234 ef_search,
235 metric,
236 filters,
237 array_prefilter,
238 ann_options,
239 skip_payload_fetch,
240 payload_filters,
241 } => visitor.vector_search(
242 collection,
243 field,
244 query_vector,
245 *top_k,
246 *ef_search,
247 *metric,
248 filters,
249 array_prefilter.as_ref(),
250 ann_options,
251 *skip_payload_fetch,
252 payload_filters,
253 ),
254 SqlPlan::MultiVectorSearch {
255 collection,
256 query_vector,
257 top_k,
258 ef_search,
259 } => visitor.multi_vector_search(collection, query_vector, *top_k, *ef_search),
260 SqlPlan::TextSearch {
261 collection,
262 query,
263 top_k,
264 filters,
265 score_alias,
266 } => visitor.text_search(collection, query, *top_k, filters, score_alias.as_deref()),
267 SqlPlan::HybridSearch {
268 collection,
269 query_vector,
270 query_text,
271 top_k,
272 ef_search,
273 vector_weight,
274 fuzzy,
275 score_alias,
276 } => visitor.hybrid_search(
277 collection,
278 query_vector,
279 query_text,
280 *top_k,
281 *ef_search,
282 *vector_weight,
283 *fuzzy,
284 score_alias.as_deref(),
285 ),
286 SqlPlan::HybridSearchTriple {
287 collection,
288 query_vector,
289 query_text,
290 graph_seed_id,
291 graph_depth,
292 graph_edge_label,
293 top_k,
294 ef_search,
295 fuzzy,
296 rrf_k,
297 score_alias,
298 } => visitor.hybrid_search_triple(
299 collection,
300 query_vector,
301 query_text,
302 graph_seed_id,
303 *graph_depth,
304 graph_edge_label.as_deref(),
305 *top_k,
306 *ef_search,
307 *fuzzy,
308 *rrf_k,
309 score_alias.as_deref(),
310 ),
311 SqlPlan::SpatialScan {
312 collection,
313 field,
314 predicate,
315 query_geometry,
316 distance_meters,
317 attribute_filters,
318 limit,
319 projection,
320 } => visitor.spatial_scan(
321 collection,
322 field,
323 predicate,
324 query_geometry,
325 *distance_meters,
326 attribute_filters,
327 *limit,
328 projection,
329 ),
330 SqlPlan::Union { inputs, distinct } => visitor.union(inputs, *distinct),
331 SqlPlan::Intersect { left, right, all } => visitor.intersect(left, right, *all),
332 SqlPlan::Except { left, right, all } => visitor.except(left, right, *all),
333 SqlPlan::RecursiveScan {
334 collection,
335 base_filters,
336 recursive_filters,
337 join_link,
338 max_iterations,
339 distinct,
340 limit,
341 } => visitor.recursive_scan(
342 collection,
343 base_filters,
344 recursive_filters,
345 join_link.as_ref(),
346 *max_iterations,
347 *distinct,
348 *limit,
349 ),
350 SqlPlan::RecursiveValue {
351 cte_name,
352 columns,
353 init_exprs,
354 step_exprs,
355 condition,
356 max_depth,
357 distinct,
358 } => visitor.recursive_value(
359 cte_name,
360 columns,
361 init_exprs,
362 step_exprs,
363 condition.as_deref(),
364 *max_depth,
365 *distinct,
366 ),
367 SqlPlan::Cte { definitions, outer } => visitor.cte(definitions, outer),
368 SqlPlan::CreateArray {
369 name,
370 dims,
371 attrs,
372 tile_extents,
373 cell_order,
374 tile_order,
375 prefix_bits,
376 audit_retain_ms,
377 minimum_audit_retain_ms,
378 } => visitor.create_array(
379 name,
380 dims,
381 attrs,
382 tile_extents,
383 *cell_order,
384 *tile_order,
385 *prefix_bits,
386 *audit_retain_ms,
387 *minimum_audit_retain_ms,
388 ),
389 SqlPlan::DropArray { name, if_exists } => visitor.drop_array(name, *if_exists),
390 SqlPlan::AlterArray {
391 name,
392 audit_retain_ms,
393 minimum_audit_retain_ms,
394 } => visitor.alter_array(name, *audit_retain_ms, *minimum_audit_retain_ms),
395 SqlPlan::InsertArray { name, rows } => visitor.insert_array(name, rows),
396 SqlPlan::DeleteArray { name, coords } => visitor.delete_array(name, coords),
397 SqlPlan::ArraySlice {
398 name,
399 slice,
400 attr_projection,
401 limit,
402 temporal,
403 } => visitor.array_slice(name, slice, attr_projection, *limit, temporal),
404 SqlPlan::ArrayProject {
405 name,
406 attr_projection,
407 } => visitor.array_project(name, attr_projection),
408 SqlPlan::ArrayAgg {
409 name,
410 attr,
411 reducer,
412 group_by_dim,
413 temporal,
414 } => visitor.array_agg(name, attr, reducer, group_by_dim.as_deref(), temporal),
415 SqlPlan::ArrayElementwise {
416 left,
417 right,
418 op,
419 attr,
420 } => visitor.array_elementwise(left, right, *op, attr),
421 SqlPlan::ArrayFlush { name } => visitor.array_flush(name),
422 SqlPlan::ArrayCompact { name } => visitor.array_compact(name),
423 SqlPlan::Merge {
424 target,
425 engine,
426 source,
427 target_join_col,
428 source_join_col,
429 source_alias,
430 clauses,
431 returning,
432 } => visitor.merge(
433 target,
434 *engine,
435 source,
436 target_join_col,
437 source_join_col,
438 source_alias,
439 clauses,
440 *returning,
441 ),
442 SqlPlan::LateralTopK {
443 outer,
444 outer_alias,
445 inner_collection,
446 inner_filters,
447 inner_order_by,
448 inner_limit,
449 correlation_keys,
450 lateral_alias,
451 projection,
452 left_join,
453 } => visitor.lateral_top_k(
454 outer,
455 outer_alias.as_deref(),
456 inner_collection,
457 inner_filters,
458 inner_order_by,
459 *inner_limit,
460 correlation_keys,
461 lateral_alias,
462 projection,
463 *left_join,
464 ),
465 SqlPlan::LateralLoop {
466 outer,
467 outer_alias,
468 inner,
469 correlation_predicates,
470 lateral_alias,
471 projection,
472 outer_row_cap,
473 left_join,
474 } => visitor.lateral_loop(
475 outer,
476 outer_alias.as_deref(),
477 inner,
478 correlation_predicates,
479 lateral_alias,
480 projection,
481 *outer_row_cap,
482 *left_join,
483 ),
484 SqlPlan::VectorPrimaryInsert {
485 collection,
486 field,
487 quantization,
488 storage_dtype,
489 payload_indexes,
490 rows,
491 } => visitor.vector_primary_insert(
492 collection,
493 field,
494 quantization,
495 storage_dtype,
496 payload_indexes,
497 rows,
498 ),
499 SqlPlan::CreateIndex {
500 index_name,
501 collection,
502 field,
503 unique,
504 if_not_exists,
505 case_insensitive,
506 } => visitor.create_index(
507 index_name.as_deref(),
508 collection,
509 field,
510 *unique,
511 *if_not_exists,
512 *case_insensitive,
513 ),
514 SqlPlan::DropIndex {
515 index_name,
516 collection,
517 if_exists,
518 } => visitor.drop_index(index_name, collection.as_deref(), *if_exists),
519 }
520}