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)
Functions
static TupleTableSlot * ExecHashJoinOuterGetTuple (PlanState *outerNode, HashJoinState *hjstate, uint32 *hashvalue)
static TupleTableSlot * ExecParallelHashJoinOuterGetTuple (PlanState *outerNode, HashJoinState *hjstate, uint32 *hashvalue)
static TupleTableSlot * ExecHashJoinGetSavedTuple (HashJoinState *hjstate, BufFile *file, uint32 *hashvalue, TupleTableSlot *tupleSlot)
static bool ExecHashJoinNewBatch (HashJoinState *hjstate)
static bool ExecParallelHashJoinNewBatch (HashJoinState *hjstate)
static void ExecParallelHashJoinPartitionOuter (HashJoinState *hjstate)
static pg_attribute_always_inline TupleTableSlot * ExecHashJoinImpl (PlanState *pstate, bool parallel)
static TupleTableSlot * ExecHashJoin (PlanState *pstate)
static TupleTableSlot * ExecParallelHashJoin (PlanState *pstate)
HashJoinState * ExecInitHashJoin (HashJoin *node, EState *estate, int eflags)
void ExecEndHashJoin (HashJoinState *node)
void ExecHashJoinSaveTuple (MinimalTuple tuple, uint32 hashvalue, BufFile **fileptr, HashJoinTable hashtable)
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)

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,

880 &hjstate->js.ps,

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

ExecShutdownHashJoin()