Skip to content

planner: add more test cases for column privilege | tidb-test=pr/2704#66542

Merged
ti-chi-bot[bot] merged 1 commit intopingcap:release-8.5from
ti-chi-bot:cherry-pick-62241-to-release-8.5
Mar 11, 2026
Merged

planner: add more test cases for column privilege | tidb-test=pr/2704#66542
ti-chi-bot[bot] merged 1 commit intopingcap:release-8.5from
ti-chi-bot:cherry-pick-62241-to-release-8.5

Conversation

@ti-chi-bot
Copy link
Copy Markdown
Member

@ti-chi-bot ti-chi-bot commented Feb 26, 2026

This is an automated cherry-pick of #62241

What problem does this PR solve?

Issue Number: ref #61706

Problem Summary:

What changed and how does it work?

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

Release Notes

  • Bug Fixes

    • Refined privilege checks for column-level operations in INSERT ... ON DUPLICATE KEY UPDATE and IMPORT INTO ... FROM SELECT statements.
    • Privilege denial error messages now report column-specific access denials instead of table-level denials for improved clarity.
  • Tests

    • Extended test coverage for column-level privilege handling in REVOKE, TRACE, and EXPLAIN operations.
    • Added comprehensive test cases for column-level privileges across DML/DDL operations, JOINs, Views, and CTEs.

@ti-chi-bot ti-chi-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. 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. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR. labels Feb 26, 2026
@ti-chi-bot ti-chi-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Feb 26, 2026
@ti-chi-bot ti-chi-bot added release-note-none Denotes a PR that doesn't merit a release note. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR. labels Feb 26, 2026
@ti-chi-bot
Copy link
Copy Markdown
Member Author

@CbcWestwolf This PR has conflicts, I have hold it.
Please resolve them or ask others to resolve them, then comment /unhold to remove the hold label.

@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Feb 26, 2026

@ti-chi-bot: ## If you want to know how to resolve it, please read the guide in TiDB Dev Guide.

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 ti-community-infra/tichi repository.

@tiprow
Copy link
Copy Markdown

tiprow Bot commented Feb 26, 2026

@ti-chi-bot: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
fast_test_tiprow_for_release c92f198 link true /test fast_test_tiprow_for_release

Full PR test history. Your PR dashboard.

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. I understand the commands that are listed here.

@ti-chi-bot ti-chi-bot Bot added cherry-pick-approved Cherry pick PR approved by release team. and removed do-not-merge/cherry-pick-not-approved labels Mar 3, 2026
Copy link
Copy Markdown
Member

@winoros winoros left a comment

Choose a reason for hiding this comment

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

don't forget to resolve conflicts

@ti-chi-bot ti-chi-bot Bot added needs-1-more-lgtm Indicates a PR needs 1 more LGTM. approved labels Mar 11, 2026
@fzzf678 fzzf678 force-pushed the cherry-pick-62241-to-release-8.5 branch from c92f198 to c63474e Compare March 11, 2026 15:29
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

This pull request expands column-level privilege checking across the query planner and executor. Key changes include per-column UPDATE privilege validation for INSERT ON DUPLICATE KEY UPDATE operations, updated column name resolution in join coalescing, comprehensive test coverage for column-level privileges in various DML/DDL scenarios, and new privilege tests for REVOKE, TRACE, EXPLAIN, and IMPORT INTO operations.

Changes

Cohort / File(s) Summary
Planner Core Privilege & Coalescing
pkg/planner/core/planbuilder.go, pkg/planner/core/logical_plan_builder.go
Modified resolveOnDuplicate to accept PlanBuilder context and perform per-column UPDATE privilege checks during INSERT ON DUPLICATE KEY UPDATE resolution. Changed column name selection in coalesceCommonColumns from using original left/right names to reordered common-name references for correct privilege tracking.
Planner Test Coverage Expansion
pkg/planner/core/logical_plans_test.go
Significantly expanded test cases for column-level privilege expectations across DML operations (INSERT, REPLACE, DELETE), various JOIN forms (INNER, OUTER, CROSS, NATURAL, USING, STRAIGHT_JOIN), and VIEW-related scenarios. Added tests for complex queries combining CTEs, window functions, and subqueries.
Privilege System & Executor Tests
pkg/executor/revoke_test.go, pkg/privilege/privileges/privileges_test.go
Added test scenarios for column-level REVOKE operations and new test suite TestColumnPrivilege4TraceAndExplain validating column-level privileges in TRACE/EXPLAIN contexts. Extended existing privilege tests with column-scoped access patterns for LOAD DATA, SELECT in subqueries/CTEs, and IMPORT INTO operations.
Integration Test Results & Expectations
tests/integrationtest/t/privilege/privileges.test, tests/integrationtest/r/privilege/privileges.result
Updated error expectations for INSERT ON DUPLICATE KEY UPDATE from table-level (ErrTableaccessDenied) to column-level (ErrColumnaccessDenied) denial, reflecting per-column privilege validation behavior.
IMPORT INTO Privilege Tests
tests/realtikvtest/importintotest2/BUILD.bazel, tests/realtikvtest/importintotest2/from_select_test.go
Added new test case TestImportFromSelectPrivilege validating per-column privilege enforcement for IMPORT INTO ... FROM SELECT operations. Updated build configuration with required auth and mysql parser dependencies.

Sequence Diagram(s)

sequenceDiagram
    participant User as User/Session
    participant Planner as Query Planner
    participant PrivilegeChecker as Privilege Checker
    participant Executor as Executor
    
    User->>Planner: INSERT ... ON DUPLICATE KEY UPDATE
    Planner->>Planner: Parse INSERT statement
    Planner->>PrivilegeChecker: Check INSERT privilege on table
    PrivilegeChecker-->>Planner: ✓ Table privilege granted
    Planner->>Planner: Resolve ON DUPLICATE columns
    Planner->>PrivilegeChecker: Check UPDATE privilege per column
    PrivilegeChecker-->>Planner: ✓ Column privileges validated
    Planner->>Planner: Generate execution plan with visitInfo
    Planner-->>Executor: Plan + per-column privilege metadata
    Executor->>Executor: Execute INSERT or UPDATE as needed
    Executor-->>User: Result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • wjhuang2016
  • winoros
  • AilinKid

Poem

🐰 Column privileges now dance with care,
Per-column checks float through the air,
INSERT with UPDATE, no secrets hide,
Each column guarded, verified with pride!
🔐✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description covers required sections: issue reference, problem summary, explanation of changes, and completed checklist with unit tests selected.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding more test cases for column privilege, which aligns with the extensive test additions and privilege-checking enhancements across multiple test files and modules.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
pkg/planner/core/planbuilder.go (1)

4300-4326: ⚠️ Potential issue | 🟠 Major

Use resolved target-table metadata for the UPDATE privilege entry.

This new visitInfo is derived from p.tableColNames[idx], but those names come from the output-name list built with tn.Schema. For unqualified INSERT INTO t ... ON DUPLICATE KEY UPDATE ..., that can leave the DB name empty and record the UPDATE privilege at the wrong scope. Please pass the resolved DB name/table name into resolveOnDuplicate and build the privilege entry from the target table metadata instead of FieldName.

Suggested fix
-	onDupColSet, err := insertPlan.resolveOnDuplicate(insert.OnDuplicate, tableInfo, b, func(node ast.ExprNode) (expression.Expression, error) {
+	onDupColSet, err := insertPlan.resolveOnDuplicate(insert.OnDuplicate, tnW.DBInfo.Name.L, tableInfo, b, func(node ast.ExprNode) (expression.Expression, error) {
 		return b.rewriteInsertOnDuplicateUpdate(ctx, node, mockTablePlan, insertPlan)
 	})
-func (p *Insert) resolveOnDuplicate(onDup []*ast.Assignment, tblInfo *model.TableInfo, b *PlanBuilder, yield func(ast.ExprNode) (expression.Expression, error)) (map[string]struct{}, error) {
+func (p *Insert) resolveOnDuplicate(onDup []*ast.Assignment, dbName string, tblInfo *model.TableInfo, b *PlanBuilder, yield func(ast.ExprNode) (expression.Expression, error)) (map[string]struct{}, error) {
 	onDupColSet := make(map[string]struct{}, len(onDup))
 	colMap := make(map[string]*table.Column, len(p.Table.Cols()))
 	for _, col := range p.Table.Cols() {
 		colMap[col.Name.L] = col
 	}
 	user := b.ctx.GetSessionVars().User
 	for _, assign := range onDup {
@@
-		fieldName := p.tableColNames[idx]
 		var authErr error
 		if user != nil {
-			authErr = plannererrors.ErrColumnaccessDenied.FastGenByArgs("UPDATE", user.AuthUsername, user.AuthHostname, fieldName.OrigColName.L, fieldName.OrigTblName.L)
+			authErr = plannererrors.ErrColumnaccessDenied.FastGenByArgs("UPDATE", user.AuthUsername, user.AuthHostname, column.Name.L, tblInfo.Name.L)
 		}
-		b.visitInfo = appendVisitInfo(b.visitInfo, mysql.UpdatePriv, fieldName.DBName.L, fieldName.OrigTblName.L, fieldName.OrigColName.L, authErr)
+		b.visitInfo = appendVisitInfo(b.visitInfo, mysql.UpdatePriv, dbName, tblInfo.Name.L, column.Name.L, authErr)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/planbuilder.go` around lines 4300 - 4326, The UPDATE
privilege entry currently uses fieldName (from p.tableColNames) which can lack
the resolved DB/table; instead use the resolved target table metadata (tblInfo)
when building the privilege and auth error. In resolveOnDuplicate, replace uses
of fieldName.DBName.L and fieldName.OrigTblName.L in the appendVisitInfo call
(and the FastGenByArgs creation of authErr) with the resolved names from tblInfo
(e.g., tblInfo.DBName.L and tblInfo.Name.L) while keeping the column name from
fieldName.OrigColName.L so the UPDATE privilege is recorded at the correct
DB/table scope.
pkg/planner/core/logical_plans_test.go (2)

1876-1881: ⚠️ Potential issue | 🟡 Minor

Error message column mismatch in test case.

Line 1879 specifies column "d" in the visitInfo but the error message references "c" in FastGenByArgs. This appears to be a copy-paste error.

Proposed fix
-				{mysql.SelectPriv, "test", "t", "d", plannererrors.ErrColumnaccessDenied.FastGenByArgs("SELECT", "", "", "c", "t"), false, nil, false},
+				{mysql.SelectPriv, "test", "t", "d", plannererrors.ErrColumnaccessDenied.FastGenByArgs("SELECT", "", "", "d", "t"), false, nil, false},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/logical_plans_test.go` around lines 1876 - 1881, The test
has a copy-paste error in the visitInfo row for column "d": the expected error
constructed by plannererrors.ErrColumnaccessDenied.FastGenByArgs uses "c"
instead of "d", causing a mismatch; update the FastGenByArgs call in that entry
so the column argument is "d" (i.e., make the FastGenByArgs call match the
visitInfo column "d") to fix the assertion.

1923-1928: ⚠️ Potential issue | 🟡 Minor

Error message column mismatch in test case.

Line 1926 has the same issue: the visitInfo specifies column "d" but the error message references "c".

Proposed fix
-				{mysql.SelectPriv, "test", "t", "d", plannererrors.ErrColumnaccessDenied.FastGenByArgs("SELECT", "", "", "c", "t"), false, nil, false},
+				{mysql.SelectPriv, "test", "t", "d", plannererrors.ErrColumnaccessDenied.FastGenByArgs("SELECT", "", "", "d", "t"), false, nil, false},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/logical_plans_test.go` around lines 1923 - 1928, The test
data has a mismatch: the visitInfo (column "d") but the expected error uses "c";
update the fourth entry in the table so the
plannererrors.ErrColumnaccessDenied.FastGenByArgs call uses "d" (i.e.,
FastGenByArgs("SELECT", "", "", "d", "t")) to match the visitInfo; locate the
entries in the test slice in logical_plans_test.go (the rows with
mysql.SelectPriv, "test", "t", ...) and fix only the error message argument for
the row that currently repeats "c".
🧹 Nitpick comments (1)
tests/realtikvtest/importintotest2/from_select_test.go (1)

178-180: Assert the denied column name here, not just error 1143.

This loop currently passes on any column-access failure. Since the regression is specifically about per-column privilege resolution, checking that the error mentions the current ungranted column (a, then b, then c) would make the test much more diagnostic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/realtikvtest/importintotest2/from_select_test.go` around lines 178 -
180, The test currently only checks for mysql.ErrColumnaccessDenied in the loop
(using userTk.MustGetErrCode(importSQL,...)) which doesn't verify which column
caused the denial; change the call to capture the actual error (e.g. use a
variant that returns error instead of MustGetErrCode) when running importSQL,
then assert that err != nil, that errors.Is(err, mysql.ErrColumnaccessDenied)
and that err.Error() contains the current colName (use fmt.Sprintf("%q",
colName) or fmt.Sprintf("column %s", colName) as appropriate) so the loop
verifies the denied column for each iteration (referencing importSQL,
userTk.MustGetErrCode usage and grantSQL in the loop).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/realtikvtest/importintotest2/from_select_test.go`:
- Around line 162-183: This test leaks global state by creating/using the shared
"test" schema and a global user; update TestImportFromSelectPrivilege to operate
entirely in the suite-local schema returned by prepareAndUseDB("from_select")
instead of hard-coded "test" (replace "test.t" and "test.t1" with the local
schema-qualified names or use the test kit's current DB), create and grant the
user scoped to that local schema (or ensure the user is dropped in teardown),
and remove any global fixtures by adding explicit DROP USER and DROP TABLE
cleanup inside the test (or use defer teardown) so all resources created by
TestImportFromSelectPrivilege (functions: TestImportFromSelectPrivilege,
prepareAndUseDB, userTk.Session().Auth, and the GRANT/IMPORT statements) stay
local and are always cleaned up.

---

Outside diff comments:
In `@pkg/planner/core/logical_plans_test.go`:
- Around line 1876-1881: The test has a copy-paste error in the visitInfo row
for column "d": the expected error constructed by
plannererrors.ErrColumnaccessDenied.FastGenByArgs uses "c" instead of "d",
causing a mismatch; update the FastGenByArgs call in that entry so the column
argument is "d" (i.e., make the FastGenByArgs call match the visitInfo column
"d") to fix the assertion.
- Around line 1923-1928: The test data has a mismatch: the visitInfo (column
"d") but the expected error uses "c"; update the fourth entry in the table so
the plannererrors.ErrColumnaccessDenied.FastGenByArgs call uses "d" (i.e.,
FastGenByArgs("SELECT", "", "", "d", "t")) to match the visitInfo; locate the
entries in the test slice in logical_plans_test.go (the rows with
mysql.SelectPriv, "test", "t", ...) and fix only the error message argument for
the row that currently repeats "c".

In `@pkg/planner/core/planbuilder.go`:
- Around line 4300-4326: The UPDATE privilege entry currently uses fieldName
(from p.tableColNames) which can lack the resolved DB/table; instead use the
resolved target table metadata (tblInfo) when building the privilege and auth
error. In resolveOnDuplicate, replace uses of fieldName.DBName.L and
fieldName.OrigTblName.L in the appendVisitInfo call (and the FastGenByArgs
creation of authErr) with the resolved names from tblInfo (e.g.,
tblInfo.DBName.L and tblInfo.Name.L) while keeping the column name from
fieldName.OrigColName.L so the UPDATE privilege is recorded at the correct
DB/table scope.

---

Nitpick comments:
In `@tests/realtikvtest/importintotest2/from_select_test.go`:
- Around line 178-180: The test currently only checks for
mysql.ErrColumnaccessDenied in the loop (using
userTk.MustGetErrCode(importSQL,...)) which doesn't verify which column caused
the denial; change the call to capture the actual error (e.g. use a variant that
returns error instead of MustGetErrCode) when running importSQL, then assert
that err != nil, that errors.Is(err, mysql.ErrColumnaccessDenied) and that
err.Error() contains the current colName (use fmt.Sprintf("%q", colName) or
fmt.Sprintf("column %s", colName) as appropriate) so the loop verifies the
denied column for each iteration (referencing importSQL, userTk.MustGetErrCode
usage and grantSQL in the loop).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 09e79847-c41e-4d2a-9006-6e6e2d2fbb0a

📥 Commits

Reviewing files that changed from the base of the PR and between a401ca4 and c63474e.

📒 Files selected for processing (9)
  • pkg/executor/revoke_test.go
  • pkg/planner/core/logical_plan_builder.go
  • pkg/planner/core/logical_plans_test.go
  • pkg/planner/core/planbuilder.go
  • pkg/privilege/privileges/privileges_test.go
  • tests/integrationtest/r/privilege/privileges.result
  • tests/integrationtest/t/privilege/privileges.test
  • tests/realtikvtest/importintotest2/BUILD.bazel
  • tests/realtikvtest/importintotest2/from_select_test.go

Comment on lines +162 to +183
func (s *mockGCSSuite) TestImportFromSelectPrivilege() {
s.prepareAndUseDB("from_select")
s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost';")
s.tk.MustExec("DROP TABLE IF EXISTS test.t")
s.tk.MustExec("DROP TABLE IF EXISTS test.t1")
s.tk.MustExec(`CREATE USER 'testuser'@'localhost';`)
s.tk.MustExec(`CREATE TABLE test.t (a INT, b INT, c INT);`)
s.tk.MustExec(`CREATE TABLE test.t1 (a INT, b INT, c INT);`)
userTk := testkit.NewTestKit(s.T(), s.store)
err := userTk.Session().Auth(&auth.UserIdentity{Username: "testuser", Hostname: "localhost"}, nil, nil, nil)
require.NoError(s.T(), err)
s.tk.MustExec("GRANT ALL ON test.t1 TO 'testuser'@'localhost'")

importSQL := "IMPORT INTO test.t1 FROM SELECT a,b,c FROM test.t"
grantSQL := "GRANT SELECT(%s) ON test.t TO 'testuser'@'localhost'"

for _, colName := range []string{"a", "b", "c"} {
userTk.MustGetErrCode(importSQL, mysql.ErrColumnaccessDenied)
s.tk.MustExec(fmt.Sprintf(grantSQL, colName))
}
userTk.MustExec(importSQL)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Keep this case inside the suite-local schema and clean up its global fixtures.

prepareAndUseDB("from_select") gives this test an isolated schema, but the body switches to test.t / test.t1 and creates a global user without deferred teardown. That makes the case depend on the shared test database and can leak state into later RealTiKV cases if it fails partway through.

Suggested fix
 func (s *mockGCSSuite) TestImportFromSelectPrivilege() {
 	s.prepareAndUseDB("from_select")
-	s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost';")
-	s.tk.MustExec("DROP TABLE IF EXISTS test.t")
-	s.tk.MustExec("DROP TABLE IF EXISTS test.t1")
+	const dbName = "from_select"
+	s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost'")
+	defer s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost'")
 	s.tk.MustExec(`CREATE USER 'testuser'@'localhost';`)
-	s.tk.MustExec(`CREATE TABLE test.t (a INT, b INT, c INT);`)
-	s.tk.MustExec(`CREATE TABLE test.t1 (a INT, b INT, c INT);`)
+	s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t")
+	s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t1")
+	defer s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t1")
+	defer s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t")
+	s.tk.MustExec(`CREATE TABLE ` + dbName + `.t (a INT, b INT, c INT);`)
+	s.tk.MustExec(`CREATE TABLE ` + dbName + `.t1 (a INT, b INT, c INT);`)
 	userTk := testkit.NewTestKit(s.T(), s.store)
 	err := userTk.Session().Auth(&auth.UserIdentity{Username: "testuser", Hostname: "localhost"}, nil, nil, nil)
 	require.NoError(s.T(), err)
-	s.tk.MustExec("GRANT ALL ON test.t1 TO 'testuser'@'localhost'")
+	s.tk.MustExec("GRANT ALL ON " + dbName + ".t1 TO 'testuser'@'localhost'")
 
-	importSQL := "IMPORT INTO test.t1 FROM SELECT a,b,c FROM test.t"
-	grantSQL := "GRANT SELECT(%s) ON test.t TO 'testuser'@'localhost'"
+	importSQL := "IMPORT INTO " + dbName + ".t1 FROM SELECT a,b,c FROM " + dbName + ".t"
+	grantSQL := "GRANT SELECT(%s) ON " + dbName + ".t TO 'testuser'@'localhost'"

As per coding guidelines, tests/realtikvtest/**: RealTiKV tests MUST start playground in background, run tests, then clean up playground/data, and **/{*_test.go,testdata/**,*.golden} changes should stay minimal and deterministic.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *mockGCSSuite) TestImportFromSelectPrivilege() {
s.prepareAndUseDB("from_select")
s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost';")
s.tk.MustExec("DROP TABLE IF EXISTS test.t")
s.tk.MustExec("DROP TABLE IF EXISTS test.t1")
s.tk.MustExec(`CREATE USER 'testuser'@'localhost';`)
s.tk.MustExec(`CREATE TABLE test.t (a INT, b INT, c INT);`)
s.tk.MustExec(`CREATE TABLE test.t1 (a INT, b INT, c INT);`)
userTk := testkit.NewTestKit(s.T(), s.store)
err := userTk.Session().Auth(&auth.UserIdentity{Username: "testuser", Hostname: "localhost"}, nil, nil, nil)
require.NoError(s.T(), err)
s.tk.MustExec("GRANT ALL ON test.t1 TO 'testuser'@'localhost'")
importSQL := "IMPORT INTO test.t1 FROM SELECT a,b,c FROM test.t"
grantSQL := "GRANT SELECT(%s) ON test.t TO 'testuser'@'localhost'"
for _, colName := range []string{"a", "b", "c"} {
userTk.MustGetErrCode(importSQL, mysql.ErrColumnaccessDenied)
s.tk.MustExec(fmt.Sprintf(grantSQL, colName))
}
userTk.MustExec(importSQL)
}
func (s *mockGCSSuite) TestImportFromSelectPrivilege() {
s.prepareAndUseDB("from_select")
const dbName = "from_select"
s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost'")
defer s.tk.MustExec("DROP USER IF EXISTS 'testuser'@'localhost'")
s.tk.MustExec(`CREATE USER 'testuser'@'localhost';`)
s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t")
s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t1")
defer s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t1")
defer s.tk.MustExec("DROP TABLE IF EXISTS " + dbName + ".t")
s.tk.MustExec(`CREATE TABLE ` + dbName + `.t (a INT, b INT, c INT);`)
s.tk.MustExec(`CREATE TABLE ` + dbName + `.t1 (a INT, b INT, c INT);`)
userTk := testkit.NewTestKit(s.T(), s.store)
err := userTk.Session().Auth(&auth.UserIdentity{Username: "testuser", Hostname: "localhost"}, nil, nil, nil)
require.NoError(s.T(), err)
s.tk.MustExec("GRANT ALL ON " + dbName + ".t1 TO 'testuser'@'localhost'")
importSQL := "IMPORT INTO " + dbName + ".t1 FROM SELECT a,b,c FROM " + dbName + ".t"
grantSQL := "GRANT SELECT(%s) ON " + dbName + ".t TO 'testuser'@'localhost'"
for _, colName := range []string{"a", "b", "c"} {
userTk.MustGetErrCode(importSQL, mysql.ErrColumnaccessDenied)
s.tk.MustExec(fmt.Sprintf(grantSQL, colName))
}
userTk.MustExec(importSQL)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/realtikvtest/importintotest2/from_select_test.go` around lines 162 -
183, This test leaks global state by creating/using the shared "test" schema and
a global user; update TestImportFromSelectPrivilege to operate entirely in the
suite-local schema returned by prepareAndUseDB("from_select") instead of
hard-coded "test" (replace "test.t" and "test.t1" with the local
schema-qualified names or use the test kit's current DB), create and grant the
user scoped to that local schema (or ensure the user is dropped in teardown),
and remove any global fixtures by adding explicit DROP USER and DROP TABLE
cleanup inside the test (or use defer teardown) so all resources created by
TestImportFromSelectPrivilege (functions: TestImportFromSelectPrivilege,
prepareAndUseDB, userTk.Session().Auth, and the GRANT/IMPORT statements) stay
local and are always cleaned up.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (release-8.5@a401ca4). Learn more about missing BASE report.

Additional details and impacted files
@@               Coverage Diff                @@
##             release-8.5     #66542   +/-   ##
================================================
  Coverage               ?   55.0066%           
================================================
  Files                  ?       1819           
  Lines                  ?     653276           
  Branches               ?          0           
================================================
  Hits                   ?     359345           
  Misses                 ?     267259           
  Partials               ?      26672           
Flag Coverage Δ
integration 38.2766% <100.0000%> (?)
unit 64.9830% <100.0000%> (?)

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

Components Coverage Δ
dumpling 52.9954% <0.0000%> (?)
parser ∅ <0.0000%> (?)
br 55.5847% <0.0000%> (?)
🚀 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.

@fzzf678 fzzf678 changed the title planner: add more test cases for column privilege | tidb-test=pr/2578 (#62241) planner: add more test cases for column privilege (#62241) | tidb-test=pr/2704 Mar 11, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Mar 11, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: fzzf678, 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 lgtm label Mar 11, 2026
@ti-chi-bot ti-chi-bot Bot removed the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Mar 11, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Mar 11, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-03-11 13:58:08.920424603 +0000 UTC m=+444920.432482254: ☑️ agreed by winoros.
  • 2026-03-11 16:19:14.086613845 +0000 UTC m=+453385.598671506: ☑️ agreed by fzzf678.

@fzzf678 fzzf678 changed the title planner: add more test cases for column privilege (#62241) | tidb-test=pr/2704 planner: add more test cases for column privilege | tidb-test=pr/2704 Mar 11, 2026
@fzzf678
Copy link
Copy Markdown
Contributor

fzzf678 commented Mar 11, 2026

/retest

@fzzf678 fzzf678 removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 11, 2026
@fzzf678
Copy link
Copy Markdown
Contributor

fzzf678 commented Mar 11, 2026

/retest

@ti-chi-bot ti-chi-bot Bot merged commit 5519e8d into pingcap:release-8.5 Mar 11, 2026
19 checks passed
@ti-chi-bot ti-chi-bot Bot deleted the cherry-pick-62241-to-release-8.5 branch March 11, 2026 17:18
@ti-chi-bot ti-chi-bot Bot added do-not-merge/cherry-pick-not-approved cherry-pick-approved Cherry pick PR approved by release team. and removed cherry-pick-approved Cherry pick PR approved by release team. do-not-merge/cherry-pick-not-approved labels Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved cherry-pick-approved Cherry pick PR approved by release team. 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. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants