45
45
* PHJ_BUILD_ALLOCATING -- one sets up the batches and table 0
46
46
* PHJ_BUILD_HASHING_INNER -- all hash the inner rel
47
47
* PHJ_BUILD_HASHING_OUTER -- (multi-batch only) all hash the outer
48
- * PHJ_BUILD_RUNNING -- building done, probing can begin
49
- * PHJ_BUILD_DONE -- all work complete, one frees batches
48
+ * PHJ_BUILD_DONE -- building done, probing can begin
50
49
*
51
50
* While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
52
51
* be used repeatedly as required to coordinate expansions in the number of
74
73
* batches whenever it encounters them while scanning and probing, which it
75
74
* can do because it processes batches in serial order.
76
75
*
77
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
76
+ * Once PHJ_BUILD_DONE is reached, backends then split up and process
78
77
* different batches, or gang up and work together on probing batches if there
79
78
* aren't enough to go around. For each batch there is a separate barrier
80
79
* with the following phases:
96
95
*
97
96
* To avoid deadlocks, we never wait for any barrier unless it is known that
98
97
* all other backends attached to it are actively executing the node or have
99
- * finished. Practically, that means that we never emit a tuple while attached
100
- * to a barrier, unless the barrier has reached a phase that means that no
101
- * process will wait on it again. We emit tuples while attached to the build
102
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
103
- * PHJ_BATCH_PROBING. These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
104
- * respectively without waiting, using BarrierArriveAndDetach(). The last to
105
- * detach receives a different return value so that it knows that it's safe to
106
- * clean up. Any straggler process that attaches after that phase is reached
107
- * will see that it's too late to participate or access the relevant shared
108
- * memory objects.
98
+ * already arrived. Practically, that means that we never return a tuple
99
+ * while attached to a barrier, unless the barrier has reached its final
100
+ * state. In the slightly special case of the per-batch barrier, we return
101
+ * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
102
+ * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
109
103
*
110
104
*-------------------------------------------------------------------------
111
105
*/
@@ -322,7 +316,6 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
322
316
323
317
build_barrier = & parallel_state -> build_barrier ;
324
318
Assert (BarrierPhase (build_barrier ) == PHJ_BUILD_HASHING_OUTER ||
325
- BarrierPhase (build_barrier ) == PHJ_BUILD_RUNNING ||
326
319
BarrierPhase (build_barrier ) == PHJ_BUILD_DONE );
327
320
if (BarrierPhase (build_barrier ) == PHJ_BUILD_HASHING_OUTER )
328
321
{
@@ -335,18 +328,9 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
335
328
BarrierArriveAndWait (build_barrier ,
336
329
WAIT_EVENT_HASH_BUILD_HASHING_OUTER );
337
330
}
338
- else if (BarrierPhase (build_barrier ) == PHJ_BUILD_DONE )
339
- {
340
- /*
341
- * If we attached so late that the job is finished and
342
- * the batch state has been freed, we can return
343
- * immediately.
344
- */
345
- return NULL ;
346
- }
331
+ Assert (BarrierPhase (build_barrier ) == PHJ_BUILD_DONE );
347
332
348
333
/* Each backend should now select a batch to work on. */
349
- Assert (BarrierPhase (build_barrier ) == PHJ_BUILD_RUNNING );
350
334
hashtable -> curbatch = -1 ;
351
335
node -> hj_JoinState = HJ_NEED_NEW_BATCH ;
352
336
@@ -1119,6 +1103,14 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
1119
1103
int start_batchno ;
1120
1104
int batchno ;
1121
1105
1106
+ /*
1107
+ * If we started up so late that the batch tracking array has been freed
1108
+ * already by ExecHashTableDetach(), then we are finished. See also
1109
+ * ExecParallelHashEnsureBatchAccessors().
1110
+ */
1111
+ if (hashtable -> batches == NULL )
1112
+ return false;
1113
+
1122
1114
/*
1123
1115
* If we were already attached to a batch, remember not to bother checking
1124
1116
* it again, and detach from it (possibly freeing the hash table if we are
0 commit comments