Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2578,6 +2578,23 @@ pub enum TableVersion {
/// When the table version is defined using a function.
/// For example: `SELECT * FROM tbl AT(TIMESTAMP => '2020-08-14 09:30:00')`
Function(Expr),
/// Snowflake CHANGES clause for change tracking queries.
/// For example:
/// ```sql
/// SELECT * FROM t
/// CHANGES(INFORMATION => DEFAULT)
/// AT(TIMESTAMP => TO_TIMESTAMP_TZ('...'))
/// END(TIMESTAMP => TO_TIMESTAMP_TZ('...'))
/// ```
/// <https://docs.snowflake.com/en/sql-reference/constructs/changes>
Changes {
/// The `CHANGES(INFORMATION => ...)` function-call expression.
changes: Expr,
/// The `AT(TIMESTAMP => ...)` function-call expression.
at: Expr,
/// The optional `END(TIMESTAMP => ...)` function-call expression.
end: Option<Expr>,
},
}

impl Display for TableVersion {
Expand All @@ -2587,6 +2604,12 @@ impl Display for TableVersion {
TableVersion::TimestampAsOf(e) => write!(f, "TIMESTAMP AS OF {e}")?,
TableVersion::VersionAsOf(e) => write!(f, "VERSION AS OF {e}")?,
TableVersion::Function(func) => write!(f, "{func}")?,
TableVersion::Changes { changes, at, end } => {
write!(f, "{changes} {at}")?;
if let Some(end) = end {
write!(f, " {end}")?;
}
}
}
Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ define_keywords!(
CENTURY,
CHAIN,
CHANGE,
CHANGES,
CHANGE_TRACKING,
CHANNEL,
CHAR,
Expand Down
14 changes: 14 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16275,6 +16275,20 @@ impl<'a> Parser<'a> {
{
let expr = self.parse_expr()?;
return Ok(Some(TableVersion::ForSystemTimeAsOf(expr)));
} else if self.peek_keyword(Keyword::CHANGES) {
// Snowflake CHANGES clause:
// CHANGES(INFORMATION => ...) AT(...) [END(...)]
let changes_name = self.parse_object_name(true)?;
let changes = self.parse_function(changes_name)?;
let at_name = self.parse_object_name(true)?;
let at = self.parse_function(at_name)?;
let end = if self.peek_keyword(Keyword::END) {
let end_name = self.parse_object_name(true)?;
Some(self.parse_function(end_name)?)
} else {
None
};
return Ok(Some(TableVersion::Changes { changes, at, end }));
} else if self.peek_keyword(Keyword::AT) || self.peek_keyword(Keyword::BEFORE) {
let func_name = self.parse_object_name(true)?;
let func = self.parse_function(func_name)?;
Expand Down
26 changes: 26 additions & 0 deletions tests/sqlparser_snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3963,6 +3963,32 @@ fn test_timetravel_at_before() {
.verified_only_select("SELECT * FROM tbl BEFORE(TIMESTAMP => '2024-12-15 00:00:00')");
}

#[test]
fn test_changes_clause() {
// CHANGES with AT and END
snowflake().verified_stmt(
"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'))",
);

// CHANGES with AT only (no END)
snowflake().verified_stmt(
"SELECT a FROM t CHANGES(INFORMATION => DEFAULT) AT(TIMESTAMP => TO_TIMESTAMP_TZ('2026-02-18 11:23:19.660000000'))",
);

// CHANGES with APPEND_ONLY
snowflake().verified_stmt(
"SELECT a FROM t CHANGES(INFORMATION => APPEND_ONLY) AT(TIMESTAMP => TO_TIMESTAMP_TZ('2026-01-01 00:00:00'))",
);

// CHANGES with OFFSET
snowflake().verified_stmt("SELECT a FROM t CHANGES(INFORMATION => DEFAULT) AT(OFFSET => -60)");

// CHANGES with STATEMENT
snowflake().verified_stmt(
"SELECT a FROM t CHANGES(INFORMATION => DEFAULT) AT(STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726')",
);
}

#[test]
fn test_grant_account_global_privileges() {
let privileges = vec![
Expand Down