88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.92 2005/03/31 02:02:52 neilc Exp $
11+ * $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.93 2005/04/16 20:07:35 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
1515/*
1616 * INTERFACE ROUTINES
17- * ExecHash - generate an in-memory hash table of the relation
17+ * MultiExecHash - generate an in-memory hash table of the relation
1818 * ExecInitHash - initialize node and subnodes
1919 * ExecEndHash - shutdown node and subnodes
2020 */
2121#include "postgres.h"
2222
2323#include "executor/execdebug.h"
2424#include "executor/hashjoin.h"
25+ #include "executor/instrument.h"
2526#include "executor/nodeHash.h"
2627#include "executor/nodeHashjoin.h"
2728#include "miscadmin.h"
@@ -36,12 +37,25 @@ static void ExecHashIncreaseNumBatches(HashJoinTable hashtable);
3637/* ----------------------------------------------------------------
3738 * ExecHash
3839 *
39- * build hash table for hashjoin, doing partitioning if more
40- * than one batch is required.
40+ * stub for pro forma compliance
4141 * ----------------------------------------------------------------
4242 */
4343TupleTableSlot *
4444ExecHash (HashState * node )
45+ {
46+ elog (ERROR , "Hash node does not support ExecProcNode call convention" );
47+ return NULL ;
48+ }
49+
50+ /* ----------------------------------------------------------------
51+ * MultiExecHash
52+ *
53+ * build hash table for hashjoin, doing partitioning if more
54+ * than one batch is required.
55+ * ----------------------------------------------------------------
56+ */
57+ Node *
58+ MultiExecHash (HashState * node )
4559{
4660 PlanState * outerNode ;
4761 List * hashkeys ;
@@ -50,6 +64,10 @@ ExecHash(HashState *node)
5064 ExprContext * econtext ;
5165 uint32 hashvalue ;
5266
67+ /* must provide our own instrumentation support */
68+ if (node -> ps .instrument )
69+ InstrStartNode (node -> ps .instrument );
70+
5371 /*
5472 * get state info from node
5573 */
@@ -70,14 +88,24 @@ ExecHash(HashState *node)
7088 slot = ExecProcNode (outerNode );
7189 if (TupIsNull (slot ))
7290 break ;
73- hashtable -> hashNonEmpty = true ;
91+ hashtable -> totalTuples += 1 ;
7492 /* We have to compute the hash value */
7593 econtext -> ecxt_innertuple = slot ;
7694 hashvalue = ExecHashGetHashValue (hashtable , econtext , hashkeys );
7795 ExecHashTableInsert (hashtable , ExecFetchSlotTuple (slot ), hashvalue );
7896 }
7997
80- /* We needn't return a tuple slot or anything else */
98+ /* must provide our own instrumentation support */
99+ if (node -> ps .instrument )
100+ InstrStopNodeMulti (node -> ps .instrument , hashtable -> totalTuples );
101+
102+ /*
103+ * We do not return the hash table directly because it's not a subtype
104+ * of Node, and so would violate the MultiExecProcNode API. Instead,
105+ * our parent Hashjoin node is expected to know how to fish it out
106+ * of our node state. Ugly but not really worth cleaning up, since
107+ * Hashjoin knows quite a bit more about Hash besides that.
108+ */
81109 return NULL ;
82110}
83111
@@ -220,7 +248,7 @@ ExecHashTableCreate(Hash *node, List *hashOperators)
220248 hashtable -> nbatch_original = nbatch ;
221249 hashtable -> nbatch_outstart = nbatch ;
222250 hashtable -> growEnabled = true;
223- hashtable -> hashNonEmpty = false ;
251+ hashtable -> totalTuples = 0 ;
224252 hashtable -> innerBatchFile = NULL ;
225253 hashtable -> outerBatchFile = NULL ;
226254 hashtable -> spaceUsed = 0 ;
0 commit comments