Skip to content

Commit 4b67b56

Browse files
committed
fix: Correct INTERVAL + INTERVAL expression parsing
1 parent 19f730c commit 4b67b56

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ impl<'a> Parser<'a> {
10261026

10271027
// The first token in an interval is a string literal which specifies
10281028
// the duration of the interval.
1029-
let value = self.parse_expr()?;
1029+
let value = self.parse_subexpr(Self::PLUS_MINUS_PREC)?;
10301030

10311031
// Following the string literal is a qualifier which indicates the units
10321032
// of the duration specified in the string literal.

tests/sqlparser_common.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,59 @@ fn parse_literal_interval() {
27082708
);
27092709
}
27102710

2711+
#[test]
2712+
fn parse_interval_math() {
2713+
let sql = "SELECT INTERVAL '1 DAY' + INTERVAL '2 DAY'";
2714+
let select = verified_only_select(sql);
2715+
assert_eq!(
2716+
&Expr::BinaryOp {
2717+
left: Box::new(Expr::Value(Value::Interval {
2718+
value: Box::new(Expr::Value(Value::SingleQuotedString("1 DAY".to_string()))),
2719+
leading_field: None,
2720+
leading_precision: None,
2721+
last_field: None,
2722+
fractional_seconds_precision: None,
2723+
})),
2724+
op: BinaryOperator::Plus,
2725+
right: Box::new(Expr::Value(Value::Interval {
2726+
value: Box::new(Expr::Value(Value::SingleQuotedString("2 DAY".to_string()))),
2727+
leading_field: None,
2728+
leading_precision: None,
2729+
last_field: None,
2730+
fractional_seconds_precision: None,
2731+
})),
2732+
},
2733+
expr_from_projection(only(&select.projection)),
2734+
);
2735+
2736+
let sql = "SELECT INTERVAL '1' || ' DAY' + INTERVAL '2 DAY'";
2737+
let select = verified_only_select(sql);
2738+
assert_eq!(
2739+
&Expr::BinaryOp {
2740+
left: Box::new(Expr::Value(Value::Interval {
2741+
value: Box::new(Expr::BinaryOp {
2742+
left: Box::new(Expr::Value(Value::SingleQuotedString("1".to_string()))),
2743+
op: BinaryOperator::StringConcat,
2744+
right: Box::new(Expr::Value(Value::SingleQuotedString(" DAY".to_string()))),
2745+
}),
2746+
leading_field: None,
2747+
leading_precision: None,
2748+
last_field: None,
2749+
fractional_seconds_precision: None,
2750+
})),
2751+
op: BinaryOperator::Plus,
2752+
right: Box::new(Expr::Value(Value::Interval {
2753+
value: Box::new(Expr::Value(Value::SingleQuotedString("2 DAY".to_string()))),
2754+
leading_field: None,
2755+
leading_precision: None,
2756+
last_field: None,
2757+
fractional_seconds_precision: None,
2758+
})),
2759+
},
2760+
expr_from_projection(only(&select.projection)),
2761+
);
2762+
}
2763+
27112764
#[test]
27122765
fn parse_at_timezone() {
27132766
let zero = Expr::Value(number("0"));

0 commit comments

Comments
 (0)