uqa_sql/schema/
columns.rs1use crate::{ColumnType, SQLError};
10
11pub const POSTGRES_SYSTEM_COLUMNS: [&str; 6] = ["tableoid", "xmin", "cmin", "xmax", "cmax", "ctid"];
12
13pub fn validate_postgres_column_name(name: &str) -> Result<(), SQLError> {
14 if POSTGRES_SYSTEM_COLUMNS.contains(&name) {
15 return Err(SQLError::Routine {
16 sqlstate: "42701".into(),
17 message: format!("column name \"{name}\" conflicts with a system column name"),
18 });
19 }
20 Ok(())
21}
22
23pub fn validate_postgres_relation_column_type(name: &str, ty: &ColumnType) -> Result<(), SQLError> {
24 let pseudo_type = match ty {
25 ColumnType::Void | ColumnType::AnyArray | ColumnType::Record => Some(ty.sql_name()),
26 ColumnType::Array(element)
27 if matches!(
28 element.as_ref(),
29 ColumnType::Void | ColumnType::AnyArray | ColumnType::Record
30 ) =>
31 {
32 Some(ty.sql_name())
33 }
34 _ => None,
35 };
36 if let Some(pseudo_type) = pseudo_type {
37 return Err(SQLError::Routine {
38 sqlstate: "42P16".into(),
39 message: format!("column \"{name}\" has pseudo-type {pseudo_type}"),
40 });
41 }
42 Ok(())
43}
44
45pub fn append_registered_column(
47 table: &str,
48 columns: &mut Vec<crate::ast::ColumnDef>,
49 column: crate::ast::ColumnDef,
50) -> Result<(), String> {
51 if columns.iter().any(|existing| existing.name == column.name) {
52 return Err(format!(
53 "column `{}` already exists on table `{table}`",
54 column.name
55 ));
56 }
57 columns.push(column);
58 Ok(())
59}
60
61pub fn reject_default_change_on_generated_column(
62 catalog: &dyn crate::assignment::columns::AssignmentColumnCatalog,
63 table: &str,
64 column: &str,
65) -> Result<(), SQLError> {
66 if crate::assignment::columns::generated_column_kind(catalog, table, column)?.is_some() {
67 return Err(SQLError::TypeMismatch(format!(
68 "column `{column}` of relation `{table}` is a generated column; use SET EXPRESSION or DROP EXPRESSION"
69 )));
70 }
71 Ok(())
72}
73
74pub mod addition;
75
76pub mod publication;
77
78pub mod alteration;
79
80pub mod removal;
81
82pub mod removal_metadata;