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