From 814fb81e6e92cb81834bd3466afb739c0afa4df9 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Mon, 1 Aug 2022 20:22:28 +0800 Subject: [PATCH 01/21] fixup --- server/conn_stmt.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/server/conn_stmt.go b/server/conn_stmt.go index 375efd1532030..cee378af2537a 100644 --- a/server/conn_stmt.go +++ b/server/conn_stmt.go @@ -39,6 +39,7 @@ import ( "context" "encoding/binary" "fmt" + "github.com/pingcap/tidb/expression" "math" "runtime/trace" "strconv" @@ -163,7 +164,7 @@ func (cc *clientConn) handleStmtExecute(ctx context.Context, data []byte) (err e ) cc.initInputEncoder(ctx) numParams := stmt.NumParams() - args := make([]types.Datum, numParams) + args := make([]expression.Expression, numParams) if numParams > 0 { nullBitmapLen := (numParams + 7) >> 3 if len(data) < (pos + nullBitmapLen + 1) { @@ -318,7 +319,7 @@ func parseStmtFetchCmd(data []byte) (uint32, uint32, error) { return stmtID, fetchSize, nil } -func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams [][]byte, +func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, boundParams [][]byte, nullBitmap, paramTypes, paramValues []byte, enc *inputDecoder) (err error) { pos := 0 var ( @@ -331,12 +332,16 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams enc = newInputDecoder(charset.CharsetUTF8) } + args := make([]types.Datum, len(params)) + ftypes := make([]*types.FieldType, len(params)) for i := 0; i < len(args); i++ { // if params had received via ComStmtSendLongData, use them directly. // ref https://dev.mysql.com/doc/internals/en/com-stmt-send-long-data.html // see clientConn#handleStmtSendLongData if boundParams[i] != nil { args[i] = types.NewBytesDatum(enc.decodeInput(boundParams[i])) + ftypes[i] = types.NewFieldType(mysql.TypeBit) + ftypes[i].AddFlag(mysql.BinaryFlag) continue } @@ -348,6 +353,7 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams var nilDatum types.Datum nilDatum.SetNull() args[i] = nilDatum + ftypes[i] = types.NewFieldType(mysql.TypeNull) continue } @@ -357,6 +363,7 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams tp := paramTypes[i<<1] isUnsigned := (paramTypes[(i<<1)+1] & 0x80) > 0 + ftypes[i] = types.NewFieldType(tp) switch tp { case mysql.TypeNull: @@ -373,6 +380,7 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams if isUnsigned { args[i] = types.NewUintDatum(uint64(paramValues[pos])) + ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(int8(paramValues[pos]))) } @@ -388,6 +396,7 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams valU16 := binary.LittleEndian.Uint16(paramValues[pos : pos+2]) if isUnsigned { args[i] = types.NewUintDatum(uint64(valU16)) + ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(int16(valU16))) } @@ -402,6 +411,7 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams valU32 := binary.LittleEndian.Uint32(paramValues[pos : pos+4]) if isUnsigned { args[i] = types.NewUintDatum(uint64(valU32)) + ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(int32(valU32))) } @@ -416,6 +426,7 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams valU64 := binary.LittleEndian.Uint64(paramValues[pos : pos+8]) if isUnsigned { args[i] = types.NewUintDatum(valU64) + ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(valU64)) } @@ -567,6 +578,11 @@ func parseExecArgs(sc *stmtctx.StatementContext, args []types.Datum, boundParams return } } + + for i := range params { + params[i] = &expression.Constant{Value: args[i], RetType: ftypes[i]} + } + return } From 14db28700ec9fae2329eb2840d87f4f8e2961582 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Mon, 1 Aug 2022 20:24:14 +0800 Subject: [PATCH 02/21] fixup --- planner/core/planbuilder.go | 2 +- server/conn_stmt.go | 2 +- server/driver.go | 4 ++-- server/driver_tidb.go | 3 ++- session/session.go | 6 +++--- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index fb6eb9475b033..4ca575b4b6a7f 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -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 } diff --git a/server/conn_stmt.go b/server/conn_stmt.go index cee378af2537a..beec3915368a7 100644 --- a/server/conn_stmt.go +++ b/server/conn_stmt.go @@ -230,7 +230,7 @@ func (cc *clientConn) handleStmtExecute(ctx context.Context, data []byte) (err e // The first return value indicates whether the call of executePreparedStmtAndWriteResult has no side effect and can be retried. // Currently the first return value is used to fallback to TiKV when TiFlash is down. -func (cc *clientConn) executePreparedStmtAndWriteResult(ctx context.Context, stmt PreparedStatement, args []types.Datum, useCursor bool) (bool, error) { +func (cc *clientConn) executePreparedStmtAndWriteResult(ctx context.Context, stmt PreparedStatement, args []expression.Expression, useCursor bool) (bool, error) { rs, err := stmt.Execute(ctx, args) if err != nil { return true, errors.Annotate(err, cc.preparedStmt2String(uint32(stmt.ID()))) diff --git a/server/driver.go b/server/driver.go index ae996715113ae..9c45cc93faddc 100644 --- a/server/driver.go +++ b/server/driver.go @@ -17,8 +17,8 @@ package server import ( "context" "crypto/tls" + "github.com/pingcap/tidb/expression" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" ) @@ -34,7 +34,7 @@ type PreparedStatement interface { ID() int // Execute executes the statement. - Execute(context.Context, []types.Datum) (ResultSet, error) + Execute(context.Context, []expression.Expression) (ResultSet, error) // AppendParam appends parameter to the statement. AppendParam(paramID int, data []byte) error diff --git a/server/driver_tidb.go b/server/driver_tidb.go index 063dca0e8bf88..ed5ebd375c2ef 100644 --- a/server/driver_tidb.go +++ b/server/driver_tidb.go @@ -18,6 +18,7 @@ import ( "context" "crypto/tls" "fmt" + "github.com/pingcap/tidb/expression" "strings" "sync/atomic" @@ -74,7 +75,7 @@ func (ts *TiDBStatement) ID() int { } // Execute implements PreparedStatement Execute method. -func (ts *TiDBStatement) Execute(ctx context.Context, args []types.Datum) (rs ResultSet, err error) { +func (ts *TiDBStatement) Execute(ctx context.Context, args []expression.Expression) (rs ResultSet, err error) { tidbRecordset, err := ts.ctx.ExecutePreparedStmt(ctx, ts.id, args) if err != nil { return nil, err diff --git a/session/session.go b/session/session.go index 819e69014f2f0..8fcee7d2ba80e 100644 --- a/session/session.go +++ b/session/session.go @@ -27,6 +27,7 @@ import ( stderrs "errors" "flag" "fmt" + "github.com/pingcap/tidb/expression" "math/rand" "runtime/pprof" "runtime/trace" @@ -82,7 +83,6 @@ import ( "github.com/pingcap/tidb/table/temptable" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/telemetry" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" @@ -154,7 +154,7 @@ type Session interface { // PrepareStmt executes prepare statement in binary protocol. PrepareStmt(sql string) (stmtID uint32, paramCount int, fields []*ast.ResultField, err error) // ExecutePreparedStmt executes a prepared statement. - ExecutePreparedStmt(ctx context.Context, stmtID uint32, param []types.Datum) (sqlexec.RecordSet, error) + ExecutePreparedStmt(ctx context.Context, stmtID uint32, param []expression.Expression) (sqlexec.RecordSet, error) DropPreparedStmt(stmtID uint32) error // SetSessionStatesHandler sets SessionStatesHandler for type stateType. SetSessionStatesHandler(stateType sessionstates.SessionStateType, handler sessionctx.SessionStatesHandler) @@ -2297,7 +2297,7 @@ func (s *session) preparedStmtExec(ctx context.Context, execStmt *ast.ExecuteStm } // ExecutePreparedStmt executes a prepared statement. -func (s *session) ExecutePreparedStmt(ctx context.Context, stmtID uint32, args []types.Datum) (sqlexec.RecordSet, error) { +func (s *session) ExecutePreparedStmt(ctx context.Context, stmtID uint32, args []expression.Expression) (sqlexec.RecordSet, error) { var err error if err = s.PrepareTxnCtx(ctx); err != nil { return nil, err From a0feb5502cba2bd3ca7b34b8cd796dfa26512d8d Mon Sep 17 00:00:00 2001 From: qw4990 Date: Mon, 1 Aug 2022 20:30:41 +0800 Subject: [PATCH 03/21] fixup --- executor/executor_test.go | 115 ++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/executor/executor_test.go b/executor/executor_test.go index 2d784d2626e13..f3a52519bba5a 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -3536,6 +3536,13 @@ func TestOOMPanicAction(t *testing.T) { tk.MustMatchErrMsg("update t set a = 4", "Out Of Memory Quota!.*") } +func newIntConst(v int) expression.Expression { + return &expression.Constant{ + Value: types.NewDatum(v), + RetType: types.NewFieldType(mysql.TypeInt24), + } +} + func TestPointGetPreparedPlan(t *testing.T) { store := testkit.CreateMockStore(t) @@ -3561,36 +3568,36 @@ func TestPointGetPreparedPlan(t *testing.T) { ctx := context.Background() // first time plan generated - rs, err := tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(0)}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // using the generated plan but with different params - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3")) @@ -3599,98 +3606,98 @@ func TestPointGetPreparedPlan(t *testing.T) { require.NoError(t, err) tk.Session().GetSessionVars().PreparedStmts[psuk1Id].(*plannercore.CachedPrepareStmt).PreparedAst.UseCache = false - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // test schema changed, cached plan should be invalidated tk.MustExec("alter table t add column col4 int default 10 after c") - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) tk.MustExec("alter table t drop index k_b") - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) tk.MustExec(`insert into t values(4, 3, 3, 11)`) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10", "4 3 3 11")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) tk.MustExec("delete from t where a = 4") tk.MustExec("alter table t add index k_b(b)") - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []types.Datum{types.NewDatum(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // use pk again - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) } @@ -3719,12 +3726,12 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { ctx := context.Background() // first time plan generated - rs, err := tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(0)}) + rs, err := tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(0)}) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // using the generated plan but with different params - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) @@ -3732,7 +3739,7 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { tk1.MustExec("set autocommit = 0") tk1.MustExec("begin") // try to exec using point get plan(this plan should not go short path) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) @@ -3742,7 +3749,7 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { tk2.MustExec("update t set c = c + 10 where c = 1") // try to point get again - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) @@ -3752,11 +3759,11 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { require.True(t, kv.ErrWriteConflict.Equal(err), fmt.Sprintf("error: %s", err)) // verify - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 11")) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []types.Datum{types.NewDatum(2)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(2)}) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) @@ -3790,29 +3797,29 @@ func TestPointUpdatePreparedPlan(t *testing.T) { ctx := context.Background() // first time plan generated - rs, err := tk.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 4")) // using the generated plan but with different params - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 5")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 6")) // updateID2 - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 8")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 10")) @@ -3821,46 +3828,46 @@ func TestPointUpdatePreparedPlan(t *testing.T) { updUkID1, _, _, err := tk.Session().PrepareStmt(`update t set c = c + 10 where b = ?`) require.NoError(t, err) tk.Session().GetSessionVars().PreparedStmts[updUkID1].(*plannercore.CachedPrepareStmt).PreparedAst.UseCache = false - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 20")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 30")) // test schema changed, cached plan should be invalidated tk.MustExec("alter table t add column col4 int default 10 after c") - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 31 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 32 10")) tk.MustExec("alter table t drop index k_b") - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 42 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 52 10")) tk.MustExec("alter table t add unique index k_b(b)") - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 62 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 72 10")) @@ -3893,12 +3900,12 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { require.NoError(t, err) // first time plan generated - rs, err := tk1.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err := tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 4")) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 5")) @@ -3907,7 +3914,7 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { tk1.MustExec("set autocommit = 0") tk1.MustExec("begin") // try to exec using point get plan(this plan should not go short path) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 6")) @@ -3938,12 +3945,12 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { // again next start a non autocommit txn tk1.MustExec("set autocommit = 0") tk1.MustExec("begin") - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 10")) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []types.Datum{types.NewDatum(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 11")) From 731c000d50535318de5d93aabc551d482007de79 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Mon, 1 Aug 2022 20:39:08 +0800 Subject: [PATCH 04/21] fixup --- testkit/asynctestkit.go | 8 ++++++-- testkit/testkit.go | 29 +++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/testkit/asynctestkit.go b/testkit/asynctestkit.go index cb9d013db20b6..4baa2f1495eac 100644 --- a/testkit/asynctestkit.go +++ b/testkit/asynctestkit.go @@ -19,6 +19,7 @@ package testkit import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "runtime" "testing" @@ -159,9 +160,12 @@ func (tk *AsyncTestKit) Exec(ctx context.Context, sql string, args ...interface{ return nil, err } - params := make([]types.Datum, len(args)) + params := make([]expression.Expression, len(args)) for i := 0; i < len(params); i++ { - params[i] = types.NewDatum(args[i]) + params[i], err = datum2Expression4Test(types.NewDatum(args[i])) + if err != nil { + return nil, err + } } rs, err := se.ExecutePreparedStmt(ctx, stmtID, params) diff --git a/testkit/testkit.go b/testkit/testkit.go index d92163b8f8fbe..575bd25814ad4 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -19,6 +19,8 @@ package testkit import ( "context" "fmt" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/parser/mysql" "strings" "sync" "testing" @@ -217,6 +219,26 @@ func (tk *TestKit) HasPlan4ExplainFor(result *Result, plan string) bool { return false } +func datum2Expression4Test(d types.Datum) (expression.Expression, error) { + 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.KindFloat64: + ft = types.NewFieldType(mysql.TypeDouble) + case types.KindString: + ft = types.NewFieldType(mysql.TypeVarString) + default: + return nil, fmt.Errorf("unsupport datum type %v", d.Kind()) + } + return &expression.Constant{ + Value: d, + RetType: ft, + }, nil +} + // Exec executes a sql statement using the prepared stmt API func (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, error) { ctx := context.Background() @@ -256,9 +278,12 @@ func (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, err if err != nil { return nil, errors.Trace(err) } - params := make([]types.Datum, len(args)) + params := make([]expression.Expression, len(args)) for i := 0; i < len(params); i++ { - params[i] = types.NewDatum(args[i]) + params[i], err = datum2Expression4Test(types.NewDatum(args[i])) + if err != nil { + return nil, err + } } rs, err := tk.session.ExecutePreparedStmt(ctx, stmtID, params) if err != nil { From 6bb805cf97a9711dfb0baa4039abade14d40c715 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Mon, 1 Aug 2022 20:50:02 +0800 Subject: [PATCH 05/21] fixup --- planner/core/plan_cache.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/planner/core/plan_cache.go b/planner/core/plan_cache.go index 6aa57399bb601..9942558e2f41a 100644 --- a/planner/core/plan_cache.go +++ b/planner/core/plan_cache.go @@ -102,8 +102,13 @@ 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 { + txtVarTypes = append(txtVarTypes, c.GetType()) + continue + } + name := param.(*expression.ScalarFunction).GetArgs()[0].String() - tp := sctx.GetSessionVars().UserVarTypes[name] + tp := sctx.GetSessionVars().UserVarTypes[name] // TODO: ??? if tp == nil { tp = types.NewFieldType(mysql.TypeNull) } From de032f7b19eb41ea6f658eea6703d99fef4bbf6f Mon Sep 17 00:00:00 2001 From: qw4990 Date: Mon, 1 Aug 2022 21:11:43 +0800 Subject: [PATCH 06/21] fixup --- planner/core/plan_cache.go | 5 +++-- server/conn_stmt.go | 2 +- server/driver.go | 2 +- server/driver_tidb.go | 2 +- session/session.go | 2 +- testkit/asynctestkit.go | 2 +- testkit/testkit.go | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/planner/core/plan_cache.go b/planner/core/plan_cache.go index 9942558e2f41a..0fe1694ac808f 100644 --- a/planner/core/plan_cache.go +++ b/planner/core/plan_cache.go @@ -102,13 +102,14 @@ 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 { + 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] // TODO: ??? + tp := sctx.GetSessionVars().UserVarTypes[name] if tp == nil { tp = types.NewFieldType(mysql.TypeNull) } diff --git a/server/conn_stmt.go b/server/conn_stmt.go index beec3915368a7..20c126132921d 100644 --- a/server/conn_stmt.go +++ b/server/conn_stmt.go @@ -39,13 +39,13 @@ import ( "context" "encoding/binary" "fmt" - "github.com/pingcap/tidb/expression" "math" "runtime/trace" "strconv" "time" "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/mysql" diff --git a/server/driver.go b/server/driver.go index 9c45cc93faddc..a805e531f056a 100644 --- a/server/driver.go +++ b/server/driver.go @@ -17,8 +17,8 @@ package server import ( "context" "crypto/tls" - "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/util/chunk" ) diff --git a/server/driver_tidb.go b/server/driver_tidb.go index ed5ebd375c2ef..12321e12e5ced 100644 --- a/server/driver_tidb.go +++ b/server/driver_tidb.go @@ -18,11 +18,11 @@ import ( "context" "crypto/tls" "fmt" - "github.com/pingcap/tidb/expression" "strings" "sync/atomic" "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/charset" diff --git a/session/session.go b/session/session.go index 8fcee7d2ba80e..dbc7efe580980 100644 --- a/session/session.go +++ b/session/session.go @@ -27,7 +27,6 @@ import ( stderrs "errors" "flag" "fmt" - "github.com/pingcap/tidb/expression" "math/rand" "runtime/pprof" "runtime/trace" @@ -49,6 +48,7 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" diff --git a/testkit/asynctestkit.go b/testkit/asynctestkit.go index 4baa2f1495eac..9f5cde79200c4 100644 --- a/testkit/asynctestkit.go +++ b/testkit/asynctestkit.go @@ -19,11 +19,11 @@ package testkit import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "runtime" "testing" "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/types" diff --git a/testkit/testkit.go b/testkit/testkit.go index 575bd25814ad4..d5ee23fea7fa8 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -19,16 +19,16 @@ package testkit import ( "context" "fmt" - "github.com/pingcap/tidb/expression" - "github.com/pingcap/tidb/parser/mysql" "strings" "sync" "testing" "time" "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" From 182078a131e064c4926be47c8e2b14e5dc799dfe Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 10:49:54 +0800 Subject: [PATCH 07/21] fixup --- executor/seqtest/prepared_test.go | 32 +++++++++++++++---------------- expression/expression.go | 23 ++++++++++++++++++++++ testkit/asynctestkit.go | 6 +----- testkit/testkit.go | 27 +------------------------- 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go index db25f96cdf5a0..52b7c3b9b70db 100644 --- a/executor/seqtest/prepared_test.go +++ b/executor/seqtest/prepared_test.go @@ -18,6 +18,7 @@ import ( "context" "crypto/tls" "fmt" + "github.com/pingcap/tidb/expression" "math" "testing" "time" @@ -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" @@ -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.Expression{expression.Value2Expression4Test(1)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 ")) @@ -118,7 +118,7 @@ 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.Expression{expression.Value2Expression4Test(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3")) @@ -126,11 +126,11 @@ func TestPrepared(t *testing.T) { 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.Expression{expression.Value2Expression4Test(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.Expression{expression.Value2Expression4Test(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3")) @@ -138,11 +138,11 @@ func TestPrepared(t *testing.T) { 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.Expression{expression.Value2Expression4Test(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.Expression{expression.Value2Expression4Test(3)}) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3")) @@ -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.Expression{expression.Value2Expression4Test(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.Expression{expression.Value2Expression4Test(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)) @@ -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.Expression{expression.Value2Expression4Test(1)}) require.NoError(t, err) if rs != nil { require.NoError(t, rs.Close()) @@ -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.Expression{expression.Value2Expression4Test(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.Expression{expression.Value2Expression4Test(1)}) require.True(t, plannercore.ErrSchemaChanged.Equal(err)) // issue 3381 @@ -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.Expression{expression.Value2Expression4Test(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.Expression{expression.Value2Expression4Test(1), expression.Value2Expression4Test(1)}) require.NoError(t, err) } } @@ -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.Expression{expression.Value2Expression4Test(1)}) require.NoError(t, err) rs.Close() } @@ -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.Expression{expression.Value2Expression4Test(nil)}) 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) diff --git a/expression/expression.go b/expression/expression.go index 52a94c6056ec4..f37620e7a488b 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -1434,3 +1434,26 @@ func PropagateType(evalType types.EvalType, args ...Expression) { } } } + +// Value2Expression4Test converts the value to an expression. +// This conversion is incomplete, so only use for test. +func Value2Expression4Test(v interface{}) Expression { + 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.KindFloat64: + ft = types.NewFieldType(mysql.TypeDouble) + case types.KindString: + ft = types.NewFieldType(mysql.TypeVarString) + default: + return nil + } + return &Constant{ + Value: d, + RetType: ft, + } +} diff --git a/testkit/asynctestkit.go b/testkit/asynctestkit.go index 9f5cde79200c4..545045fb6668e 100644 --- a/testkit/asynctestkit.go +++ b/testkit/asynctestkit.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/session" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/sqlexec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -162,10 +161,7 @@ func (tk *AsyncTestKit) Exec(ctx context.Context, sql string, args ...interface{ params := make([]expression.Expression, len(args)) for i := 0; i < len(params); i++ { - params[i], err = datum2Expression4Test(types.NewDatum(args[i])) - if err != nil { - return nil, err - } + params[i] = expression.Value2Expression4Test(args[i]) } rs, err := se.ExecutePreparedStmt(ctx, stmtID, params) diff --git a/testkit/testkit.go b/testkit/testkit.go index d5ee23fea7fa8..5e04ea519d785 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -28,11 +28,9 @@ import ( "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" - "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/sqlexec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -219,26 +217,6 @@ func (tk *TestKit) HasPlan4ExplainFor(result *Result, plan string) bool { return false } -func datum2Expression4Test(d types.Datum) (expression.Expression, error) { - 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.KindFloat64: - ft = types.NewFieldType(mysql.TypeDouble) - case types.KindString: - ft = types.NewFieldType(mysql.TypeVarString) - default: - return nil, fmt.Errorf("unsupport datum type %v", d.Kind()) - } - return &expression.Constant{ - Value: d, - RetType: ft, - }, nil -} - // Exec executes a sql statement using the prepared stmt API func (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, error) { ctx := context.Background() @@ -280,10 +258,7 @@ func (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, err } params := make([]expression.Expression, len(args)) for i := 0; i < len(params); i++ { - params[i], err = datum2Expression4Test(types.NewDatum(args[i])) - if err != nil { - return nil, err - } + params[i] = expression.Value2Expression4Test(args[i]) } rs, err := tk.session.ExecutePreparedStmt(ctx, stmtID, params) if err != nil { From 96d5f78325c439e0163a54a11f4830b0847c78cc Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 11:25:59 +0800 Subject: [PATCH 08/21] fixup --- executor/executor_test.go | 115 +++++++++---------- executor/seqtest/prepared_test.go | 30 ++--- expression/expression.go | 37 +++--- testkit/asynctestkit.go | 5 +- testkit/testkit.go | 5 +- tests/realtikvtest/txntest/txn_state_test.go | 8 +- 6 files changed, 93 insertions(+), 107 deletions(-) diff --git a/executor/executor_test.go b/executor/executor_test.go index f3a52519bba5a..16e40483a55fb 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -3536,13 +3536,6 @@ func TestOOMPanicAction(t *testing.T) { tk.MustMatchErrMsg("update t set a = 4", "Out Of Memory Quota!.*") } -func newIntConst(v int) expression.Expression { - return &expression.Constant{ - Value: types.NewDatum(v), - RetType: types.NewFieldType(mysql.TypeInt24), - } -} - func TestPointGetPreparedPlan(t *testing.T) { store := testkit.CreateMockStore(t) @@ -3568,36 +3561,36 @@ func TestPointGetPreparedPlan(t *testing.T) { ctx := context.Background() // first time plan generated - rs, err := tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(0)}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // using the generated plan but with different params - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3")) @@ -3606,98 +3599,98 @@ func TestPointGetPreparedPlan(t *testing.T) { require.NoError(t, err) tk.Session().GetSessionVars().PreparedStmts[psuk1Id].(*plannercore.CachedPrepareStmt).PreparedAst.UseCache = false - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // test schema changed, cached plan should be invalidated tk.MustExec("alter table t add column col4 int default 10 after c") - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) tk.MustExec("alter table t drop index k_b") - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) tk.MustExec(`insert into t values(4, 3, 3, 11)`) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10", "4 3 3 11")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) tk.MustExec("delete from t where a = 4") tk.MustExec("alter table t add index k_b(b)") - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, []expression.Expression{newIntConst(0)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // use pk again - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk2Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(3)) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("3 3 3 10")) } @@ -3726,12 +3719,12 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { ctx := context.Background() // first time plan generated - rs, err := tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(0)}) + rs, err := tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(0)) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(nil) // using the generated plan but with different params - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) @@ -3739,7 +3732,7 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { tk1.MustExec("set autocommit = 0") tk1.MustExec("begin") // try to exec using point get plan(this plan should not go short path) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) @@ -3749,7 +3742,7 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { tk2.MustExec("update t set c = c + 10 where c = 1") // try to point get again - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 1")) @@ -3759,11 +3752,11 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { require.True(t, kv.ErrWriteConflict.Equal(err), fmt.Sprintf("error: %s", err)) // verify - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(1)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1 11")) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, []expression.Expression{newIntConst(2)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, pspk1Id, expression.Args2Expressions4Test(2)) require.NoError(t, err) tk1.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("2 2 2")) @@ -3797,29 +3790,29 @@ func TestPointUpdatePreparedPlan(t *testing.T) { ctx := context.Background() // first time plan generated - rs, err := tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 4")) // using the generated plan but with different params - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 5")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 6")) // updateID2 - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 8")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID2, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 10")) @@ -3828,46 +3821,46 @@ func TestPointUpdatePreparedPlan(t *testing.T) { updUkID1, _, _, err := tk.Session().PrepareStmt(`update t set c = c + 10 where b = ?`) require.NoError(t, err) tk.Session().GetSessionVars().PreparedStmts[updUkID1].(*plannercore.CachedPrepareStmt).PreparedAst.UseCache = false - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 20")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 30")) // test schema changed, cached plan should be invalidated tk.MustExec("alter table t add column col4 int default 10 after c") - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 31 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 32 10")) tk.MustExec("alter table t drop index k_b") - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 42 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 52 10")) tk.MustExec("alter table t add unique index k_b(b)") - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 62 10")) - rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, []expression.Expression{newIntConst(3)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 72 10")) @@ -3900,12 +3893,12 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { require.NoError(t, err) // first time plan generated - rs, err := tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err := tk1.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 4")) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 5")) @@ -3914,7 +3907,7 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { tk1.MustExec("set autocommit = 0") tk1.MustExec("begin") // try to exec using point get plan(this plan should not go short path) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 6")) @@ -3945,12 +3938,12 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { // again next start a non autocommit txn tk1.MustExec("set autocommit = 0") tk1.MustExec("begin") - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 10")) - rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, []expression.Expression{newIntConst(3)}) + rs, err = tk1.Session().ExecutePreparedStmt(ctx, updateID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) tk1.MustQuery("select * from t where a = 3").Check(testkit.Rows("3 3 11")) diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go index 52b7c3b9b70db..f3c1c9225cd7b 100644 --- a/executor/seqtest/prepared_test.go +++ b/executor/seqtest/prepared_test.go @@ -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, []expression.Expression{expression.Value2Expression4Test(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 ")) @@ -118,7 +118,7 @@ func TestPrepared(t *testing.T) { tk1.MustExec("use test") tk1.MustExec("insert prepare_test (c1) values (3)") - rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, []expression.Expression{expression.Value2Expression4Test(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")) @@ -126,11 +126,11 @@ func TestPrepared(t *testing.T) { 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, []expression.Expression{expression.Value2Expression4Test(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, []expression.Expression{expression.Value2Expression4Test(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")) @@ -138,11 +138,11 @@ func TestPrepared(t *testing.T) { 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, []expression.Expression{expression.Value2Expression4Test(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, []expression.Expression{expression.Value2Expression4Test(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")) @@ -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, []expression.Expression{expression.Value2Expression4Test(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: []expression.Expression{expression.Value2Expression4Test(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)) @@ -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, []expression.Expression{expression.Value2Expression4Test(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1)) require.NoError(t, err) if rs != nil { require.NoError(t, rs.Close()) @@ -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, []expression.Expression{expression.Value2Expression4Test(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, []expression.Expression{expression.Value2Expression4Test(1)}) + _, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1)) require.True(t, plannercore.ErrSchemaChanged.Equal(err)) // issue 3381 @@ -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, []expression.Expression{expression.Value2Expression4Test(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, []expression.Expression{expression.Value2Expression4Test(1), expression.Value2Expression4Test(1)}) + _, err = tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1, 1)) require.NoError(t, err) } } @@ -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, []expression.Expression{expression.Value2Expression4Test(1)}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1)) require.NoError(t, err) rs.Close() } @@ -910,7 +910,7 @@ func TestPreparedIssue17419(t *testing.T) { tk1.Session().SetSessionManager(sm) dom.ExpensiveQueryHandle().SetSessionManager(sm) - rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, []expression.Expression{expression.Value2Expression4Test(nil)}) + rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(nil)) 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) diff --git a/expression/expression.go b/expression/expression.go index f37620e7a488b..0c78f16ebe7ad 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -1435,25 +1435,24 @@ func PropagateType(evalType types.EvalType, args ...Expression) { } } -// Value2Expression4Test converts the value to an expression. +// Args2Expressions4Test converts these values to an expression list. // This conversion is incomplete, so only use for test. -func Value2Expression4Test(v interface{}) Expression { - 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.KindFloat64: - ft = types.NewFieldType(mysql.TypeDouble) - case types.KindString: - ft = types.NewFieldType(mysql.TypeVarString) - default: - return nil - } - return &Constant{ - Value: d, - RetType: ft, +func Args2Expressions4Test(args ...interface{}) []Expression { + exprs := make([]Expression, len(args)) + for i, v := range args { + d := types.NewDatum(v) + switch d.Kind() { + case types.KindNull: + exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeNull)} + case types.KindInt64: + exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeLong)} + case types.KindFloat64: + exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeDouble)} + case types.KindString: + exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeVarString)} + default: + exprs[i] = nil + } } + return exprs } diff --git a/testkit/asynctestkit.go b/testkit/asynctestkit.go index 545045fb6668e..aa0f3fcadf8ef 100644 --- a/testkit/asynctestkit.go +++ b/testkit/asynctestkit.go @@ -159,10 +159,7 @@ func (tk *AsyncTestKit) Exec(ctx context.Context, sql string, args ...interface{ return nil, err } - params := make([]expression.Expression, len(args)) - for i := 0; i < len(params); i++ { - params[i] = expression.Value2Expression4Test(args[i]) - } + params := expression.Args2Expressions4Test(args...) rs, err := se.ExecutePreparedStmt(ctx, stmtID, params) if err != nil { diff --git a/testkit/testkit.go b/testkit/testkit.go index 5e04ea519d785..78605a88e296b 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -256,10 +256,7 @@ func (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, err if err != nil { return nil, errors.Trace(err) } - params := make([]expression.Expression, len(args)) - for i := 0; i < len(params); i++ { - params[i] = expression.Value2Expression4Test(args[i]) - } + params := expression.Args2Expressions4Test(args...) rs, err := tk.session.ExecutePreparedStmt(ctx, stmtID, params) if err != nil { return rs, errors.Trace(err) diff --git a/tests/realtikvtest/txntest/txn_state_test.go b/tests/realtikvtest/txntest/txn_state_test.go index 092c3af2f0b8d..d68f4a527edd3 100644 --- a/tests/realtikvtest/txntest/txn_state_test.go +++ b/tests/realtikvtest/txntest/txn_state_test.go @@ -16,6 +16,7 @@ package txntest import ( "context" + "github.com/pingcap/tidb/expression" "strconv" "testing" "time" @@ -25,7 +26,6 @@ import ( "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/tests/realtikvtest" - "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" ) @@ -309,7 +309,7 @@ func TestTxnInfoWithPSProtocol(t *testing.T) { require.NoError(t, failpoint.Enable("tikvclient/beforePrewrite", "pause")) ch := make(chan interface{}) go func() { - _, err := tk.Session().ExecutePreparedStmt(context.Background(), idInsert, types.MakeDatums(1)) + _, err := tk.Session().ExecutePreparedStmt(context.Background(), idInsert, expression.Args2Expressions4Test(1)) require.NoError(t, err) ch <- nil }() @@ -338,12 +338,12 @@ func TestTxnInfoWithPSProtocol(t *testing.T) { tk.MustExec("begin pessimistic") - _, err = tk.Session().ExecutePreparedStmt(context.Background(), id1, types.MakeDatums(1)) + _, err = tk.Session().ExecutePreparedStmt(context.Background(), id1, expression.Args2Expressions4Test(1)) require.NoError(t, err) require.NoError(t, failpoint.Enable("tikvclient/beforePessimisticLock", "pause")) go func() { - _, err := tk.Session().ExecutePreparedStmt(context.Background(), id2, types.MakeDatums(1)) + _, err := tk.Session().ExecutePreparedStmt(context.Background(), id2, expression.Args2Expressions4Test(1)) require.NoError(t, err) ch <- nil }() From 8fa64c85bbd47b91dbfa0dd3157afb7b5e30e04a Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 11:27:24 +0800 Subject: [PATCH 09/21] fixup --- executor/seqtest/prepared_test.go | 2 +- tests/realtikvtest/txntest/txn_state_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go index f3c1c9225cd7b..2553ab10c4f01 100644 --- a/executor/seqtest/prepared_test.go +++ b/executor/seqtest/prepared_test.go @@ -18,12 +18,12 @@ import ( "context" "crypto/tls" "fmt" - "github.com/pingcap/tidb/expression" "math" "testing" "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" diff --git a/tests/realtikvtest/txntest/txn_state_test.go b/tests/realtikvtest/txntest/txn_state_test.go index d68f4a527edd3..59049dd129151 100644 --- a/tests/realtikvtest/txntest/txn_state_test.go +++ b/tests/realtikvtest/txntest/txn_state_test.go @@ -16,12 +16,12 @@ package txntest import ( "context" - "github.com/pingcap/tidb/expression" "strconv" "testing" "time" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/testkit" From d8a759d8c5612ca511c102a4dea61d74c31fd024 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 11:43:13 +0800 Subject: [PATCH 10/21] fixup --- planner/core/prepare_test.go | 26 +++++++++---------- session/bench_test.go | 3 ++- .../sessionstates/session_states_test.go | 11 +++----- sessiontxn/isolation/readcommitted_test.go | 10 +++---- .../pessimistictest/pessimistic_test.go | 8 +++--- tests/realtikvtest/txntest/txn_test.go | 4 +-- 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index bae9b4d491a5d..35799f7de56c9 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -17,6 +17,7 @@ package core_test import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "math" "math/rand" "strconv" @@ -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" @@ -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) } @@ -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()) @@ -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")) @@ -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 @@ -2907,7 +2907,7 @@ func TestConsistencyBetweenPrepareExecuteAndNormalSql(t *testing.T) { // Execute using sql tk1.MustQuery("execute s").Check(testkit.Rows("1 1", "2 2", "3 ")) // 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 ")) // Normal sql @@ -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")) @@ -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")) @@ -3024,12 +3024,12 @@ 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")) @@ -3037,12 +3037,12 @@ func TestPointGetForUpdateAutoCommitCache(t *testing.T) { 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")) diff --git a/session/bench_test.go b/session/bench_test.go index 44178871a124e..78b58948a0f64 100644 --- a/session/bench_test.go +++ b/session/bench_test.go @@ -27,6 +27,7 @@ import ( "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" @@ -326,7 +327,7 @@ func BenchmarkPreparedPointGet(b *testing.B) { alloc := chunk.NewAllocator() b.ResetTimer() for i := 0; i < b.N; i++ { - rs, err := se.ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(64)}) + rs, err := se.ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(64)) if err != nil { b.Fatal(err) } diff --git a/sessionctx/sessionstates/session_states_test.go b/sessionctx/sessionstates/session_states_test.go index 5d35e168ec925..0b01bb57481af 100644 --- a/sessionctx/sessionstates/session_states_test.go +++ b/sessionctx/sessionstates/session_states_test.go @@ -18,6 +18,7 @@ import ( "context" "encoding/binary" "fmt" + "github.com/pingcap/tidb/expression" "strconv" "strings" "testing" @@ -31,7 +32,6 @@ import ( "github.com/pingcap/tidb/server" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/sem" "github.com/stretchr/testify/require" ) @@ -855,8 +855,7 @@ func TestPreparedStatements(t *testing.T) { return stmtID }, checkFunc: func(tk *testkit.TestKit, conn server.MockConn, param any) { - datum := []types.Datum{types.NewDatum(1)} - rs, err := tk.Session().ExecutePreparedStmt(context.Background(), param.(uint32), datum) + rs, err := tk.Session().ExecutePreparedStmt(context.Background(), param.(uint32), expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, "").Check(testkit.Rows("1")) }, @@ -878,8 +877,7 @@ func TestPreparedStatements(t *testing.T) { }, checkFunc: func(tk *testkit.TestKit, conn server.MockConn, param any) { tk.MustQuery("execute stmt").Check(testkit.Rows("10")) - datum := []types.Datum{types.NewDatum(1)} - rs, err := tk.Session().ExecutePreparedStmt(context.Background(), param.(uint32), datum) + rs, err := tk.Session().ExecutePreparedStmt(context.Background(), param.(uint32), expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.ResultSetToResult(rs, "").Check(testkit.Rows("1")) }, @@ -911,8 +909,7 @@ func TestPreparedStatements(t *testing.T) { rs, err := tk.Session().ExecutePreparedStmt(context.Background(), stmtIDs[1], nil) require.NoError(t, err) tk.ResultSetToResult(rs, "").Check(testkit.Rows()) - datum := []types.Datum{types.NewDatum(1), types.NewDatum(2), types.NewDatum(3)} - _, err = tk.Session().ExecutePreparedStmt(context.Background(), stmtIDs[0], datum) + _, err = tk.Session().ExecutePreparedStmt(context.Background(), stmtIDs[0], expression.Args2Expressions4Test(1, 2, 3)) require.NoError(t, err) rs, err = tk.Session().ExecutePreparedStmt(context.Background(), stmtIDs[1], nil) require.NoError(t, err) diff --git a/sessiontxn/isolation/readcommitted_test.go b/sessiontxn/isolation/readcommitted_test.go index 896a4ddbc134e..30c82091a07e6 100644 --- a/sessiontxn/isolation/readcommitted_test.go +++ b/sessiontxn/isolation/readcommitted_test.go @@ -17,6 +17,7 @@ package isolation_test import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "testing" "time" @@ -35,7 +36,6 @@ import ( "github.com/pingcap/tidb/sessiontxn/isolation" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/testfork" - "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" tikverr "github.com/tikv/client-go/v2/error" ) @@ -164,7 +164,7 @@ func TestPessimisticRCTxnContextProviderRCCheckForPrepareExecute(t *testing.T) { // first ts should use the txn startTS stmt, _, _, err := tk.Session().PrepareStmt("select * from t") require.NoError(t, err) - rs, err := tk.Session().ExecutePreparedStmt(ctx, stmt, []types.Datum{}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, stmt, expression.Args2Expressions4Test()) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1")) require.NoError(t, err) ts, err := provider.GetStmtForUpdateTS() @@ -172,7 +172,7 @@ func TestPessimisticRCTxnContextProviderRCCheckForPrepareExecute(t *testing.T) { require.Equal(t, txnStartTS, ts) // second ts should reuse the txn startTS - rs, err = tk.Session().ExecutePreparedStmt(ctx, stmt, []types.Datum{}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, stmt, expression.Args2Expressions4Test()) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 1")) require.NoError(t, err) ts, err = provider.GetStmtForUpdateTS() @@ -181,7 +181,7 @@ func TestPessimisticRCTxnContextProviderRCCheckForPrepareExecute(t *testing.T) { tk2.MustExec("update t set v = v + 10 where id = 1") compareTS := getOracleTS(t, se) - rs, err = tk.Session().ExecutePreparedStmt(ctx, stmt, []types.Datum{}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, stmt, expression.Args2Expressions4Test()) require.NoError(t, err) _, err = session.ResultSetToStringSlice(ctx, tk.Session(), rs) require.Error(t, err) @@ -192,7 +192,7 @@ func TestPessimisticRCTxnContextProviderRCCheckForPrepareExecute(t *testing.T) { require.Greater(t, compareTS, ts) // retry tk.Session().GetSessionVars().RetryInfo.Retrying = true - rs, err = tk.Session().ExecutePreparedStmt(ctx, stmt, []types.Datum{}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, stmt, expression.Args2Expressions4Test()) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 11")) ts, err = provider.GetStmtForUpdateTS() diff --git a/tests/realtikvtest/pessimistictest/pessimistic_test.go b/tests/realtikvtest/pessimistictest/pessimistic_test.go index 89c818dca5d5f..324ad4de854d4 100644 --- a/tests/realtikvtest/pessimistictest/pessimistic_test.go +++ b/tests/realtikvtest/pessimistictest/pessimistic_test.go @@ -17,6 +17,7 @@ package pessimistictest import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "strconv" "strings" "sync" @@ -41,7 +42,6 @@ import ( "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/tests/realtikvtest" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/deadlockhistory" "github.com/stretchr/testify/require" @@ -2767,7 +2767,7 @@ func TestPlanCacheSchemaChange(t *testing.T) { stmtID, _, _, err := tk2.Session().PrepareStmt("update t set vv = vv + 1 where v = ?") require.NoError(t, err) - _, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(1)}) + _, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(1)) require.NoError(t, err) tk.MustExec("begin pessimistic") @@ -2786,11 +2786,11 @@ func TestPlanCacheSchemaChange(t *testing.T) { tk.CheckExecResult(1, 0) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) - _, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(4)}) + _, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(4)) require.NoError(t, err) tk2.CheckExecResult(0, 0) tk2.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) - _, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, []types.Datum{types.NewDatum(5)}) + _, err = tk2.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(5)) require.NoError(t, err) tk2.CheckExecResult(1, 0) tk2.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) diff --git a/tests/realtikvtest/txntest/txn_test.go b/tests/realtikvtest/txntest/txn_test.go index 3d7c512c14505..7020587f02d66 100644 --- a/tests/realtikvtest/txntest/txn_test.go +++ b/tests/realtikvtest/txntest/txn_test.go @@ -17,12 +17,12 @@ package txntest import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "testing" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/tests/realtikvtest" - "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" ) @@ -41,7 +41,7 @@ func TestInTxnPSProtoPointGet(t *testing.T) { require.NoError(t, err) idForUpdate, _, _, err := tk.Session().PrepareStmt("select c1, c2 from t1 where c1 = ? for update") require.NoError(t, err) - params := []types.Datum{types.NewDatum(1)} + params := expression.Args2Expressions4Test(1) rs, err := tk.Session().ExecutePreparedStmt(ctx, id, params) require.NoError(t, err) tk.ResultSetToResult(rs, fmt.Sprintf("%v", rs)).Check(testkit.Rows("1 10")) From 38d2d971447c34ba686716a7da771c0d6bc9bcbb Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 11:44:43 +0800 Subject: [PATCH 11/21] fixup --- sessiontxn/txn_context_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sessiontxn/txn_context_test.go b/sessiontxn/txn_context_test.go index 74245fadd16f1..4793a1577c7d0 100644 --- a/sessiontxn/txn_context_test.go +++ b/sessiontxn/txn_context_test.go @@ -17,6 +17,7 @@ package sessiontxn_test import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "strings" "testing" "time" @@ -31,7 +32,6 @@ import ( "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/testfork" "github.com/pingcap/tidb/testkit/testsetup" - "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" "go.uber.org/goleak" ) @@ -907,18 +907,18 @@ func TestTSOCmdCountForPrepareExecute(t *testing.T) { for i := 1; i < 100; i++ { tk.MustExec("begin pessimistic") - stmt, err := tk.Session().ExecutePreparedStmt(ctx, sqlSelectID, []types.Datum{types.NewDatum(1)}) + stmt, err := tk.Session().ExecutePreparedStmt(ctx, sqlSelectID, expression.Args2Expressions4Test(1)) require.NoError(t, err) require.NoError(t, stmt.Close()) - stmt, err = tk.Session().ExecutePreparedStmt(ctx, sqlUpdateID, []types.Datum{types.NewDatum(1)}) + stmt, err = tk.Session().ExecutePreparedStmt(ctx, sqlUpdateID, expression.Args2Expressions4Test(1)) require.NoError(t, err) require.Nil(t, stmt) val := i * 10 - stmt, err = tk.Session().ExecutePreparedStmt(ctx, sqlInsertID1, []types.Datum{types.NewDatum(val), types.NewDatum(val)}) + stmt, err = tk.Session().ExecutePreparedStmt(ctx, sqlInsertID1, expression.Args2Expressions4Test(val, val)) require.NoError(t, err) require.Nil(t, stmt) - stmt, err = tk.Session().ExecutePreparedStmt(ctx, sqlInsertID2, []types.Datum{types.NewDatum(val), types.NewDatum(val)}) + stmt, err = tk.Session().ExecutePreparedStmt(ctx, sqlInsertID2, expression.Args2Expressions4Test(val, val)) require.NoError(t, err) require.Nil(t, stmt) tk.MustExec("commit") From 271c0166718f3d931c5e848023a8c1ebcf035f03 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 13:51:46 +0800 Subject: [PATCH 12/21] fix ci --- sessionctx/sessionstates/session_states_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sessionctx/sessionstates/session_states_test.go b/sessionctx/sessionstates/session_states_test.go index 0b01bb57481af..aad78a39924c3 100644 --- a/sessionctx/sessionstates/session_states_test.go +++ b/sessionctx/sessionstates/session_states_test.go @@ -18,7 +18,6 @@ import ( "context" "encoding/binary" "fmt" - "github.com/pingcap/tidb/expression" "strconv" "strings" "testing" @@ -27,6 +26,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/server" From 4478f410166ab061c3f11cca3ff34b087cd4c9a5 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 14:10:10 +0800 Subject: [PATCH 13/21] fix ci --- server/conn_stmt_test.go | 39 ++++++++++--------- sessiontxn/isolation/readcommitted_test.go | 2 +- sessiontxn/txn_context_test.go | 2 +- .../pessimistictest/pessimistic_test.go | 2 +- tests/realtikvtest/txntest/txn_test.go | 2 +- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/server/conn_stmt_test.go b/server/conn_stmt_test.go index a4ff4c2ee7070..9ff62bfbb2d20 100644 --- a/server/conn_stmt_test.go +++ b/server/conn_stmt_test.go @@ -15,6 +15,7 @@ package server import ( + "github.com/pingcap/tidb/expression" "testing" "github.com/pingcap/tidb/parser/mysql" @@ -26,7 +27,7 @@ import ( func TestParseExecArgs(t *testing.T) { type args struct { - args []types.Datum + args []expression.Expression boundParams [][]byte nullBitmap []byte paramTypes []byte @@ -40,7 +41,7 @@ func TestParseExecArgs(t *testing.T) { // Tests for int overflow { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{1, 0}, @@ -51,7 +52,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{2, 0}, @@ -62,7 +63,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{3, 0}, @@ -74,7 +75,7 @@ func TestParseExecArgs(t *testing.T) { // Tests for date/datetime/timestamp { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{12, 0}, @@ -85,7 +86,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{10, 0}, @@ -96,7 +97,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{7, 0}, @@ -107,7 +108,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{7, 0}, @@ -118,7 +119,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{7, 0}, @@ -130,7 +131,7 @@ func TestParseExecArgs(t *testing.T) { // Tests for time { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{11, 0}, @@ -141,7 +142,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{11, 0}, @@ -152,7 +153,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{11, 0}, @@ -164,7 +165,7 @@ func TestParseExecArgs(t *testing.T) { // For error test { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{7, 0}, @@ -175,7 +176,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{11, 0}, @@ -186,7 +187,7 @@ func TestParseExecArgs(t *testing.T) { }, { args{ - make([]types.Datum, 1), + expression.Args2Expressions4Test(1), [][]byte{nil}, []byte{0x0}, []byte{11, 0}, @@ -199,12 +200,12 @@ func TestParseExecArgs(t *testing.T) { for _, tt := range tests { err := parseExecArgs(&stmtctx.StatementContext{}, tt.args.args, tt.args.boundParams, tt.args.nullBitmap, tt.args.paramTypes, tt.args.paramValues, nil) require.Truef(t, terror.ErrorEqual(err, tt.err), "err %v", err) - require.Equal(t, tt.expect, tt.args.args[0].GetValue()) + require.Equal(t, tt.expect, tt.args.args[0].(*expression.Constant).Value.GetValue()) } } func TestParseExecArgsAndEncode(t *testing.T) { - dt := make([]types.Datum, 1) + dt := expression.Args2Expressions4Test(1) err := parseExecArgs(&stmtctx.StatementContext{}, dt, [][]byte{nil}, @@ -213,7 +214,7 @@ func TestParseExecArgsAndEncode(t *testing.T) { []byte{4, 178, 226, 202, 212}, newInputDecoder("gbk")) require.NoError(t, err) - require.Equal(t, "测试", dt[0].GetValue()) + require.Equal(t, "测试", dt[0].(*expression.Constant).Value.GetValue()) err = parseExecArgs(&stmtctx.StatementContext{}, dt, @@ -223,7 +224,7 @@ func TestParseExecArgsAndEncode(t *testing.T) { []byte{}, newInputDecoder("gbk")) require.NoError(t, err) - require.Equal(t, "测试", dt[0].GetString()) + require.Equal(t, "测试", dt[0].(*expression.Constant).Value.GetValue()) } func TestParseStmtFetchCmd(t *testing.T) { diff --git a/sessiontxn/isolation/readcommitted_test.go b/sessiontxn/isolation/readcommitted_test.go index 30c82091a07e6..537672819a123 100644 --- a/sessiontxn/isolation/readcommitted_test.go +++ b/sessiontxn/isolation/readcommitted_test.go @@ -17,7 +17,6 @@ package isolation_test import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "testing" "time" @@ -26,6 +25,7 @@ import ( "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser" diff --git a/sessiontxn/txn_context_test.go b/sessiontxn/txn_context_test.go index 4793a1577c7d0..022563b36c046 100644 --- a/sessiontxn/txn_context_test.go +++ b/sessiontxn/txn_context_test.go @@ -17,13 +17,13 @@ package sessiontxn_test import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "strings" "testing" "time" "github.com/pingcap/failpoint" "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/planner/core" diff --git a/tests/realtikvtest/pessimistictest/pessimistic_test.go b/tests/realtikvtest/pessimistictest/pessimistic_test.go index 324ad4de854d4..6368a3e0f5250 100644 --- a/tests/realtikvtest/pessimistictest/pessimistic_test.go +++ b/tests/realtikvtest/pessimistictest/pessimistic_test.go @@ -17,7 +17,6 @@ package pessimistictest import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "strconv" "strings" "sync" @@ -29,6 +28,7 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/auth" diff --git a/tests/realtikvtest/txntest/txn_test.go b/tests/realtikvtest/txntest/txn_test.go index 7020587f02d66..e282f3d84fada 100644 --- a/tests/realtikvtest/txntest/txn_test.go +++ b/tests/realtikvtest/txntest/txn_test.go @@ -17,9 +17,9 @@ package txntest import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "testing" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/tests/realtikvtest" From 32cb86f76695f9c6da41febc205a61e954ceed61 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 14:18:55 +0800 Subject: [PATCH 14/21] fix ci --- server/conn_stmt_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/conn_stmt_test.go b/server/conn_stmt_test.go index 9ff62bfbb2d20..291cfc4bf01d4 100644 --- a/server/conn_stmt_test.go +++ b/server/conn_stmt_test.go @@ -15,9 +15,9 @@ package server import ( - "github.com/pingcap/tidb/expression" "testing" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx/stmtctx" From c4f486b1ae3bd1fb64b09c9c0734380804a38786 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 14:33:30 +0800 Subject: [PATCH 15/21] fix ci --- server/conn_stmt_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/conn_stmt_test.go b/server/conn_stmt_test.go index 291cfc4bf01d4..886dd0207611e 100644 --- a/server/conn_stmt_test.go +++ b/server/conn_stmt_test.go @@ -200,7 +200,9 @@ func TestParseExecArgs(t *testing.T) { for _, tt := range tests { err := parseExecArgs(&stmtctx.StatementContext{}, tt.args.args, tt.args.boundParams, tt.args.nullBitmap, tt.args.paramTypes, tt.args.paramValues, nil) require.Truef(t, terror.ErrorEqual(err, tt.err), "err %v", err) - require.Equal(t, tt.expect, tt.args.args[0].(*expression.Constant).Value.GetValue()) + if err == nil { + require.Equal(t, tt.expect, tt.args.args[0].(*expression.Constant).Value.GetValue()) + } } } From 8fecb6876ef3a7a565005da103401562f407acf3 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 14:34:11 +0800 Subject: [PATCH 16/21] fix ci --- server/conn_stmt_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/conn_stmt_test.go b/server/conn_stmt_test.go index 886dd0207611e..1b8ea55e61c35 100644 --- a/server/conn_stmt_test.go +++ b/server/conn_stmt_test.go @@ -226,7 +226,7 @@ func TestParseExecArgsAndEncode(t *testing.T) { []byte{}, newInputDecoder("gbk")) require.NoError(t, err) - require.Equal(t, "测试", dt[0].(*expression.Constant).Value.GetValue()) + require.Equal(t, "测试", dt[0].(*expression.Constant).Value.GetString()) } func TestParseStmtFetchCmd(t *testing.T) { From 6577ca6337756a910d63e922b5fea54dc2ff87c7 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 14:47:44 +0800 Subject: [PATCH 17/21] fix ci --- session/main_test.go | 6 ++---- session/session_test/session_test.go | 14 +++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/session/main_test.go b/session/main_test.go index 06db872864bb4..f4238f078e17e 100644 --- a/session/main_test.go +++ b/session/main_test.go @@ -18,6 +18,7 @@ import ( "context" "flag" "fmt" + "github.com/pingcap/tidb/expression" "testing" "time" @@ -116,10 +117,7 @@ func exec(se Session, sql string, args ...interface{}) (sqlexec.RecordSet, error if err != nil { return nil, err } - params := make([]types.Datum, len(args)) - for i := 0; i < len(params); i++ { - params[i] = types.NewDatum(args[i]) - } + params := expression.Args2Expressions4Test(args...) rs, err := se.ExecutePreparedStmt(ctx, stmtID, params) if err != nil { return nil, err diff --git a/session/session_test/session_test.go b/session/session_test/session_test.go index 7105497341467..d6f44cd5a0ac6 100644 --- a/session/session_test/session_test.go +++ b/session/session_test/session_test.go @@ -17,6 +17,7 @@ package session_test import ( "context" "fmt" + "github.com/pingcap/tidb/expression" "net" "sort" "strconv" @@ -2629,7 +2630,7 @@ func TestPrepare(t *testing.T) { require.Equal(t, uint32(1), id) require.Equal(t, 1, ps) tk.MustExec(`set @a=1`) - rs, err := tk.Session().ExecutePreparedStmt(ctx, id, []types.Datum{types.NewDatum("1")}) + rs, err := tk.Session().ExecutePreparedStmt(ctx, id, expression.Args2Expressions4Test("1")) require.NoError(t, err) require.NoError(t, rs.Close()) err = tk.Session().DropPreparedStmt(id) @@ -2651,10 +2652,10 @@ func TestPrepare(t *testing.T) { tk.MustExec("insert multiexec values (1, 1), (2, 2)") id, _, _, err = tk.Session().PrepareStmt("select a from multiexec where b = ? order by b") require.NoError(t, err) - rs, err = tk.Session().ExecutePreparedStmt(ctx, id, []types.Datum{types.NewDatum(1)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, id, expression.Args2Expressions4Test(1)) require.NoError(t, err) require.NoError(t, rs.Close()) - rs, err = tk.Session().ExecutePreparedStmt(ctx, id, []types.Datum{types.NewDatum(2)}) + rs, err = tk.Session().ExecutePreparedStmt(ctx, id, expression.Args2Expressions4Test(2)) require.NoError(t, err) require.NoError(t, rs.Close()) } @@ -3393,8 +3394,7 @@ func TestQueryString(t *testing.T) { tk.MustExec("show create table t") id, _, _, err := tk.Session().PrepareStmt("CREATE TABLE t2(id bigint PRIMARY KEY, age int)") require.NoError(t, err) - var params []types.Datum - _, err = tk.Session().ExecutePreparedStmt(context.Background(), id, params) + _, err = tk.Session().ExecutePreparedStmt(context.Background(), id, expression.Args2Expressions4Test()) require.NoError(t, err) qs := tk.Session().Value(sessionctx.QueryString) require.Equal(t, "CREATE TABLE t2(id bigint PRIMARY KEY, age int)", qs.(string)) @@ -4038,12 +4038,12 @@ func TestBinaryReadOnly(t *testing.T) { require.NoError(t, err) tk.MustExec("set autocommit = 0") tk.MustExec("set tidb_disable_txn_auto_retry = 0") - _, err = tk.Session().ExecutePreparedStmt(context.Background(), id, []types.Datum{types.NewDatum(1)}) + _, err = tk.Session().ExecutePreparedStmt(context.Background(), id, expression.Args2Expressions4Test(1)) require.NoError(t, err) require.Equal(t, 0, session.GetHistory(tk.Session()).Count()) tk.MustExec("insert into t values (1)") require.Equal(t, 1, session.GetHistory(tk.Session()).Count()) - _, err = tk.Session().ExecutePreparedStmt(context.Background(), id2, []types.Datum{types.NewDatum(2)}) + _, err = tk.Session().ExecutePreparedStmt(context.Background(), id2, expression.Args2Expressions4Test(2)) require.NoError(t, err) require.Equal(t, 2, session.GetHistory(tk.Session()).Count()) tk.MustExec("commit") From 9d55ec48406ec39f84624ad163dacccb58047d15 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 15:02:15 +0800 Subject: [PATCH 18/21] fix ci --- planner/core/prepare_test.go | 2 +- session/main_test.go | 2 +- session/session_test/session_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index 35799f7de56c9..dc95884aa6870 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -17,7 +17,6 @@ package core_test import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "math" "math/rand" "strconv" @@ -26,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" diff --git a/session/main_test.go b/session/main_test.go index f4238f078e17e..a54a3378a4d8a 100644 --- a/session/main_test.go +++ b/session/main_test.go @@ -18,12 +18,12 @@ import ( "context" "flag" "fmt" - "github.com/pingcap/tidb/expression" "testing" "time" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/testkit/testdata" diff --git a/session/session_test/session_test.go b/session/session_test/session_test.go index d6f44cd5a0ac6..4d8307d49ab95 100644 --- a/session/session_test/session_test.go +++ b/session/session_test/session_test.go @@ -17,7 +17,6 @@ package session_test import ( "context" "fmt" - "github.com/pingcap/tidb/expression" "net" "sort" "strconv" @@ -31,6 +30,7 @@ import ( "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/auth" From ec26fda0e6e28b1cd2c930f732f4dddb9a717abd Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 15:40:15 +0800 Subject: [PATCH 19/21] fix ci --- expression/expression.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/expression/expression.go b/expression/expression.go index 0c78f16ebe7ad..81d071287ad2a 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -1441,18 +1441,24 @@ 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: - exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeNull)} + ft = types.NewFieldType(mysql.TypeNull) case types.KindInt64: - exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeLong)} + ft = types.NewFieldType(mysql.TypeLong) + case types.KindUint64: + ft = types.NewFieldType(mysql.TypeLong) + ft.AddFlag(mysql.UnsignedFlag) case types.KindFloat64: - exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeDouble)} + ft = types.NewFieldType(mysql.TypeDouble) case types.KindString: - exprs[i] = &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeVarString)} + ft = types.NewFieldType(mysql.TypeVarString) default: exprs[i] = nil + continue } + exprs[i] = &Constant{Value: d, RetType: ft} } return exprs } From 34b48eed9b5656c2ac981a1c956b82ca254a5729 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Tue, 2 Aug 2022 15:44:40 +0800 Subject: [PATCH 20/21] fix ci --- executor/seqtest/prepared_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go index 2553ab10c4f01..572c23fae43d4 100644 --- a/executor/seqtest/prepared_test.go +++ b/executor/seqtest/prepared_test.go @@ -910,7 +910,7 @@ func TestPreparedIssue17419(t *testing.T) { tk1.Session().SetSessionManager(sm) dom.ExpensiveQueryHandle().SetSessionManager(sm) - rs, err := tk1.Session().ExecutePreparedStmt(ctx, stmtID, expression.Args2Expressions4Test(nil)) + 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) From 71c029c862f133795253ff17d0eb8f6f0adad3f9 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 3 Aug 2022 14:37:39 +0800 Subject: [PATCH 21/21] fix ci --- server/conn_stmt.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/server/conn_stmt.go b/server/conn_stmt.go index 20c126132921d..e1b7ff416b2c3 100644 --- a/server/conn_stmt.go +++ b/server/conn_stmt.go @@ -333,15 +333,12 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, } args := make([]types.Datum, len(params)) - ftypes := make([]*types.FieldType, len(params)) for i := 0; i < len(args); i++ { // if params had received via ComStmtSendLongData, use them directly. // ref https://dev.mysql.com/doc/internals/en/com-stmt-send-long-data.html // see clientConn#handleStmtSendLongData if boundParams[i] != nil { args[i] = types.NewBytesDatum(enc.decodeInput(boundParams[i])) - ftypes[i] = types.NewFieldType(mysql.TypeBit) - ftypes[i].AddFlag(mysql.BinaryFlag) continue } @@ -353,7 +350,6 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, var nilDatum types.Datum nilDatum.SetNull() args[i] = nilDatum - ftypes[i] = types.NewFieldType(mysql.TypeNull) continue } @@ -363,7 +359,6 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, tp := paramTypes[i<<1] isUnsigned := (paramTypes[(i<<1)+1] & 0x80) > 0 - ftypes[i] = types.NewFieldType(tp) switch tp { case mysql.TypeNull: @@ -380,7 +375,6 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, if isUnsigned { args[i] = types.NewUintDatum(uint64(paramValues[pos])) - ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(int8(paramValues[pos]))) } @@ -396,7 +390,6 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, valU16 := binary.LittleEndian.Uint16(paramValues[pos : pos+2]) if isUnsigned { args[i] = types.NewUintDatum(uint64(valU16)) - ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(int16(valU16))) } @@ -411,7 +404,6 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, valU32 := binary.LittleEndian.Uint32(paramValues[pos : pos+4]) if isUnsigned { args[i] = types.NewUintDatum(uint64(valU32)) - ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(int32(valU32))) } @@ -426,7 +418,6 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, valU64 := binary.LittleEndian.Uint64(paramValues[pos : pos+8]) if isUnsigned { args[i] = types.NewUintDatum(valU64) - ftypes[i].AddFlag(mysql.UnsignedFlag) } else { args[i] = types.NewIntDatum(int64(valU64)) } @@ -580,9 +571,10 @@ func parseExecArgs(sc *stmtctx.StatementContext, params []expression.Expression, } for i := range params { - params[i] = &expression.Constant{Value: args[i], RetType: ftypes[i]} + ft := new(types.FieldType) + types.DefaultParamTypeForValue(args[i].GetValue(), ft) + params[i] = &expression.Constant{Value: args[i], RetType: ft} } - return }