mod operators;
mod precedence;
mod primary;
mod special;
use crate::error::{DbError, DbResult};
use crate::sdbql::ast::Expression;
use crate::sdbql::lexer::Token;
use crate::sdbql::parser::Parser;
impl Parser {
pub(crate) fn parse_expression(&mut self) -> DbResult<Expression> {
self.check_depth()?;
let result = self.parse_ternary_expression();
self.leave_depth();
result
}
}
impl Parser {
pub(super) fn parse_function_call_args(&mut self) -> DbResult<Vec<Expression>> {
let mut args = Vec::new();
while !matches!(self.current_token(), Token::RightParen | Token::Eof) {
args.push(self.parse_expression()?);
if matches!(self.current_token(), Token::Comma) {
self.advance();
} else {
break;
}
}
self.expect(Token::RightParen)?;
Ok(args)
}
pub(super) fn token_to_field_name(token: &Token) -> Option<String> {
match token {
Token::Identifier(name) => Some(name.clone()),
Token::Sort => Some("sort".to_string()),
Token::Count => Some("count".to_string()),
Token::Filter => Some("filter".to_string()),
Token::Return => Some("return".to_string()),
Token::In => Some("in".to_string()),
Token::For => Some("for".to_string()),
Token::Let => Some("let".to_string()),
Token::Limit => Some("limit".to_string()),
Token::Partition => Some("partition".to_string()),
Token::Over => Some("over".to_string()),
Token::Case => Some("case".to_string()),
Token::When => Some("when".to_string()),
Token::Then => Some("then".to_string()),
Token::Else => Some("else".to_string()),
Token::End => Some("end".to_string()),
Token::True => Some("true".to_string()),
Token::False => Some("false".to_string()),
Token::Null => Some("null".to_string()),
Token::And => Some("and".to_string()),
Token::Or => Some("or".to_string()),
Token::Not => Some("not".to_string()),
Token::Like => Some("like".to_string()),
Token::Insert => Some("insert".to_string()),
Token::Update => Some("update".to_string()),
Token::Remove => Some("remove".to_string()),
Token::Upsert => Some("upsert".to_string()),
Token::Into => Some("into".to_string()),
Token::With => Some("with".to_string()),
Token::Collect => Some("collect".to_string()),
Token::Aggregate => Some("aggregate".to_string()),
Token::Asc => Some("asc".to_string()),
Token::Desc => Some("desc".to_string()),
Token::Recursive => Some("recursive".to_string()),
Token::Replace => Some("replace".to_string()),
Token::Satisfies => Some("satisfies".to_string()),
Token::Outbound => Some("outbound".to_string()),
Token::Inbound => Some("inbound".to_string()),
Token::Any => Some("any".to_string()),
Token::ShortestPath => Some("shortest_path".to_string()),
Token::Graph => Some("graph".to_string()),
Token::To => Some("to".to_string()),
Token::Create => Some("create".to_string()),
Token::Stream => Some("stream".to_string()),
Token::As => Some("as".to_string()),
Token::Window => Some("window".to_string()),
Token::Tumbling => Some("tumbling".to_string()),
Token::Sliding => Some("sliding".to_string()),
Token::Size => Some("size".to_string()),
Token::Materialized => Some("materialized".to_string()),
Token::View => Some("view".to_string()),
Token::Refresh => Some("refresh".to_string()),
Token::Join => Some("join".to_string()),
Token::Left => Some("left".to_string()),
Token::Right => Some("right".to_string()),
Token::Full => Some("full".to_string()),
Token::Outer => Some("outer".to_string()),
Token::On => Some("on".to_string()),
_ => None,
}
}
pub(super) fn get_field_name(&self) -> Option<String> {
Self::token_to_field_name(self.current_token())
}
pub(super) fn parse_keyword_as_function(&mut self, name: &str) -> DbResult<Expression> {
self.advance();
if matches!(self.current_token(), Token::LeftParen) {
self.advance(); let args = self.parse_function_call_args()?;
if matches!(self.current_token(), Token::Over) {
return self.parse_window_function(name.to_string(), args);
}
Ok(Expression::FunctionCall {
name: name.to_string(),
args,
})
} else {
Err(DbError::ParseError(format!("Expected '(' after {}", name)))
}
}
pub(super) fn parse_keyword_as_function_no_window(
&mut self,
name: &str,
error_msg: &str,
) -> DbResult<Expression> {
self.advance();
if matches!(self.current_token(), Token::LeftParen) {
self.advance(); let args = self.parse_function_call_args()?;
Ok(Expression::FunctionCall {
name: name.to_string(),
args,
})
} else {
Err(DbError::ParseError(error_msg.to_string()))
}
}
}