uqa_sql/schema/
table_creation.rs1use 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;