From 23692ca1c815ef05209cf31ec23186edd9322b72 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Mon, 24 Aug 2020 20:50:51 +0800 Subject: [PATCH] cherry pick #19235 to release-4.0 Signed-off-by: ti-srebot --- executor/index_lookup_hash_join.go | 3 ++- executor/index_lookup_join.go | 9 ++++--- executor/index_lookup_join_test.go | 39 +++++++++++++++++++++++++++++ executor/index_lookup_merge_join.go | 4 +++ types/datum.go | 9 +++---- 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/executor/index_lookup_hash_join.go b/executor/index_lookup_hash_join.go index 40310d54742a6..53a9a5697d425 100644 --- a/executor/index_lookup_hash_join.go +++ b/executor/index_lookup_hash_join.go @@ -591,6 +591,7 @@ func (iw *indexHashJoinInnerWorker) doJoinUnordered(ctx context.Context, task *i select { case resultCh <- joinResult: case <-ctx.Done(): + return ctx.Err() } joinResult, ok = iw.getNewJoinResult(ctx) if !ok { @@ -738,7 +739,7 @@ func (iw *indexHashJoinInnerWorker) doJoinInOrder(ctx context.Context, task *ind select { case resultCh <- joinResult: case <-ctx.Done(): - return nil + return ctx.Err() } joinResult, ok = iw.getNewJoinResult(ctx) if !ok { diff --git a/executor/index_lookup_join.go b/executor/index_lookup_join.go index be31b762482c4..0201d7149791f 100644 --- a/executor/index_lookup_join.go +++ b/executor/index_lookup_join.go @@ -293,7 +293,7 @@ func (e *IndexLookUpJoin) getFinishedTask(ctx context.Context) (*lookUpJoinTask, select { case task = <-e.resultCh: case <-ctx.Done(): - return nil, nil + return nil, ctx.Err() } if task == nil { return nil, nil @@ -305,7 +305,7 @@ func (e *IndexLookUpJoin) getFinishedTask(ctx context.Context) (*lookUpJoinTask, return nil, err } case <-ctx.Done(): - return nil, nil + return nil, ctx.Err() } e.task = task @@ -556,6 +556,9 @@ func (iw *innerWorker) constructDatumLookupKey(task *lookUpJoinTask, chkIdx, row if terror.ErrorEqual(err, types.ErrOverflow) { return nil, nil } + if terror.ErrorEqual(err, types.ErrTruncated) && (innerColType.Tp == mysql.TypeSet || innerColType.Tp == mysql.TypeEnum) { + return nil, nil + } return nil, err } cmp, err := outerValue.CompareDatum(sc, &innerValue) @@ -619,7 +622,7 @@ func (iw *innerWorker) fetchInnerResults(ctx context.Context, task *lookUpJoinTa for { select { case <-ctx.Done(): - return nil + return ctx.Err() default: } err := Next(ctx, innerExec, iw.executorChk) diff --git a/executor/index_lookup_join_test.go b/executor/index_lookup_join_test.go index f67dfcdd8eb84..dffd3289f0ff1 100644 --- a/executor/index_lookup_join_test.go +++ b/executor/index_lookup_join_test.go @@ -15,6 +15,7 @@ package executor_test import ( "context" + "fmt" . "github.com/pingcap/check" "github.com/pingcap/tidb/util/testkit" @@ -211,3 +212,41 @@ func (s *testSuite5) TestIssue16887(c *C) { rows = tk.MustQuery("show warnings").Rows() c.Assert(len(rows) > 0, Equals, true) } + +func (s *testSuite5) TestIndexJoinEnumSetIssue19233(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t;") + tk.MustExec("drop table if exists i;") + tk.MustExec("drop table if exists p1;") + tk.MustExec("drop table if exists p2;") + tk.MustExec(`CREATE TABLE p1 (type enum('HOST_PORT') NOT NULL, UNIQUE KEY (type)) ;`) + tk.MustExec(`CREATE TABLE p2 (type set('HOST_PORT') NOT NULL, UNIQUE KEY (type)) ;`) + tk.MustExec(`CREATE TABLE i (objectType varchar(64) NOT NULL);`) + tk.MustExec(`insert into i values ('SWITCH');`) + tk.MustExec(`create table t like i;`) + tk.MustExec(`insert into t values ('HOST_PORT');`) + tk.MustExec(`insert into t select * from t;`) + tk.MustExec(`insert into t select * from t;`) + tk.MustExec(`insert into t select * from t;`) + tk.MustExec(`insert into t select * from t;`) + tk.MustExec(`insert into t select * from t;`) + tk.MustExec(`insert into t select * from t;`) + + tk.MustExec(`insert into i select * from t;`) + + tk.MustExec(`insert into p1 values('HOST_PORT');`) + tk.MustExec(`insert into p2 values('HOST_PORT');`) + for _, table := range []string{"p1", "p2"} { + for _, hint := range []string{"INL_HASH_JOIN", "INL_MERGE_JOIN", "INL_JOIN"} { + sql := fmt.Sprintf(`select /*+ %s(%s) */ * from i, %s where i.objectType = %s.type;`, hint, table, table, table) + rows := tk.MustQuery(sql).Rows() + c.Assert(len(rows), Equals, 64) + for i := 0; i < len(rows); i++ { + c.Assert(fmt.Sprint(rows[i][0]), Equals, "HOST_PORT") + } + rows = tk.MustQuery("show warnings").Rows() + c.Assert(len(rows), Equals, 0) + } + } +} diff --git a/executor/index_lookup_merge_join.go b/executor/index_lookup_merge_join.go index 044a4216cdb43..d162b00cb24df 100644 --- a/executor/index_lookup_merge_join.go +++ b/executor/index_lookup_merge_join.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/expression" plannercore "github.com/pingcap/tidb/planner/core" @@ -670,6 +671,9 @@ func (imw *innerMergeWorker) constructDatumLookupKey(task *lookUpMergeJoinTask, if terror.ErrorEqual(err, types.ErrOverflow) { return nil, nil } + if terror.ErrorEqual(err, types.ErrTruncated) && (innerColType.Tp == mysql.TypeSet || innerColType.Tp == mysql.TypeEnum) { + return nil, nil + } return nil, err } cmp, err := outerValue.CompareDatum(sc, &innerValue) diff --git a/types/datum.go b/types/datum.go index c9575b3730866..1ac56c9fff255 100644 --- a/types/datum.go +++ b/types/datum.go @@ -31,8 +31,6 @@ import ( "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/hack" - "github.com/pingcap/tidb/util/logutil" - "go.uber.org/zap" ) // Kind constants. @@ -1385,8 +1383,7 @@ func (d *Datum) convertToMysqlEnum(sc *stmtctx.StatementContext, target *FieldTy e, err = ParseEnumValue(target.Elems, uintDatum.GetUint64()) } if err != nil { - logutil.BgLogger().Error("convert to MySQL enum failed", zap.Error(err)) - err = errors.Trace(ErrTruncated) + err = errors.Wrap(ErrTruncated, "convert to MySQL enum failed: "+err.Error()) } ret.SetMysqlEnum(e, target.Collate) return ret, err @@ -1411,10 +1408,10 @@ func (d *Datum) convertToMysqlSet(sc *stmtctx.StatementContext, target *FieldTyp } if err != nil { - return invalidConv(d, target.Tp) + err = errors.Wrap(ErrTruncated, "convert to MySQL set failed: "+err.Error()) } ret.SetMysqlSet(s, target.Collate) - return ret, nil + return ret, err } func (d *Datum) convertToMysqlJSON(sc *stmtctx.StatementContext, target *FieldType) (ret Datum, err error) {