use sql_dialect_fmt_syntax::SyntaxKind::*;
use crate::parser::{ContextualKeyword, Parser};
pub(in crate::grammar) fn at_delta_stmt_start(p: &Parser) -> bool {
at_command_word(p) || at_describe_history(p)
}
fn at_command_word(p: &Parser) -> bool {
let cmd = p.nth_contextual(0, ContextualKeyword::Vacuum)
|| p.nth_contextual(0, ContextualKeyword::Optimize)
|| p.nth_contextual(0, ContextualKeyword::Cache)
|| p.nth_contextual(0, ContextualKeyword::Uncache)
|| p.nth_contextual(0, ContextualKeyword::Refresh);
cmd && at_command_operand(p, 1)
}
fn at_command_operand(p: &Parser, n: usize) -> bool {
p.nth_at(n, IDENT)
|| p.nth_at(n, QUOTED_IDENT)
|| p.nth_at(n, STRING)
|| p.nth_at(n, TABLE_KW)
|| p.nth_at(n, IF_KW)
|| p.nth_contextual(n, ContextualKeyword::Lazy)
}
pub(in crate::grammar) fn at_describe_history(p: &Parser) -> bool {
(p.at(DESCRIBE_KW) || p.at(DESC_KW)) && p.nth_contextual(1, ContextualKeyword::History)
}
pub(in crate::grammar) fn delta_stmt(p: &mut Parser) {
if at_describe_history(p) {
describe_history_stmt(p);
} else if p.nth_contextual(0, ContextualKeyword::Vacuum) {
vacuum_stmt(p);
} else if p.nth_contextual(0, ContextualKeyword::Optimize) {
optimize_stmt(p);
} else if p.nth_contextual(0, ContextualKeyword::Uncache) {
uncache_stmt(p);
} else if p.nth_contextual(0, ContextualKeyword::Cache) {
cache_stmt(p);
} else if p.nth_contextual(0, ContextualKeyword::Refresh) {
refresh_stmt(p);
} else {
super::expr(p);
}
}
fn table_or_path(p: &mut Parser) {
if p.at(STRING) {
let m = p.start();
p.bump(STRING);
m.complete(p, NAME_REF);
} else if p.at_name() {
super::name_ref(p);
} else {
p.error("expected a table name or path");
}
}
fn vacuum_stmt(p: &mut Parser) {
let m = p.start();
p.bump_as(CONTEXTUAL_KEYWORD); table_or_path(p);
if p.nth_contextual(0, ContextualKeyword::Retain) {
p.bump_as(CONTEXTUAL_KEYWORD); if super::at_expr_start(p) {
super::expr(p); } else {
p.error("expected a retention duration after RETAIN");
}
if p.nth_contextual(0, ContextualKeyword::Hours) {
p.bump_as(CONTEXTUAL_KEYWORD); } else {
p.error("expected HOURS after the retention duration");
}
}
if p.nth_contextual(0, ContextualKeyword::Dry) {
p.bump_as(CONTEXTUAL_KEYWORD); if p.nth_contextual(0, ContextualKeyword::Run) {
p.bump_as(CONTEXTUAL_KEYWORD); } else {
p.error("expected RUN after DRY");
}
}
m.complete(p, VACUUM_STMT);
}
fn optimize_stmt(p: &mut Parser) {
let m = p.start();
p.bump_as(CONTEXTUAL_KEYWORD); table_or_path(p);
if p.at(WHERE_KW) {
super::where_clause(p);
}
if p.nth_contextual(0, ContextualKeyword::Zorder) {
zorder_clause(p);
}
m.complete(p, OPTIMIZE_STMT);
}
fn zorder_clause(p: &mut Parser) {
let m = p.start();
p.bump_as(CONTEXTUAL_KEYWORD); p.expect(BY_KW);
if p.at(L_PAREN) {
super::column_list(p);
} else {
p.error("expected '(' after ZORDER BY");
}
m.complete(p, ZORDER_CLAUSE);
}
fn cache_stmt(p: &mut Parser) {
let m = p.start();
p.bump_as(CONTEXTUAL_KEYWORD); if p.nth_contextual(0, ContextualKeyword::Lazy) {
p.bump_as(CONTEXTUAL_KEYWORD); }
p.expect(TABLE_KW);
table_or_path(p);
if p.nth_contextual(0, ContextualKeyword::Options) {
p.bump_as(CONTEXTUAL_KEYWORD); if p.at(L_PAREN) {
super::balanced_parens(p);
} else {
p.error("expected '(' after OPTIONS");
}
}
p.eat(AS_KW);
if at_cache_query(p) {
super::query_expr(p);
}
m.complete(p, CACHE_STMT);
}
fn at_cache_query(p: &Parser) -> bool {
p.at(SELECT_KW)
|| p.at(WITH_KW)
|| p.at(VALUES_KW)
|| p.at(TABLE_KW)
|| p.at(FROM_KW)
|| (p.at(L_PAREN) && (p.nth_at(1, SELECT_KW) || p.nth_at(1, WITH_KW)))
}
fn uncache_stmt(p: &mut Parser) {
let m = p.start();
p.bump_as(CONTEXTUAL_KEYWORD); p.expect(TABLE_KW);
if p.at(IF_KW) {
p.bump(IF_KW);
p.expect(EXISTS_KW);
}
table_or_path(p);
m.complete(p, UNCACHE_STMT);
}
fn refresh_stmt(p: &mut Parser) {
let m = p.start();
p.bump_as(CONTEXTUAL_KEYWORD); p.eat(TABLE_KW);
table_or_path(p);
m.complete(p, REFRESH_STMT);
}
fn describe_history_stmt(p: &mut Parser) {
let m = p.start();
p.bump_any(); p.bump_as(CONTEXTUAL_KEYWORD); if p.at_name() || p.at(STRING) {
table_or_path(p);
}
while !super::at_stmt_terminator(p) {
p.bump_any();
}
m.complete(p, DESCRIBE_HISTORY_STMT);
}