1use std::fmt;
2
3use crate::{keywords::Keyword, lexer::Lexer, token::Token};
4
5mod advanced_objects;
6mod alter;
7mod create;
8mod cursor;
9mod delete;
10mod domain;
11mod drop;
12mod truncate;
13mod expressions;
14mod grant;
15mod helpers;
16mod index;
17mod insert;
18mod introspection;
19mod prepared;
20mod revoke;
21mod role;
22mod schema;
23mod select;
24mod table_options;
25mod transaction;
26mod trigger;
27mod update;
28mod view;
29
30#[derive(Debug, Clone, PartialEq)]
32pub struct ParseError {
33 pub message: String,
34}
35
36impl fmt::Display for ParseError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "Parse error: {}", self.message)
39 }
40}
41
42pub struct Parser {
44 tokens: Vec<Token>,
45 position: usize,
46 placeholder_count: usize,
49}
50
51impl Parser {
52 pub fn new(tokens: Vec<Token>) -> Self {
54 Parser { tokens, position: 0, placeholder_count: 0 }
55 }
56
57 pub fn parse_comma_separated_list<T, F>(&mut self, parse_item: F) -> Result<Vec<T>, ParseError>
79 where
80 F: Fn(&mut Self) -> Result<T, ParseError>,
81 {
82 let mut items = Vec::new();
83
84 items.push(parse_item(self)?);
86
87 while matches!(self.peek(), Token::Comma) {
89 self.advance(); items.push(parse_item(self)?);
91 }
92
93 Ok(items)
94 }
95
96 pub fn parse_sql(input: &str) -> Result<vibesql_ast::Statement, ParseError> {
98 let mut lexer = Lexer::new(input);
99 let tokens =
100 lexer.tokenize().map_err(|e| ParseError { message: format!("Lexer error: {}", e) })?;
101
102 let mut parser = Parser::new(tokens);
103 parser.parse_statement()
104 }
105
106 pub fn parse_statement(&mut self) -> Result<vibesql_ast::Statement, ParseError> {
108 match self.peek() {
109 Token::Keyword(Keyword::Select) | Token::Keyword(Keyword::With) => {
110 let select_stmt = self.parse_select_statement()?;
111 Ok(vibesql_ast::Statement::Select(Box::new(select_stmt)))
112 }
113 Token::Keyword(Keyword::Insert) => {
114 let insert_stmt = self.parse_insert_statement()?;
115 Ok(vibesql_ast::Statement::Insert(insert_stmt))
116 }
117 Token::Keyword(Keyword::Replace) => {
118 let insert_stmt = self.parse_replace_statement()?;
119 Ok(vibesql_ast::Statement::Insert(insert_stmt))
120 }
121 Token::Keyword(Keyword::Update) => {
122 let update_stmt = self.parse_update_statement()?;
123 Ok(vibesql_ast::Statement::Update(update_stmt))
124 }
125 Token::Keyword(Keyword::Delete) => {
126 let delete_stmt = self.parse_delete_statement()?;
127 Ok(vibesql_ast::Statement::Delete(delete_stmt))
128 }
129 Token::Keyword(Keyword::Create) => {
130 if self.peek_next_keyword(Keyword::Or) && matches!(self.peek_at_offset(2), Token::Keyword(Keyword::Replace)) {
132 if matches!(self.peek_at_offset(3), Token::Keyword(Keyword::View))
134 || matches!(self.peek_at_offset(3), Token::Keyword(Keyword::Temp))
135 || matches!(self.peek_at_offset(3), Token::Keyword(Keyword::Temporary))
136 {
137 return Ok(vibesql_ast::Statement::CreateView(self.parse_create_view_statement()?));
138 }
139 }
140 if self.peek_next_keyword(Keyword::Table) {
141 Ok(vibesql_ast::Statement::CreateTable(self.parse_create_table_statement()?))
142 } else if self.peek_next_keyword(Keyword::Schema) {
143 Ok(vibesql_ast::Statement::CreateSchema(self.parse_create_schema_statement()?))
144 } else if self.peek_next_keyword(Keyword::Role) {
145 Ok(vibesql_ast::Statement::CreateRole(self.parse_create_role_statement()?))
146 } else if self.peek_next_keyword(Keyword::Domain) {
147 Ok(vibesql_ast::Statement::CreateDomain(self.parse_create_domain_statement()?))
148 } else if self.peek_next_keyword(Keyword::Sequence) {
149 Ok(vibesql_ast::Statement::CreateSequence(self.parse_create_sequence_statement()?))
150 } else if self.peek_next_keyword(Keyword::Type) {
151 Ok(vibesql_ast::Statement::CreateType(self.parse_create_type_statement()?))
152 } else if self.peek_next_keyword(Keyword::Collation) {
153 Ok(vibesql_ast::Statement::CreateCollation(self.parse_create_collation_statement()?))
154 } else if self.peek_next_keyword(Keyword::Character) {
155 Ok(vibesql_ast::Statement::CreateCharacterSet(
156 self.parse_create_character_set_statement()?,
157 ))
158 } else if self.peek_next_keyword(Keyword::Translation) {
159 Ok(vibesql_ast::Statement::CreateTranslation(
160 self.parse_create_translation_statement()?,
161 ))
162 } else if self.peek_next_keyword(Keyword::View) {
163 Ok(vibesql_ast::Statement::CreateView(self.parse_create_view_statement()?))
164 } else if self.peek_next_keyword(Keyword::Temp) || self.peek_next_keyword(Keyword::Temporary) {
165 Ok(vibesql_ast::Statement::CreateView(self.parse_create_view_statement()?))
167 } else if self.peek_next_keyword(Keyword::Trigger) {
168 Ok(vibesql_ast::Statement::CreateTrigger(self.parse_create_trigger_statement()?))
169 } else if self.peek_next_keyword(Keyword::Index)
170 || self.peek_next_keyword(Keyword::Unique)
171 || self.peek_next_keyword(Keyword::Fulltext)
172 || self.peek_next_keyword(Keyword::Spatial)
173 {
174 Ok(vibesql_ast::Statement::CreateIndex(self.parse_create_index_statement()?))
175 } else if self.peek_next_keyword(Keyword::Assertion) {
176 Ok(vibesql_ast::Statement::CreateAssertion(self.parse_create_assertion_statement()?))
177 } else if self.peek_next_keyword(Keyword::Procedure) {
178 Ok(vibesql_ast::Statement::CreateProcedure(self.parse_create_procedure_statement()?))
179 } else if self.peek_next_keyword(Keyword::Function) {
180 Ok(vibesql_ast::Statement::CreateFunction(self.parse_create_function_statement()?))
181 } else {
182 Err(ParseError {
183 message:
184 "Expected TABLE, SCHEMA, ROLE, DOMAIN, SEQUENCE, TYPE, COLLATION, CHARACTER, TRANSLATION, VIEW, TRIGGER, INDEX, ASSERTION, PROCEDURE, or FUNCTION after CREATE"
185 .to_string(),
186 })
187 }
188 }
189 Token::Keyword(Keyword::Drop) => {
190 if self.peek_next_keyword(Keyword::Table) {
191 Ok(vibesql_ast::Statement::DropTable(self.parse_drop_table_statement()?))
192 } else if self.peek_next_keyword(Keyword::Schema) {
193 Ok(vibesql_ast::Statement::DropSchema(self.parse_drop_schema_statement()?))
194 } else if self.peek_next_keyword(Keyword::Role) {
195 Ok(vibesql_ast::Statement::DropRole(self.parse_drop_role_statement()?))
196 } else if self.peek_next_keyword(Keyword::Domain) {
197 Ok(vibesql_ast::Statement::DropDomain(self.parse_drop_domain_statement()?))
198 } else if self.peek_next_keyword(Keyword::Sequence) {
199 Ok(vibesql_ast::Statement::DropSequence(self.parse_drop_sequence_statement()?))
200 } else if self.peek_next_keyword(Keyword::Type) {
201 Ok(vibesql_ast::Statement::DropType(self.parse_drop_type_statement()?))
202 } else if self.peek_next_keyword(Keyword::Collation) {
203 Ok(vibesql_ast::Statement::DropCollation(self.parse_drop_collation_statement()?))
204 } else if self.peek_next_keyword(Keyword::Character) {
205 Ok(vibesql_ast::Statement::DropCharacterSet(self.parse_drop_character_set_statement()?))
206 } else if self.peek_next_keyword(Keyword::Translation) {
207 Ok(vibesql_ast::Statement::DropTranslation(self.parse_drop_translation_statement()?))
208 } else if self.peek_next_keyword(Keyword::View) {
209 Ok(vibesql_ast::Statement::DropView(self.parse_drop_view_statement()?))
210 } else if self.peek_next_keyword(Keyword::Trigger) {
211 Ok(vibesql_ast::Statement::DropTrigger(self.parse_drop_trigger_statement()?))
212 } else if self.peek_next_keyword(Keyword::Index) {
213 Ok(vibesql_ast::Statement::DropIndex(self.parse_drop_index_statement()?))
214 } else if self.peek_next_keyword(Keyword::Assertion) {
215 Ok(vibesql_ast::Statement::DropAssertion(self.parse_drop_assertion_statement()?))
216 } else if self.peek_next_keyword(Keyword::Procedure) {
217 Ok(vibesql_ast::Statement::DropProcedure(self.parse_drop_procedure_statement()?))
218 } else if self.peek_next_keyword(Keyword::Function) {
219 Ok(vibesql_ast::Statement::DropFunction(self.parse_drop_function_statement()?))
220 } else {
221 Err(ParseError {
222 message:
223 "Expected TABLE, SCHEMA, ROLE, DOMAIN, SEQUENCE, TYPE, COLLATION, CHARACTER, TRANSLATION, VIEW, TRIGGER, INDEX, ASSERTION, PROCEDURE, or FUNCTION after DROP"
224 .to_string(),
225 })
226 }
227 }
228 Token::Keyword(Keyword::Truncate) => {
229 let truncate_stmt = self.parse_truncate_table_statement()?;
230 Ok(vibesql_ast::Statement::TruncateTable(truncate_stmt))
231 }
232 Token::Keyword(Keyword::Alter) => {
233 if self.peek_next_keyword(Keyword::Table) {
234 let alter_stmt = self.parse_alter_table_statement()?;
235 Ok(vibesql_ast::Statement::AlterTable(alter_stmt))
236 } else if self.peek_next_keyword(Keyword::Sequence) {
237 let alter_stmt = self.parse_alter_sequence_statement()?;
238 Ok(vibesql_ast::Statement::AlterSequence(alter_stmt))
239 } else if self.peek_next_keyword(Keyword::Trigger) {
240 let alter_stmt = self.parse_alter_trigger_statement()?;
241 Ok(vibesql_ast::Statement::AlterTrigger(alter_stmt))
242 } else {
243 Err(ParseError {
244 message: "Expected TABLE, SEQUENCE, or TRIGGER after ALTER".to_string(),
245 })
246 }
247 }
248 Token::Keyword(Keyword::Reindex) => {
249 let reindex_stmt = self.parse_reindex_statement()?;
250 Ok(vibesql_ast::Statement::Reindex(reindex_stmt))
251 }
252 Token::Keyword(Keyword::Analyze) => {
253 let analyze_stmt = self.parse_analyze_statement()?;
254 Ok(vibesql_ast::Statement::Analyze(analyze_stmt))
255 }
256 Token::Keyword(Keyword::Explain) => {
257 let explain_stmt = self.parse_explain_statement()?;
258 Ok(vibesql_ast::Statement::Explain(explain_stmt))
259 }
260 Token::Keyword(Keyword::Begin) | Token::Keyword(Keyword::Start) => {
261 let begin_stmt = self.parse_begin_statement()?;
262 Ok(vibesql_ast::Statement::BeginTransaction(begin_stmt))
263 }
264 Token::Keyword(Keyword::Commit) => {
265 let commit_stmt = self.parse_commit_statement()?;
266 Ok(vibesql_ast::Statement::Commit(commit_stmt))
267 }
268 Token::Keyword(Keyword::Rollback) => {
269 let saved_position = self.position;
271 self.advance(); if self.peek_keyword(Keyword::To) {
273 self.position = saved_position;
275 let rollback_to_stmt = self.parse_rollback_to_savepoint_statement()?;
276 Ok(vibesql_ast::Statement::RollbackToSavepoint(rollback_to_stmt))
277 } else {
278 self.position = saved_position;
280 let rollback_stmt = self.parse_rollback_statement()?;
281 Ok(vibesql_ast::Statement::Rollback(rollback_stmt))
282 }
283 }
284 Token::Keyword(Keyword::Savepoint) => {
285 let savepoint_stmt = self.parse_savepoint_statement()?;
286 Ok(vibesql_ast::Statement::Savepoint(savepoint_stmt))
287 }
288 Token::Keyword(Keyword::Release) => {
289 let release_stmt = self.parse_release_savepoint_statement()?;
290 Ok(vibesql_ast::Statement::ReleaseSavepoint(release_stmt))
291 }
292 Token::Keyword(Keyword::Set) => {
293 if self.peek_next_keyword(Keyword::Schema) {
295 let set_stmt = self.parse_set_schema_statement()?;
296 Ok(vibesql_ast::Statement::SetSchema(set_stmt))
297 } else if self.peek_next_keyword(Keyword::Catalog) {
298 let set_stmt = schema::parse_set_catalog(self)?;
299 Ok(vibesql_ast::Statement::SetCatalog(set_stmt))
300 } else if self.peek_next_keyword(Keyword::Names) {
301 let set_stmt = schema::parse_set_names(self)?;
302 Ok(vibesql_ast::Statement::SetNames(set_stmt))
303 } else if self.peek_next_keyword(Keyword::Time) {
304 let set_stmt = schema::parse_set_time_zone(self)?;
305 Ok(vibesql_ast::Statement::SetTimeZone(set_stmt))
306 } else if self.peek_next_keyword(Keyword::Transaction) {
307 let set_stmt = self.parse_set_transaction_statement()?;
308 Ok(vibesql_ast::Statement::SetTransaction(set_stmt))
309 } else if self.peek_next_keyword(Keyword::Local) {
310 let set_stmt = self.parse_set_transaction_statement()?;
312 Ok(vibesql_ast::Statement::SetTransaction(set_stmt))
313 } else {
314 let set_stmt = schema::parse_set_variable(self)?;
316 Ok(vibesql_ast::Statement::SetVariable(set_stmt))
317 }
318 }
319 Token::Keyword(Keyword::Grant) => {
320 let grant_stmt = self.parse_grant_statement()?;
321 Ok(vibesql_ast::Statement::Grant(grant_stmt))
322 }
323 Token::Keyword(Keyword::Revoke) => {
324 let revoke_stmt = self.parse_revoke_statement()?;
325 Ok(vibesql_ast::Statement::Revoke(revoke_stmt))
326 }
327 Token::Keyword(Keyword::Declare) => {
328 let declare_cursor_stmt = self.parse_declare_cursor_statement()?;
329 Ok(vibesql_ast::Statement::DeclareCursor(declare_cursor_stmt))
330 }
331 Token::Keyword(Keyword::Open) => {
332 let open_cursor_stmt = self.parse_open_cursor_statement()?;
333 Ok(vibesql_ast::Statement::OpenCursor(open_cursor_stmt))
334 }
335 Token::Keyword(Keyword::Fetch) => {
336 let fetch_stmt = self.parse_fetch_statement()?;
337 Ok(vibesql_ast::Statement::Fetch(fetch_stmt))
338 }
339 Token::Keyword(Keyword::Close) => {
340 let close_cursor_stmt = self.parse_close_cursor_statement()?;
341 Ok(vibesql_ast::Statement::CloseCursor(close_cursor_stmt))
342 }
343 Token::Keyword(Keyword::Call) => {
344 let call_stmt = self.parse_call_statement()?;
345 Ok(vibesql_ast::Statement::Call(call_stmt))
346 }
347 Token::Keyword(Keyword::Show) => self.parse_show_statement(),
348 Token::Keyword(Keyword::Describe) => {
349 let describe_stmt = self.parse_describe_statement()?;
350 Ok(vibesql_ast::Statement::Describe(describe_stmt))
351 }
352 Token::Keyword(Keyword::Prepare) => {
353 let prepare_stmt = self.parse_prepare_statement()?;
354 Ok(vibesql_ast::Statement::Prepare(prepare_stmt))
355 }
356 Token::Keyword(Keyword::Execute) => {
357 let execute_stmt = self.parse_execute_statement()?;
358 Ok(vibesql_ast::Statement::Execute(execute_stmt))
359 }
360 Token::Keyword(Keyword::Deallocate) => {
361 let deallocate_stmt = self.parse_deallocate_statement()?;
362 Ok(vibesql_ast::Statement::Deallocate(deallocate_stmt))
363 }
364 _ => {
365 Err(ParseError { message: format!("Expected statement, found {:?}", self.peek()) })
366 }
367 }
368 }
369
370 pub fn parse_begin_statement(&mut self) -> Result<vibesql_ast::BeginStmt, ParseError> {
372 transaction::parse_begin_statement(self)
373 }
374
375 pub fn parse_commit_statement(&mut self) -> Result<vibesql_ast::CommitStmt, ParseError> {
377 transaction::parse_commit_statement(self)
378 }
379
380 pub fn parse_rollback_statement(&mut self) -> Result<vibesql_ast::RollbackStmt, ParseError> {
382 transaction::parse_rollback_statement(self)
383 }
384
385 pub fn parse_alter_table_statement(&mut self) -> Result<vibesql_ast::AlterTableStmt, ParseError> {
387 alter::parse_alter_table(self)
388 }
389
390 pub fn parse_savepoint_statement(&mut self) -> Result<vibesql_ast::SavepointStmt, ParseError> {
392 transaction::parse_savepoint_statement(self)
393 }
394
395 pub fn parse_rollback_to_savepoint_statement(
397 &mut self,
398 ) -> Result<vibesql_ast::RollbackToSavepointStmt, ParseError> {
399 transaction::parse_rollback_to_savepoint_statement(self)
400 }
401
402 pub fn parse_release_savepoint_statement(
404 &mut self,
405 ) -> Result<vibesql_ast::ReleaseSavepointStmt, ParseError> {
406 transaction::parse_release_savepoint_statement(self)
407 }
408
409 pub fn parse_create_schema_statement(&mut self) -> Result<vibesql_ast::CreateSchemaStmt, ParseError> {
411 schema::parse_create_schema(self)
412 }
413
414 pub fn parse_drop_schema_statement(&mut self) -> Result<vibesql_ast::DropSchemaStmt, ParseError> {
416 schema::parse_drop_schema(self)
417 }
418
419 pub fn parse_set_schema_statement(&mut self) -> Result<vibesql_ast::SetSchemaStmt, ParseError> {
421 schema::parse_set_schema(self)
422 }
423
424 pub fn parse_grant_statement(&mut self) -> Result<vibesql_ast::GrantStmt, ParseError> {
426 grant::parse_grant(self)
427 }
428
429 pub fn parse_revoke_statement(&mut self) -> Result<vibesql_ast::RevokeStmt, ParseError> {
431 revoke::parse_revoke(self)
432 }
433
434 pub fn parse_create_role_statement(&mut self) -> Result<vibesql_ast::CreateRoleStmt, ParseError> {
436 role::parse_create_role(self)
437 }
438
439 pub fn parse_drop_role_statement(&mut self) -> Result<vibesql_ast::DropRoleStmt, ParseError> {
441 role::parse_drop_role(self)
442 }
443
444 pub fn parse_create_domain_statement(&mut self) -> Result<vibesql_ast::CreateDomainStmt, ParseError> {
450 domain::parse_create_domain(self)
451 }
452
453 pub fn parse_drop_domain_statement(&mut self) -> Result<vibesql_ast::DropDomainStmt, ParseError> {
455 domain::parse_drop_domain(self)
456 }
457
458 pub fn parse_create_sequence_statement(
460 &mut self,
461 ) -> Result<vibesql_ast::CreateSequenceStmt, ParseError> {
462 advanced_objects::parse_create_sequence(self)
463 }
464
465 pub fn parse_drop_sequence_statement(&mut self) -> Result<vibesql_ast::DropSequenceStmt, ParseError> {
467 advanced_objects::parse_drop_sequence(self)
468 }
469
470 pub fn parse_alter_sequence_statement(&mut self) -> Result<vibesql_ast::AlterSequenceStmt, ParseError> {
472 advanced_objects::parse_alter_sequence(self)
473 }
474
475 pub fn parse_create_type_statement(&mut self) -> Result<vibesql_ast::CreateTypeStmt, ParseError> {
477 advanced_objects::parse_create_type(self)
478 }
479
480 pub fn parse_set_transaction_statement(
482 &mut self,
483 ) -> Result<vibesql_ast::SetTransactionStmt, ParseError> {
484 self.expect_keyword(Keyword::Set)?;
486
487 let local = self.try_consume_keyword(Keyword::Local);
489
490 self.expect_keyword(Keyword::Transaction)?;
492
493 let mut isolation_level = None;
495 let mut access_mode = None;
496
497 loop {
498 if self.try_consume_keyword(Keyword::Serializable) {
499 isolation_level = Some(vibesql_ast::IsolationLevel::Serializable);
500 } else if self.try_consume_keyword(Keyword::Read) {
501 if self.try_consume_keyword(Keyword::Only) {
502 access_mode = Some(vibesql_ast::TransactionAccessMode::ReadOnly);
503 } else if self.try_consume_keyword(Keyword::Write) {
504 access_mode = Some(vibesql_ast::TransactionAccessMode::ReadWrite);
505 } else {
506 return Err(ParseError {
507 message: "Expected ONLY or WRITE after READ".to_string(),
508 });
509 }
510 } else if self.try_consume_keyword(Keyword::Isolation) {
511 self.expect_keyword(Keyword::Level)?;
512 if self.try_consume_keyword(Keyword::Serializable) {
513 isolation_level = Some(vibesql_ast::IsolationLevel::Serializable);
514 } else {
515 return Err(ParseError {
516 message: "Expected SERIALIZABLE after ISOLATION LEVEL".to_string(),
517 });
518 }
519 } else {
520 break;
521 }
522
523 if !self.try_consume(&Token::Comma) {
525 break;
526 }
527 }
528
529 Ok(vibesql_ast::SetTransactionStmt { local, isolation_level, access_mode })
530 }
531
532 pub fn parse_drop_type_statement(&mut self) -> Result<vibesql_ast::DropTypeStmt, ParseError> {
534 advanced_objects::parse_drop_type(self)
535 }
536
537 pub fn parse_create_collation_statement(
539 &mut self,
540 ) -> Result<vibesql_ast::CreateCollationStmt, ParseError> {
541 advanced_objects::parse_create_collation(self)
542 }
543
544 pub fn parse_drop_collation_statement(&mut self) -> Result<vibesql_ast::DropCollationStmt, ParseError> {
546 advanced_objects::parse_drop_collation(self)
547 }
548
549 pub fn parse_create_character_set_statement(
551 &mut self,
552 ) -> Result<vibesql_ast::CreateCharacterSetStmt, ParseError> {
553 advanced_objects::parse_create_character_set(self)
554 }
555
556 pub fn parse_drop_character_set_statement(
558 &mut self,
559 ) -> Result<vibesql_ast::DropCharacterSetStmt, ParseError> {
560 advanced_objects::parse_drop_character_set(self)
561 }
562
563 pub fn parse_create_translation_statement(
565 &mut self,
566 ) -> Result<vibesql_ast::CreateTranslationStmt, ParseError> {
567 advanced_objects::parse_create_translation(self)
568 }
569
570 pub fn parse_drop_translation_statement(
572 &mut self,
573 ) -> Result<vibesql_ast::DropTranslationStmt, ParseError> {
574 advanced_objects::parse_drop_translation(self)
575 }
576
577 pub fn parse_create_assertion_statement(
579 &mut self,
580 ) -> Result<vibesql_ast::CreateAssertionStmt, ParseError> {
581 advanced_objects::parse_create_assertion(self)
582 }
583
584 pub fn parse_drop_assertion_statement(&mut self) -> Result<vibesql_ast::DropAssertionStmt, ParseError> {
586 advanced_objects::parse_drop_assertion(self)
587 }
588
589 pub fn parse_create_procedure_statement(
591 &mut self,
592 ) -> Result<vibesql_ast::CreateProcedureStmt, ParseError> {
593 self.advance(); self.advance(); self.parse_create_procedure()
596 }
597
598 pub fn parse_drop_procedure_statement(
600 &mut self,
601 ) -> Result<vibesql_ast::DropProcedureStmt, ParseError> {
602 self.advance(); self.advance(); self.parse_drop_procedure()
605 }
606
607 pub fn parse_create_function_statement(
609 &mut self,
610 ) -> Result<vibesql_ast::CreateFunctionStmt, ParseError> {
611 self.advance(); self.advance(); self.parse_create_function()
614 }
615
616 pub fn parse_drop_function_statement(
618 &mut self,
619 ) -> Result<vibesql_ast::DropFunctionStmt, ParseError> {
620 self.advance(); self.advance(); self.parse_drop_function()
623 }
624
625 pub fn parse_call_statement(&mut self) -> Result<vibesql_ast::CallStmt, ParseError> {
627 self.advance(); self.parse_call()
629 }
630}