Skip to content

planner: recheck prepared preprocess sysvars#68194

Open
hawkingrei wants to merge 1 commit into
pingcap:masterfrom
hawkingrei:fix/issue-65266-preprocess-check
Open

planner: recheck prepared preprocess sysvars#68194
hawkingrei wants to merge 1 commit into
pingcap:masterfrom
hawkingrei:fix/issue-65266-preprocess-check

Conversation

@hawkingrei
Copy link
Copy Markdown
Member

@hawkingrei hawkingrei commented May 7, 2026

What problem does this PR solve?

Issue Number: close #65266

Problem Summary:

Prepared statements can skip Preprocess validations after session variables that affect those checks change between PREPARE and EXECUTE. This can make EXECUTE accept SQL that direct execution would reject, such as FOR SHARE after disabling shared-lock promotion or duplicate aliases after leaving Oracle SQL mode.

What changed and how does it work?

This PR records the Preprocess-sensitive session variables on PlanCacheStmt at prepare time:

  • SQLMode
  • noop-functions mode
  • shared-lock promotion

During prepared execution, planCachePreprocess now reruns Preprocess when those values differ from the current session state, even if the schema version is unchanged. Schema-change errors still keep the existing ErrSchemaChanged wrapping, while sysvar-driven validation failures return the original validation error so they match direct execution behavior.

The session-level prepare dedup cache also records the current Preprocess state when rebuilding a statement from the cached template.

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.

Focused validation reported for this patch:

./tools/check/failpoint-go-test.sh pkg/executor/test/issuetest -run TestPrepareExecutePreprocessChecksAfterSysvarChange -count=1
go test -p=1 -tags=intest,deadlock ./pkg/planner/core/tests/prepare -run TestCacheHitInForUpdateRead -count=1
go test -p=1 -tags=intest,deadlock ./pkg/executor/test/plancache -run TestPreparedPlanCacheSessionInteractions -count=1
make bazel_prepare
git -c core.fsmonitor=false diff --check HEAD~1..HEAD

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.

Fix an issue that prepared statement execution could skip preprocess validation after SQL mode or shared-lock promotion changes.

Summary by CodeRabbit

Release Notes

  • Tests

    • Added test for prepared statement behavior when system variables affecting query execution change
  • Bug Fixes

    • Improved prepared statement cache handling to properly detect and respond to changes in SQL mode, shared lock promotion, and noop function settings

@ti-chi-bot ti-chi-bot Bot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label May 7, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 7, 2026

[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 0xpoe 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

@ti-chi-bot ti-chi-bot Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. sig/planner SIG: Planner labels May 7, 2026
@hawkingrei hawkingrei added the AI-Correction Bugfix by AI label May 7, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

📝 Walkthrough

Walkthrough

This PR addresses plan cache preprocessing validation when system variables change during prepared statement execution. New fields track preprocessing configuration state (SQL mode, noop-funcs mode, shared-lock promotion) on cached statements. Logic differentiates schema-version failures from other preprocessing errors and re-checks preprocessing conditions before cache hits. A test validates behavior across variable enable/disable cycles.

Changes

Plan Cache Preprocessing Checks for Sysvar Changes

Layer / File(s) Summary
Data Shape
pkg/planner/core/plan_cache_utils.go
PlanCacheStmt gains three new exported fields: PreprocessSQLMode, PreprocessNoopFuncsMode, and PreprocessSharedLockPromotion to store immutable preprocessing configuration.
Core Logic
pkg/planner/core/plan_cache.go
planCachePreprocess now computes preprocessing variable changes alongside schema version mismatches, re-preprocesses when either changes, stores updated preprocess mode values back on the statement, and distinguishes schema-version failures from other preprocessing errors.
Initialization & Wiring
pkg/planner/core/plan_cache_utils.go, pkg/session/session.go
GeneratePlanCacheStmtWithAST and rebuildFromPrepareCache populate the new preprocessing fields from session state and copy them from cached templates during prepared statement rebuilding.
Test Coverage & Execution
pkg/executor/test/issuetest/executor_issue_test.go, pkg/executor/test/issuetest/BUILD.bazel
New test TestPrepareExecutePreprocessChecksAfterSysvarChange validates that preprocessing checks trigger correctly when @@tidb_enable_shared_lock_promotion and sql_mode change across PREPARE/EXECUTE cycles; test shard count increased from 25 to 26.

Sequence Diagram

sequenceDiagram
    actor User
    participant Session
    participant PlanCache as Plan Cache<br/>(Planner)
    participant Executor

    rect rgba(200, 150, 255, 0.5)
    Note over User,Executor: Prepare Statement (captures sysvar state)
    User->>Session: PREPARE stmt FROM 'SELECT ... FOR SHARE'
    Session->>PlanCache: GeneratePlanCacheStmtWithAST()
    PlanCache->>PlanCache: Store PreprocessSQLMode,<br/>PreprocessNoopFuncsMode,<br/>PreprocessSharedLockPromotion
    PlanCache-->>Session: Return PlanCacheStmt
    Session-->>User: Prepared
    end

    rect rgba(255, 200, 150, 0.5)
    Note over User,Executor: Change System Variable
    User->>Session: SET @@tidb_enable_shared_lock_promotion = 0
    Session->>Session: Update session sysvar
    end

    rect rgba(150, 200, 255, 0.5)
    Note over User,Executor: Execute Statement (check if preprocess changed)
    User->>Session: EXECUTE stmt
    Session->>PlanCache: planCachePreprocess()
    PlanCache->>PlanCache: Compare current session sysvars<br/>vs. stored PreprocessSQLMode, etc.
    alt Preprocess vars changed
        PlanCache->>PlanCache: Trigger re-preprocessing
        PlanCache->>PlanCache: Validation fails<br/>(FOR SHARE not allowed)
        PlanCache-->>Session: Return error
    else Preprocess vars match
        PlanCache-->>Session: Use cached plan
    end
    Session-->>User: Execution result/error
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • pingcap/tidb#67857: Directly related plan cache flow modifications—both add and sync preprocess-related fields on PlanCacheStmt, updating rebuildFromPrepareCache and plan cache utilities together.
  • pingcap/tidb#67820: Directly related code paths—both modify struct field initialization and preprocessing configuration population in GeneratePlanCacheStmtWithAST and related plan cache construction.

Suggested Labels

ok-to-test, approved, lgtm

Suggested Reviewers

  • YangKeao
  • yudongusa

Poem

A rabbit hops through cache so deep,
Sysvars change—no silent sleep!
Re-check and test with care,
PREPARE meets EXECUTE fair! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% 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 title 'planner: recheck prepared preprocess sysvars' clearly and specifically describes the main change: fixing prepared statement preprocessing to recheck session variables affecting validation.
Description check ✅ Passed The description includes the issue link, problem summary, explanation of changes, checked integration test, affected behavior documentation, and release note. The required sections are present and completed.
Linked Issues check ✅ Passed The code changes implement the fix for issue #65266 by adding preprocessing state tracking (SQLMode, noop-functions mode, shared-lock promotion) to PlanCacheStmt and re-running Preprocess when these values differ during execution.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the prepared statement preprocessing issue: test addition, plan cache logic updates, preprocessing state tracking in PlanCacheStmt, and session cache rebuilding. No out-of-scope changes detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pkg/executor/test/issuetest/executor_issue_test.go (1)

95-95: ⚡ Quick win

Use an explicit non-Oracle sql_mode instead of default for determinism.

At Line 95, set sql_mode = default can become brittle if defaults change. Prefer setting an explicit non-Oracle mode (or empty mode) so this test remains stable.

Proposed tweak
-	tk.MustExec("set sql_mode = default")
+	tk.MustExec("set sql_mode = ''")

As per coding guidelines "Keep test changes minimal and deterministic; avoid broad golden/testdata churn unless required."

🤖 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/executor/test/issuetest/executor_issue_test.go` at line 95, The test
currently runs tk.MustExec("set sql_mode = default") which is brittle; change
this call so it sets an explicit, non-Oracle sql_mode string (for example an
empty mode "" or a deterministic mode like
"NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES") instead of "default". Locate the
tk.MustExec invocation in executor_issue_test.go and replace the argument to set
sql_mode with the chosen explicit mode so the test behavior is deterministic
across environments.
🤖 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/executor/test/issuetest/executor_issue_test.go`:
- Line 95: The test currently runs tk.MustExec("set sql_mode = default") which
is brittle; change this call so it sets an explicit, non-Oracle sql_mode string
(for example an empty mode "" or a deterministic mode like
"NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES") instead of "default". Locate the
tk.MustExec invocation in executor_issue_test.go and replace the argument to set
sql_mode with the chosen explicit mode so the test behavior is deterministic
across environments.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6675167f-55b7-4af4-82a3-ea3439f78007

📥 Commits

Reviewing files that changed from the base of the PR and between 84d8269 and b052745.

📒 Files selected for processing (5)
  • pkg/executor/test/issuetest/BUILD.bazel
  • pkg/executor/test/issuetest/executor_issue_test.go
  • pkg/planner/core/plan_cache.go
  • pkg/planner/core/plan_cache_utils.go
  • pkg/session/session.go

@hawkingrei
Copy link
Copy Markdown
Member Author

/retest

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

❌ Patch coverage is 62.22222% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.0571%. Comparing base (9d1ac81) to head (b052745).
⚠️ Report is 14 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #68194        +/-   ##
================================================
- Coverage   77.7620%   77.0571%   -0.7050%     
================================================
  Files          1990       1972        -18     
  Lines        551774     554386      +2612     
================================================
- Hits         429071     427194      -1877     
- Misses       121783     127044      +5261     
+ Partials        920        148       -772     
Flag Coverage Δ
integration 41.4959% <62.2222%> (+1.6941%) ⬆️

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

Components Coverage Δ
dumpling 60.4888% <ø> (ø)
parser ∅ <ø> (∅)
br 50.0597% <ø> (-13.0338%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hawkingrei
Copy link
Copy Markdown
Member Author

/retest

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

Labels

AI-Correction Bugfix by AI release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/planner SIG: Planner size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Checks in Preprocess doesn't work with PREPARE/EXECUTE

1 participant