Skip to main content

sql_fun_sqlast/sem/
constraint.rs

1mod foreign;
2mod primary;
3mod unique;
4
5use crate::{
6    sem::{AnalysisError, ParseContext, TableName},
7    syn::{ConstrType, Opt},
8};
9
10use super::ImplicitChange;
11
12pub use self::{
13    foreign::ForeignKeyConstraint, primary::PrimaryKeyConstraint, unique::UniqueConstraint,
14};
15
16/// analyze [`crate::syn::Constraint`] variants
17pub trait AnalizeConstraint<TParseContext>
18where
19    TParseContext: ParseContext,
20{
21    /// analyze [`crate::syn::Constraint`] variants
22    fn analyze(
23        context: &mut TParseContext,
24        target_table: Option<&TableName>,
25        constraint: crate::syn::Constraint,
26    ) -> Result<Constraint, AnalysisError>;
27}
28
29/// analyzed [`crate::syn::Constraint`]
30#[derive(Debug, Clone)]
31pub enum Constraint {
32    /// primary key constraint
33    PrimaryKey(PrimaryKeyConstraint),
34    /// unique constraint
35    Unique(UniqueConstraint),
36    /// foreign key constraint
37    Foreign(ForeignKeyConstraint),
38}
39
40impl Constraint {
41    /// get constraint name
42    #[must_use]
43    pub fn name(&self) -> &str {
44        match self {
45            Self::PrimaryKey(pk) => pk.name(),
46            Self::Unique(u) => u.name(),
47            Self::Foreign(f) => f.name(),
48        }
49    }
50
51    /// get constraint derive index definition
52    pub fn implicit_changes(&self) -> Result<Vec<ImplicitChange>, AnalysisError> {
53        match self {
54            Self::PrimaryKey(pk) => pk.implicit_changes(),
55            Self::Unique(u) => u.implicit_changes(),
56            Self::Foreign(f) => f.implicit_changes(),
57        }
58    }
59
60    /// return true if constraint is primary key
61    #[must_use]
62    pub fn is_primary_key_constraint(&self) -> bool {
63        matches!(self, Self::PrimaryKey(_))
64    }
65
66    /// get primary key reference
67    #[must_use]
68    pub fn as_primary_key_constraint(&self) -> Option<&PrimaryKeyConstraint> {
69        match self {
70            Self::PrimaryKey(p) => Some(p),
71            _ => None,
72        }
73    }
74}
75
76impl<TParseContext> AnalizeConstraint<TParseContext> for Constraint
77where
78    TParseContext: ParseContext,
79{
80    fn analyze(
81        context: &mut TParseContext,
82        target_table: Option<&TableName>,
83        constraint: crate::syn::Constraint,
84    ) -> Result<Constraint, AnalysisError> {
85        let Some(constraint_type) = constraint.get_contype().as_inner() else {
86            AnalysisError::raise_unexpected_none("constraint.contype")?
87        };
88
89        match constraint_type {
90            ConstrType::ConstrNull => todo!(),
91            ConstrType::ConstrNotnull => todo!(),
92            ConstrType::ConstrDefault => todo!(),
93            ConstrType::ConstrIdentity => todo!(),
94            ConstrType::ConstrGenerated => todo!(),
95            ConstrType::ConstrCheck => todo!(),
96            ConstrType::ConstrPrimary => {
97                PrimaryKeyConstraint::analyze(context, target_table, constraint)
98            }
99            ConstrType::ConstrUnique => {
100                UniqueConstraint::analyze(context, target_table, constraint)
101            }
102            ConstrType::ConstrExclusion => todo!(),
103            ConstrType::ConstrForeign => {
104                ForeignKeyConstraint::analyze(context, target_table, constraint)
105            }
106            ConstrType::ConstrAttrDeferrable => todo!(),
107            ConstrType::ConstrAttrNotDeferrable => todo!(),
108            ConstrType::ConstrAttrDeferred => todo!(),
109            ConstrType::ConstrAttrImmediate => todo!(),
110            ConstrType::OptionNone => todo!(),
111            ConstrType::Undefined => todo!(),
112        }
113    }
114}