Skip to main content

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