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
*/
@@ -323,7 +317,6 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
323
317
324
318
build_barrier = & parallel_state -> build_barrier ;
325
319
Assert (BarrierPhase (build_barrier ) == PHJ_BUILD_HASHING_OUTER ||
326
- BarrierPhase (build_barrier ) == PHJ_BUILD_RUNNING ||
327
320
BarrierPhase (build_barrier ) == PHJ_BUILD_DONE );
328
321
if (BarrierPhase (build_barrier ) == PHJ_BUILD_HASHING_OUTER )
329
322
{
@@ -336,18 +329,9 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
336
329
BarrierArriveAndWait (build_barrier ,
337
330
WAIT_EVENT_HASH_BUILD_HASHING_OUTER );
338
331
}
339
- else if (BarrierPhase (build_barrier ) == PHJ_BUILD_DONE )
340
- {
341
- /*
342
- * If we attached so late that the job is finished and
343
- * the batch state has been freed, we can return
344
- * immediately.
345
- */
346
- return NULL ;
347
- }
332
+ Assert (BarrierPhase (build_barrier ) == PHJ_BUILD_DONE );
348
333
349
334
/* Each backend should now select a batch to work on. */
350
- Assert (BarrierPhase (build_barrier ) == PHJ_BUILD_RUNNING );
351
335
hashtable -> curbatch = -1 ;
352
336
node -> hj_JoinState = HJ_NEED_NEW_BATCH ;
353
337
@@ -1106,6 +1090,14 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
1106
1090
int start_batchno ;
1107
1091
int batchno ;
1108
1092
1093
+ /*
1094
+ * If we started up so late that the batch tracking array has been freed
1095
+ * already by ExecHashTableDetach(), then we are finished. See also
1096
+ * ExecParallelHashEnsureBatchAccessors().
1097
+ */
1098
+ if (hashtable -> batches == NULL )
1099
+ return false;
1100
+
1109
1101
/*
1110
1102
* If we were already attached to a batch, remember not to bother checking
1111
1103
* it again, and detach from it (possibly freeing the hash table if we are
0 commit comments