use super::args::{
AggregateVisitArgs, DocumentIndexLookupVisitArgs, HybridSearchTripleVisitArgs,
HybridSearchVisitArgs, InsertVisitArgs, JoinVisitArgs, RecursiveScanVisitArgs,
RecursiveValueVisitArgs, ScanVisitArgs, SpatialScanVisitArgs, TimeseriesScanVisitArgs,
UpdateFromVisitArgs, UpsertVisitArgs, VectorSearchVisitArgs,
};
use super::dispatch_rest::dispatch_rest;
use super::trait_def::PlanVisitor;
use crate::types::SqlPlan;
pub fn dispatch<V: PlanVisitor>(visitor: &mut V, plan: &SqlPlan) -> Result<V::Output, V::Error> {
match plan {
SqlPlan::ConstantResult { columns, values } => visitor.constant_result(columns, values),
SqlPlan::Scan {
collection,
alias,
engine,
filters,
projection,
sort_keys,
limit,
offset,
distinct,
window_functions,
temporal,
} => visitor.scan(ScanVisitArgs {
collection,
alias: alias.as_deref(),
engine: *engine,
filters,
projection,
sort_keys,
limit: *limit,
offset: *offset,
distinct: *distinct,
window_functions,
temporal,
}),
SqlPlan::PointGet {
collection,
alias,
engine,
key_column,
key_value,
projection: _,
} => visitor.point_get(collection, alias.as_deref(), *engine, key_column, key_value),
SqlPlan::DocumentIndexLookup {
collection,
alias,
engine,
field,
value,
filters,
projection,
sort_keys,
limit,
offset,
distinct,
window_functions,
case_insensitive,
temporal,
} => visitor.document_index_lookup(DocumentIndexLookupVisitArgs {
collection,
alias: alias.as_deref(),
engine: *engine,
field,
value,
filters,
projection,
sort_keys,
limit: *limit,
offset: *offset,
distinct: *distinct,
window_functions,
case_insensitive: *case_insensitive,
temporal,
}),
SqlPlan::RangeScan {
collection,
field,
lower,
upper,
limit,
projection: _,
} => visitor.range_scan(collection, field, lower.as_ref(), upper.as_ref(), *limit),
SqlPlan::Insert {
collection,
engine,
rows,
column_defaults,
if_absent,
column_schema,
primary_key,
} => visitor.insert(InsertVisitArgs {
collection,
engine: *engine,
rows,
column_defaults,
if_absent: *if_absent,
column_schema,
primary_key: primary_key.as_deref(),
}),
SqlPlan::KvInsert {
collection,
entries,
ttl_secs,
intent,
on_conflict_updates,
} => visitor.kv_insert(collection, entries, *ttl_secs, *intent, on_conflict_updates),
SqlPlan::Upsert {
collection,
engine,
rows,
column_defaults,
on_conflict_updates,
column_schema,
primary_key,
} => visitor.upsert(UpsertVisitArgs {
collection,
engine: *engine,
rows,
column_defaults,
on_conflict_updates,
column_schema,
primary_key: primary_key.as_deref(),
}),
SqlPlan::InsertSelect {
target,
source,
limit,
} => visitor.insert_select(target, source, *limit),
SqlPlan::Update {
collection,
engine,
assignments,
filters,
target_keys,
returning,
} => visitor.update(
collection,
*engine,
assignments,
filters,
target_keys,
*returning,
),
SqlPlan::UpdateFrom {
collection,
engine,
source,
target_join_col,
source_join_col,
assignments,
target_filters,
returning,
} => visitor.update_from(UpdateFromVisitArgs {
collection,
engine: *engine,
source,
target_join_col,
source_join_col,
assignments,
target_filters,
returning: *returning,
}),
SqlPlan::Delete {
collection,
engine,
filters,
target_keys,
} => visitor.delete(collection, *engine, filters, target_keys),
SqlPlan::Truncate {
collection,
restart_identity,
} => visitor.truncate(collection, *restart_identity),
SqlPlan::Join {
left,
right,
on,
join_type,
condition,
limit,
projection,
filters,
} => visitor.join(JoinVisitArgs {
left,
right,
on,
join_type: *join_type,
condition: condition.as_ref(),
limit: *limit,
projection,
filters,
}),
SqlPlan::Aggregate {
input,
group_by,
group_by_aliases: _,
output_order: _,
aggregates,
having,
limit,
grouping_sets,
sort_keys,
} => visitor.aggregate(AggregateVisitArgs {
input,
group_by,
aggregates,
having,
limit: *limit,
grouping_sets: grouping_sets.as_deref(),
sort_keys,
}),
SqlPlan::TimeseriesScan {
collection,
time_range,
bucket_interval_ms,
group_by,
aggregates,
filters,
projection,
gap_fill,
limit,
tiered,
temporal,
} => visitor.timeseries_scan(TimeseriesScanVisitArgs {
collection,
time_range: *time_range,
bucket_interval_ms: *bucket_interval_ms,
group_by,
aggregates,
filters,
projection,
gap_fill,
limit: *limit,
tiered: *tiered,
temporal,
}),
SqlPlan::TimeseriesIngest { collection, rows } => {
visitor.timeseries_ingest(collection, rows)
}
SqlPlan::VectorSearch {
collection,
field,
query_vector,
top_k,
ef_search,
metric,
filters,
array_prefilter,
ann_options,
skip_payload_fetch,
payload_filters,
projection: _,
} => visitor.vector_search(VectorSearchVisitArgs {
collection,
field,
query_vector,
top_k: *top_k,
ef_search: *ef_search,
metric: *metric,
filters,
array_prefilter: array_prefilter.as_ref(),
ann_options,
skip_payload_fetch: *skip_payload_fetch,
payload_filters,
}),
SqlPlan::MultiVectorSearch {
collection,
query_vector,
top_k,
ef_search,
projection: _,
} => visitor.multi_vector_search(collection, query_vector, *top_k, *ef_search),
SqlPlan::SparseSearch {
collection,
field,
query_entries,
top_k,
projection: _,
} => visitor.sparse_search(collection, field, query_entries, *top_k),
SqlPlan::TextSearch {
collection,
query,
top_k,
filters,
score_alias,
projection: _,
} => visitor.text_search(collection, query, *top_k, filters, score_alias.as_deref()),
SqlPlan::HybridSearch {
collection,
query_vector,
query_text,
top_k,
ef_search,
vector_weight,
fuzzy,
score_alias,
projection: _,
} => visitor.hybrid_search(HybridSearchVisitArgs {
collection,
query_vector,
query_text,
top_k: *top_k,
ef_search: *ef_search,
vector_weight: *vector_weight,
fuzzy: *fuzzy,
score_alias: score_alias.as_deref(),
}),
SqlPlan::HybridSearchTriple {
collection,
query_vector,
query_text,
graph_seed_id,
graph_depth,
graph_edge_label,
top_k,
ef_search,
fuzzy,
rrf_k,
score_alias,
projection: _,
} => visitor.hybrid_search_triple(HybridSearchTripleVisitArgs {
collection,
query_vector,
query_text,
graph_seed_id,
graph_depth: *graph_depth,
graph_edge_label: graph_edge_label.as_deref(),
top_k: *top_k,
ef_search: *ef_search,
fuzzy: *fuzzy,
rrf_k: *rrf_k,
score_alias: score_alias.as_deref(),
}),
SqlPlan::SpatialScan {
collection,
field,
predicate,
query_geometry,
distance_meters,
attribute_filters,
limit,
projection,
} => visitor.spatial_scan(SpatialScanVisitArgs {
collection,
field,
predicate,
query_geometry,
distance_meters: *distance_meters,
attribute_filters,
limit: *limit,
projection,
}),
SqlPlan::RecursiveScan {
collection,
base_filters,
recursive_filters,
join_link,
max_iterations,
distinct,
limit,
projection: _,
} => visitor.recursive_scan(RecursiveScanVisitArgs {
collection,
base_filters,
recursive_filters,
join_link: join_link.as_ref(),
max_iterations: *max_iterations,
distinct: *distinct,
limit: *limit,
}),
SqlPlan::RecursiveValue {
cte_name,
columns,
init_exprs,
step_exprs,
condition,
max_depth,
distinct,
} => visitor.recursive_value(RecursiveValueVisitArgs {
cte_name,
columns,
init_exprs,
step_exprs,
condition: condition.as_deref(),
max_depth: *max_depth,
distinct: *distinct,
}),
other => dispatch_rest(visitor, other),
}
}