Skip to content

planner: rewrite FTS predicates to LIKE for evaluation of non-TiCI query plan#65626

Merged
ti-chi-bot[bot] merged 46 commits into
pingcap:masterfrom
terry1purcell:fts
May 13, 2026
Merged

planner: rewrite FTS predicates to LIKE for evaluation of non-TiCI query plan#65626
ti-chi-bot[bot] merged 46 commits into
pingcap:masterfrom
terry1purcell:fts

Conversation

@terry1purcell
Copy link
Copy Markdown
Contributor

@terry1purcell terry1purcell commented Jan 18, 2026

What problem does this PR solve?

Issue Number: close #68153

Problem Summary:

What changed and how does it work?

Summary

When tidb_opt_enable_alternative_logical_plans=ON, adds a fallback that rewrites MATCH ... AGAINST to case-insensitive ILIKE predicates so full-text-search queries can execute without an FTS index. The rewrite is intentionally conservative: it only fires for a strict subset of search strings in direct-boolean predicate positions, and reaches the plan only when the round-1 native path is not viable. Anything outside that envelope either keeps the native builtin (errors at execution without an FTS index) or is rejected at plan time, never silently producing wrong rows.

Architecture

Round 1 (default, matches Alt-disabled behavior) — emits the native FTSMysqlMatchAgainst builtin. The expression rewriter records nonViableFTSMatch on the PlanBuilder when a direct-boolean-context MATCH cannot be served natively (no FTS index on a TiFlash replica, or a non-pushdown-safe modifier).

Round 2: fts-like-fallback — fires only when round 1 reported a non-viable MATCH. The driver discards round 1's plan and re-runs the build with AlternativeLogicalPlanFTSLikeFallback=true, which switches the rewriter to ILIKE in direct-boolean positions. If this round also errors (e.g. unsupported search string with no FTS-index rescue), lastAltRoundErr propagates the message instead of the generic "failed to build logical plan" sentinel.

A single flag (AlternativeLogicalPlanFTSLikeFallback) drives the dispatch; viability state stays local to the build on PlanBuilder.nonViableFTSMatch.

Where the rewrite applies

inDirectMatchBooleanContext (modeled on the existing canTreatInSubqueryAsExistsForFilter) walks the AST ancestor stack and accepts only:

  • Root of WHERE / HAVING / JOIN ON, with ancestors limited to AND, OR, NOT, parentheses.

Everything else — MATCH ... > 0.5, MATCH ... = 0, MATCH ... IS NULL, MATCH inside CASE WHEN, arithmetic, scoring (SELECT field list, ORDER BY), etc. — keeps the native builtin, which preserves the float relevance score and errors at execution if no FTS index exists. Substituting a 0/1 integer in those positions would silently corrupt the comparison or sort.

Strict search-string subset

ValidateFTSSearchStringForLikeFallback rejects anything that would tokenize differently in MySQL FTS than a substring ILIKE match. Accepted by mode:

  • Natural-language mode: whitespace-separated alphanumeric word tokens only.
  • Boolean mode: each token is word, +word, or -word, where word is alphanumeric (ASCII or non-ASCII UTF-8).

Rejected at plan time with error 1235 (ErrNotSupportedYet): phrases "...", prefix wildcard term*, relevance modifiers > < ~, grouping (...), mid-word punctuation like xx-yy, and any token containing %, _, , ,, ., :, etc. WITH QUERY EXPANSION is likewise rejected (no ILIKE approximation exists).

Modifier handling

The tipb pushdown protocol does not serialize the FTS modifier (see distsql_builtin.go), so a Boolean-mode or WITH QUERY EXPANSION MATCH pushed down to TiFlash would silently execute as natural-language mode. To prevent this, matchAgainstToBuiltin rejects non-default modifiers at plan time unless matchHasLikeFallbackRescue is true (alt enabled + direct-boolean context, where the alt-rounds driver will discard the native plan and rebuild via fts-like-fallback). In practice:

  │     Modifier     │     Direct-boolean predicate     │ Scalar/scoring position │
  ├──────────────────┼──────────────────────────────────┼─────────────────────────┤                                                                                               
  │ Natural language │ native (round 1) or ILIKE rescue │ native                  │                                                                                             
  ├──────────────────┼──────────────────────────────────┼─────────────────────────┤
  │ Boolean          │ ILIKE rescue                     │ error 1235              │                                                                                               
  ├──────────────────┼──────────────────────────────────┼─────────────────────────┤                                                                                               
  │ With QE          │ error 1235 from ILIKE round      │ error 1235              │                                                                                               
  └──────────────────┴──────────────────────────────────┴─────────────────────────┘                                                                                               

NULL search handling

MATCH(c) AGAINST(NULL) matches nothing in MySQL FTS semantics, but three-valued logic matters under NOT: native evalReal returns NULL, so NOT NULL = NULL filters the row. The rewrite emits Constant(NULL) rather than Constant(0) so the same semantics hold under NOT, IS NULL, etc. The plan-cache skip is set before the NULL fast-path, so a prepared statement bound to NULL first followed by a non-NULL bind re-plans and returns correct rows instead of reusing a cached constant-false plan.

Boolean-mode operator support (post-strict-subset)

  │   Operator    │                              Behavior                               │                                                                                       
  ├───────────────┼─────────────────────────────────────────────────────────────────────┤                                                                                         
  │ +term         │ All required terms must match (AND across the per-term column DNFs) │
  ├───────────────┼─────────────────────────────────────────────────────────────────────┤                                                                                         
  │ -term         │ NOT(any column matches term)                                        │                                                                                         
  ├───────────────┼─────────────────────────────────────────────────────────────────────┤
  │ term          │ Optional — anchors the result only when no +term exists             │                                                                                         
  ├───────────────┼─────────────────────────────────────────────────────────────────────┤                                                                                         
  │ --only        │ Returns empty (matches MySQL)                                       │
  ├───────────────┼─────────────────────────────────────────────────────────────────────┤                                                                                         
  │ Anything else │ Rejected by ValidateFTSSearchStringForLikeFallback (1235)           │                                                                                       
  └───────────────┴─────────────────────────────────────────────────────────────────────┘                                                                                         

Plan cache

Marks the plan non-cacheable when the AGAINST argument is mutable across executions (? parameter marker, user variable, deferred expression). Literal AGAINST values keep the plan cacheable. The skip runs before the NULL fast-path so a NULL first bind can't bake a constant plan that gets reused later.

Selectivity

BuildFTSToILikeExpressionFromBuiltin substitutes the equivalent ILIKE form for the opaque FTSMysqlMatchAgainst builtin so the round 1 native plan's cost reflects column histogram/TopN rather than the flat SelectivityFactor (0.8). Restricted to single-column MATCH because GetSelectivityByFilter declines multi-column expressions — a multi-column substitute would fall through to the same str-match default anyway.

Known semantic differences

These apply to ILIKE round queries only; the native path preserves full MySQL semantics:

  • No relevance scoring (0/1 boolean output).
  • No word boundaries (%cat% matches concatenate).
  • No stop-word filtering or minimum word length.
  • Optional-term relevance ranking is approximated as a filter when no required terms exist.

Files changed

  │                           File                            │                                                    Purpose                                                     │
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤  
  │ pkg/expression/fts_to_like.go                             │ Strict-subset validator, ILIKE expression builder, mode-dispatch helpers, single-column substitution wrapper   │
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤  
  │ pkg/expression/fts_to_like_test.go                        │ Validator coverage (33 cases), BuildFTSToILikeExpressionFromBuiltin coverage                                   │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤  
  │ pkg/expression/builtin_fts.go                             │ Native builtinFtsMysqlMatchAgainstSig with modifier, defensive evalReal returning NULL for NULL search         │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤  
  │ pkg/planner/core/expression_rewriter.go                   │ matchAgainstToExpression dispatcher, inDirectMatchBooleanContext, ftsNativeViable, modifier guard,             │
  │                                                           │ matchHasLikeFallbackRescue                                                                                     │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/planner/core/fulltext_to_like.go                      │ Thin wrapper delegating to pkg/expression                                                                      │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/planner/core/fulltext_to_like_test.go                 │ Unit tests for ftsModifierAllowsNativePushdown, tableHasPublicFTSIndexOnColumn                                 │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/planner/core/planbuilder.go                           │ PlanBuilder.nonViableFTSMatch + HasNonViableFTSMatch/MarkNonViableFTSMatch accessors                           │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/planner/optimize.go                                   │ fts-like-fallback alternative round, round-1 plan invalidation, lastAltRoundErr                                │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/planner/cardinality/selectivity.go                    │ Selectivity substitution for FTSMysqlMatchAgainst (single-column only)                                         │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/sessionctx/stmtctx/stmtctx.go                         │ Single AlternativeLogicalPlanFTSLikeFallback flag                                                              │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ pkg/parser/ast/functions.go                               │ FTSMysqlMatchAgainst = "match_against" constant                                                                │  
  ├───────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ tests/integrationtest/t/planner/core/fulltext_search.test │ 94 integration test cases                                                                                      │  
  └───────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Test plan

  • 94 integration cases covering: natural-language mode, boolean mode (+/-/optional), empty/whitespace/NULL search, non-string columns, HAVING/JOIN ON predicates, NOT MATCH,
    parenthesized MATCH, scalar positions (IS NULL, > 0.5, = 0, CASE), non-default modifiers in scoring/scalar/alt-disabled contexts, prepared statements (literal cacheable,
    parameter-marker non-cacheable, NULL-first-bind re-plans).
  • Unit: validator (33 cases), BuildFTSToILikeExpressionFromBuiltin (nil/wrong-fn/single-column/multi-column/NULL/non-subset), parser tests aligned with the strict subset.
  • Strict-subset rejections previously-passing edge cases now expect error 1235.
  • make lint passes.
  • gofmt clean.

🤖 Generated with https://claude.com/claude-code

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

Please refer to Release Notes Language Style Guide to write a quality release note.

None

Summary by CodeRabbit

  • New Features

    • LIKE-based fallback for MATCH...AGAINST so full-text queries run when native FTS isn’t viable; supports natural and boolean modes, preserves NULL semantics, and surfaces clear errors for unsupported patterns/modifiers.
    • Session controls to choose fallback vs. error behavior and planner handling across native/fallback rounds.
    • Improved planner handling and selectivity estimation for full-text predicates.
  • Tests

    • Extensive unit and integration tests covering parsing, LIKE conversion, planner rewrites, prepared-plan cache behavior, and edge cases.
  • Chores

    • Updated ignore rules and test sharding configuration.

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-linked-issue release-note-none Denotes a PR that doesn't merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. sig/planner SIG: Planner labels Jan 18, 2026
@terry1purcell terry1purcell requested a review from Copilot January 18, 2026 02:09
@tiprow
Copy link
Copy Markdown

tiprow Bot commented Jan 18, 2026

Hi @terry1purcell. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

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.

@terry1purcell terry1purcell changed the title planner: rewrite FTS predicates to LIKE if no FTS index planner: rewrite FTS predicates to LIKE if no FTS index (WIP) Jan 18, 2026
@terry1purcell
Copy link
Copy Markdown
Contributor Author

/ok-to-test

@ti-chi-bot ti-chi-bot Bot added the ok-to-test Indicates a PR is ready to be tested. label Jan 18, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds functionality to rewrite MATCH...AGAINST (fulltext search) predicates to LIKE predicates when no fulltext index is available. This is controlled by a new session variable tidb_opt_fulltext_search_fallback which can be set to either 'like' (convert to LIKE predicates, default) or 'error' (throw an error if no fulltext index exists).

Changes:

  • Added new session variable tidb_opt_fulltext_search_fallback to control fulltext search fallback behavior
  • Implemented conversion logic from MATCH...AGAINST to LIKE predicates supporting both natural language mode and Boolean mode
  • Added unit and integration tests for the conversion logic

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/sessionctx/vardef/tidb_vars.go Defines the new session variable constant and default value
pkg/sessionctx/variable/sysvar.go Registers the new session variable with its configuration
pkg/sessionctx/variable/session.go Adds the FulltextSearchFallback field to SessionVars struct
pkg/planner/core/fulltext_to_like.go Implements the conversion logic from MATCH...AGAINST to LIKE predicates
pkg/planner/core/fulltext_to_like_test.go Unit tests for parsing Boolean search strings
pkg/planner/core/expression_rewriter.go Integrates MATCH...AGAINST handling into the expression rewriter
pkg/planner/core/BUILD.bazel Adds new source and test files to the build configuration
tests/integrationtest/t/planner/core/fulltext_search.test Integration test cases for the fulltext to LIKE conversion

Comment thread pkg/planner/core/fulltext_to_like.go Outdated
Comment thread tests/integrationtest/t/planner/core/fulltext_search.test Outdated
Comment thread tests/integrationtest/t/planner/core/fulltext_search.test Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 18, 2026

Codecov Report

❌ Patch coverage is 72.91667% with 169 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.3877%. Comparing base (4598d48) to head (ed3e7a3).
⚠️ Report is 12 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #65626        +/-   ##
================================================
- Coverage   77.7123%   76.3877%   -1.3247%     
================================================
  Files          1991       1992         +1     
  Lines        552087     562593     +10506     
================================================
+ Hits         429040     429752       +712     
- Misses       122127     132315     +10188     
+ Partials        920        526       -394     
Flag Coverage Δ
integration 41.2309% <72.9166%> (+1.4291%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 60.4888% <ø> (ø)
parser ∅ <ø> (∅)
br 49.4896% <ø> (-13.6039%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI review requested due to automatic review settings January 18, 2026 17:05
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Comment thread pkg/sessionctx/variable/session.go Outdated
Comment thread pkg/planner/core/fulltext_to_like.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings January 18, 2026 19:45
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Comment thread pkg/planner/core/fulltext_to_like.go Outdated
Comment thread pkg/planner/core/fulltext_to_like.go Outdated
Comment thread pkg/planner/core/fulltext_to_like.go Outdated
Comment on lines +323 to +328
// perfectly enforce word-start boundaries. We use %term% which may produce false positives
// (matching mid-word like "reOptimizing"), but avoids false negatives. This is an acceptable
// limitation for a fallback implementation.
var pattern string
// Both prefix and general matches use %term% to find the term anywhere in text
pattern = "%" + escapedTerm + "%"
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

The comment explains that prefix matching (with * wildcard) uses the same %term% pattern as regular matching, making the isPrefixMatch parameter effectively unused. While this is documented as an acceptable limitation, the parameter serves no functional purpose in the current implementation and could be removed for clarity, or the implementation could be enhanced to use %term (without trailing %) for prefix matches to better approximate the intended behavior.

Suggested change
// perfectly enforce word-start boundaries. We use %term% which may produce false positives
// (matching mid-word like "reOptimizing"), but avoids false negatives. This is an acceptable
// limitation for a fallback implementation.
var pattern string
// Both prefix and general matches use %term% to find the term anywhere in text
pattern = "%" + escapedTerm + "%"
// perfectly enforce word-start boundaries. We previously used %term% for both prefix and
// general matches, which may produce false positives (matching mid-word like "reOptimizing"),
// but avoids false negatives. Here we approximate prefix semantics by using a different
// pattern when isPrefixMatch is true.
var pattern string
if isPrefixMatch {
// For prefix matches, use %term (no trailing %) to better approximate the intended behavior.
pattern = "%" + escapedTerm
} else {
// For general matches, keep using %term% to find the term anywhere in the text.
pattern = "%" + escapedTerm + "%"
}

Copilot uses AI. Check for mistakes.
Comment thread pkg/planner/core/fulltext_to_like.go Outdated
Comment thread pkg/planner/core/expression_rewriter.go
Comment thread pkg/planner/core/fulltext_to_like.go Outdated
terry1purcell and others added 2 commits May 11, 2026 18:31
…hange

The substitution comment said "AGAINST(NULL) and empty-string search produce
a constant substitute (Constant 0)" but commit b0b04c4 changed
BuildFTSToILikeExpressionFromBuiltin to emit Constant(NULL) for AGAINST(NULL)
(empty-string search still uses Constant(0) via ftsZeroIntConst). Update the
comment to spell out which shape comes from which case and to note that the
constant-folding pass below handles both shapes equivalently via its IsNull
and ToBool branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…token

ValidateFTSSearchStringForLikeFallback indexed body[0] inside the boolean-
mode operator-strip branch without first checking len(body). The indexing
is safe today because strings.Fields never returns an empty token, but the
guard makes the bound explicit at the call site and protects against any
future change to the tokenization that could produce an empty substring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@terry1purcell terry1purcell requested review from AilinKid and qw4990 May 12, 2026 02:21
@ti-chi-bot ti-chi-bot Bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label May 12, 2026
@terry1purcell
Copy link
Copy Markdown
Contributor Author

/hold

I found a problem in the cost competition

@ti-chi-bot ti-chi-bot Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 13, 2026
Round 1 already runs with the native FTSMysqlMatchAgainst builtin; the
fts-like-fallback alternative round previously fired only when round 1's
plan was non-executable. Queries where both plans were valid (alphanumeric
word search in a direct-boolean predicate position) had no competitor —
the native plan won by default even when an ILIKE plan would have been
cheaper given a selective non-FTS predicate.

Split the planBuilder signal into two:

  - HasNonViableFTSMatch (existing): round 1's plan cannot execute;
    driver discards it and forces FTSLikeFallback across all subsequent
    rounds.
  - HasPredicateMatch (new): round 1 saw a direct-boolean-context MATCH.
    Driver propagates this into stmtctx as
    AlternativeLogicalPlanHasPredicateContextMatch, enabling the
    fts-like-fallback round for cost competition.

The fts-like-fallback round now:

  - enables on (FTSLikeFallback || HasPredicateContextMatch),
  - via setup/cleanup saves and forces AlternativeLogicalPlanFTSLikeFallback
    true during its own build so the rewriter emits ILIKE,
  - restores the flag after the round.

Behavior matrix:

  | native viable | predicate MATCH | LIKE round | outcome              |
  | yes           | yes             | yes        | strict-< cost compare |
  | yes           | no (scoring)    | no         | native wins          |
  | no            | yes             | yes        | LIKE wins (discard)  |
  | no            | yes, LIKE bad   | yes(error) | surface LIKE error   |

The existing fulltext_search integration suite (95 cases, all on a
TiKV-only / no-FTS-index environment) exercises only the discard path and
continues to pass unchanged. The new cost-competition branch requires a
TiFlash replica + public FTS index in test fixtures and is not exercised
by the current integration test environment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@terry1purcell
Copy link
Copy Markdown
Contributor Author

/retest-required

@terry1purcell
Copy link
Copy Markdown
Contributor Author

/unhold

@ti-chi-bot ti-chi-bot Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 13, 2026
@ti-chi-bot ti-chi-bot Bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels May 13, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 13, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-05-12 13:04:10.769698423 +0000 UTC m=+184419.302477752: ☑️ agreed by qw4990.
  • 2026-05-13 08:19:15.080911936 +0000 UTC m=+253723.613691265: ☑️ agreed by AilinKid.

Copy link
Copy Markdown
Collaborator

@Benjamin2037 Benjamin2037 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Collaborator

@Benjamin2037 Benjamin2037 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Contributor

@windtalker windtalker left a comment

Choose a reason for hiding this comment

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

lgtm

@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 13, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: AilinKid, Benjamin2037, qw4990, windtalker

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

The pull request process is described 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

@ti-chi-bot
Copy link
Copy Markdown
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #68743.
But this PR has conflicts, please resolve them!

yongman pushed a commit to yongman/tidb that referenced this pull request Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved lgtm needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. ok-to-test Indicates a PR is ready to be tested. release-note-none Denotes a PR that doesn't merit a release note. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

planner: query fails with MySQL compatible FTS search

9 participants