Skip to content

Commit 4ffcab4

Browse files
committed
Support nested expressions in BETWEEN
`BETWEEN <thing> AND <thing>` allows <thing> to be any expr that doesn't contain boolean operators. (Allowing boolean operators would wreak havoc, because of the repurposing of AND as both a boolean operation and part of the syntax of BETWEEN.)
1 parent 4f944dd commit 4ffcab4

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/sqlparser.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,10 @@ impl Parser {
478478

479479
/// Parses `BETWEEN <low> AND <high>`, assuming the `BETWEEN` keyword was already consumed
480480
pub fn parse_between(&mut self, expr: ASTNode, negated: bool) -> Result<ASTNode, ParserError> {
481-
let low = self.parse_prefix()?;
481+
let prec = self.get_precedence(&Token::make_keyword("BETWEEN"))?;
482+
let low = self.parse_subexpr(prec)?;
482483
self.expect_keyword("AND")?;
483-
let high = self.parse_prefix()?;
484+
let high = self.parse_subexpr(prec)?;
484485
Ok(ASTNode::SQLBetween {
485486
expr: Box::new(expr),
486487
negated,

tests/sqlparser_common.rs

+27
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,33 @@ fn parse_between() {
450450
chk(true);
451451
}
452452

453+
#[test]
454+
fn parse_between_with_expr() {
455+
use self::ASTNode::*;
456+
use self::SQLOperator::*;
457+
let sql = "SELECT * FROM t WHERE 1 BETWEEN 1 + 2 AND 3 + 4 IS NULL";
458+
let select = verified_only_select(sql);
459+
let low = SQLBinaryExpr {
460+
left: Box::new(ASTNode::SQLValue(Value::Long(1))),
461+
op: Plus,
462+
right: Box::new(ASTNode::SQLValue(Value::Long(2))),
463+
};
464+
let high = SQLBinaryExpr {
465+
left: Box::new(ASTNode::SQLValue(Value::Long(3))),
466+
op: Plus,
467+
right: Box::new(ASTNode::SQLValue(Value::Long(4))),
468+
};
469+
assert_eq!(
470+
ASTNode::SQLIsNull(Box::new(ASTNode::SQLBetween {
471+
expr: Box::new(ASTNode::SQLValue(Value::Long(1))),
472+
low: Box::new(low),
473+
high: Box::new(high),
474+
negated: false,
475+
})),
476+
select.selection.unwrap()
477+
);
478+
}
479+
453480
#[test]
454481
fn parse_select_order_by() {
455482
fn chk(sql: &str) {

0 commit comments

Comments
 (0)