use sql_dialect_fmt_syntax::SyntaxKind::*;
use crate::parser::{CompletedMarker, Parser};
mod access;
mod copy;
mod ddl;
mod delta;
mod dml;
mod expr;
mod match_recognize;
mod query;
mod scripting;
mod stage;
mod stmt;
use self::access::{grant_stmt, revoke_stmt};
use self::copy::{copy_option, copy_stmt, stage_ref};
use self::ddl::{alter_stmt, at_comment_stmt, comment_stmt, create_stmt, drop_stmt};
pub(crate) use self::expr::expr;
use self::expr::{
arg_list, at_expr_start, expr_bp, expr_list, partition_by_clause, type_name, window_spec,
BP_CMP,
};
use self::match_recognize::match_recognize;
use self::query::{
from_clause, order_by_clause, query_expr, select_item, subquery, table_ref, values_clause,
where_clause, with_query,
};
use self::scripting::{at_begin_transaction, at_block_start, block_stmt};
use self::stmt::call_stmt;
pub(crate) fn source_file(p: &mut Parser) {
let m = p.start();
while !p.at_eof() {
if p.at(SEMICOLON) {
p.bump(SEMICOLON); } else if stmt::at_stmt_start(p) {
stmt::statement_or_flow(p);
} else {
p.err_and_bump("expected a statement");
}
}
m.complete(p, SOURCE_FILE);
}
fn at_stmt_terminator(p: &Parser) -> bool {
p.at(SEMICOLON) || (p.dialect().supports_flow_operator() && p.at(FLOW_PIPE)) || p.at_eof()
}
fn name(p: &mut Parser) {
let m = p.start();
if p.at_name() {
p.bump_any();
} else {
p.error("expected a name");
}
m.complete(p, NAME);
}
fn name_ref(p: &mut Parser) -> CompletedMarker {
let m = p.start();
if p.at_name() {
p.bump_any();
while p.at(DOT) {
p.bump(DOT);
if p.at_name() {
p.bump_any();
} else if p.at(STAR) {
p.bump(STAR); break;
} else {
p.error("expected a name after '.'");
break;
}
}
} else {
p.error("expected a name");
}
m.complete(p, NAME_REF)
}
fn column_list(p: &mut Parser) {
let m = p.start();
p.bump(L_PAREN);
if p.at_name() {
name(p);
while p.eat(COMMA) {
if p.at(R_PAREN) {
break;
}
name(p);
}
}
p.expect(R_PAREN);
m.complete(p, COLUMN_LIST);
}
fn balanced_parens(p: &mut Parser) {
p.bump(L_PAREN);
let mut depth = 1u32;
while depth > 0 && !p.at_eof() {
if p.at(L_PAREN) {
depth += 1;
} else if p.at(R_PAREN) {
depth -= 1;
}
p.bump_any();
}
}
fn balanced_token_run_until(
p: &mut Parser,
stop: impl Fn(&Parser) -> bool,
mut bump_word: impl FnMut(&mut Parser),
) {
let mut depth = 0u32;
while !p.at_eof() {
if depth == 0 && stop(p) {
break;
}
if p.at(L_PAREN) {
depth += 1;
p.bump_any();
} else if p.at(R_PAREN) && depth > 0 {
depth -= 1;
p.bump_any();
} else {
bump_word(p);
}
}
}