Skip to content

planner: validate NAME_CONST arguments like MySQL#68439

Open
hawkingrei wants to merge 3 commits into
pingcap:masterfrom
hawkingrei:issue-59459-name-const-args
Open

planner: validate NAME_CONST arguments like MySQL#68439
hawkingrei wants to merge 3 commits into
pingcap:masterfrom
hawkingrei:issue-59459-name-const-args

Conversation

@hawkingrei
Copy link
Copy Markdown
Member

@hawkingrei hawkingrei commented May 17, 2026

What problem does this PR solve?

Issue Number: close #59459

Problem Summary:

NAME_CONST() accepted TRUE / FALSE pseudo-literals but rejected PI(), which is incompatible with MySQL. MySQL returns incorrect-arguments errors for the boolean pseudo-literals and accepts NAME_CONST('pi', PI()).

What changed and how does it work?

This PR keeps the fix local to NAME_CONST preprocessing validation:

  • reject TRUE / FALSE pseudo-literals by checking the parser value expression's boolean flag;
  • keep ordinary literal and unary literal values valid;
  • allow the MySQL-compatible special case PI() as a zero-argument function value;
  • keep other expression/function values rejected.

The expression evaluation signatures are unchanged. The owner path is pkg/planner/core/preprocess.go, where NAME_CONST already validates constant-like arguments before expression building.

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.

Fix NAME_CONST() argument validation to reject TRUE and FALSE pseudo-literals and accept PI(), matching MySQL behavior.

Tests

go test --tags=intest ./pkg/expression/integration_test -run TestNameConstBuiltin -count=1
go test ./pkg/expression -run TestNameConst -count=1
make bazel_prepare
git diff --check

Summary by CodeRabbit

  • Bug Fixes

    • Improved validation for name_const(): rejects boolean pseudo-literals, accepts unary +/- numeric expressions (including parenthesized), and recognizes pi() when called with no arguments; clearer errors for invalid name/value combinations.
  • Tests

    • Added an integration test covering successful and failing name_const() cases, numeric/string/NULL handling, unary/parenthesized expressions, and expected error conditions.

Review Change Stack

@ti-chi-bot ti-chi-bot Bot added 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. labels May 17, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d0c248a5-1cc8-421d-ad79-599f910536c7

📥 Commits

Reviewing files that changed from the base of the PR and between 10f88cd and 59ef32b.

📒 Files selected for processing (2)
  • pkg/expression/integration_test/integration_test.go
  • pkg/planner/core/preprocess.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/planner/core/preprocess.go
  • pkg/expression/integration_test/integration_test.go

📝 Walkthrough

Walkthrough

Centralize NAME_CONST second-argument validation in the planner via helper functions that enforce accepted AST forms (reject boolean pseudo-literals, allow unary-wrapped values and PI() with zero args) and add an integration test verifying accepted and rejected argument patterns and planner errors.

Changes

NAME_CONST Validation

Layer / File(s) Summary
NAME_CONST validation implementation
pkg/planner/core/preprocess.go
Updated planner Leave visitor to validate NAME_CONST's second argument through isValidNameConstValue and added isValidNameConstUnaryValue helpers that reject boolean pseudo-literals (value expr booleans), permit unary operations wrapping valid non-boolean value-exprs, and allow zero-arg PI() calls.
Integration test coverage
pkg/expression/integration_test/integration_test.go
Added TestNameConstBuiltin to assert NAME_CONST accepts valid constant/value pairs (including pi()), handles negative numeric, string, and NULL cases (including -(1)), and returns planner error [planner:1210]Incorrect arguments to NAME_CONST for boolean pseudo-literals, compound expressions, and unevaluable calls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through ASTs, keen and spry,
NAME_CONST now knows the rules to try.
No booleans sneaking in the fold,
PI and negatives handled bold.
A carrot-coded test — success! 🎋

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 clearly summarizes the main change: validating NAME_CONST arguments to align with MySQL behavior, which is the core objective of the PR.
Description check ✅ Passed The description comprehensively covers the problem, solution, changes made, includes proper issue reference, test checklist, and release notes following the template structure.
Linked Issues check ✅ Passed Code changes fully address issue #59459 objectives: reject TRUE/FALSE pseudo-literals, accept PI() as zero-argument function, and maintain existing literal/unary literal validation.
Out of Scope Changes check ✅ Passed All changes are directly scoped to NAME_CONST argument validation in preprocess.go and corresponding integration tests, with no extraneous modifications 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

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.

@hawkingrei hawkingrei added the AI-Correction Bugfix by AI label May 17, 2026
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.

Actionable comments posted: 1

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

762-769: ⚡ Quick win

Add doc comment explaining unary value validation rules.

The function validates unary-wrapped values for NAME_CONST but lacks documentation. Add a comment explaining:

  • Why only ValueExpr is accepted inside unary operations
  • Why boolean pseudo-literals are rejected even when wrapped
📝 Suggested doc comment
+// isValidNameConstUnaryValue validates unary operations wrapping the second NAME_CONST argument.
+// MySQL accepts unary operations only when they wrap ordinary literals (not boolean pseudo-literals
+// or function calls). For example, -5 is accepted, but -TRUE and -PI() are rejected.
 func isValidNameConstUnaryValue(arg *ast.UnaryOperationExpr) bool {

As per coding guidelines, comments should explain non-obvious intent and SQL/compatibility contracts.

🤖 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/preprocess.go` around lines 762 - 769, Add a doc comment
above isValidNameConstUnaryValue that explains the validation rules: clarify
that the function only accepts an ast.UnaryOperationExpr whose inner expression
is a *driver.ValueExpr (so only literal/constant values are allowed, not nested
expressions or identifiers), and state that boolean pseudo-literals are
explicitly rejected by checking mysql.HasIsBooleanFlag(v.Type.GetFlag()) even
when wrapped in a unary operation to preserve SQL compatibility and prevent
treating boolean-like tokens as numeric/string NAME_CONST values; reference the
function name isValidNameConstUnaryValue, the parameter type
ast.UnaryOperationExpr, the inner type *driver.ValueExpr, and the flag check
mysql.HasIsBooleanFlag(v.Type.GetFlag()) in the comment.
pkg/expression/integration_test/integration_test.go (1)

1571-1583: ⚡ Quick win

Consider adding a test case for non-PI() function rejection.

The test verifies that PI() is accepted as a special-case zero-argument function, but doesn't verify that other functions are rejected. According to the PR objectives, PI() is specifically mentioned as a "MySQL-compatible special case" and other functions should continue to be rejected.

Adding a test for a non-PI() function (e.g., NOW(), UUID(), or RAND()) would confirm that the validation specifically allows only PI() rather than all zero-argument functions.

Suggested addition
 	tk.MustGetErrMsg("select /* issue:59459 */ name_const('bool1', true)", "[planner:1210]Incorrect arguments to NAME_CONST")
 	tk.MustGetErrMsg("select /* issue:59459 */ name_const('bool2', false)", "[planner:1210]Incorrect arguments to NAME_CONST")
 	tk.MustQuery("select /* issue:59459 */ name_const('pi', pi())").Check(testkit.Rows("3.141592653589793"))
+	tk.MustGetErrMsg("select name_const('now', now())", "[planner:1210]Incorrect arguments to NAME_CONST")

 	tk.MustQuery("select name_const('neg', -1), name_const('negd', -1.0), name_const('str', 'x'), name_const('nil', null)").Check(testkit.Rows("-1 -1.0 x <nil>"))
 	tk.MustGetErrMsg("select name_const('expr', 1+1)", "[planner:1210]Incorrect arguments to NAME_CONST")
🤖 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/expression/integration_test/integration_test.go` around lines 1571 -
1583, Add a test in TestNameConstBuiltin to assert that only PI() is allowed as
a zero-argument function for name_const and that other zero-arg functions are
rejected; specifically add a MustGetErrMsg call using name_const('bad', NOW())
(or RAND()/UUID()) expecting "[planner:1210]Incorrect arguments to NAME_CONST"
to ensure name_const accepts PI() but not other zero-arg functions. Locate the
test in the integration_test.go TestNameConstBuiltin function where existing
name_const checks are and add the new assertion next to the PI() and other error
cases.
🤖 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/preprocess.go`:
- Around line 748-760: The function isValidNameConstValue implements
MySQL-specific NAME_CONST validation but lacks a doc comment explaining the
compatibility contract; add a clear doc comment above isValidNameConstValue that
states: this function enforces MySQL NAME_CONST rules (accept only literal
values, unary expressions validated by isValidNameConstUnaryValue, and the
special-case PI() with zero args), explicitly note that driver.ValueExprs with
boolean pseudo-literals are rejected by checking
mysql.HasIsBooleanFlag(v.Type.GetFlag()), and describe the overall validation
contract so callers understand why driver.ValueExpr, ast.UnaryOperationExpr, and
ast.FuncCallExpr (with ast.PI and zero args) are treated specially.

---

Nitpick comments:
In `@pkg/expression/integration_test/integration_test.go`:
- Around line 1571-1583: Add a test in TestNameConstBuiltin to assert that only
PI() is allowed as a zero-argument function for name_const and that other
zero-arg functions are rejected; specifically add a MustGetErrMsg call using
name_const('bad', NOW()) (or RAND()/UUID()) expecting "[planner:1210]Incorrect
arguments to NAME_CONST" to ensure name_const accepts PI() but not other
zero-arg functions. Locate the test in the integration_test.go
TestNameConstBuiltin function where existing name_const checks are and add the
new assertion next to the PI() and other error cases.

In `@pkg/planner/core/preprocess.go`:
- Around line 762-769: Add a doc comment above isValidNameConstUnaryValue that
explains the validation rules: clarify that the function only accepts an
ast.UnaryOperationExpr whose inner expression is a *driver.ValueExpr (so only
literal/constant values are allowed, not nested expressions or identifiers), and
state that boolean pseudo-literals are explicitly rejected by checking
mysql.HasIsBooleanFlag(v.Type.GetFlag()) even when wrapped in a unary operation
to preserve SQL compatibility and prevent treating boolean-like tokens as
numeric/string NAME_CONST values; reference the function name
isValidNameConstUnaryValue, the parameter type ast.UnaryOperationExpr, the inner
type *driver.ValueExpr, and the flag check
mysql.HasIsBooleanFlag(v.Type.GetFlag()) in the comment.
🪄 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: 75160f2a-4ecd-43e8-aaea-5c82633476d3

📥 Commits

Reviewing files that changed from the base of the PR and between 6a6eefe and 51f14bf.

📒 Files selected for processing (2)
  • pkg/expression/integration_test/integration_test.go
  • pkg/planner/core/preprocess.go

Comment thread pkg/planner/core/preprocess.go
@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

❌ Patch coverage is 79.16667% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.4903%. Comparing base (6a6eefe) to head (59ef32b).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #68439        +/-   ##
================================================
- Coverage   77.2762%   76.4903%   -0.7860%     
================================================
  Files          2010       1992        -18     
  Lines        555477     557631      +2154     
================================================
- Hits         429252     426534      -2718     
- Misses       125305     131053      +5748     
+ Partials        920         44       -876     
Flag Coverage Δ
integration 41.5393% <79.1666%> (+1.7452%) ⬆️

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

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

@hawkingrei
Copy link
Copy Markdown
Member Author

/retest-required

@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 18, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: qw4990
Once this PR has been reviewed and has the lgtm label, please assign zanmato1984 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 the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label May 18, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 18, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-05-18 02:56:47.510318092 +0000 UTC m=+146537.014448768: ☑️ agreed by qw4990.

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

Labels

AI-Correction Bugfix by AI needs-1-more-lgtm Indicates a PR needs 1 more LGTM. 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.

NAME_CONST accepts different kind of arguments compared with MySQL

2 participants