Skip to content

Commit ce74e7f

Browse files
JamesVorderiffyio
andauthored
Databricks: Support Timetravel With "TIMESTAMP AS OF" (#2134)
Co-authored-by: Ifeanyi Ubah <[email protected]>
1 parent 4de1ac9 commit ce74e7f

File tree

5 files changed

+28
-1
lines changed

5 files changed

+28
-1
lines changed

src/ast/query.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,10 @@ pub enum TableVersion {
22412241
/// When the table version is defined using `FOR SYSTEM_TIME AS OF`.
22422242
/// For example: `SELECT * FROM tbl FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)`
22432243
ForSystemTimeAsOf(Expr),
2244+
/// When the table version is defined using `TIMESTAMP AS OF`.
2245+
/// Databricks supports this syntax.
2246+
/// For example: `SELECT * FROM tbl TIMESTAMP AS OF CURRENT_TIMESTAMP() - INTERVAL 1 HOUR`
2247+
TimestampAsOf(Expr),
22442248
/// When the table version is defined using a function.
22452249
/// For example: `SELECT * FROM tbl AT(TIMESTAMP => '2020-08-14 09:30:00')`
22462250
Function(Expr),
@@ -2250,6 +2254,7 @@ impl Display for TableVersion {
22502254
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22512255
match self {
22522256
TableVersion::ForSystemTimeAsOf(e) => write!(f, "FOR SYSTEM_TIME AS OF {e}")?,
2257+
TableVersion::TimestampAsOf(e) => write!(f, "TIMESTAMP AS OF {e}")?,
22532258
TableVersion::Function(func) => write!(f, "{func}")?,
22542259
}
22552260
Ok(())

src/dialect/databricks.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ impl Dialect for DatabricksDialect {
4747
true
4848
}
4949

50+
/// <https://docs.databricks.com/gcp/en/delta/history#delta-time-travel-syntax>
51+
fn supports_timestamp_versioning(&self) -> bool {
52+
true
53+
}
54+
5055
fn supports_lambda_functions(&self) -> bool {
5156
true
5257
}

src/parser/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15493,6 +15493,9 @@ impl<'a> Parser<'a> {
1549315493
let func_name = self.parse_object_name(true)?;
1549415494
let func = self.parse_function(func_name)?;
1549515495
return Ok(Some(TableVersion::Function(func)));
15496+
} else if self.parse_keywords(&[Keyword::TIMESTAMP, Keyword::AS, Keyword::OF]) {
15497+
let expr = self.parse_expr()?;
15498+
return Ok(Some(TableVersion::TimestampAsOf(expr)));
1549615499
}
1549715500
}
1549815501
Ok(None)

tests/sqlparser_bigquery.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1739,7 +1739,7 @@ fn parse_table_time_travel() {
17391739
args: None,
17401740
with_hints: vec![],
17411741
version: Some(TableVersion::ForSystemTimeAsOf(Expr::Value(
1742-
Value::SingleQuotedString(version).with_empty_span()
1742+
Value::SingleQuotedString(version.clone()).with_empty_span()
17431743
))),
17441744
partitions: vec![],
17451745
with_ordinality: false,

tests/sqlparser_databricks.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,17 @@ fn data_type_timestamp_ntz() {
366366
s => panic!("Unexpected statement: {s:?}"),
367367
}
368368
}
369+
370+
#[test]
371+
fn parse_table_time_travel() {
372+
all_dialects_where(|d| d.supports_timestamp_versioning())
373+
.verified_only_select("SELECT 1 FROM t1 TIMESTAMP AS OF '2018-10-18T22:15:12.013Z'");
374+
375+
all_dialects_where(|d| d.supports_timestamp_versioning()).verified_only_select(
376+
"SELECT 1 FROM t1 TIMESTAMP AS OF CURRENT_TIMESTAMP() - INTERVAL 12 HOURS",
377+
);
378+
379+
assert!(databricks()
380+
.parse_sql_statements("SELECT 1 FROM t1 FOR TIMESTAMP AS OF 'some_timestamp'")
381+
.is_err());
382+
}

0 commit comments

Comments
 (0)