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