千家信息网

PostgreSQL聚合函数的实现方法是什么

发表于:2025-02-11 作者:千家信息网编辑
千家信息网最后更新 2025年02月11日,本篇内容介绍了"PostgreSQL聚合函数的实现方法是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有
千家信息网最后更新 2025年02月11日PostgreSQL聚合函数的实现方法是什么

本篇内容介绍了"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) n1537        TupleTableSlot *result = NULL;(gdb) p *node$1 = {ss = {ps = {type = T_AggState, plan = 0x120ba30, state = 0x12eb428, ExecProcNode = 0x6ee438 ,       ExecProcNodeReal = 0x6ee438 , 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 , expr = 0x12eb640, evalfunc_private = 0x6cb43e ,   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 , 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 , 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 },     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, arg = {      0 }, argnull = {false }}}(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 , 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 },     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, arg = {      0 }, argnull = {false }}}(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 , 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 },     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, arg = {      0 }, argnull = {false }}}

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->combinedprojCannot access memory at address 0x0

简单来说,整个过程大体如下:
每个Group的列信息会存储在aggstate->perhash中,按阶段(aggstate->phases)逐个执行.
扫描数据表,在遍历tuple的时候,通过hash函数比对(Key为最小化tuple)找到/创建相应的Group组aggstate->perhash(hash table),提取tuple中相应的列值作为参数输入到aggstate->pertrans中定义的转换函数中,解析执行结果并存储,最后执行投影操作,把最终结果返回给客户端

"PostgreSQL聚合函数的实现方法是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数据 步骤 函数 信息 输入 数组 结构 阶段 模式 存储 只有 大小 指针 数据结构 状态 结果 表达式 面的 投影 支持 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 FGO服务器数据互通吗 中专网络技术的学费 菲律宾软件开发工资水平 英灵神殿加入服务器版本不兼容 网络安全毕业项目 数据库管理与应用电大教学大纲 数据库之间传输数据过慢 混凝土搅拌站系统数据库 数据库组合关键词怎么设置 新版英雄联盟无法连接服务器 深圳嵌入式软件开发大概多少钱 魂师对决服务器爆率高 网络技术部组建架构 app软件开发黑客专业技术 网络安全班会案例 数据库设计 机票预定系统 saas软件开发合同 烟台中科网络技术研究所规划 中国移动宽带增加了服务器吗 上海西城网络技术有限公司 中经网软件开发公司干什么的 建设网络安全对抗实验室 oracle 数据库启动 软件开发人才队伍建设 路由器的dhcp服务器如何设置 上海软件开发驻场费用是多少 网易云邮箱显示对方服务器未响应 文投科技互联网 徐汇区营销软件开发市场报价 服务器可以改家用电脑吗
0