From a1a04e670a42c174a90806ebf2af1384dceeaae0 Mon Sep 17 00:00:00 2001 From: lysu Date: Wed, 23 Dec 2020 17:19:29 +0800 Subject: [PATCH 1/2] cherry pick #21904 to release-4.0 Signed-off-by: ti-srebot --- executor/batch_checker.go | 10 +++++++++- executor/executor.go | 1 + executor/insert.go | 6 ++++++ executor/insert_common.go | 3 +++ executor/write_test.go | 4 ++++ sessionctx/stmtctx/stmtctx.go | 1 + 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/executor/batch_checker.go b/executor/batch_checker.go index 3fb697e68af3a..f8eedf0352f39 100644 --- a/executor/batch_checker.go +++ b/executor/batch_checker.go @@ -18,6 +18,8 @@ import ( "strconv" "github.com/pingcap/parser/model" + "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/sessionctx" @@ -38,7 +40,8 @@ type toBeCheckedRow struct { handleKey *keyValueWithDupInfo uniqueKeys []*keyValueWithDupInfo // t is the table or partition this row belongs to. - t table.Table + t table.Table + ignored bool } // encodeNewRow encodes a new row to value. @@ -96,6 +99,11 @@ func getKeysNeedCheckOneRow(ctx sessionctx.Context, t table.Table, row []types.D if p, ok := t.(table.PartitionedTable); ok { t, err = p.GetPartitionByRow(ctx, row) if err != nil { + if terr, ok := errors.Cause(err).(*terror.Error); ctx.GetSessionVars().StmtCtx.IgnoreNoPartition && ok && terr.Code() == errno.ErrNoPartitionForGivenValue { + ctx.GetSessionVars().StmtCtx.AppendWarning(err) + result = append(result, toBeCheckedRow{ignored: true}) + return result, nil + } return nil, err } } diff --git a/executor/executor.go b/executor/executor.go index 88c8610b1ac08..d215c829c832d 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -1691,6 +1691,7 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { // but should not make DupKeyAsWarning or BadNullAsWarning, sc.DupKeyAsWarning = stmt.IgnoreErr sc.BadNullAsWarning = stmt.IgnoreErr + sc.IgnoreNoPartition = stmt.IgnoreErr sc.TruncateAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.DividedByZeroAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.AllowInvalidDate = vars.SQLMode.HasAllowInvalidDatesMode() diff --git a/executor/insert.go b/executor/insert.go index dbba7e0e4d144..e853b3e2485f0 100644 --- a/executor/insert.go +++ b/executor/insert.go @@ -113,6 +113,9 @@ func prefetchUniqueIndices(ctx context.Context, txn kv.Transaction, rows []toBeC nKeys := 0 for _, r := range rows { + if r.ignored { + continue + } if r.handleKey != nil { nKeys++ } @@ -120,6 +123,9 @@ func prefetchUniqueIndices(ctx context.Context, txn kv.Transaction, rows []toBeC } batchKeys := make([]kv.Key, 0, nKeys) for _, r := range rows { + if r.ignored { + continue + } if r.handleKey != nil { batchKeys = append(batchKeys, r.handleKey.newKey) } diff --git a/executor/insert_common.go b/executor/insert_common.go index 1ac9d7b7f2726..6c2f27700ed10 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -1028,6 +1028,9 @@ func (e *InsertValues) batchCheckAndInsert(ctx context.Context, rows [][]types.D // append warnings and get no duplicated error rows for i, r := range toBeCheckedRows { + if r.ignored { + continue + } skip := false if r.handleKey != nil { _, err := txn.Get(ctx, r.handleKey.newKey) diff --git a/executor/write_test.go b/executor/write_test.go index f6570d51dba6b..a08ca5e04bfea 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -569,6 +569,10 @@ commit;` tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'i' cannot be null")) testSQL = `select * from badnull` tk.MustQuery(testSQL).Check(testkit.Rows("0")) + + tk.MustExec("create table tp (id int) partition by range (id) (partition p0 values less than (1), partition p1 values less than(2))") + tk.MustExec("insert ignore into tp values (1), (3)") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3")) } func (s *testSuite8) TestInsertOnDup(c *C) { diff --git a/sessionctx/stmtctx/stmtctx.go b/sessionctx/stmtctx/stmtctx.go index 4a20741c6abe6..fbba707a9cc77 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -80,6 +80,7 @@ type StatementContext struct { InNullRejectCheck bool AllowInvalidDate bool OptimDependOnMutableConst bool + IgnoreNoPartition bool // mu struct holds variables that change during execution. mu struct { From 9c1d1e99e4eb13824a94e65bc36d9d97a1efbb13 Mon Sep 17 00:00:00 2001 From: lysu Date: Tue, 29 Dec 2020 10:31:54 +0800 Subject: [PATCH 2/2] fix compile error Signed-off-by: lysu --- executor/batch_checker.go | 1 + 1 file changed, 1 insertion(+) diff --git a/executor/batch_checker.go b/executor/batch_checker.go index f8eedf0352f39..dd550933a8f7d 100644 --- a/executor/batch_checker.go +++ b/executor/batch_checker.go @@ -17,6 +17,7 @@ import ( "context" "strconv" + "github.com/pingcap/errors" "github.com/pingcap/parser/model" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/errno"