Skip to content

Commit 7bc304c

Browse files
SQLite: Parse & and | at the same precedence (#2683)
1 parent 3d27cf7 commit 7bc304c

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

‎src/dialect/sqlite.rs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ use alloc::boxed::Box;
2020

2121
use crate::ast::BinaryOperator;
2222
use crate::ast::{Expr, Statement};
23-
use crate::dialect::Dialect;
23+
use crate::dialect::{Dialect, Precedence};
2424
use crate::keywords::Keyword;
2525
use crate::parser::{Parser, ParserError};
26+
use crate::tokenizer::Token;
2627

2728
/// A [`Dialect`] for [SQLite](https://www.sqlite.org)
2829
///
@@ -97,6 +98,15 @@ impl Dialect for SQLiteDialect {
9798
None
9899
}
99100

101+
/// `&` and `|` share one left-associative precedence level.
102+
/// See <https://www.sqlite.org/lang_expr.html#operators_and_parse_affecting_attributes>
103+
fn get_next_precedence(&self, parser: &Parser) -> Option<Result<u8, ParserError>> {
104+
match parser.peek_token_ref().token {
105+
Token::Ampersand | Token::Pipe => Some(Ok(self.prec_value(Precedence::Ampersand))),
106+
_ => None,
107+
}
108+
}
109+
100110
fn supports_in_empty_list(&self) -> bool {
101111
true
102112
}

‎tests/sqlparser_sqlite.rs‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,3 +1186,63 @@ fn test_dollar_sign_in_identifier() {
11861186
.parse_sql_statements("SELECT a$ FROM t")
11871187
.unwrap_err();
11881188
}
1189+
1190+
#[test]
1191+
fn parse_bitwise_and_or_share_precedence() {
1192+
fn num(n: &str) -> Expr {
1193+
Expr::value(number(n))
1194+
}
1195+
fn bin(left: Expr, op: BinaryOperator, right: Expr) -> Expr {
1196+
Expr::BinaryOp {
1197+
left: Box::new(left),
1198+
op,
1199+
right: Box::new(right),
1200+
}
1201+
}
1202+
use BinaryOperator::{BitwiseAnd, BitwiseOr, Eq, Multiply, Plus};
1203+
1204+
for (sql, expected) in [
1205+
(
1206+
"6 | 1 & 3",
1207+
bin(bin(num("6"), BitwiseOr, num("1")), BitwiseAnd, num("3")),
1208+
),
1209+
(
1210+
"6 & 3 | 8",
1211+
bin(bin(num("6"), BitwiseAnd, num("3")), BitwiseOr, num("8")),
1212+
),
1213+
(
1214+
"1 & 2 & 3",
1215+
bin(bin(num("1"), BitwiseAnd, num("2")), BitwiseAnd, num("3")),
1216+
),
1217+
(
1218+
"1 | 2 | 3",
1219+
bin(bin(num("1"), BitwiseOr, num("2")), BitwiseOr, num("3")),
1220+
),
1221+
(
1222+
"1 | 2 + 3 & 4 * 5",
1223+
bin(
1224+
bin(num("1"), BitwiseOr, bin(num("2"), Plus, num("3"))),
1225+
BitwiseAnd,
1226+
bin(num("4"), Multiply, num("5")),
1227+
),
1228+
),
1229+
(
1230+
"6 | (1 & 3)",
1231+
bin(
1232+
num("6"),
1233+
BitwiseOr,
1234+
Expr::Nested(Box::new(bin(num("1"), BitwiseAnd, num("3")))),
1235+
),
1236+
),
1237+
(
1238+
"1 | 2 = 3 & 4",
1239+
bin(
1240+
bin(num("1"), BitwiseOr, num("2")),
1241+
Eq,
1242+
bin(num("3"), BitwiseAnd, num("4")),
1243+
),
1244+
),
1245+
] {
1246+
assert_eq!(sqlite().verified_expr(sql), expected, "{sql}");
1247+
}
1248+
}

0 commit comments

Comments
 (0)