From 3c29c2e87268220e9415873332ce2a00d7be08d6 Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Thu, 30 Oct 2025 16:47:14 -0700 Subject: [PATCH 1/5] Added dynamic keyword parsing for snowflake --- src/ast/ddl.rs | 7 +++++ src/ast/spans.rs | 1 + src/dialect/snowflake.rs | 28 ++++++++++++++++++- src/keywords.rs | 1 + tests/sqlparser_snowflake.rs | 53 ++++++++++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index fd481213f..01bc785e3 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -365,6 +365,10 @@ pub enum AlterTableOperation { DropClusteringKey, SuspendRecluster, ResumeRecluster, + /// `REFRESH` + /// + /// Note: this is Snowflake specific for dynamic tables + Refresh, /// `ALGORITHM [=] { DEFAULT | INSTANT | INPLACE | COPY }` /// /// [MySQL]-specific table alter algorithm. @@ -845,6 +849,9 @@ impl fmt::Display for AlterTableOperation { write!(f, "RESUME RECLUSTER")?; Ok(()) } + AlterTableOperation::Refresh => { + write!(f, "REFRESH") + } AlterTableOperation::AutoIncrement { equals, value } => { write!( f, diff --git a/src/ast/spans.rs b/src/ast/spans.rs index 7d2a00095..8b758ccc6 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -1107,6 +1107,7 @@ impl Spanned for AlterTableOperation { AlterTableOperation::DropClusteringKey => Span::empty(), AlterTableOperation::SuspendRecluster => Span::empty(), AlterTableOperation::ResumeRecluster => Span::empty(), + AlterTableOperation::Refresh => Span::empty(), AlterTableOperation::Algorithm { .. } => Span::empty(), AlterTableOperation::AutoIncrement { value, .. } => value.span(), AlterTableOperation::Lock { .. } => Span::empty(), diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index 825fd45f0..e6485968d 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -26,7 +26,7 @@ use crate::ast::helpers::stmt_data_loading::{ FileStagingCommand, StageLoadSelectItem, StageLoadSelectItemKind, StageParamsObject, }; use crate::ast::{ - CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, ColumnPolicyProperty, ContactEntry, + AlterTableOperation, CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, ColumnPolicyProperty, ContactEntry, CopyIntoSnowflakeKind, CreateTableLikeKind, DollarQuotedString, Ident, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, InitializeKind, ObjectName, ObjectNamePart, RefreshModeKind, RowAccessPolicy, ShowObjects, @@ -214,6 +214,11 @@ impl Dialect for SnowflakeDialect { return Some(parser.parse_begin_exception_end()); } + if parser.parse_keywords(&[Keyword::ALTER, Keyword::DYNAMIC, Keyword::TABLE]) { + // ALTER DYNAMIC TABLE + return Some(parse_alter_dynamic_table(parser)); + } + if parser.parse_keywords(&[Keyword::ALTER, Keyword::SESSION]) { // ALTER SESSION let set = match parser.parse_one_of_keywords(&[Keyword::SET, Keyword::UNSET]) { @@ -604,6 +609,27 @@ fn parse_file_staging_command(kw: Keyword, parser: &mut Parser) -> Result +fn parse_alter_dynamic_table(parser: &mut Parser) -> Result { + let table_name = parser.parse_object_name(false)?; + + // Parse the operation (currently only REFRESH is supported) + if parser.parse_keyword(Keyword::REFRESH) { + Ok(Statement::AlterTable { + name: table_name, + if_exists: false, + only: false, + operations: vec![AlterTableOperation::Refresh], + location: None, + on_cluster: None, + iceberg: false, + }) + } else { + parser.expected("REFRESH after ALTER DYNAMIC TABLE", parser.peek_token()) + } +} + /// Parse snowflake alter session. /// fn parse_alter_session(parser: &mut Parser, set: bool) -> Result { diff --git a/src/keywords.rs b/src/keywords.rs index 319c57827..bed7b02a9 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -784,6 +784,7 @@ define_keywords!( REFERENCES, REFERENCING, REFRESH_MODE, + REFRESH, REGCLASS, REGEXP, REGION, diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index 2be5eae8c..fc2d18129 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -4662,3 +4662,56 @@ fn test_drop_constraints() { snowflake().verified_stmt("ALTER TABLE tbl DROP FOREIGN KEY k1 RESTRICT"); snowflake().verified_stmt("ALTER TABLE tbl DROP CONSTRAINT c1 CASCADE"); } + +#[test] +fn test_snowflake_alter_dynamic_table_refresh() { + // Test with simple table name + let sql = "ALTER DYNAMIC TABLE MY_DYNAMIC_TABLE REFRESH"; + let result = snowflake().parse_sql_statements(sql); + + assert!( + result.is_ok(), + "Expected ALTER DYNAMIC TABLE to parse successfully" + ); + + match result.unwrap().first().unwrap() { + Statement::AlterTable { + name, operations, .. + } => { + assert_eq!(name.to_string(), "MY_DYNAMIC_TABLE"); + assert_eq!(operations.len(), 1); + match &operations[0] { + AlterTableOperation::Refresh => { + // Success! + } + _ => panic!("Expected Refresh operation"), + } + } + _ => panic!("Expected AlterTable statement"), + } + + // Test with qualified table name + let sql3 = "ALTER DYNAMIC TABLE my_database.my_schema.my_dynamic_table REFRESH"; + let result3 = snowflake().parse_sql_statements(sql3); + + assert!( + result3.is_ok(), + "Expected ALTER DYNAMIC TABLE to parse successfully" + ); + + match result3.unwrap().first().unwrap() { + Statement::AlterTable { + name, operations, .. + } => { + assert_eq!(name.to_string(), "my_database.my_schema.my_dynamic_table"); + assert_eq!(operations.len(), 1); + match &operations[0] { + AlterTableOperation::Refresh => { + // Success! + } + _ => panic!("Expected Refresh operation"), + } + } + _ => panic!("Expected AlterTable statement"), + } +} From 07ae024eb6a594069f2e05d6bdbd232d1087d664 Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Wed, 15 Oct 2025 15:13:54 -0700 Subject: [PATCH 2/5] Added parsing of suspend and resume --- src/ast/ddl.rs | 19 +++++++++++++ src/ast/spans.rs | 2 ++ src/dialect/snowflake.rs | 49 ++++++++++++++++++++++---------- src/keywords.rs | 2 +- src/parser/mod.rs | 1 + tests/sqlparser_mysql.rs | 1 + tests/sqlparser_snowflake.rs | 55 ++++-------------------------------- 7 files changed, 63 insertions(+), 66 deletions(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 01bc785e3..ba218a0b4 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -369,6 +369,14 @@ pub enum AlterTableOperation { /// /// Note: this is Snowflake specific for dynamic tables Refresh, + /// `SUSPEND` + /// + /// Note: this is Snowflake specific for dynamic tables + Suspend, + /// `RESUME` + /// + /// Note: this is Snowflake specific for dynamic tables + Resume, /// `ALGORITHM [=] { DEFAULT | INSTANT | INPLACE | COPY }` /// /// [MySQL]-specific table alter algorithm. @@ -852,6 +860,12 @@ impl fmt::Display for AlterTableOperation { AlterTableOperation::Refresh => { write!(f, "REFRESH") } + AlterTableOperation::Suspend => { + write!(f, "SUSPEND") + } + AlterTableOperation::Resume => { + write!(f, "RESUME") + } AlterTableOperation::AutoIncrement { equals, value } => { write!( f, @@ -3558,6 +3572,9 @@ pub struct AlterTable { /// Snowflake "ICEBERG" clause for Iceberg tables /// pub iceberg: bool, + /// Snowflake "DYNAMIC" clause for Dynamic tables + /// + pub dynamic: bool, /// Token that represents the end of the statement (semicolon or EOF) pub end_token: AttachedToken, } @@ -3566,6 +3583,8 @@ impl fmt::Display for AlterTable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.iceberg { write!(f, "ALTER ICEBERG TABLE ")?; + } else if self.dynamic { + write!(f, "ALTER DYNAMIC TABLE ")?; } else { write!(f, "ALTER TABLE ")?; } diff --git a/src/ast/spans.rs b/src/ast/spans.rs index 8b758ccc6..573f31ba7 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -1108,6 +1108,8 @@ impl Spanned for AlterTableOperation { AlterTableOperation::SuspendRecluster => Span::empty(), AlterTableOperation::ResumeRecluster => Span::empty(), AlterTableOperation::Refresh => Span::empty(), + AlterTableOperation::Suspend => Span::empty(), + AlterTableOperation::Resume => Span::empty(), AlterTableOperation::Algorithm { .. } => Span::empty(), AlterTableOperation::AutoIncrement { value, .. } => value.span(), AlterTableOperation::Lock { .. } => Span::empty(), diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index e6485968d..7096ede9e 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -26,7 +26,7 @@ use crate::ast::helpers::stmt_data_loading::{ FileStagingCommand, StageLoadSelectItem, StageLoadSelectItemKind, StageParamsObject, }; use crate::ast::{ - AlterTableOperation, CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, ColumnPolicyProperty, ContactEntry, + AlterTable, AlterTableOperation, CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, ColumnPolicyProperty, ContactEntry, CopyIntoSnowflakeKind, CreateTableLikeKind, DollarQuotedString, Ident, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, InitializeKind, ObjectName, ObjectNamePart, RefreshModeKind, RowAccessPolicy, ShowObjects, @@ -34,6 +34,7 @@ use crate::ast::{ }; use crate::dialect::{Dialect, Precedence}; use crate::keywords::Keyword; +use crate::ast::helpers::attached_token::AttachedToken; use crate::parser::{IsOptional, Parser, ParserError}; use crate::tokenizer::Token; #[cfg(not(feature = "std"))] @@ -612,22 +613,40 @@ fn parse_file_staging_command(kw: Keyword, parser: &mut Parser) -> Result fn parse_alter_dynamic_table(parser: &mut Parser) -> Result { - let table_name = parser.parse_object_name(false)?; + // Use parse_object_name(true) to support IDENTIFIER() function + let table_name = parser.parse_object_name(true)?; + + // Parse the operation (REFRESH, SUSPEND, or RESUME) + let operation = if parser.parse_keyword(Keyword::REFRESH) { + AlterTableOperation::Refresh + } else if parser.parse_keyword(Keyword::SUSPEND) { + AlterTableOperation::Suspend + } else if parser.parse_keyword(Keyword::RESUME) { + AlterTableOperation::Resume + } else { + return parser.expected( + "REFRESH, SUSPEND, or RESUME after ALTER DYNAMIC TABLE", + parser.peek_token(), + ); + }; - // Parse the operation (currently only REFRESH is supported) - if parser.parse_keyword(Keyword::REFRESH) { - Ok(Statement::AlterTable { - name: table_name, - if_exists: false, - only: false, - operations: vec![AlterTableOperation::Refresh], - location: None, - on_cluster: None, - iceberg: false, - }) + let end_token = if parser.peek_token_ref().token == Token::SemiColon { + parser.peek_token_ref().clone() } else { - parser.expected("REFRESH after ALTER DYNAMIC TABLE", parser.peek_token()) - } + parser.get_current_token().clone() + }; + + Ok(Statement::AlterTable(AlterTable { + name: table_name, + if_exists: false, + only: false, + operations: vec![operation], + location: None, + on_cluster: None, + iceberg: false, + dynamic: true, + end_token: AttachedToken(end_token), + })) } /// Parse snowflake alter session. diff --git a/src/keywords.rs b/src/keywords.rs index bed7b02a9..dc4ecd2f9 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -783,8 +783,8 @@ define_keywords!( REF, REFERENCES, REFERENCING, - REFRESH_MODE, REFRESH, + REFRESH_MODE, REGCLASS, REGEXP, REGION, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 9a01e510b..ae96d040f 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -9462,6 +9462,7 @@ impl<'a> Parser<'a> { location, on_cluster, iceberg, + dynamic: false, end_token: AttachedToken(end_token), } .into()) diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index e43df87ab..2edc7822c 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -2747,6 +2747,7 @@ fn parse_alter_table_add_column() { only, operations, iceberg, + dynamic: _, location: _, on_cluster: _, end_token: _, diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index fc2d18129..f187af1bd 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -4664,54 +4664,9 @@ fn test_drop_constraints() { } #[test] -fn test_snowflake_alter_dynamic_table_refresh() { - // Test with simple table name - let sql = "ALTER DYNAMIC TABLE MY_DYNAMIC_TABLE REFRESH"; - let result = snowflake().parse_sql_statements(sql); - - assert!( - result.is_ok(), - "Expected ALTER DYNAMIC TABLE to parse successfully" - ); - - match result.unwrap().first().unwrap() { - Statement::AlterTable { - name, operations, .. - } => { - assert_eq!(name.to_string(), "MY_DYNAMIC_TABLE"); - assert_eq!(operations.len(), 1); - match &operations[0] { - AlterTableOperation::Refresh => { - // Success! - } - _ => panic!("Expected Refresh operation"), - } - } - _ => panic!("Expected AlterTable statement"), - } - - // Test with qualified table name - let sql3 = "ALTER DYNAMIC TABLE my_database.my_schema.my_dynamic_table REFRESH"; - let result3 = snowflake().parse_sql_statements(sql3); - - assert!( - result3.is_ok(), - "Expected ALTER DYNAMIC TABLE to parse successfully" - ); - - match result3.unwrap().first().unwrap() { - Statement::AlterTable { - name, operations, .. - } => { - assert_eq!(name.to_string(), "my_database.my_schema.my_dynamic_table"); - assert_eq!(operations.len(), 1); - match &operations[0] { - AlterTableOperation::Refresh => { - // Success! - } - _ => panic!("Expected Refresh operation"), - } - } - _ => panic!("Expected AlterTable statement"), - } +fn test_alter_dynamic_table() { + snowflake().verified_stmt("ALTER DYNAMIC TABLE MY_DYNAMIC_TABLE REFRESH"); + snowflake().verified_stmt("ALTER DYNAMIC TABLE my_database.my_schema.my_dynamic_table REFRESH"); + snowflake().verified_stmt("ALTER DYNAMIC TABLE my_dyn_table SUSPEND"); + snowflake().verified_stmt("ALTER DYNAMIC TABLE my_dyn_table RESUME"); } From c585baad60560c7ebeac3bf3484b58d5ddbc8fd2 Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Thu, 30 Oct 2025 17:11:50 -0700 Subject: [PATCH 3/5] cargo fmt --- src/dialect/snowflake.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index 7096ede9e..5b9f9f959 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -17,6 +17,7 @@ #[cfg(not(feature = "std"))] use crate::alloc::string::ToString; +use crate::ast::helpers::attached_token::AttachedToken; use crate::ast::helpers::key_value_options::{ KeyValueOption, KeyValueOptionKind, KeyValueOptions, KeyValueOptionsDelimiter, }; @@ -26,15 +27,15 @@ use crate::ast::helpers::stmt_data_loading::{ FileStagingCommand, StageLoadSelectItem, StageLoadSelectItemKind, StageParamsObject, }; use crate::ast::{ - AlterTable, AlterTableOperation, CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, ColumnPolicyProperty, ContactEntry, - CopyIntoSnowflakeKind, CreateTableLikeKind, DollarQuotedString, Ident, IdentityParameters, - IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, - InitializeKind, ObjectName, ObjectNamePart, RefreshModeKind, RowAccessPolicy, ShowObjects, - SqlOption, Statement, StorageSerializationPolicy, TagsColumnOption, Value, WrappedCollection, + AlterTable, AlterTableOperation, CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, + ColumnPolicyProperty, ContactEntry, CopyIntoSnowflakeKind, CreateTableLikeKind, + DollarQuotedString, Ident, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, + IdentityPropertyKind, IdentityPropertyOrder, InitializeKind, ObjectName, ObjectNamePart, + RefreshModeKind, RowAccessPolicy, ShowObjects, SqlOption, Statement, + StorageSerializationPolicy, TagsColumnOption, Value, WrappedCollection, }; use crate::dialect::{Dialect, Precedence}; use crate::keywords::Keyword; -use crate::ast::helpers::attached_token::AttachedToken; use crate::parser::{IsOptional, Parser, ParserError}; use crate::tokenizer::Token; #[cfg(not(feature = "std"))] @@ -215,10 +216,10 @@ impl Dialect for SnowflakeDialect { return Some(parser.parse_begin_exception_end()); } - if parser.parse_keywords(&[Keyword::ALTER, Keyword::DYNAMIC, Keyword::TABLE]) { + if parser.parse_keywords(&[Keyword::ALTER, Keyword::DYNAMIC, Keyword::TABLE]) { // ALTER DYNAMIC TABLE return Some(parse_alter_dynamic_table(parser)); - } + } if parser.parse_keywords(&[Keyword::ALTER, Keyword::SESSION]) { // ALTER SESSION From ae993f5f86a1c43e897fc0d08445b27b69758cff Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Thu, 30 Oct 2025 17:31:23 -0700 Subject: [PATCH 4/5] Fixed lint error --- src/ast/mod.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 176d36545..3a448312b 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -2787,10 +2787,11 @@ impl fmt::Display for Declare { } /// Sql options of a `CREATE TABLE` statement. -#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] pub enum CreateTableOptions { + #[default] None, /// Options specified using the `WITH` keyword. /// e.g. `WITH (description = "123")` @@ -2819,12 +2820,6 @@ pub enum CreateTableOptions { TableProperties(Vec), } -impl Default for CreateTableOptions { - fn default() -> Self { - Self::None - } -} - impl fmt::Display for CreateTableOptions { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { From c0be3430074f772f5f2850e7b6d52e2cb873fdd4 Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Tue, 4 Nov 2025 23:05:14 -0800 Subject: [PATCH 5/5] Added AlterTableType enum --- src/ast/ddl.rs | 32 ++++++++++++++++++++------------ src/ast/mod.rs | 2 +- src/dialect/snowflake.rs | 7 +++---- src/parser/mod.rs | 7 +++++-- src/test_utils.rs | 2 +- tests/sqlparser_mysql.rs | 5 ++--- 6 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index ba218a0b4..1ae24a7f4 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -3553,6 +3553,20 @@ impl Spanned for DropExtension { } } +/// Table type for ALTER TABLE statements. +/// Used to distinguish between regular tables, Iceberg tables, and Dynamic tables. +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub enum AlterTableType { + /// Iceberg table type + /// + Iceberg, + /// Dynamic table type + /// + Dynamic, +} + /// ALTER TABLE statement #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -3569,24 +3583,18 @@ pub struct AlterTable { /// 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) pub on_cluster: Option, - /// Snowflake "ICEBERG" clause for Iceberg tables - /// - pub iceberg: bool, - /// Snowflake "DYNAMIC" clause for Dynamic tables - /// - pub dynamic: bool, + /// Table type: None for regular tables, Some(AlterTableType) for Iceberg or Dynamic tables + pub table_type: Option, /// Token that represents the end of the statement (semicolon or EOF) pub end_token: AttachedToken, } impl fmt::Display for AlterTable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.iceberg { - write!(f, "ALTER ICEBERG TABLE ")?; - } else if self.dynamic { - write!(f, "ALTER DYNAMIC TABLE ")?; - } else { - write!(f, "ALTER TABLE ")?; + match &self.table_type { + Some(AlterTableType::Iceberg) => write!(f, "ALTER ICEBERG TABLE ")?, + Some(AlterTableType::Dynamic) => write!(f, "ALTER DYNAMIC TABLE ")?, + None => write!(f, "ALTER TABLE ")?, } if self.if_exists { diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 3a448312b..c838b3b68 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -61,7 +61,7 @@ pub use self::dcl::{ pub use self::ddl::{ AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock, - AlterTableOperation, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, + AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction, diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index 5b9f9f959..bb0d4f16b 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -27,8 +27,8 @@ use crate::ast::helpers::stmt_data_loading::{ FileStagingCommand, StageLoadSelectItem, StageLoadSelectItemKind, StageParamsObject, }; use crate::ast::{ - AlterTable, AlterTableOperation, CatalogSyncNamespaceMode, ColumnOption, ColumnPolicy, - ColumnPolicyProperty, ContactEntry, CopyIntoSnowflakeKind, CreateTableLikeKind, + AlterTable, AlterTableOperation, AlterTableType, CatalogSyncNamespaceMode, ColumnOption, + ColumnPolicy, ColumnPolicyProperty, ContactEntry, CopyIntoSnowflakeKind, CreateTableLikeKind, DollarQuotedString, Ident, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, InitializeKind, ObjectName, ObjectNamePart, RefreshModeKind, RowAccessPolicy, ShowObjects, SqlOption, Statement, @@ -644,8 +644,7 @@ fn parse_alter_dynamic_table(parser: &mut Parser) -> Result Parser<'a> { operations, location, on_cluster, - iceberg, - dynamic: false, + table_type: if iceberg { + Some(AlterTableType::Iceberg) + } else { + None + }, end_token: AttachedToken(end_token), } .into()) diff --git a/src/test_utils.rs b/src/test_utils.rs index a8c8afd59..b6100d498 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -347,7 +347,7 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa assert_eq!(alter_table.name.to_string(), expected_name); assert!(!alter_table.if_exists); assert!(!alter_table.only); - assert!(!alter_table.iceberg); + assert_eq!(alter_table.table_type, None); only(alter_table.operations) } _ => panic!("Expected ALTER TABLE statement"), diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 2edc7822c..86c1013c3 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -2746,15 +2746,14 @@ fn parse_alter_table_add_column() { if_exists, only, operations, - iceberg, - dynamic: _, + table_type, location: _, on_cluster: _, end_token: _, }) => { assert_eq!(name.to_string(), "tab"); assert!(!if_exists); - assert!(!iceberg); + assert_eq!(table_type, None); assert!(!only); assert_eq!( operations,