Skip to content

Commit

Permalink
executor: fix index join error when join key is ENUM or SET (#19235) (#…
Browse files Browse the repository at this point in the history
…19415)

Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
ti-srebot authored Aug 25, 2020
1 parent 7d6fd41 commit 3fe0255
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 10 deletions.
3 changes: 2 additions & 1 deletion executor/index_lookup_hash_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
9 changes: 6 additions & 3 deletions executor/index_lookup_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
39 changes: 39 additions & 0 deletions executor/index_lookup_join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package executor_test

import (
"context"
"fmt"

. "github.com/pingcap/check"
"github.com/pingcap/tidb/util/testkit"
Expand Down Expand Up @@ -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)
}
}
}
4 changes: 4 additions & 0 deletions executor/index_lookup_merge_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 3 additions & 6 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down

0 comments on commit 3fe0255

Please sign in to comment.