From 4d91f19ab296ee18620c54d563808e2525e8effe Mon Sep 17 00:00:00 2001 From: TcMits Date: Fri, 15 Aug 2025 17:05:28 +0700 Subject: [PATCH] rebase --- parser/src/ast.rs | 13 ---- parser/src/lexer.rs | 36 +++++------ parser/src/parser.rs | 148 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 31 deletions(-) diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 0b442489d..55184d990 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -1201,19 +1201,6 @@ pub enum ResolveType { Replace, } -impl ResolveType { - /// Get the OE_XXX bit value - pub fn bit_value(&self) -> usize { - match self { - ResolveType::Rollback => 1, - ResolveType::Abort => 2, - ResolveType::Fail => 3, - ResolveType::Ignore => 4, - ResolveType::Replace => 5, - } - } -} - /// `WITH` clause // https://sqlite.org/lang_with.html // https://sqlite.org/syntax/with-clause.html diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index 0f31cfe1b..714378221 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -142,7 +142,7 @@ impl<'a> Lexer<'a> { Some(b'_') => { if start == self.offset { // before the underscore, there was no digit - return Err(Error::BadNumber((self.offset, 1).into())); + return Err(Error::BadNumber((start, self.offset - start).into())); } self.eat_and_assert(|b| b == b'_'); @@ -150,7 +150,7 @@ impl<'a> Lexer<'a> { Some(b) if b.is_ascii_digit() => continue, // Continue if next is a digit _ => { // after the underscore, there is no digit - return Err(Error::BadNumber((self.offset, 1).into())); + return Err(Error::BadNumber((start, self.offset - start).into())); } } } @@ -167,7 +167,7 @@ impl<'a> Lexer<'a> { Some(b'_') => { if start == self.offset { // before the underscore, there was no digit - return Err(Error::BadNumber((self.offset, 1).into())); + return Err(Error::BadNumber((start, self.offset - start).into())); } self.eat_and_assert(|b| b == b'_'); @@ -175,7 +175,7 @@ impl<'a> Lexer<'a> { Some(b) if b.is_ascii_hexdigit() => continue, // Continue if next is a digit _ => { // after the underscore, there is no digit - return Err(Error::BadNumber((self.offset, 1).into())); + return Err(Error::BadNumber((start, self.offset - start).into())); } } } @@ -260,14 +260,14 @@ impl<'a> Lexer<'a> { } None => { return Err(Error::UnterminatedBlockComment( - (self.offset, 1).into(), + (start, self.offset - start).into(), )) } _ => {} } } None => { - return Err(Error::UnterminatedBlockComment((self.offset, 1).into())) + return Err(Error::UnterminatedBlockComment((start, self.offset - start).into())) } _ => unreachable!(), // We should not reach here } @@ -362,7 +362,7 @@ impl<'a> Lexer<'a> { Some(b'=') => { self.eat_and_assert(|b| b == b'='); } - _ => return Err(Error::ExpectedEqualsSign((self.offset, 1).into())), + _ => return Err(Error::ExpectedEqualsSign((start, self.offset - start).into())), } Ok(Token { @@ -411,7 +411,7 @@ impl<'a> Lexer<'a> { _ => break, } } - None => return Err(Error::UnterminatedLiteral((self.offset, 1).into())), + None => return Err(Error::UnterminatedLiteral((start, self.offset - start).into())), _ => unreachable!(), }; } @@ -438,7 +438,7 @@ impl<'a> Lexer<'a> { }) } Some(b) if is_identifier_start(b) => { - Err(Error::BadFractionalPart((self.offset, 1).into())) + Err(Error::BadFractionalPart((start, self.offset - start).into())) } _ => Ok(Token { value: &self.input[start..self.offset], @@ -466,11 +466,11 @@ impl<'a> Lexer<'a> { let start_num = self.offset; self.eat_while_number_digit()?; if start_num == self.offset { - return Err(Error::BadExponentPart((self.offset, 1).into())); + return Err(Error::BadExponentPart((start, self.offset - start).into())); } if self.peek().is_some() && is_identifier_start(self.peek().unwrap()) { - return Err(Error::BadExponentPart((self.offset, 1).into())); + return Err(Error::BadExponentPart((start, self.offset - start).into())); } Ok(Token { @@ -499,7 +499,7 @@ impl<'a> Lexer<'a> { } if self.peek().is_some() && is_identifier_start(self.peek().unwrap()) { - return Err(Error::BadNumber((self.offset, 1).into())); + return Err(Error::BadNumber((start, self.offset - start).into())); } return Ok(Token { @@ -527,7 +527,7 @@ impl<'a> Lexer<'a> { token_type: Some(TokenType::TK_FLOAT), }) } - Some(b) if is_identifier_start(b) => Err(Error::BadNumber((self.offset, 1).into())), + Some(b) if is_identifier_start(b) => Err(Error::BadNumber((start, self.offset - start).into())), _ => Ok(Token { value: &self.input[start..self.offset], token_type: Some(TokenType::TK_INTEGER), @@ -547,7 +547,7 @@ impl<'a> Lexer<'a> { token_type: Some(TokenType::TK_ID), }) } - None => Err(Error::UnterminatedBracket((self.offset, 1).into())), + None => Err(Error::UnterminatedBracket((start, self.offset - start).into())), _ => unreachable!(), // We should not reach here } } @@ -564,7 +564,7 @@ impl<'a> Lexer<'a> { // empty variable name if start_digit == self.offset { - return Err(Error::BadVariableName((self.offset, 1).into())); + return Err(Error::BadVariableName((start, self.offset - start).into())); } Ok(Token { @@ -578,7 +578,7 @@ impl<'a> Lexer<'a> { // empty variable name if start_id == self.offset { - return Err(Error::BadVariableName((self.offset, 1).into())); + return Err(Error::BadVariableName((start, self.offset - start).into())); } Ok(Token { @@ -608,7 +608,7 @@ impl<'a> Lexer<'a> { self.eat_and_assert(|b| b == b'\''); if (end_hex - start_hex) % 2 != 0 { - return Err(Error::UnrecognizedToken((self.offset, 1).into())); + return Err(Error::UnrecognizedToken((start, self.offset - start).into())); } Ok(Token { @@ -616,7 +616,7 @@ impl<'a> Lexer<'a> { token_type: Some(TokenType::TK_BLOB), }) } - _ => Err(Error::UnterminatedLiteral((self.offset, 1).into())), + _ => Err(Error::UnterminatedLiteral((start, self.offset - start).into())), } } _ => { diff --git a/parser/src/parser.rs b/parser/src/parser.rs index de94e912c..56c9a3f23 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -5622,6 +5622,154 @@ mod tests { }))], ), // parse expr + ( + b"SELECT 1 NOT NULL AND 1".as_slice(), + vec![Cmd::Stmt(Stmt::Select(Select { + with: None, + body: SelectBody { + select: OneSelect::Select { + distinctness: None, + columns: vec![ResultColumn::Expr( + Box::new(Expr::Binary ( + Box::new(Expr::NotNull( + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + )), + Operator::And, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + )), + None, + )], + from: None, + where_clause: None, + group_by: None, + window_clause: vec![], + }, + compounds: vec![], + }, + order_by: vec![], + limit: None, + }))], + ), + ( + b"SELECT 1 IS 1 AND 1".as_slice(), + vec![Cmd::Stmt(Stmt::Select(Select { + with: None, + body: SelectBody { + select: OneSelect::Select { + distinctness: None, + columns: vec![ResultColumn::Expr( + Box::new(Expr::Binary ( + Box::new(Expr::Binary ( + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + Operator::Is, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))) + )), + Operator::And, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + )), + None, + )], + from: None, + where_clause: None, + group_by: None, + window_clause: vec![], + }, + compounds: vec![], + }, + order_by: vec![], + limit: None, + }))], + ), + ( + b"SELECT 1 IS NOT 1 AND 1".as_slice(), + vec![Cmd::Stmt(Stmt::Select(Select { + with: None, + body: SelectBody { + select: OneSelect::Select { + distinctness: None, + columns: vec![ResultColumn::Expr( + Box::new(Expr::Binary ( + Box::new(Expr::Binary ( + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + Operator::IsNot, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))) + )), + Operator::And, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + )), + None, + )], + from: None, + where_clause: None, + group_by: None, + window_clause: vec![], + }, + compounds: vec![], + }, + order_by: vec![], + limit: None, + }))], + ), + ( + b"SELECT 1 IS NOT DISTINCT FROM 1 AND 1".as_slice(), + vec![Cmd::Stmt(Stmt::Select(Select { + with: None, + body: SelectBody { + select: OneSelect::Select { + distinctness: None, + columns: vec![ResultColumn::Expr( + Box::new(Expr::Binary ( + Box::new(Expr::Binary ( + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + Operator::Is, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))) + )), + Operator::And, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + )), + None, + )], + from: None, + where_clause: None, + group_by: None, + window_clause: vec![], + }, + compounds: vec![], + }, + order_by: vec![], + limit: None, + }))], + ), + ( + b"SELECT 1 IS DISTINCT FROM 1 AND 1".as_slice(), + vec![Cmd::Stmt(Stmt::Select(Select { + with: None, + body: SelectBody { + select: OneSelect::Select { + distinctness: None, + columns: vec![ResultColumn::Expr( + Box::new(Expr::Binary ( + Box::new(Expr::Binary ( + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + Operator::IsNot, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))) + )), + Operator::And, + Box::new(Expr::Literal(Literal::Numeric("1".to_owned()))), + )), + None, + )], + from: None, + where_clause: None, + group_by: None, + window_clause: vec![], + }, + compounds: vec![], + }, + order_by: vec![], + limit: None, + }))], + ), ( b"SELECT 1 + 2 * 3".as_slice(), vec![Cmd::Stmt(Stmt::Select(Select {