Skip to content

Commit

Permalink
fix: Correct INTERVAL + INTERVAL expression parsing
Browse files Browse the repository at this point in the history
Recheck this after rebase on commit 57083a0 "Fix interval parsing logic and precedence (apache#705)", first released in 0.28.0
  • Loading branch information
MazterQyou authored and mcheshkov committed Sep 2, 2024
1 parent f342d66 commit 862e7a6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,7 @@ impl<'a> Parser<'a> {

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

// Following the string literal is a qualifier which indicates the units
// of the duration specified in the string literal.
Expand Down
53 changes: 53 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2863,6 +2863,59 @@ fn parse_literal_interval() {
);
}

#[test]
fn parse_interval_math() {
let sql = "SELECT INTERVAL '1 DAY' + INTERVAL '2 DAY'";
let select = verified_only_select(sql);
assert_eq!(
&Expr::BinaryOp {
left: Box::new(Expr::Value(Value::Interval {
value: Box::new(Expr::Value(Value::SingleQuotedString("1 DAY".to_string()))),
leading_field: None,
leading_precision: None,
last_field: None,
fractional_seconds_precision: None,
})),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(Value::Interval {
value: Box::new(Expr::Value(Value::SingleQuotedString("2 DAY".to_string()))),
leading_field: None,
leading_precision: None,
last_field: None,
fractional_seconds_precision: None,
})),
},
expr_from_projection(only(&select.projection)),
);

let sql = "SELECT INTERVAL '1' || ' DAY' + INTERVAL '2 DAY'";
let select = verified_only_select(sql);
assert_eq!(
&Expr::BinaryOp {
left: Box::new(Expr::Value(Value::Interval {
value: Box::new(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::SingleQuotedString("1".to_string()))),
op: BinaryOperator::StringConcat,
right: Box::new(Expr::Value(Value::SingleQuotedString(" DAY".to_string()))),
}),
leading_field: None,
leading_precision: None,
last_field: None,
fractional_seconds_precision: None,
})),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(Value::Interval {
value: Box::new(Expr::Value(Value::SingleQuotedString("2 DAY".to_string()))),
leading_field: None,
leading_precision: None,
last_field: None,
fractional_seconds_precision: None,
})),
},
expr_from_projection(only(&select.projection)),
);
}

#[test]
fn parse_at_timezone() {
let zero = Expr::Value(number("0"));
Expand Down

0 comments on commit 862e7a6

Please sign in to comment.