Skip to main content

databend_common_ast/ast/statements/
dynamic_table.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::BTreeMap;
16use std::fmt::Display;
17use std::fmt::Formatter;
18
19use derive_visitor::Drive;
20use derive_visitor::DriveMut;
21
22use crate::ast::ClusterOption;
23use crate::ast::CreateOption;
24use crate::ast::CreateTableSource;
25use crate::ast::Identifier;
26use crate::ast::Query;
27use crate::ast::WarehouseOptions;
28use crate::ast::write_dot_separated_list;
29use crate::ast::write_space_separated_string_map;
30
31#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
32pub enum TargetLag {
33    IntervalSecs(u64),
34    Downstream,
35}
36
37impl Display for TargetLag {
38    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
39        match self {
40            TargetLag::IntervalSecs(secs) => {
41                write!(f, "{} SECOND", secs)
42            }
43            TargetLag::Downstream => {
44                write!(f, "DOWNSTREAM")
45            }
46        }
47    }
48}
49
50#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
51pub enum RefreshMode {
52    Auto,
53    Full,
54    Incremental,
55}
56
57impl Display for RefreshMode {
58    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
59        match self {
60            RefreshMode::Auto => {
61                write!(f, "AUTO")
62            }
63            RefreshMode::Full => {
64                write!(f, "FULL")
65            }
66            RefreshMode::Incremental => {
67                write!(f, "INCREMENTAL")
68            }
69        }
70    }
71}
72
73#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
74pub enum InitializeMode {
75    OnCreate,
76    OnSchedule,
77}
78
79impl Display for InitializeMode {
80    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
81        match self {
82            InitializeMode::OnCreate => {
83                write!(f, "ON_CREATE")
84            }
85            InitializeMode::OnSchedule => {
86                write!(f, "ON_SCHEDULE")
87            }
88        }
89    }
90}
91
92#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
93pub struct CreateDynamicTableStmt {
94    pub create_option: CreateOption,
95    pub transient: bool,
96    pub catalog: Option<Identifier>,
97    pub database: Option<Identifier>,
98    pub table: Identifier,
99    pub source: Option<CreateTableSource>,
100    pub cluster_by: Option<ClusterOption>,
101
102    pub target_lag: TargetLag,
103    pub warehouse_opts: WarehouseOptions,
104    pub refresh_mode: RefreshMode,
105    pub initialize: InitializeMode,
106
107    pub table_options: BTreeMap<String, String>,
108    pub as_query: Box<Query>,
109}
110
111impl Display for CreateDynamicTableStmt {
112    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
113        write!(f, "CREATE ")?;
114        if let CreateOption::CreateOrReplace = self.create_option {
115            write!(f, "OR REPLACE ")?;
116        }
117        if self.transient {
118            write!(f, "TRANSIENT ")?;
119        }
120        write!(f, "DYNAMIC TABLE ")?;
121        if let CreateOption::CreateIfNotExists = self.create_option {
122            write!(f, "IF NOT EXISTS ")?;
123        }
124        write_dot_separated_list(
125            f,
126            self.catalog
127                .iter()
128                .chain(&self.database)
129                .chain(Some(&self.table)),
130        )?;
131
132        if let Some(source) = &self.source {
133            write!(f, " {source}")?;
134        }
135
136        if let Some(cluster_by) = &self.cluster_by {
137            write!(f, " {cluster_by}")?;
138        }
139
140        write!(f, " TARGET_LAG = {}", self.target_lag)?;
141        if self.warehouse_opts.warehouse.is_some() {
142            write!(f, " {}", self.warehouse_opts)?;
143        }
144        write!(f, " REFRESH_MODE = {}", self.refresh_mode)?;
145        write!(f, " INITIALIZE = {}", self.initialize)?;
146
147        // Format table options
148        if !self.table_options.is_empty() {
149            write!(f, " ")?;
150            write_space_separated_string_map(f, &self.table_options)?;
151        }
152
153        write!(f, " AS {}", self.as_query)?;
154        Ok(())
155    }
156}