您好,登錄后才能下訂單哦!
本篇內容介紹了“PostgreSQL聚合函數的實現方法是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
AggState
聚合函數執行時狀態結構體,內含AggStatePerAgg等結構體
/* --------------------- * AggState information * * ss.ss_ScanTupleSlot refers to output of underlying plan. * ss.ss_ScanTupleSlot指的是基礎計劃的輸出. * (ss = ScanState,ps = PlanState) * * Note: ss.ps.ps_ExprContext contains ecxt_aggvalues and * ecxt_aggnulls arrays, which hold the computed agg values for the current * input group during evaluation of an Agg node's output tuple(s). We * create a second ExprContext, tmpcontext, in which to evaluate input * expressions and run the aggregate transition functions. * 注意:ss.ps.ps_ExprContext包含了ecxt_aggvalues和ecxt_aggnulls數組, * 這兩個數組保存了在計算agg節點的輸出元組時當前輸入組已計算的agg值. * --------------------- */ /* these structs are private in nodeAgg.c: */ //在nodeAgg.c中私有的結構體 typedef struct AggStatePerAggData *AggStatePerAgg; typedef struct AggStatePerTransData *AggStatePerTrans; typedef struct AggStatePerGroupData *AggStatePerGroup; typedef struct AggStatePerPhaseData *AggStatePerPhase; typedef struct AggStatePerHashData *AggStatePerHash; typedef struct AggState { //第一個字段是NodeTag(繼承自ScanState) ScanState ss; /* its first field is NodeTag */ //targetlist和quals中所有的Aggref List *aggs; /* all Aggref nodes in targetlist & quals */ //鏈表的大小(可以為0) int numaggs; /* length of list (could be zero!) */ //pertrans條目大小 int numtrans; /* number of pertrans items */ //Agg策略模式 AggStrategy aggstrategy; /* strategy mode */ //agg-splitting模式,參見nodes.h AggSplit aggsplit; /* agg-splitting mode, see nodes.h */ //指向當前步驟數據的指針 AggStatePerPhase phase; /* pointer to current phase data */ //步驟數(包括0) int numphases; /* number of phases (including phase 0) */ //當前步驟 int current_phase; /* current phase number */ //per-Aggref信息 AggStatePerAgg peragg; /* per-Aggref information */ //per-Trans狀態信息 AggStatePerTrans pertrans; /* per-Trans state information */ //長生命周期數據的ExprContexts(hashtable) ExprContext *hashcontext; /* econtexts for long-lived data (hashtable) */ ////長生命周期數據的ExprContexts(每一個GS使用) ExprContext **aggcontexts; /* econtexts for long-lived data (per GS) */ //輸入表達式的ExprContext ExprContext *tmpcontext; /* econtext for input expressions */ #define FIELDNO_AGGSTATE_CURAGGCONTEXT 14 //當前活躍的aggcontext ExprContext *curaggcontext; /* currently active aggcontext */ //當前活躍的aggregate(如存在) AggStatePerAgg curperagg; /* currently active aggregate, if any */ #define FIELDNO_AGGSTATE_CURPERTRANS 16 //當前活躍的trans state AggStatePerTrans curpertrans; /* currently active trans state, if any */ //輸入結束? bool input_done; /* indicates end of input */ //Agg掃描結束? bool agg_done; /* indicates completion of Agg scan */ //最后一個grouping set int projected_set; /* The last projected grouping set */ #define FIELDNO_AGGSTATE_CURRENT_SET 20 //將要解析的當前grouping set int current_set; /* The current grouping set being evaluated */ //當前投影操作的分組列 Bitmapset *grouped_cols; /* grouped cols in current projection */ //倒序的分組列鏈表 List *all_grouped_cols; /* list of all grouped cols in DESC order */ /* These fields are for grouping set phase data */ //-------- 下面的列用于grouping set步驟數據 //所有步驟中最大的sets大小 int maxsets; /* The max number of sets in any phase */ //所有步驟的數組 AggStatePerPhase phases; /* array of all phases */ //對于phases > 1,已排序的輸入信息 Tuplesortstate *sort_in; /* sorted input to phases > 1 */ //對于下一個步驟,輸入已拷貝 Tuplesortstate *sort_out; /* input is copied here for next phase */ //排序結果的slot TupleTableSlot *sort_slot; /* slot for sort results */ /* these fields are used in AGG_PLAIN and AGG_SORTED modes: */ //------- 下面的列用于AGG_PLAIN和AGG_SORTED模式: //per-group指針的grouping set編號數組 AggStatePerGroup *pergroups; /* grouping set indexed array of per-group * pointers */ //當前組的第一個元組拷貝 HeapTuple grp_firstTuple; /* copy of first tuple of current group */ /* these fields are used in AGG_HASHED and AGG_MIXED modes: */ //--------- 下面的列用于AGG_HASHED和AGG_MIXED模式: //是否已填充hash表? bool table_filled; /* hash table filled yet? */ //hash桶數? int num_hashes; //相應的哈希表數據數組 AggStatePerHash perhash; /* array of per-hashtable data */ //per-group指針的grouping set編號數組 AggStatePerGroup *hash_pergroup; /* grouping set indexed array of * per-group pointers */ /* support for evaluation of agg input expressions: */ //---------- agg輸入表達式解析支持 #define FIELDNO_AGGSTATE_ALL_PERGROUPS 34 //首先是->pergroups,然后是hash_pergroup AggStatePerGroup *all_pergroups; /* array of first ->pergroups, than * ->hash_pergroup */ //投影實現機制 ProjectionInfo *combinedproj; /* projection machinery */ } AggState; /* Primitive options supported by nodeAgg.c: */ //nodeag .c支持的基本選項 #define AGGSPLITOP_COMBINE 0x01 /* substitute combinefn for transfn */ #define AGGSPLITOP_SKIPFINAL 0x02 /* skip finalfn, return state as-is */ #define AGGSPLITOP_SERIALIZE 0x04 /* apply serializefn to output */ #define AGGSPLITOP_DESERIALIZE 0x08 /* apply deserializefn to input */ /* Supported operating modes (i.e., useful combinations of these options): */ //支持的操作模式 typedef enum AggSplit { /* Basic, non-split aggregation: */ //基本 : 非split聚合 AGGSPLIT_SIMPLE = 0, /* Initial phase of partial aggregation, with serialization: */ //部分聚合的初始步驟,序列化 AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE, /* Final phase of partial aggregation, with deserialization: */ //部分聚合的最終步驟,反序列化 AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE } AggSplit; /* Test whether an AggSplit value selects each primitive option: */ //測試AggSplit選擇了哪些基本選項 #define DO_AGGSPLIT_COMBINE(as) (((as) & AGGSPLITOP_COMBINE) != 0) #define DO_AGGSPLIT_SKIPFINAL(as) (((as) & AGGSPLITOP_SKIPFINAL) != 0) #define DO_AGGSPLIT_SERIALIZE(as) (((as) & AGGSPLITOP_SERIALIZE) != 0) #define DO_AGGSPLIT_DESERIALIZE(as) (((as) & AGGSPLITOP_DESERIALIZE) != 0)
N/A
跟蹤分析數據結構中的相關信息.
測試數據:
-- 禁用并行 set max_parallel_workers_per_gather=0; select bh,avg(c1),min(c1),max(c2) from t_agg_simple group by bh;
aggstate是聚合運算的運行狀態.
1536 AggState *node = castNode(AggState, pstate); (gdb) n 1537 TupleTableSlot *result = NULL; (gdb) p *node $1 = {ss = {ps = {type = T_AggState, plan = 0x120ba30, state = 0x12eb428, ExecProcNode = 0x6ee438 <ExecAgg>, ExecProcNodeReal = 0x6ee438 <ExecAgg>, instrument = 0x0, worker_instrument = 0x0, worker_jit_instrument = 0x0, qual = 0x0, lefttree = 0x12ebbb0, righttree = 0x0, initPlan = 0x0, subPlan = 0x0, chgParam = 0x0, ps_ResultTupleSlot = 0x12ec7b0, ps_ExprContext = 0x12ebaf0, ps_ProjInfo = 0x12ec8f0, scandesc = 0x12ebf00}, ss_currentRelation = 0x0, ss_currentScanDesc = 0x0, ss_ScanTupleSlot = 0x12ec458}, aggs = 0x12ece00, numaggs = 3, numtrans = 3, aggstrategy = AGG_HASHED, aggsplit = AGGSPLIT_SIMPLE, phase = 0x12ecef8, numphases = 1, current_phase = 0, peragg = 0x13083e0, pertrans = 0x130a3f0, hashcontext = 0x12eba30, aggcontexts = 0x12eb858, tmpcontext = 0x12eb878, curaggcontext = 0x12eba30, curperagg = 0x0, curpertrans = 0x0, input_done = false, agg_done = false, projected_set = -1, current_set = 0, grouped_cols = 0x0, all_grouped_cols = 0x12ed090, maxsets = 1, phases = 0x12ecef8, sort_in = 0x0, sort_out = 0x0, sort_slot = 0x0, pergroups = 0x0, grp_firstTuple = 0x0, table_filled = false, num_hashes = 1, perhash = 0x12ecf50, hash_pergroup = 0x13085f8, all_pergroups = 0x13085f8, combinedproj = 0x0}
aggstate->phase/phases是當前階段/所有階段的信息.
在本例中,由于只有一個階段:AGG_HASHED,因此兩者是一樣的.
(gdb) p *node->phase $2 = {aggstrategy = AGG_HASHED, numsets = 1, gset_lengths = 0x12ecfe8, grouped_cols = 0x12ed008, eqfunctions = 0x0, aggnode = 0x120ba30, sortnode = 0x0, evaltrans = 0x1315800} (gdb) p node->phases[0] $27 = {aggstrategy = AGG_HASHED, numsets = 1, gset_lengths = 0x12ecfe8, grouped_cols = 0x12ed008, eqfunctions = 0x0, aggnode = 0x120ba30, sortnode = 0x0, evaltrans = 0x1315800}
aggstate->phase->evaltrans是該階段的表達式解析轉換函數.
在本例中,該函數是ExecInterpExpr(通過執行一系列的步驟得到值)
(gdb) p *node->phase->evaltrans $3 = {tag = {type = T_ExprState}, flags = 6 '\006', resnull = false, resvalue = 0, resultslot = 0x0, steps = 0x1315ac0, evalfunc = 0x6cd882 <ExecInterpExprStillValid>, expr = 0x12eb640, evalfunc_private = 0x6cb43e <ExecInterpExpr>, steps_len = 16, steps_alloc = 16, parent = 0x12eb640, ext_params = 0x0, innermost_caseval = 0x0, innermost_casenull = 0x0, innermost_domainval = 0x0, innermost_domainnull = 0x0}
aggstate->phase->evaltrans是該階段的聚合節點,即T_AGG.
(gdb) p *node->phase->aggnode $9 = {plan = {type = T_Agg, startup_cost = 24.800000000000001, total_cost = 27.300000000000001, plan_rows = 200, plan_width = 98, parallel_aware = false, parallel_safe = false, plan_node_id = 0, targetlist = 0x12fbf10, qual = 0x0, lefttree = 0x12fb9d0, righttree = 0x0, initPlan = 0x0, extParam = 0x0, allParam = 0x0}, aggstrategy = AGG_HASHED, aggsplit = AGGSPLIT_SIMPLE, numCols = 1, grpColIdx = 0x12fbcc0, grpOperators = 0x12fbca0, numGroups = 200, aggParams = 0x0, groupingSets = 0x0, chain = 0x0}
aggstate->peragg存儲的是per-Aggref信息,亦即每一個聚合對應一個,每一個peragg->aggref對應一個聚合信息.
第1個是max:
(gdb) p *node->peragg $10 = {aggref = 0x12fc458, 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 = 0x0, fn_mcxt = 0x0, fn_expr = 0x0}, numFinalArgs = 1, aggdirectargs = 0x0, resulttypeLen = 4, resulttypeByVal = true, shareable = true} (gdb) p *node->peragg->aggref $11 = {xpr = {type = T_Aggref}, aggfnoid = 2116, aggtype = 23, aggcollid = 0, inputcollid = 0, aggtranstype = 23, aggargtypes = 0x12fc518, aggdirectargs = 0x0, args = 0x12fc628, aggorder = 0x0, aggdistinct = 0x0, aggfilter = 0x0, aggstar = false, aggvariadic = false, aggkind = 110 'n', agglevelsup = 0, aggsplit = AGGSPLIT_SIMPLE, location = 26} ######## testdb=# select oid,proname from pg_proc where oid in (2116,768); oid | proname ------+------------ 768 | int4larger 2116 | max (2 rows) ########
第2個是min:
(gdb) p node->peragg[1] $38 = {aggref = 0x12fc1d0, transno = 1, 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 = 0x0, fn_mcxt = 0x0, fn_expr = 0x0}, numFinalArgs = 1, aggdirectargs = 0x0, resulttypeLen = 4, resulttypeByVal = true, shareable = true} (gdb) p *node->peragg[1]->aggref $39 = {xpr = {type = T_Aggref}, aggfnoid = 2132, aggtype = 23, aggcollid = 0, inputcollid = 0, aggtranstype = 23, aggargtypes = 0x12fc290, aggdirectargs = 0x0, args = 0x12fc3a0, aggorder = 0x0, aggdistinct = 0x0, aggfilter = 0x0, aggstar = false, aggvariadic = false, aggkind = 110 'n', agglevelsup = 0, aggsplit = AGGSPLIT_SIMPLE, location = 18} ############ testdb=# select oid,proname from pg_proc where oid in (2132,769); oid | proname ------+------------- 769 | int4smaller 2132 | min (2 rows) ###########
第3個是avg:
(gdb) p node->peragg[2] $40 = {aggref = 0x12fbf48, transno = 2, finalfn_oid = 1964, finalfn = {fn_addr = 0x978251 <int8_avg>, fn_oid = 1964, fn_nargs = 1, fn_strict = true, fn_retset = false, fn_stats = 2 '\002', fn_extra = 0x0, fn_mcxt = 0x12eb310, fn_expr = 0x1315698}, numFinalArgs = 1, aggdirectargs = 0x0, resulttypeLen = -1, resulttypeByVal = false, shareable = true} (gdb) p *node->peragg[2]->aggref $41 = {xpr = {type = T_Aggref}, aggfnoid = 2101, aggtype = 1700, aggcollid = 0, inputcollid = 0, aggtranstype = 1016, aggargtypes = 0x12fc008, aggdirectargs = 0x0, args = 0x12fc118, aggorder = 0x0, aggdistinct = 0x0, aggfilter = 0x0, aggstar = false, aggvariadic = false, aggkind = 110 'n', agglevelsup = 0, aggsplit = AGGSPLIT_SIMPLE, location = 10} ##### testdb=# select oid,proname from pg_proc where oid in (2101,1963); oid | proname ------+---------------- 1963 | int4_avg_accum 2101 | avg (2 rows) #####
aggstate->pertrans保存的是轉換函數.
第1/2/3個分別是int4larger/int4smaller/int4_avg_accum
(gdb) p node->pertrans[0] $19 = {aggref = 0x12fc458, aggshared = false, numInputs = 1, numTransInputs = 1, transfn_oid = 768, serialfn_oid = 0, deserialfn_oid = 0, aggtranstype = 23, transfn = {fn_addr = 0x93e877 <int4larger>, fn_oid = 768, fn_nargs = 2, fn_strict = true, fn_retset = false, fn_stats = 2 '\002', fn_extra = 0x0, fn_mcxt = 0x12eb310, fn_expr = 0x1315458}, serialfn = {fn_addr = 0x0, fn_oid = 0, fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0 '\000', 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 '\000', 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 '\000', 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 = 0x0, sortdesc = 0x0, sortstates = 0x1308620, transfn_fcinfo = {flinfo = 0x130a418, context = 0x12eb640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}, serialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = {0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}, deserialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = { 0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}} (gdb) p node->pertrans[1] $20 = {aggref = 0x12fc1d0, aggshared = false, numInputs = 1, numTransInputs = 1, transfn_oid = 769, serialfn_oid = 0, deserialfn_oid = 0, aggtranstype = 23, transfn = {fn_addr = 0x93e8a3 <int4smaller>, fn_oid = 769, fn_nargs = 2, fn_strict = true, fn_retset = false, fn_stats = 2 '\002', fn_extra = 0x0, fn_mcxt = 0x12eb310, fn_expr = 0x13155a8}, serialfn = {fn_addr = 0x0, fn_oid = 0, fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0 '\000', 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 '\000', 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 '\000', 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 = 0x0, sortdesc = 0x0, sortstates = 0x1308640, transfn_fcinfo = {flinfo = 0x130b060, context = 0x12eb640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}, serialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = {0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}, deserialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = { 0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}} (gdb) p node->pertrans[2] $21 = {aggref = 0x12fbf48, aggshared = false, numInputs = 1, numTransInputs = 1, transfn_oid = 1963, serialfn_oid = 0, deserialfn_oid = 0, aggtranstype = 1016, transfn = {fn_addr = 0x977d8f <int4_avg_accum>, fn_oid = 1963, fn_nargs = 2, fn_strict = true, fn_retset = false, fn_stats = 2 '\002', fn_extra = 0x0, fn_mcxt = 0x12eb310, fn_expr = 0x1315a68}, serialfn = {fn_addr = 0x0, fn_oid = 0, fn_nargs = 0, fn_strict = false, fn_retset = false, fn_stats = 0 '\000', 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 '\000', 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 '\000', fn_extra = 0x0, fn_mcxt = 0x0, fn_expr = 0x0}, equalfnMulti = 0x0, initValue = 20010920, initValueIsNull = false, inputtypeLen = 0, transtypeLen = -1, inputtypeByVal = false, transtypeByVal = false, sortslot = 0x0, uniqslot = 0x0, sortdesc = 0x0, sortstates = 0x13156f0, transfn_fcinfo = {flinfo = 0x130bca8, context = 0x12eb640, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, arg = {0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}, serialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = {0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}, deserialfn_fcinfo = {flinfo = 0x0, context = 0x0, resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 0, arg = { 0 <repeats 100 times>}, argnull = {false <repeats 100 times>}}}
aggstate->perhash存儲的是per-hashtable數據.perhash->hashslot存儲的是最小化Tuple.
本例只有一個group set,因此對應的hash表只有一個.
(gdb) p node->perhash[0] $30 = {hashtable = 0x1308890, hashiter = {cur = 0, end = 0, done = false}, hashslot = 0x12ed238, hashfunctions = 0x12ed2d0, eqfuncoids = 0x1308700, numCols = 1, numhashGrpCols = 1, largestGrpColIdx = 1, hashGrpColIdxInput = 0x1308660, hashGrpColIdxHash = 0x1308680, aggnode = 0x120ba30} (gdb) p node->perhash[0]->hashslot[0] $32 = {type = T_TupleTableSlot, tts_isempty = true, tts_shouldFree = false, tts_shouldFreeMin = false, tts_slow = false, tts_tuple = 0x0, tts_tupleDescriptor = 0x12ed120, tts_mcxt = 0x12eb310, tts_buffer = 0, tts_nvalid = 0, tts_values = 0x12ed298, tts_isnull = 0x12ed2a0, 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}
其他的數據結構.
aggstate->hash_pergroup/all_pergroups/combinedproj
(gdb) p node->hash_pergroup $35 = (AggStatePerGroup *) 0x13085f8 (gdb) p *node->hash_pergroup $36 = (AggStatePerGroup) 0x0 (gdb) p *node->all_pergroups $37 = (AggStatePerGroup) 0x0 (gdb) p *node->combinedproj Cannot access memory at address 0x0
簡單來說,整個過程大體如下:
每個Group的列信息會存儲在aggstate->perhash中,按階段(aggstate->phases)逐個執行.
掃描數據表,在遍歷tuple的時候,通過hash函數比對(Key為最小化tuple)找到/創建相應的Group組aggstate->perhash(hash table),提取tuple中相應的列值作為參數輸入到aggstate->pertrans中定義的轉換函數中,解析執行結果并存儲,最后執行投影操作,把最終結果返回給客戶端
“PostgreSQL聚合函數的實現方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。