Skip to content

MySQL: Fix REGEXP and RLIKE parsing when pattern is NULL - #2791

Closed
slopgobblercobbler wants to merge 1 commit into
apache:mainfrom
slopgobblercobbler:fix/mysql-regexp-rlike-null
Closed

slopgobblercobbler wants to merge 1 commit into
apache:mainfrom
slopgobblercobbler:fix/mysql-regexp-rlike-null

Conversation

@slopgobblercobbler

Copy link
Copy Markdown

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:

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.

@github-actions github-actions Bot added the MySQL label Oct 31, 2026
@LucaCappelletti94 LucaCappelletti94 added the Prolific Author author has opened PRs in many repositories in the last month label Nov 1, 2026
@alamb

alamb commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Thank you for the contribution. The change may well be correct, but I am closing this PR under the DataFusion AI policy, which also applies to sqlparser-rs: https://datafusion.apache.org/contributor-guide/ai-policy.html#what-is-an-ai-dump-and-why-it-is-not-helpful

Maintainer review time is the scarcest resource in this project. This account has recently opened many AI-generated PRs across many repositories. That suggests the changes aren't coming from someone who uses sqlparser-rs, and that no human will be around to discuss review feedback and maintain the code. Reviewing PRs like this costs us more time than it saves.

If you do use sqlparser-rs and this fix matters to you, please pick the one change you care most about. Then open a focused PR with a short description in your own words, one you have reviewed and understand, and we'd be happy to help with review.

@alamb alamb closed this Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

MySQL Prolific Author author has opened PRs in many repositories in the last month

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MySQL: REGEXP/RLIKE followed by NULL is rejected or misparsed (regression in 0.59.0)

3 participants