Skip to content

Commit 5fc1434

Browse files
MazterQyoumcheshkov
authored andcommitted
fix: Correct INTERVAL + INTERVAL expression parsing
Recheck this after rebase on commit 57083a0 "Fix interval parsing logic and precedence (apache#705)", first released in 0.28.0
1 parent 4fcaaeb commit 5fc1434

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
@@ -1095,7 +1095,7 @@ impl<'a> Parser<'a> {
10951095

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

11001100
// Following the string literal is a qualifier which indicates the units
11011101
// 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
@@ -2864,6 +2864,59 @@ fn parse_literal_interval() {
28642864
);
28652865
}
28662866

2867+
#[test]
2868+
fn parse_interval_math() {
2869+
let sql = "SELECT INTERVAL '1 DAY' + INTERVAL '2 DAY'";
2870+
let select = verified_only_select(sql);
2871+
assert_eq!(
2872+
&Expr::BinaryOp {
2873+
left: Box::new(Expr::Value(Value::Interval {
2874+
value: Box::new(Expr::Value(Value::SingleQuotedString("1 DAY".to_string()))),
2875+
leading_field: None,
2876+
leading_precision: None,
2877+
last_field: None,
2878+
fractional_seconds_precision: None,
2879+
})),
2880+
op: BinaryOperator::Plus,
2881+
right: Box::new(Expr::Value(Value::Interval {
2882+
value: Box::new(Expr::Value(Value::SingleQuotedString("2 DAY".to_string()))),
2883+
leading_field: None,
2884+
leading_precision: None,
2885+
last_field: None,
2886+
fractional_seconds_precision: None,
2887+
})),
2888+
},
2889+
expr_from_projection(only(&select.projection)),
2890+
);
2891+
2892+
let sql = "SELECT INTERVAL '1' || ' DAY' + INTERVAL '2 DAY'";
2893+
let select = verified_only_select(sql);
2894+
assert_eq!(
2895+
&Expr::BinaryOp {
2896+
left: Box::new(Expr::Value(Value::Interval {
2897+
value: Box::new(Expr::BinaryOp {
2898+
left: Box::new(Expr::Value(Value::SingleQuotedString("1".to_string()))),
2899+
op: BinaryOperator::StringConcat,
2900+
right: Box::new(Expr::Value(Value::SingleQuotedString(" DAY".to_string()))),
2901+
}),
2902+
leading_field: None,
2903+
leading_precision: None,
2904+
last_field: None,
2905+
fractional_seconds_precision: None,
2906+
})),
2907+
op: BinaryOperator::Plus,
2908+
right: Box::new(Expr::Value(Value::Interval {
2909+
value: Box::new(Expr::Value(Value::SingleQuotedString("2 DAY".to_string()))),
2910+
leading_field: None,
2911+
leading_precision: None,
2912+
last_field: None,
2913+
fractional_seconds_precision: None,
2914+
})),
2915+
},
2916+
expr_from_projection(only(&select.projection)),
2917+
);
2918+
}
2919+
28672920
#[test]
28682921
fn parse_at_timezone() {
28692922
let zero = Expr::Value(number("0"));

0 commit comments

Comments
 (0)