mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-25 08:24:05 +00:00
Refactoring
This commit is contained in:
parent
375671e208
commit
a86bd30515
6 changed files with 101 additions and 338 deletions
204
src/parser.rs
204
src/parser.rs
|
@ -1,6 +1,5 @@
|
|||
use std::cmp::PartialEq;
|
||||
use std::fmt::Debug;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::tokenizer::*;
|
||||
|
||||
|
@ -8,7 +7,7 @@ use super::tokenizer::*;
|
|||
|
||||
/// ANSI SQL:2011 Data Types
|
||||
#[derive(Debug)]
|
||||
pub enum SQLDataType<T> {
|
||||
pub enum SQLDataType {
|
||||
/// BOOLEAN
|
||||
Boolean,
|
||||
/// NUMERIC, DECIMAL, DEC
|
||||
|
@ -49,14 +48,12 @@ pub enum SQLDataType<T> {
|
|||
Time { precision: usize, tz: bool },
|
||||
/// Time: `TIMESTAMP [(precision)] [WITH TIME ZONE | WITHOUT TIME ZONE]`
|
||||
Timestamp { precision: usize, tz: bool },
|
||||
/// Custom data type
|
||||
Custom(T)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SQLOperator<T> {
|
||||
pub enum SQLOperator {
|
||||
Plus,
|
||||
Minus,
|
||||
Mult,
|
||||
|
@ -66,217 +63,44 @@ pub enum SQLOperator<T> {
|
|||
GtEq,
|
||||
Lt,
|
||||
LtEq,
|
||||
Custom(T) // extension point for vendor-specific operators
|
||||
}
|
||||
|
||||
/// SQL Expressions
|
||||
#[derive(Debug)]
|
||||
pub enum SQLExpr<ExprType> {
|
||||
pub enum SQLExpr{
|
||||
/// Identifier e.g. table name or column name
|
||||
Identifier(String),
|
||||
/// Literal value
|
||||
Literal(String),
|
||||
/// Binary expression e.g. `1 + 2` or `fname LIKE "A%"`
|
||||
Binary(Box<SQLExpr<ExprType>>, SQLOperator<ExprType>, Box<SQLExpr<ExprType>>),
|
||||
Binary(Box<SQLExpr>, SQLOperator, Box<SQLExpr>),
|
||||
/// Function invocation with function name and list of argument expressions
|
||||
FunctionCall(String, Vec<SQLExpr<ExprType>>),
|
||||
FunctionCall(String, Vec<SQLExpr>),
|
||||
Insert,
|
||||
Update,
|
||||
Delete,
|
||||
Select,
|
||||
CreateTable,
|
||||
/// Custom expression (vendor-specific)
|
||||
Custom(ExprType)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ParserError<TokenType>
|
||||
where TokenType: Debug + PartialEq {
|
||||
WrongToken { expected: Vec<SQLToken<TokenType>>, actual: SQLToken<TokenType>, line: usize, col: usize },
|
||||
pub enum ParserError {
|
||||
WrongToken { expected: Vec<SQLToken>, actual: SQLToken, line: usize, col: usize },
|
||||
Custom(String)
|
||||
}
|
||||
|
||||
impl<TokenType> From<TokenizerError> for ParserError<TokenType>
|
||||
where TokenType: Debug + PartialEq {
|
||||
|
||||
fn from(_: TokenizerError) -> Self {
|
||||
unimplemented!()
|
||||
impl From<TokenizerError> for ParserError {
|
||||
fn from(e: TokenizerError) -> Self {
|
||||
ParserError::Custom(format!("{:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait SQLParser<TokenType, ExprType>
|
||||
where TokenType: Debug + PartialEq, ExprType: Debug {
|
||||
|
||||
pub trait SQLParser {
|
||||
fn parse_expr(&mut self) -> Result<Option<Box<SQLExpr>>, ParserError>;
|
||||
/// parse the prefix and stop once an infix operator is reached
|
||||
fn parse_prefix(&mut self, chars: &mut CharSeq) -> Result<Option<Box<SQLExpr<ExprType>>>, ParserError<TokenType>> ;
|
||||
fn parse_prefix(&mut self) -> Result<Option<Box<SQLExpr>>, ParserError> ;
|
||||
/// parse the next infix expression, returning None if the precedence has changed
|
||||
fn parse_infix(&mut self, chars: &mut CharSeq, left: &SQLExpr<ExprType>, precedence: usize) -> Result<Option<Box<SQLExpr<ExprType>>>, ParserError<TokenType>>;
|
||||
fn parse_infix(&mut self, left: &SQLExpr, precedence: usize) -> Result<Option<Box<SQLExpr>>, ParserError>;
|
||||
}
|
||||
|
||||
pub struct PrattParser<TokenType, ExprType> {
|
||||
pub chars: CharSeq,
|
||||
pub parsers: Vec<Arc<Mutex<SQLParser<TokenType, ExprType>>>>
|
||||
}
|
||||
|
||||
impl<TokenType, ExprType> PrattParser<TokenType, ExprType> where TokenType: Debug + PartialEq, ExprType: Debug {
|
||||
|
||||
pub fn parse_expr(&mut self) -> Result<Option<Box<SQLExpr<ExprType>>>, ParserError<TokenType>> {
|
||||
|
||||
for i in 0..self.parsers.len() {
|
||||
let mut p = self.parsers[i].lock().unwrap();
|
||||
let expr = p.parse_prefix(&mut self.chars)?;
|
||||
|
||||
// return as soon as we have a match
|
||||
match expr {
|
||||
Some(_) => return Ok(expr),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// found no valid token
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//pub fn parse_expr<'a, TokenType, ExprType>(parser: Arc<Mutex<SQLParser<TokenType, ExprType>>>)
|
||||
// -> Result<Box<SQLExpr<ExprType>>, ParserError<TokenType>> where TokenType: Debug + PartialEq, ExprType: Debug {
|
||||
// let mut guard = parser.lock().unwrap();
|
||||
//
|
||||
// //Result<Box<SQLExpr<ExprType>>, ParserError<TokenType>>
|
||||
// let x = guard.parse_prefix();
|
||||
// x
|
||||
//}
|
||||
|
||||
|
||||
//impl<'a, TokenType, ExprType> PrattParser<'a, TokenType, ExprType>
|
||||
// where TokenType: Debug + PartialEq, ExprType: Debug {
|
||||
//
|
||||
// pub fn parse_expr(&mut self) -> Result<Box<SQLExpr<ExprType>>, ParserError<TokenType>> {
|
||||
//
|
||||
// let precedence: usize = 0;
|
||||
// let parser_ref = self.parser.as_ref();
|
||||
//
|
||||
// let mut expr = parser_ref.parse_prefix()?;
|
||||
//
|
||||
// while let Some(token) = self.tokenizer.peek_token(&mut self.chars)? {
|
||||
//
|
||||
// let next_precedence = self.tokenizer.precedence(&token);
|
||||
//
|
||||
// if precedence >= next_precedence {
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// expr = parser_ref.parse_infix(&expr, next_precedence)?.unwrap(); //TODO: fix me
|
||||
// }
|
||||
//
|
||||
// Ok(expr)
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
// fn parse_prefix(&mut self) -> Result<Box<SQLExpr>, ParserError> {
|
||||
//
|
||||
// match self.tokenizer.peek_token()? {
|
||||
// Some(SQLToken::Keyword(ref k)) => match k.to_uppercase().as_ref() {
|
||||
// "INSERT" => unimplemented!(),
|
||||
// "UPDATE" => unimplemented!(),
|
||||
// "DELETE" => unimplemented!(),
|
||||
// "SELECT" => unimplemented!(),
|
||||
// "CREATE" => unimplemented!(),
|
||||
// _ => unimplemented!()
|
||||
// },
|
||||
// _ => unimplemented!()
|
||||
// }
|
||||
// unimplemented!()
|
||||
// }
|
||||
//
|
||||
// fn parse_infix(&mut self, expr: Box<SQLExpr>, precedence: u8) -> Result<Box<SQLExpr>, ParserError> {
|
||||
//
|
||||
// match self.tokenizer.next_token()? {
|
||||
// Some(tok) => {
|
||||
// match tok {
|
||||
// SQLToken::Eq | SQLToken::Gt | SQLToken::GtEq |
|
||||
// SQLToken::Lt | SQLToken::LtEq => Ok(Box::new(SQLExpr::Binary(
|
||||
// expr,
|
||||
// self.to_sql_operator(&tok),
|
||||
// self.parse_expr(precedence)?
|
||||
// ))),
|
||||
// _ => Err(ParserError::WrongToken {
|
||||
// expected: vec![SQLToken::Eq, SQLToken::Gt], //TODO: complete
|
||||
// actual: tok,
|
||||
// line: 0,
|
||||
// col: 0
|
||||
// })
|
||||
// }
|
||||
// },
|
||||
// None => Err(ParserError::TBD)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fn to_sql_operator(&self, token: &SQLToken) -> SQLOperator {
|
||||
// unimplemented!()
|
||||
// }
|
||||
//
|
||||
// fn get_precedence(&self, token: &SQLToken) -> u8 {
|
||||
// unimplemented!()
|
||||
// }
|
||||
//
|
||||
// /// parse a list of SQL expressions separated by a comma
|
||||
// fn parse_expr_list(&mut self, precedence: u8) -> Result<Vec<SQLExpr>, ParserError> {
|
||||
// unimplemented!()
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
////impl GenericParser {
|
||||
////
|
||||
//// fn tokenizer(&mut self) -> &mut SQLTokenizer {
|
||||
//// &mut self.tokenizer
|
||||
//// }
|
||||
////
|
||||
//// fn parse_keywords(&mut self, keywords: Vec<&str>) -> Result<bool, ParserError> {
|
||||
//// unimplemented!()
|
||||
//// }
|
||||
////
|
||||
////// fn parse_identifier(&mut self) -> Result<String, ParserError>;
|
||||
////
|
||||
////}
|
||||
//
|
||||
|
||||
//
|
||||
//
|
||||
//#[cfg(test)]
|
||||
//mod tests {
|
||||
//
|
||||
// use super::SQLToken::*;
|
||||
// use super::*;
|
||||
// #[test]
|
||||
// fn parse_Acme_create_table() {
|
||||
//
|
||||
// // CREATE TABLE test (col1 int8) HASH (col1)
|
||||
// let tokens = vec![
|
||||
// k("CREATE"), k("TABLE"), i("test"), LParen,
|
||||
// i("col1"), k("int8"),
|
||||
// RParen,
|
||||
// k("HASH"), LParen, i("col1"), RParen
|
||||
// ];
|
||||
//
|
||||
// //let parser = AcmeParser { generic_parser: }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fn k(s: &str) -> SQLToken {
|
||||
// Keyword(s.to_string())
|
||||
// }
|
||||
//
|
||||
// fn i(s: &str) -> SQLToken {
|
||||
// Identifier(s.to_string())
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue