From bfeca0e3f00c891b23281b3246dead8fa07f1e30 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Tue, 20 Sep 2022 11:45:01 +0800 Subject: [PATCH] executor: HashJoinExec checks the buildError even if the probeSide is empty (#30471) (#30796) close pingcap/tidb#30289 --- executor/executor_test.go | 14 ++++++++++++++ executor/join.go | 13 ++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/executor/executor_test.go b/executor/executor_test.go index 8658668f3d994..58c6277d5be06 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -9120,6 +9120,20 @@ func (s *testSerialSuite) TestIssue28650(c *C) { } } +func (s *testSerialSuite) TestIssue30289(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + fpName := "github.com/pingcap/tidb/executor/issue30289" + c.Assert(failpoint.Enable(fpName, `return(true)`), IsNil) + defer func() { + c.Assert(failpoint.Disable(fpName), IsNil) + }() + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int)") + err := tk.QueryToErr("select /*+ hash_join(t1) */ * from t t1 join t t2 on t1.a=t2.a") + c.Assert(err.Error(), Matches, "issue30289 build return error") +} + // Test invoke Close without invoking Open before for each operators. func (s *testSerialSuite) TestUnreasonablyClose(c *C) { defer testleak.AfterTest(c)() diff --git a/executor/join.go b/executor/join.go index e75ff3203148e..b94debad28796 100644 --- a/executor/join.go +++ b/executor/join.go @@ -218,9 +218,13 @@ func (e *HashJoinExec) fetchProbeSideChunks(ctx context.Context) { return } if !hasWaitedForBuild { + failpoint.Inject("issue30289", func(val failpoint.Value) { + if val.(bool) { + probeSideResult.Reset() + } + }) if probeSideResult.NumRows() == 0 && !e.useOuterToBuild { e.finished.Store(true) - return } emptyBuild, buildErr := e.wait4BuildSide() if buildErr != nil { @@ -262,6 +266,13 @@ func (e *HashJoinExec) wait4BuildSide() (emptyBuild bool, err error) { func (e *HashJoinExec) fetchBuildSideRows(ctx context.Context, chkCh chan<- *chunk.Chunk, doneCh <-chan struct{}) { defer close(chkCh) var err error + failpoint.Inject("issue30289", func(val failpoint.Value) { + if val.(bool) { + err = errors.Errorf("issue30289 build return error") + e.buildFinished <- errors.Trace(err) + return + } + }) for { if e.finished.Load().(bool) { return