提交 b79cb1ee 编写于 作者: T Tom Lane

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.
上级 d4fc4ac4
......@@ -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,24 +804,26 @@ ExecReScanHashJoin(HashJoinState *node, ExprContext *exprCtxt)
* inner subnode, then we can just re-use the existing hash table without
* rebuilding it.
*/
if (node->hj_HashTable->nbatch == 1 &&
((PlanState *) node)->righttree->chgParam == NULL)
{
/* okay to reuse the hash table; needn't rescan inner, either */
}
else
if (node->hj_HashTable != NULL)
{
/* must destroy and rebuild hash table */
ExecHashTableDestroy(node->hj_HashTable);
node->hj_HashTable = NULL;
node->hj_FirstOuterTupleSlot = NULL;
if (node->hj_HashTable->nbatch == 1 &&
((PlanState *) node)->righttree->chgParam == NULL)
{
/* okay to reuse the hash table; needn't rescan inner, either */
}
else
{
/* must destroy and rebuild hash table */
ExecHashTableDestroy(node->hj_HashTable);
node->hj_HashTable = NULL;
/*
* 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);
/*
* 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 */
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册