This commit is contained in:
TcMits
2025-08-15 17:05:28 +07:00
parent fb5203ce45
commit 4d91f19ab2
3 changed files with 166 additions and 31 deletions

View File

@@ -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

View File

@@ -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())),
}
}
_ => {

View File

@@ -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 {