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)