Skip to main content

uqa_sql/schema/
table_alteration.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Bind inherited ALTER declarations and their durable constraint identities.
8use super::constraint_metadata::CatalogIdentityAllocator;
9use crate::{
10    ast::{AlterTableAction, ColumnDef, TableConstraintSet},
11    SQLError,
12};
13use uqa_core::RelationIdentity;
14
15pub fn normalize_inherited_action(action: &mut AlterTableAction) {
16    if let AlterTableAction::AddColumn { column, .. } = action {
17        column.not_null_is_local = !column.not_null;
18        column.check_is_local = column.check.is_none();
19        column.check_object_id = None;
20        if column.check_no_inherit {
21            column.check = None;
22            column.check_name = None;
23            column.check_is_local = true;
24            column.check_no_inherit = false;
25        }
26    }
27    if let AlterTableAction::AddCheckConstraint { constraint } = action {
28        constraint.is_local = false;
29        constraint.object_id = None;
30    }
31}
32
33pub fn materialize_recursive_action_names(
34    relation: &RelationIdentity,
35    columns: &mut Vec<ColumnDef>,
36    constraints: &mut TableConstraintSet,
37    action: &mut AlterTableAction,
38    allocate: &mut CatalogIdentityAllocator<'_>,
39) -> Result<(), SQLError> {
40    match action {
41        AlterTableAction::AddColumn { column, .. } => {
42            columns.push(column.clone());
43            super::constraint_metadata::materialize_constraint_metadata(
44                relation,
45                columns,
46                constraints,
47                allocate,
48            )
49            .map_err(|error| {
50                crate::catalog::errors::storage_error("ALTER TABLE ADD COLUMN", &error)
51            })?;
52            *column = columns
53                .pop()
54                .ok_or_else(|| SQLError::Internal("new column disappeared".into()))?;
55        }
56        AlterTableAction::AddCheckConstraint { constraint }
57            if !constraint.no_inherit && constraint.name.is_none() =>
58        {
59            constraints.checks.push(constraint.clone());
60            super::constraint_metadata::materialize_constraint_metadata(
61                relation,
62                columns,
63                constraints,
64                allocate,
65            )
66            .map_err(|error| {
67                crate::catalog::errors::storage_error("ALTER TABLE ADD CONSTRAINT", &error)
68            })?;
69            *constraint = constraints
70                .checks
71                .pop()
72                .ok_or_else(|| SQLError::Internal("new CHECK constraint disappeared".into()))?;
73        }
74        AlterTableAction::AddNotNullConstraint {
75            name,
76            column,
77            validated,
78            no_inherit: false,
79        } if name.is_none() => {
80            if let Some(definition) = columns
81                .iter_mut()
82                .find(|definition| definition.name == *column && !definition.not_null)
83            {
84                definition.not_null = true;
85                definition.not_null_explicit = true;
86                definition.not_null_validated = *validated;
87                super::constraint_metadata::materialize_constraint_metadata(
88                    relation,
89                    columns,
90                    constraints,
91                    allocate,
92                )
93                .map_err(|error| {
94                    crate::catalog::errors::storage_error("ALTER TABLE ADD CONSTRAINT", &error)
95                })?;
96                *name = columns
97                    .iter()
98                    .find(|definition| definition.name == *column)
99                    .and_then(|definition| definition.not_null_name.clone());
100            }
101        }
102        _ => {}
103    }
104    Ok(())
105}
106
107pub mod syntax;
108pub mod targets;