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) | Token::Keyword(Keyword::Indexes) | Token::Keyword(Keyword::Keys) => {
42 Ok(vibesql_ast::Statement::ShowIndex(self.parse_show_index()?))
43 }
44 Token::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 {
50 message: "Expected TABLE after SHOW CREATE".to_string(),
51 })
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 {
130 message: "Expected COLUMNS or FIELDS".to_string(),
131 });
132 }
133 self.advance();
134
135 self.expect_keyword(Keyword::From)?;
137 let table_name = self.parse_identifier()?;
138
139 let database = if self.peek_keyword(Keyword::From) {
141 self.advance();
142 Some(self.parse_identifier()?)
143 } else {
144 None
145 };
146
147 let like_pattern = if self.peek_keyword(Keyword::Like) {
149 self.advance();
150 Some(self.parse_string()?)
151 } else {
152 None
153 };
154
155 let where_clause = if self.peek_keyword(Keyword::Where) {
157 self.advance();
158 Some(self.parse_expression()?)
159 } else {
160 None
161 };
162
163 Ok(vibesql_ast::ShowColumnsStmt {
164 table_name,
165 database,
166 full,
167 like_pattern,
168 where_clause,
169 })
170 }
171
172 fn parse_show_index(&mut self) -> Result<vibesql_ast::ShowIndexStmt, ParseError> {
174 self.advance(); self.expect_keyword(Keyword::From)?;
179 let table_name = self.parse_identifier()?;
180
181 let database = if self.peek_keyword(Keyword::From) {
183 self.advance();
184 Some(self.parse_identifier()?)
185 } else {
186 None
187 };
188
189 Ok(vibesql_ast::ShowIndexStmt { table_name, database })
190 }
191
192 fn parse_show_create_table(&mut self) -> Result<vibesql_ast::ShowCreateTableStmt, ParseError> {
194 self.expect_keyword(Keyword::Table)?;
195 let table_name = self.parse_identifier()?;
196
197 Ok(vibesql_ast::ShowCreateTableStmt { table_name })
198 }
199
200 pub fn parse_describe_statement(&mut self) -> Result<vibesql_ast::DescribeStmt, ParseError> {
202 self.expect_keyword(Keyword::Describe)?;
203
204 let table_name = self.parse_identifier()?;
205
206 let column_pattern = if matches!(self.peek(), Token::Identifier(_) | Token::String(_)) {
208 Some(match self.peek() {
209 Token::String(_) => self.parse_string()?,
210 _ => self.parse_identifier()?,
211 })
212 } else {
213 None
214 };
215
216 Ok(vibesql_ast::DescribeStmt { table_name, column_pattern })
217 }
218
219 pub fn parse_explain_statement(&mut self) -> Result<vibesql_ast::ExplainStmt, ParseError> {
223 self.expect_keyword(Keyword::Explain)?;
224
225 let analyze = if matches!(self.peek(), Token::Keyword(Keyword::Analyze)) {
227 self.advance();
228 true
229 } else {
230 false
231 };
232
233 let format = if matches!(self.peek(), Token::Identifier(ref s) if s.to_uppercase() == "FORMAT") {
235 self.advance(); match self.peek() {
237 Token::Identifier(ref s) if s.to_uppercase() == "TEXT" => {
238 self.advance();
239 vibesql_ast::ExplainFormat::Text
240 }
241 Token::Identifier(ref s) if s.to_uppercase() == "JSON" => {
242 self.advance();
243 vibesql_ast::ExplainFormat::Json
244 }
245 _ => {
246 return Err(ParseError {
247 message: format!("Expected TEXT or JSON after FORMAT, found {:?}", self.peek()),
248 });
249 }
250 }
251 } else {
252 vibesql_ast::ExplainFormat::Text
253 };
254
255 let statement = match self.peek() {
257 Token::Keyword(Keyword::Select) | Token::Keyword(Keyword::With) => {
258 let select_stmt = self.parse_select_statement()?;
259 vibesql_ast::Statement::Select(Box::new(select_stmt))
260 }
261 Token::Keyword(Keyword::Insert) => {
262 let insert_stmt = self.parse_insert_statement()?;
263 vibesql_ast::Statement::Insert(insert_stmt)
264 }
265 Token::Keyword(Keyword::Update) => {
266 let update_stmt = self.parse_update_statement()?;
267 vibesql_ast::Statement::Update(update_stmt)
268 }
269 Token::Keyword(Keyword::Delete) => {
270 let delete_stmt = self.parse_delete_statement()?;
271 vibesql_ast::Statement::Delete(delete_stmt)
272 }
273 _ => {
274 return Err(ParseError {
275 message: format!(
276 "EXPLAIN requires SELECT, INSERT, UPDATE, or DELETE statement, found {:?}",
277 self.peek()
278 ),
279 });
280 }
281 };
282
283 Ok(vibesql_ast::ExplainStmt { statement: Box::new(statement), format, analyze })
284 }
285}