Skip to content

Commit d80f9f3

Browse files
authored
Merge pull request #80 from benesch/between-expr
Support nested expressions in BETWEEN
2 parents 646479e + ba21ce9 commit d80f9f3

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/sqlparser.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -508,9 +508,12 @@ impl Parser {
508508

509509
/// Parses `BETWEEN <low> AND <high>`, assuming the `BETWEEN` keyword was already consumed
510510
pub fn parse_between(&mut self, expr: ASTNode, negated: bool) -> Result<ASTNode, ParserError> {
511-
let low = self.parse_prefix()?;
511+
// Stop parsing subexpressions for <low> and <high> on tokens with
512+
// precedence lower than that of `BETWEEN`, such as `AND`, `IS`, etc.
513+
let prec = self.get_precedence(&Token::make_keyword("BETWEEN"))?;
514+
let low = self.parse_subexpr(prec)?;
512515
self.expect_keyword("AND")?;
513-
let high = self.parse_prefix()?;
516+
let high = self.parse_subexpr(prec)?;
514517
Ok(ASTNode::SQLBetween {
515518
expr: Box::new(expr),
516519
negated,

tests/sqlparser_common.rs

+49
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,55 @@ fn parse_between() {
497497
chk(true);
498498
}
499499

500+
#[test]
501+
fn parse_between_with_expr() {
502+
use self::ASTNode::*;
503+
use self::SQLOperator::*;
504+
let sql = "SELECT * FROM t WHERE 1 BETWEEN 1 + 2 AND 3 + 4 IS NULL";
505+
let select = verified_only_select(sql);
506+
assert_eq!(
507+
ASTNode::SQLIsNull(Box::new(ASTNode::SQLBetween {
508+
expr: Box::new(ASTNode::SQLValue(Value::Long(1))),
509+
low: Box::new(SQLBinaryExpr {
510+
left: Box::new(ASTNode::SQLValue(Value::Long(1))),
511+
op: Plus,
512+
right: Box::new(ASTNode::SQLValue(Value::Long(2))),
513+
}),
514+
high: Box::new(SQLBinaryExpr {
515+
left: Box::new(ASTNode::SQLValue(Value::Long(3))),
516+
op: Plus,
517+
right: Box::new(ASTNode::SQLValue(Value::Long(4))),
518+
}),
519+
negated: false,
520+
})),
521+
select.selection.unwrap()
522+
);
523+
524+
let sql = "SELECT * FROM t WHERE 1 = 1 AND 1 + x BETWEEN 1 AND 2";
525+
let select = verified_only_select(sql);
526+
assert_eq!(
527+
ASTNode::SQLBinaryExpr {
528+
left: Box::new(ASTNode::SQLBinaryExpr {
529+
left: Box::new(ASTNode::SQLValue(Value::Long(1))),
530+
op: SQLOperator::Eq,
531+
right: Box::new(ASTNode::SQLValue(Value::Long(1))),
532+
}),
533+
op: SQLOperator::And,
534+
right: Box::new(ASTNode::SQLBetween {
535+
expr: Box::new(ASTNode::SQLBinaryExpr {
536+
left: Box::new(ASTNode::SQLValue(Value::Long(1))),
537+
op: SQLOperator::Plus,
538+
right: Box::new(ASTNode::SQLIdentifier("x".to_string())),
539+
}),
540+
low: Box::new(ASTNode::SQLValue(Value::Long(1))),
541+
high: Box::new(ASTNode::SQLValue(Value::Long(2))),
542+
negated: false,
543+
}),
544+
},
545+
select.selection.unwrap(),
546+
)
547+
}
548+
500549
#[test]
501550
fn parse_select_order_by() {
502551
fn chk(sql: &str) {

0 commit comments

Comments
 (0)