Skip to main content

uqa_sql/schema/sequences/
dependencies.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Rewrite literal sequence references in stored table and view declarations.
8use crate::schema::dependencies::rewrites::{
9    rewrite_sequence_function_references, stored_relation_reference_matches,
10};
11use uqa_core::RelationIdentity;
12pub fn rewrite_sequence_schema_references(
13    columns: &mut [crate::ast::ColumnDef],
14    checks: &mut [crate::ast::TableCheck],
15    from: &RelationIdentity,
16    to: &str,
17) -> Result<bool, String> {
18    let mut changed = false;
19    for column in columns {
20        if let Some(sequence) = column
21            .auto_increment
22            .as_mut()
23            .and_then(|provenance| provenance.sequence.as_mut())
24        {
25            if stored_relation_reference_matches(sequence, from) {
26                *sequence = to.to_string();
27                changed = true;
28            }
29        }
30        for expression in [&mut column.default, &mut column.check]
31            .into_iter()
32            .flatten()
33        {
34            rewrite_sequence_function_references(expression, &mut |reference| {
35                if stored_relation_reference_matches(reference, from) {
36                    *reference = to.to_string();
37                    changed = true;
38                }
39                Ok(())
40            })?;
41        }
42        if let Some(generated) = &mut column.generated {
43            rewrite_sequence_function_references(&mut generated.expression, &mut |reference| {
44                if stored_relation_reference_matches(reference, from) {
45                    *reference = to.to_string();
46                    changed = true;
47                }
48                Ok(())
49            })?;
50        }
51    }
52    for check in checks {
53        rewrite_sequence_function_references(&mut check.expr, &mut |reference| {
54            if stored_relation_reference_matches(reference, from) {
55                *reference = to.to_string();
56                changed = true;
57            }
58            Ok(())
59        })?;
60    }
61    Ok(changed)
62}
63
64pub fn rewritten_view_sequence_references(
65    stored: &crate::catalog::stored_view::StoredView,
66    from: &RelationIdentity,
67    to: &str,
68) -> Result<Option<crate::catalog::stored_view::StoredView>, String> {
69    let mut rewritten = stored.clone();
70    let mut changed = false;
71    crate::binding::view_dependencies::bind_query_plan_sequence_references(
72        &mut rewritten.query,
73        &mut |reference| -> Result<String, String> {
74            let (schema, name) = RelationIdentity::parse_reference(reference).map_err(|error| {
75                format!("invalid stored view sequence reference `{reference}`: {error}")
76            })?;
77            let matches = schema.as_deref().map_or(name == from.name, |schema| {
78                schema == from.schema && name == from.name
79            });
80            if matches {
81                changed = true;
82                Ok(to.to_string())
83            } else {
84                Ok(reference.to_string())
85            }
86        },
87    )?;
88    Ok(changed.then_some(rewritten))
89}
90
91pub mod analysis;
92
93pub fn detach_sequence_provenance(columns: &mut [crate::ast::ColumnDef], sequence: &str) -> bool {
94    let mut changed = false;
95    for column in columns {
96        if column
97            .auto_increment
98            .as_ref()
99            .is_some_and(|provenance| provenance.sequence.as_deref() == Some(sequence))
100        {
101            column.auto_increment = None;
102            changed = true;
103        }
104    }
105    changed
106}