From cafe6d8cd323be8e19214e172d9fed6ce954a7a6 Mon Sep 17 00:00:00 2001 From: AilinKid <314806019@qq.com> Date: Mon, 28 Aug 2023 16:23:08 +0800 Subject: [PATCH 1/3] don't recompute the hashcode when generated column substitution doesn't happened Signed-off-by: AilinKid <314806019@qq.com> --- planner/core/logical_plans_test.go | 20 ++ .../core/rule_generate_column_substitute.go | 40 ++- .../rule_generate_column_substitute_test.go | 280 ++++++++++++++++++ 3 files changed, 328 insertions(+), 12 deletions(-) create mode 100644 planner/core/rule_generate_column_substitute_test.go diff --git a/planner/core/logical_plans_test.go b/planner/core/logical_plans_test.go index 164ed95f2dae8..d0dd80af359fe 100644 --- a/planner/core/logical_plans_test.go +++ b/planner/core/logical_plans_test.go @@ -46,6 +46,26 @@ type plannerSuite struct { ctx sessionctx.Context } +func (p *plannerSuite) GetParser() *parser.Parser { + return p.p +} + +func (p *plannerSuite) GetIS() infoschema.InfoSchema { + return p.is +} + +func (p *plannerSuite) GetCtx() sessionctx.Context { + return p.ctx +} + +func CreatePlannerSuite(sctx sessionctx.Context, is infoschema.InfoSchema) (s *plannerSuite) { + s = new(plannerSuite) + s.is = is + s.p = parser.New() + s.ctx = sctx + return s +} + func createPlannerSuite() (s *plannerSuite) { s = new(plannerSuite) tblInfos := []*model.TableInfo{ diff --git a/planner/core/rule_generate_column_substitute.go b/planner/core/rule_generate_column_substitute.go index 2ddcda033adae..0baae3496d850 100644 --- a/planner/core/rule_generate_column_substitute.go +++ b/planner/core/rule_generate_column_substitute.go @@ -76,12 +76,15 @@ func collectGenerateColumn(lp LogicalPlan, exprToColumn ExprColumnMap) { } } -func tryToSubstituteExpr(expr *expression.Expression, lp LogicalPlan, candidateExpr expression.Expression, tp types.EvalType, schema *expression.Schema, col *expression.Column, opt *logicalOptimizeOp) { +func tryToSubstituteExpr(expr *expression.Expression, lp LogicalPlan, candidateExpr expression.Expression, tp types.EvalType, schema *expression.Schema, col *expression.Column, opt *logicalOptimizeOp) bool { + changed := false if (*expr).Equal(lp.SCtx(), candidateExpr) && candidateExpr.GetType().EvalType() == tp && schema.ColumnIndex(col) != -1 { *expr = col appendSubstituteColumnStep(lp, candidateExpr, col, opt) + changed = true } + return changed } func appendSubstituteColumnStep(lp LogicalPlan, candidateExpr expression.Expression, col *expression.Column, opt *logicalOptimizeOp) { @@ -97,26 +100,38 @@ func appendSubstituteColumnStep(lp LogicalPlan, candidateExpr expression.Express opt.appendStepToCurrent(lp.ID(), lp.TP(), reason, action) } -func substituteExpression(cond expression.Expression, lp LogicalPlan, exprToColumn ExprColumnMap, schema *expression.Schema, opt *logicalOptimizeOp) { +// SubstituteExpression is Exported for bench +func SubstituteExpression(cond expression.Expression, lp LogicalPlan, exprToColumn ExprColumnMap, schema *expression.Schema, opt *logicalOptimizeOp) bool { + return substituteExpression(cond, lp, exprToColumn, schema, opt) +} + +func substituteExpression(cond expression.Expression, lp LogicalPlan, exprToColumn ExprColumnMap, schema *expression.Schema, opt *logicalOptimizeOp) bool { sf, ok := cond.(*expression.ScalarFunction) if !ok { - return + return false } sctx := lp.SCtx().GetSessionVars().StmtCtx + changed := false + collectChanged := func(partial bool) { + if partial && !changed { + changed = true + } + } defer func() { // If the argument is not changed, hash code doesn't need to recount again. - // But we always do it to keep the code simple and stupid. - expression.ReHashCode(sf, sctx) + if changed { + expression.ReHashCode(sf, sctx) + } }() var expr *expression.Expression var tp types.EvalType switch sf.FuncName.L { case ast.EQ, ast.LT, ast.LE, ast.GT, ast.GE: for candidateExpr, column := range exprToColumn { - tryToSubstituteExpr(&sf.GetArgs()[1], lp, candidateExpr, sf.GetArgs()[0].GetType().EvalType(), schema, column, opt) + collectChanged(tryToSubstituteExpr(&sf.GetArgs()[1], lp, candidateExpr, sf.GetArgs()[0].GetType().EvalType(), schema, column, opt)) } for candidateExpr, column := range exprToColumn { - tryToSubstituteExpr(&sf.GetArgs()[0], lp, candidateExpr, sf.GetArgs()[1].GetType().EvalType(), schema, column, opt) + collectChanged(tryToSubstituteExpr(&sf.GetArgs()[0], lp, candidateExpr, sf.GetArgs()[1].GetType().EvalType(), schema, column, opt)) } case ast.In: expr = &sf.GetArgs()[0] @@ -132,21 +147,22 @@ func substituteExpression(cond expression.Expression, lp LogicalPlan, exprToColu } if canSubstitute { for candidateExpr, column := range exprToColumn { - tryToSubstituteExpr(expr, lp, candidateExpr, tp, schema, column, opt) + collectChanged(tryToSubstituteExpr(expr, lp, candidateExpr, tp, schema, column, opt)) } } case ast.Like: expr = &sf.GetArgs()[0] tp = sf.GetArgs()[1].GetType().EvalType() for candidateExpr, column := range exprToColumn { - tryToSubstituteExpr(expr, lp, candidateExpr, tp, schema, column, opt) + collectChanged(tryToSubstituteExpr(expr, lp, candidateExpr, tp, schema, column, opt)) } case ast.LogicOr, ast.LogicAnd: - substituteExpression(sf.GetArgs()[0], lp, exprToColumn, schema, opt) - substituteExpression(sf.GetArgs()[1], lp, exprToColumn, schema, opt) + collectChanged(substituteExpression(sf.GetArgs()[0], lp, exprToColumn, schema, opt)) + collectChanged(substituteExpression(sf.GetArgs()[1], lp, exprToColumn, schema, opt)) case ast.UnaryNot: - substituteExpression(sf.GetArgs()[0], lp, exprToColumn, schema, opt) + collectChanged(substituteExpression(sf.GetArgs()[0], lp, exprToColumn, schema, opt)) } + return changed } func (gc *gcSubstituter) substitute(ctx context.Context, lp LogicalPlan, exprToColumn ExprColumnMap, opt *logicalOptimizeOp) LogicalPlan { diff --git a/planner/core/rule_generate_column_substitute_test.go b/planner/core/rule_generate_column_substitute_test.go new file mode 100644 index 0000000000000..95582999fbed8 --- /dev/null +++ b/planner/core/rule_generate_column_substitute_test.go @@ -0,0 +1,280 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core_test + +import ( + "context" + "fmt" + "testing" + + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" +) + +// ➜ core git:(master) ✗ go tool pprof m5.file +// File: ___5BenchmarkSubstituteExpression_in_github_com_pingcap_tidb_planner_core.test +// Build ID: ea7c603fe0cf5e18deac5bf65d36f115467fce80 +// Type: alloc_space +// Time: Aug 28, 2023 at 3:58pm (CST) +// Entering interactive mode (type "help" for commands, "o" for options) +// (pprof) list BenchmarkSubstituteExpression +// Total: 1.40GB +// ROUTINE ======================== github.com/pingcap/tidb/planner/core_test.BenchmarkSubstituteExpression in /home/arenatlx/go/src/github.com/pingcap/tidb/planner/core/rule_generate_column_substitute_test.go +// +// 0 173.44MB (flat, cum) 12.12% of Total +// . . 29:func BenchmarkSubstituteExpression(b *testing.B) { +// . 169.91MB 30: store := testkit.CreateMockStore(b) +// . . 31: tk := testkit.NewTestKit(b, store) +// . . 32: tk.MustExec("use test") +// . . 33: tk.MustExec("drop table if exists tai") +// . 512.19kB 34: tk.MustExec("create table tai(a varchar(256), b varchar(256), c int as (a+1), d int as (b+1))") +// . . 35: is := domain.GetDomain(tk.Session()).InfoSchema() +// . . 36: _, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("tai")) +// . . 37: require.NoError(b, err) +// . . 38: condition := "(tai.a='%s' AND tai.b='%s') OR" + +// . . 39: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 40: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 41: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 42: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 43: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 44: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 45: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 46: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 47: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 48: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 49: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 50: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 51: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 52: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 53: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 54: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 55: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 56: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 57: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 58: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 59: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 60: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 61: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 62: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 63: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 64: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 65: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 66: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 67: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 68: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 69: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 70: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 71: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 72: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 73: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 74: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 75: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 76: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 77: "(tai.a='%s' AND tai.b='%s')" +// . . 78: addresses := make([]interface{}, 0, 90) +// . . 79: for i := 0; i < 80; i++ { +// . . 80: addresses = append(addresses, "0x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC51") +// . . 81: } +// . 520.04kB 82: condition = fmt.Sprintf(condition, addresses...) +// . . 83: s := core.CreatePlannerSuite(tk.Session(), is) +// . . 84: ctx := context.Background() +// . . 85: sql := "select * from tai where " + condition +// . . 86: fmt.Println(sql) +// . . 87: stmt, err := s.GetParser().ParseOneStmt(sql, "", "") +// . . 88: require.NoError(b, err, sql) +// . 512.01kB 89: p, _, err := core.BuildLogicalPlanForTest(ctx, s.GetCtx(), stmt, s.GetIS()) +// . . 90: require.NoError(b, err) +// . . 91: selection := p.(core.LogicalPlan).Children()[0] +// . . 92: m := make(core.ExprColumnMap, len(selection.Schema().Columns)) +// . . 93: for _, col := range selection.Schema().Columns { +// . . 94: if col.VirtualExpr != nil { +// . . 95: m[col.VirtualExpr] = col +// . . 96: } +// . . 97: } +// . . 98: b.ResetTimer() +// . . 99: b.StartTimer() +// . . 100: for i := 0; i < b.N; i++ { +// . 2.02MB 101: core.SubstituteExpression(selection.(*core.LogicalSelection).Conditions[0], selection, m, selection.Schema(), nil) +// . . 102: } +// . . 103: b.StopTimer() +// . . 104:} +// +// **************************************************************************************************************************************************************** +// after this patch +// ➜ core git:(fix-42788) ✗ go tool pprof m5.file +// File: ___5BenchmarkSubstituteExpression_in_github_com_pingcap_tidb_planner_core.test +// Build ID: dce9437cc5156c542bc642092b25b29de9b14d87 +// Type: alloc_space +// Time: Aug 28, 2023 at 4:04pm (CST) +// Entering interactive mode (type "help" for commands, "o" for options) +// (pprof) list BenchmarkSubstituteExpression +// Total: 1.41GB +// ROUTINE ======================== github.com/pingcap/tidb/planner/core_test.BenchmarkSubstituteExpression in /home/arenatlx/go/src/github.com/pingcap/tidb/planner/core/rule_generate_column_substitute_test.go +// +// 0 172.22MB (flat, cum) 11.90% of Total +// . . 29:func BenchmarkSubstituteExpression(b *testing.B) { +// . 170.21MB 30: store := testkit.CreateMockStore(b) +// . 1.01MB 31: tk := testkit.NewTestKit(b, store) +// . . 32: tk.MustExec("use test") +// . . 33: tk.MustExec("drop table if exists tai") +// . . 34: tk.MustExec("create table tai(a varchar(256), b varchar(256), c int as (a+1), d int as (b+1))") +// . . 35: is := domain.GetDomain(tk.Session()).InfoSchema() +// . . 36: _, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("tai")) +// . . 37: require.NoError(b, err) +// . . 38: condition := "(tai.a='%s' AND tai.b='%s') OR" + +// . . 39: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 40: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 41: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 42: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 43: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 44: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 45: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 46: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 47: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 48: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 49: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 50: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 51: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 52: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 53: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 54: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 55: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 56: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 57: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 58: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 59: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 60: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 61: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 62: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 63: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 64: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 65: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 66: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 67: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 68: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 69: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 70: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 71: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 72: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 73: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 74: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 75: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 76: "(tai.a='%s' AND tai.b='%s') OR" + +// . . 77: "(tai.a='%s' AND tai.b='%s')q" +// . . 78: addresses := make([]interface{}, 0, 90) +// . . 79: for i := 0; i < 80; i++ { +// . . 80: addresses = append(addresses, "0x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC51") +// . . 81: } +// . . 82: condition = fmt.Sprintf(condition, addresses...) +// . 520.04kB 83: s := core.CreatePlannerSuite(tk.Session(), is) +// . . 84: ctx := context.Background() +// . . 85: sql := "select * from tai where " + condition +// . . 86: fmt.Println(sql) +// . . 87: stmt, err := s.GetParser().ParseOneStmt(sql, "", "") +// . . 88: require.NoError(b, err, sql) +// . 512.07kB 89: p, _, err := core.BuildLogicalPlanForTest(ctx, s.GetCtx(), stmt, s.GetIS()) +// . . 90: require.NoError(b, err) +// . . 91: selection := p.(core.LogicalPlan).Children()[0] +// . . 92: m := make(core.ExprColumnMap, len(selection.Schema().Columns)) +// . . 93: for _, col := range selection.Schema().Columns { +// . . 94: if col.VirtualExpr != nil { +// +// (pprof) +// (pprof) q +// +// We couldn't see any allocation around core.SubstituteExpression after this patch is applied when there is no generated expression substitution happened +// in the recursive dfs down. In the real environment, the contract hash address will be more complicated and embedding layer will be deeper, causing +// the more memory consumption rather than just a few 2MB as shown above. +// +// Expression hashcode is a lazy utility used for comparison in some cases, if the later usage is not exist, the re-computation of them here is also unnecessary. +func BenchmarkSubstituteExpression(b *testing.B) { + store := testkit.CreateMockStore(b) + tk := testkit.NewTestKit(b, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists tai") + tk.MustExec("create table tai(a varchar(256), b varchar(256), c int as (a+1), d int as (b+1))") + is := domain.GetDomain(tk.Session()).InfoSchema() + _, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("tai")) + require.NoError(b, err) + condition := "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s') OR" + + "(tai.a='%s' AND tai.b='%s')q" + addresses := make([]interface{}, 0, 90) + for i := 0; i < 80; i++ { + addresses = append(addresses, "0x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC51") + } + condition = fmt.Sprintf(condition, addresses...) + s := core.CreatePlannerSuite(tk.Session(), is) + ctx := context.Background() + sql := "select * from tai where " + condition + fmt.Println(sql) + stmt, err := s.GetParser().ParseOneStmt(sql, "", "") + require.NoError(b, err, sql) + p, _, err := core.BuildLogicalPlanForTest(ctx, s.GetCtx(), stmt, s.GetIS()) + require.NoError(b, err) + selection := p.(core.LogicalPlan).Children()[0] + m := make(core.ExprColumnMap, len(selection.Schema().Columns)) + for _, col := range selection.Schema().Columns { + if col.VirtualExpr != nil { + m[col.VirtualExpr] = col + } + } + b.ResetTimer() + b.StartTimer() + for i := 0; i < b.N; i++ { + core.SubstituteExpression(selection.(*core.LogicalSelection).Conditions[0], selection, m, selection.Schema(), nil) + } + b.StopTimer() +} From 6b5927154e92e60c8066bfe58eceece1782c5b99 Mon Sep 17 00:00:00 2001 From: AilinKid <314806019@qq.com> Date: Mon, 28 Aug 2023 16:34:09 +0800 Subject: [PATCH 2/3] make fmt Signed-off-by: AilinKid <314806019@qq.com> --- planner/core/rule_generate_column_substitute_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/rule_generate_column_substitute_test.go b/planner/core/rule_generate_column_substitute_test.go index 95582999fbed8..ece8c6915f9a2 100644 --- a/planner/core/rule_generate_column_substitute_test.go +++ b/planner/core/rule_generate_column_substitute_test.go @@ -250,7 +250,7 @@ func BenchmarkSubstituteExpression(b *testing.B) { "(tai.a='%s' AND tai.b='%s') OR" + "(tai.a='%s' AND tai.b='%s') OR" + "(tai.a='%s' AND tai.b='%s') OR" + - "(tai.a='%s' AND tai.b='%s')q" + "(tai.a='%s' AND tai.b='%s')" addresses := make([]interface{}, 0, 90) for i := 0; i < 80; i++ { addresses = append(addresses, "0x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC510x6ab6Bf9117A8A9dd5a2FF203aa8a22457162fC51") From a57b1785818435ad9adb36dc3779f7722b149d9e Mon Sep 17 00:00:00 2001 From: AilinKid <314806019@qq.com> Date: Mon, 28 Aug 2023 17:31:37 +0800 Subject: [PATCH 3/3] make bazel Signed-off-by: AilinKid <314806019@qq.com> --- planner/core/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/planner/core/BUILD.bazel b/planner/core/BUILD.bazel index d0fffee8402ba..643509993f70f 100644 --- a/planner/core/BUILD.bazel +++ b/planner/core/BUILD.bazel @@ -221,6 +221,7 @@ go_test( "planbuilder_test.go", "point_get_plan_test.go", "preprocess_test.go", + "rule_generate_column_substitute_test.go", "rule_join_reorder_dp_test.go", "rule_join_reorder_test.go", "rule_result_reorder_test.go",