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 */
154154if (hashtable -> totalTuples == 0 && node -> js .jointype != JOIN_LEFT )
155- {
156- ExecHashTableDestroy (hashtable );
157- node -> hj_HashTable = NULL ;
158- node -> hj_FirstOuterTupleSlot = NULL ;
159155return NULL ;
160- }
161156
162157/*
163158 * need to remember whether nbatch has increased since we began
@@ -487,7 +482,6 @@ ExecEndHashJoin(HashJoinState *node)
487482{
488483ExecHashTableDestroy (node -> hj_HashTable );
489484node -> hj_HashTable = NULL ;
490- node -> hj_FirstOuterTupleSlot = NULL ;
491485}
492486
493487/*
@@ -803,38 +797,33 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
803797void
804798ExecReScanHashJoin (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)
846835node -> js .ps .ps_TupFromTlist = false;
847836node -> hj_NeedNewOuter = true;
848837node -> 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