Skip to main content

uqa_sql/schema/
table_creation.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! CREATE TABLE column validation and CREATE TABLE AS result declarations.
8use crate::{ast::CreateTable, ColumnType, SQLError};
9use std::collections::BTreeSet;
10
11pub fn validate_create_table_columns(table: &CreateTable) -> Result<(), SQLError> {
12    for column in &table.columns {
13        super::columns::validate_postgres_column_name(&column.name)?;
14        super::columns::validate_postgres_relation_column_type(&column.name, &column.ty)?;
15    }
16    Ok(())
17}
18
19pub fn create_table_as_columns(
20    query_schema: &crate::RowSchema,
21    column_names: &[String],
22) -> Result<Vec<crate::ast::ColumnDef>, SQLError> {
23    if column_names.len() > query_schema.len() {
24        return Err(SQLError::Routine {
25            sqlstate: "42601".into(),
26            message: "too many column names were specified".into(),
27        });
28    }
29    let names = query_schema
30        .columns()
31        .iter()
32        .enumerate()
33        .map(|(position, name)| {
34            column_names
35                .get(position)
36                .cloned()
37                .unwrap_or_else(|| name.clone())
38        })
39        .collect::<Vec<_>>();
40    let mut seen = BTreeSet::new();
41    for name in &names {
42        super::columns::validate_postgres_column_name(name)?;
43        if !seen.insert(name) {
44            return Err(SQLError::Routine {
45                sqlstate: "42701".into(),
46                message: format!("column \"{name}\" specified more than once"),
47            });
48        }
49    }
50    let columns = names
51        .into_iter()
52        .enumerate()
53        .map(|(position, name)| crate::ast::ColumnDef {
54            name,
55            ty: query_schema
56                .column_type(position)
57                .cloned()
58                .unwrap_or(ColumnType::Text),
59            object_id: None,
60            missing_value: None,
61            primary_key: false,
62            not_null: false,
63            not_null_explicit: false,
64            not_null_name: None,
65            not_null_validated: true,
66            not_null_no_inherit: false,
67            not_null_is_local: true,
68            auto_increment: None,
69            unique: false,
70            default: None,
71            generated: None,
72            check: None,
73            check_name: None,
74            check_enforced: true,
75            check_validated: true,
76            check_no_inherit: false,
77            check_is_local: true,
78            check_object_id: None,
79            references: None,
80        })
81        .collect::<Vec<_>>();
82    for column in &columns {
83        super::columns::validate_postgres_relation_column_type(&column.name, &column.ty)?;
84    }
85    Ok(columns)
86}
87
88pub mod declaration;