You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by if...@apache.org on 2025/06/04 17:49:13 UTC
(datafusion-sqlparser-rs) branch main updated: Add ICEBERG keyword support to ALTER TABLE statement (#1869)
This is an automated email from the ASF dual-hosted git repository.
iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 5327f0ce Add ICEBERG keyword support to ALTER TABLE statement (#1869)
5327f0ce is described below
commit 5327f0ce132e12de71db7d03711397c5ac6c0031
Author: Artem Osipov <59...@users.noreply.github.com>
AuthorDate: Wed Jun 4 20:49:07 2025 +0300
Add ICEBERG keyword support to ALTER TABLE statement (#1869)
---
src/ast/mod.rs | 13 +++++++--
src/ast/spans.rs | 1 +
src/parser/mod.rs | 65 +++++++++++++++++++++++++-------------------
src/test_utils.rs | 2 ++
tests/sqlparser_mysql.rs | 8 +++---
tests/sqlparser_postgres.rs | 6 ++--
tests/sqlparser_snowflake.rs | 7 +++++
7 files changed, 64 insertions(+), 38 deletions(-)
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 653f58e4..711e580d 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -3281,6 +3281,9 @@ pub enum Statement {
/// For example: `ALTER TABLE table_name ON CLUSTER cluster_name ADD COLUMN c UInt32`
/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/alter/update)
on_cluster: Option<Ident>,
+ /// Snowflake "ICEBERG" clause for Iceberg tables
+ /// <https://docs.snowflake.com/en/sql-reference/sql/alter-iceberg-table>
+ iceberg: bool,
},
/// ```sql
/// ALTER INDEX
@@ -3405,7 +3408,7 @@ pub enum Statement {
purge: bool,
/// MySQL-specific "TEMPORARY" keyword
temporary: bool,
- /// MySQL-specific drop index syntax, which requires table specification
+ /// MySQL-specific drop index syntax, which requires table specification
/// See <https://dev.mysql.com/doc/refman/8.4/en/drop-index.html>
table: Option<ObjectName>,
},
@@ -5139,8 +5142,14 @@ impl fmt::Display for Statement {
operations,
location,
on_cluster,
+ iceberg,
} => {
- write!(f, "ALTER TABLE ")?;
+ if *iceberg {
+ write!(f, "ALTER ICEBERG TABLE ")?;
+ } else {
+ write!(f, "ALTER TABLE ")?;
+ }
+
if *if_exists {
write!(f, "IF EXISTS ")?;
}
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index d612738c..dd918c34 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -431,6 +431,7 @@ impl Spanned for Statement {
operations,
location: _,
on_cluster,
+ iceberg: _,
} => union_spans(
core::iter::once(name.span())
.chain(operations.iter().map(|i| i.span()))
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index a28540d1..3e721072 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -8893,38 +8893,15 @@ impl<'a> Parser<'a> {
Keyword::ROLE,
Keyword::POLICY,
Keyword::CONNECTOR,
+ Keyword::ICEBERG,
])?;
match object_type {
Keyword::VIEW => self.parse_alter_view(),
Keyword::TYPE => self.parse_alter_type(),
- Keyword::TABLE => {
- let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
- let only = self.parse_keyword(Keyword::ONLY); // [ ONLY ]
- let table_name = self.parse_object_name(false)?;
- let on_cluster = self.parse_optional_on_cluster()?;
- let operations = self.parse_comma_separated(Parser::parse_alter_table_operation)?;
-
- let mut location = None;
- if self.parse_keyword(Keyword::LOCATION) {
- location = Some(HiveSetLocation {
- has_set: false,
- location: self.parse_identifier()?,
- });
- } else if self.parse_keywords(&[Keyword::SET, Keyword::LOCATION]) {
- location = Some(HiveSetLocation {
- has_set: true,
- location: self.parse_identifier()?,
- });
- }
-
- Ok(Statement::AlterTable {
- name: table_name,
- if_exists,
- only,
- operations,
- location,
- on_cluster,
- })
+ Keyword::TABLE => self.parse_alter_table(false),
+ Keyword::ICEBERG => {
+ self.expect_keyword(Keyword::TABLE)?;
+ self.parse_alter_table(true)
}
Keyword::INDEX => {
let index_name = self.parse_object_name(false)?;
@@ -8952,6 +8929,38 @@ impl<'a> Parser<'a> {
}
}
+ /// Parse a [Statement::AlterTable]
+ pub fn parse_alter_table(&mut self, iceberg: bool) -> Result<Statement, ParserError> {
+ let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
+ let only = self.parse_keyword(Keyword::ONLY); // [ ONLY ]
+ let table_name = self.parse_object_name(false)?;
+ let on_cluster = self.parse_optional_on_cluster()?;
+ let operations = self.parse_comma_separated(Parser::parse_alter_table_operation)?;
+
+ let mut location = None;
+ if self.parse_keyword(Keyword::LOCATION) {
+ location = Some(HiveSetLocation {
+ has_set: false,
+ location: self.parse_identifier()?,
+ });
+ } else if self.parse_keywords(&[Keyword::SET, Keyword::LOCATION]) {
+ location = Some(HiveSetLocation {
+ has_set: true,
+ location: self.parse_identifier()?,
+ });
+ }
+
+ Ok(Statement::AlterTable {
+ name: table_name,
+ if_exists,
+ only,
+ operations,
+ location,
+ on_cluster,
+ iceberg,
+ })
+ }
+
pub fn parse_alter_view(&mut self) -> Result<Statement, ParserError> {
let name = self.parse_object_name(false)?;
let columns = self.parse_parenthesized_column_list(Optional, false)?;
diff --git a/src/test_utils.rs b/src/test_utils.rs
index 3c22fa91..24c0ca57 100644
--- a/src/test_utils.rs
+++ b/src/test_utils.rs
@@ -345,10 +345,12 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa
operations,
on_cluster: _,
location: _,
+ iceberg,
} => {
assert_eq!(name.to_string(), expected_name);
assert!(!if_exists);
assert!(!is_only);
+ assert!(!iceberg);
only(operations)
}
_ => panic!("Expected ALTER TABLE statement"),
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index 337707c9..0800c329 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -2507,11 +2507,13 @@ fn parse_alter_table_add_column() {
if_exists,
only,
operations,
+ iceberg,
location: _,
on_cluster: _,
} => {
assert_eq!(name.to_string(), "tab");
assert!(!if_exists);
+ assert!(!iceberg);
assert!(!only);
assert_eq!(
operations,
@@ -2536,8 +2538,7 @@ fn parse_alter_table_add_column() {
if_exists,
only,
operations,
- location: _,
- on_cluster: _,
+ ..
} => {
assert_eq!(name.to_string(), "tab");
assert!(!if_exists);
@@ -2574,8 +2575,7 @@ fn parse_alter_table_add_columns() {
if_exists,
only,
operations,
- location: _,
- on_cluster: _,
+ ..
} => {
assert_eq!(name.to_string(), "tab");
assert!(!if_exists);
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 682c0d6c..d54d4e2a 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -834,8 +834,7 @@ fn parse_alter_table_add_columns() {
if_exists,
only,
operations,
- location: _,
- on_cluster: _,
+ ..
} => {
assert_eq!(name.to_string(), "tab");
assert!(if_exists);
@@ -915,8 +914,7 @@ fn parse_alter_table_owner_to() {
if_exists: _,
only: _,
operations,
- location: _,
- on_cluster: _,
+ ..
} => {
assert_eq!(name.to_string(), "tab");
assert_eq!(
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index 52be3143..b4d62506 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -1591,6 +1591,13 @@ fn test_alter_table_clustering() {
snowflake_and_generic().verified_stmt("ALTER TABLE tbl RESUME RECLUSTER");
}
+#[test]
+fn test_alter_iceberg_table() {
+ snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl DROP CLUSTERING KEY");
+ snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl SUSPEND RECLUSTER");
+ snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl RESUME RECLUSTER");
+}
+
#[test]
fn test_drop_stage() {
match snowflake_and_generic().verified_stmt("DROP STAGE s1") {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org