From bc516e1de14acecc814809ee5400b5fe5dd379c3 Mon Sep 17 00:00:00 2001 From: yibin Date: Fri, 26 Apr 2024 14:51:23 +0800 Subject: [PATCH] Fix issue 52902 by recongnizing anti semi and anti semi left outer join Signed-off-by: yibin --- pkg/executor/index_lookup_hash_join.go | 3 +-- .../test/jointest/hashjoin/BUILD.bazel | 2 +- .../test/jointest/hashjoin/hash_join_test.go | 25 +++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pkg/executor/index_lookup_hash_join.go b/pkg/executor/index_lookup_hash_join.go index d443845624913..8dba9d3673215 100644 --- a/pkg/executor/index_lookup_hash_join.go +++ b/pkg/executor/index_lookup_hash_join.go @@ -28,7 +28,6 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/pkg/executor/internal/exec" "github.com/pingcap/tidb/pkg/expression" - plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/types" "github.com/pingcap/tidb/pkg/util" "github.com/pingcap/tidb/pkg/util/channel" @@ -736,7 +735,7 @@ func (iw *indexHashJoinInnerWorker) getMatchedOuterRows(innerRow chunk.Row, task return nil, nil, nil } joinType := JoinerType(iw.joiner) - isSemiJoin := joinType == plannercore.SemiJoin || joinType == plannercore.LeftOuterSemiJoin + isSemiJoin := joinType.IsSemiJoin() for ; matchedOuterEntry != nil; matchedOuterEntry = matchedOuterEntry.next { ptr := matchedOuterEntry.ptr outerRow := task.outerResult.GetRow(ptr) diff --git a/pkg/executor/test/jointest/hashjoin/BUILD.bazel b/pkg/executor/test/jointest/hashjoin/BUILD.bazel index 944eeb60c8537..11f52cb3a8aae 100644 --- a/pkg/executor/test/jointest/hashjoin/BUILD.bazel +++ b/pkg/executor/test/jointest/hashjoin/BUILD.bazel @@ -9,7 +9,7 @@ go_test( ], flaky = True, race = "on", - shard_count = 10, + shard_count = 11, deps = [ "//pkg/config", "//pkg/meta/autoid", diff --git a/pkg/executor/test/jointest/hashjoin/hash_join_test.go b/pkg/executor/test/jointest/hashjoin/hash_join_test.go index c93b93748bb61..6de6676196eb4 100644 --- a/pkg/executor/test/jointest/hashjoin/hash_join_test.go +++ b/pkg/executor/test/jointest/hashjoin/hash_join_test.go @@ -169,6 +169,31 @@ func TestIndexNestedLoopHashJoin(t *testing.T) { tk.MustExec("drop table orders") } +func TestIssue52902(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + // index hash join with semi join + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/planner/core/MockOnlyEnableIndexHashJoin", "return(true)")) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/planner/core/MockOnlyEnableIndexHashJoin")) + }() + tk.MustExec("use test") + tk.MustExec("drop table if exists t0") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (x int, y int)") + tk.MustExec("create table t0 (a int, b int, key (`b`))") + tk.MustExec("insert into t1 values(103, 600)") + tk.MustExec("insert into t1 values(100, 200)") + tk.MustExec("insert into t0 values( 105, 400)") + tk.MustExec("insert into t0 values( 104, 300)") + tk.MustExec("insert into t0 values( 103, 300)") + tk.MustExec("insert into t0 values( 102, 200)") + tk.MustExec("insert into t0 values( 101, 200)") + tk.MustExec("insert into t0 values( 100, 200)") + tk.MustQuery("select * from t1 where 1 = 1 and case when t1.x < 1000 then 1 = 1 " + + "when t1.x < 2000 then not exists (select 1 from t0 where t0.b = t1.y) else 1 = 1 end").Check(testkit.Rows("100 200", "103 600")) +} + func TestHashJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store)