@@ -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"
@@ -8823,19 +8835,15 @@ impl<'a> Parser<'a> {
88238835 } else if self.parse_keyword(Keyword::NULL) {
88248836 Ok(Some(ColumnOption::Null))
88258837 } else if self.parse_keyword(Keyword::DEFAULT) {
8826- Ok(Some(ColumnOption::Default(
8827- self.parse_column_option_expr()?,
8828- )))
8838+ Ok(Some(ColumnOption::Default(self.parse_expr()?)))
88298839 } else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88308840 && self.parse_keyword(Keyword::MATERIALIZED)
88318841 {
8832- Ok(Some(ColumnOption::Materialized(
8833- self.parse_column_option_expr()?,
8834- )))
8842+ Ok(Some(ColumnOption::Materialized(self.parse_expr()?)))
88358843 } else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88368844 && self.parse_keyword(Keyword::ALIAS)
88378845 {
8838- Ok(Some(ColumnOption::Alias(self.parse_column_option_expr ()?)))
8846+ Ok(Some(ColumnOption::Alias(self.parse_expr ()?)))
88398847 } else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88408848 && self.parse_keyword(Keyword::EPHEMERAL)
88418849 {
@@ -8844,9 +8852,7 @@ impl<'a> Parser<'a> {
88448852 if matches!(self.peek_token().token, Token::Comma | Token::RParen) {
88458853 Ok(Some(ColumnOption::Ephemeral(None)))
88468854 } else {
8847- Ok(Some(ColumnOption::Ephemeral(Some(
8848- self.parse_column_option_expr()?,
8849- ))))
8855+ Ok(Some(ColumnOption::Ephemeral(Some(self.parse_expr()?))))
88508856 }
88518857 } else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) {
88528858 let characteristics = self.parse_constraint_characteristics()?;
@@ -8968,7 +8974,7 @@ impl<'a> Parser<'a> {
89688974 } else if self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
89698975 && dialect_of!(self is MySqlDialect | GenericDialect)
89708976 {
8971- let expr = self.parse_column_option_expr ()?;
8977+ let expr = self.parse_expr ()?;
89728978 Ok(Some(ColumnOption::OnUpdate(expr)))
89738979 } else if self.parse_keyword(Keyword::GENERATED) {
89748980 self.parse_optional_column_option_generated()
@@ -8986,9 +8992,7 @@ impl<'a> Parser<'a> {
89868992 } else if self.parse_keyword(Keyword::SRID)
89878993 && dialect_of!(self is MySqlDialect | GenericDialect)
89888994 {
8989- Ok(Some(ColumnOption::Srid(Box::new(
8990- self.parse_column_option_expr()?,
8991- ))))
8995+ Ok(Some(ColumnOption::Srid(Box::new(self.parse_expr()?))))
89928996 } else if self.parse_keyword(Keyword::IDENTITY)
89938997 && dialect_of!(self is MsSqlDialect | GenericDialect)
89948998 {
@@ -9030,31 +9034,6 @@ impl<'a> Parser<'a> {
90309034 }
90319035 }
90329036
9033- /// When parsing some column option expressions we need to revert to [ParserState::Normal] since
9034- /// `NOT NULL` is allowed as an alias for `IS NOT NULL`.
9035- /// In those cases we use this helper instead of calling [Parser::parse_expr] directly.
9036- ///
9037- /// For example, consider these `CREATE TABLE` statements:
9038- /// ```sql
9039- /// CREATE TABLE foo (abc BOOL DEFAULT (42 NOT NULL) NOT NULL);
9040- /// ```
9041- /// vs
9042- /// ```sql
9043- /// CREATE TABLE foo (abc BOOL NOT NULL);
9044- /// ```
9045- ///
9046- /// In the first we should parse the inner portion of `(42 NOT NULL)` as [Expr::IsNotNull],
9047- /// whereas is both statements that trailing `NOT NULL` should only be parsed as a
9048- /// [ColumnOption::NotNull].
9049- fn parse_column_option_expr(&mut self) -> Result<Expr, ParserError> {
9050- if self.peek_token_ref().token == Token::LParen {
9051- let expr: Expr = self.with_state(ParserState::Normal, |p| p.parse_prefix())?;
9052- Ok(expr)
9053- } else {
9054- Ok(self.parse_expr()?)
9055- }
9056- }
9057-
90589037 pub(crate) fn parse_tag(&mut self) -> Result<Tag, ParserError> {
90599038 let name = self.parse_object_name(false)?;
90609039 self.expect_token(&Token::Eq)?;
0 commit comments