Skip to content

Commit 7850a2d

Browse files
JamesVorderayman-sigma
authored andcommitted
Databricks: Support Timetravel With "VERSION AS OF" (apache#2155)
1 parent 88dfec7 commit 7850a2d

8 files changed

Lines changed: 23 additions & 8 deletions

File tree

src/ast/query.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,6 +2411,10 @@ pub enum TableVersion {
24112411
/// Databricks supports this syntax.
24122412
/// For example: `SELECT * FROM tbl TIMESTAMP AS OF CURRENT_TIMESTAMP() - INTERVAL 1 HOUR`
24132413
TimestampAsOf(Expr),
2414+
/// When the table version is defined using `VERSION AS OF`.
2415+
/// Databricks supports this syntax.
2416+
/// For example: `SELECT * FROM tbl VERSION AS OF 2`
2417+
VersionAsOf(Expr),
24142418
/// When the table version is defined using a function.
24152419
/// For example: `SELECT * FROM tbl AT(TIMESTAMP => '2020-08-14 09:30:00')`
24162420
Function(Expr),
@@ -2421,6 +2425,7 @@ impl Display for TableVersion {
24212425
match self {
24222426
TableVersion::ForSystemTimeAsOf(e) => write!(f, "FOR SYSTEM_TIME AS OF {e}")?,
24232427
TableVersion::TimestampAsOf(e) => write!(f, "TIMESTAMP AS OF {e}")?,
2428+
TableVersion::VersionAsOf(e) => write!(f, "VERSION AS OF {e}")?,
24242429
TableVersion::Function(func) => write!(f, "{func}")?,
24252430
}
24262431
Ok(())

src/dialect/bigquery.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl Dialect for BigQueryDialect {
136136
}
137137

138138
// See <https://cloud.google.com/bigquery/docs/access-historical-data>
139-
fn supports_timestamp_versioning(&self) -> bool {
139+
fn supports_table_versioning(&self) -> bool {
140140
true
141141
}
142142

src/dialect/databricks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl Dialect for DatabricksDialect {
6363
}
6464

6565
/// <https://docs.databricks.com/gcp/en/delta/history#delta-time-travel-syntax>
66-
fn supports_timestamp_versioning(&self) -> bool {
66+
fn supports_table_versioning(&self) -> bool {
6767
true
6868
}
6969

src/dialect/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ pub trait Dialect: Debug + Any {
10771077

10781078
/// Returns true if this dialect supports querying historical table data
10791079
/// by specifying which version of the data to query.
1080-
fn supports_timestamp_versioning(&self) -> bool {
1080+
fn supports_table_versioning(&self) -> bool {
10811081
false
10821082
}
10831083

src/dialect/mssql.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Dialect for MsSqlDialect {
107107
}
108108

109109
/// See: <https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table>
110-
fn supports_timestamp_versioning(&self) -> bool {
110+
fn supports_table_versioning(&self) -> bool {
111111
true
112112
}
113113

src/dialect/snowflake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ impl Dialect for SnowflakeDialect {
540540
}
541541

542542
/// See: <https://docs.snowflake.com/en/sql-reference/constructs/at-before>
543-
fn supports_timestamp_versioning(&self) -> bool {
543+
fn supports_table_versioning(&self) -> bool {
544544
true
545545
}
546546

src/parser/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15763,7 +15763,7 @@ impl<'a> Parser<'a> {
1576315763

1576415764
/// Parses a the timestamp version specifier (i.e. query historical data)
1576515765
pub fn maybe_parse_table_version(&mut self) -> Result<Option<TableVersion>, ParserError> {
15766-
if self.dialect.supports_timestamp_versioning() {
15766+
if self.dialect.supports_table_versioning() {
1576715767
if self.parse_keywords(&[Keyword::FOR, Keyword::SYSTEM_TIME, Keyword::AS, Keyword::OF])
1576815768
{
1576915769
let expr = self.parse_expr()?;
@@ -15775,6 +15775,9 @@ impl<'a> Parser<'a> {
1577515775
} else if self.parse_keywords(&[Keyword::TIMESTAMP, Keyword::AS, Keyword::OF]) {
1577615776
let expr = self.parse_expr()?;
1577715777
return Ok(Some(TableVersion::TimestampAsOf(expr)));
15778+
} else if self.parse_keywords(&[Keyword::VERSION, Keyword::AS, Keyword::OF]) {
15779+
let expr = Expr::Value(self.parse_number_value()?);
15780+
return Ok(Some(TableVersion::VersionAsOf(expr)));
1577815781
}
1577915782
}
1578015783
Ok(None)

tests/sqlparser_databricks.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,14 +491,21 @@ fn parse_semi_structured_data_traversal() {
491491

492492
#[test]
493493
fn parse_table_time_travel() {
494-
all_dialects_where(|d| d.supports_timestamp_versioning())
494+
all_dialects_where(|d| d.supports_table_versioning())
495495
.verified_only_select("SELECT 1 FROM t1 TIMESTAMP AS OF '2018-10-18T22:15:12.013Z'");
496496

497-
all_dialects_where(|d| d.supports_timestamp_versioning()).verified_only_select(
497+
all_dialects_where(|d| d.supports_table_versioning()).verified_only_select(
498498
"SELECT 1 FROM t1 TIMESTAMP AS OF CURRENT_TIMESTAMP() - INTERVAL 12 HOURS",
499499
);
500500

501+
all_dialects_where(|d| d.supports_table_versioning())
502+
.verified_only_select("SELECT 1 FROM t1 VERSION AS OF 1");
503+
501504
assert!(databricks()
502505
.parse_sql_statements("SELECT 1 FROM t1 FOR TIMESTAMP AS OF 'some_timestamp'")
503506
.is_err());
507+
508+
assert!(all_dialects_where(|d| d.supports_table_versioning())
509+
.parse_sql_statements("SELECT 1 FROM t1 VERSION AS OF 1 - 2",)
510+
.is_err())
504511
}

0 commit comments

Comments
 (0)