Skip to content

schemastore: fix cross-schema create view with unqualified source table (#5027)#5317

Merged
ti-chi-bot[bot] merged 3 commits into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-5027-to-release-8.5
Jun 11, 2026
Merged

schemastore: fix cross-schema create view with unqualified source table (#5027)#5317
ti-chi-bot[bot] merged 3 commits into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-5027-to-release-8.5

Conversation

@ti-chi-bot

Copy link
Copy Markdown
Member

This is an automated cherry-pick of #5027

What problem does this PR solve?

Issue Number: close #5026

What is changed and how it works?

This pull request addresses an issue where cross-schema CREATE VIEW statements could fail or be incorrectly processed due to unqualified source table references. By leveraging the normalized SELECT statement stored in the table metadata, the system can now correctly reconstruct the view definition with fully qualified table names. This ensures consistency and accuracy in downstream replication for views that span multiple schemas.

Highlights

  • Cross-Schema View Normalization: Introduced logic to normalize CREATE VIEW queries by utilizing the stored SELECT statement from the table metadata, ensuring that cross-schema table references are correctly resolved.
  • AST Table Schema Extraction: Added a helper utility to extract schema qualifiers from AST nodes, allowing the system to identify when a view's SELECT statement references tables outside the current schema.
  • Integration Testing: Expanded integration tests to verify that cross-schema views are correctly handled and that original queries are preserved when only the current schema is involved.

Check List

Tests

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

Questions

Will it cause performance regression or break compatibility?
Do you need to update user documentation, design documentation or monitoring documentation?

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.

If you don't think this PR needs a release note then fill it with `None`.

Summary by CodeRabbit

  • New Features

    • Enhanced persistence and replication of database views
    • Improved handling for views that reference tables across different schemas with proper DDL query normalization
  • Tests

    • Added validation tests for view creation DDL events
    • Added test coverage for schema extraction and query normalization logic

Review Change Stack

Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
@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. lgtm release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 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 Jun 10, 2026
@ti-chi-bot

Copy link
Copy Markdown
Member Author

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

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3679d976-a63c-4393-8e8c-5498d5f32ef7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ 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.

@ti-chi-bot

ti-chi-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

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

@ti-chi-bot ti-chi-bot Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 10, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces query normalization for view creation to resolve issues with cross-schema views referencing unqualified source tables. It adds helper functions to extract table schemas and verify schema references, along with comprehensive unit and integration tests. However, the changes currently contain several unresolved git merge conflict markers in both logservice/schemastore/utils.go and logservice/schemastore/utils_test.go, as well as unused imports in the test file that will cause compilation failures.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread logservice/schemastore/utils.go Outdated
Comment on lines +24 to +27
<<<<<<< HEAD
"github.com/pingcap/tidb/pkg/parser/format"
=======
>>>>>>> 5745770ea (schemastore: fix cross-schema create view with unqualified source table (#5027))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Unresolved merge conflict markers found in the imports section. Please resolve the conflict and keep the required format import.

	"github.com/pingcap/tidb/pkg/parser/format"

Comment thread logservice/schemastore/utils.go Outdated
Comment on lines +104 to +177
<<<<<<< HEAD
=======

func getIndexIDs(job *model.Job) []int64 {
if job == nil {
return nil
}

// Anonymous index rewrite only needs IDs for ADD INDEX clauses, and it
// consumes them in SQL order. Other modify-index subjobs such as DROP INDEX,
// RENAME INDEX, or ADD PRIMARY KEY would shift that positional mapping and
// make the downstream rewrite pick the wrong upstream name.
if job.Type == model.ActionAddIndex {
return extractAddIndexIDs(job)
}

if job.MultiSchemaInfo == nil {
return nil
}

res := make([]int64, 0)
for idx, subJob := range job.MultiSchemaInfo.SubJobs {
if subJob.Type != model.ActionAddIndex {
continue
}
proxyJob := subJob.ToProxyJob(job, idx)
res = append(res, extractAddIndexIDs(&proxyJob)...)
}
return res
}

func extractAddIndexIDs(job *model.Job) []int64 {
idxArgs, err := model.GetModifyIndexArgs(job)
if idxArgs == nil || err != nil {
return nil
}

res := make([]int64, 0, len(idxArgs.IndexArgs))
for _, indexArg := range idxArgs.IndexArgs {
res = append(res, indexArg.IndexID)
}
return res
}

type tableSchemaExtractor struct {
schemas []string
}

func (e *tableSchemaExtractor) Enter(in ast.Node) (ast.Node, bool) {
if t, ok := in.(*ast.TableName); ok {
e.schemas = append(e.schemas, t.Schema.O)
return in, true
}
return in, false
}

func (e *tableSchemaExtractor) Leave(in ast.Node) (ast.Node, bool) {
return in, true
}

// extractTableSchemas returns schema qualifiers from all *ast.TableName nodes in
// AST visit order. Unqualified tables contribute an empty schema name.
func extractTableSchemas(node ast.Node) []string {
if node == nil {
return nil
}

extractor := &tableSchemaExtractor{
schemas: make([]string, 0),
}
node.Accept(extractor)
return extractor.schemas
}
>>>>>>> 5745770ea (schemastore: fix cross-schema create view with unqualified source table (#5027))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Unresolved merge conflict markers found at the end of the file. Please resolve the conflict and keep the helper functions.

func getIndexIDs(job *model.Job) []int64 {
	if job == nil {
		return nil
	}

	// Anonymous index rewrite only needs IDs for ADD INDEX clauses, and it
	// consumes them in SQL order. Other modify-index subjobs such as DROP INDEX,
	// RENAME INDEX, or ADD PRIMARY KEY would shift that positional mapping and
	// make the downstream rewrite pick the wrong upstream name.
	if job.Type == model.ActionAddIndex {
		return extractAddIndexIDs(job)
	}

	if job.MultiSchemaInfo == nil {
		return nil
	}

	res := make([]int64, 0)
	for idx, subJob := range job.MultiSchemaInfo.SubJobs {
		if subJob.Type != model.ActionAddIndex {
			continue
		}
		proxyJob := subJob.ToProxyJob(job, idx)
		res = append(res, extractAddIndexIDs(&proxyJob)...)
	}
	return res
}

func extractAddIndexIDs(job *model.Job) []int64 {
	idxArgs, err := model.GetModifyIndexArgs(job)
	if idxArgs == nil || err != nil {
		return nil
	}

	res := make([]int64, 0, len(idxArgs.IndexArgs))
	for _, indexArg := range idxArgs.IndexArgs {
		res = append(res, indexArg.IndexID)
	}
	return res
}

type tableSchemaExtractor struct {
	schemas []string
}

func (e *tableSchemaExtractor) Enter(in ast.Node) (ast.Node, bool) {
	if t, ok := in.(*ast.TableName); ok {
		e.schemas = append(e.schemas, t.Schema.O)
		return in, true
	}
	return in, false
}

func (e *tableSchemaExtractor) Leave(in ast.Node) (ast.Node, bool) {
	return in, true
}

// extractTableSchemas returns schema qualifiers from all *ast.TableName nodes in
// AST visit order. Unqualified tables contribute an empty schema name.
func extractTableSchemas(node ast.Node) []string {
	if node == nil {
		return nil
	}

	extractor := &tableSchemaExtractor{
		schemas: make([]string, 0),
	}
	node.Accept(extractor)
	return extractor.schemas
}

Comment thread logservice/schemastore/utils_test.go Outdated
Comment on lines +20 to +27
<<<<<<< HEAD
=======
"github.com/pingcap/ticdc/pkg/config/kerneltype"
ticonfig "github.com/pingcap/tidb/pkg/config"
"github.com/pingcap/tidb/pkg/disttask/framework/handle"
"github.com/pingcap/tidb/pkg/meta/model"
"github.com/pingcap/tidb/pkg/parser"
>>>>>>> 5745770ea (schemastore: fix cross-schema create view with unqualified source table (#5027))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Unresolved merge conflict markers found in the imports section. Also, several unused imports (kerneltype, ticonfig, handle) were introduced, which will cause compilation errors in Go. Please resolve the conflict and keep only the used imports.

	"github.com/pingcap/tidb/pkg/meta/model"
	"github.com/pingcap/tidb/pkg/parser"

Comment thread logservice/schemastore/utils_test.go Outdated
Comment on lines +71 to +259
<<<<<<< HEAD
=======

func TestBuildPersistedDDLEventForMultiSchemaChangeContainsIndexIDs(t *testing.T) {
helper := commonEvent.NewEventTestHelper(t)
defer helper.Close()

helper.Tk().MustExec("use test")
helper.DDL2Event("create table t (id int primary key, c1 int)")

job := helper.DDL2Job("alter table t add column c2 int, add index (c1)")
require.Equal(t, model.ActionMultiSchemaChange, job.Type)

args := buildPersistedDDLEventFuncArgs{
job: job,
databaseMap: map[int64]*BasicDatabaseInfo{
job.SchemaID: {
Name: "test",
Tables: map[int64]bool{
job.TableID: true,
},
},
},
tableMap: map[int64]*BasicTableInfo{
job.TableID: {
SchemaID: job.SchemaID,
Name: "t",
},
},
}

event := buildPersistedDDLEventForMultiSchemaChange(args)
expectedIndexIDs := getIndexIDs(job)
require.Len(t, expectedIndexIDs, 1)
require.Equal(t, expectedIndexIDs, event.IndexIDs)
require.Equal(t, "test", event.SchemaName)
require.Equal(t, "t", event.TableName)
}

func TestGetIndexIDsReturnsAllAddIndexIDsInOrder(t *testing.T) {
helper := commonEvent.NewEventTestHelper(t)
defer helper.Close()

helper.Tk().MustExec("use test")
helper.DDL2Event("create table t (id int primary key, c1 int)")

job := helper.DDL2Job("alter table t add index idx_c1(c1), add index (c1)")
tableInfo := helper.GetModelTableInfo(job)
require.NotNil(t, tableInfo)

var namedIndexID int64
var anonymousIndexID int64
for _, index := range tableInfo.Indices {
if index == nil {
continue
}
if index.Name.O == "idx_c1" {
namedIndexID = index.ID
continue
}
if len(index.Columns) == 1 && index.Columns[0].Name.L == "c1" {
anonymousIndexID = index.ID
}
}
require.NotZero(t, namedIndexID)
require.NotZero(t, anonymousIndexID)
require.Equal(t, []int64{namedIndexID, anonymousIndexID}, getIndexIDs(job))
}

func TestGetIndexIDsReturnsAllAddIndexIDsInOrderForMultiSchemaChange(t *testing.T) {
helper := commonEvent.NewEventTestHelper(t)
defer helper.Close()

helper.Tk().MustExec("use test")
helper.DDL2Event("create table t (id int primary key, c1 int)")

job := helper.DDL2Job("alter table t add column c2 int, add index idx_c1(c1), add index (c1)")
require.Equal(t, model.ActionMultiSchemaChange, job.Type)
tableInfo := helper.GetModelTableInfo(job)
require.NotNil(t, tableInfo)

var namedIndexID int64
var anonymousIndexID int64
for _, index := range tableInfo.Indices {
if index == nil {
continue
}
if index.Name.O == "idx_c1" {
namedIndexID = index.ID
continue
}
if len(index.Columns) == 1 && index.Columns[0].Name.L == "c1" {
anonymousIndexID = index.ID
}
}
require.NotZero(t, namedIndexID)
require.NotZero(t, anonymousIndexID)
require.Equal(t, []int64{namedIndexID, anonymousIndexID}, getIndexIDs(job))
}

func TestGetIndexIDsIgnoresDropIndexSubJobsForMultiSchemaChange(t *testing.T) {
helper := commonEvent.NewEventTestHelper(t)
defer helper.Close()

helper.Tk().MustExec("use test")
helper.DDL2Event("create table t (id int primary key, a int, key idx_old(id))")

job := helper.DDL2Job("alter table t drop index idx_old, add index (a)")
require.Equal(t, model.ActionMultiSchemaChange, job.Type)

tableInfo := helper.GetModelTableInfo(job)
require.NotNil(t, tableInfo)

var anonymousIndexID int64
for _, index := range tableInfo.Indices {
if index == nil || index.Primary || len(index.Columns) != 1 {
continue
}
if index.Columns[0].Name.L == "a" {
anonymousIndexID = index.ID
break
}
}
require.NotZero(t, anonymousIndexID)
require.Equal(t, []int64{anonymousIndexID}, getIndexIDs(job))
}

func TestGetIndexIDsIgnoresAddPrimaryKeySubJobsForMultiSchemaChange(t *testing.T) {
helper := commonEvent.NewEventTestHelper(t)
defer helper.Close()

helper.Tk().MustExec("use test")
helper.DDL2Event("create table t (id int, a int)")

job := helper.DDL2Job("alter table t add primary key(id), add index (a)")
require.Equal(t, model.ActionMultiSchemaChange, job.Type)

tableInfo := helper.GetModelTableInfo(job)
require.NotNil(t, tableInfo)

var anonymousIndexID int64
for _, index := range tableInfo.Indices {
if index == nil || index.Primary || len(index.Columns) != 1 {
continue
}
if index.Columns[0].Name.L == "a" {
anonymousIndexID = index.ID
break
}
}
require.NotZero(t, anonymousIndexID)
require.Equal(t, []int64{anonymousIndexID}, getIndexIDs(job))
}

func TestExtractTableSchemas(t *testing.T) {
cases := []struct {
name string
query string
expected []string
}{
{
name: "unqualified table",
query: "SELECT * FROM `t`",
expected: []string{""},
},
{
name: "mixed qualified tables",
query: "SELECT * FROM `db1`.`t1` JOIN `t2` ON `db1`.`t1`.`id` = `t2`.`id`",
expected: []string{"db1", ""},
},
{
name: "subquery preserves visit order",
query: "SELECT * FROM `db1`.`t1` WHERE EXISTS (SELECT 1 FROM `db2`.`t2`)",
expected: []string{"db1", "db2"},
},
}

p := parser.New()
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
stmt, err := p.ParseOneStmt(tc.query, "", "")
require.NoError(t, err)
require.Equal(t, tc.expected, extractTableSchemas(stmt))
})
}

require.Nil(t, extractTableSchemas(nil))
}
>>>>>>> 5745770ea (schemastore: fix cross-schema create view with unqualified source table (#5027))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Unresolved merge conflict markers found in the test functions section. Please resolve the conflict and keep the added test cases.

func TestBuildPersistedDDLEventForMultiSchemaChangeContainsIndexIDs(t *testing.T) {
	helper := commonEvent.NewEventTestHelper(t)
	defer helper.Close()

	helper.Tk().MustExec("use test")
	helper.DDL2Event("create table t (id int primary key, c1 int)")

	job := helper.DDL2Job("alter table t add column c2 int, add index (c1)")
	require.Equal(t, model.ActionMultiSchemaChange, job.Type)

	args := buildPersistedDDLEventFuncArgs{
		job: job,
		databaseMap: map[int64]*BasicDatabaseInfo{
			job.SchemaID: {
				Name: "test",
				Tables: map[int64]bool{
					job.TableID: true,
				},
			},
		},
		tableMap: map[int64]*BasicTableInfo{
			job.TableID: {
				SchemaID: job.SchemaID,
				Name:     "t",
			},
		},
	}

	event := buildPersistedDDLEventForMultiSchemaChange(args)
	expectedIndexIDs := getIndexIDs(job)
	require.Len(t, expectedIndexIDs, 1)
	require.Equal(t, expectedIndexIDs, event.IndexIDs)
	require.Equal(t, "test", event.SchemaName)
	require.Equal(t, "t", event.TableName)
}

func TestGetIndexIDsReturnsAllAddIndexIDsInOrder(t *testing.T) {
	helper := commonEvent.NewEventTestHelper(t)
	defer helper.Close()

	helper.Tk().MustExec("use test")
	helper.DDL2Event("create table t (id int primary key, c1 int)")

	job := helper.DDL2Job("alter table t add index idx_c1(c1), add index (c1)")
	tableInfo := helper.GetModelTableInfo(job)
	require.NotNil(t, tableInfo)

	var namedIndexID int64
	var anonymousIndexID int64
	for _, index := range tableInfo.Indices {
		if index == nil {
			continue
		}
		if index.Name.O == "idx_c1" {
			namedIndexID = index.ID
			continue
		}
		if len(index.Columns) == 1 && index.Columns[0].Name.L == "c1" {
			anonymousIndexID = index.ID
		}
	}
	require.NotZero(t, namedIndexID)
	require.NotZero(t, anonymousIndexID)
	require.Equal(t, []int64{namedIndexID, anonymousIndexID}, getIndexIDs(job))
}

func TestGetIndexIDsReturnsAllAddIndexIDsInOrderForMultiSchemaChange(t *testing.T) {
	helper := commonEvent.NewEventTestHelper(t)
	defer helper.Close()

	helper.Tk().MustExec("use test")
	helper.DDL2Event("create table t (id int primary key, c1 int)")

	job := helper.DDL2Job("alter table t add column c2 int, add index idx_c1(c1), add index (c1)")
	require.Equal(t, model.ActionMultiSchemaChange, job.Type)
	tableInfo := helper.GetModelTableInfo(job)
	require.NotNil(t, tableInfo)

	var namedIndexID int64
	var anonymousIndexID int64
	for _, index := range tableInfo.Indices {
		if index == nil {
			continue
		}
		if index.Name.O == "idx_c1" {
			namedIndexID = index.ID
			continue
		}
		if len(index.Columns) == 1 && index.Columns[0].Name.L == "c1" {
			anonymousIndexID = index.ID
		}
	}
	require.NotZero(t, namedIndexID)
	require.NotZero(t, anonymousIndexID)
	require.Equal(t, []int64{namedIndexID, anonymousIndexID}, getIndexIDs(job))
}

func TestGetIndexIDsIgnoresDropIndexSubJobsForMultiSchemaChange(t *testing.T) {
	helper := commonEvent.NewEventTestHelper(t)
	defer helper.Close()

	helper.Tk().MustExec("use test")
	helper.DDL2Event("create table t (id int primary key, a int, key idx_old(id))")

	job := helper.DDL2Job("alter table t drop index idx_old, add index (a)")
	require.Equal(t, model.ActionMultiSchemaChange, job.Type)

	tableInfo := helper.GetModelTableInfo(job)
	require.NotNil(t, tableInfo)

	var anonymousIndexID int64
	for _, index := range tableInfo.Indices {
		if index == nil || index.Primary || len(index.Columns) != 1 {
			continue
		}
		if index.Columns[0].Name.L == "a" {
			anonymousIndexID = index.ID
			break
		}
	}
	require.NotZero(t, anonymousIndexID)
	require.Equal(t, []int64{anonymousIndexID}, getIndexIDs(job))
}

func TestGetIndexIDsIgnoresAddPrimaryKeySubJobsForMultiSchemaChange(t *testing.T) {
	helper := commonEvent.NewEventTestHelper(t)
	defer helper.Close()

	helper.Tk().MustExec("use test")
	helper.DDL2Event("create table t (id int, a int)")

	job := helper.DDL2Job("alter table t add primary key(id), add index (a)")
	require.Equal(t, model.ActionMultiSchemaChange, job.Type)

	tableInfo := helper.GetModelTableInfo(job)
	require.NotNil(t, tableInfo)

	var anonymousIndexID int64
	for _, index := range tableInfo.Indices {
		if index == nil || index.Primary || len(index.Columns) != 1 {
			continue
		}
		if index.Columns[0].Name.L == "a" {
			anonymousIndexID = index.ID
			break
		}
	}
	require.NotZero(t, anonymousIndexID)
	require.Equal(t, []int64{anonymousIndexID}, getIndexIDs(job))
}

func TestExtractTableSchemas(t *testing.T) {
	cases := []struct {
		name     string
		query    string
		expected []string
	}{
		{
			name:     "unqualified table",
			query:    "SELECT * FROM `t`",
			expected: []string{""},
		},
		{
			name:     "mixed qualified tables",
			query:    "SELECT * FROM `db1`.`t1` JOIN `t2` ON `db1`.`t1`.`id` = `t2`.`id`",
			expected: []string{"db1", ""},
		},
		{
			name:     "subquery preserves visit order",
			query:    "SELECT * FROM `db1`.`t1` WHERE EXISTS (SELECT 1 FROM `db2`.`t2`)",
			expected: []string{"db1", "db2"},
		},
	}

	p := parser.New()
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			stmt, err := p.ParseOneStmt(tc.query, "", "")
			require.NoError(t, err)
			require.Equal(t, tc.expected, extractTableSchemas(stmt))
		})
	}

	require.Nil(t, extractTableSchemas(nil))
}

@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 Jun 10, 2026
lidezhu and others added 2 commits June 11, 2026 08:00
Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
…ot/ticdc-1 into cherry-pick-5027-to-release-8.5

# Conflicts:
#	logservice/schemastore/persist_storage_ddl_handlers.go
#	logservice/schemastore/persist_storage_test.go
#	logservice/schemastore/utils.go
#	logservice/schemastore/utils_test.go
@ti-chi-bot ti-chi-bot Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jun 11, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lidezhu

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 11, 2026
@lidezhu lidezhu removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 11, 2026
@ti-chi-bot ti-chi-bot Bot merged commit f25c6f8 into pingcap:release-8.5 Jun 11, 2026
20 checks passed
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 Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 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.

2 participants