PostgreSQL Source Code: src/backend/executor/execGrouping.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

22

29

30

31

32

33

34

35#define SH_PREFIX tuplehash

36#define SH_ELEMENT_TYPE TupleHashEntryData

37#define SH_KEY_TYPE MinimalTuple

38#define SH_KEY firstTuple

39#define SH_HASH_KEY(tb, key) TupleHashTableHash_internal(tb, key)

40#define SH_EQUAL(tb, a, b) TupleHashTableMatch(tb, a, b) == 0

41#define SH_SCOPE extern

42#define SH_STORE_HASH

43#define SH_GET_HASH(tb, a) a->hash

44#define SH_DEFINE

46

47

48

49

50

51

52

53

54

55

56

59 int numCols,

61 const Oid *eqOperators,

62 const Oid *collations,

64{

65 Oid *eqFunctions;

66 int i;

68

69 if (numCols == 0)

70 return NULL;

71

72 eqFunctions = (Oid *) palloc(numCols * sizeof(Oid));

73

74

75 for (i = 0; i < numCols; i++)

77

78

80 numCols, keyColIdx, eqFunctions, collations,

81 parent);

82

83 return expr;

84}

85

86

87

88

89

90

91

92

93

94

95

96void

98 const Oid *eqOperators,

99 Oid **eqFuncOids,

101{

102 int i;

103

104 *eqFuncOids = (Oid *) palloc(numCols * sizeof(Oid));

106

107 for (i = 0; i < numCols; i++)

108 {

109 Oid eq_opr = eqOperators[i];

110 Oid eq_function;

111 Oid left_hash_function;

112 Oid right_hash_function;

113

116 &left_hash_function, &right_hash_function))

117 elog(ERROR, "could not find hash function for hash operator %u",

118 eq_opr);

119

120 Assert(left_hash_function == right_hash_function);

121 (*eqFuncOids)[i] = eq_function;

122 fmgr_info(right_hash_function, &(*hashFunctions)[i]);

123 }

124}

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

164 int numCols,

166 const Oid *eqfuncoids,

168 Oid *collations,

169 long nbuckets,

170 Size additionalsize,

174 bool use_variable_hash_iv)

175{

177 Size entrysize;

178 Size hash_mem_limit;

180 bool allow_jit;

182

183 Assert(nbuckets > 0);

184 additionalsize = MAXALIGN(additionalsize);

186

187

189 if (nbuckets > hash_mem_limit)

190 nbuckets = hash_mem_limit;

191

193

195

196 hashtable->numCols = numCols;

197 hashtable->keyColIdx = keyColIdx;

199 hashtable->tablecxt = tablecxt;

200 hashtable->tempcxt = tempcxt;

202 hashtable->tableslot = NULL;

206

207

208

209

210

211

212

213

214

215 if (use_variable_hash_iv)

217

218 hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable);

219

220

221

222

223

226

227

228

229

230

231

232

233

234

235 allow_jit = (metacxt != tablecxt);

236

237

239 inputOps,

240 hashfunctions,

241 collations,

242 numCols,

243 keyColIdx,

244 allow_jit ? parent : NULL,

245 hash_iv);

246

247

249 inputOps,

251 numCols,

252 keyColIdx, eqfuncoids, collations,

253 allow_jit ? parent : NULL);

254

255

256

257

258

259

260

262

264

265 return hashtable;

266}

267

268

269

270

271

272

273void

275{

276 tuplehash_reset(hashtable->hashtab);

277}

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

297{

301

302

304

305

309

312

313 if (hash != NULL)

314 *hash = local_hash;

315

316 Assert(entry == NULL || entry->hash == local_hash);

317

319

320 return entry;

321}

322

323

324

325

328{

331

334

335

337

339

341

343}

344

345

346

347

348

352{

355

356

358

359

363

366

368

369 return entry;

370}

371

372

373

374

375

376

377

378

379

380

385{

389

390

392

393

397

398

399 key = NULL;

400 entry = tuplehash_lookup(hashtable->hashtab, key);

402

403 return entry;

404}

405

406

407

408

409

410

411

412

413

417{

421 bool isnull;

422

423 if (tuple == NULL)

424 {

425

429 &isnull));

430 }

431 else

432 {

433

434

435

436

437

438

443 &isnull));

444 }

445

446

447

448

449

450

452}

453

454

455

456

457

458

459

460

461

465{

467 bool found;

469

470 key = NULL;

471

472 if (isnew)

473 {

474 entry = tuplehash_insert_hash(hashtable->hashtab, key, hash, &found);

475

476 if (found)

477 {

478

479 *isnew = false;

480 }

481 else

482 {

483

484 *isnew = true;

485

487

488

489

490

491

492

493

494

495

496

497

500 }

501 }

502 else

503 {

504 entry = tuplehash_lookup_hash(hashtable->hashtab, key, hash);

505 }

506

507 return entry;

508}

509

510

511

512

513static int

515{

520

521

522

523

524

525

526

527 Assert(tuple1 != NULL);

530 Assert(tuple2 == NULL);

532

533

534 econtext->ecxt_innertuple = slot2;

535 econtext->ecxt_outertuple = slot1;

537}

ExprState * ExecBuildHash32FromAttrs(TupleDesc desc, const TupleTableSlotOps *ops, FmgrInfo *hashfunctions, Oid *collations, int numCols, AttrNumber *keyColIdx, PlanState *parent, uint32 init_value)

ExprState * ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx, const Oid *eqfunctions, const Oid *collations, PlanState *parent)

ExprState * execTuplesMatchPrepare(TupleDesc desc, int numCols, const AttrNumber *keyColIdx, const Oid *eqOperators, const Oid *collations, PlanState *parent)

void execTuplesHashPrepare(int numCols, const Oid *eqOperators, Oid **eqFuncOids, FmgrInfo **hashFunctions)

TupleHashEntry LookupTupleHashEntryHash(TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew, uint32 hash)

TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew, uint32 *hash)

static uint32 TupleHashTableHash_internal(struct tuplehash_hash *tb, const MinimalTuple tuple)

uint32 TupleHashTableHash(TupleHashTable hashtable, TupleTableSlot *slot)

TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot, ExprState *eqcomp, ExprState *hashexpr)

static int TupleHashTableMatch(struct tuplehash_hash *tb, const MinimalTuple tuple1, const MinimalTuple tuple2)

TupleHashTable BuildTupleHashTable(PlanState *parent, TupleDesc inputDesc, const TupleTableSlotOps *inputOps, int numCols, AttrNumber *keyColIdx, const Oid *eqfuncoids, FmgrInfo *hashfunctions, Oid *collations, long nbuckets, Size additionalsize, MemoryContext metacxt, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)

void ResetTupleHashTable(TupleHashTable hashtable)

static TupleHashEntry LookupTupleHashEntry_internal(TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew, uint32 hash)

TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)

TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)

const TupleTableSlotOps TTSOpsMinimalTuple

ExprContext * CreateStandaloneExprContext(void)

struct TupleHashTableData * TupleHashTable

struct TupleHashEntryData TupleHashEntryData

static bool ExecQualAndReset(ExprState *state, ExprContext *econtext)

static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)

void fmgr_info(Oid functionId, FmgrInfo *finfo)

static uint32 murmurhash32(uint32 data)

Assert(PointerIsAligned(start, uint64))

if(TABLE==NULL||TABLE_index==NULL)

RegProcedure get_opcode(Oid opno)

bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)

size_t get_hash_memory_limit(void)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

static uint32 DatumGetUInt32(Datum X)

static unsigned hash(unsigned *uv, int n)

TupleTableSlot * ecxt_innertuple

ExprState * tab_hash_expr

TupleTableSlot * tableslot

ExprContext * exprcontext

TupleTableSlot * inputslot

TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)

static MinimalTuple ExecCopySlotMinimalTupleExtra(TupleTableSlot *slot, Size extra)