Skip to main content

uqa_sql/schema/inheritance/
origins.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Track whether NOT NULL and CHECK declarations are local after a hierarchy edge changes.
8use crate::ast::{ColumnDef, TableCheck, TableHierarchy};
9use std::collections::BTreeSet;
10
11#[derive(Clone, Copy)]
12pub struct InheritanceOriginChange {
13    removed_parent: bool,
14    attached_partition: bool,
15}
16impl InheritanceOriginChange {
17    pub fn between(previous: &TableHierarchy, next: &TableHierarchy) -> Option<Self> {
18        let removed_parent = previous
19            .parents
20            .iter()
21            .any(|parent| !next.parents.contains(parent));
22        let attached_partition = !previous.is_partition() && next.is_partition();
23        (removed_parent || attached_partition).then_some(Self {
24            removed_parent,
25            attached_partition,
26        })
27    }
28    pub fn update_not_null(self, columns: &mut [ColumnDef], inherited: &BTreeSet<String>) {
29        for column in columns.iter_mut().filter(|column| column.not_null) {
30            if self.attached_partition && inherited.contains(&column.name) {
31                column.not_null_is_local = false;
32            } else if self.removed_parent && !inherited.contains(&column.name) {
33                column.not_null_is_local = true;
34            }
35        }
36    }
37    pub fn update_checks(
38        self,
39        columns: &mut [ColumnDef],
40        checks: &mut [TableCheck],
41        inherited: &BTreeSet<String>,
42    ) {
43        let update = |name: Option<&String>, local: &mut bool| {
44            let supplied = name.is_some_and(|name| inherited.contains(name));
45            if self.attached_partition && supplied {
46                *local = false;
47            } else if self.removed_parent && !supplied {
48                *local = true;
49            }
50        };
51        for column in columns.iter_mut().filter(|column| column.check.is_some()) {
52            update(column.check_name.as_ref(), &mut column.check_is_local);
53        }
54        for check in checks {
55            update(check.name.as_ref(), &mut check.is_local);
56        }
57    }
58}