Skip to content

Commit

Permalink
Merge branch 'master' into functional-dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
winoros committed Mar 13, 2022
2 parents 7726e19 + 9fcc6b0 commit d297b73
Show file tree
Hide file tree
Showing 225 changed files with 24,035 additions and 21,262 deletions.
21 changes: 17 additions & 4 deletions bindinfo/bind_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ import (
)

const (
// Enabled is the bind info's in enabled status.
// It is the same as the previous 'Using' status.
// Only use 'Enabled' status in the future, not the 'Using' status.
// The 'Using' status is preserved for compatibility.
Enabled = "enabled"
// Disabled is the bind info's in disabled status.
Disabled = "disabled"
// Using is the bind info's in use status.
// The 'Using' status is preserved for compatibility.
Using = "using"
// deleted is the bind info's deleted status.
deleted = "deleted"
Expand All @@ -53,7 +61,7 @@ type Binding struct {
BindSQL string
// Status represents the status of the binding. It can only be one of the following values:
// 1. deleted: BindRecord is deleted, can not be used anymore.
// 2. using: Binding is in the normal active mode.
// 2. enabled, using: Binding is in the normal active mode.
Status string
CreateTime types.Time
UpdateTime types.Time
Expand All @@ -74,6 +82,11 @@ func (b *Binding) isSame(rb *Binding) bool {
return b.BindSQL == rb.BindSQL
}

// IsBindingEnabled returns whether the binding is enabled.
func (b *Binding) IsBindingEnabled() bool {
return b.Status == Enabled || b.Status == Using
}

// SinceUpdateTime returns the duration since last update time. Export for test.
func (b *Binding) SinceUpdateTime() (time.Duration, error) {
updateTime, err := b.UpdateTime.GoTime(time.Local)
Expand All @@ -94,7 +107,7 @@ type BindRecord struct {
// HasUsingBinding checks if there are any using bindings in bind record.
func (br *BindRecord) HasUsingBinding() bool {
for _, binding := range br.Bindings {
if binding.Status == Using {
if binding.IsBindingEnabled() {
return true
}
}
Expand All @@ -105,7 +118,7 @@ func (br *BindRecord) HasUsingBinding() bool {
// There is at most one binding that can be used now
func (br *BindRecord) FindUsingBinding() *Binding {
for _, binding := range br.Bindings {
if binding.Status == Using {
if binding.IsBindingEnabled() {
return &binding
}
}
Expand Down Expand Up @@ -242,7 +255,7 @@ func (br *BindRecord) size() float64 {
}

var statusIndex = map[string]int{
Using: 0,
Enabled: 0,
deleted: 1,
Invalid: 2,
}
Expand Down
26 changes: 13 additions & 13 deletions bindinfo/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func TestBindingSymbolList(t *testing.T) {
bind := bindData.Bindings[0]
require.Equal(t, "SELECT `a`,`b` FROM `test`.`t` USE INDEX (`ib`) WHERE `a` = 1 LIMIT 0,1", bind.BindSQL)
require.Equal(t, "test", bindData.Db)
require.Equal(t, "using", bind.Status)
require.Equal(t, bindinfo.Enabled, bind.Status)
require.NotNil(t, bind.Charset)
require.NotNil(t, bind.Collation)
require.NotNil(t, bind.CreateTime)
Expand Down Expand Up @@ -498,7 +498,7 @@ func TestBestPlanInBaselines(t *testing.T) {
bind := bindData.Bindings[0]
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` `ia`)*/ `a`,`b` FROM `test`.`t` WHERE `a` = 1 LIMIT 0,1", bind.BindSQL)
require.Equal(t, "test", bindData.Db)
require.Equal(t, "using", bind.Status)
require.Equal(t, bindinfo.Enabled, bind.Status)

tk.MustQuery("select a, b from t where a = 3 limit 1, 10")
require.Equal(t, "t:ia", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
Expand Down Expand Up @@ -532,7 +532,7 @@ func TestErrorBind(t *testing.T) {
bind := bindData.Bindings[0]
require.Equal(t, "SELECT * FROM `test`.`t` USE INDEX (`index_t`) WHERE `i` > 100", bind.BindSQL)
require.Equal(t, "test", bindData.Db)
require.Equal(t, "using", bind.Status)
require.Equal(t, bindinfo.Enabled, bind.Status)
require.NotNil(t, bind.Charset)
require.NotNil(t, bind.Collation)
require.NotNil(t, bind.CreateTime)
Expand Down Expand Up @@ -651,7 +651,7 @@ func TestAddEvolveTasks(t *testing.T) {
require.Len(t, rows, 2)
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0", rows[0][1])
status := rows[0][3].(string)
require.True(t, status == "using" || status == "rejected")
require.True(t, status == bindinfo.Enabled || status == bindinfo.Rejected)
}

func TestRuntimeHintsInEvolveTasks(t *testing.T) {
Expand Down Expand Up @@ -910,7 +910,7 @@ func TestNotEvolvePlanForReadStorageHint(t *testing.T) {
// None evolve task, because of the origin binding is a read_from_storage binding.
require.Len(t, rows, 1)
require.Equal(t, "SELECT /*+ read_from_storage(tiflash[`t`])*/ * FROM `test`.`t` WHERE `a` >= 1 AND `b` >= 1", rows[0][1])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
}

func TestBindingWithIsolationRead(t *testing.T) {
Expand Down Expand Up @@ -1055,23 +1055,23 @@ func TestReCreateBind(t *testing.T) {

tk.MustExec("create global binding for select * from t using select * from t")
tk.MustQuery("select original_sql, status from mysql.bind_info where source != 'builtin';").Check(testkit.Rows(
"select * from `test` . `t` using",
"select * from `test` . `t` enabled",
))
rows := tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t`", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])

tk.MustExec("create global binding for select * from t using select * from t")
rows = tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t`", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])

rows = tk.MustQuery("select original_sql, status from mysql.bind_info where source != 'builtin';").Rows()
require.Len(t, rows, 2)
require.Equal(t, "deleted", rows[0][1])
require.Equal(t, "using", rows[1][1])
require.Equal(t, bindinfo.Enabled, rows[1][1])
}

func TestExplainShowBindSQL(t *testing.T) {
Expand Down Expand Up @@ -1218,9 +1218,9 @@ func TestGCBindRecord(t *testing.T) {
rows := tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t` where `a` = ?", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
tk.MustQuery("select status from mysql.bind_info where original_sql = 'select * from `test` . `t` where `a` = ?'").Check(testkit.Rows(
"using",
bindinfo.Enabled,
))

h := dom.BindHandle()
Expand All @@ -1229,9 +1229,9 @@ func TestGCBindRecord(t *testing.T) {
rows = tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t` where `a` = ?", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
tk.MustQuery("select status from mysql.bind_info where original_sql = 'select * from `test` . `t` where `a` = ?'").Check(testkit.Rows(
"using",
bindinfo.Enabled,
))

tk.MustExec("drop global binding for select * from t where a = 1")
Expand Down
8 changes: 4 additions & 4 deletions bindinfo/capture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func TestCaptureBaselinesDefaultDB(t *testing.T) {
require.Len(t, rows, 1)
// Default DB should be "" when all columns have explicit database name.
require.Equal(t, "", rows[0][2])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
tk.MustExec("use spm")
tk.MustExec("select * from spm.t where a > 10")
// Should use TableScan because of the "ignore index" binding.
Expand Down Expand Up @@ -345,7 +345,7 @@ func TestConcurrentCapture(t *testing.T) {

// Simulate an existing binding generated by concurrent CREATE BINDING, which has not been synchronized to current tidb-server yet.
// Actually, it is more common to be generated by concurrent baseline capture, I use Manual just for simpler test verification.
tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t`', 'select * from `test` . `t`', '', 'using', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" +
tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t`', 'select * from `test` . `t`', '', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" +
bindinfo.Manual + "')")
tk.MustQuery("select original_sql, source from mysql.bind_info where source != 'builtin'").Check(testkit.Rows(
"select * from `test` . `t` manual",
Expand All @@ -360,7 +360,7 @@ func TestConcurrentCapture(t *testing.T) {
tk.MustExec("admin capture bindings")
tk.MustQuery("select original_sql, source, status from mysql.bind_info where source != 'builtin'").Check(testkit.Rows(
"select * from `test` . `t` manual deleted",
"select * from `test` . `t` capture using",
"select * from `test` . `t` capture enabled",
))
}

Expand Down Expand Up @@ -461,7 +461,7 @@ func TestIssue20417(t *testing.T) {
require.Equal(t, "select * from `test` . `t` where `c` = ?", rows[0][0])
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idxc`)*/ * FROM `test`.`t` WHERE `c` = 3924541", rows[0][1])
status := rows[0][3].(string)
require.True(t, status == "using" || status == "rejected")
require.True(t, status == bindinfo.Enabled || status == bindinfo.Rejected)
tk.MustExec("set @@tidb_evolve_plan_baselines=0")
}

Expand Down
11 changes: 8 additions & 3 deletions bindinfo/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,14 @@ func (h *BindHandle) SetBindCacheCapacity(capacity int64) {

// newBindRecord builds BindRecord from a tuple in storage.
func (h *BindHandle) newBindRecord(row chunk.Row) (string, *BindRecord, error) {
status := row.GetString(3)
// For compatibility, the 'Using' status binding will be converted to the 'Enabled' status binding.
if status == Using {
status = Enabled
}
hint := Binding{
BindSQL: row.GetString(1),
Status: row.GetString(3),
Status: status,
CreateTime: row.GetTime(4),
UpdateTime: row.GetTime(5),
Charset: row.GetString(6),
Expand Down Expand Up @@ -749,7 +754,7 @@ func (h *BindHandle) CaptureBaselines() {
charset, collation := h.sctx.GetSessionVars().GetCharsetInfo()
binding := Binding{
BindSQL: bindSQL,
Status: Using,
Status: Enabled,
Charset: charset,
Collation: collation,
Source: Capture,
Expand Down Expand Up @@ -1061,7 +1066,7 @@ func (h *BindHandle) HandleEvolvePlanTask(sctx sessionctx.Context, adminEvolve b
zap.String("digestText", digestText),
)
} else {
binding.Status = Using
binding.Status = Enabled
}
// We don't need to pass the `sctx` because the BindSQL has been validated already.
return h.AddBindRecord(nil, &BindRecord{OriginalSQL: originalSQL, Db: db, Bindings: []Binding{binding}})
Expand Down
Loading

0 comments on commit d297b73

Please sign in to comment.