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.
This commit is contained in:
Tom Lane 2005-11-28 17:14:23 +00:00
parent d4fc4ac4c7
commit b79cb1eea1

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.77 2005/11/22 18:17:10 momjian Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.78 2005/11/28 17:14:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -152,12 +152,7 @@ ExecHashJoin(HashJoinState *node)
* outer join, we can quit without scanning the outer relation.
*/
if (hashtable->totalTuples == 0 && node->js.jointype != JOIN_LEFT)
{
ExecHashTableDestroy(hashtable);
node->hj_HashTable = NULL;
node->hj_FirstOuterTupleSlot = NULL;
return NULL;
}
/*
* need to remember whether nbatch has increased since we began
@ -487,7 +482,6 @@ ExecEndHashJoin(HashJoinState *node)
{
ExecHashTableDestroy(node->hj_HashTable);
node->hj_HashTable = NULL;
node->hj_FirstOuterTupleSlot = NULL;
}
/*
@ -803,13 +797,6 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
void
ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
{
/*
* If we haven't yet built the hash table then we can just return; nothing
* done yet, so nothing to undo.
*/
if (node->hj_HashTable == NULL)
return;
/*
* In a multi-batch join, we currently have to do rescans the hard way,
* primarily because batch temp files may have already been released. But
@ -817,6 +804,8 @@ ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
* inner subnode, then we can just re-use the existing hash table without
* rebuilding it.
*/
if (node->hj_HashTable != NULL)
{
if (node->hj_HashTable->nbatch == 1 &&
((PlanState *) node)->righttree->chgParam == NULL)
{
@ -827,15 +816,15 @@ ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
/* must destroy and rebuild hash table */
ExecHashTableDestroy(node->hj_HashTable);
node->hj_HashTable = NULL;
node->hj_FirstOuterTupleSlot = NULL;
/*
* if chgParam of subnode is not null then plan will be re-scanned by
* first ExecProcNode.
* if chgParam of subnode is not null then plan will be re-scanned
* by first ExecProcNode.
*/
if (((PlanState *) node)->righttree->chgParam == NULL)
ExecReScan(((PlanState *) node)->righttree, exprCtxt);
}
}
/* Always reset intra-tuple state */
node->hj_CurHashValue = 0;
@ -846,6 +835,7 @@ ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
node->js.ps.ps_TupFromTlist = false;
node->hj_NeedNewOuter = true;
node->hj_MatchedOuter = false;
node->hj_FirstOuterTupleSlot = NULL;
/*
* if chgParam of subnode is not null then plan will be re-scanned by