PostgreSQL Source Code  git master
nodeHashjoin.h File Reference
#include "access/parallel.h"
#include "nodes/execnodes.h"
#include "storage/buffile.h"
Include dependency graph for nodeHashjoin.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

HashJoinStateExecInitHashJoin (HashJoin *node, EState *estate, int eflags)
 
void ExecEndHashJoin (HashJoinState *node)
 
void ExecReScanHashJoin (HashJoinState *node)
 
void ExecShutdownHashJoin (HashJoinState *node)
 
void ExecHashJoinEstimate (HashJoinState *state, ParallelContext *pcxt)
 
void ExecHashJoinInitializeDSM (HashJoinState *state, ParallelContext *pcxt)
 
void ExecHashJoinReInitializeDSM (HashJoinState *state, ParallelContext *pcxt)
 
void ExecHashJoinInitializeWorker (HashJoinState *state, ParallelWorkerContext *pwcxt)
 
void ExecHashJoinSaveTuple (MinimalTuple tuple, uint32 hashvalue, BufFile **fileptr)
 

Function Documentation

◆ ExecEndHashJoin()

void ExecEndHashJoin ( HashJoinState node)

Definition at line 765 of file nodeHashjoin.c.

766 {
767  /*
768  * Free hash table
769  */
770  if (node->hj_HashTable)
771  {
773  node->hj_HashTable = NULL;
774  }
775 
776  /*
777  * Free the exprcontext
778  */
779  ExecFreeExprContext(&node->js.ps);
780 
781  /*
782  * clean out the tuple table
783  */
787 
788  /*
789  * clean up subtrees
790  */
793 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:557
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:651
#define outerPlanState(node)
Definition: execnodes.h:1120
#define innerPlanState(node)
Definition: execnodes.h:1119
void ExecHashTableDestroy(HashJoinTable hashtable)
Definition: nodeHash.c:871
TupleTableSlot * hj_OuterTupleSlot
Definition: execnodes.h:2089
JoinState js
Definition: execnodes.h:2079
HashJoinTable hj_HashTable
Definition: execnodes.h:2084
TupleTableSlot * hj_HashTupleSlot
Definition: execnodes.h:2090
PlanState ps
Definition: execnodes.h:1977
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1062
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:433

References ExecClearTuple(), ExecEndNode(), ExecFreeExprContext(), ExecHashTableDestroy(), HashJoinState::hj_HashTable, HashJoinState::hj_HashTupleSlot, HashJoinState::hj_OuterTupleSlot, innerPlanState, HashJoinState::js, outerPlanState, JoinState::ps, and PlanState::ps_ResultTupleSlot.

Referenced by ExecEndNode().

◆ ExecHashJoinEstimate()

void ExecHashJoinEstimate ( HashJoinState state,
ParallelContext pcxt 
)

Definition at line 1440 of file nodeHashjoin.c.

1441 {
1443  shm_toc_estimate_keys(&pcxt->estimator, 1);
1444 }
#define shm_toc_estimate_chunk(e, sz)
Definition: shm_toc.h:51
#define shm_toc_estimate_keys(e, cnt)
Definition: shm_toc.h:53
shm_toc_estimator estimator
Definition: parallel.h:42

References ParallelContext::estimator, shm_toc_estimate_chunk, and shm_toc_estimate_keys.

Referenced by ExecParallelEstimate().

◆ ExecHashJoinInitializeDSM()

void ExecHashJoinInitializeDSM ( HashJoinState state,
ParallelContext pcxt 
)

Definition at line 1447 of file nodeHashjoin.c.

1448 {
1449  int plan_node_id = state->js.ps.plan->plan_node_id;
1450  HashState *hashNode;
1451  ParallelHashJoinState *pstate;
1452 
1453  /*
1454  * Disable shared hash table mode if we failed to create a real DSM
1455  * segment, because that means that we don't have a DSA area to work with.
1456  */
1457  if (pcxt->seg == NULL)
1458  return;
1459 
1461 
1462  /*
1463  * Set up the state needed to coordinate access to the shared hash
1464  * table(s), using the plan node ID as the toc key.
1465  */
1466  pstate = shm_toc_allocate(pcxt->toc, sizeof(ParallelHashJoinState));
1467  shm_toc_insert(pcxt->toc, plan_node_id, pstate);
1468 
1469  /*
1470  * Set up the shared hash join state with no batches initially.
1471  * ExecHashTableCreate() will prepare at least one later and set nbatch
1472  * and space_allowed.
1473  */
1474  pstate->nbatch = 0;
1475  pstate->space_allowed = 0;
1476  pstate->batches = InvalidDsaPointer;
1477  pstate->old_batches = InvalidDsaPointer;
1478  pstate->nbuckets = 0;
1479  pstate->growth = PHJ_GROWTH_OK;
1481  pg_atomic_init_u32(&pstate->distributor, 0);
1482  pstate->nparticipants = pcxt->nworkers + 1;
1483  pstate->total_tuples = 0;
1484  LWLockInitialize(&pstate->lock,
1486  BarrierInit(&pstate->build_barrier, 0);
1487  BarrierInit(&pstate->grow_batches_barrier, 0);
1488  BarrierInit(&pstate->grow_buckets_barrier, 0);
1489 
1490  /* Set up the space we'll use for shared temporary files. */
1491  SharedFileSetInit(&pstate->fileset, pcxt->seg);
1492 
1493  /* Initialize the shared state in the hash node. */
1494  hashNode = (HashState *) innerPlanState(state);
1495  hashNode->parallel_state = pstate;
1496 }
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:218
void BarrierInit(Barrier *barrier, int participants)
Definition: barrier.c:100
#define InvalidDsaPointer
Definition: dsa.h:78
void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
Definition: execProcnode.c:425
@ PHJ_GROWTH_OK
Definition: hashjoin.h:221
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:729
@ LWTRANCHE_PARALLEL_HASH_JOIN
Definition: lwlock.h:192
static TupleTableSlot * ExecParallelHashJoin(PlanState *pstate)
Definition: nodeHashjoin.c:601
void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:44
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition: shm_toc.c:171
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition: shm_toc.c:88
struct ParallelHashJoinState * parallel_state
Definition: execnodes.h:2655
dsm_segment * seg
Definition: parallel.h:43
shm_toc * toc
Definition: parallel.h:45
Barrier grow_batches_barrier
Definition: hashjoin.h:249
dsa_pointer old_batches
Definition: hashjoin.h:237
dsa_pointer chunk_work_queue
Definition: hashjoin.h:242
Barrier grow_buckets_barrier
Definition: hashjoin.h:250
ParallelHashGrowth growth
Definition: hashjoin.h:241
pg_atomic_uint32 distributor
Definition: hashjoin.h:251
SharedFileSet fileset
Definition: hashjoin.h:253
dsa_pointer batches
Definition: hashjoin.h:236
Definition: regguts.h:318

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()

void ExecHashJoinInitializeWorker ( HashJoinState state,
ParallelWorkerContext pwcxt 
)

Definition at line 1538 of file nodeHashjoin.c.

1540 {
1541  HashState *hashNode;
1542  int plan_node_id = state->js.ps.plan->plan_node_id;
1543  ParallelHashJoinState *pstate =
1544  shm_toc_lookup(pwcxt->toc, plan_node_id, false);
1545 
1546  /* Attach to the space for shared temporary files. */
1547  SharedFileSetAttach(&pstate->fileset, pwcxt->seg);
1548 
1549  /* Attach to the shared state in the hash node. */
1550  hashNode = (HashState *) innerPlanState(state);
1551  hashNode->parallel_state = pstate;
1552 
1554 }
void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:62
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
Definition: shm_toc.c:232
dsm_segment * seg
Definition: parallel.h:53

References ExecParallelHashJoin(), ExecSetExecProcNode(), ParallelHashJoinState::fileset, innerPlanState, HashState::parallel_state, ParallelWorkerContext::seg, SharedFileSetAttach(), shm_toc_lookup(), and ParallelWorkerContext::toc.

Referenced by ExecParallelInitializeWorker().

◆ ExecHashJoinReInitializeDSM()

void ExecHashJoinReInitializeDSM ( HashJoinState state,
ParallelContext pcxt 
)

Definition at line 1505 of file nodeHashjoin.c.

1506 {
1507  int plan_node_id = state->js.ps.plan->plan_node_id;
1508  ParallelHashJoinState *pstate =
1509  shm_toc_lookup(pcxt->toc, plan_node_id, false);
1510 
1511  /*
1512  * It would be possible to reuse the shared hash table in single-batch
1513  * cases by resetting and then fast-forwarding build_barrier to
1514  * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
1515  * currently shared hash tables are already freed by now (by the last
1516  * participant to detach from the batch). We could consider keeping it
1517  * around for single-batch joins. We'd also need to adjust
1518  * finalize_plan() so that it doesn't record a dummy dependency for
1519  * Parallel Hash nodes, preventing the rescan optimization. For now we
1520  * don't try.
1521  */
1522 
1523  /* Detach, freeing any remaining shared memory. */
1524  if (state->hj_HashTable != NULL)
1525  {
1526  ExecHashTableDetachBatch(state->hj_HashTable);
1527  ExecHashTableDetach(state->hj_HashTable);
1528  }
1529 
1530  /* Clear any shared batch files. */
1531  SharedFileSetDeleteAll(&pstate->fileset);
1532 
1533  /* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
1534  BarrierInit(&pstate->build_barrier, 0);
1535 }
void ExecHashTableDetachBatch(HashJoinTable hashtable)
Definition: nodeHash.c:3125
void ExecHashTableDetach(HashJoinTable hashtable)
Definition: nodeHash.c:3182
void SharedFileSetDeleteAll(SharedFileSet *fileset)
Definition: sharedfileset.c:89

References BarrierInit(), ParallelHashJoinState::build_barrier, ExecHashTableDetach(), ExecHashTableDetachBatch(), ParallelHashJoinState::fileset, SharedFileSetDeleteAll(), shm_toc_lookup(), and ParallelContext::toc.

Referenced by ExecParallelReInitializeDSM().

◆ ExecHashJoinSaveTuple()

void ExecHashJoinSaveTuple ( MinimalTuple  tuple,
uint32  hashvalue,
BufFile **  fileptr 
)

Definition at line 1218 of file nodeHashjoin.c.

1220 {
1221  BufFile *file = *fileptr;
1222 
1223  if (file == NULL)
1224  {
1225  /* First write to this batch file, so open it. */
1226  file = BufFileCreateTemp(false);
1227  *fileptr = file;
1228  }
1229 
1230  BufFileWrite(file, (void *) &hashvalue, sizeof(uint32));
1231  BufFileWrite(file, (void *) tuple, tuple->t_len);
1232 }
BufFile * BufFileCreateTemp(bool interXact)
Definition: buffile.c:188
void BufFileWrite(BufFile *file, void *ptr, size_t size)
Definition: buffile.c:625
unsigned int uint32
Definition: c.h:442

References BufFileCreateTemp(), BufFileWrite(), and MinimalTupleData::t_len.

Referenced by ExecHashIncreaseNumBatches(), ExecHashJoinImpl(), ExecHashRemoveNextSkewBucket(), and ExecHashTableInsert().

◆ ExecInitHashJoin()

HashJoinState* ExecInitHashJoin ( HashJoin node,
EState estate,
int  eflags 
)

Definition at line 617 of file nodeHashjoin.c.

618 {
619  HashJoinState *hjstate;
620  Plan *outerNode;
621  Hash *hashNode;
622  TupleDesc outerDesc,
623  innerDesc;
624  const TupleTableSlotOps *ops;
625 
626  /* check for unsupported flags */
627  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
628 
629  /*
630  * create state structure
631  */
632  hjstate = makeNode(HashJoinState);
633  hjstate->js.ps.plan = (Plan *) node;
634  hjstate->js.ps.state = estate;
635 
636  /*
637  * See ExecHashJoinInitializeDSM() and ExecHashJoinInitializeWorker()
638  * where this function may be replaced with a parallel version, if we
639  * managed to launch a parallel query.
640  */
641  hjstate->js.ps.ExecProcNode = ExecHashJoin;
642  hjstate->js.jointype = node->join.jointype;
643 
644  /*
645  * Miscellaneous initialization
646  *
647  * create expression context for node
648  */
649  ExecAssignExprContext(estate, &hjstate->js.ps);
650 
651  /*
652  * initialize child nodes
653  *
654  * Note: we could suppress the REWIND flag for the inner input, which
655  * would amount to betting that the hash will be a single batch. Not
656  * clear if this would be a win or not.
657  */
658  outerNode = outerPlan(node);
659  hashNode = (Hash *) innerPlan(node);
660 
661  outerPlanState(hjstate) = ExecInitNode(outerNode, estate, eflags);
662  outerDesc = ExecGetResultType(outerPlanState(hjstate));
663  innerPlanState(hjstate) = ExecInitNode((Plan *) hashNode, estate, eflags);
664  innerDesc = ExecGetResultType(innerPlanState(hjstate));
665 
666  /*
667  * Initialize result slot, type and projection.
668  */
670  ExecAssignProjectionInfo(&hjstate->js.ps, NULL);
671 
672  /*
673  * tuple table initialization
674  */
675  ops = ExecGetResultSlotOps(outerPlanState(hjstate), NULL);
676  hjstate->hj_OuterTupleSlot = ExecInitExtraTupleSlot(estate, outerDesc,
677  ops);
678 
679  /*
680  * detect whether we need only consider the first matching inner tuple
681  */
682  hjstate->js.single_match = (node->join.inner_unique ||
683  node->join.jointype == JOIN_SEMI);
684 
685  /* set up null tuples for outer joins, if needed */
686  switch (node->join.jointype)
687  {
688  case JOIN_INNER:
689  case JOIN_SEMI:
690  break;
691  case JOIN_LEFT:
692  case JOIN_ANTI:
693  hjstate->hj_NullInnerTupleSlot =
694  ExecInitNullTupleSlot(estate, innerDesc, &TTSOpsVirtual);
695  break;
696  case JOIN_RIGHT:
697  hjstate->hj_NullOuterTupleSlot =
698  ExecInitNullTupleSlot(estate, outerDesc, &TTSOpsVirtual);
699  break;
700  case JOIN_FULL:
701  hjstate->hj_NullOuterTupleSlot =
702  ExecInitNullTupleSlot(estate, outerDesc, &TTSOpsVirtual);
703  hjstate->hj_NullInnerTupleSlot =
704  ExecInitNullTupleSlot(estate, innerDesc, &TTSOpsVirtual);
705  break;
706  default:
707  elog(ERROR, "unrecognized join type: %d",
708  (int) node->join.jointype);
709  }
710 
711  /*
712  * now for some voodoo. our temporary tuple slot is actually the result
713  * tuple slot of the Hash node (which is our inner plan). we can do this
714  * because Hash nodes don't return tuples via ExecProcNode() -- instead
715  * the hash join node uses ExecScanHashBucket() to get at the contents of
716  * the hash table. -cim 6/9/91
717  */
718  {
719  HashState *hashstate = (HashState *) innerPlanState(hjstate);
720  TupleTableSlot *slot = hashstate->ps.ps_ResultTupleSlot;
721 
722  hjstate->hj_HashTupleSlot = slot;
723  }
724 
725  /*
726  * initialize child expressions
727  */
728  hjstate->js.ps.qual =
729  ExecInitQual(node->join.plan.qual, (PlanState *) hjstate);
730  hjstate->js.joinqual =
731  ExecInitQual(node->join.joinqual, (PlanState *) hjstate);
732  hjstate->hashclauses =
733  ExecInitQual(node->hashclauses, (PlanState *) hjstate);
734 
735  /*
736  * initialize hash-specific info
737  */
738  hjstate->hj_HashTable = NULL;
739  hjstate->hj_FirstOuterTupleSlot = NULL;
740 
741  hjstate->hj_CurHashValue = 0;
742  hjstate->hj_CurBucketNo = 0;
744  hjstate->hj_CurTuple = NULL;
745 
746  hjstate->hj_OuterHashKeys = ExecInitExprList(node->hashkeys,
747  (PlanState *) hjstate);
748  hjstate->hj_HashOperators = node->hashoperators;
749  hjstate->hj_Collations = node->hashcollations;
750 
751  hjstate->hj_JoinState = HJ_BUILD_HASHTABLE;
752  hjstate->hj_MatchedOuter = false;
753  hjstate->hj_OuterNotEmpty = false;
754 
755  return hjstate;
756 }
#define ERROR
Definition: elog.h:35
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:319
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:210
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:142
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
TupleTableSlot * ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1847
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1831
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1799
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:491
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Definition: execUtils.c:500
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:481
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:536
#define EXEC_FLAG_BACKWARD
Definition: executor.h:58
#define EXEC_FLAG_MARK
Definition: executor.h:59
#define INVALID_SKEW_BUCKET_NO
Definition: hashjoin.h:109
Assert(fmt[strlen(fmt) - 1] !='\n')
static TupleTableSlot * ExecHashJoin(PlanState *pstate)
Definition: nodeHashjoin.c:585
#define HJ_BUILD_HASHTABLE
Definition: nodeHashjoin.c:124
#define makeNode(_type_)
Definition: nodes.h:159
@ JOIN_SEMI
Definition: nodes.h:301
@ JOIN_FULL
Definition: nodes.h:289
@ JOIN_INNER
Definition: nodes.h:287
@ JOIN_RIGHT
Definition: nodes.h:290
@ JOIN_LEFT
Definition: nodes.h:288
@ JOIN_ANTI
Definition: nodes.h:302
#define innerPlan(node)
Definition: plannodes.h:179
#define outerPlan(node)
Definition: plannodes.h:180
HashJoinTuple hj_CurTuple
Definition: execnodes.h:2088
int hj_CurSkewBucketNo
Definition: execnodes.h:2087
List * hj_OuterHashKeys
Definition: execnodes.h:2081
TupleTableSlot * hj_NullOuterTupleSlot
Definition: execnodes.h:2091
bool hj_OuterNotEmpty
Definition: execnodes.h:2096
TupleTableSlot * hj_NullInnerTupleSlot
Definition: execnodes.h:2092
List * hj_HashOperators
Definition: execnodes.h:2082
ExprState * hashclauses
Definition: execnodes.h:2080
TupleTableSlot * hj_FirstOuterTupleSlot
Definition: execnodes.h:2093
bool hj_MatchedOuter
Definition: execnodes.h:2095
uint32 hj_CurHashValue
Definition: execnodes.h:2085
List * hj_Collations
Definition: execnodes.h:2083
int hj_CurBucketNo
Definition: execnodes.h:2086
List * hashcollations
Definition: plannodes.h:858
List * hashclauses
Definition: plannodes.h:856
List * hashoperators
Definition: plannodes.h:857
Join join
Definition: plannodes.h:855
List * hashkeys
Definition: plannodes.h:864
PlanState ps
Definition: execnodes.h:2635
JoinType jointype
Definition: execnodes.h:1978
ExprState * joinqual
Definition: execnodes.h:1981
bool single_match
Definition: execnodes.h:1979
List * joinqual
Definition: plannodes.h:784
JoinType jointype
Definition: plannodes.h:782
bool inner_unique
Definition: plannodes.h:783
ExprState * qual
Definition: execnodes.h:1045
Plan * plan
Definition: execnodes.h:1024
EState * state
Definition: execnodes.h:1026
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1030

References Assert(), elog(), ERROR, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignProjectionInfo(), ExecGetResultSlotOps(), ExecGetResultType(), ExecHashJoin(), ExecInitExprList(), ExecInitExtraTupleSlot(), ExecInitNode(), ExecInitNullTupleSlot(), ExecInitQual(), ExecInitResultTupleSlotTL(), PlanState::ExecProcNode, HashJoinState::hashclauses, HashJoin::hashclauses, HashJoin::hashcollations, HashJoin::hashkeys, HashJoin::hashoperators, HJ_BUILD_HASHTABLE, HashJoinState::hj_Collations, HashJoinState::hj_CurBucketNo, HashJoinState::hj_CurHashValue, HashJoinState::hj_CurSkewBucketNo, HashJoinState::hj_CurTuple, HashJoinState::hj_FirstOuterTupleSlot, HashJoinState::hj_HashOperators, HashJoinState::hj_HashTable, HashJoinState::hj_HashTupleSlot, HashJoinState::hj_JoinState, HashJoinState::hj_MatchedOuter, HashJoinState::hj_NullInnerTupleSlot, HashJoinState::hj_NullOuterTupleSlot, HashJoinState::hj_OuterHashKeys, HashJoinState::hj_OuterNotEmpty, HashJoinState::hj_OuterTupleSlot, Join::inner_unique, innerPlan, innerPlanState, INVALID_SKEW_BUCKET_NO, HashJoin::join, JOIN_ANTI, JOIN_FULL, JOIN_INNER, JOIN_LEFT, JOIN_RIGHT, JOIN_SEMI, JoinState::joinqual, Join::joinqual, JoinState::jointype, Join::jointype, HashJoinState::js, makeNode, outerPlan, outerPlanState, PlanState::plan, JoinState::ps, HashState::ps, PlanState::ps_ResultTupleSlot, PlanState::qual, JoinState::single_match, PlanState::state, and TTSOpsVirtual.

Referenced by ExecInitNode().

◆ ExecReScanHashJoin()

void ExecReScanHashJoin ( HashJoinState node)

Definition at line 1291 of file nodeHashjoin.c.

1292 {
1295 
1296  /*
1297  * In a multi-batch join, we currently have to do rescans the hard way,
1298  * primarily because batch temp files may have already been released. But
1299  * if it's a single-batch join, and there is no parameter change for the
1300  * inner subnode, then we can just re-use the existing hash table without
1301  * rebuilding it.
1302  */
1303  if (node->hj_HashTable != NULL)
1304  {
1305  if (node->hj_HashTable->nbatch == 1 &&
1306  innerPlan->chgParam == NULL)
1307  {
1308  /*
1309  * Okay to reuse the hash table; needn't rescan inner, either.
1310  *
1311  * However, if it's a right/full join, we'd better reset the
1312  * inner-tuple match flags contained in the table.
1313  */
1314  if (HJ_FILL_INNER(node))
1316 
1317  /*
1318  * Also, we need to reset our state about the emptiness of the
1319  * outer relation, so that the new scan of the outer will update
1320  * it correctly if it turns out to be empty this time. (There's no
1321  * harm in clearing it now because ExecHashJoin won't need the
1322  * info. In the other cases, where the hash table doesn't exist
1323  * or we are destroying it, we leave this state alone because
1324  * ExecHashJoin will need it the first time through.)
1325  */
1326  node->hj_OuterNotEmpty = false;
1327 
1328  /* ExecHashJoin can skip the BUILD_HASHTABLE step */
1330  }
1331  else
1332  {
1333  /* must destroy and rebuild hash table */
1334  HashState *hashNode = castNode(HashState, innerPlan);
1335 
1336  Assert(hashNode->hashtable == node->hj_HashTable);
1337  /* accumulate stats from old hash table, if wanted */
1338  /* (this should match ExecShutdownHash) */
1339  if (hashNode->ps.instrument && !hashNode->hinstrument)
1340  hashNode->hinstrument = (HashInstrumentation *)
1341  palloc0(sizeof(HashInstrumentation));
1342  if (hashNode->hinstrument)
1344  hashNode->hashtable);
1345  /* for safety, be sure to clear child plan node's pointer too */
1346  hashNode->hashtable = NULL;
1347 
1349  node->hj_HashTable = NULL;
1351 
1352  /*
1353  * if chgParam of subnode is not null then plan will be re-scanned
1354  * by first ExecProcNode.
1355  */
1356  if (innerPlan->chgParam == NULL)
1358  }
1359  }
1360 
1361  /* Always reset intra-tuple state */
1362  node->hj_CurHashValue = 0;
1363  node->hj_CurBucketNo = 0;
1365  node->hj_CurTuple = NULL;
1366 
1367  node->hj_MatchedOuter = false;
1368  node->hj_FirstOuterTupleSlot = NULL;
1369 
1370  /*
1371  * if chgParam of subnode is not null then plan will be re-scanned by
1372  * first ExecProcNode.
1373  */
1374  if (outerPlan->chgParam == NULL)
1376 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:78
void * palloc0(Size size)
Definition: mcxt.c:1230
void ExecHashAccumInstrumentation(HashInstrumentation *instrument, HashJoinTable hashtable)
Definition: nodeHash.c:2697
void ExecHashTableResetMatchFlags(HashJoinTable hashtable)
Definition: nodeHash.c:2175
#define HJ_FILL_INNER(hjstate)
Definition: nodeHashjoin.c:134
#define HJ_NEED_NEW_OUTER
Definition: nodeHashjoin.c:125
#define castNode(_type_, nodeptr)
Definition: nodes.h:180
HashJoinTable hashtable
Definition: execnodes.h:2636
HashInstrumentation * hinstrument
Definition: execnodes.h:2652
Instrumentation * instrument
Definition: execnodes.h:1034

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, HashJoinTableData::nbatch, outerPlan, outerPlanState, palloc0(), and HashState::ps.

Referenced by ExecReScan().

◆ ExecShutdownHashJoin()

void ExecShutdownHashJoin ( HashJoinState node)

Definition at line 1379 of file nodeHashjoin.c.

1380 {
1381  if (node->hj_HashTable)
1382  {
1383  /*
1384  * Detach from shared state before DSM memory goes away. This makes
1385  * sure that we don't have any pointers into DSM memory by the time
1386  * ExecEndHashJoin runs.
1387  */
1390  }
1391 }

References ExecHashTableDetach(), ExecHashTableDetachBatch(), and HashJoinState::hj_HashTable.

Referenced by ExecShutdownNode_walker().