Skip to content

Commit 375fe8c

Browse files
committed
fixup: Add ParserState::ColumnDefinition to avoid parsing NOT NULL as Expr::IsNotNull.
1 parent ab6607b commit 375fe8c

2 files changed

Lines changed: 30 additions & 19 deletions

File tree

src/dialect/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,9 @@ pub trait Dialect: Debug + Any {
650650
Token::Word(w) if w.keyword == Keyword::MATCH => Ok(p!(Like)),
651651
Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(p!(Like)),
652652
Token::Word(w) if w.keyword == Keyword::MEMBER => Ok(p!(Like)),
653+
Token::Word(w) if w.keyword == Keyword::NULL && parser.in_normal_state() => {
654+
Ok(p!(Is))
655+
}
653656
_ => Ok(self.prec_unknown()),
654657
},
655658
Token::Word(w) if w.keyword == Keyword::NOTNULL && self.supports_notnull_operator() => {

src/parser/mod.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ use helpers::attached_token::AttachedToken;
2828

2929
use log::debug;
3030

31-
use recursion::RecursionCounter;
32-
use IsLateral::*;
33-
use IsOptional::*;
34-
3531
use crate::ast::helpers::stmt_create_table::{CreateTableBuilder, CreateTableConfiguration};
3632
use crate::ast::Statement::CreatePolicy;
3733
use crate::ast::*;
3834
use crate::dialect::*;
3935
use crate::keywords::{Keyword, ALL_KEYWORDS};
4036
use crate::tokenizer::*;
37+
use recursion::RecursionCounter;
38+
use sqlparser::parser::ParserState::ColumnDefinition;
39+
use IsLateral::*;
40+
use IsOptional::*;
4141

4242
mod alter;
4343

@@ -271,6 +271,9 @@ enum ParserState {
271271
/// PRIOR expressions while still allowing prior as an identifier name
272272
/// in other contexts.
273273
ConnectBy,
274+
/// The state when parsing column definitions. This state prohibits
275+
/// NOT NULL as an alias for IS NOT NULL.
276+
ColumnDefinition,
274277
}
275278

276279
/// A SQL Parser
@@ -1243,21 +1246,6 @@ impl<'a> Parser<'a> {
12431246

12441247
expr = self.parse_infix(expr, next_precedence)?;
12451248
}
1246-
1247-
// Special case: if expr is an identifier or NULL, accept `expr NOT NULL`
1248-
// as an alias for `expr IS NOT NULL`.
1249-
if match &expr {
1250-
Expr::Identifier(_) if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) => true,
1251-
Expr::Value(v)
1252-
if v.value == Value::Null
1253-
&& self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) =>
1254-
{
1255-
true
1256-
}
1257-
_ => false,
1258-
} {
1259-
return Ok(Expr::IsNotNull(Box::new(expr)));
1260-
}
12611249
Ok(expr)
12621250
}
12631251

@@ -3577,6 +3565,11 @@ impl<'a> Parser<'a> {
35773565
let negated = self.parse_keyword(Keyword::NOT);
35783566
let regexp = self.parse_keyword(Keyword::REGEXP);
35793567
let rlike = self.parse_keyword(Keyword::RLIKE);
3568+
let null = if self.in_normal_state() {
3569+
self.parse_keyword(Keyword::NULL)
3570+
} else {
3571+
false
3572+
};
35803573
if regexp || rlike {
35813574
Ok(Expr::RLike {
35823575
negated,
@@ -3586,6 +3579,8 @@ impl<'a> Parser<'a> {
35863579
),
35873580
regexp,
35883581
})
3582+
} else if negated && null {
3583+
Ok(Expr::IsNotNull(Box::new(expr)))
35893584
} else if self.parse_keyword(Keyword::IN) {
35903585
self.parse_in(expr, negated)
35913586
} else if self.parse_keyword(Keyword::BETWEEN) {
@@ -7734,6 +7729,15 @@ impl<'a> Parser<'a> {
77347729
return option;
77357730
}
77367731

7732+
self.with_state(
7733+
ColumnDefinition,
7734+
|parser| -> Result<Option<ColumnOption>, ParserError> {
7735+
parser.parse_optional_column_option_inner()
7736+
},
7737+
)
7738+
}
7739+
7740+
fn parse_optional_column_option_inner(&mut self) -> Result<Option<ColumnOption>, ParserError> {
77377741
if self.parse_keywords(&[Keyword::CHARACTER, Keyword::SET]) {
77387742
Ok(Some(ColumnOption::CharacterSet(
77397743
self.parse_object_name(false)?,
@@ -16510,6 +16514,10 @@ impl<'a> Parser<'a> {
1651016514
Ok(None)
1651116515
}
1651216516
}
16517+
16518+
pub fn in_normal_state(&self) -> bool {
16519+
matches!(self.state, ParserState::Normal)
16520+
}
1651316521
}
1651416522

1651516523
fn maybe_prefixed_expr(expr: Expr, prefix: Option<Ident>) -> Expr {

0 commit comments

Comments
 (0)