Skip to main content

radixdb_sql/ast/
control.rs

1// Copyright 2026 RadixDB Contributors
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 super::*;
16
17/// BEGIN statement
18#[derive(Debug, Clone, PartialEq)]
19pub struct BeginStatement {
20    pub token: Token,
21    pub isolation_level: Option<SmartString>,
22}
23
24impl fmt::Display for BeginStatement {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        let mut result = String::from("BEGIN TRANSACTION");
27        if let Some(ref level) = self.isolation_level {
28            result.push_str(&format!(" ISOLATION LEVEL {}", level));
29        }
30        write!(f, "{}", result)
31    }
32}
33
34/// COMMIT statement
35#[derive(Debug, Clone, PartialEq)]
36pub struct CommitStatement {
37    pub token: Token,
38}
39
40impl fmt::Display for CommitStatement {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        write!(f, "COMMIT")
43    }
44}
45
46/// ROLLBACK statement
47#[derive(Debug, Clone, PartialEq)]
48pub struct RollbackStatement {
49    pub token: Token,
50    pub savepoint_name: Option<Identifier>,
51}
52
53impl fmt::Display for RollbackStatement {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        if let Some(ref name) = self.savepoint_name {
56            write!(f, "ROLLBACK TO SAVEPOINT {}", name)
57        } else {
58            write!(f, "ROLLBACK")
59        }
60    }
61}
62
63/// SAVEPOINT statement
64#[derive(Debug, Clone, PartialEq)]
65pub struct SavepointStatement {
66    pub token: Token,
67    pub savepoint_name: Identifier,
68}
69
70impl fmt::Display for SavepointStatement {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        write!(f, "SAVEPOINT {}", self.savepoint_name)
73    }
74}
75
76/// RELEASE SAVEPOINT statement
77#[derive(Debug, Clone, PartialEq)]
78pub struct ReleaseSavepointStatement {
79    pub token: Token,
80    pub savepoint_name: Identifier,
81}
82
83impl fmt::Display for ReleaseSavepointStatement {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        write!(f, "RELEASE SAVEPOINT {}", self.savepoint_name)
86    }
87}
88
89/// SET statement
90#[derive(Debug, Clone, PartialEq)]
91pub struct SetStatement {
92    pub token: Token,
93    pub name: Identifier,
94    pub value: Expression,
95}
96
97impl fmt::Display for SetStatement {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        write!(f, "SET {} = {}", self.name, self.value)
100    }
101}
102
103/// SHOW a connection-local variable.
104#[derive(Debug, Clone, PartialEq)]
105pub struct ShowVariableStatement {
106    pub token: Token,
107    pub name: Identifier,
108}
109
110impl fmt::Display for ShowVariableStatement {
111    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
112        write!(formatter, "SHOW {}", self.name)
113    }
114}
115
116/// PRAGMA statement
117#[derive(Debug, Clone, PartialEq)]
118pub struct PragmaStatement {
119    pub token: Token,
120    pub name: Identifier,
121    pub value: Option<Expression>,
122}
123
124impl fmt::Display for PragmaStatement {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        if let Some(ref value) = self.value {
127            write!(f, "PRAGMA {} = {}", self.name, value)
128        } else {
129            write!(f, "PRAGMA {}", self.name)
130        }
131    }
132}
133
134/// SHOW TABLES statement
135#[derive(Debug, Clone, PartialEq)]
136pub struct ShowTablesStatement {
137    pub token: Token,
138}
139
140impl fmt::Display for ShowTablesStatement {
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        write!(f, "SHOW TABLES")
143    }
144}
145
146/// SHOW VIEWS statement
147#[derive(Debug, Clone, PartialEq)]
148pub struct ShowViewsStatement {
149    pub token: Token,
150}
151
152impl fmt::Display for ShowViewsStatement {
153    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154        write!(f, "SHOW VIEWS")
155    }
156}
157
158/// SHOW CREATE TABLE statement
159#[derive(Debug, Clone, PartialEq)]
160pub struct ShowCreateTableStatement {
161    pub token: Token,
162    pub table_name: Identifier,
163}
164
165impl fmt::Display for ShowCreateTableStatement {
166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167        write!(f, "SHOW CREATE TABLE {}", self.table_name)
168    }
169}
170
171/// SHOW CREATE VIEW statement
172#[derive(Debug, Clone, PartialEq)]
173pub struct ShowCreateViewStatement {
174    pub token: Token,
175    pub view_name: Identifier,
176}
177
178impl fmt::Display for ShowCreateViewStatement {
179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180        write!(f, "SHOW CREATE VIEW {}", self.view_name)
181    }
182}
183
184/// SHOW INDEXES statement
185#[derive(Debug, Clone, PartialEq)]
186pub struct ShowIndexesStatement {
187    pub token: Token,
188    pub table_name: Identifier,
189}
190
191impl fmt::Display for ShowIndexesStatement {
192    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193        write!(f, "SHOW INDEXES FROM {}", self.table_name)
194    }
195}
196
197/// DESCRIBE target.
198#[derive(Debug, Clone, PartialEq)]
199pub enum DescribeTarget {
200    Table(Identifier),
201    Database,
202}
203
204/// DESCRIBE output representation.
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
206pub enum DescribeFormat {
207    Tabular,
208    Json,
209}
210
211/// DESCRIBE statement - shows table structure or a versioned JSON catalog.
212#[derive(Debug, Clone, PartialEq)]
213pub struct DescribeStatement {
214    pub token: Token,
215    pub target: DescribeTarget,
216    pub format: DescribeFormat,
217}
218
219impl fmt::Display for DescribeStatement {
220    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221        match (&self.target, self.format) {
222            (DescribeTarget::Table(table), DescribeFormat::Tabular) => {
223                write!(f, "DESCRIBE {table}")
224            }
225            (DescribeTarget::Table(table), DescribeFormat::Json) => {
226                write!(f, "DESCRIBE TABLE {table} FORMAT JSON")
227            }
228            (DescribeTarget::Database, DescribeFormat::Json) => {
229                write!(f, "DESCRIBE DATABASE FORMAT JSON")
230            }
231            (DescribeTarget::Database, DescribeFormat::Tabular) => {
232                write!(f, "DESCRIBE DATABASE")
233            }
234        }
235    }
236}
237
238/// Expression statement (standalone expression)
239#[derive(Debug, Clone, PartialEq)]
240pub struct ExpressionStatement {
241    pub token: Token,
242    pub expression: Expression,
243}
244
245impl fmt::Display for ExpressionStatement {
246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247        write!(f, "{}", self.expression)
248    }
249}
250
251/// EXPLAIN statement
252#[derive(Debug, Clone, PartialEq)]
253pub struct ExplainStatement {
254    pub token: Token,
255    pub statement: Box<Statement>,
256    pub analyze: bool,
257}
258
259impl fmt::Display for ExplainStatement {
260    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261        if self.analyze {
262            write!(f, "EXPLAIN ANALYZE {}", self.statement)
263        } else {
264            write!(f, "EXPLAIN {}", self.statement)
265        }
266    }
267}
268
269/// ANALYZE statement for collecting table statistics
270#[derive(Debug, Clone, PartialEq)]
271pub struct AnalyzeStatement {
272    pub token: Token,
273    /// Table name to analyze (None = analyze all tables)
274    pub table_name: Option<SmartString>,
275}
276
277impl fmt::Display for AnalyzeStatement {
278    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279        match &self.table_name {
280            Some(name) => write!(f, "ANALYZE {}", name),
281            None => write!(f, "ANALYZE"),
282        }
283    }
284}