Skip to main content

nodedb_sql/visitor/plan_visitor/
dispatch_rest.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Second half of the exhaustive [`SqlPlan`] → [`PlanVisitor`] dispatcher.
3//!
4//! Handles set-ops, array DDL/DML/TVF, merge, lateral, and index-DDL
5//! variants. Called only from [`super::dispatch::dispatch`]'s trailing
6//! `other => dispatch_rest(visitor, other)` arm; the variants handled there
7//! reach the trailing `unreachable!()` arm here, which exists solely to
8//! satisfy the compiler that this match is exhaustive over the full
9//! `SqlPlan` enum without repeating their field lists.
10use super::args::{
11    CreateArrayVisitArgs, LateralLoopVisitArgs, LateralTopKVisitArgs, MergeVisitArgs,
12    VectorPrimaryDeleteVisitArgs, VectorPrimaryInsertVisitArgs, VectorPrimaryUpdateVisitArgs,
13};
14use super::trait_def::PlanVisitor;
15use crate::types::SqlPlan;
16use crate::types::{
17    AlterArrayPlan, ArrayAggPlan, ArrayElementwisePlan, ArrayProjectPlan, ArraySlicePlan,
18    CreateArrayPlan, CreateIndexPlan, CtePlan, DeleteArrayPlan, DropIndexPlan, InsertArrayPlan,
19    LateralLoopPlan, LateralTopKPlan, MergePlan, VectorPrimaryDeletePlan, VectorPrimaryInsertPlan,
20    VectorPrimaryTruncatePlan, VectorPrimaryUpdatePlan,
21};
22
23pub(super) fn dispatch_rest<V: PlanVisitor>(
24    visitor: &mut V,
25    plan: &SqlPlan,
26) -> Result<V::Output, V::Error> {
27    match plan {
28        SqlPlan::Union { inputs, distinct } => visitor.union(inputs, *distinct),
29        SqlPlan::Intersect { left, right, all } => visitor.intersect(left, right, *all),
30        SqlPlan::Except { left, right, all } => visitor.except(left, right, *all),
31        SqlPlan::Cte(CtePlan { definitions, outer }) => visitor.cte(definitions, outer),
32        SqlPlan::Subquery {
33            input,
34            filters,
35            projection,
36            window_functions,
37            sort_keys,
38            offset,
39            distinct,
40            limit,
41        } => visitor.subquery(super::args::SubqueryVisitArgs {
42            input,
43            filters,
44            projection,
45            window_functions,
46            sort_keys,
47            offset: *offset,
48            distinct: *distinct,
49            limit: *limit,
50        }),
51        SqlPlan::CreateArray(CreateArrayPlan {
52            name,
53            dims,
54            attrs,
55            tile_extents,
56            cell_order,
57            tile_order,
58            prefix_bits,
59            audit_retain_ms,
60            minimum_audit_retain_ms,
61        }) => visitor.create_array(CreateArrayVisitArgs {
62            name,
63            dims,
64            attrs,
65            tile_extents,
66            cell_order: *cell_order,
67            tile_order: *tile_order,
68            prefix_bits: *prefix_bits,
69            audit_retain_ms: *audit_retain_ms,
70            minimum_audit_retain_ms: *minimum_audit_retain_ms,
71        }),
72        SqlPlan::DropArray { name, if_exists } => visitor.drop_array(name, *if_exists),
73        SqlPlan::AlterArray(AlterArrayPlan {
74            name,
75            audit_retain_ms,
76            minimum_audit_retain_ms,
77        }) => visitor.alter_array(name, *audit_retain_ms, *minimum_audit_retain_ms),
78        SqlPlan::InsertArray(InsertArrayPlan { name, rows }) => visitor.insert_array(name, rows),
79        SqlPlan::DeleteArray(DeleteArrayPlan { name, coords }) => {
80            visitor.delete_array(name, coords)
81        }
82        SqlPlan::ArraySlice(ArraySlicePlan {
83            name,
84            slice,
85            attr_projection,
86            limit,
87            temporal,
88        }) => visitor.array_slice(name, slice, attr_projection, *limit, temporal),
89        SqlPlan::ArrayProject(ArrayProjectPlan {
90            name,
91            attr_projection,
92        }) => visitor.array_project(name, attr_projection),
93        SqlPlan::ArrayAgg(ArrayAggPlan {
94            name,
95            attr,
96            reducer,
97            group_by_dim,
98            temporal,
99        }) => visitor.array_agg(name, attr, reducer, group_by_dim.as_deref(), temporal),
100        SqlPlan::ArrayElementwise(ArrayElementwisePlan {
101            left,
102            right,
103            op,
104            attr,
105        }) => visitor.array_elementwise(left, right, *op, attr),
106        SqlPlan::ArrayFlush { name } => visitor.array_flush(name),
107        SqlPlan::ArrayCompact { name } => visitor.array_compact(name),
108        SqlPlan::Merge(MergePlan {
109            target,
110            engine,
111            source,
112            target_join_col,
113            source_join_col,
114            source_alias,
115            clauses,
116            returning,
117        }) => visitor.merge(MergeVisitArgs {
118            target,
119            engine: *engine,
120            source,
121            target_join_col,
122            source_join_col,
123            source_alias,
124            clauses,
125            returning: *returning,
126        }),
127        SqlPlan::LateralTopK(LateralTopKPlan {
128            outer,
129            outer_alias,
130            inner_collection,
131            inner_filters,
132            inner_order_by,
133            inner_limit,
134            correlation_keys,
135            lateral_alias,
136            projection,
137            left_join,
138        }) => visitor.lateral_top_k(LateralTopKVisitArgs {
139            outer,
140            outer_alias: outer_alias.as_deref(),
141            inner_collection,
142            inner_filters,
143            inner_order_by,
144            inner_limit: *inner_limit,
145            correlation_keys,
146            lateral_alias,
147            projection,
148            left_join: *left_join,
149        }),
150        SqlPlan::LateralLoop(LateralLoopPlan {
151            outer,
152            outer_alias,
153            inner,
154            correlation_predicates,
155            lateral_alias,
156            projection,
157            outer_row_cap,
158            left_join,
159        }) => visitor.lateral_loop(LateralLoopVisitArgs {
160            outer,
161            outer_alias: outer_alias.as_deref(),
162            inner,
163            correlation_predicates,
164            lateral_alias,
165            projection,
166            outer_row_cap: *outer_row_cap,
167            left_join: *left_join,
168        }),
169        SqlPlan::VectorPrimaryInsert(VectorPrimaryInsertPlan {
170            collection,
171            field,
172            quantization,
173            storage_dtype,
174            payload_indexes,
175            rows,
176            // Cache eligibility only; lowering does not read it.
177            volatile_defaults: _,
178            intent,
179            on_conflict_updates,
180            primary_key,
181        }) => visitor.vector_primary_insert(VectorPrimaryInsertVisitArgs {
182            collection,
183            field,
184            quantization: *quantization,
185            storage_dtype: *storage_dtype,
186            payload_indexes,
187            rows,
188            intent: *intent,
189            on_conflict_updates,
190            primary_key: primary_key.as_deref(),
191        }),
192        SqlPlan::VectorPrimaryDelete(VectorPrimaryDeletePlan {
193            collection,
194            field,
195            filters,
196            target_keys,
197            primary_key,
198        }) => visitor.vector_primary_delete(VectorPrimaryDeleteVisitArgs {
199            collection,
200            field,
201            filters,
202            target_keys,
203            primary_key: primary_key.as_deref(),
204        }),
205        SqlPlan::VectorPrimaryTruncate(VectorPrimaryTruncatePlan {
206            collection,
207            field,
208            restart_identity,
209        }) => visitor.vector_primary_truncate(collection, field, *restart_identity),
210        SqlPlan::VectorPrimaryUpdate(VectorPrimaryUpdatePlan {
211            collection,
212            field,
213            quantization,
214            storage_dtype,
215            payload_indexes,
216            new_vector,
217            assignments,
218            filters,
219            target_keys,
220            returning,
221            primary_key,
222        }) => visitor.vector_primary_update(VectorPrimaryUpdateVisitArgs {
223            collection,
224            field,
225            quantization: *quantization,
226            storage_dtype: *storage_dtype,
227            payload_indexes,
228            new_vector: new_vector.as_deref(),
229            assignments,
230            filters,
231            target_keys,
232            returning: *returning,
233            primary_key: primary_key.as_deref(),
234        }),
235        SqlPlan::CreateIndex(CreateIndexPlan {
236            index_name,
237            collection,
238            field,
239            unique,
240            if_not_exists,
241            case_insensitive,
242        }) => visitor.create_index(
243            index_name.as_deref(),
244            collection,
245            field,
246            *unique,
247            *if_not_exists,
248            *case_insensitive,
249        ),
250        SqlPlan::DropIndex(DropIndexPlan {
251            index_name,
252            collection,
253            if_exists,
254        }) => visitor.drop_index(index_name, collection.as_deref(), *if_exists),
255        _ => unreachable!(
256            "dispatch() already handles every remaining SqlPlan variant before forwarding here"
257        ),
258    }
259}