Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Interpretation of PostgreSQL Source Code-query # 106 (aggregate function # 11-finalize_aggregate)

2025-03-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)06/01 Report--

< numFinalArgs; i++) { fcinfo.arg[i] = (Datum) 0; fcinfo.argnull[i] = true; anynull = true; } if (fcinfo.flinfo->

Fn_strict & & anynull) {/ * don't call a strict function with NULL inputs * / / do not pass the NULL parameter * resultVal = (Datum) 0 when calling a strict function; * resultIsNull = true;} else {/ / call the function and get the result value * resultVal = FunctionCallInvoke (& fcinfo) * resultIsNull = fcinfo.isnull;} aggstate- > curperagg = NULL;} else {/ * Don't need MakeExpandedObjectReadOnly; datumCopy will copy it * / / the data will be copied without MakeExpandedObjectReadOnly,datumCopy. * resultVal = pergroupstate- > transValue; * resultIsNull = pergroupstate- > transValueIsNull;} / * * If result is pass-by-ref, make sure it is in the right context. * if the result is passed by reference, make sure it is in the correct context. * / if (! peragg- > resulttypeByVal & &! * resultIsNull & &! MemoryContextContains (CurrentMemoryContext, DatumGetPointer (* resultVal)) * resultVal = datumCopy (* resultVal, peragg- > resulttypeByVal, peragg- > resulttypeLen); MemoryContextSwitchTo (oldContext);} III. Tracking analysis

Test script

-- disable parallel set max_parallel_workers_per_gather=0;select bh,avg (C1), min (C1), max (c2) from t_agg_simple group by bh

Tracking and analysis

(gdb) b finalize_aggregateBreakpoint 1 at 0x6ed256: file nodeAgg.c, line 901. (gdb) cContinuing.Breakpoint 1, finalize_aggregate (aggstate=0x154a640, peragg=0x154e390, pergroupstate=0x155f850, resultVal=0x154c0c8, resultIsNull=0x154c100) at nodeAgg.c:901901 bool anynull = false; (gdb)

Input parameters

(gdb) p * aggstate$1 = {ss = {ps = {type = T_AggState, plan = 0x1575890, state = 0x154a428, ExecProcNode = 0x6ee438, ExecProcNodeReal = 0x6ee438, instrument = 0x0, worker_instrument = 0x0, worker_jit_instrument = 0x0, qual = 0x0, lefttree = 0x154abb0, righttree = 0x0, initPlan = 0x0, subPlan = 0x0, chgParam = 0x0, ps_ResultTupleSlot = 0x154b7b0, ps_ExprContext = 0x154aaf0, 0x154aaf0 = 0x0, ps_ResultTupleSlot = 0x154b7b0, ps_ExprContext = 0x154aaf0, 0x154aaf0 = ps_ProjInfo, 0x154b8f0 = 0x154b8f0}, 0x154b8f0 = 0x154b8f0, scandesc =} Aggs = 0x154be00, numaggs = 3, numtrans = 3, aggstrategy = AGG_HASHED, aggsplit = AGGSPLIT_SIMPLE, phase = 0x154bef8, numphases = 1, current_phase = 0, peragg = 0x154e390, pertrans = 0x15673e0, hashcontext = 0x154aa30, aggcontexts = 0x154a858, tmpcontext = 0x154a878, curaggcontext = 0x154aa30, curperagg = 0x0, curpertrans = 0x1568c70, input_done = false, agg_done = false, projected_set =-1, current_set = 0, grouped_cols = 0x154c028, all_grouped_cols = all_grouped_cols, all_grouped_cols = 1, 0x154c090 = 0x154c090, 0x154c090 = 0x154c090 Sort_out = 0x0, sort_slot = 0x0, pergroups = 0x0, grp_firstTuple = 0x0, table_filled = true, num_hashes = 1, perhash = 0x154bf50, hash_pergroup = 0x154e5a8, all_pergroups = 0x154e5a8, combinedproj = 0x0} (gdb) p * peragg$2 = {aggref = 0x155b6e8, transno = 0, finalfn_oid = 0, finalfn = {fn_addr = 0x0, fn_oid = 0, fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0'\ 000, fn_extra = fn_extra Fn_mcxt = 0x0, fn_expr = 0x0}, numFinalArgs = 1, aggdirectargs = 0x0, resulttypeLen = 4, resulttypeByVal = true, shareable = true} (gdb) p * pergroupstate$3 = {transValue = 5, transValueIsNull = false, noTransValue = false} (gdb) p * resultVal$4 = 0 (gdb) p * resultIsNull$5 = false (gdb)

Get the conversion function, switch the context

(gdb) n905 AggStatePerTrans pertrans = & aggstate- > pertranst [peragg-> transno]; (gdb) 907 oldContext = MemoryContextSwitchTo (aggstate- > ss.ps.ps_ExprContext- > ecxt_per_tuple_memory); (gdb) 915I = 1 (gdb) p * pertrans$6 = {aggref = 0x155b6e8, 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 = 0x154a310, fn_expr = 0x157a580}, 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 = 0x154a640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {40,50,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)

Parse all direct parameters (none).

(gdb) n916 foreach (lc, peragg- > aggdirectargs) (gdb) p peragg- > aggdirectargs$7 = (List *) 0x0 (gdb) n930 if (OidIsValid (peragg- > finalfn_oid)) (gdb)

Invalid finalfn, direct assignment (this is max aggregation)

(gdb) n930 if (OidIsValid (peragg- > finalfn_oid)) (gdb) p peragg- > finalfn_oid$8 = 0 (gdb) n973 * resultVal = pergroupstate- > transValue; (gdb) 974 * resultIsNull = pergroupstate- > transValueIsNull; (gdb) (gdb) p * resultVal$9 = 5

Switch back to the original context

(gdb) n980 if (! peragg- > resulttypeByVal &! * resultIsNull & & (gdb) 987 MemoryContextSwitchTo (oldContext); (gdb) 988}

The second aggregation is min, and there is no finalfn

(gdb) nfinalize_aggregates (aggstate=0x154a640, peraggs=0x154e390, pergroup=0x155f850) at nodeAgg.c:11601160 for (aggno = 0; aggno

< aggstate->

Numaggs; aggno++) (gdb) cContinuing.Breakpoint 1, finalize_aggregate (aggstate=0x154a640, peragg=0x154e3e8, pergroupstate=0x155f860, resultVal=0x154c0d0, resultIsNull=0x154c101) at nodeAgg.c:901901 bool anynull = false; (gdb) n905 AggStatePerTrans pertrans = & aggstate- > pertrans [peragg-> transno] (gdb) p * peragg$10 = {aggref = 0x155b460, transno = 1, finalfn_oid = 0, finalfn = {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}, numFinalArgs = 1, aggdirectargs = 0x0, resulttypeLen = 4, resulttypeByVal = true Shareable = true} (gdb) n907 oldContext = MemoryContextSwitchTo (aggstate- > ss.ps.ps_ExprContext- > ecxt_per_tuple_memory) (gdb) p * pertrans$11 = {aggref = 0x155b460, aggshared = false, numInputs = 1, numTransInputs = 1, transfn_oid = 769,serialfn_oid = 0, deserialfn_oid = 0, aggtranstype = 23, transfn = {fn_addr = 0x93e8a3, fn_oid = 769, fn_nargs = 2, fn_strict = true, fn_retset = false, fn_stats = 2'\ 002, fn_extra = 0x0, fn_mcxt = 0x154a310, fn_expr = 0x157a6d0}, 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 = 0x154a640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {2,50,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)

The third aggregate operation is avg, and there is a finalfn

(gdb) cContinuing.Breakpoint 1, finalize_aggregate (aggstate=0x154a640, peragg=0x154e440, pergroupstate=0x155f870, resultVal=0x154c0d8, resultIsNull=0x154c102) at nodeAgg.c:901901 bool anynull = false; (gdb) n905 AggStatePerTrans pertrans = & aggstate- > peragg-> transno]; (gdb) 907 oldContext = MemoryContextSwitchTo (aggstate- > ss.ps.ps_ExprContext- > ecxt_per_tuple_memory) (gdb) p * pertrans$12 = {aggref = 0x155b1d8, aggshared = false, numInputs = 1, numTransInputs = 1, transfn_oid = 1963, serialfn_oid = 0, deserialfn_oid = 0, aggtranstype = 1016, transfn = {fn_addr = 0x977d8f, fn_oid = 1963, fn_nargs = 2, fn_strict = true, fn_retset = false, fn_stats = 2'\ 002, fn_extra = 0x0, fn_mcxt = 0x154a310, fn_expr = 0x157aa40}, 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 = 22522136, initValueIsNull = false, inputtypeLen = 0, transtypeLen =-1, inputtypeByVal = false, transtypeByVal = false, sortslot = 0x0, uniqslot = uniqslot, 0x0 = 0x0, 0x0 = 0x0 Transfn_fcinfo = {flinfo = 0x1568c98, context = 0x154a640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {22410736, 50,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 = isnull, isnull = 0 Arg = {0}, argnull = {false}} (gdb) p * peragg$13 = {aggref = 0x155b1d8, transno = 2, finalfn_oid = 1964, finalfn = {fn_addr = 0x978251, fn_oid = 1964, fn_nargs = 1, fn_strict = true, fn_retset = false, fn_stats = 2'\ 002, fn_extra = 0x0, fn_mcxt = 0x154a310, fn_expr = 0x157a7c0}, numFinalArgs = 1, aggdirectargs = 0x0, resulttypeLen =-1, resulttypeByVal = false, shareable = true} (gdb)

There is finalfn (int4_avg_accum)

(gdb) n915 I = 1; (gdb) 916 foreach (lc, peragg- > aggdirectargs) (gdb) 930 if (OidIsValid (peragg- > finalfn_oid)) (gdb) p peragg- > finalfn_oid$14 = 1964 (gdb)

Initialize function call information & populate the transition status value & use nulls to populate other remaining parameters

(gdb) n932 int numFinalArgs = peragg- > numFinalArgs; (gdb) 935 aggstate- > curperagg = peragg; (gdb) p numFinalArgs$15 = 1 (gdb) n937 InitFunctionCallInfoData (fcinfo, & peragg- > finalfn, (gdb) 943 fcinfo.arg [0] = MakeExpandedObjectReadOnly (pergroupstate- > transValue, (gdb) 946 fcinfo.argnull [0] = pergroupstate- > transValueIsNull; (gdb) 947 anynull | = pergroupstate- > transValueIsNull; (gdb) n950 for (; I)

< numFinalArgs; i++)(gdb) p fcinfo$17 = {flinfo = 0x154e450, context = 0x154a640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 1, arg = { 22411432, 4696688, 70368744179327, 262183, 0, 22291296, 22291800, 72057594037927952, 139949568947584, 532575944705, 139949566113024, 11508082471248244084, 139950313735104, 22291264, 140735692522224, 8884187, 0, 0, 481036337152, 22088784, 140735692522064, 22324800, 22522520, 22522520, 1, 22519768, 16302624, 140735692522192, 16302624, 139950284069640, 1, 22519768, 140735692522160, 22341032, 140735692522224, 4696688, 140735692525536, 0, 0, 7135662, 12884901892, 22326664, 7124177, 139950314519480, 139949574157416, 139949574157415, 0, 139949574157392, 0, 22449600, 139950314519224, 22410736, 140735692522336, 9928139, 140735692522336, 22449600, 125, 22291296, 4317427920, 536893372416, 140735692522368, 10923480, 536887362208, 22291264, 140735692522432, 8890594, 4294967296, 139949568947584, 22449600, 22410680, 16450208, 9441796618804569664, 140735692522548, 139949568947608, 125, 72057594060219232, 140735692522512, 8881213, 140735692522512, 16450208, 140735692522548, 139949568947608, 140735692522576, 8891011, 4317417729, 139949568947584, 9441796623099544216, 9441796618782244874, 16450208, 536893253520, 140735692522608, 8899958, 139949574149760, 536893253368, 140735692522640, 7227524, 4317293960, 22326664, 140735692522720, 7406960}, argnull = {false, 197, 245, 148, 255, 127, false, false, 176, 171, 84, true, false, false, false, false, 48, false, false, false, true, false , 136, 173, 84, true, false, false, false, false, 232, 132, 87, true, true, false, false, false, 40, 164, 84, true, false, false, false, false, 104, 176, 87, true, false, false, false, false, 48, 197, 245, 148, 255, 127, false, false, 67, 35, 110, false, false, false, false, false, 32, 174, 84, true, false, false, false, false, 118, 5, 113, false, false, false, false, false, 171, 4, 113, false}}(gdb) (gdb) n957 if (fcinfo.flinfo->

Fn_strict & & anynull) (gdb)

Call the function to get the result value

(gdb) n965 * resultVal = FunctionCallInvoke (& fcinfo); (gdb) p * fcinfo.flinfo$18 = {fn_addr = 0x978251, fn_oid = 1964, fn_nargs = 1, fn_strict = true, fn_retset = false, fn_stats = 2'\ 002, fn_extra = 0x0, fn_mcxt = 0x154a310, fn_expr = 0x157a7c0} (gdb) p * fcinfo.flinfo- > fn_expr$19 = {type = T_FuncExpr} (gdb) b int8_avgBreakpoint 2 at 0x97825d: file numeric.c, line 5426. (gdb)

Enter int8_avg

(gdb) cContinuing.Breakpoint 2, int8_avg (fcinfo=0x7fff94f5c160) at numeric.c:54265426 ArrayType * transarray = PG_GETARG_ARRAYTYPE_P (0); (gdb) n5431 if (ARR_HASNULL (transarray) | | (gdb) 5432 ARR_SIZE (transarray)! = ARR_OVERHEAD_NONULLS (1) + sizeof (Int8TransTypeData)) (gdb) 5431 if (ARR_HASNULL (transarray) | | (gdb) 5434 transdata = (Int8TransTypeData *) ARR_DATA_PTR (transarray)) (gdb) n5437 if (transdata- > count = 0) (gdb) p * transarray$1 = {vl_len_ = 160, ndim = 1, dataoffset = 0, elemtype = 20} (gdb) p * transdata$2 = {count = 2, sum = 55} (gdb)

Prepare the parameters and call the numeric_div function

(gdb) n5440 countd = DirectFunctionCall1 (int8_numeric, (gdb) 5442 sumd = DirectFunctionCall1 (int8_numeric, (gdb) 5445 PG_RETURN_DATUM (DirectFunctionCall2 (numeric_div, sumd, countd)); (gdb) x/1xg countd0x1572780: 0x0002800000000020 (gdb) x/1xg sumd0x15727a0: 0x0037800000000020

After the call, go back to finalize_aggregate

Gdb) n5446} (gdb) finalize_aggregate (aggstate=0x1578960, peragg=0x157a730, pergroupstate=0x1570b40, resultVal=0x157a3f8, resultIsNull=0x157a422) at nodeAgg.c:966966 * resultIsNull= fcinfo.isnull; (gdb) (gdb) p * resultVal$10 = 22489080 (gdb) p resultVal$11 = (Datum *) 0x157a3f8 (gdb) x/1xg resultVal0x157a3f8: 0x00000000015727f8 (gdb) x/1fg resultVal0x157a3f8: 1.1111081834575461e-316 (gdb) x/1fw resultVal0x157a3f8: 3.95179395e-38

DONE!

IV. Reference materials

PostgreSQL Source Code interpretation (178)-query # 95 (aggregate function) # 1 related data structures

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report