From 9f7c4c01e1dca9dc38d477808c886a50a296632d Mon Sep 17 00:00:00 2001 From: Yiding Cui Date: Tue, 21 Jul 2020 15:38:50 +0800 Subject: [PATCH] cherry pick #18565 to release-3.0 Signed-off-by: ti-srebot --- executor/join_test.go | 147 ++++++++++++++++++++++++++++++++++ planner/core/logical_plans.go | 25 ++++++ 2 files changed, 172 insertions(+) diff --git a/executor/join_test.go b/executor/join_test.go index 1b34c8c868ba0..204a23b1de39b 100644 --- a/executor/join_test.go +++ b/executor/join_test.go @@ -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( + " ", + " 2", + " 2", + " 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", + "0 0 ", + "0 0 ", + "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>>>>>> 847a3b7... planner: don't put the handle column twice into the index column (#18565) diff --git a/planner/core/logical_plans.go b/planner/core/logical_plans.go index 29b2a53dd347e..67ec5f571eab1 100644 --- a/planner/core/logical_plans.go +++ b/planner/core/logical_plans.go @@ -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 }