PostgreSQL Source Code: src/backend/executor/nodeHashjoin.c File Reference (original) (raw)
Go to the source code of this file.
Macros | |
---|---|
#define | HJ_BUILD_HASHTABLE 1 |
#define | HJ_NEED_NEW_OUTER 2 |
#define | HJ_SCAN_BUCKET 3 |
#define | HJ_FILL_OUTER_TUPLE 4 |
#define | HJ_FILL_INNER_TUPLES 5 |
#define | HJ_NEED_NEW_BATCH 6 |
#define | HJ_FILL_OUTER(hjstate) ((hjstate)->hj_NullInnerTupleSlot != NULL) |
#define | HJ_FILL_INNER(hjstate) ((hjstate)->hj_NullOuterTupleSlot != NULL) |
◆ HJ_BUILD_HASHTABLE
#define HJ_BUILD_HASHTABLE 1
◆ HJ_FILL_INNER
| #define HJ_FILL_INNER | ( | | hjstate | ) | ((hjstate)->hj_NullOuterTupleSlot != NULL) | | ----------------------- | - | | ------- | - | ------------------------------------------- |
◆ HJ_FILL_INNER_TUPLES
#define HJ_FILL_INNER_TUPLES 5
◆ HJ_FILL_OUTER
| #define HJ_FILL_OUTER | ( | | hjstate | ) | ((hjstate)->hj_NullInnerTupleSlot != NULL) | | ----------------------- | - | | ------- | - | ------------------------------------------- |
◆ HJ_FILL_OUTER_TUPLE
#define HJ_FILL_OUTER_TUPLE 4
◆ HJ_NEED_NEW_BATCH
#define HJ_NEED_NEW_BATCH 6
◆ HJ_NEED_NEW_OUTER
#define HJ_NEED_NEW_OUTER 2
◆ HJ_SCAN_BUCKET
◆ ExecEndHashJoin()
◆ ExecHashJoin()
◆ ExecHashJoinEstimate()
◆ ExecHashJoinGetSavedTuple()
Definition at line 1455 of file nodeHashjoin.c.
1459{
1461 size_t nread;
1463
1464
1465
1466
1467
1468
1470
1471
1472
1473
1474
1475
1477 if (nread == 0)
1478 {
1480 return NULL;
1481 }
1482 *hashvalue = header[0];
1484 tuple->t_len = header[1];
1486 (char *) tuple + sizeof(uint32),
1487 header[1] - sizeof(uint32));
1489 return tupleSlot;
1490}
void BufFileReadExact(BufFile *file, void *ptr, size_t size)
size_t BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK)
void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
MinimalTupleData * MinimalTuple
#define CHECK_FOR_INTERRUPTS()
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
References BufFileReadExact(), BufFileReadMaybeEOF(), CHECK_FOR_INTERRUPTS, ExecClearTuple(), ExecForceStoreMinimalTuple(), palloc(), and MinimalTupleData::t_len.
Referenced by ExecHashJoinNewBatch(), and ExecHashJoinOuterGetTuple().
◆ ExecHashJoinImpl()
Definition at line 221 of file nodeHashjoin.c.
222{
232 int batchno;
234
235
236
237
239 otherqual = node->js.ps.qual;
245
246
247
248
249
251
252
253
254
255 for (;;)
256 {
257
258
259
260
261
262
264
266 {
268
269
270
271
272 Assert(hashtable == NULL);
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
298 {
299
301 }
302 else if (parallel)
303 {
304
305
306
307
308
309
310
311
313 }
317 {
320 {
322 return NULL;
323 }
324 else
326 }
327 else
329
330
331
332
333
334
337
338
339
340
341
342
345
346
347
348
349
350
352 {
353 if (parallel)
354 {
355
356
357
358
360
363 }
364 return NULL;
365 }
366
367
368
369
370
372
373
374
375
376
377
379
380 if (parallel)
381 {
383
389 {
390
391
392
393
394 if (hashtable->nbatch > 1)
397 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
398 }
400 {
401
402
403
404
405
406 return NULL;
407 }
408
409
413
414 continue;
415 }
416 else
418
419
420
422
423
424
425
426 if (parallel)
427 outerTupleSlot =
429 &hashvalue);
430 else
431 outerTupleSlot =
433
435 {
436
438 {
439
440 if (parallel)
441 {
442
443
444
445
446
449 else
451 }
452 else
453 {
456 }
457 }
458 else
460 continue;
461 }
462
465
466
467
468
469
474 hashvalue);
476
477
478
479
480
481 if (batchno != hashtable->curbatch &&
483 {
484 bool shouldFree;
486 &shouldFree);
487
488
489
490
491
492 Assert(parallel_state == NULL);
496 hashtable);
497
498 if (shouldFree)
500
501
502 continue;
503 }
504
505
507
508
509
511
512
513
514
515 if (parallel)
516 {
518 {
519
521 continue;
522 }
523 }
524 else
525 {
527 {
528
530 continue;
531 }
532 }
533
534
535
536
537
540 continue;
541
542
543
544
545
546
547
548
549
550
551
552
553
554 if (joinqual == NULL || ExecQual(joinqual, econtext))
555 {
557
558
559
560
561
562
565
566
568 {
570 continue;
571 }
572
573
574
575
576
577
580
581
582
583
584
585
586
588 continue;
589
590 if (otherqual == NULL || ExecQual(otherqual, econtext))
592 else
594 }
595 else
597 break;
598
600
601
602
603
604
605
607
610 {
611
612
613
614
616
617 if (otherqual == NULL || ExecQual(otherqual, econtext))
619 else
621 }
622 break;
623
625
626
627
628
629
630
631
634 {
635
637 continue;
638 }
639
640
641
642
643
645
646 if (otherqual == NULL || ExecQual(otherqual, econtext))
648 else
650 break;
651
653
654
655
656
657 if (parallel)
658 {
660 return NULL;
661 }
662 else
663 {
665 return NULL;
666 }
668 break;
669
670 default:
671 elog(ERROR, "unrecognized hashjoin state: %d",
673 }
674 }
675}
int BarrierPhase(Barrier *barrier)
bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info)
Node * MultiExecProcNode(PlanState *node)
MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot, bool *shouldFree)
#define InstrCountFiltered1(node, delta)
#define InstrCountFiltered2(node, delta)
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
#define ResetExprContext(econtext)
static bool ExecQual(ExprState *state, ExprContext *econtext)
static TupleTableSlot * ExecProcNode(PlanState *node)
Assert(PointerIsAligned(start, uint64))
#define PHJ_BUILD_HASH_OUTER
#define HJTUPLE_MINTUPLE(hjtup)
#define INVALID_SKEW_BUCKET_NO
void heap_free_minimal_tuple(MinimalTuple mtup)
static void HeapTupleHeaderSetMatch(MinimalTupleData *tup)
static bool HeapTupleHeaderHasMatch(const MinimalTupleData *tup)
bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext)
void ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
HashJoinTable ExecHashTableCreate(HashState *state)
int ExecHashGetSkewBucket(HashJoinTable hashtable, uint32 hashvalue)
bool ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
void ExecHashGetBucketAndBatch(HashJoinTable hashtable, uint32 hashvalue, int *bucketno, int *batchno)
bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext)
#define HJ_NEED_NEW_BATCH
#define HJ_FILL_OUTER_TUPLE
static bool ExecHashJoinNewBatch(HashJoinState *hjstate)
static TupleTableSlot * ExecParallelHashJoinOuterGetTuple(PlanState *outerNode, HashJoinState *hjstate, uint32 *hashvalue)
#define HJ_FILL_INNER(hjstate)
static bool ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
#define HJ_FILL_INNER_TUPLES
static TupleTableSlot * ExecHashJoinOuterGetTuple(PlanState *outerNode, HashJoinState *hjstate, uint32 *hashvalue)
void ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue, BufFile **fileptr, HashJoinTable hashtable)
#define HJ_NEED_NEW_OUTER
#define HJ_FILL_OUTER(hjstate)
static void ExecParallelHashJoinPartitionOuter(HashJoinState *hjstate)
#define HJ_BUILD_HASHTABLE
#define castNode(_type_, nodeptr)
TupleTableSlot * ecxt_innertuple
TupleTableSlot * ecxt_outertuple
HashJoinTuple hj_CurTuple
TupleTableSlot * hj_NullOuterTupleSlot
TupleTableSlot * hj_NullInnerTupleSlot
TupleTableSlot * hj_FirstOuterTupleSlot
BufFile ** outerBatchFile
struct ParallelHashJoinState * parallel_state
ExprContext * ps_ExprContext
ProjectionInfo * ps_ProjInfo
References Assert(), BarrierArriveAndWait(), BarrierPhase(), ParallelHashJoinState::build_barrier, castNode, CHECK_FOR_INTERRUPTS, HashJoinTableData::curbatch, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, elog, ERROR, ExecFetchSlotMinimalTuple(), ExecHashGetBucketAndBatch(), ExecHashGetSkewBucket(), ExecHashJoinNewBatch(), ExecHashJoinOuterGetTuple(), ExecHashJoinSaveTuple(), ExecHashTableCreate(), ExecParallelHashJoinNewBatch(), ExecParallelHashJoinOuterGetTuple(), ExecParallelHashJoinPartitionOuter(), ExecParallelPrepHashTableForUnmatched(), ExecParallelScanHashBucket(), ExecParallelScanHashTableForUnmatched(), ExecPrepHashTableForUnmatched(), ExecProcNode(), ExecProject(), ExecQual(), ExecScanHashBucket(), ExecScanHashTableForUnmatched(), HashState::hashtable, heap_free_minimal_tuple(), HeapTupleHeaderHasMatch(), HeapTupleHeaderSetMatch(), HJ_BUILD_HASHTABLE, HashJoinState::hj_CurBucketNo, HashJoinState::hj_CurHashValue, HashJoinState::hj_CurSkewBucketNo, HashJoinState::hj_CurTuple, HJ_FILL_INNER, HJ_FILL_INNER_TUPLES, HJ_FILL_OUTER, HJ_FILL_OUTER_TUPLE, HashJoinState::hj_FirstOuterTupleSlot, HashJoinState::hj_HashTable, HashJoinState::hj_JoinState, HashJoinState::hj_MatchedOuter, HJ_NEED_NEW_BATCH, HJ_NEED_NEW_OUTER, HashJoinState::hj_NullInnerTupleSlot, HashJoinState::hj_NullOuterTupleSlot, HashJoinState::hj_OuterNotEmpty, HJ_SCAN_BUCKET, HJTUPLE_MINTUPLE, innerPlanState, InstrCountFiltered1, InstrCountFiltered2, INVALID_SKEW_BUCKET_NO, JOIN_ANTI, JOIN_RIGHT_ANTI, JOIN_RIGHT_SEMI, JoinState::joinqual, JoinState::jointype, HashJoinState::js, MultiExecProcNode(), HashJoinTableData::nbatch, HashJoinTableData::nbatch_outstart, HashJoinTableData::outerBatchFile, outerPlanState, HashState::parallel_state, PHJ_BUILD_FREE, PHJ_BUILD_HASH_OUTER, PHJ_BUILD_RUN, PlanState::plan, JoinState::ps, HashState::ps, PlanState::ps_ExprContext, PlanState::ps_ProjInfo, PlanState::qual, ResetExprContext, JoinState::single_match, Plan::startup_cost, Plan::total_cost, HashJoinTableData::totalTuples, and TupIsNull.
Referenced by ExecHashJoin(), and ExecParallelHashJoin().
◆ ExecHashJoinInitializeDSM()
Definition at line 1656 of file nodeHashjoin.c.
1657{
1658 int plan_node_id = state->js.ps.plan->plan_node_id;
1661
1662
1663
1664
1665
1666 if (pcxt->seg == NULL)
1667 return;
1668
1670
1671
1672
1673
1674
1677
1678
1679
1680
1681
1682
1698
1699
1701
1702
1705}
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
void BarrierInit(Barrier *barrier, int participants)
#define InvalidDsaPointer
void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
void LWLockInitialize(LWLock *lock, int tranche_id)
@ LWTRANCHE_PARALLEL_HASH_JOIN
static TupleTableSlot * ExecParallelHashJoin(PlanState *pstate)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Barrier grow_batches_barrier
dsa_pointer chunk_work_queue
Barrier grow_buckets_barrier
ParallelHashGrowth growth
pg_atomic_uint32 distributor
References BarrierInit(), ParallelHashJoinState::batches, ParallelHashJoinState::build_barrier, ParallelHashJoinState::chunk_work_queue, ParallelHashJoinState::distributor, ExecParallelHashJoin(), ExecSetExecProcNode(), ParallelHashJoinState::fileset, ParallelHashJoinState::grow_batches_barrier, ParallelHashJoinState::grow_buckets_barrier, ParallelHashJoinState::growth, innerPlanState, InvalidDsaPointer, ParallelHashJoinState::lock, LWLockInitialize(), LWTRANCHE_PARALLEL_HASH_JOIN, ParallelHashJoinState::nbatch, ParallelHashJoinState::nbuckets, ParallelHashJoinState::nparticipants, ParallelContext::nworkers, ParallelHashJoinState::old_batches, HashState::parallel_state, pg_atomic_init_u32(), PHJ_GROWTH_OK, ParallelContext::seg, SharedFileSetInit(), shm_toc_allocate(), shm_toc_insert(), ParallelHashJoinState::space_allowed, ParallelContext::toc, and ParallelHashJoinState::total_tuples.
Referenced by ExecParallelInitializeDSM().
◆ ExecHashJoinInitializeWorker()
Definition at line 1752 of file nodeHashjoin.c.
1754{
1756 int plan_node_id = state->js.ps.plan->plan_node_id;
1759
1760
1762
1763
1766
1768}
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
References ExecParallelHashJoin(), ExecSetExecProcNode(), ParallelHashJoinState::fileset, innerPlanState, HashState::parallel_state, ParallelWorkerContext::seg, SharedFileSetAttach(), shm_toc_lookup(), and ParallelWorkerContext::toc.
Referenced by ExecParallelInitializeWorker().
◆ ExecHashJoinNewBatch()
static bool ExecHashJoinNewBatch ( HashJoinState * hjstate) | static |
---|
Definition at line 1130 of file nodeHashjoin.c.
1131{
1133 int nbatch;
1134 int curbatch;
1138
1139 nbatch = hashtable->nbatch;
1140 curbatch = hashtable->curbatch;
1141
1142 if (curbatch > 0)
1143 {
1144
1145
1146
1147
1151 }
1152 else
1153 {
1154
1155
1156
1157
1158
1159
1165 }
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185 curbatch++;
1186 while (curbatch < nbatch &&
1189 {
1192 break;
1195 break;
1198 break;
1201 break;
1202
1203
1210 curbatch++;
1211 }
1212
1213 if (curbatch >= nbatch)
1214 return false;
1215
1216 hashtable->curbatch = curbatch;
1217
1218
1219
1220
1222
1224
1225 if (innerFile != NULL)
1226 {
1227 if (BufFileSeek(innerFile, 0, 0, SEEK_SET))
1230 errmsg("could not rewind hash-join temporary file")));
1231
1233 innerFile,
1234 &hashvalue,
1236 {
1237
1238
1239
1240
1242 }
1243
1244
1245
1246
1247
1250 }
1251
1252
1253
1254
1256 {
1260 errmsg("could not rewind hash-join temporary file")));
1261 }
1262
1263 return true;
1264}
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
void BufFileClose(BufFile *file)
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ExecHashTableReset(HashJoinTable hashtable)
void ExecHashTableInsert(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue)
static TupleTableSlot * ExecHashJoinGetSavedTuple(HashJoinState *hjstate, BufFile *file, uint32 *hashvalue, TupleTableSlot *tupleSlot)
TupleTableSlot * hj_HashTupleSlot
BufFile ** innerBatchFile
HashSkewBucket ** skewBucket
References BufFileClose(), BufFileSeek(), HashJoinTableData::curbatch, ereport, errcode_for_file_access(), errmsg(), ERROR, ExecHashJoinGetSavedTuple(), ExecHashTableInsert(), ExecHashTableReset(), HJ_FILL_INNER, HJ_FILL_OUTER, HashJoinState::hj_HashTable, HashJoinState::hj_HashTupleSlot, HashJoinTableData::innerBatchFile, HashJoinTableData::nbatch, HashJoinTableData::nbatch_original, HashJoinTableData::nbatch_outstart, HashJoinTableData::nSkewBuckets, HashJoinTableData::outerBatchFile, HashJoinTableData::skewBucket, HashJoinTableData::skewBucketNums, HashJoinTableData::skewEnabled, and HashJoinTableData::spaceUsedSkew.
Referenced by ExecHashJoinImpl().
◆ ExecHashJoinOuterGetTuple()
Definition at line 979 of file nodeHashjoin.c.
982{
984 int curbatch = hashtable->curbatch;
986
987 if (curbatch == 0)
988 {
989
990
991
992
996 else
998
1000 {
1001 bool isnull;
1002
1003
1004
1005
1007
1009
1011
1013 econtext,
1014 &isnull));
1015
1016 if (!isnull)
1017 {
1018
1020
1021 return slot;
1022 }
1023
1024
1025
1026
1027
1029 }
1030 }
1031 else if (curbatch < hashtable->nbatch)
1032 {
1034
1035
1036
1037
1038
1039 if (file == NULL)
1040 return NULL;
1041
1043 file,
1044 hashvalue,
1047 return slot;
1048 }
1049
1050
1051 return NULL;
1052}
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
static uint32 DatumGetUInt32(Datum X)
TupleTableSlot * hj_OuterTupleSlot
References HashJoinTableData::curbatch, DatumGetUInt32(), ExprContext::ecxt_outertuple, ExecEvalExprSwitchContext(), ExecHashJoinGetSavedTuple(), ExecProcNode(), HashJoinState::hj_FirstOuterTupleSlot, HashJoinState::hj_HashTable, HashJoinState::hj_OuterHash, HashJoinState::hj_OuterNotEmpty, HashJoinState::hj_OuterTupleSlot, HashJoinState::js, HashJoinTableData::outerBatchFile, JoinState::ps, PlanState::ps_ExprContext, ResetExprContext, and TupIsNull.
Referenced by ExecHashJoinImpl().
◆ ExecHashJoinReInitializeDSM()
◆ ExecHashJoinSaveTuple()
◆ ExecInitHashJoin()
Definition at line 716 of file nodeHashjoin.c.
717{
719 Plan *outerNode;
720 Hash *hashNode;
722 innerDesc;
724
725
727
728
729
730
734
735
736
737
738
739
742
743
744
745
746
747
749
750
751
752
753
754
755
756
759
764
765
766
767
770
771
772
773
776 ops);
777
778
779
780
783
784
786 {
790 break;
795 break;
800 break;
806 break;
807 default:
808 elog(ERROR, "unrecognized join type: %d",
810 }
811
812
813
814
815
816
817
818
819 {
823 Oid *outer_hashfuncid;
824 Oid *inner_hashfuncid;
825 bool *hash_strict;
827 int nkeys;
828
829
831
832
833
834
835
836
837
838
839
840
842
846
847
848
849
850
852 {
855
857 &outer_hashfuncid[i],
858 &inner_hashfuncid[i]))
860 "could not find hash function for hash operator %u",
861 hashop);
863 }
864
865
866
867
868
869
870
871
872
876 outer_hashfuncid,
879 hash_strict,
881 0,
883
884
888 inner_hashfuncid,
890 hash->hashkeys,
891 hash_strict,
892 &hashstate->ps,
893 0,
895
896
897
898
899
901 {
905 }
906
907
908 pfree(outer_hashfuncid);
909 pfree(inner_hashfuncid);
910 pfree(hash_strict);
911 }
912
913
914
915
922
923
924
925
928
933
937
938 return hjstate;
939}
#define OidIsValid(objectId)
ExprState * ExecInitQual(List *qual, PlanState *parent)
ExprState * ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops, const Oid *hashfunc_oids, const List *collations, const List *hash_exprs, const bool *opstrict, PlanState *parent, uint32 init_value, bool keep_nulls)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
const TupleTableSlotOps TTSOpsVirtual
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
TupleTableSlot * ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, const TupleTableSlotOps *tts_ops)
TupleDesc ExecGetResultType(PlanState *planstate)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
#define EXEC_FLAG_BACKWARD
#define palloc_array(type, count)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
void pfree(void *pointer)
void * palloc0(Size size)
static TupleTableSlot * ExecHashJoin(PlanState *pstate)
static int list_length(const List *l)
#define foreach_current_index(var_or_cell)
static unsigned hash(unsigned *uv, int n)
FmgrInfo * skew_hashfunction
const TupleTableSlotOps * resultops
TupleDesc ps_ResultTupleDesc
TupleTableSlot * ps_ResultTupleSlot
ExecProcNodeMtd ExecProcNode
References Assert(), elog, ERROR, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignProjectionInfo(), ExecBuildHash32Expr(), ExecGetResultSlotOps(), ExecGetResultType(), ExecHashJoin(), ExecInitExtraTupleSlot(), ExecInitNode(), ExecInitNullTupleSlot(), ExecInitQual(), ExecInitResultTupleSlotTL(), PlanState::ExecProcNode, fmgr_info(), foreach_current_index, get_op_hash_functions(), hash(), HashState::hash_expr, HashJoinState::hashclauses, HashJoin::hashclauses, HashJoin::hashcollations, HashJoin::hashkeys, HashJoin::hashoperators, HJ_BUILD_HASHTABLE, HashJoinState::hj_CurBucketNo, HashJoinState::hj_CurHashValue, HashJoinState::hj_CurSkewBucketNo, HashJoinState::hj_CurTuple, HJ_FILL_INNER, HJ_FILL_OUTER, HashJoinState::hj_FirstOuterTupleSlot, HashJoinState::hj_HashTable, HashJoinState::hj_HashTupleSlot, HashJoinState::hj_JoinState, HashJoinState::hj_MatchedOuter, HashJoinState::hj_NullInnerTupleSlot, HashJoinState::hj_NullOuterTupleSlot, HashJoinState::hj_OuterHash, HashJoinState::hj_OuterNotEmpty, HashJoinState::hj_OuterTupleSlot, i, Join::inner_unique, innerPlan, innerPlanState, INVALID_SKEW_BUCKET_NO, HashJoin::join, JOIN_ANTI, JOIN_FULL, JOIN_INNER, JOIN_LEFT, JOIN_RIGHT, JOIN_RIGHT_ANTI, JOIN_RIGHT_SEMI, JOIN_SEMI, JoinState::joinqual, Join::joinqual, JoinState::jointype, Join::jointype, HashJoinState::js, lfirst_oid, linitial_oid, list_length(), makeNode, OidIsValid, op_strict(), outerPlan, outerPlanState, palloc0(), palloc_array, pfree(), PlanState::plan, JoinState::ps, HashState::ps, PlanState::ps_ResultTupleDesc, PlanState::ps_ResultTupleSlot, PlanState::qual, PlanState::resultops, JoinState::single_match, HashState::skew_collation, HashState::skew_hashfunction, PlanState::state, and TTSOpsVirtual.
Referenced by ExecInitNode().
◆ ExecParallelHashJoin()
◆ ExecParallelHashJoinNewBatch()
static bool ExecParallelHashJoinNewBatch ( HashJoinState * hjstate) | static |
---|
Definition at line 1271 of file nodeHashjoin.c.
1272{
1274 int start_batchno;
1275 int batchno;
1276
1277
1278
1279
1280
1281
1282 if (hashtable->curbatch >= 0)
1283 {
1286 }
1287
1288
1289
1290
1291
1292
1293 batchno = start_batchno =
1296 do
1297 {
1301
1303 {
1305 Barrier *batch_barrier =
1307
1309 {
1311
1312
1314 WAIT_EVENT_HASH_BATCH_ELECT))
1316
1317
1319
1321 WAIT_EVENT_HASH_BATCH_ALLOCATE);
1322
1323
1325
1330 &hashvalue)))
1331 {
1334 false);
1337 hashvalue);
1338 }
1341 WAIT_EVENT_HASH_BATCH_LOAD);
1342
1343
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1358
1359 return true;
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1375 hashtable->batches[batchno].done = true;
1377 break;
1378
1380
1381
1382
1383
1384
1386 hashtable->batches[batchno].done = true;
1388 break;
1389
1390 default:
1391 elog(ERROR, "unexpected batch phase %d",
1393 }
1394 }
1395 batchno = (batchno + 1) % hashtable->nbatch;
1396 } while (batchno != start_batchno);
1397
1398 return false;
1399}
static uint32 pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
int BarrierAttach(Barrier *barrier)
bool BarrierDetach(Barrier *barrier)
#define PHJ_BATCH_ALLOCATE
void ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
void ExecParallelHashTableAlloc(HashJoinTable hashtable, int batchno)
void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue)
ParallelHashJoinBatchAccessor * batches
ParallelHashJoinState * parallel_state
SharedTuplestoreAccessor * outer_tuples
ParallelHashJoinBatch * shared
SharedTuplestoreAccessor * inner_tuples
References BarrierArriveAndWait(), BarrierAttach(), BarrierDetach(), BarrierPhase(), ParallelHashJoinBatch::batch_barrier, HashJoinTableData::batches, HashJoinTableData::curbatch, ParallelHashJoinState::distributor, ParallelHashJoinBatchAccessor::done, elog, ERROR, ExecForceStoreMinimalTuple(), ExecHashTableDetachBatch(), ExecParallelHashTableAlloc(), ExecParallelHashTableInsertCurrentBatch(), ExecParallelHashTableSetCurrentBatch(), HashJoinState::hj_HashTable, HashJoinState::hj_HashTupleSlot, ParallelHashJoinBatchAccessor::inner_tuples, HashJoinTableData::nbatch, ParallelHashJoinBatchAccessor::outer_tuples, HashJoinTableData::parallel_state, pg_atomic_fetch_add_u32(), PHJ_BATCH_ALLOCATE, PHJ_BATCH_ELECT, PHJ_BATCH_FREE, PHJ_BATCH_LOAD, PHJ_BATCH_PROBE, PHJ_BATCH_SCAN, ParallelHashJoinBatchAccessor::shared, sts_begin_parallel_scan(), sts_end_parallel_scan(), and sts_parallel_scan_next().
Referenced by ExecHashJoinImpl().
◆ ExecParallelHashJoinOuterGetTuple()
Definition at line 1058 of file nodeHashjoin.c.
1061{
1063 int curbatch = hashtable->curbatch;
1065
1066
1067
1068
1069
1070
1071 if (curbatch == 0 && hashtable->nbatch == 1)
1072 {
1074
1076 {
1077 bool isnull;
1078
1080
1082
1084
1086 econtext,
1087 &isnull));
1088
1089 if (!isnull)
1090 return slot;
1091
1092
1093
1094
1095
1097 }
1098 }
1099 else if (curbatch < hashtable->nbatch)
1100 {
1102
1104 hashvalue);
1105 if (tuple != NULL)
1106 {
1109 false);
1111 return slot;
1112 }
1113 else
1115 }
1116
1117
1119
1120 return NULL;
1121}
References HashJoinTableData::batches, HashJoinTableData::curbatch, DatumGetUInt32(), ExprContext::ecxt_outertuple, ExecClearTuple(), ExecEvalExprSwitchContext(), ExecForceStoreMinimalTuple(), ExecProcNode(), HashJoinState::hj_HashTable, HashJoinState::hj_OuterHash, HashJoinState::hj_OuterTupleSlot, HashJoinState::js, HashJoinTableData::nbatch, ParallelHashJoinBatchAccessor::outer_eof, ParallelHashJoinBatchAccessor::outer_tuples, JoinState::ps, PlanState::ps_ExprContext, ResetExprContext, sts_parallel_scan_next(), and TupIsNull.
Referenced by ExecHashJoinImpl().
◆ ExecParallelHashJoinPartitionOuter()
static void ExecParallelHashJoinPartitionOuter ( HashJoinState * hjstate) | static |
---|
Definition at line 1598 of file nodeHashjoin.c.
1599{
1605 int i;
1606
1608
1609
1610 for (;;)
1611 {
1612 bool isnull;
1613
1616 break;
1618
1620
1622 econtext,
1623 &isnull));
1624
1625 if (!isnull)
1626 {
1627 int batchno;
1628 int bucketno;
1629 bool shouldFree;
1631
1633 &batchno);
1635 &hashvalue, mintup);
1636
1637 if (shouldFree)
1639 }
1641 }
1642
1643
1644 for (i = 0; i < hashtable->nbatch; ++i)
1646}
References Assert(), HashJoinTableData::batches, CHECK_FOR_INTERRUPTS, DatumGetUInt32(), ExprContext::ecxt_outertuple, ExecEvalExprSwitchContext(), ExecFetchSlotMinimalTuple(), ExecHashGetBucketAndBatch(), ExecProcNode(), heap_free_minimal_tuple(), HashJoinState::hj_FirstOuterTupleSlot, HashJoinState::hj_HashTable, HashJoinState::hj_OuterHash, i, HashJoinState::js, HashJoinTableData::nbatch, ParallelHashJoinBatchAccessor::outer_tuples, outerPlanState, JoinState::ps, PlanState::ps_ExprContext, ResetExprContext, sts_end_write(), sts_puttuple(), and TupIsNull.
Referenced by ExecHashJoinImpl().
◆ ExecReScanHashJoin()
Definition at line 1494 of file nodeHashjoin.c.
1495{
1498
1499
1500
1501
1502
1503
1504
1505
1507 {
1510 {
1511
1512
1513
1514
1515
1516
1517
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1531
1532
1534 }
1535 else
1536 {
1537
1539
1541
1542
1549
1551
1555
1556
1557
1558
1559
1560 if (innerPlan->chgParam == NULL)
1562 }
1563 }
1564
1565
1570
1573
1574
1575
1576
1577
1578 if (outerPlan->chgParam == NULL)
1580}
void ExecReScan(PlanState *node)
void ExecHashAccumInstrumentation(HashInstrumentation *instrument, HashJoinTable hashtable)
void ExecHashTableResetMatchFlags(HashJoinTable hashtable)
HashInstrumentation * hinstrument
Instrumentation * instrument
References Assert(), castNode, ExecHashAccumInstrumentation(), ExecHashTableDestroy(), ExecHashTableResetMatchFlags(), ExecReScan(), HashState::hashtable, HashState::hinstrument, HJ_BUILD_HASHTABLE, HashJoinState::hj_CurBucketNo, HashJoinState::hj_CurHashValue, HashJoinState::hj_CurSkewBucketNo, HashJoinState::hj_CurTuple, HJ_FILL_INNER, HashJoinState::hj_FirstOuterTupleSlot, HashJoinState::hj_HashTable, HashJoinState::hj_JoinState, HashJoinState::hj_MatchedOuter, HJ_NEED_NEW_OUTER, HashJoinState::hj_OuterNotEmpty, innerPlan, innerPlanState, PlanState::instrument, INVALID_SKEW_BUCKET_NO, JOIN_RIGHT_SEMI, JoinState::jointype, HashJoinState::js, HashJoinTableData::nbatch, outerPlan, outerPlanState, palloc0(), and HashState::ps.
Referenced by ExecReScan().