slopgobblercobbler opened a new pull request, #2791:
URL: https://github.com/apache/datafusion-sqlparser-rs/pull/2791
<!-- comma separated, or `none` -->
Dialects: mysql, generic
### Description
Fixes #2760.
In `Parser::parse_subexpr`, when matching infix operators (`NOT`, `IN`,
`BETWEEN`, `LIKE`, `ILIKE`, `SIMILAR`, `REGEXP`, `RLIKE`), the parser
previously parsed `Keyword::NULL` eagerly into a `null` boolean before checking
if a `REGEXP` or `RLIKE` operator matched:
```rust
let negated = self.parse_keyword(Keyword::NOT);
let regexp = self.parse_keyword(Keyword::REGEXP);
let rlike = self.parse_keyword(Keyword::RLIKE);
let null = if !self.in_column_definition_state() {
self.parse_keyword(Keyword::NULL)
} else {
false
};
```
When an expression contained `REGEXP NULL` or `RLIKE NULL` (with or without
`NOT`), `self.parse_keyword(Keyword::REGEXP)` (or `RLIKE`) consumed the
operator token, placing the parser cursor directly at `NULL`. The subsequent
`self.parse_keyword(Keyword::NULL)` call then consumed the `NULL` token under
the assumption that it was part of a `NOT NULL` expression.
Consequently, when `Expr::RLike` went to parse its `pattern` operand with
`self.parse_subexpr(Precedence::Like)`, the `NULL` token was already consumed:
- `SELECT 'abc' REGEXP NULL` failed with `ParserError("Expected: an
expression, found: EOF")`.
- `SELECT a RLIKE NULL FROM t` consumed `FROM` as the pattern identifier.
- `SELECT a NOT REGEXP NULL OR b FROM t` consumed `OR` as the pattern
identifier.
This PR defers the `Keyword::NULL` check so it is only evaluated when
checking for `NOT NULL` in the `else if negated &&
!self.in_column_definition_state() && self.parse_keyword(Keyword::NULL)`
branch, ensuring `REGEXP` and `RLIKE` pattern expressions retain access to
`NULL` literals.
### Tests
- Extended `parse_rlike_and_regexp` in `tests/sqlparser_mysql.rs` with:
- `SELECT 'abc' REGEXP NULL`
- `SELECT a RLIKE NULL FROM t`
- `SELECT a NOT REGEXP NULL OR b FROM t`
- `SELECT a NOT RLIKE NULL FROM t`
- Explicit AST verification that `Expr::RLike` pattern contains
`Value(Null)`.
- Verified `cargo test --test sqlparser_mysql`, `cargo test --test
sqlparser_common`, and `cargo test --lib` all pass.
- Verified `cargo fmt --check` and `cargo clippy --all-targets -- -D
warnings` pass with 0 warnings.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]