180 #define HJ_BUILD_HASHTABLE 1
181 #define HJ_NEED_NEW_OUTER 2
182 #define HJ_SCAN_BUCKET 3
183 #define HJ_FILL_OUTER_TUPLE 4
184 #define HJ_FILL_INNER_TUPLES 5
185 #define HJ_NEED_NEW_BATCH 6
188 #define HJ_FILL_OUTER(hjstate) ((hjstate)->hj_NullInnerTupleSlot != NULL)
190 #define HJ_FILL_INNER(hjstate) ((hjstate)->hj_NullOuterTupleSlot != NULL)
272 Assert(hashtable == NULL);
394 if (hashtable->
nbatch > 1)
397 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
481 if (batchno != hashtable->
curbatch &&
492 Assert(parallel_state == NULL);
554 if (joinqual == NULL ||
ExecQual(joinqual, econtext))
590 if (otherqual == NULL ||
ExecQual(otherqual, econtext))
617 if (otherqual == NULL ||
ExecQual(otherqual, econtext))
646 if (otherqual == NULL ||
ExecQual(otherqual, econtext))
671 elog(
ERROR,
"unrecognized hashjoin state: %d",
808 elog(
ERROR,
"unrecognized join type: %d",
823 Oid *outer_hashfuncid;
824 Oid *inner_hashfuncid;
857 &outer_hashfuncid[
i],
858 &inner_hashfuncid[
i]))
860 "could not find hash function for hash operator %u",
908 pfree(outer_hashfuncid);
909 pfree(inner_hashfuncid);
1031 else if (curbatch < hashtable->nbatch)
1063 int curbatch = hashtable->
curbatch;
1071 if (curbatch == 0 && hashtable->
nbatch == 1)
1099 else if (curbatch < hashtable->nbatch)
1139 nbatch = hashtable->
nbatch;
1186 while (curbatch < nbatch &&
1213 if (curbatch >= nbatch)
1225 if (innerFile != NULL)
1230 errmsg(
"could not rewind hash-join temporary file")));
1260 errmsg(
"could not rewind hash-join temporary file")));
1293 batchno = start_batchno =
1314 WAIT_EVENT_HASH_BATCH_ELECT))
1321 WAIT_EVENT_HASH_BATCH_ALLOCATE);
1341 WAIT_EVENT_HASH_BATCH_LOAD);
1391 elog(
ERROR,
"unexpected batch phase %d",
1395 batchno = (batchno + 1) % hashtable->
nbatch;
1396 }
while (batchno != start_batchno);
1482 *hashvalue = header[0];
1484 tuple->
t_len = header[1];
1486 (
char *) tuple +
sizeof(
uint32),
1487 header[1] -
sizeof(
uint32));
1634 &hashvalue, mintup);
1657 int plan_node_id =
state->js.ps.plan->plan_node_id;
1665 if (pcxt->
seg == NULL)
1715 int plan_node_id =
state->js.ps.plan->plan_node_id;
1732 if (
state->hj_HashTable != NULL)
1750 int plan_node_id =
state->js.ps.plan->plan_node_id;
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
int BarrierAttach(Barrier *barrier)
void BarrierInit(Barrier *barrier, int participants)
int BarrierPhase(Barrier *barrier)
bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info)
bool BarrierDetach(Barrier *barrier)
void BufFileReadExact(BufFile *file, void *ptr, size_t size)
BufFile * BufFileCreateTemp(bool interXact)
void BufFileWrite(BufFile *file, const void *ptr, size_t size)
size_t BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK)
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
void BufFileClose(BufFile *file)
#define Assert(condition)
#define pg_attribute_always_inline
#define OidIsValid(objectId)
#define InvalidDsaPointer
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ExecReScan(PlanState *node)
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)
void ExecEndNode(PlanState *node)
Node * MultiExecProcNode(PlanState *node)
void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
const TupleTableSlotOps TTSOpsVirtual
TupleTableSlot * ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, const TupleTableSlotOps *tts_ops)
void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot, bool *shouldFree)
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
TupleDesc ExecGetResultType(PlanState *planstate)
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
#define InstrCountFiltered1(node, delta)
#define outerPlanState(node)
#define InstrCountFiltered2(node, delta)
#define innerPlanState(node)
#define EXEC_FLAG_BACKWARD
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
#define ResetExprContext(econtext)
static bool ExecQual(ExprState *state, ExprContext *econtext)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
static TupleTableSlot * ExecProcNode(PlanState *node)
#define palloc_array(type, count)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define PHJ_BUILD_HASH_OUTER
#define HJTUPLE_MINTUPLE(hjtup)
#define PHJ_BATCH_ALLOCATE
#define INVALID_SKEW_BUCKET_NO
void heap_free_minimal_tuple(MinimalTuple mtup)
MinimalTupleData * MinimalTuple
#define HeapTupleHeaderHasMatch(tup)
#define HeapTupleHeaderSetMatch(tup)
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
void LWLockInitialize(LWLock *lock, int tranche_id)
@ LWTRANCHE_PARALLEL_HASH_JOIN
void pfree(void *pointer)
void * palloc0(Size size)
#define CHECK_FOR_INTERRUPTS()
void ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
void ExecHashTableReset(HashJoinTable hashtable)
bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext)
void ExecHashAccumInstrumentation(HashInstrumentation *instrument, HashJoinTable hashtable)
void ExecHashTableDetachBatch(HashJoinTable hashtable)
void ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
void ExecHashTableDetach(HashJoinTable hashtable)
bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
void ExecHashTableDestroy(HashJoinTable hashtable)
HashJoinTable ExecHashTableCreate(HashState *state)
int ExecHashGetSkewBucket(HashJoinTable hashtable, uint32 hashvalue)
bool ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
void ExecHashTableResetMatchFlags(HashJoinTable hashtable)
void ExecHashTableInsert(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue)
void ExecHashGetBucketAndBatch(HashJoinTable hashtable, uint32 hashvalue, int *bucketno, int *batchno)
void ExecParallelHashTableAlloc(HashJoinTable hashtable, int batchno)
bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue)
bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext)
#define HJ_NEED_NEW_BATCH
static pg_attribute_always_inline TupleTableSlot * ExecHashJoinImpl(PlanState *pstate, bool parallel)
void ExecHashJoinInitializeDSM(HashJoinState *state, ParallelContext *pcxt)
HashJoinState * ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
void ExecEndHashJoin(HashJoinState *node)
#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)
static TupleTableSlot * ExecHashJoinGetSavedTuple(HashJoinState *hjstate, BufFile *file, uint32 *hashvalue, TupleTableSlot *tupleSlot)
static TupleTableSlot * ExecParallelHashJoin(PlanState *pstate)
void ExecShutdownHashJoin(HashJoinState *node)
#define HJ_FILL_INNER_TUPLES
void ExecHashJoinEstimate(HashJoinState *state, ParallelContext *pcxt)
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 TupleTableSlot * ExecHashJoin(PlanState *pstate)
void ExecReScanHashJoin(HashJoinState *node)
void ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *pcxt)
void ExecHashJoinInitializeWorker(HashJoinState *state, ParallelWorkerContext *pwcxt)
static void ExecParallelHashJoinPartitionOuter(HashJoinState *hjstate)
#define HJ_BUILD_HASHTABLE
#define castNode(_type_, nodeptr)
static int list_length(const List *l)
#define foreach_current_index(var_or_cell)
static uint32 DatumGetUInt32(Datum X)
MemoryContextSwitchTo(old_ctx)
static unsigned hash(unsigned *uv, int n)
void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
void SharedFileSetDeleteAll(SharedFileSet *fileset)
void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
MinimalTuple sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
void sts_end_write(SharedTuplestoreAccessor *accessor)
void sts_end_parallel_scan(SharedTuplestoreAccessor *accessor)
void sts_puttuple(SharedTuplestoreAccessor *accessor, void *meta_data, MinimalTuple tuple)
void sts_begin_parallel_scan(SharedTuplestoreAccessor *accessor)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
TupleTableSlot * ecxt_innertuple
TupleTableSlot * ecxt_outertuple
HashJoinTuple hj_CurTuple
TupleTableSlot * hj_NullOuterTupleSlot
TupleTableSlot * hj_OuterTupleSlot
TupleTableSlot * hj_NullInnerTupleSlot
TupleTableSlot * hj_FirstOuterTupleSlot
HashJoinTable hj_HashTable
TupleTableSlot * hj_HashTupleSlot
ParallelHashJoinBatchAccessor * batches
ParallelHashJoinState * parallel_state
BufFile ** innerBatchFile
BufFile ** outerBatchFile
HashSkewBucket ** skewBucket
struct ParallelHashJoinState * parallel_state
FmgrInfo * skew_hashfunction
HashInstrumentation * hinstrument
shm_toc_estimator estimator
SharedTuplestoreAccessor * outer_tuples
ParallelHashJoinBatch * shared
SharedTuplestoreAccessor * inner_tuples
Barrier grow_batches_barrier
dsa_pointer chunk_work_queue
Barrier grow_buckets_barrier
ParallelHashGrowth growth
pg_atomic_uint32 distributor
const TupleTableSlotOps * resultops
Instrumentation * instrument
TupleDesc ps_ResultTupleDesc
ExprContext * ps_ExprContext
TupleTableSlot * ps_ResultTupleSlot
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)