databend_common_ast/ast/statements/
index.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::write_comma_separated_list;
23use crate::ast::write_dot_separated_list;
24use crate::ast::write_space_separated_string_map;
25use crate::ast::CreateOption;
26use crate::ast::Identifier;
27use crate::ast::Query;
28
29#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
30pub struct CreateIndexStmt {
31    pub index_type: TableIndexType,
32    pub create_option: CreateOption,
33
34    pub index_name: Identifier,
35
36    pub query: Box<Query>,
37    pub sync_creation: bool,
38}
39
40#[derive(Debug, Copy, Clone, PartialEq, Eq, Drive, DriveMut)]
41pub enum TableIndexType {
42    Aggregating,
43    // Join
44    Inverted,
45    Ngram,
46    Vector,
47}
48
49impl Display for TableIndexType {
50    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
51        match self {
52            TableIndexType::Aggregating => {
53                write!(f, "AGGREGATING")
54            }
55            TableIndexType::Inverted => {
56                write!(f, "INVERTED")
57            }
58            TableIndexType::Ngram => {
59                write!(f, "NGRAM")
60            }
61            TableIndexType::Vector => {
62                write!(f, "VECTOR")
63            }
64        }
65    }
66}
67
68impl Display for CreateIndexStmt {
69    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
70        write!(f, "CREATE ")?;
71        if let CreateOption::CreateOrReplace = self.create_option {
72            write!(f, "OR REPLACE ")?;
73        }
74        if !self.sync_creation {
75            write!(f, "ASYNC ")?;
76        }
77        write!(f, "{} INDEX", self.index_type)?;
78        if let CreateOption::CreateIfNotExists = self.create_option {
79            write!(f, " IF NOT EXISTS")?;
80        }
81
82        write!(f, " {}", self.index_name)?;
83        write!(f, " AS {}", self.query)
84    }
85}
86
87#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
88pub struct DropIndexStmt {
89    pub if_exists: bool,
90    pub index: Identifier,
91}
92
93impl Display for DropIndexStmt {
94    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
95        write!(f, "DROP AGGREGATING INDEX")?;
96        if self.if_exists {
97            write!(f, " IF EXISTS")?;
98        }
99
100        write!(f, " {index}", index = self.index)?;
101        Ok(())
102    }
103}
104
105#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
106pub struct RefreshIndexStmt {
107    pub index: Identifier,
108    pub limit: Option<u64>,
109}
110
111impl Display for RefreshIndexStmt {
112    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
113        write!(f, "REFRESH AGGREGATING INDEX {index}", index = self.index)?;
114        if let Some(limit) = self.limit {
115            write!(f, " LIMIT {limit}")?;
116        }
117        Ok(())
118    }
119}
120
121#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
122pub struct CreateTableIndexStmt {
123    pub create_option: CreateOption,
124
125    pub index_name: Identifier,
126    pub index_type: TableIndexType,
127
128    pub catalog: Option<Identifier>,
129    pub database: Option<Identifier>,
130    pub table: Identifier,
131
132    pub columns: Vec<Identifier>,
133    pub sync_creation: bool,
134    pub index_options: BTreeMap<String, String>,
135}
136
137impl Display for CreateTableIndexStmt {
138    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
139        write!(f, "CREATE ")?;
140        if let CreateOption::CreateOrReplace = self.create_option {
141            write!(f, "OR REPLACE ")?;
142        }
143        if !self.sync_creation {
144            write!(f, "ASYNC ")?;
145        }
146        write!(f, "{} INDEX", self.index_type)?;
147        if let CreateOption::CreateIfNotExists = self.create_option {
148            write!(f, " IF NOT EXISTS")?;
149        }
150
151        write!(f, " {}", self.index_name)?;
152        write!(f, " ON ")?;
153        write_dot_separated_list(
154            f,
155            self.catalog
156                .iter()
157                .chain(&self.database)
158                .chain(Some(&self.table)),
159        )?;
160        write!(f, " (")?;
161        write_comma_separated_list(f, &self.columns)?;
162        write!(f, ")")?;
163
164        if !self.index_options.is_empty() {
165            write!(f, " ")?;
166            write_space_separated_string_map(f, &self.index_options)?;
167        }
168
169        Ok(())
170    }
171}
172
173#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
174pub struct DropTableIndexStmt {
175    pub if_exists: bool,
176    pub index_name: Identifier,
177    pub index_type: TableIndexType,
178    pub catalog: Option<Identifier>,
179    pub database: Option<Identifier>,
180    pub table: Identifier,
181}
182
183impl Display for DropTableIndexStmt {
184    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
185        write!(f, "DROP {} INDEX", self.index_type)?;
186        if self.if_exists {
187            write!(f, " IF EXISTS")?;
188        }
189
190        write!(f, " {}", self.index_name)?;
191        write!(f, " ON ")?;
192        write_dot_separated_list(
193            f,
194            self.catalog
195                .iter()
196                .chain(&self.database)
197                .chain(Some(&self.table)),
198        )?;
199        Ok(())
200    }
201}
202
203#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
204pub struct RefreshTableIndexStmt {
205    pub index_name: Identifier,
206    pub index_type: TableIndexType,
207    pub catalog: Option<Identifier>,
208    pub database: Option<Identifier>,
209    pub table: Identifier,
210    pub limit: Option<u64>,
211}
212
213impl Display for RefreshTableIndexStmt {
214    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
215        write!(f, "REFRESH {} INDEX", self.index_type)?;
216        write!(f, " {}", self.index_name)?;
217        write!(f, " ON ")?;
218        write_dot_separated_list(
219            f,
220            self.catalog
221                .iter()
222                .chain(&self.database)
223                .chain(Some(&self.table)),
224        )?;
225        if let Some(limit) = self.limit {
226            write!(f, " LIMIT {limit}")?;
227        }
228        Ok(())
229    }
230}