diff --git a/src/ast/helpers/stmt_create_table.rs b/src/ast/helpers/stmt_create_table.rs index d66a869bf..543f8f2c9 100644 --- a/src/ast/helpers/stmt_create_table.rs +++ b/src/ast/helpers/stmt_create_table.rs @@ -383,6 +383,16 @@ impl CreateTableBuilder { self } + /// Returns true if information on the structure of the table + /// to be created was provided to the builder. If not, the + /// statement is invalid. + pub fn has_schema_info(&self) -> bool { + !self.columns.is_empty() + || self.query.is_some() + || self.like.is_some() + || self.clone.is_some() + } + pub fn build(self) -> Statement { Statement::CreateTable(CreateTable { or_replace: self.or_replace, diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index 212cf217d..63746efeb 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -452,17 +452,14 @@ pub fn parse_create_table( Keyword::AS => { let query = parser.parse_query()?; builder = builder.query(Some(query)); - break; } Keyword::CLONE => { let clone = parser.parse_object_name(false).ok(); builder = builder.clone_clause(clone); - break; } Keyword::LIKE => { let like = parser.parse_object_name(false).ok(); builder = builder.like(like); - break; } Keyword::CLUSTER => { parser.expect_keyword_is(Keyword::BY)?; @@ -588,7 +585,7 @@ pub fn parse_create_table( builder = builder.columns(columns).constraints(constraints); } Token::EOF => { - if builder.columns.is_empty() { + if !builder.has_schema_info() { return Err(ParserError::ParserError( "unexpected end of input".to_string(), )); @@ -597,7 +594,7 @@ pub fn parse_create_table( break; } Token::SemiColon => { - if builder.columns.is_empty() { + if !builder.has_schema_info() { return Err(ParserError::ParserError( "unexpected end of input".to_string(), )); diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index e7393d3f8..c4eebdb5e 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -995,6 +995,21 @@ fn test_snowflake_create_iceberg_table_without_location() { ); } +#[test] +fn test_snowflake_create_table_trailing_options() { + snowflake() + .parse_sql_statements( + "CREATE TEMP TABLE dst AS (SELECT * FROM src) ON COMMIT PRESERVE ROWS", + ) + .unwrap(); + snowflake() + .parse_sql_statements("CREATE TEMP TABLE tbl LIKE customers ON COMMIT PRESERVE ROWS;") + .unwrap(); + snowflake() + .parse_sql_statements("CREATE TEMP TABLE tbl CLONE customers ON COMMIT PRESERVE ROWS;") + .unwrap(); +} + #[test] fn parse_sf_create_or_replace_view_with_comment_missing_equal() { assert!(snowflake_and_generic()