diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index ee4b5be23..50b9e21cf 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -1100,10 +1100,10 @@ pub enum IdentityOrder { impl fmt::Display for IdentityProperty { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if let Some(parameters) = &self.parameters { - write!(f, "{parameters}")?; + write!(f, " {parameters}")?; } if let Some(order) = &self.order { - write!(f, "{order}")?; + write!(f, " {order}")?; } Ok(()) } @@ -1116,7 +1116,7 @@ impl fmt::Display for IdentityParameters { write!(f, "({}, {})", self.seed, self.increment) } IdentityParametersFormat::StartIncrement => { - write!(f, "START {} INCREMENT {})", self.seed, self.increment) + write!(f, "START {} INCREMENT {}", self.seed, self.increment) } } } diff --git a/src/ast/mod.rs b/src/ast/mod.rs index d15ff79e5..6d726df87 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -41,9 +41,9 @@ pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue, pub use self::ddl::{ AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ConstraintCharacteristics, Deduplicate, DeferrableInitial, - GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityParametersFormat, - IdentityProperty, IdentityPropertyCommand, IndexOption, IndexType, KeyOrIndexDisplay, Owner, - Partition, ProcedureParam, ReferentialAction, TableConstraint, + GeneratedAs, GeneratedExpressionMode, IdentityOrder, IdentityParameters, + IdentityParametersFormat, IdentityProperty, IdentityPropertyCommand, IndexOption, IndexType, + KeyOrIndexDisplay, Owner, Partition, ProcedureParam, ReferentialAction, TableConstraint, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, ViewColumnDef, }; pub use self::dml::{CreateIndex, CreateTable, Delete, Insert}; diff --git a/src/keywords.rs b/src/keywords.rs index 49c6ce20f..6db3ed25c 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -504,6 +504,7 @@ define_keywords!( NOINHERIT, NOLOGIN, NONE, + NOORDER, NOREPLICATION, NORMALIZE, NOSCAN, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 092d4b742..61ec01663 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -6146,6 +6146,52 @@ impl<'a> Parser<'a> { Ok(Some(ColumnOption::DialectSpecific(vec![ Token::make_keyword("AUTO_INCREMENT"), ]))) + } else if self + .parse_one_of_keywords(&[Keyword::IDENTITY, Keyword::AUTOINCREMENT]) + .is_some() + && dialect_of!(self is SnowflakeDialect) + { + self.prev_token(); + let format = + match self.parse_one_of_keywords(&[Keyword::IDENTITY, Keyword::AUTOINCREMENT]) { + Some(Keyword::IDENTITY) => IdentityPropertyCommand::Identity, + Some(Keyword::AUTOINCREMENT) => IdentityPropertyCommand::Autoincrement, + _ => self.expected("one of IDENTITY or AUTOINCREMENT", self.peek_token())?, + }; + let parameters = if self.consume_token(&Token::LParen) { + let seed = self.parse_number()?; + self.expect_token(&Token::Comma)?; + let increment = self.parse_number()?; + self.expect_token(&Token::RParen)?; + + Some(IdentityParameters { + format: IdentityParametersFormat::FunctionCall, + seed, + increment, + }) + } else if self.parse_keyword(Keyword::START) { + let seed = self.parse_number()?; + self.expect_keyword(Keyword::INCREMENT)?; + let increment = self.parse_number()?; + + Some(IdentityParameters { + format: IdentityParametersFormat::StartIncrement, + seed, + increment, + }) + } else { + None + }; + let order = match self.parse_one_of_keywords(&[Keyword::ORDER, Keyword::NOORDER]) { + Some(Keyword::ORDER) => Some(IdentityOrder::Order), + Some(Keyword::NOORDER) => Some(IdentityOrder::Noorder), + _ => None, + }; + Ok(Some(ColumnOption::Identity(IdentityProperty { + format, + parameters, + order, + }))) } else if self.parse_keyword(Keyword::AUTOINCREMENT) && dialect_of!(self is SQLiteDialect | GenericDialect) { diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index 50c5f740e..c5a9dd7c6 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -525,6 +525,19 @@ fn test_snowflake_single_line_tokenize() { assert_eq!(expected, tokens); } +#[test] +fn test_snowflake_create_table_with_all_parameters() { + let sql = concat!( + "CREATE TABLE my_table (", + "a INT AUTOINCREMENT ORDER, ", + "b INT AUTOINCREMENT (100, -1) NOORDER, ", + "c INT IDENTITY, ", + "d INT IDENTITY START 100 INCREMENT -1 ORDER", + ")" + ); + snowflake().verified_stmt(sql); +} + #[test] fn parse_sf_create_or_replace_view_with_comment_missing_equal() { assert!(snowflake_and_generic()