sql_fun_sqlast/sem/
create_view.rs1use sql_fun_core::IVec;
2
3use crate::{
4 sem::{
5 AlterView, AstAndContextPair,
6 alter_table::AlterObjSubCommand,
7 create_table::{ColumnDefinition, ColumnName},
8 },
9 syn::{Opt, ScanToken},
10};
11
12use super::{AnalysisError, FullName, ParseContext, SelectStatement, SemAst, analyze_select};
13
14#[derive(Debug, Clone)]
16pub struct CreateView {
17 name: FullName,
18 query: SelectStatement,
19 alter_statements: Vec<AlterView>,
20 owner: Option<String>,
21 materialized: bool,
22}
23
24impl CreateView {
25 #[must_use]
27 pub fn new(
28 name: &FullName,
29 query: &SelectStatement,
30 alter_statements: &[AlterView],
31 owner: &Option<String>,
32 materialized: bool,
33 ) -> Self {
34 Self {
35 name: name.clone(),
36 query: query.clone(),
37 alter_statements: alter_statements.to_owned(),
38 owner: owner.clone(),
39 materialized,
40 }
41 }
42
43 #[must_use]
45 pub fn name(&self) -> &FullName {
46 &self.name
47 }
48
49 #[must_use]
51 pub fn get_column_def(&self, column_name: &ColumnName) -> Option<ColumnDefinition> {
52 self.query.get_result_column_def(column_name)
53 }
54
55 #[must_use]
57 pub fn has_column(&self, column: &ColumnName) -> bool {
58 self.query.has_column(column)
59 }
60
61 pub fn apply_alter(&mut self, alter_view: &AlterView) -> Result<(), AnalysisError> {
63 self.alter_statements.push(alter_view.clone());
64
65 for cmd in alter_view.commands() {
66 match cmd {
67 AlterObjSubCommand::ChangeOwner(new_owner) => self.owner = Some(new_owner.clone()),
68 _ => todo!(),
69 }
70 }
71
72 Ok(())
73 }
74
75 #[must_use]
77 pub fn is_materialized(&self) -> bool {
78 self.materialized
79 }
80}
81
82#[tracing::instrument(skip(context))]
84pub fn analyze_create_view<TParseContext>(
85 context: TParseContext,
86 parent_schema: &Option<String>,
87 syn: crate::syn::ViewStmt,
88 tokens: &IVec<ScanToken>,
89) -> Result<AstAndContextPair<TParseContext>, AnalysisError>
90where
91 TParseContext: ParseContext,
92{
93 let Some(view) = syn.get_view().as_inner() else {
94 AnalysisError::raise_unexpected_none("view_stmt.view")?
95 };
96 let _materialized = syn.get_options();
97
98 let Some(query) = syn.get_query().as_select_stmt().as_inner() else {
99 AnalysisError::raise_unexpected_none("view_stmt.query")?
100 };
101
102 let AstAndContextPair(select, context) = analyze_select(context, query, tokens)?;
103 let SemAst::SelectStatement(stmt) = select else {
104 AnalysisError::raise_unexpected_none("select_statement")?
105 };
106 let name = FullName::try_from(view)?;
107 let create_view = CreateView::new(&name, &stmt, &[], &Default::default(), false);
108 let context = context.apply_create_view(&create_view)?;
109 Ok(AstAndContextPair::new(
110 SemAst::CreateView(create_view),
111 context,
112 ))
113}