@@ -1820,7 +1820,19 @@ impl<'a> Parser<'a> {
18201820 } else if let Some(lambda) = self.try_parse_lambda()? {
18211821 return Ok(lambda);
18221822 } else {
1823- let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1823+ // Parentheses in expressions switch to "normal" parsing state.
1824+ // This matters for dialects (SQLite, DuckDB) where `NOT NULL` can
1825+ // be an alias for `IS NOT NULL`. In column definitions like:
1826+ //
1827+ // CREATE TABLE t (c INT DEFAULT (42 NOT NULL) NOT NULL)
1828+ //
1829+ // The `(42 NOT NULL)` is an expression with parens, so it parses
1830+ // as `IsNotNull(42)`. The trailing `NOT NULL` is outside those
1831+ // expression parens (the outer parens are CREATE TABLE syntax),
1832+ // so it remains a column constraint.
1833+ let exprs = self.with_state(ParserState::Normal, |p| {
1834+ p.parse_comma_separated(Parser::parse_expr)
1835+ })?;
18241836 match exprs.len() {
18251837 0 => return Err(ParserError::ParserError(
18261838 "Internal parser error: parse_comma_separated returned empty list"
@@ -8854,19 +8866,15 @@ impl<'a> Parser<'a> {
88548866 } else if self.parse_keyword(Keyword::NULL) {
88558867 Ok(Some(ColumnOption::Null))
88568868 } else if self.parse_keyword(Keyword::DEFAULT) {
8857- Ok(Some(ColumnOption::Default(
8858- self.parse_column_option_expr()?,
8859- )))
8869+ Ok(Some(ColumnOption::Default(self.parse_expr()?)))
88608870 } else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88618871 && self.parse_keyword(Keyword::MATERIALIZED)
88628872 {
8863- Ok(Some(ColumnOption::Materialized(
8864- self.parse_column_option_expr()?,
8865- )))
8873+ Ok(Some(ColumnOption::Materialized(self.parse_expr()?)))
88668874 } else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88678875 && self.parse_keyword(Keyword::ALIAS)
88688876 {
8869- Ok(Some(ColumnOption::Alias(self.parse_column_option_expr ()?)))
8877+ Ok(Some(ColumnOption::Alias(self.parse_expr ()?)))
88708878 } else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88718879 && self.parse_keyword(Keyword::EPHEMERAL)
88728880 {
@@ -8875,9 +8883,7 @@ impl<'a> Parser<'a> {
88758883 if matches!(self.peek_token().token, Token::Comma | Token::RParen) {
88768884 Ok(Some(ColumnOption::Ephemeral(None)))
88778885 } else {
8878- Ok(Some(ColumnOption::Ephemeral(Some(
8879- self.parse_column_option_expr()?,
8880- ))))
8886+ Ok(Some(ColumnOption::Ephemeral(Some(self.parse_expr()?))))
88818887 }
88828888 } else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) {
88838889 let characteristics = self.parse_constraint_characteristics()?;
@@ -8999,7 +9005,7 @@ impl<'a> Parser<'a> {
89999005 } else if self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
90009006 && dialect_of!(self is MySqlDialect | GenericDialect)
90019007 {
9002- let expr = self.parse_column_option_expr ()?;
9008+ let expr = self.parse_expr ()?;
90039009 Ok(Some(ColumnOption::OnUpdate(expr)))
90049010 } else if self.parse_keyword(Keyword::GENERATED) {
90059011 self.parse_optional_column_option_generated()
@@ -9017,9 +9023,7 @@ impl<'a> Parser<'a> {
90179023 } else if self.parse_keyword(Keyword::SRID)
90189024 && dialect_of!(self is MySqlDialect | GenericDialect)
90199025 {
9020- Ok(Some(ColumnOption::Srid(Box::new(
9021- self.parse_column_option_expr()?,
9022- ))))
9026+ Ok(Some(ColumnOption::Srid(Box::new(self.parse_expr()?))))
90239027 } else if self.parse_keyword(Keyword::IDENTITY)
90249028 && dialect_of!(self is MsSqlDialect | GenericDialect)
90259029 {
@@ -9061,31 +9065,6 @@ impl<'a> Parser<'a> {
90619065 }
90629066 }
90639067
9064- /// When parsing some column option expressions we need to revert to [ParserState::Normal] since
9065- /// `NOT NULL` is allowed as an alias for `IS NOT NULL`.
9066- /// In those cases we use this helper instead of calling [Parser::parse_expr] directly.
9067- ///
9068- /// For example, consider these `CREATE TABLE` statements:
9069- /// ```sql
9070- /// CREATE TABLE foo (abc BOOL DEFAULT (42 NOT NULL) NOT NULL);
9071- /// ```
9072- /// vs
9073- /// ```sql
9074- /// CREATE TABLE foo (abc BOOL NOT NULL);
9075- /// ```
9076- ///
9077- /// In the first we should parse the inner portion of `(42 NOT NULL)` as [Expr::IsNotNull],
9078- /// whereas is both statements that trailing `NOT NULL` should only be parsed as a
9079- /// [ColumnOption::NotNull].
9080- fn parse_column_option_expr(&mut self) -> Result<Expr, ParserError> {
9081- if self.peek_token_ref().token == Token::LParen {
9082- let expr: Expr = self.with_state(ParserState::Normal, |p| p.parse_prefix())?;
9083- Ok(expr)
9084- } else {
9085- Ok(self.parse_expr()?)
9086- }
9087- }
9088-
90899068 pub(crate) fn parse_tag(&mut self) -> Result<Tag, ParserError> {
90909069 let name = self.parse_object_name(false)?;
90919070 self.expect_token(&Token::Eq)?;
0 commit comments