Skip to content

Commit 97d861e

Browse files
authored
planner: refactor some code related to binding (#59644)
ref #51347
1 parent 9b8296b commit 97d861e

6 files changed

+27
-57
lines changed

pkg/bindinfo/binding.go

+5-35
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func matchSQLBinding(sctx sessionctx.Context, stmtNode ast.StmtNode, info *Bindi
132132
var noDBDigest string
133133
var tableNames []*ast.TableName
134134
if info == nil || info.TableNames == nil || info.NoDBDigest == "" {
135-
_, noDBDigest = NormalizeStmtForBinding(stmtNode, WithoutDB(true))
135+
_, noDBDigest = NormalizeStmtForBinding(stmtNode, "", true)
136136
tableNames = CollectTableNames(stmtNode)
137137
if info != nil {
138138
info.NoDBDigest = noDBDigest
@@ -165,7 +165,7 @@ func noDBDigestFromBinding(binding *Binding) (string, error) {
165165
if err != nil {
166166
return "", err
167167
}
168-
_, bindingNoDBDigest := NormalizeStmtForBinding(stmt, WithoutDB(true))
168+
_, bindingNoDBDigest := NormalizeStmtForBinding(stmt, "", true)
169169
return bindingNoDBDigest, nil
170170
}
171171

@@ -367,44 +367,14 @@ func pickCachedBinding(cachedBinding *Binding, bindingsFromStorage ...*Binding)
367367
return bindings[0]
368368
}
369369

370-
type option struct {
371-
specifiedDB string
372-
noDB bool
373-
}
374-
375-
type optionFunc func(*option)
376-
377-
// WithoutDB specifies whether to eliminate schema names.
378-
func WithoutDB(noDB bool) optionFunc {
379-
return func(user *option) {
380-
user.noDB = noDB
381-
}
382-
}
383-
384-
// WithSpecifiedDB specifies the specified DB name.
385-
func WithSpecifiedDB(specifiedDB string) optionFunc {
386-
return func(user *option) {
387-
user.specifiedDB = specifiedDB
388-
}
389-
}
390-
391-
// NormalizeStmtForBinding normalizes a statement for binding.
392-
// when noDB is false, schema names will be completed automatically: `select * from t` --> `select * from db . t`.
393-
// when noDB is true, schema names will be eliminated automatically: `select * from db . t` --> `select * from t`.
394-
func NormalizeStmtForBinding(stmtNode ast.StmtNode, options ...optionFunc) (normalizedStmt, exactSQLDigest string) {
395-
opt := &option{}
396-
for _, option := range options {
397-
option(opt)
398-
}
399-
return normalizeStmt(stmtNode, opt.specifiedDB, opt.noDB)
400-
}
401-
402370
// NormalizeStmtForBinding normalizes a statement for binding.
403371
// This function skips Explain automatically, and literals in in-lists will be normalized as '...'.
404372
// For normal bindings, DB name will be completed automatically:
373+
// when noDB is false, schema names will be completed automatically: `select * from t` --> `select * from db . t`.
374+
// when noDB is true, schema names will be eliminated automatically: `select * from db . t` --> `select * from t`.
405375
//
406376
// e.g. `select * from t where a in (1, 2, 3)` --> `select * from test.t where a in (...)`
407-
func normalizeStmt(stmtNode ast.StmtNode, specifiedDB string, noDB bool) (normalizedStmt, sqlDigest string) {
377+
func NormalizeStmtForBinding(stmtNode ast.StmtNode, specifiedDB string, noDB bool) (normalizedStmt, sqlDigest string) {
408378
normalize := func(n ast.StmtNode) (normalizedStmt, sqlDigest string) {
409379
eraseLastSemicolon(n)
410380
var digest *parser.Digest

pkg/bindinfo/binding_cache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func (c *bindingCache) SetBinding(sqlDigest string, binding *Binding) (err error
214214
if err != nil {
215215
return err
216216
}
217-
_, noDBDigest := NormalizeStmtForBinding(stmt, WithoutDB(true))
217+
_, noDBDigest := NormalizeStmtForBinding(stmt, "", true)
218218
c.digestBiMap.Add(noDBDigest, sqlDigest)
219219
// NOTE: due to LRU eviction, the underlying BindingCache state might be inconsistent with digestBiMap,
220220
// but it's acceptable, the optimizer will load the binding when cache-miss.

pkg/bindinfo/binding_cache_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func bindingNoDBDigest(t *testing.T, b *Binding) string {
3030
p := parser.New()
3131
stmt, err := p.ParseOneStmt(b.BindSQL, b.Charset, b.Collation)
3232
require.NoError(t, err)
33-
_, noDBDigest := NormalizeStmtForBinding(stmt, WithoutDB(true))
33+
_, noDBDigest := NormalizeStmtForBinding(stmt, "", true)
3434
return noDBDigest
3535
}
3636

pkg/bindinfo/global_handle_test.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestBindingLastUpdateTime(t *testing.T) {
7373
stmt, err := parser.New().ParseOneStmt("select * from test . t0", "", "")
7474
require.NoError(t, err)
7575

76-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
76+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
7777
binding, matched := bindHandle.MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
7878
require.True(t, matched)
7979
updateTime := binding.UpdateTime.String()
@@ -139,7 +139,7 @@ func TestBindParse(t *testing.T) {
139139

140140
stmt, err := parser.New().ParseOneStmt("select * from test . t", "", "")
141141
require.NoError(t, err)
142-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
142+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
143143
binding, matched := bindHandle.MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
144144
require.True(t, matched)
145145
require.Equal(t, "select * from `test` . `t`", binding.OriginalSQL)
@@ -435,7 +435,7 @@ func TestGlobalBinding(t *testing.T) {
435435

436436
stmt, _, _ := utilNormalizeWithDefaultDB(t, testSQL.querySQL)
437437

438-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
438+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
439439
binding, matched := dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
440440
require.True(t, matched)
441441
require.Equal(t, testSQL.originSQL, binding.OriginalSQL)
@@ -468,7 +468,7 @@ func TestGlobalBinding(t *testing.T) {
468468
require.NoError(t, err)
469469
require.Equal(t, 1, len(bindHandle.GetAllGlobalBindings()))
470470

471-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
471+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
472472
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
473473
require.True(t, matched)
474474
require.Equal(t, testSQL.originSQL, binding.OriginalSQL)
@@ -483,15 +483,15 @@ func TestGlobalBinding(t *testing.T) {
483483
_, err = tk.Exec("drop global " + testSQL.dropSQL)
484484
require.Equal(t, uint64(1), tk.Session().AffectedRows())
485485
require.NoError(t, err)
486-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
486+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
487487
_, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
488488
require.False(t, matched) // dropped
489489
bindHandle = bindinfo.NewGlobalBindingHandle(&mockSessionPool{tk.Session()})
490490
err = bindHandle.LoadFromStorageToCache(true)
491491
require.NoError(t, err)
492492
require.Equal(t, 0, len(bindHandle.GetAllGlobalBindings()))
493493

494-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
494+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
495495
_, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
496496
require.False(t, matched) // dropped
497497

@@ -679,7 +679,7 @@ func TestNormalizeStmtForBinding(t *testing.T) {
679679
}
680680
for _, test := range tests {
681681
stmt, _, _ := utilNormalizeWithDefaultDB(t, test.sql)
682-
n, digest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
682+
n, digest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
683683
require.Equal(t, test.normalized, n)
684684
require.Equal(t, test.digest, digest)
685685
}
@@ -696,39 +696,39 @@ func TestHintsSetID(t *testing.T) {
696696
// Verify the added Binding contains ID with restored query block.
697697
stmt, err := parser.New().ParseOneStmt("select * from t where a > ?", "", "")
698698
require.NoError(t, err)
699-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
699+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
700700
binding, matched := dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
701701
require.True(t, matched)
702702
require.Equal(t, "select * from `test` . `t` where `a` > ?", binding.OriginalSQL)
703703
require.Equal(t, "use_index(@`sel_1` `test`.`t` `idx_a`)", binding.ID)
704704

705705
utilCleanBindingEnv(tk)
706706
tk.MustExec("create global binding for select * from t where a > 10 using select /*+ use_index(t, idx_a) */ * from t where a > 10")
707-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
707+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
708708
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
709709
require.True(t, matched)
710710
require.Equal(t, "select * from `test` . `t` where `a` > ?", binding.OriginalSQL)
711711
require.Equal(t, "use_index(@`sel_1` `test`.`t` `idx_a`)", binding.ID)
712712

713713
utilCleanBindingEnv(tk)
714714
tk.MustExec("create global binding for select * from t where a > 10 using select /*+ use_index(@sel_1 t, idx_a) */ * from t where a > 10")
715-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
715+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
716716
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
717717
require.True(t, matched)
718718
require.Equal(t, "select * from `test` . `t` where `a` > ?", binding.OriginalSQL)
719719
require.Equal(t, "use_index(@`sel_1` `test`.`t` `idx_a`)", binding.ID)
720720

721721
utilCleanBindingEnv(tk)
722722
tk.MustExec("create global binding for select * from t where a > 10 using select /*+ use_index(@qb1 t, idx_a) qb_name(qb1) */ * from t where a > 10")
723-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
723+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
724724
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
725725
require.True(t, matched)
726726
require.Equal(t, "select * from `test` . `t` where `a` > ?", binding.OriginalSQL)
727727
require.Equal(t, "use_index(@`sel_1` `test`.`t` `idx_a`)", binding.ID)
728728

729729
utilCleanBindingEnv(tk)
730730
tk.MustExec("create global binding for select * from t where a > 10 using select /*+ use_index(T, IDX_A) */ * from t where a > 10")
731-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
731+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
732732
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
733733
require.True(t, matched)
734734
require.Equal(t, "select * from `test` . `t` where `a` > ?", binding.OriginalSQL)
@@ -738,7 +738,7 @@ func TestHintsSetID(t *testing.T) {
738738
err = tk.ExecToErr("create global binding for select * from t using select /*+ non_exist_hint() */ * from t")
739739
require.True(t, terror.ErrorEqual(err, parser.ErrParse))
740740
tk.MustExec("create global binding for select * from t where a > 10 using select * from t where a > 10")
741-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
741+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
742742
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
743743
require.True(t, matched)
744744
require.Equal(t, "select * from `test` . `t` where `a` > ?", binding.OriginalSQL)
@@ -761,7 +761,7 @@ func TestErrorBind(t *testing.T) {
761761

762762
stmt, err := parser.New().ParseOneStmt("select * from test . t where i > ?", "", "")
763763
require.NoError(t, err)
764-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
764+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
765765
binding, matched := dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
766766
require.True(t, matched)
767767
require.Equal(t, "select * from `test` . `t` where `i` > ?", binding.OriginalSQL)
@@ -801,7 +801,7 @@ func TestBestPlanInBaselines(t *testing.T) {
801801

802802
stmt, _, _ := utilNormalizeWithDefaultDB(t, "select a, b from t where a = 1 limit 0, 1")
803803

804-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
804+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
805805
binding, matched := dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
806806
require.True(t, matched)
807807
require.Equal(t, "select `a` , `b` from `test` . `t` where `a` = ? limit ...", binding.OriginalSQL)
@@ -844,7 +844,7 @@ func TestBindingSymbolList(t *testing.T) {
844844
stmt, err := parser.New().ParseOneStmt("select a, b from test . t where a = 1 limit 0, 1", "", "")
845845
require.NoError(t, err)
846846

847-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
847+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
848848
binding, matched := dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
849849
require.True(t, matched)
850850
require.Equal(t, "select `a` , `b` from `test` . `t` where `a` = ? limit ...", binding.OriginalSQL)
@@ -889,7 +889,7 @@ func TestBindingInListWithSingleLiteral(t *testing.T) {
889889
stmt, err := parser.New().ParseOneStmt("select a, b from test . t where a in (1)", "", "")
890890
require.NoError(t, err)
891891

892-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
892+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
893893
binding, matched := dom.BindHandle().MatchGlobalBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
894894
require.True(t, matched)
895895
require.Equal(t, "select `a` , `b` from `test` . `t` where `a` in ( ... )", binding.OriginalSQL)

pkg/bindinfo/session_handle_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func TestSessionBinding(t *testing.T) {
9292
stmt, err := parser.New().ParseOneStmt(testSQL.originSQL, "", "")
9393
require.NoError(t, err)
9494

95-
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
95+
_, noDBDigest := bindinfo.NormalizeStmtForBinding(stmt, "", true)
9696
binding, matched := handle.MatchSessionBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
9797
require.True(t, matched)
9898
require.Equal(t, testSQL.originSQL, binding.OriginalSQL)
@@ -129,7 +129,7 @@ func TestSessionBinding(t *testing.T) {
129129

130130
_, err = tk.Exec("drop session " + testSQL.dropSQL)
131131
require.NoError(t, err)
132-
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, bindinfo.WithoutDB(true))
132+
_, noDBDigest = bindinfo.NormalizeStmtForBinding(stmt, "", true)
133133
_, matched = handle.MatchSessionBinding(tk.Session(), noDBDigest, bindinfo.CollectTableNames(stmt))
134134
require.False(t, matched) // dropped
135135
}

pkg/planner/core/planbuilder.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ func (b *PlanBuilder) buildSet(ctx context.Context, v *ast.SetStmt) (base.Plan,
741741
func (b *PlanBuilder) buildDropBindPlan(v *ast.DropBindingStmt) (base.Plan, error) {
742742
var p *SQLBindPlan
743743
if v.OriginNode != nil {
744-
normdOrigSQL, sqlDigestWithDB := bindinfo.NormalizeStmtForBinding(v.OriginNode, bindinfo.WithSpecifiedDB(b.ctx.GetSessionVars().CurrentDB))
744+
normdOrigSQL, sqlDigestWithDB := bindinfo.NormalizeStmtForBinding(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, false)
745745
p = &SQLBindPlan{
746746
IsGlobal: v.GlobalScope,
747747
SQLBindOp: OpSQLBindDrop,

0 commit comments

Comments
 (0)