Skip to content

LIKE ... ESCAPE '''' panics in parser reparse assertion because Expr::Display does not escape the escape literal #19563

@TCeason

Description

@TCeason

Repro

SELECT 'a' LIKE 'a' ESCAPE '''';

Actual

The query fails with an internal panic:

Code: 1104
called `Result::unwrap()` on an `Err` value: ParseError(Some(29..32), "unable to recognize the rest tokens")

Panic site:

  • src/query/ast/src/parser/parser.rs:210

Expected

Databend should parse the query and then either execute it or return a normal SQL error. It must not panic inside parser self-check logic.

Why this looks like the root cause

assert_reparse() serializes the parsed AST back into SQL and then tokenizes it again:

let new_sql = stmt.to_string();
let new_tokens = crate::parser::tokenize_sql(&new_sql).unwrap();

at:

  • src/query/ast/src/parser/parser.rs:209
  • src/query/ast/src/parser/parser.rs:210

For LIKE ... ESCAPE, Expr::Display currently prints:

write!(f, " LIKE {right} ESCAPE '{escape}'")?;

and similar forms at:

  • src/query/ast/src/ast/expr.rs:649
  • src/query/ast/src/ast/expr.rs:659
  • src/query/ast/src/ast/expr.rs:672

That output does not SQL-escape the literal contents. If escape itself is ', the reserialized SQL becomes invalid, so tokenize_sql() returns Err and unwrap() panics.

Impact

  • panic.log shows this happened during the migration batch for LIKE ESCAPE coverage.
  • Any escape literal that needs re-escaping in SQL text can break parser round-trip validation.

Suggested fix direction

  • Escape string literals when rendering Expr::LikeSubquery, Expr::LikeAnyWithEscape, and Expr::LikeWithEscape
  • Avoid unwrap() inside assert_reparse() so round-trip failures become actionable diagnostics instead of panics

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions