fix: unary negation operator with operators: Mul, Div and Mod (#902)

This commit is contained in:
Igor Izvekov 2023-06-22 18:15:31 +03:00 committed by GitHub
parent f72b5a5d9b
commit 8877cbafa6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 6 deletions

View file

@ -799,7 +799,7 @@ impl<'a> Parser<'a> {
}; };
Ok(Expr::UnaryOp { Ok(Expr::UnaryOp {
op, op,
expr: Box::new(self.parse_subexpr(Self::PLUS_MINUS_PREC)?), expr: Box::new(self.parse_subexpr(Self::MUL_DIV_MOD_OP_PREC)?),
}) })
} }
tok @ Token::DoubleExclamationMark tok @ Token::DoubleExclamationMark
@ -1964,6 +1964,7 @@ impl<'a> Parser<'a> {
} }
// use https://www.postgresql.org/docs/7.0/operators.htm#AEN2026 as a reference // use https://www.postgresql.org/docs/7.0/operators.htm#AEN2026 as a reference
const MUL_DIV_MOD_OP_PREC: u8 = 40;
const PLUS_MINUS_PREC: u8 = 30; const PLUS_MINUS_PREC: u8 = 30;
const XOR_PREC: u8 = 24; const XOR_PREC: u8 = 24;
const TIME_ZONE_PREC: u8 = 20; const TIME_ZONE_PREC: u8 = 20;
@ -1974,8 +1975,6 @@ impl<'a> Parser<'a> {
const AND_PREC: u8 = 10; const AND_PREC: u8 = 10;
const OR_PREC: u8 = 5; const OR_PREC: u8 = 5;
const DIV_OP_PREC: u8 = 40;
/// Get the precedence of the next token /// Get the precedence of the next token
pub fn get_next_precedence(&self) -> Result<u8, ParserError> { pub fn get_next_precedence(&self) -> Result<u8, ParserError> {
// allow the dialect to override precedence logic // allow the dialect to override precedence logic
@ -2025,7 +2024,7 @@ impl<'a> Parser<'a> {
Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(Self::LIKE_PREC), Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(Self::LIKE_PREC),
Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(Self::LIKE_PREC), Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(Self::LIKE_PREC),
Token::Word(w) if w.keyword == Keyword::OPERATOR => Ok(Self::BETWEEN_PREC), Token::Word(w) if w.keyword == Keyword::OPERATOR => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::DIV => Ok(Self::DIV_OP_PREC), Token::Word(w) if w.keyword == Keyword::DIV => Ok(Self::MUL_DIV_MOD_OP_PREC),
Token::Eq Token::Eq
| Token::Lt | Token::Lt
| Token::LtEq | Token::LtEq
@ -2043,7 +2042,7 @@ impl<'a> Parser<'a> {
Token::Ampersand => Ok(23), Token::Ampersand => Ok(23),
Token::Plus | Token::Minus => Ok(Self::PLUS_MINUS_PREC), Token::Plus | Token::Minus => Ok(Self::PLUS_MINUS_PREC),
Token::Mul | Token::Div | Token::DuckIntDiv | Token::Mod | Token::StringConcat => { Token::Mul | Token::Div | Token::DuckIntDiv | Token::Mod | Token::StringConcat => {
Ok(40) Ok(Self::MUL_DIV_MOD_OP_PREC)
} }
Token::DoubleColon => Ok(50), Token::DoubleColon => Ok(50),
Token::Colon => Ok(50), Token::Colon => Ok(50),

View file

@ -1074,7 +1074,7 @@ fn parse_compound_expr_2() {
} }
#[test] #[test]
fn parse_unary_math() { fn parse_unary_math_with_plus() {
use self::Expr::*; use self::Expr::*;
let sql = "-a + -b"; let sql = "-a + -b";
assert_eq!( assert_eq!(
@ -1093,6 +1093,26 @@ fn parse_unary_math() {
); );
} }
#[test]
fn parse_unary_math_with_multiply() {
use self::Expr::*;
let sql = "-a * -b";
assert_eq!(
BinaryOp {
left: Box::new(UnaryOp {
op: UnaryOperator::Minus,
expr: Box::new(Identifier(Ident::new("a"))),
}),
op: BinaryOperator::Multiply,
right: Box::new(UnaryOp {
op: UnaryOperator::Minus,
expr: Box::new(Identifier(Ident::new("b"))),
}),
},
verified_expr(sql)
);
}
#[test] #[test]
fn parse_is_null() { fn parse_is_null() {
use self::Expr::*; use self::Expr::*;