sql_fun_sqlast/sem/
create_table_as.rs1use sql_fun_core::IVec;
2
3use crate::{
4 sem::{AstAndContextPair, alter_table::AlterObjSubCommand, create_table::ColumnDefinition},
5 syn::{ObjectType, Opt, ScanToken},
6};
7
8use super::{AlterView, AnalysisError, CreateTable, FullName, ParseContext, SemAst, TableName};
9
10#[derive(Debug, Clone)]
12pub struct CreateTableAs {
13 name: FullName,
14 #[expect(dead_code)]
15 query: Box<SemAst>,
16 obj_type: ObjectType,
17 owner: Option<String>,
18 alter_statements: Vec<AlterView>,
19}
20
21impl CreateTableAs {
22 #[must_use]
24 pub fn name(&self) -> &FullName {
25 &self.name
26 }
27
28 #[must_use]
30 pub fn obj_type(&self) -> ObjectType {
31 self.obj_type
32 }
33
34 pub(crate) fn apply_alter(&mut self, alter_view: &AlterView) -> Result<(), AnalysisError> {
35 self.alter_statements.push(alter_view.clone());
36
37 for cmd in alter_view.commands() {
38 match cmd {
39 AlterObjSubCommand::ChangeOwner(new_owner) => self.owner = Some(new_owner.clone()),
40 _ => todo!(),
41 }
42 }
43
44 Ok(())
45 }
46
47 pub(crate) fn get_column_def(
48 &self,
49 _column_name: &super::ColumnName,
50 ) -> Option<ColumnDefinition> {
51 todo!()
52 }
53
54 pub(crate) fn has_column(&self, _column_name: &super::ColumnName) -> bool {
55 todo!()
56 }
57}
58
59#[tracing::instrument(skip_all)]
61pub fn analyze_create_table_as<TParseContext>(
62 context: TParseContext,
63 parent_schema: &Option<String>,
64 syn: crate::syn::CreateTableAsStmt,
65 tokens: &IVec<ScanToken>,
66) -> Result<AstAndContextPair<TParseContext>, AnalysisError>
67where
68 TParseContext: ParseContext,
69{
70 let Some(obj_type) = syn.get_objtype().as_inner() else {
71 AnalysisError::raise_unexpected_none("create_table_as.obj_type")?
72 };
73
74 let Some(into) = syn.get_into().as_inner() else {
75 AnalysisError::raise_unexpected_none("create_table_as.into")?
76 };
77 let Some(into_rel) = into.get_rel().as_inner() else {
78 AnalysisError::raise_unexpected_none("into_clause.rel")?
79 };
80 let name = FullName::try_from(into_rel.clone())?;
81 let Some(q) = syn.get_query().as_inner() else {
82 AnalysisError::raise_unexpected_none("create_table_as.query")?
83 };
84 let AstAndContextPair(sem, context) = super::analyze_node(context, parent_schema, q, tokens)?;
85 let context = match &sem {
86 SemAst::SelectStatement(s) => {
87 let columns = s.result_columns().column_definitions()?;
88 let create_table = CreateTable::new(TableName::try_from(into_rel)?, columns);
89 context.apply_create_table(&create_table)?
90 }
91 _ => AnalysisError::raise_unexpected_none("SemAst As Select statement")?,
92 };
93 let create_table_as = CreateTableAs {
94 name,
95 query: Box::new(sem),
96 obj_type,
97 owner: None,
98 alter_statements: Vec::new(),
99 };
100 let result_context = context.apply_create_table_as(&create_table_as)?;
101 Ok(AstAndContextPair::new(
102 SemAst::CreateTableAs(create_table_as),
103 result_context,
104 ))
105}