Skip to content

Commit 2fd41b0

Browse files
committed
New approach to handle at parenthesis boundary
1 parent 2f20af6 commit 2fd41b0

1 file changed

Lines changed: 14 additions & 40 deletions

File tree

src/parser/mod.rs

Lines changed: 14 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,14 @@ impl<'a> Parser<'a> {
18181818
} else if let Some(lambda) = self.try_parse_lambda()? {
18191819
return Ok(lambda);
18201820
} else {
1821-
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1821+
// Parentheses create a "normal" expression context.
1822+
// This ensures that e.g. `NOT NULL` inside parens is parsed
1823+
// as `IS NOT NULL` (for dialects that support it), while
1824+
// `NOT NULL` outside parens in a column definition context
1825+
// remains a column constraint.
1826+
let exprs = self.with_state(ParserState::Normal, |p| {
1827+
p.parse_comma_separated(Parser::parse_expr)
1828+
})?;
18221829
match exprs.len() {
18231830
0 => return Err(ParserError::ParserError(
18241831
"Internal parser error: parse_comma_separated returned empty list"
@@ -8787,18 +8794,18 @@ impl<'a> Parser<'a> {
87878794
Ok(Some(ColumnOption::Null))
87888795
} else if self.parse_keyword(Keyword::DEFAULT) {
87898796
Ok(Some(ColumnOption::Default(
8790-
self.parse_column_option_expr()?,
8797+
self.parse_expr()?,
87918798
)))
87928799
} else if dialect_of!(self is ClickHouseDialect| GenericDialect)
87938800
&& self.parse_keyword(Keyword::MATERIALIZED)
87948801
{
87958802
Ok(Some(ColumnOption::Materialized(
8796-
self.parse_column_option_expr()?,
8803+
self.parse_expr()?,
87978804
)))
87988805
} else if dialect_of!(self is ClickHouseDialect| GenericDialect)
87998806
&& self.parse_keyword(Keyword::ALIAS)
88008807
{
8801-
Ok(Some(ColumnOption::Alias(self.parse_column_option_expr()?)))
8808+
Ok(Some(ColumnOption::Alias(self.parse_expr()?)))
88028809
} else if dialect_of!(self is ClickHouseDialect| GenericDialect)
88038810
&& self.parse_keyword(Keyword::EPHEMERAL)
88048811
{
@@ -8808,7 +8815,7 @@ impl<'a> Parser<'a> {
88088815
Ok(Some(ColumnOption::Ephemeral(None)))
88098816
} else {
88108817
Ok(Some(ColumnOption::Ephemeral(Some(
8811-
self.parse_column_option_expr()?,
8818+
self.parse_expr()?,
88128819
))))
88138820
}
88148821
} else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) {
@@ -8922,7 +8929,7 @@ impl<'a> Parser<'a> {
89228929
} else if self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
89238930
&& dialect_of!(self is MySqlDialect | GenericDialect)
89248931
{
8925-
let expr = self.parse_column_option_expr()?;
8932+
let expr = self.parse_expr()?;
89268933
Ok(Some(ColumnOption::OnUpdate(expr)))
89278934
} else if self.parse_keyword(Keyword::GENERATED) {
89288935
self.parse_optional_column_option_generated()
@@ -8941,7 +8948,7 @@ impl<'a> Parser<'a> {
89418948
&& dialect_of!(self is MySqlDialect | GenericDialect)
89428949
{
89438950
Ok(Some(ColumnOption::Srid(Box::new(
8944-
self.parse_column_option_expr()?,
8951+
self.parse_expr()?,
89458952
))))
89468953
} else if self.parse_keyword(Keyword::IDENTITY)
89478954
&& dialect_of!(self is MsSqlDialect | GenericDialect)
@@ -8984,39 +8991,6 @@ impl<'a> Parser<'a> {
89848991
}
89858992
}
89868993

8987-
/// When parsing some column option expressions we need to revert to [ParserState::Normal] since
8988-
/// `NOT NULL` is allowed as an alias for `IS NOT NULL`.
8989-
/// In those cases we use this helper instead of calling [Parser::parse_expr] directly.
8990-
///
8991-
/// For example, consider these `CREATE TABLE` statements:
8992-
/// ```sql
8993-
/// CREATE TABLE foo (abc BOOL DEFAULT (42 NOT NULL) NOT NULL);
8994-
/// ```
8995-
/// vs
8996-
/// ```sql
8997-
/// CREATE TABLE foo (abc BOOL NOT NULL);
8998-
/// ```
8999-
///
9000-
/// In the first we should parse the inner portion of `(42 NOT NULL)` as [Expr::IsNotNull],
9001-
/// whereas is both statements that trailing `NOT NULL` should only be parsed as a
9002-
/// [ColumnOption::NotNull].
9003-
fn parse_column_option_expr(&mut self) -> Result<Expr, ParserError> {
9004-
if self.peek_token_ref().token == Token::LParen {
9005-
let mut expr = self.with_state(ParserState::Normal, |p| p.parse_prefix())?;
9006-
expr = self.parse_compound_expr(expr, vec![])?;
9007-
loop {
9008-
let next_precedence = self.get_next_precedence()?;
9009-
if next_precedence == 0 || self.peek_token_ref().token == Token::Period {
9010-
break;
9011-
}
9012-
expr = self.parse_infix(expr, next_precedence)?;
9013-
}
9014-
Ok(expr)
9015-
} else {
9016-
Ok(self.parse_expr()?)
9017-
}
9018-
}
9019-
90208994
pub(crate) fn parse_tag(&mut self) -> Result<Tag, ParserError> {
90218995
let name = self.parse_object_name(false)?;
90228996
self.expect_token(&Token::Eq)?;

0 commit comments

Comments
 (0)