Skip to content

planner: recheck LIKE/ILIKE with a non-default ESCAPE on memtable scans#69670

Open
vismaytiwari wants to merge 1 commit into
pingcap:masterfrom
vismaytiwari:infoschema-like-escape-recheck
Open

planner: recheck LIKE/ILIKE with a non-default ESCAPE on memtable scans#69670
vismaytiwari wants to merge 1 commit into
pingcap:masterfrom
vismaytiwari:infoschema-like-escape-recheck

Conversation

@vismaytiwari

@vismaytiwari vismaytiwari commented Jul 4, 2026

Copy link
Copy Markdown

What problem does this PR solve?

Issue Number: close #69653

Problem Summary:

A LIKE ... ESCAPE predicate on an information_schema table can return rows that fail the predicate and drop rows that match. The memtable predicate extractor pushes the LIKE pattern into the scan and removes the original predicate, but it always compiles the pattern with the default \ escape via stringutil.CompileLike2Regexp, ignoring the custom ESCAPE. The pushed-down (default-escape) pattern then becomes authoritative and diverges from the real predicate.

For example, with ESCAPE '#', %#_% means "contains a literal underscore", so only abc_def should match. Instead the scan compiles %#_% with the \ escape (where _ is the single-char wildcard) and returns abc#x, which fails its own predicate.

What changed and how does it work?

extractLikePattern now builds a pushed-down pattern for LIKE/ILIKE only when the ESCAPE argument is the default backslash. For any non-default (or non-constant) escape it returns no pattern, so the predicate stays in the remaining filters and is rechecked as a scalar Selection. This keeps the existing fast path for the common default-escape case and restores correct results for custom escapes (and for NO_BACKSLASH_ESCAPES, which sets the escape to empty).

The related REGEXP_LIKE(..., match_type) case on cluster_log mentioned in the issue shares the same shape (the extractor models only part of the operator). I've kept this PR focused on the self-contained LIKE ... ESCAPE fix, and I'm happy to follow up on the regexp match_type case if that's preferred.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Fix `information_schema` queries with a `LIKE ... ESCAPE` predicate that uses a non-default escape character returning incorrect rows.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of LIKE and ILIKE filters so patterns with custom escape characters are evaluated correctly.
    • Queries now avoid incorrect optimization when the escape value is missing, non-constant, or different from the default.
  • Tests

    • Added coverage for information_schema table-name matching with custom ESCAPE behavior.
    • Verified both the returned rows and the resulting query plan.

The information_schema memtable predicate extractor pushes a LIKE pattern
down into the scan and drops the original predicate, but always compiles the
pattern with the default '\' escape via stringutil.CompileLike2Regexp. When
the query uses a custom ESCAPE, the pushed-down pattern diverges from the real
predicate, so the scan can return rows that fail the predicate and omit rows
that match. The same is true when NO_BACKSLASH_ESCAPES makes the escape empty.

Only build a pushed-down pattern when the escape is the default backslash;
otherwise leave the predicate in place so it is rechecked as a scalar
Selection. This keeps the existing fast path for the common default-escape
case while restoring correct results for custom escapes.

Issue Number: close pingcap#69653

Signed-off-by: vismaytiwari <vismay.t@gmail.com>
@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-tests-checked release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/needs-triage-completed labels Jul 4, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown

Hi @vismaytiwari. Thanks for your PR.

I'm waiting for a pingcap member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot Bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. contribution This PR is from a community contributor. sig/planner SIG: Planner needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. first-time-contributor Indicates that the PR was contributed by an external member and is a first-time contributor. labels Jul 4, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown

Welcome @vismaytiwari!

It looks like this is your first PR to pingcap/tidb 🎉.

I'm the bot to help you request reviewers, add labels and more, See available commands.

We want to make sure your contribution gets all the attention it needs!



Thank you, and welcome to pingcap/tidb. 😃

@ti-chi-bot

ti-chi-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign guo-shaoge for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@pingcap-cla-assistant

pingcap-cla-assistant Bot commented Jul 4, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The memtable predicate extractor now checks whether a LIKE/ILIKE predicate's ESCAPE argument is the default backslash before pushing the pattern down for memtable scans; non-default escapes skip extraction, keeping the scalar predicate for recheck. A new test validates correct behavior with a custom ESCAPE character.

Changes

LIKE ESCAPE extraction fix

Layer / File(s) Summary
Skip pattern extraction for non-default ESCAPE
pkg/planner/core/memtable_predicate_extractor.go
Adds likeEscapeIsDefault helper validating the ESCAPE argument is a non-deferred constant equal to backslash; extraction is skipped when the escape is non-default or missing/non-constant, leaving the original predicate for recheck.
Test coverage for custom ESCAPE on information_schema.tables
pkg/planner/core/tests/extractor/memtable_infoschema_extractor_test.go
Adds TestInfoSchemaTableNameLikeEscape, which creates tables with _ and # patterns and verifies LIKE '%#_%' ESCAPE '#' returns only the correct row while EXPLAIN shows the predicate remains a Selection.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

Skipped, as this change is a targeted bug fix to predicate extraction logic without multi-component interaction flow.

Poem

A backslash checked, an escape confessed,
No more wrong rows, put to the test.
Hop, hop, hooray, the pattern's true,
abc_def shines, abc#x too... not! 🐇
Selection stands where pushdown flew astray.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code and test address #69653 by avoiding pushdown when ESCAPE is non-default, preserving correct results for custom escapes.
Out of Scope Changes check ✅ Passed The changes stay focused on the ESCAPE-handling fix and its regression test, with no obvious unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately summarizes the main change: handling non-default ESCAPE for LIKE/ILIKE on memtable scans.
Description check ✅ Passed The description follows the template with issue number, problem summary, implementation details, tests, and a release note.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
pkg/planner/core/tests/extractor/memtable_infoschema_extractor_test.go (1)

533-539: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Plan assertion only checks for presence of "Selection", not absence of pushdown.

The test asserts strings.Contains(plan, "Selection"), which is a fairly loose check — a Selection node could appear in the plan for unrelated reasons (e.g., from the table_schema predicate or other implicit filtering), making the assertion pass even if the LIKE-specific bug regressed. A more targeted check (e.g., asserting the LIKE predicate text appears within a Selection operator line, or asserting the extractor's LikePatterns/pushed conditions are empty) would more precisely pin down the regression this test guards against.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/planner/core/tests/extractor/memtable_infoschema_extractor_test.go`
around lines 533 - 539, The current plan assertion is too broad because checking
only for “Selection” can pass even when the LIKE predicate is still pushed down.
Update the test around the information_schema.tables query in
memtable_infoschema_extractor_test to verify the custom-escape LIKE is
specifically retained in a Selection tied to that predicate, or assert on the
extractor output (for example, that the pushed-down LikePatterns/conditions are
empty for this case). Use the existing explain query and the affected
Selection/LikePatterns behavior to make the regression check precise.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/planner/core/tests/extractor/memtable_infoschema_extractor_test.go`:
- Around line 533-539: The current plan assertion is too broad because checking
only for “Selection” can pass even when the LIKE predicate is still pushed down.
Update the test around the information_schema.tables query in
memtable_infoschema_extractor_test to verify the custom-escape LIKE is
specifically retained in a Selection tied to that predicate, or assert on the
extractor output (for example, that the pushed-down LikePatterns/conditions are
empty for this case). Use the existing explain query and the affected
Selection/LikePatterns behavior to make the regression check precise.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f5919765-c265-49a8-bf43-965376fec98c

📥 Commits

Reviewing files that changed from the base of the PR and between b2c55fb and a8b00e0.

📒 Files selected for processing (2)
  • pkg/planner/core/memtable_predicate_extractor.go
  • pkg/planner/core/tests/extractor/memtable_infoschema_extractor_test.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution This PR is from a community contributor. do-not-merge/needs-triage-completed first-time-contributor Indicates that the PR was contributed by an external member and is a first-time contributor. needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/planner SIG: Planner size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

information_schema LIKE with a custom ESCAPE returns rows that fail the predicate (memtable extractor ignores ESCAPE)

1 participant