Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: use the unified parameters for plan cache #36781

Merged
merged 36 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
814fb81
fixup
qw4990 Aug 1, 2022
14db287
fixup
qw4990 Aug 1, 2022
a0feb55
fixup
qw4990 Aug 1, 2022
731c000
fixup
qw4990 Aug 1, 2022
6bb805c
fixup
qw4990 Aug 1, 2022
de032f7
fixup
qw4990 Aug 1, 2022
d108699
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
182078a
fixup
qw4990 Aug 2, 2022
96d5f78
fixup
qw4990 Aug 2, 2022
8fa64c8
fixup
qw4990 Aug 2, 2022
e0e9596
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
d8a759d
fixup
qw4990 Aug 2, 2022
38d2d97
fixup
qw4990 Aug 2, 2022
23cb0ff
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
271c016
fix ci
qw4990 Aug 2, 2022
88f9ff3
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
4478f41
fix ci
qw4990 Aug 2, 2022
32cb86f
fix ci
qw4990 Aug 2, 2022
c4f486b
fix ci
qw4990 Aug 2, 2022
8fecb68
fix ci
qw4990 Aug 2, 2022
50438cf
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
6577ca6
fix ci
qw4990 Aug 2, 2022
cf14e3c
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
9d55ec4
fix ci
qw4990 Aug 2, 2022
ec26fda
fix ci
qw4990 Aug 2, 2022
34b48ee
fix ci
qw4990 Aug 2, 2022
a059b4a
Merge branch 'master' into unified-vars-1
qw4990 Aug 2, 2022
71c029c
fix ci
qw4990 Aug 3, 2022
0cebcaa
Merge branch 'master' into unified-vars-1
qw4990 Aug 3, 2022
2aa058e
Merge branch 'master' into unified-vars-1
qw4990 Aug 3, 2022
9039818
Merge branch 'master' into unified-vars-1
qw4990 Aug 3, 2022
26eb162
Merge branch 'master' into unified-vars-1
ti-chi-bot Aug 3, 2022
fe34939
Merge branch 'master' into unified-vars-1
qw4990 Aug 3, 2022
9d3bf21
Merge branch 'master' into unified-vars-1
qw4990 Aug 3, 2022
d677aa5
Merge branch 'master' into unified-vars-1
ti-chi-bot Aug 3, 2022
e4974c8
Merge branch 'master' into unified-vars-1
qw4990 Aug 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 54 additions & 54 deletions executor/executor_test.go

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions executor/seqtest/prepared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"time"

"github.com/pingcap/tidb/executor"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/metrics"
"github.com/pingcap/tidb/parser/ast"
Expand All @@ -31,7 +32,6 @@ import (
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/session/txninfo"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/kvcache"
dto "github.com/prometheus/client_model/go"
Expand Down Expand Up @@ -100,7 +100,7 @@ func TestPrepared(t *testing.T) {
query := "select c1, c2 from prepare_test where c1 = ?"
stmtID, _, _, err := tk.Session().PrepareStmt(query)
require.NoError(t, err)
rs, err := tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)})
rs, err := tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1))
require.NoError(t, err)
tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 <nil>"))

Expand All @@ -118,31 +118,31 @@ func TestPrepared(t *testing.T) {

tk1.MustExec("use test")
tk1.MustExec("insert prepare_test (c1) values (3)")
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(3)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(3))
require.NoError(t, err)
tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3"))

tk.MustExec("delete from prepare_test")
query = "select c1 from prepare_test where c1 = (select c1 from prepare_test where c1 = ?)"
stmtID, _, _, err = tk.Session().PrepareStmt(query)
require.NoError(t, err)
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(3)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(3))
require.NoError(t, err)
require.NoError(t, rs.Close())
tk1.MustExec("insert prepare_test (c1) values (3)")
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(3)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(3))
require.NoError(t, err)
tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3"))

tk.MustExec("delete from prepare_test")
query = "select c1 from prepare_test where c1 in (select c1 from prepare_test where c1 = ?)"
stmtID, _, _, err = tk.Session().PrepareStmt(query)
require.NoError(t, err)
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(3)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(3))
require.NoError(t, err)
require.NoError(t, rs.Close())
tk1.MustExec("insert prepare_test (c1) values (3)")
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(3)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(3))
require.NoError(t, err)
tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3"))

Expand All @@ -152,11 +152,11 @@ func TestPrepared(t *testing.T) {
stmtID, _, _, err = tk.Session().PrepareStmt(query)
require.NoError(t, err)
tk.MustExec("rollback")
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(4)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(4))
require.NoError(t, err)
tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows())

execStmt := &ast.ExecuteStmt{ExecID: stmtID, BinaryArgs: []types.Datum{types.NewDatum(1)}}
execStmt := &ast.ExecuteStmt{ExecID: stmtID, BinaryArgs: expression.Args2Expressions4Test(1)}
// Check that ast.Statement created by executor.CompileExecutePreparedStmt has query text.
stmt, err := executor.CompileExecutePreparedStmt(context.TODO(), tk.Session(), execStmt,
tk.Session().GetInfoSchema().(infoschema.InfoSchema))
Expand All @@ -181,7 +181,7 @@ func TestPrepared(t *testing.T) {
require.NoError(t, err)

// Should success as the changed schema do not affect the prepared statement.
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)})
rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1))
require.NoError(t, err)
if rs != nil {
require.NoError(t, rs.Close())
Expand All @@ -193,11 +193,11 @@ func TestPrepared(t *testing.T) {
require.NoError(t, err)
tk.MustExec("alter table prepare_test drop column c2")

_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)})
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1))
require.True(t, plannercore.ErrUnknownColumn.Equal(err))

tk.MustExec("drop table prepare_test")
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)})
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1))
require.True(t, plannercore.ErrSchemaChanged.Equal(err))

// issue 3381
Expand Down Expand Up @@ -282,11 +282,11 @@ func TestPrepared(t *testing.T) {
// issue 8065
stmtID, _, _, err = tk.Session().PrepareStmt("select ? from dual")
require.NoError(t, err)
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)})
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1))
require.NoError(t, err)
stmtID, _, _, err = tk.Session().PrepareStmt("update prepare1 set a = ? where a = ?")
require.NoError(t, err)
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1), types.NewDatum(1)})
_, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1, 1))
require.NoError(t, err)
}
}
Expand Down Expand Up @@ -327,7 +327,7 @@ func TestPreparedLimitOffset(t *testing.T) {

stmtID, _, _, err := tk.Session().PrepareStmt("select id from prepare_test limit ?")
require.NoError(t, err)
rs, err := tk.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)})
rs, err := tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1))
require.NoError(t, err)
rs.Close()
}
Expand Down Expand Up @@ -910,7 +910,7 @@ func TestPreparedIssue17419(t *testing.T) {
tk1.Session().SetSessionManager(sm)
dom.ExpensiveQueryHandle().SetSessionManager(sm)

rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.NoError(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1", "2", "3"))
tk1.Session().SetProcessInfo("", time.Now(), mysql.ComStmtExecute, 0)
Expand Down
28 changes: 28 additions & 0 deletions expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -1434,3 +1434,31 @@ func PropagateType(evalType types.EvalType, args ...Expression) {
}
}
}

// Args2Expressions4Test converts these values to an expression list.
// This conversion is incomplete, so only use for test.
func Args2Expressions4Test(args ...interface{}) []Expression {
exprs := make([]Expression, len(args))
for i, v := range args {
d := types.NewDatum(v)
var ft *types.FieldType
switch d.Kind() {
case types.KindNull:
ft = types.NewFieldType(mysql.TypeNull)
case types.KindInt64:
ft = types.NewFieldType(mysql.TypeLong)
case types.KindUint64:
ft = types.NewFieldType(mysql.TypeLong)
ft.AddFlag(mysql.UnsignedFlag)
case types.KindFloat64:
ft = types.NewFieldType(mysql.TypeDouble)
case types.KindString:
ft = types.NewFieldType(mysql.TypeVarString)
default:
exprs[i] = nil
continue
}
exprs[i] = &Constant{Value: d, RetType: ft}
}
return exprs
}
6 changes: 6 additions & 0 deletions planner/core/plan_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ func parseParamTypes(sctx sessionctx.Context, isBinProtocol bool, binProtoVars [
} else { // txt protocol
varsNum = len(txtProtoVars)
for _, param := range txtProtoVars {
if c, ok := param.(*expression.Constant); ok { // from binary protocol
txtVarTypes = append(txtVarTypes, c.GetType())
continue
}

// from text protocol, there must be a GetVar function
name := param.(*expression.ScalarFunction).GetArgs()[0].String()
tp := sctx.GetSessionVars().UserVarTypes[name]
if tp == nil {
Expand Down
2 changes: 1 addition & 1 deletion planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ func (b *PlanBuilder) buildExecute(ctx context.Context, v *ast.ExecuteStmt) (Pla
}
exe := &Execute{Name: v.Name, TxtProtoVars: vars, ExecID: v.ExecID}
if v.BinaryArgs != nil {
exe.BinProtoVars = v.BinaryArgs.([]types.Datum)
exe.TxtProtoVars = v.BinaryArgs.([]expression.Expression)
}
return exe, nil
}
Expand Down
26 changes: 13 additions & 13 deletions planner/core/prepare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"time"

"github.com/pingcap/tidb/executor"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/metrics"
Expand All @@ -35,7 +36,6 @@ import (
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/hint"
"github.com/pingcap/tidb/util/kvcache"
"github.com/prometheus/client_golang/prometheus"
Expand Down Expand Up @@ -71,11 +71,11 @@ func TestPointGetPreparedPlan4PlanCache(t *testing.T) {

ctx := context.Background()
// first time plan generated
_, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(0)})
_, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(0))
require.NoError(t, err)

// using the generated plan but with different params
_, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(nil)})
_, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(nil))
require.NoError(t, err)
}

Expand Down Expand Up @@ -2851,7 +2851,7 @@ func TestPlanCacheWithRCWhenInfoSchemaChange(t *testing.T) {
tk2.MustExec("set tx_isolation='READ-COMMITTED'")
tk2.MustExec("begin pessimistic")
tk1.MustQuery("execute s").Check(testkit.Rows())
rs, err := tk2.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err := tk2.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk2.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows())

Expand All @@ -2865,7 +2865,7 @@ func TestPlanCacheWithRCWhenInfoSchemaChange(t *testing.T) {
tk1.MustQuery("execute s").Check(testkit.Rows("1 0"))
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
// execute binary protocol
rs, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk2.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 0"))
tk2.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
Expand Down Expand Up @@ -2895,7 +2895,7 @@ func TestConsistencyBetweenPrepareExecuteAndNormalSql(t *testing.T) {
// Execute using sql
tk1.MustQuery("execute s").Check(testkit.Rows("1 1", "2 2"))
// Execute using binary
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1", "2 2"))
// Normal sql
Expand All @@ -2907,7 +2907,7 @@ func TestConsistencyBetweenPrepareExecuteAndNormalSql(t *testing.T) {
// Execute using sql
tk1.MustQuery("execute s").Check(testkit.Rows("1 1", "2 2", "3 <nil>"))
// Execute using binary
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1", "2 2", "3 <nil>"))
// Normal sql
Expand All @@ -2925,7 +2925,7 @@ func verifyCache(ctx context.Context, t *testing.T, tk1 *testkit.TestKit, tk2 *t
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))

// This time, the cache will be hit.
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.NoError(t, err)
require.NoError(t, rs.Close())
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
Expand All @@ -2937,7 +2937,7 @@ func verifyCache(ctx context.Context, t *testing.T, tk1 *testkit.TestKit, tk2 *t
tk1.MustExec("execute s")
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
// Now the plan cache will be valid
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.NoError(t, err)
require.NoError(t, rs.Close())
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
Expand Down Expand Up @@ -3024,25 +3024,25 @@ func TestPointGetForUpdateAutoCommitCache(t *testing.T) {
tk1.MustExec("prepare s from 'select * from t1 where id = 1 for update'")
stmtID, _, _, err := tk1.Session().PrepareStmt("select * from t1 where id = 1 for update")
require.Nil(t, err)
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1"))
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))

rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1"))
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk2.MustExec("alter table t1 drop column c")
tk2.MustExec("update t1 set id = 10 where id = 1")

rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows())
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))

rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{})
rs, err = tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test())
require.Nil(t, err)
tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows())
tk1.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
Expand Down
Loading