Skip to content

Commit

Permalink
executor: fix data race at the ShowExec (#39817)
Browse files Browse the repository at this point in the history
close #39816, close #40295
  • Loading branch information
hawkingrei authored Jan 9, 2023
1 parent f7c87c8 commit 2d755a8
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
1 change: 1 addition & 0 deletions executor/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ go_library(
"//util/servermemorylimit",
"//util/set",
"//util/size",
"//util/slice",
"//util/sqlexec",
"//util/stmtsummary",
"//util/stringutil",
Expand Down
8 changes: 5 additions & 3 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import (
"github.com/pingcap/tidb/util/memory"
"github.com/pingcap/tidb/util/sem"
"github.com/pingcap/tidb/util/set"
"github.com/pingcap/tidb/util/slice"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pingcap/tidb/util/stringutil"
"golang.org/x/exp/slices"
Expand Down Expand Up @@ -306,13 +307,14 @@ func (v *visibleChecker) Leave(in ast.Node) (out ast.Node, ok bool) {
}

func (e *ShowExec) fetchShowBind() error {
var bindRecords []*bindinfo.BindRecord
var tmp []*bindinfo.BindRecord
if !e.GlobalScope {
handle := e.ctx.Value(bindinfo.SessionBindInfoKeyType).(*bindinfo.SessionHandle)
bindRecords = handle.GetAllBindRecord()
tmp = handle.GetAllBindRecord()
} else {
bindRecords = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord()
tmp = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord()
}
bindRecords := slice.Copy(tmp)
// Remove the invalid bindRecord.
ind := 0
for _, bindData := range bindRecords {
Expand Down
13 changes: 13 additions & 0 deletions util/slice/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,16 @@ func AllOf(s interface{}, p func(int) bool) bool {
}
return NoneOf(s, np)
}

// Copy is a deep copy of the slice.
func Copy[T any](a []*T) []*T {
b := make([]*T, len(a))
for i, p := range a {
if p == nil {
continue
}
v := *p
b[i] = &v
}
return b
}
16 changes: 16 additions & 0 deletions util/slice/slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,19 @@ func TestSlice(t *testing.T) {
})
}
}

func TestCopy(t *testing.T) {
type T int
v0, v1, v2, v3 := T(0), T(1), T(2), T(3)
s := []*T{&v0, &v1, &v2, &v3, nil}
e := Copy(s)
require.Equal(t, len(s), len(e))
for i := range s {
if s[i] == nil {
require.Nil(t, e[i])
} else {
require.Equal(t, *s[i], *e[i])
require.True(t, s[i] != e[i])
}
}
}

0 comments on commit 2d755a8

Please sign in to comment.