vibesql_parser/parser/
introspection.rs1use super::{ParseError, Parser};
4use crate::{keywords::Keyword, token::Token};
5
6impl Parser {
7 fn parse_string(&mut self) -> Result<String, ParseError> {
9 match self.peek() {
10 Token::String(s) => {
11 let string_val = s.clone();
12 self.advance();
13 Ok(string_val)
14 }
15 _ => Err(ParseError { message: self.peek().syntax_error() }),
16 }
17 }
18
19 pub fn parse_show_statement(&mut self) -> Result<vibesql_ast::Statement, ParseError> {
21 self.expect_keyword(Keyword::Show)?;
22
23 match self.peek() {
25 Token::Keyword { keyword: Keyword::Tables, .. } => {
26 Ok(vibesql_ast::Statement::ShowTables(self.parse_show_tables()?))
27 }
28 Token::Keyword { keyword: Keyword::Databases, .. } => {
29 Ok(vibesql_ast::Statement::ShowDatabases(self.parse_show_databases()?))
30 }
31 Token::Keyword { keyword: Keyword::Full, .. } => {
32 Ok(vibesql_ast::Statement::ShowColumns(self.parse_show_columns()?))
34 }
35 Token::Keyword { keyword: Keyword::Columns, .. }
36 | Token::Keyword { keyword: Keyword::Fields, .. } => {
37 Ok(vibesql_ast::Statement::ShowColumns(self.parse_show_columns()?))
38 }
39 Token::Keyword { keyword: Keyword::Index, .. }
40 | Token::Keyword { keyword: Keyword::Indexes, .. }
41 | Token::Keyword { keyword: Keyword::Keys, .. } => {
42 Ok(vibesql_ast::Statement::ShowIndex(self.parse_show_index()?))
43 }
44 Token::Keyword { keyword: Keyword::Create, .. } => {
45 self.advance(); if self.peek_keyword(Keyword::Table) {
47 Ok(vibesql_ast::Statement::ShowCreateTable(self.parse_show_create_table()?))
48 } else {
49 Err(ParseError { message: "Expected TABLE after SHOW CREATE".to_string() })
50 }
51 }
52 _ => Err(ParseError {
53 message: format!(
54 "Expected TABLES, DATABASES, COLUMNS, INDEX, or CREATE after SHOW, found {:?}",
55 self.peek()
56 ),
57 }),
58 }
59 }
60
61 fn parse_show_tables(&mut self) -> Result<vibesql_ast::ShowTablesStmt, ParseError> {
63 self.expect_keyword(Keyword::Tables)?;
64
65 let database = if self.peek_keyword(Keyword::From) {
67 self.advance();
68 Some(self.parse_identifier()?)
69 } else {
70 None
71 };
72
73 let like_pattern = if self.peek_keyword(Keyword::Like) {
75 self.advance();
76 Some(self.parse_string()?)
77 } else {
78 None
79 };
80
81 let where_clause = if self.peek_keyword(Keyword::Where) {
83 self.advance();
84 Some(self.parse_expression()?)
85 } else {
86 None
87 };
88
89 Ok(vibesql_ast::ShowTablesStmt { database, like_pattern, where_clause })
90 }
91
92 fn parse_show_databases(&mut self) -> Result<vibesql_ast::ShowDatabasesStmt, ParseError> {
94 self.expect_keyword(Keyword::Databases)?;
95
96 let like_pattern = if self.peek_keyword(Keyword::Like) {
98 self.advance();
99 Some(self.parse_string()?)
100 } else {
101 None
102 };
103
104 let where_clause = if self.peek_keyword(Keyword::Where) {
106 self.advance();
107 Some(self.parse_expression()?)
108 } else {
109 None
110 };
111
112 Ok(vibesql_ast::ShowDatabasesStmt { like_pattern, where_clause })
113 }
114
115 fn parse_show_columns(&mut self) -> Result<vibesql_ast::ShowColumnsStmt, ParseError> {
117 let full = if self.peek_keyword(Keyword::Full) {
119 self.advance();
120 true
121 } else {
122 false
123 };
124
125 if !self.peek_keyword(Keyword::Columns) && !self.peek_keyword(Keyword::Fields) {
127 return Err(ParseError { message: "Expected COLUMNS or FIELDS".to_string() });
128 }
129 self.advance();
130
131 self.expect_keyword(Keyword::From)?;
133 let table_name = self.parse_identifier()?;
134
135 let database = if self.peek_keyword(Keyword::From) {
137 self.advance();
138 Some(self.parse_identifier()?)
139 } else {
140 None
141 };
142
143 let like_pattern = if self.peek_keyword(Keyword::Like) {
145 self.advance();
146 Some(self.parse_string()?)
147 } else {
148 None
149 };
150
151 let where_clause = if self.peek_keyword(Keyword::Where) {
153 self.advance();
154 Some(self.parse_expression()?)
155 } else {
156 None
157 };
158
159 Ok(vibesql_ast::ShowColumnsStmt { table_name, database, full, like_pattern, where_clause })
160 }
161
162 fn parse_show_index(&mut self) -> Result<vibesql_ast::ShowIndexStmt, ParseError> {
164 self.advance(); self.expect_keyword(Keyword::From)?;
169 let table_name = self.parse_identifier()?;
170
171 let database = if self.peek_keyword(Keyword::From) {
173 self.advance();
174 Some(self.parse_identifier()?)
175 } else {
176 None
177 };
178
179 Ok(vibesql_ast::ShowIndexStmt { table_name, database })
180 }
181
182 fn parse_show_create_table(&mut self) -> Result<vibesql_ast::ShowCreateTableStmt, ParseError> {
184 self.expect_keyword(Keyword::Table)?;
185 let table_name = self.parse_identifier()?;
186
187 Ok(vibesql_ast::ShowCreateTableStmt { table_name })
188 }
189
190 pub fn parse_describe_statement(&mut self) -> Result<vibesql_ast::DescribeStmt, ParseError> {
192 self.expect_keyword(Keyword::Describe)?;
193
194 let table_name = self.parse_identifier()?;
195
196 let column_pattern = if matches!(self.peek(), Token::Identifier(_) | Token::String(_)) {
198 Some(match self.peek() {
199 Token::String(_) => self.parse_string()?,
200 _ => self.parse_identifier()?,
201 })
202 } else {
203 None
204 };
205
206 Ok(vibesql_ast::DescribeStmt { table_name, column_pattern })
207 }
208
209 pub fn parse_explain_statement(&mut self) -> Result<vibesql_ast::ExplainStmt, ParseError> {
213 self.expect_keyword(Keyword::Explain)?;
214
215 let query_plan = if matches!(self.peek(), Token::Keyword { keyword: Keyword::Query, .. }) {
217 self.advance(); self.expect_keyword(Keyword::Plan)?;
219 true
220 } else {
221 false
222 };
223
224 let analyze = if !query_plan
226 && matches!(self.peek(), Token::Keyword { keyword: Keyword::Analyze, .. })
227 {
228 self.advance();
229 true
230 } else {
231 false
232 };
233
234 let format = if matches!(self.peek(), Token::Identifier(ref s) if s.to_uppercase() == "FORMAT")
236 {
237 self.advance(); match self.peek() {
239 Token::Identifier(ref s) if s.to_uppercase() == "TEXT" => {
240 self.advance();
241 vibesql_ast::ExplainFormat::Text
242 }
243 Token::Identifier(ref s) if s.to_uppercase() == "JSON" => {
244 self.advance();
245 vibesql_ast::ExplainFormat::Json
246 }
247 _ => {
248 return Err(ParseError {
249 message: format!(
250 "Expected TEXT or JSON after FORMAT, found {:?}",
251 self.peek()
252 ),
253 });
254 }
255 }
256 } else {
257 vibesql_ast::ExplainFormat::Text
258 };
259
260 let statement = match self.peek() {
262 Token::Keyword { keyword: Keyword::Select, .. }
263 | Token::Keyword { keyword: Keyword::With, .. } => {
264 let select_stmt = self.parse_select_statement()?;
265 vibesql_ast::Statement::Select(Box::new(select_stmt))
266 }
267 Token::Keyword { keyword: Keyword::Insert, .. } => {
268 let insert_stmt = self.parse_insert_statement()?;
269 vibesql_ast::Statement::Insert(insert_stmt)
270 }
271 Token::Keyword { keyword: Keyword::Update, .. } => {
272 let update_stmt = self.parse_update_statement()?;
273 vibesql_ast::Statement::Update(update_stmt)
274 }
275 Token::Keyword { keyword: Keyword::Delete, .. } => {
276 let delete_stmt = self.parse_delete_statement()?;
277 vibesql_ast::Statement::Delete(delete_stmt)
278 }
279 _ => {
280 return Err(ParseError {
281 message: format!(
282 "EXPLAIN requires SELECT, INSERT, UPDATE, or DELETE statement, found {:?}",
283 self.peek()
284 ),
285 });
286 }
287 };
288
289 Ok(vibesql_ast::ExplainStmt { statement: Box::new(statement), format, analyze, query_plan })
290 }
291}