Skip to content

Commit c375ae2

Browse files
committed
bq: handle interval parsing
1 parent e9ae6bb commit c375ae2

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

src/ast/value.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub enum Value {
4343
/// so the user will have to reject intervals like `HOUR TO YEAR`.
4444
Interval {
4545
value: String,
46+
value_quoting: Option<char>,
4647
leading_field: Option<DateTimeField>,
4748
leading_precision: Option<u64>,
4849
last_field: Option<DateTimeField>,
@@ -66,6 +67,7 @@ impl fmt::Display for Value {
6667
Value::Boolean(v) => write!(f, "{}", v),
6768
Value::Interval {
6869
value,
70+
value_quoting,
6971
leading_field: Some(DateTimeField::Second),
7072
leading_precision: Some(leading_precision),
7173
last_field,
@@ -74,22 +76,32 @@ impl fmt::Display for Value {
7476
// When the leading field is SECOND, the parser guarantees that
7577
// the last field is None.
7678
assert!(last_field.is_none());
79+
write!(f, "INTERVAL ")?;
80+
if let Some(ch) = value_quoting {
81+
write!(f, "{}{}{}", ch, escape_single_quote_string(value), ch)?;
82+
} else {
83+
write!(f, "{}", value)?;
84+
}
7785
write!(
7886
f,
79-
"INTERVAL '{}' SECOND ({}, {})",
80-
escape_single_quote_string(value),
81-
leading_precision,
82-
fractional_seconds_precision
87+
" SECOND ({}, {})",
88+
leading_precision, fractional_seconds_precision
8389
)
8490
}
8591
Value::Interval {
8692
value,
93+
value_quoting,
8794
leading_field,
8895
leading_precision,
8996
last_field,
9097
fractional_seconds_precision,
9198
} => {
92-
write!(f, "INTERVAL '{}'", escape_single_quote_string(value))?;
99+
write!(f, "INTERVAL ")?;
100+
if let Some(ch) = value_quoting {
101+
write!(f, "{}{}{}", ch, escape_single_quote_string(value), ch)?;
102+
} else {
103+
write!(f, "{}", value)?;
104+
}
93105
if let Some(leading_field) = leading_field {
94106
write!(f, " {}", leading_field)?;
95107
}

src/parser.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,13 @@ impl<'a> Parser<'a> {
719719

720720
// The first token in an interval is a string literal which specifies
721721
// the duration of the interval.
722-
let value = self.parse_literal_string()?;
722+
let (value, value_quoting) = if dialect_of!(self is BigQueryDialect) {
723+
// in BigQuery, the value is not quoted
724+
// https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions
725+
(self.parse_expr()?.to_string(), None)
726+
} else {
727+
(self.parse_literal_string()?, Some('\''))
728+
};
723729

724730
// Following the string literal is a qualifier which indicates the units
725731
// of the duration specified in the string literal.
@@ -771,6 +777,7 @@ impl<'a> Parser<'a> {
771777

772778
Ok(Expr::Value(Value::Interval {
773779
value,
780+
value_quoting,
774781
leading_field,
775782
leading_precision,
776783
last_field,

0 commit comments

Comments
 (0)