Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b79cb1e

Browse files
committed
Recent changes to allow hash join to exit early given empty input from
one child or the other had a problem: they did not leave the node in a state that ExecReScanHashJoin would understand. In particular it would tend to fail to reset the child plans when needed. Per report from Mario Weilguni.
1 parent d4fc4ac commit b79cb1e

File tree

1 file changed

+20
-30
lines changed

1 file changed

+20
-30
lines changed

src/backend/executor/nodeHashjoin.c

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.77 2005/11/22 18:17:10 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.78 2005/11/28 17:14:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -152,12 +152,7 @@ ExecHashJoin(HashJoinState *node)
152152
* outer join, we can quit without scanning the outer relation.
153153
*/
154154
if (hashtable->totalTuples == 0 && node->js.jointype != JOIN_LEFT)
155-
{
156-
ExecHashTableDestroy(hashtable);
157-
node->hj_HashTable = NULL;
158-
node->hj_FirstOuterTupleSlot = NULL;
159155
return NULL;
160-
}
161156

162157
/*
163158
* need to remember whether nbatch has increased since we began
@@ -487,7 +482,6 @@ ExecEndHashJoin(HashJoinState *node)
487482
{
488483
ExecHashTableDestroy(node->hj_HashTable);
489484
node->hj_HashTable = NULL;
490-
node->hj_FirstOuterTupleSlot = NULL;
491485
}
492486

493487
/*
@@ -803,38 +797,33 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
803797
void
804798
ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
805799
{
806-
/*
807-
* If we haven't yet built the hash table then we can just return; nothing
808-
* done yet, so nothing to undo.
809-
*/
810-
if (node->hj_HashTable == NULL)
811-
return;
812-
813800
/*
814801
* In a multi-batch join, we currently have to do rescans the hard way,
815802
* primarily because batch temp files may have already been released. But
816803
* if it's a single-batch join, and there is no parameter change for the
817804
* inner subnode, then we can just re-use the existing hash table without
818805
* rebuilding it.
819806
*/
820-
if (node->hj_HashTable->nbatch == 1 &&
821-
((PlanState *) node)->righttree->chgParam == NULL)
822-
{
823-
/* okay to reuse the hash table; needn't rescan inner, either */
824-
}
825-
else
807+
if (node->hj_HashTable != NULL)
826808
{
827-
/* must destroy and rebuild hash table */
828-
ExecHashTableDestroy(node->hj_HashTable);
829-
node->hj_HashTable = NULL;
830-
node->hj_FirstOuterTupleSlot = NULL;
809+
if (node->hj_HashTable->nbatch == 1 &&
810+
((PlanState *) node)->righttree->chgParam == NULL)
811+
{
812+
/* okay to reuse the hash table; needn't rescan inner, either */
813+
}
814+
else
815+
{
816+
/* must destroy and rebuild hash table */
817+
ExecHashTableDestroy(node->hj_HashTable);
818+
node->hj_HashTable = NULL;
831819

832-
/*
833-
* if chgParam of subnode is not null then plan will be re-scanned by
834-
* first ExecProcNode.
835-
*/
836-
if (((PlanState *) node)->righttree->chgParam == NULL)
837-
ExecReScan(((PlanState *) node)->righttree, exprCtxt);
820+
/*
821+
* if chgParam of subnode is not null then plan will be re-scanned
822+
* by first ExecProcNode.
823+
*/
824+
if (((PlanState *) node)->righttree->chgParam == NULL)
825+
ExecReScan(((PlanState *) node)->righttree, exprCtxt);
826+
}
838827
}
839828

840829
/* Always reset intra-tuple state */
@@ -846,6 +835,7 @@ ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
846835
node->js.ps.ps_TupFromTlist = false;
847836
node->hj_NeedNewOuter = true;
848837
node->hj_MatchedOuter = false;
838+
node->hj_FirstOuterTupleSlot = NULL;
849839

850840
/*
851841
* if chgParam of subnode is not null then plan will be re-scanned by

0 commit comments

Comments
 (0)