Skip to content

Commit 5f0c7ff

Browse files
committed
Parse alter iceberg table
1 parent 7caf743 commit 5f0c7ff

File tree

5 files changed

+56
-29
lines changed

5 files changed

+56
-29
lines changed

src/ast/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2677,6 +2677,9 @@ pub enum Statement {
26772677
/// For example: `ALTER TABLE table_name ON CLUSTER cluster_name ADD COLUMN c UInt32`
26782678
/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/alter/update)
26792679
on_cluster: Option<Ident>,
2680+
/// Snowflake "ICEBERG" clause for Iceberg tables
2681+
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-iceberg-table>
2682+
iceberg: bool,
26802683
},
26812684
/// ```sql
26822685
/// ALTER INDEX
@@ -4448,8 +4451,13 @@ impl fmt::Display for Statement {
44484451
operations,
44494452
location,
44504453
on_cluster,
4454+
iceberg,
44514455
} => {
4452-
write!(f, "ALTER TABLE ")?;
4456+
if *iceberg {
4457+
write!(f, "ALTER ICEBERG TABLE ")?;
4458+
} else {
4459+
write!(f, "ALTER TABLE ")?;
4460+
}
44534461
if *if_exists {
44544462
write!(f, "IF EXISTS ")?;
44554463
}

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ impl Spanned for Statement {
410410
operations,
411411
location: _,
412412
on_cluster,
413+
iceberg: _,
413414
} => union_spans(
414415
core::iter::once(name.span())
415416
.chain(operations.iter().map(|i| i.span()))

src/parser/mod.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8221,39 +8221,16 @@ impl<'a> Parser<'a> {
82218221
Keyword::ROLE,
82228222
Keyword::POLICY,
82238223
Keyword::CONNECTOR,
8224+
Keyword::ICEBERG,
82248225
])?;
82258226
match object_type {
82268227
Keyword::VIEW => self.parse_alter_view(),
82278228
Keyword::TYPE => self.parse_alter_type(),
8228-
Keyword::TABLE => {
8229-
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
8230-
let only = self.parse_keyword(Keyword::ONLY); // [ ONLY ]
8231-
let table_name = self.parse_object_name(false)?;
8232-
let on_cluster = self.parse_optional_on_cluster()?;
8233-
let operations = self.parse_comma_separated(Parser::parse_alter_table_operation)?;
8234-
8235-
let mut location = None;
8236-
if self.parse_keyword(Keyword::LOCATION) {
8237-
location = Some(HiveSetLocation {
8238-
has_set: false,
8239-
location: self.parse_identifier()?,
8240-
});
8241-
} else if self.parse_keywords(&[Keyword::SET, Keyword::LOCATION]) {
8242-
location = Some(HiveSetLocation {
8243-
has_set: true,
8244-
location: self.parse_identifier()?,
8245-
});
8246-
}
8247-
8248-
Ok(Statement::AlterTable {
8249-
name: table_name,
8250-
if_exists,
8251-
only,
8252-
operations,
8253-
location,
8254-
on_cluster,
8255-
})
8229+
Keyword::ICEBERG => {
8230+
self.expect_keyword(Keyword::TABLE)?;
8231+
self.parse_alter_table(true)
82568232
}
8233+
Keyword::TABLE => self.parse_alter_table(false),
82578234
Keyword::INDEX => {
82588235
let index_name = self.parse_object_name(false)?;
82598236
let operation = if self.parse_keyword(Keyword::RENAME) {
@@ -8346,6 +8323,38 @@ impl<'a> Parser<'a> {
83468323
}
83478324
}
83488325

8326+
/// Parse a [Statement::AlterTable]
8327+
pub fn parse_alter_table(&mut self, iceberg: bool) -> Result<Statement, ParserError> {
8328+
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
8329+
let only = self.parse_keyword(Keyword::ONLY); // [ ONLY ]
8330+
let table_name = self.parse_object_name(false)?;
8331+
let on_cluster = self.parse_optional_on_cluster()?;
8332+
let operations = self.parse_comma_separated(Parser::parse_alter_table_operation)?;
8333+
8334+
let mut location = None;
8335+
if self.parse_keyword(Keyword::LOCATION) {
8336+
location = Some(HiveSetLocation {
8337+
has_set: false,
8338+
location: self.parse_identifier()?,
8339+
});
8340+
} else if self.parse_keywords(&[Keyword::SET, Keyword::LOCATION]) {
8341+
location = Some(HiveSetLocation {
8342+
has_set: true,
8343+
location: self.parse_identifier()?,
8344+
});
8345+
}
8346+
8347+
Ok(Statement::AlterTable {
8348+
name: table_name,
8349+
if_exists,
8350+
only,
8351+
operations,
8352+
location,
8353+
on_cluster,
8354+
iceberg,
8355+
})
8356+
}
8357+
83498358
/// Parse a `CALL procedure_name(arg1, arg2, ...)`
83508359
/// or `CALL procedure_name` statement
83518360
pub fn parse_call(&mut self) -> Result<Statement, ParserError> {

src/test_utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,12 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa
325325
operations,
326326
on_cluster: _,
327327
location: _,
328+
iceberg,
328329
} => {
329330
assert_eq!(name.to_string(), expected_name);
330331
assert!(!if_exists);
331332
assert!(!is_only);
333+
assert!(!iceberg);
332334
only(operations)
333335
}
334336
_ => panic!("Expected ALTER TABLE statement"),

tests/sqlparser_snowflake.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,13 @@ fn test_alter_table_clustering() {
15631563
snowflake_and_generic().verified_stmt("ALTER TABLE tbl RESUME RECLUSTER");
15641564
}
15651565

1566+
#[test]
1567+
fn test_alter_iceberg_table() {
1568+
snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl DROP CLUSTERING KEY");
1569+
snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl SUSPEND RECLUSTER");
1570+
snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl RESUME RECLUSTER");
1571+
}
1572+
15661573
#[test]
15671574
fn test_drop_stage() {
15681575
match snowflake_and_generic().verified_stmt("DROP STAGE s1") {

0 commit comments

Comments
 (0)