Skip to content

Commit

Permalink
cherry pick pingcap#18565 to release-3.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
winoros authored and ti-srebot committed Jul 21, 2020
1 parent 27b8693 commit 9f7c4c0
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 0 deletions.
147 changes: 147 additions & 0 deletions executor/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1458,3 +1458,150 @@ func (s *testSuite2) TestIssue14514(c *C) {
tk.MustExec("create table t (pk varchar(14) primary key, a varchar(12));")
tk.MustQuery("select * from (select t1.pk or '/' as c from t as t1 left join t as t2 on t1.a = t2.pk) as t where t.c = 1;").Check(testkit.Rows())
}
<<<<<<< HEAD
=======

func (s *testSuiteJoinSerial) TestOuterMatchStatusIssue14742(c *C) {
plannercore.ForceUseOuterBuild4Test = true
defer func() { plannercore.ForceUseOuterBuild4Test = false }()
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists testjoin;")
tk.MustExec("create table testjoin(a int);")
tk.Se.GetSessionVars().MaxChunkSize = 2

tk.MustExec("insert into testjoin values (NULL);")
tk.MustExec("insert into testjoin values (1);")
tk.MustExec("insert into testjoin values (2), (2), (2);")
tk.MustQuery("SELECT * FROM testjoin t1 RIGHT JOIN testjoin t2 ON t1.a > t2.a order by t1.a, t2.a;").Check(testkit.Rows(
"<nil> <nil>",
"<nil> 2",
"<nil> 2",
"<nil> 2",
"2 1",
"2 1",
"2 1",
))
}

func (s *testSuiteJoinSerial) TestInlineProjection4HashJoinIssue15316(c *C) {
// Two necessary factors to reproduce this issue:
// (1) taking HashLeftJoin, i.e., letting the probing tuple lay at the left side of joined tuples
// (2) the projection only contains a part of columns from the build side, i.e., pruning the same probe side
plannercore.ForcedHashLeftJoin4Test = true
defer func() { plannercore.ForcedHashLeftJoin4Test = false }()
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("create table S (a int not null, b int, c int);")
tk.MustExec("create table T (a int not null, b int, c int);")
tk.MustExec("insert into S values (0,1,2),(0,1,null),(0,1,2);")
tk.MustExec("insert into T values (0,10,2),(0,10,null),(1,10,2);")
tk.MustQuery("select T.a,T.a,T.c from S join T on T.a = S.a where S.b<T.b order by T.a,T.c;").Check(testkit.Rows(
"0 0 <nil>",
"0 0 <nil>",
"0 0 <nil>",
"0 0 2",
"0 0 2",
"0 0 2",
))
// NOTE: the HashLeftJoin should be kept
tk.MustQuery("explain select T.a,T.a,T.c from S join T on T.a = S.a where S.b<T.b order by T.a,T.c;").Check(testkit.Rows(
"Sort_8 12487.50 root test.t.a, test.t.c",
"└─Projection_10 12487.50 root test.t.a, test.t.a, test.t.c",
" └─HashJoin_11 12487.50 root inner join, equal:[eq(test.s.a, test.t.a)], other cond:lt(test.s.b, test.t.b)",
" ├─TableReader_17(Build) 9990.00 root data:Selection_16",
" │ └─Selection_16 9990.00 cop[tikv] not(isnull(test.t.b))",
" │ └─TableFullScan_15 10000.00 cop[tikv] table:T keep order:false, stats:pseudo",
" └─TableReader_14(Probe) 9990.00 root data:Selection_13",
" └─Selection_13 9990.00 cop[tikv] not(isnull(test.s.b))",
" └─TableFullScan_12 10000.00 cop[tikv] table:S keep order:false, stats:pseudo"))
}

func (s *testSuiteJoinSerial) TestIssue18070(c *C) {
config.GetGlobalConfig().OOMAction = config.OOMActionCancel
defer func() { config.GetGlobalConfig().OOMAction = config.OOMActionLog }()
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(a int, index(a))")
tk.MustExec("create table t2(a int, index(a))")
tk.MustExec("insert into t1 values(1),(2)")
tk.MustExec("insert into t2 values(1),(1),(2),(2)")
tk.MustExec("set @@tidb_mem_quota_query=1000")
err := tk.QueryToErr("select /*+ inl_hash_join(t1)*/ * from t1 join t2 on t1.a = t2.a;")
c.Assert(strings.Contains(err.Error(), "Out Of Memory Quota!"), IsTrue)

fpName := "github.com/pingcap/tidb/executor/mockIndexMergeJoinOOMPanic"
c.Assert(failpoint.Enable(fpName, `panic("ERROR 1105 (HY000): Out Of Memory Quota![conn_id=1]")`), IsNil)
defer func() {
c.Assert(failpoint.Disable(fpName), IsNil)
}()
err = tk.QueryToErr("select /*+ inl_merge_join(t1)*/ * from t1 join t2 on t1.a = t2.a;")
c.Assert(strings.Contains(err.Error(), "Out Of Memory Quota!"), IsTrue)
}

func (s *testSuiteJoin1) TestIssue18564(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(a int, b int, primary key(a), index idx(b,a));")
tk.MustExec("create table t2(a int, b int, primary key(a), index idx(b,a));")
tk.MustExec("insert into t1 values(1, 1)")
tk.MustExec("insert into t2 values(1, 1)")
tk.MustQuery("select /*+ INL_JOIN(t1) */ * from t1 FORCE INDEX (idx) join t2 on t1.b=t2.b and t1.a = t2.a").Check(testkit.Rows("1 1 1 1"))
}

func (s *testSuite9) TestIssue18572_1(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int, b int, index idx(b));")
tk.MustExec("insert into t1 values(1, 1);")
tk.MustExec("insert into t1 select * from t1;")

c.Assert(failpoint.Enable("github.com/pingcap/tidb/executor/testIndexHashJoinInnerWorkerErr", "return"), IsNil)
defer func() {
c.Assert(failpoint.Disable("github.com/pingcap/tidb/executor/testIndexHashJoinInnerWorkerErr"), IsNil)
}()

rs, err := tk.Exec("select /*+ inl_hash_join(t1) */ * from t1 right join t1 t2 on t1.b=t2.b;")
c.Assert(err, IsNil)
_, err = session.GetRows4Test(context.Background(), nil, rs)
c.Assert(strings.Contains(err.Error(), "mockIndexHashJoinInnerWorkerErr"), IsTrue)
}

func (s *testSuite9) TestIssue18572_2(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int, b int, index idx(b));")
tk.MustExec("insert into t1 values(1, 1);")
tk.MustExec("insert into t1 select * from t1;")

c.Assert(failpoint.Enable("github.com/pingcap/tidb/executor/testIndexHashJoinOuterWorkerErr", "return"), IsNil)
defer func() {
c.Assert(failpoint.Disable("github.com/pingcap/tidb/executor/testIndexHashJoinOuterWorkerErr"), IsNil)
}()

rs, err := tk.Exec("select /*+ inl_hash_join(t1) */ * from t1 right join t1 t2 on t1.b=t2.b;")
c.Assert(err, IsNil)
_, err = session.GetRows4Test(context.Background(), nil, rs)
c.Assert(strings.Contains(err.Error(), "mockIndexHashJoinOuterWorkerErr"), IsTrue)
}

func (s *testSuite9) TestIssue18572_3(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int, b int, index idx(b));")
tk.MustExec("insert into t1 values(1, 1);")
tk.MustExec("insert into t1 select * from t1;")

c.Assert(failpoint.Enable("github.com/pingcap/tidb/executor/testIndexHashJoinBuildErr", "return"), IsNil)
defer func() {
c.Assert(failpoint.Disable("github.com/pingcap/tidb/executor/testIndexHashJoinBuildErr"), IsNil)
}()

rs, err := tk.Exec("select /*+ inl_hash_join(t1) */ * from t1 right join t1 t2 on t1.b=t2.b;")
c.Assert(err, IsNil)
_, err = session.GetRows4Test(context.Background(), nil, rs)
c.Assert(strings.Contains(err.Error(), "mockIndexHashJoinBuildErr"), IsTrue)
}
>>>>>>> 847a3b7... planner: don't put the handle column twice into the index column (#18565)
25 changes: 25 additions & 0 deletions planner/core/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,37 @@ func (ds *DataSource) deriveTablePathStats(path *accessPath) (bool, error) {
// determine whether we remove other paths or not.
func (ds *DataSource) deriveIndexPathStats(path *accessPath) (bool, error) {
sc := ds.ctx.GetSessionVars().StmtCtx
<<<<<<< HEAD
path.ranges = ranger.FullRange()
path.countAfterAccess = float64(ds.statisticTable.Count)
path.idxCols, path.idxColLens = expression.IndexInfo2Cols(ds.schema.Columns, path.index)
eqOrInCount := 0
if len(path.idxCols) != 0 {
res, err := ranger.DetachCondAndBuildRangeForIndex(ds.ctx, ds.pushedDownConds, path.idxCols, path.idxColLens)
=======
path.Ranges = ranger.FullRange()
path.CountAfterAccess = float64(ds.statisticTable.Count)
path.IdxCols, path.IdxColLens = expression.IndexInfo2PrefixCols(ds.Columns, ds.schema.Columns, path.Index)
path.FullIdxCols, path.FullIdxColLens = expression.IndexInfo2Cols(ds.Columns, ds.schema.Columns, path.Index)
if !path.Index.Unique && !path.Index.Primary && len(path.Index.Columns) == len(path.IdxCols) {
handleCol := ds.getPKIsHandleCol()
if handleCol != nil && !mysql.HasUnsignedFlag(handleCol.RetType.Flag) {
alreadyHandle := false
for _, col := range path.IdxCols {
if col.ID == model.ExtraHandleID || col.Equal(nil, handleCol) {
alreadyHandle = true
}
}
// Don't add one column twice to the index. May cause unexpected errors.
if !alreadyHandle {
path.IdxCols = append(path.IdxCols, handleCol)
path.IdxColLens = append(path.IdxColLens, types.UnspecifiedLength)
}
}
}
if len(path.IdxCols) != 0 {
res, err := ranger.DetachCondAndBuildRangeForIndex(ds.ctx, conds, path.IdxCols, path.IdxColLens)
>>>>>>> 847a3b7... planner: don't put the handle column twice into the index column (#18565)
if err != nil {
return false, err
}
Expand Down

0 comments on commit 9f7c4c0

Please sign in to comment.