diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 7d87d88de..9e3137d94 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -143,6 +143,8 @@ pub enum AlterTableOperation { /// /// Note: this is Snowflake specific SwapWith { table_name: ObjectName }, + /// 'SET TBLPROPERTIES ( { property_key [ = ] property_val } [, ...] )' + SetTblProperties { table_properties: Vec }, } #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] @@ -283,6 +285,13 @@ impl fmt::Display for AlterTableOperation { AlterTableOperation::SwapWith { table_name } => { write!(f, "SWAP WITH {table_name}") } + AlterTableOperation::SetTblProperties { table_properties } => { + write!( + f, + "SET TBLPROPERTIES({})", + display_comma_separated(table_properties) + ) + } } } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 36ac2fd28..b766cefbb 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -4862,6 +4862,20 @@ impl<'a> Parser<'a> { } } + pub fn parse_options_with_keywords( + &mut self, + keywords: &[Keyword], + ) -> Result, ParserError> { + if self.parse_keywords(keywords) { + self.expect_token(&Token::LParen)?; + let options = self.parse_comma_separated(Parser::parse_sql_option)?; + self.expect_token(&Token::RParen)?; + Ok(options) + } else { + Ok(vec![]) + } + } + pub fn parse_index_type(&mut self) -> Result { if self.parse_keyword(Keyword::BTREE) { Ok(IndexType::BTree) @@ -5123,10 +5137,18 @@ impl<'a> Parser<'a> { let table_name = self.parse_object_name(false)?; AlterTableOperation::SwapWith { table_name } } else { - return self.expected( - "ADD, RENAME, PARTITION, SWAP or DROP after ALTER TABLE", - self.peek_token(), - ); + let options: Vec = + self.parse_options_with_keywords(&[Keyword::SET, Keyword::TBLPROPERTIES])?; + if !options.is_empty() { + AlterTableOperation::SetTblProperties { + table_properties: options, + } + } else { + return self.expected( + "ADD, RENAME, PARTITION, SWAP, DROP, or SET TBLPROPERTIES after ALTER TABLE", + self.peek_token(), + ); + } }; Ok(operation) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index fcacb3459..b4c743cca 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -3497,6 +3497,23 @@ fn parse_alter_table() { } _ => unreachable!(), } + + let set_table_properties = "ALTER TABLE tab SET TBLPROPERTIES('classification' = 'parquet')"; + match alter_table_op(verified_stmt(set_table_properties)) { + AlterTableOperation::SetTblProperties { table_properties } => { + assert_eq!( + table_properties, + [SqlOption { + name: Ident { + value: "classification".to_string(), + quote_style: Some('\'') + }, + value: Expr::Value(Value::SingleQuotedString("parquet".to_string())), + }], + ); + } + _ => unreachable!(), + } } #[test]