Skip to content

*: support fts query for starter mode - #69012

Merged
ti-chi-bot[bot] merged 10 commits into
pingcap:masterfrom
ChangRui-Ryan:changrui_cse_fts
Jun 22, 2026
Merged

*: support fts query for starter mode#69012
ti-chi-bot[bot] merged 10 commits into
pingcap:masterfrom
ChangRui-Ryan:changrui_cse_fts

Conversation

@ChangRui-Ryan

@ChangRui-Ryan ChangRui-Ryan commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: ref #67765

Problem Summary

TiDB already has the FTS_MATCH_WORD() builtin and FULLTEXT index syntax, but it does not have the planner path that rewrites FTS_MATCH_WORD() predicates into TiFlash/CSE columnar full-text scans. As a result, Starter deployments cannot execute FULLTEXT index queries through the columnar FTS engine.

The feature should be available only in Starter deployment mode. Creating FULLTEXT indexes or executing FTS_MATCH_WORD() outside Starter mode should fail early instead of silently taking an unsupported path.

What changed and how does it work

This PR adds the Starter-only FULLTEXT query path for TiDB:

  • Gates FULLTEXT index creation and FTS_MATCH_WORD() execution by deploymode.IsStarter().
  • Resolves FTS_MATCH_WORD(<query>, <column>) in WHERE to a matching FULLTEXT index on the target column.
  • Rewrites the logical plan so the predicate is pushed into a TiFlash/CSE columnar full-text scan through tipb.FTSQueryInfo.
  • Supports no-score filtering queries, for example:
SELECT *
FROM t
WHERE fts_match_word('keyword', title);
  • Supports score-based TopN queries by rewriting matching ORDER BY fts_match_word(...) DESC LIMIT N into a topK FTS scan:
SELECT *
FROM t
WHERE fts_match_word('keyword', title)
ORDER BY fts_match_word('keyword', title) DESC
LIMIT 10;
  • Supports projecting the FTS score when the SELECT expression matches the WHERE expression:
SELECT id, fts_match_word('keyword', title) AS score
FROM t
WHERE fts_match_word('keyword', title)
ORDER BY score DESC
LIMIT 10;
  • Adds the virtual FTS score column to the scan schema and keeps projection output types aligned with the score column returned by TiFlash.
  • Keeps unsupported FTS_MATCH_WORD() usages rejected with clear planner errors, such as mismatched SELECT/WHERE expressions, unsupported wrapping expressions, or use without a matching FULLTEXT index.
  • Does not change protobuf definitions; it reuses the existing tipb.FTSQueryInfo / columnar index pushdown path.
  • Adds targeted planner/expression tests and validates the path with a local Starter playground using CSE TiKV columnar storage plus one TiFlash compute node.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)

E2E validation

I also validated the FTS query path with a real local cluster.

The cluster was started with tiup playground / lightly using the TiDB binary built from this PR. It used normal Starter deployment mode only; no FTS-specific mode was enabled, and it did not use playground:v1.16.2-feature.fts.

The tested topology included:

  • TiDB built from this PR, using the next-gen build.
  • TiKV / columnar storage built from /Users/changrui/GITHUB/TiDB-Cloud/cloud-storage-engine.
  • TiFlash built from /Users/changrui/GITHUB/tiflash, used as the query node.
  • One TiFlash node was enough for query execution; no dedicated TiFlash write node was required.

The test created a table with a FULLTEXT index, inserted sample rows, and verified both NoScore and WithScore FTS query paths.

Example SQL used in the validation:

CREATE DATABASE IF NOT EXISTS test;
USE test;

CREATE TABLE fts_t (
    id BIGINT PRIMARY KEY,
    title TEXT,
    body TEXT,
    FULLTEXT KEY ft_title(title)
);

INSERT INTO fts_t VALUES
    (1, 'hello tidb full text search', 'row 1'),
    (2, 'hello mysql', 'row 2'),
    (3, 'tidb vector and fulltext', 'row 3');

EXPLAIN FORMAT = 'plan_tree'
SELECT *
FROM fts_t
WHERE fts_match_word('tidb', title);

SELECT *
FROM fts_t
WHERE fts_match_word('tidb', title);

EXPLAIN FORMAT = 'plan_tree'
SELECT id, fts_match_word('tidb', title) AS score
FROM fts_t
WHERE fts_match_word('tidb', title)
ORDER BY fts_match_word('tidb', title) DESC
LIMIT 10;

SELECT id, fts_match_word('tidb', title) AS score
FROM fts_t
WHERE fts_match_word('tidb', title)
ORDER BY fts_match_word('tidb', title) DESC
LIMIT 10;
- [ ] No need to test
  > - [ ] I checked and no code files have been changed.
  > <!-- Or your custom  "No need to test" reasons -->

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

<!-- compatibility change, improvement, bugfix, and new feature need a release note -->

Please refer to [Release Notes Language Style Guide](https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/release-notes-style-guide.html) to write a quality release note.

```release-note
None

Summary by CodeRabbit

  • New Features

    • FULLTEXT indexes and FTS_MATCH_WORD() are supported in Starter deployment mode; planner can push FTS predicates to columnar storage for WHERE, ORDER BY+LIMIT and projection cases.
    • Query relevance exposed as a virtual _FTS_SCORE column; EXPLAIN shows FTS index details and redacts search literals when configured.
  • Behavior / Validation

    • CREATE and usage of FULLTEXT and FTS_MATCH_WORD() enforce Starter-mode and produce clear errors for unsupported placements or storage.
  • Tests

    • Added tests covering Starter-mode guards, pushdown behavior, redaction, and invalid-usage errors.

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-tests-checked release-note-none Denotes a PR that doesn't merit a release note. labels Jun 8, 2026
@pantheon-ai

pantheon-ai Bot commented Jun 8, 2026

Copy link
Copy Markdown

@ChangRui-Ryan I've received your pull request and will start the review. I'll conduct a thorough review covering code quality, potential issues, and implementation details.

⏳ This process typically takes 10-30 minutes depending on the complexity of the changes.

ℹ️ Learn more details on Pantheon AI.

@ti-chi-bot ti-chi-bot Bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. sig/planner SIG: Planner and removed do-not-merge/needs-tests-checked labels Jun 8, 2026
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Starter-only full-text search: gates FTS in expressions and DDL, adds planner rewrite rules to push FTS to TiFlash (with virtual score column and validation), updates physical scan/operator formatting and access-path filtering to TiFlash, ensures safe cloning of QueryInfo, and adds integration tests.

Changes

Full-Text Search Planning and Execution

Layer / File(s) Summary
Deployment gating & FTS expression support
pkg/ddl/BUILD.bazel, pkg/ddl/index.go, pkg/ddl/executor.go, pkg/expression/BUILD.bazel, pkg/expression/builtin.go, pkg/expression/builtin_fts.go, pkg/expression/integration_test/BUILD.bazel, pkg/expression/integration_test/integration_test.go, pkg/sessionctx/stmtctx/stmtctx.go, pkg/ddl/cancel_test.go
Gates FTS_MATCH_WORD() on deploymode.IsStarter(), sets StatementContext.FTSFunctionIsUsed when used, validates FULLTEXT DDL in Starter mode, updates BUILD deps, and conditionally skips or configures tests for non-starter modes.
Metadata and planner flags
pkg/meta/model/table.go, pkg/planner/core/operator/logicalop/logical_datasource.go, pkg/planner/core/rule/logical_rules.go, pkg/planner/core/BUILD.bazel
Adds VirtualColFTSScoreID, FTSPushDown metadata on DataSource, imports for tipb, and new optimization flags for full-text resolver passes.
FTS query resolution and transformation rules
pkg/planner/core/fts_resolve_index.go, pkg/planner/core/optimizer.go, pkg/planner/core/task.go
Adds resolver rules for WHERE/TopN/Projection/Reject to extract FTS_MATCH_WORD(), validate indexes, push QueryInfo into scans, append a virtual _FTS_SCORE column, rewrite ORDER BY/SELECT to use the score, and reject unsupported usages. Marks fts_match_word as a heavy function.
Physical integration and TiFlash constraints
pkg/planner/core/operator/physicalop/physical_table_scan.go, pkg/planner/core/indexmerge_path.go, pkg/planner/core/operator/physicalop/tiflash_predicate_push_down.go, pkg/planner/core/stats.go
Appends FTS ColumnarIndexExtra to UsedColumnarIndexes, extends OperatorInfo formatting (with redaction support), filters access paths to TiFlash-only for FTS queries, short-circuits predicate pushdown when FTS is present, and calls cleanup during stats derivation.
Plan cloning and comprehensive testing
pkg/planner/core/plan_clone_utils.go, pkg/planner/core/fts_resolve_index_test.go, pkg/ddl/cancel_test.go
Deep-clones QueryInfo protobuf when cloning plans and adds integration tests that verify Starter-mode enforcement, TiFlash FTS pushdown / redaction, negative usage cases, and DDL cancel-test deploy-mode handling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

ok-to-test

Suggested reviewers

  • winoros
  • hawkingrei
  • AilinKid
  • YangKeao

Poem

🐰 I hopped through planner rules at dawn,
Starter gates closed till the flag was on,
TiFlash hummed and scores took flight,
Plans rewrite beneath the moonlight,
A rabbit cheers: full-text done!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title '*: support fts query for starter mode' accurately describes the main change: adding FTS query support restricted to Starter deployment mode.
Description check ✅ Passed The PR description comprehensively addresses the template requirements: it clearly states the problem (missing planner path for FTS queries), explains what changed (gates FULLTEXT to Starter mode, adds FTS predicate resolution and pushdown), includes issue reference, covers test coverage with unit/manual tests, and provides detailed implementation context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@tiprow

tiprow Bot commented Jun 8, 2026

Copy link
Copy Markdown

Hi @ChangRui-Ryan. 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.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/pingcap/tidb/issues/comments/4645305564","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- review_stack_entry_start -->\n\n[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/pingcap/tidb/pull/69012?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)\n\n<!-- review_stack_entry_end -->\n<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->\n\n> [!NOTE]\n> Currently processing new changes in this PR. This may take a few minutes, please wait...\n> \n> <details>\n> <summary>⚙️ Run configuration</summary>\n> \n> **Configuration used**: Repository UI\n> \n> **Review profile**: CHILL\n> \n> **Plan**: Pro\n> \n> **Run ID**: `fcc0aa69-5229-4c3c-b03b-0b680afe75e0`\n> \n> </details>\n> \n> <details>\n> <summary>📥 Commits</summary>\n> \n> Reviewing files that changed from the base of the PR and between d568a8528e9c0fc0246c7fc3c3bc0e69be9b1c16 and 13eb0362e15a8eb1fd2c9ce2bb4a76ee379f4cf7.\n> \n> </details>\n> \n> <details>\n> <summary>📒 Files selected for processing (22)</summary>\n> \n> * `pkg/ddl/BUILD.bazel`\n> * `pkg/ddl/executor.go`\n> * `pkg/ddl/index.go`\n> * `pkg/expression/BUILD.bazel`\n> * `pkg/expression/builtin.go`\n> * `pkg/expression/builtin_fts.go`\n> * `pkg/expression/integration_test/BUILD.bazel`\n> * `pkg/expression/integration_test/integration_test.go`\n> * `pkg/meta/model/table.go`\n> * `pkg/planner/core/BUILD.bazel`\n> * `pkg/planner/core/fts_resolve_index.go`\n> * `pkg/planner/core/fts_resolve_index_test.go`\n> * `pkg/planner/core/indexmerge_path.go`\n> * `pkg/planner/core/operator/logicalop/logical_datasource.go`\n> * `pkg/planner/core/operator/physicalop/physical_table_scan.go`\n> * `pkg/planner/core/operator/physicalop/tiflash_predicate_push_down.go`\n> * `pkg/planner/core/optimizer.go`\n> * `pkg/planner/core/plan_clone_utils.go`\n> * `pkg/planner/core/rule/logical_rules.go`\n> * `pkg/planner/core/stats.go`\n> * `pkg/planner/core/task.go`\n> * `pkg/sessionctx/stmtctx/stmtctx.go`\n> \n> </details>\n> \n> ```ascii\n>  _______________________________________________\n> < Finding your faults 10 times faster than Mom. >\n>  -----------------------------------------------\n>   \\\n>    \\   \\\n>         \\ /\\\n>         ( )\n>       .( o ).\n> ```\n\n<!-- end of auto-generated comment: review in progress by coderabbit.ai -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=pingcap/tidb&utm_content=69012)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n<!-- usage_tips_start -->\n\n> [!TIP]\n> <details>\n> <summary>CodeRabbit can generate a title for your PR based on the changes.</summary>\n> \n> Add `@coderabbitai` placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the `reviews.auto_title_placeholder` setting.\n> \n> </details>\n\n<!-- usage_tips_end -->"},"request":{"retryCount":3,"signal":{},"retries":3,"retryAfter":16}}}

@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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/planner/core/fts_resolve_index_test.go (1)

87-88: ⚡ Quick win

Consider clarifying the error messages for better user guidance.

The error message "Currently 'FTS_MATCH_WORD()' in SELECT must not be placed" (used for both line 87 and line 88 test cases) may confuse users because:

  • Line 87 tests fts_match_word in SELECT without WHERE—the actual constraint is that SELECT requires a matching WHERE clause.
  • Line 88 tests fts_match_word wrapped in an expression (* 2)—the actual constraint is that it must be used directly, not wrapped.
  • Lines 79-82 show that fts_match_word can appear in SELECT when it matches the WHERE clause exactly.

Suggested improvements:

  • Line 87 scenario: "FTS_MATCH_WORD() in SELECT requires a matching FTS_MATCH_WORD() in WHERE"
  • Line 88 scenario: "FTS_MATCH_WORD() in SELECT must not be wrapped in expressions"
🤖 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/fts_resolve_index_test.go` around lines 87 - 88, Update the
two assertions' expected error strings to be more specific: for the assertion
that checks "explain select fts_match_word('hello', title) from fts_t" (testing
SELECT without WHERE) change the expected message to indicate that
FTS_MATCH_WORD() in SELECT requires a matching FTS_MATCH_WORD() in WHERE, and
for the assertion that checks "explain select fts_match_word('hello', title) * 2
from fts_t where fts_match_word('hello', title)" (testing wrapping in an
expression) change the expected message to indicate that FTS_MATCH_WORD() in
SELECT must not be wrapped in expressions; keep the checks using
tk.MustContainErrMsg and the function name fts_match_word to locate the two
assertions.
🤖 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.

Inline comments:
In `@pkg/planner/core/fts_resolve_index.go`:
- Around line 257-263: The TopK pushdown currently computes TopK from
planTopN.Offset + planTopN.Count even when the ORDER BY has additional
tie-breakers, which can change results; update the guard in the block that
checks planSelection, ds.PushedDownConds and planTopN.ByItems[0].Desc to also
ensure planTopN.ByItems has exactly one item (e.g., len(planTopN.ByItems) == 1)
before computing and setting queryInfo.TopK, so TopK is only pushed when the FTS
score is the sole sort key; keep the existing maxFTSTopK cap logic and the
uint32Ptr conversion.

In `@pkg/planner/core/operator/physicalop/physical_table_scan.go`:
- Around line 593-597: The explain output currently writes raw FTS query text
when normalized is false (ftsIndexBuffer.WriteString(ftsQueryInfo.QueryText)),
which ignores redaction mode; update the code around where normalized and
ftsIndexBuffer are used to consult the redaction setting and, when redaction is
enabled, write a redacted placeholder (e.g., "REDACTED" or an empty/obfuscated
string) instead of ftsQueryInfo.QueryText; ensure normalized handling remains
unchanged when redaction is disabled so that normalized ? "?" :
ftsQueryInfo.QueryText logic only writes raw text when redaction is off.

---

Nitpick comments:
In `@pkg/planner/core/fts_resolve_index_test.go`:
- Around line 87-88: Update the two assertions' expected error strings to be
more specific: for the assertion that checks "explain select
fts_match_word('hello', title) from fts_t" (testing SELECT without WHERE) change
the expected message to indicate that FTS_MATCH_WORD() in SELECT requires a
matching FTS_MATCH_WORD() in WHERE, and for the assertion that checks "explain
select fts_match_word('hello', title) * 2 from fts_t where
fts_match_word('hello', title)" (testing wrapping in an expression) change the
expected message to indicate that FTS_MATCH_WORD() in SELECT must not be wrapped
in expressions; keep the checks using tk.MustContainErrMsg and the function name
fts_match_word to locate the two assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fcc0aa69-5229-4c3c-b03b-0b680afe75e0

📥 Commits

Reviewing files that changed from the base of the PR and between d568a85 and 13eb036.

📒 Files selected for processing (22)
  • pkg/ddl/BUILD.bazel
  • pkg/ddl/executor.go
  • pkg/ddl/index.go
  • pkg/expression/BUILD.bazel
  • pkg/expression/builtin.go
  • pkg/expression/builtin_fts.go
  • pkg/expression/integration_test/BUILD.bazel
  • pkg/expression/integration_test/integration_test.go
  • pkg/meta/model/table.go
  • pkg/planner/core/BUILD.bazel
  • pkg/planner/core/fts_resolve_index.go
  • pkg/planner/core/fts_resolve_index_test.go
  • pkg/planner/core/indexmerge_path.go
  • pkg/planner/core/operator/logicalop/logical_datasource.go
  • pkg/planner/core/operator/physicalop/physical_table_scan.go
  • pkg/planner/core/operator/physicalop/tiflash_predicate_push_down.go
  • pkg/planner/core/optimizer.go
  • pkg/planner/core/plan_clone_utils.go
  • pkg/planner/core/rule/logical_rules.go
  • pkg/planner/core/stats.go
  • pkg/planner/core/task.go
  • pkg/sessionctx/stmtctx/stmtctx.go

Comment thread pkg/planner/core/fts_resolve_index.go Outdated
Comment thread pkg/planner/core/operator/physicalop/physical_table_scan.go Outdated
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 4.72279% with 464 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.3233%. Comparing base (e7b15cd) to head (3599a66).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69012        +/-   ##
================================================
+ Coverage   76.3218%   76.3233%   +0.0014%     
================================================
  Files          2041       2063        +22     
  Lines        561480     576014     +14534     
================================================
+ Hits         428532     439633     +11101     
- Misses       132045     134447      +2402     
- Partials        903       1934      +1031     
Flag Coverage Δ
integration 46.0092% <4.7227%> (+6.3958%) ⬆️

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

Components Coverage Δ
dumpling 60.4610% <ø> (ø)
parser ∅ <ø> (∅)
br 64.8456% <ø> (+2.0207%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ChangRui-Ryan

Copy link
Copy Markdown
Contributor Author

/retest

@tiprow

tiprow Bot commented Jun 8, 2026

Copy link
Copy Markdown

@ChangRui-Ryan: 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.

Details

In response to this:

/retest

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.

@ChangRui-Ryan

Copy link
Copy Markdown
Contributor Author

/retest

@tiprow

tiprow Bot commented Jun 8, 2026

Copy link
Copy Markdown

@ChangRui-Ryan: 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.

Details

In response to this:

/retest

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.

@ChangRui-Ryan

Copy link
Copy Markdown
Contributor Author

/retest

@tiprow

tiprow Bot commented Jun 8, 2026

Copy link
Copy Markdown

@ChangRui-Ryan: 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.

Details

In response to this:

/retest

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 commented Jun 9, 2026

Copy link
Copy Markdown

@JaySon-Huang: adding LGTM is restricted to approvers and reviewers in OWNERS files.

Details

In response to this:

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.

Comment thread pkg/planner/core/rule/logical_rules.go Outdated
FlagEliminateProjection
FlagMaxMinEliminate
FlagConstantPropagation
FlagFullTextIndexResolveWhere

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

are those flags stored somewhere, or being part of the protocol, insert here will change value of below flags, might break stored/protocol part

Do not mess up the order.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, fixed. I kept the existing flag values stable by appending the new FTS flags and decoupling rule order from flag values with an explicit mapping, so adding these rules no longer shifts existing bits.

@ChangRui-Ryan

Copy link
Copy Markdown
Contributor Author

/retest

@tiprow

tiprow Bot commented Jun 9, 2026

Copy link
Copy Markdown

@ChangRui-Ryan: 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.

Details

In response to this:

/retest

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.

@ChangRui-Ryan

Copy link
Copy Markdown
Contributor Author

/retest

@tiprow

tiprow Bot commented Jun 13, 2026

Copy link
Copy Markdown

@ChangRui-Ryan: 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.

Details

In response to this:

/retest

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.

if err := c.verifyArgs(args); err != nil {
return nil, err
}
if !deploymode.IsStarter() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Will this will break current planner's rewrite for FTS function? From planner's view, "rewrite fts function to ilike function" should work even not in starter

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This should not affect the ILIKE fallback. The starter-mode gate is only for fts_match_word() (ast.FTSMatchWord). MATCH ... AGAINST uses the separate ast.FTSMysqlMatchAgainst builtin and its ILIKE fallback path remains unchanged.


tk.MustExec("begin")
tk.MustExec("insert into fts_t values (1, 'hello', 'dirty')")
tk.MustContainErrMsg("select * from fts_t where fts_match_word('hello', title)", "Currently 'FTS_MATCH_WORD()' must be used alone")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This error message means that the code does nothing about the dirty txn.

@ChangRui-Ryan

Copy link
Copy Markdown
Contributor Author

/retest

Comment thread pkg/planner/core/optimizer.go Outdated
// When we use the straight Join Order hint, we should disable the join reorder optimization.
flag &= ^rule.FlagJoinReOrder
}
if logic.SCtx().GetSessionVars().StmtCtx.FTSFunctionIsUsed {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

&& is starter mode

@winoros winoros left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved because it's only used in starter mode.
It needs more changes to make it generally available across all tiers.

@ti-chi-bot ti-chi-bot Bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Jun 22, 2026

@windtalker windtalker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

expression part lgtm

@ti-chi-bot ti-chi-bot Bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Jun 22, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-06-22 07:41:54.252288684 +0000 UTC m=+1982615.322606064: ☑️ agreed by winoros.
  • 2026-06-22 09:28:51.12744444 +0000 UTC m=+1989032.197761840: ☑️ agreed by windtalker.


func (p *PhysicalTableScan) hasFullTextIndexPushDown() bool {
for _, idx := range p.UsedColumnarIndexes {
if idx != nil && idx.QueryInfo != nil && idx.QueryInfo.IndexType == tipb.ColumnarIndexType_TypeFulltext {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

when will idx == nil

} else if idx.QueryInfo != nil && idx.QueryInfo.IndexType == tipb.ColumnarIndexType_TypeInverted {
invertedIndexes = append(invertedIndexes, idx.IndexInfo.Name.L)
} else if idx.QueryInfo != nil && idx.QueryInfo.IndexType == tipb.ColumnarIndexType_TypeFulltext {
ftsQueryInfo := idx.QueryInfo.GetFtsQueryInfo()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe put those to another method, already too long

@D3Hunter D3Hunter left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/approve

ddl part lgtm

@ti-chi-bot

ti-chi-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: D3Hunter, JaySon-Huang, windtalker, winoros

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 ti-chi-bot Bot added the approved label Jun 22, 2026
@D3Hunter

Copy link
Copy Markdown
Contributor

/hold

please fix existing comments

@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 Jun 22, 2026
@ChangRui-Ryan

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 Jun 22, 2026
@ti-chi-bot
ti-chi-bot Bot merged commit 6bb13b7 into pingcap:master Jun 22, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved lgtm 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.

5 participants