1use super::args::{
9 AggregateVisitArgs, DocumentIndexLookupVisitArgs, HybridSearchTripleVisitArgs,
10 HybridSearchVisitArgs, InsertVisitArgs, JoinVisitArgs, RecursiveScanVisitArgs,
11 RecursiveValueVisitArgs, ScanVisitArgs, SpatialScanVisitArgs, TextSearchVisitArgs,
12 TimeseriesScanVisitArgs, UpdateFromVisitArgs, UpsertVisitArgs, VectorSearchVisitArgs,
13};
14use super::dispatch_rest::dispatch_rest;
15use super::trait_def::PlanVisitor;
16use crate::types::SqlPlan;
17use crate::types::{
18 DocumentIndexLookupPlan, HybridSearchPlan, HybridSearchTriplePlan, InsertPlan, KvInsertPlan,
19 RangeScanPlan, RecursiveScanPlan, RecursiveValuePlan, TextSearchPlan, TimeseriesIngestPlan,
20 TimeseriesScanPlan, UpsertPlan,
21};
22
23pub fn dispatch<V: PlanVisitor>(visitor: &mut V, plan: &SqlPlan) -> Result<V::Output, V::Error> {
24 match plan {
25 SqlPlan::ConstantResult {
26 columns, values, ..
27 } => visitor.constant_result(columns, values),
28 SqlPlan::Scan {
29 collection,
30 alias,
31 engine,
32 filters,
33 projection,
34 sort_keys,
35 limit,
36 offset,
37 distinct,
38 window_functions,
39 temporal,
40 } => visitor.scan(ScanVisitArgs {
41 collection,
42 alias: alias.as_deref(),
43 engine: *engine,
44 filters,
45 projection,
46 sort_keys,
47 limit: *limit,
48 offset: *offset,
49 distinct: *distinct,
50 window_functions,
51 temporal,
52 }),
53 SqlPlan::PointGet {
54 collection,
55 alias,
56 engine,
57 key_column,
58 key_value,
59 projection: _,
60 } => visitor.point_get(collection, alias.as_deref(), *engine, key_column, key_value),
61 SqlPlan::DocumentIndexLookup(DocumentIndexLookupPlan {
62 collection,
63 alias,
64 engine,
65 field,
66 value,
67 filters,
68 projection,
69 sort_keys,
70 limit,
71 offset,
72 distinct,
73 window_functions,
74 case_insensitive,
75 temporal,
76 }) => visitor.document_index_lookup(DocumentIndexLookupVisitArgs {
77 collection,
78 alias: alias.as_deref(),
79 engine: *engine,
80 field,
81 value,
82 filters,
83 projection,
84 sort_keys,
85 limit: *limit,
86 offset: *offset,
87 distinct: *distinct,
88 window_functions,
89 case_insensitive: *case_insensitive,
90 temporal,
91 }),
92 SqlPlan::RangeScan(RangeScanPlan {
93 collection,
94 field,
95 lower,
96 upper,
97 limit,
98 projection: _,
99 }) => visitor.range_scan(collection, field, lower.as_ref(), upper.as_ref(), *limit),
100 SqlPlan::Insert(InsertPlan {
101 collection,
102 engine,
103 route,
104 rows,
105 volatile_defaults: _,
106 if_absent,
107 column_schema,
108 primary_key,
109 }) => visitor.insert(InsertVisitArgs {
110 collection,
111 engine: *engine,
112 route: *route,
113 rows,
114 if_absent: *if_absent,
115 column_schema,
116 primary_key: primary_key.as_deref(),
117 }),
118 SqlPlan::KvInsert(KvInsertPlan {
119 collection,
120 entries,
121 ttl_secs,
122 intent,
123 on_conflict_updates,
124 ..
125 }) => visitor.kv_insert(collection, entries, *ttl_secs, *intent, on_conflict_updates),
126 SqlPlan::Upsert(UpsertPlan {
127 collection,
128 engine,
129 route,
130 rows,
131 volatile_defaults: _,
132 on_conflict_updates,
133 column_schema,
134 primary_key,
135 }) => visitor.upsert(UpsertVisitArgs {
136 collection,
137 engine: *engine,
138 route: *route,
139 rows,
140 on_conflict_updates,
141 column_schema,
142 primary_key: primary_key.as_deref(),
143 }),
144 SqlPlan::InsertSelect {
145 target,
146 source,
147 column_map,
148 source_columns,
149 } => visitor.insert_select(target, source, column_map, source_columns),
150 SqlPlan::Update {
151 collection,
152 engine,
153 assignments,
154 filters,
155 target_keys,
156 returning,
157 } => visitor.update(
158 collection,
159 *engine,
160 assignments,
161 filters,
162 target_keys,
163 *returning,
164 ),
165 SqlPlan::UpdateFrom {
166 collection,
167 engine,
168 source,
169 source_alias,
170 target_join_col,
171 source_join_col,
172 assignments,
173 target_filters,
174 returning,
175 } => visitor.update_from(UpdateFromVisitArgs {
176 collection,
177 engine: *engine,
178 source,
179 source_alias,
180 target_join_col,
181 source_join_col,
182 assignments,
183 target_filters,
184 returning: *returning,
185 }),
186 SqlPlan::Delete {
187 collection,
188 engine,
189 filters,
190 target_keys,
191 } => visitor.delete(collection, *engine, filters, target_keys),
192 SqlPlan::Truncate {
193 collection,
194 engine,
195 restart_identity,
196 } => visitor.truncate(collection, *engine, *restart_identity),
197 SqlPlan::Join {
198 left,
199 right,
200 on,
201 join_type,
202 condition,
203 limit,
204 projection,
205 filters,
206 } => visitor.join(JoinVisitArgs {
207 left,
208 right,
209 on,
210 join_type: *join_type,
211 condition: condition.as_ref(),
212 limit: *limit,
213 projection,
214 filters,
215 }),
216 SqlPlan::Aggregate {
217 input,
218 group_by,
219 group_by_aliases: _,
220 output_order: _,
221 aggregates,
222 having,
223 limit,
224 grouping_sets,
225 sort_keys,
226 } => visitor.aggregate(AggregateVisitArgs {
227 input,
228 group_by,
229 aggregates,
230 having,
231 limit: *limit,
232 grouping_sets: grouping_sets.as_deref(),
233 sort_keys,
234 }),
235 SqlPlan::TimeseriesScan(TimeseriesScanPlan {
236 collection,
237 time_range,
238 bucket_interval_ms,
239 group_by,
240 aggregates,
241 filters,
242 having,
243 projection,
244 gap_fill,
245 limit,
246 sort_keys,
247 tiered,
248 temporal,
249 }) => visitor.timeseries_scan(TimeseriesScanVisitArgs {
250 collection,
251 time_range: *time_range,
252 bucket_interval_ms: *bucket_interval_ms,
253 group_by,
254 aggregates,
255 filters,
256 having,
257 projection,
258 gap_fill,
259 limit: *limit,
260 sort_keys,
261 tiered: *tiered,
262 temporal,
263 }),
264 SqlPlan::TimeseriesIngest(TimeseriesIngestPlan {
265 collection,
266 rows,
267 volatile_defaults: _,
268 }) => visitor.timeseries_ingest(collection, rows),
269 SqlPlan::VectorSearch {
270 collection,
271 field,
272 query_vector,
273 top_k,
274 ef_search,
275 metric,
276 filters,
277 array_prefilter,
278 ann_options,
279 skip_payload_fetch,
280 payload_filters,
281 pk_prefilter,
282 projection: _,
283 } => visitor.vector_search(VectorSearchVisitArgs {
284 collection,
285 field,
286 query_vector,
287 top_k: *top_k,
288 ef_search: *ef_search,
289 metric: *metric,
290 filters,
291 array_prefilter: array_prefilter.as_ref(),
292 ann_options,
293 skip_payload_fetch: *skip_payload_fetch,
294 payload_filters,
295 pk_prefilter: pk_prefilter.as_deref(),
296 }),
297 SqlPlan::MultiVectorSearch {
298 collection,
299 query_vector,
300 top_k,
301 ef_search,
302 projection: _,
303 } => visitor.multi_vector_search(collection, query_vector, *top_k, *ef_search),
304 SqlPlan::SparseSearch {
305 collection,
306 field,
307 query_entries,
308 top_k,
309 projection: _,
310 } => visitor.sparse_search(collection, field, query_entries, *top_k),
311 SqlPlan::TextSearch(TextSearchPlan {
312 collection,
313 shape,
314 filters,
315 scores,
316 projection: _,
317 }) => visitor.text_search(TextSearchVisitArgs {
318 collection,
319 shape,
320 filters,
321 scores,
322 }),
323 SqlPlan::HybridSearch(HybridSearchPlan {
324 collection,
325 vector_field,
326 query_vector,
327 text_field,
328 query_text,
329 filters,
330 top_k,
331 ef_search,
332 vector_weight,
333 mode,
334 fuzzy,
335 score_alias,
336 projection: _,
337 }) => visitor.hybrid_search(HybridSearchVisitArgs {
338 collection,
339 vector_field,
340 query_vector,
341 text_field: text_field.as_deref(),
342 query_text,
343 filters,
344 top_k: *top_k,
345 ef_search: *ef_search,
346 vector_weight: *vector_weight,
347 mode: *mode,
348 fuzzy: *fuzzy,
349 score_alias: score_alias.as_deref(),
350 }),
351 SqlPlan::HybridSearchTriple(HybridSearchTriplePlan {
352 collection,
353 vector_field,
354 query_vector,
355 text_field,
356 query_text,
357 filters,
358 graph_seed_id,
359 graph_depth,
360 graph_edge_label,
361 top_k,
362 ef_search,
363 mode,
364 fuzzy,
365 rrf_k,
366 score_alias,
367 projection: _,
368 }) => visitor.hybrid_search_triple(HybridSearchTripleVisitArgs {
369 collection,
370 vector_field,
371 query_vector,
372 text_field: text_field.as_deref(),
373 query_text,
374 filters,
375 graph_seed_id,
376 graph_depth: *graph_depth,
377 graph_edge_label: graph_edge_label.as_deref(),
378 top_k: *top_k,
379 ef_search: *ef_search,
380 mode: *mode,
381 fuzzy: *fuzzy,
382 rrf_k: *rrf_k,
383 score_alias: score_alias.as_deref(),
384 }),
385 SqlPlan::SpatialScan {
386 collection,
387 field,
388 predicate,
389 query_geometry,
390 distance_meters,
391 attribute_filters,
392 limit,
393 projection,
394 } => visitor.spatial_scan(SpatialScanVisitArgs {
395 collection,
396 field,
397 predicate,
398 query_geometry,
399 distance_meters: *distance_meters,
400 attribute_filters,
401 limit: *limit,
402 projection,
403 }),
404 SqlPlan::RecursiveScan(RecursiveScanPlan {
405 collection,
406 base_filters,
407 recursive_filters,
408 join_link,
409 max_iterations,
410 distinct,
411 limit,
412 projection: _,
413 }) => visitor.recursive_scan(RecursiveScanVisitArgs {
414 collection,
415 base_filters,
416 recursive_filters,
417 join_link: join_link.as_ref(),
418 max_iterations: *max_iterations,
419 distinct: *distinct,
420 limit: *limit,
421 }),
422 SqlPlan::RecursiveValue(RecursiveValuePlan {
423 cte_name,
424 columns,
425 init_exprs,
426 step_exprs,
427 condition,
428 max_depth,
429 distinct,
430 }) => visitor.recursive_value(RecursiveValueVisitArgs {
431 cte_name,
432 columns,
433 init_exprs,
434 step_exprs,
435 condition: condition.as_deref(),
436 max_depth: *max_depth,
437 distinct: *distinct,
438 }),
439 other => dispatch_rest(visitor, other),
440 }
441}