uqa_sql/binding/view_dependencies/
restoration.rs1use super::{bind_query_plan_relations, canonical_virtual_relation_reference};
9use crate::{ast::FunctionBinding, plan::QueryPlan};
10use uqa_core::RelationIdentity;
11
12pub fn upgrade_legacy_view_dispatches(plan: &mut QueryPlan) -> bool {
13 let mut changed = false;
14 plan.rewrite_scalar_expressions(&mut |expression| {
15 let crate::ScalarExpr::Func { name, binding, .. } = expression else {
16 return;
17 };
18 changed |= FunctionBinding::upgrade_legacy_serialized_dispatch(name, binding);
19 });
20 changed
21}
22
23pub fn bind_stored_view_relations(
24 plan: &mut QueryPlan,
25 relations: &std::collections::BTreeSet<RelationIdentity>,
26) -> Result<(), String> {
27 bind_query_plan_relations(plan, &std::collections::BTreeSet::new(), &mut |reference| {
28 if let Some(canonical) = canonical_virtual_relation_reference(reference) {
29 return Ok(canonical);
30 }
31 let (schema, local_name) = RelationIdentity::parse_reference(reference)
32 .map_err(|error| format!("invalid stored view source `{reference}`: {error}"))?;
33 if let Some(schema) = schema {
34 let candidate = RelationIdentity::new(schema, local_name);
35 if relations.contains(&candidate) {
36 return Ok(candidate.qualified_name());
37 }
38 } else {
39 let candidates = relations
40 .iter()
41 .filter(|candidate| candidate.name == local_name)
42 .map(RelationIdentity::qualified_name)
43 .collect::<Vec<_>>();
44 match candidates.as_slice() {
45 [candidate] => return Ok(candidate.clone()),
46 [] => {}
47 _ => {
48 return Err(format!(
49 "ambiguous stored view source `{reference}` matches {}",
50 candidates.join(", ")
51 ));
52 }
53 }
54 }
55 Err(format!(
56 "stored view source relation `{reference}` does not exist"
57 ))
58 })
59}
60
61#[cfg(test)]
62mod tests;