PostgreSQL Source Code interpretation (182)-query # 98 (aggregate function # 3-ExecAgg)
Additional;}} / * * Find or create a hashtable entry for the tuple group containing the current * tuple (already set in tmpcontext's outertuple slot), in the current grouping * set (which the caller must have selected-note that initialize_aggregate * depends on this). * retrieve or create a hash table entry for the group containing the current tuple (outertuple slot has been set in the context of tmpcontext), * set it in the current grouping set (the caller has completed the selection-note that initialize_aggregate depends on it) * * When called, CurrentMemoryContext should be the per-query context. * once the call is completed, CurrentMemoryContext should be the per-query context * / static TupleHashEntryData * lookup_hash_entry (AggState * aggstate) {/ / input tuple TupleTableSlot * inputslot = aggstate- > tmpcontext- > ecxt_outertuple; / / perhash AggStatePerHash perhash = & aggstate- > perhash [aggstate-> current_set]; / / hashslot TupleTableSlot * hashslot = perhash- > hashslot; / / entry entry TupleHashEntryData * entry; / / variable bool isnew; int i / * transfer just the needed columns into hashslot * / / convert the required columns to hashslot slot_getsomeattrs (inputslot, perhash- > largestGrpColIdx); ExecClearTuple (hashslot); for (I = 0; I
< perhash->NumhashGrpCols; iTunes +) {/ / traverse grouping column / / column number int varNumber = perhash- > hashGrpColIdxInput [I]-1; / / assign hashslot- > tts_ values [I] = inputslot- > tts_ values [varNumber]; hashslot- > tts_ isnull [I] = inputslot- > tts_ isnull [varNumber];} / store virtual tuple ExecStoreVirtualTuple (hashslot) / * find or create the hashtable entry using the filtered tuple * / / use filtered tuples to retrieve or create hash table entries entry = LookupTupleHashEntry (perhash- > hashtable, hashslot, & isnew); if (isnew) {/ / new entry AggStatePerGroup pergroup; int transno / / allocate memory pergroup = (AggStatePerGroup) MemoryContextAlloc (perhash- > hashtable- > tablecxt, sizeof (AggStatePerGroupData) * aggstate- > numtrans); entry- > additional = pergroup; / * * Initialize aggregates for new tuple group, lookup_hash_entries () * already has selected the relevant grouping set. * initialize the aggregation operation for the new tuple group, and lookup_hash_entries () has selected the corresponding grouping set * / for (transno = 0; transno)
< aggstate-> < numHashes; setno++)(gdb) p *pergroup$6 = (AggStatePerGroup) 0x0(gdb) n1515 select_current_set(aggstate, setno, true);(gdb) stepselect_current_set (aggstate=0x1f895a0, setno=0, is_hash=true) at nodeAgg.c:306306 if (is_hash)(gdb) n307 aggstate->Curaggcontext = aggstate- > hashcontext; (gdb) 311 aggstate- > current_set = setno; (gdb) 312} (gdb) lookup_hash_entries (aggstate=0x1f895a0) at nodeAgg.c:15161516 pergroup [setno] = lookup_hash_entry (aggstate)-> additional; (gdb)
Lookup_hash_entry- > calls lookup_hash_entry, which retrieves or creates hash table entries for the group that contains the current tuple.
(gdb) steplookup_hash_entry (aggstate=0x1f895a0) at nodeAgg.c:14511451 TupleTableSlot * inputslot = aggstate- > tmpcontext- > ecxt_outertuple; (gdb) n1452 AggStatePerHash perhash = & aggstate- > Perhash [aggstate-> current_set]; (gdb) p aggstate- > current_set$7 = 0 (gdb) n1453 TupleTableSlot * hashslot = perhash- > hashslot (gdb) p * perhash$8 = {hashtable = 0x1f9fc98, hashiter = {cur = 0, end = 0, done = false}, hashslot = 0x1f8b198, hashfunctions = 0x1f8b230, eqfuncoids = 0x1f9fc50, numCols = 1, numhashGrpCols = 1, largestGrpColIdx = 1, hashGrpColIdxInput = 0x1f9fbb0, hashGrpColIdxHash = 0x1f9fbd0, aggnode = 0x1f7b1e0} (gdb) n1459 slot_getsomeattrs (inputslot, perhash- > largestGrpColIdx); (gdb) 1460 ExecClearTuple (hashslot) (gdb) p * perhash$9 = {hashtable = 0x1f9fc98, hashiter = {cur = 0, end = 0, done = false}, hashslot = 0x1f8b198, hashfunctions = 0x1f8b230, eqfuncoids = 0x1f9fc50, numCols = 1, numhashGrpCols = 1, largestGrpColIdx = 1, hashGrpColIdxInput = 0x1f9fbb0, hashGrpColIdxHash = 0x1f9fbd0, aggnode = 0x1f7b1e0} (gdb) p * perhash- > hashslot$10 = {type = T_TupleTableSlot, tts_isempty = true, tts_shouldFree = false, tts_shouldFreeMin = false, tts_slow = tts_slow, false = false, tts_tuple = tts_tuple, tts_tuple = tts_tuple, tts_tuple = 0 Tts_nvalid = 0, tts_values = 0x1f8b1f8, tts_isnull = 0x1f8b200, tts_mintuple = 0x0, tts_minhdr = {t_len = 0, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 0}, t_tableOid = 0, t_data = 0x0}, tts_off = 0, tts_fixedTupleDescriptor = true} (gdb) p * perhash- > hashfunctions$11 = {fn_addr = 0x4c8a31, fn_oid = 400,fn_nargs = 1, fn_strict = true Fn_retset = false, fn_stats = 2'\ 002, fn_extra = 0x0, fn_mcxt = 0x1f89270, fn_expr = 0x0} (gdb) p * perhash- > eqfuncoids$12 = 67 (gdb) p * perhash- > hashGrpColIdxInput$13 = 1 (gdb) p * perhash- > hashGrpColIdxHash$14 = 1 (gdb) p * perhash- > aggnode$15 = {plan = {type = T_Agg, startup_cost = 13677, total_cost = 13677.0625, plan_rows = 5, plan_width = 45, parallel_aware = false, parallel_safe = false, plan_node_id = 0 Targetlist = 0x1f84108, qual = 0x0, lefttree = 0x1f83bc8, righttree = 0x0, initPlan = 0x0, extParam = 0x0, allParam = 0x0}, aggstrategy = AGG_HASHED, aggsplit = AGGSPLIT_SIMPLE, numCols = 1, grpColIdx = 0x1f83eb8, grpOperators = 0x1f83e98, numGroups = 5, aggParams = 0x0, groupingSets = 0x0, chain = 0x0} (gdb)
Lookup_hash_entry- > traverses the grouping key (here is the bh column)
(gdb) n1462 for (I = 0; I
< perhash->NumhashGrpCols; iTunes +) (gdb) 1464 int varNumber = perhash- > hashGrpColIdxInput [I]-1; (gdb) 1466 hashslot- > tts_ values [I] = inputslot- > tts_ values [varNumber]; (gdb) p varNumber$16 = 0 (gdb) n1467 hashslot- > tts_ isnull [I] = inputslot- > tts_isnull [varNumber]; (gdb) 1462 for (I = 0; I
< perhash->NumhashGrpCols ITunes +) (gdb) p * hashslot$17 = {type = T_TupleTableSlot, tts_isempty = true, tts_shouldFree = false, tts_shouldFreeMin = false, tts_slow = false, tts_tuple = 0x0, tts_tupleDescriptor = 0x1f8b080, tts_mcxt = 0x1f89270, tts_buffer = 0, tts_nvalid = 0, tts_values = 0x1f8b1f8, tts_isnull = 0x1f8b200, tts_mintuple = 0x0, tts_minhdr = {t_len = 0, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0} Ip_posid = 0}, t_tableOid = 0, t_data = 0x0}, tts_off = 0, tts_fixedTupleDescriptor = true} (gdb) p * hashslot- > tts_values [0] $18 = 811222795 (gdb)
Lookup_hash_entry- > calls LookupTupleHashEntry, which uses filtered tuples to retrieve or create hash table entries
(gdb) stepLookupTupleHashEntry (hashtable=0x1f9fc98, slot=0x1f8b198, isnew=0x7fff7f065e17) at execGrouping.c:290290 oldContext = MemoryContextSwitchTo (hashtable- > tempcxt) (gdb) p * hashtable$19 = {hashtab = 0x1f9fd30, numCols = 1, keyColIdx = 0x1f9fbd0, tab_hash_funcs = 0x1f8b230, tab_eq_func = 0x1fa0050, tablecxt = 0x1f91370, tempcxt = 0x1f9d8e0, entrysize = 24, tableslot = 0x1f9ffb8, inputslot = 0x0, in_hash_funcs = 0x0, cur_eq_func = 0x0, hash_iv = 0, exprcontext = 0x1fa0970} (gdb) p * hashtable- > hashtab$20 = {size = 8, members = 0, sizemask = 7, grow_threshold = 7, data = 0x1f9fd88, 0x1f9fd88 = ctx Private_data = 0x1f9fc98} (gdb) p * hashtable- > keyColIdx$21 = 1 (gdb) p * hashtable- > tab_hash_funcs$22 = {fn_addr = 0x4c8a31, fn_oid = 400, fn_nargs = 1, fn_strict = true, fn_retset = false, fn_stats = 2'\ 002 hashtable-, fn_extra = 0x0, fn_mcxt = 0x1f89270, fn_expr = 0x0} (gdb) n293 hashtable- > inputslot = slot (gdb) 294 hashtable- > in_hash_funcs = hashtable- > tab_hash_funcs; (gdb) 295 hashtable- > cur_eq_func = hashtable- > tab_eq_func; (gdb) 297 key = NULL; / * flag to reference inputslot * / (gdb) 299 if (isnew) (gdb) 301 entry = tuplehash_insert (hashtable- > hashtab, key, & found) (gdb) steptuplehash_insert (tb=0x1f9fd30, key=0x0, found=0x7fff7f065dd7) at.. / src/include/lib/simplehash.h:490490 uint32 hash = SH_HASH_KEY (tb, key) (gdb) finishRun till exit from # 0 tuplehash_insert (tb=0x1f9fd30, key=0x0, found=0x7fff7f065dd7) at.. / src/include/lib/simplehash.h:4900x00000000006d3a1e in LookupTupleHashEntry (hashtable=0x1f9fc98, slot=0x1f8b198, isnew=0x7fff7f065e17) at execGrouping.c:301301 entry = tuplehash_insert (hashtable- > hashtab, key, & found); Value returned is $23 = (TupleHashEntryData *) 0x1f9fdb8 (gdb) n303 if (found) (gdb) p found$24 = false (gdb)
LookupTupleHashEntry- > insert a new entry and return entry
(gdb) n311 * isnew = true; (gdb) 313 entry- > additional = NULL; (gdb) 314 MemoryContextSwitchTo (hashtable- > tablecxt); (gdb) 316 entry- > firstTuple = ExecCopySlotMinimalTuple (slot); (gdb) 324 MemoryContextSwitchTo (oldContext); (gdb) 326 return entry; (gdb) 327}
Lookup_hash_entry- > back to lookup_hash_entry
(gdb) lookup_hash_entry (aggstate=0x1f895a0) at nodeAgg.c:14741474 if (isnew) (gdb)
Lookup_hash_entry- > allocate memory, set additional information for entries
(gdb) n1481 sizeof (AggStatePerGroupData) * aggstate- > numtrans); (gdb) p * entry$25 = {firstTuple = 0x1f91488, additional = 0x0, status = 1, hash = 443809650} (gdb) n1480 MemoryContextAlloc (perhash- > hashtable- > tablecxt, (gdb) 1479 pergroup = (AggStatePerGroup) (gdb) 1482 entry- > additional = pergroup; (gdb)
Lookup_hash_entry- > initializes the aggregation operation for the new tuple group, and lookup_hash_entries () has selected the corresponding grouping set (here are 3 aggregation columns)
1488 for (transno = 0; transno)
< aggstate->Numtrans; transno++) (gdb) p aggstate- > numtrans$26 = 3 (gdb) (gdb) n1490 AggStatePerTrans pertrans = & aggstate- > pertrans [transno]; (gdb) 1491 AggStatePerGroup pergroupstate = & pergroup [Transno] (gdb) p * pertrans$27 = {aggref = 0x1f84650, aggshared = false, numInputs = 1, numTransInputs = 1, transfn_oid = 768, serialfn_oid = 0, deserialfn_oid = 0, aggtranstype = 23, transfn = {fn_addr = 0x93e877, fn_oid = 768, fn_nargs = 2, fn_strict = true, fn_retset = false, fn_stats = 2'\ 002, fn_extra = 0x0, fn_mcxt = 0x1f89270, fn_expr = 0x1fa0b00}, serialfn = {fn_addr = 0x0, fn_oid = 0 Fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0'\ 000mm, fn_extra = 0x0, fn_mcxt = 0x0, fn_expr = 0x0}, deserialfn = {fn_addr = 0x0, fn_oid = 0, fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0'\ 000mm, fn_extra = 0x0, fn_mcxt = 0x0, fn_expr = 0x0}, aggCollation = 0, numSortCols = 0, numDistinctCols = 0, sortColIdx = 0x0 SortOperators = 0x0, sortCollations = 0x0, sortNullsFirst = 0x0, equalfnOne = {fn_addr = 0x0, fn_oid = 0, fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0'\ 000mm, fn_extra = 0x0, fn_mcxt = 0x0, fn_expr = 0x0}, equalfnMulti = 0x0, initValue = 0, initValueIsNull = true, inputtypeLen = 0, transtypeLen = 4, inputtypeByVal = false, transtypeByVal = true, sortslot = 0x0, uniqslot = uniqslot, 0x0 = 0x0, 0x0 = sortdesc, sortdesc = sortdesc Context = 0x1f895a0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {0}, argnull = {false}}, serialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = {0}, argnull = {false}}, deserialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, nargs = {0} Argnull = {false}} (gdb) n1493 initialize_aggregate (aggstate, pertrans, pergroupstate) (gdb) p * pergroupstate$28 = {transValue = 9187201950435737471, transValueIsNull = 127, noTransValue = 127} (gdb) n1488 for (transno = 0; transno)
< aggstate->Numtrans Transno++) (gdb) p * aggstate$29 = {ss = {ps = {type = T_AggState, plan = 0x1f7b1e0, state = 0x1f89388, ExecProcNode = 0x6ee438, ExecProcNodeReal = 0x6ee438, instrument = 0x0, worker_instrument = 0x0, worker_jit_instrument = 0x0, qual = 0x0, lefttree = 0x1f89b10, righttree = 0x0, initPlan = 0x0, subPlan = 0x0, chgParam = 0x0, ps_ResultTupleSlot = 0x1f8a710, ps_ExprContext = 0x0, ps_ResultTupleSlot = 0x1f8a710, ps_ExprContext = ps_ExprContext, 0x1f89a50 = 0x1f89a50, ps_ProjInfo = 0x1f8a850}, ps_ProjInfo = 0x1f8a850 Ss_ScanTupleSlot = 0x1f8a3b8}, aggs = 0x1f8ad60, numaggs = 3, numtrans = 3, aggstrategy = AGG_HASHED, aggsplit = AGGSPLIT_SIMPLE, phase = 0x1f8ae58, numphases = 1, current_phase = 0, peragg = 0x1f9f930, pertrans = 0x1f993f0, hashcontext = 0x1f89990, aggcontexts = 0x1f897b8, tmpcontext = 0x1f897d8, curaggcontext = 0x1f89990, curperagg = 0x0, curpertrans = 0x0, input_done = false, agg_done = false, projected_set =-1, current_set = 0, grouped_cols = grouped_cols, grouped_cols = grouped_cols, 0x0 = 1, 0x0 = Sort_in = 0x0, sort_out = 0x0, sort_slot = 0x0, pergroups = 0x0, grp_firstTuple = 0x0, table_filled = false, num_hashes = 1, perhash = 0x1f8aeb0, hash_pergroup = 0x1f9fb48, all_pergroups = 0x1f9fb48, combinedproj = 0x0} (gdb) n1490 AggStatePerTrans pertrans = & aggstate- > pertrans [transno] (gdb) 1491 AggStatePerGroup pergroupstate = & pergroup [Transno]; (gdb) 1493 initialize_aggregate (aggstate, pertrans, pergroupstate); (gdb) 1488 for (transno = 0; transno)
< aggstate->Numtrans; transno++) (gdb) 1490 AggStatePerTrans pertrans = & aggstate- > pertrans [transno]; (gdb) 1491 AggStatePerGroup pergroupstate = & pergroup [Transno]; (gdb) 1493 initialize_aggregate (aggstate, pertrans, pergroupstate); (gdb) 1488 for (transno = 0; transno)
< aggstate->Numtrans; transno++) (gdb) 1497 return entry; (gdb) 1498} (gdb)
Lookup_hash_entries- > back to lookup_hash_entries
(gdb) nlookup_hash_entries (aggstate=0x1f895a0) at nodeAgg.c:15131513 for (setno = 0; setno)
< numHashes; setno++) agg_fill_hash_table->Back to agg_fill_hash_table
(gdb) n1518} (gdb) agg_fill_hash_table (aggstate=0x1f895a0) at nodeAgg.c:19341934 advance_aggregates (aggstate); (gdb)
Advance_aggregates- > enter advance_aggregates
(gdb) stepadvance_aggregates (aggstate=0x1f895a0) at nodeAgg.c:680680 ExecEvalExprSwitchContext (aggstate- > phase- > evaltrans, (gdb) p * aggstate- > phase- > evaltrans$30 = {tag = {type = T_ExprState}, flags = 6'\ 006, resnull = false, resvalue = 0, resultslot = 0x0, steps = 0x1fa10d0, evalfunc = 0x6cd882, expr = 0x1f895a0, evalfunc_private = 0x6cb43e, steps_len = 16, steps_alloc = 16, parent = 0x1f895a0, ext_params = 0x0, innermost_caseval = 0x0, innermost_casenull = innermost_casenull, innermost_casenull = innermost_casenull Innermost_domainnull = 0x0} (gdb) stepExecEvalExprSwitchContext (state=0x1fa1038, econtext=0x1f897d8, isNull=0x7fff7f065e9f) at.. / src/include/executor/executor.h:312312 oldContext = MemoryContextSwitchTo (econtext- > ecxt_per_tuple_memory) (gdb) finishRun till exit from # 0 ExecEvalExprSwitchContext (state=0x1fa1038, econtext=0x1f897d8, isNull=0x7fff7f065e9f) at.. / src/include/executor/executor.h:312advance_aggregates (aggstate=0x1f895a0) at nodeAgg.c:683683} Value returned is $31 = 0
Enter the second cycle
(gdb) stepagg_fill_hash_table (aggstate=0x1f895a0) at nodeAgg.c:19401940 ResetExprContext (aggstate- > tmpcontext); (gdb) n1941}
View relevant information
(gdb) n1941} (gdb) 1923 outerslot = fetch_input_tuple (aggstate); (gdb) 1924 if (TupIsNull (outerslot)) (gdb) n1928 tmpcontext- > ecxt_outertuple = outerslot; (gdb) 1931 lookup_hash_entries (aggstate); (gdb) 1934 advance_aggregates (aggstate); (gdb) 1940 ResetExprContext (aggstate- > tmpcontext) (gdb) p * outerslot$32 = {type = T_TupleTableSlot, tts_isempty = false, tts_shouldFree = false, tts_shouldFreeMin = false, tts_slow = true, tts_tuple = 0x1fa5998, tts_tupleDescriptor = 0x7ff7dd2d1380, tts_mcxt = 0x1f89270, tts_buffer = 124, tts_nvalid = 3, tts_values = 0x1f89d48, tts_isnull = 0x1f89d80, tts_mintuple = 0x0, tts_minhdr = {t_len = 0, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0} Ip_posid = 0}, t_tableOid = 0, t_data = 0x0}, tts_off = 16, tts_fixedTupleDescriptor = true} (gdb) x outerslot- > tts_values0x1f89d48: 0x28 0xf6 0x0b 0xb1 0xf7 0x7f 0x00 0x000x1f89d50: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x000x1f89d58: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x000x1f89d60: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Tuple data
(gdb) x outerslot- 56x outerslot- > tts_tuple- > tweak data-> t_bits0x7ff7b2e1365f: 0x00 0x0b 0x47 0x5a 0x30 0x31 0x00 0x000x7ff7b2e13667: 0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x000x7ff7b2e1366f: 0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x000x7ff7b2e13677: 0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x000x7ff7b2e1367f: 0x00 0x000 X00 0x00 0x00 0x00 0x00 0x000x7ff7b2e13687: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x000x7ff7b2e1368f: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
DONE!
IV. Reference materials
N/A