Skip to content

Commit 8c8fe43

Browse files
committed
Update base on comments
1 parent 72e5fb4 commit 8c8fe43

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

src/ast/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2578,7 +2578,7 @@ pub enum TableVersion {
25782578
/// When the table version is defined using a function.
25792579
/// For example: `SELECT * FROM tbl AT(TIMESTAMP => '2020-08-14 09:30:00')`
25802580
Function(Expr),
2581-
/// Snowflake CHANGES clause for change tracking queries.
2581+
/// Snowflake `CHANGES` clause for change tracking queries.
25822582
/// For example:
25832583
/// ```sql
25842584
/// SELECT * FROM t

src/parser/mod.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16276,19 +16276,7 @@ impl<'a> Parser<'a> {
1627616276
let expr = self.parse_expr()?;
1627716277
return Ok(Some(TableVersion::ForSystemTimeAsOf(expr)));
1627816278
} else if self.peek_keyword(Keyword::CHANGES) {
16279-
// Snowflake CHANGES clause:
16280-
// CHANGES(INFORMATION => ...) AT(...) [END(...)]
16281-
let changes_name = self.parse_object_name(true)?;
16282-
let changes = self.parse_function(changes_name)?;
16283-
let at_name = self.parse_object_name(true)?;
16284-
let at = self.parse_function(at_name)?;
16285-
let end = if self.peek_keyword(Keyword::END) {
16286-
let end_name = self.parse_object_name(true)?;
16287-
Some(self.parse_function(end_name)?)
16288-
} else {
16289-
None
16290-
};
16291-
return Ok(Some(TableVersion::Changes { changes, at, end }));
16279+
return self.parse_table_version_changes().map(Some);
1629216280
} else if self.peek_keyword(Keyword::AT) || self.peek_keyword(Keyword::BEFORE) {
1629316281
let func_name = self.parse_object_name(true)?;
1629416282
let func = self.parse_function(func_name)?;
@@ -16304,6 +16292,30 @@ impl<'a> Parser<'a> {
1630416292
Ok(None)
1630516293
}
1630616294

16295+
/// Parses the Snowflake `CHANGES` clause for change tracking queries.
16296+
///
16297+
/// Syntax:
16298+
/// ```sql
16299+
/// CHANGES (INFORMATION => DEFAULT)
16300+
/// AT (TIMESTAMP => <expr>)
16301+
/// [END (TIMESTAMP => <expr>)]
16302+
/// ```
16303+
///
16304+
/// <https://docs.snowflake.com/en/sql-reference/constructs/changes>
16305+
fn parse_table_version_changes(&mut self) -> Result<TableVersion, ParserError> {
16306+
let changes_name = self.parse_object_name(true)?;
16307+
let changes = self.parse_function(changes_name)?;
16308+
let at_name = self.parse_object_name(true)?;
16309+
let at = self.parse_function(at_name)?;
16310+
let end = if self.peek_keyword(Keyword::END) {
16311+
let end_name = self.parse_object_name(true)?;
16312+
Some(self.parse_function(end_name)?)
16313+
} else {
16314+
None
16315+
};
16316+
Ok(TableVersion::Changes { changes, at, end })
16317+
}
16318+
1630716319
/// Parses MySQL's JSON_TABLE column definition.
1630816320
/// For example: `id INT EXISTS PATH '$' DEFAULT '0' ON EMPTY ERROR ON ERROR`
1630916321
pub fn parse_json_table_column_def(&mut self) -> Result<JsonTableColumn, ParserError> {

tests/sqlparser_snowflake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3967,7 +3967,7 @@ fn test_timetravel_at_before() {
39673967
fn test_changes_clause() {
39683968
// CHANGES with AT and END
39693969
snowflake().verified_stmt(
3970-
"SELECT a FROM \"PCH_ODS_FIDELIO\".\"SRC_VW_SYS_ACC_MASTER\" CHANGES(INFORMATION => DEFAULT) AT(TIMESTAMP => TO_TIMESTAMP_TZ('2026-02-18 11:23:19.660000000')) END(TIMESTAMP => TO_TIMESTAMP_TZ('2026-02-18 11:38:30.211000000'))",
3970+
r#"SELECT a FROM "PCH_ODS_FIDELIO"."SRC_VW_SYS_ACC_MASTER" CHANGES(INFORMATION => DEFAULT) AT(TIMESTAMP => TO_TIMESTAMP_TZ('2026-02-18 11:23:19.660000000')) END(TIMESTAMP => TO_TIMESTAMP_TZ('2026-02-18 11:38:30.211000000'))"#,
39713971
);
39723972

39733973
// CHANGES with AT only (no END)

0 commit comments

Comments
 (0)