Skip to main content

uqa_sql/binding/view_dependencies/
restoration.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Restore legacy view source names and scalar dispatches from explicit catalog identities.
8use 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;