文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PostgreSQL执行聚合函数所使用的数据结构有哪些

2024-04-02 19:55

关注

这篇文章主要讲解了“PostgreSQL执行聚合函数所使用的数据结构有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PostgreSQL执行聚合函数所使用的数据结构有哪些”吧!

一、数据结构

AggState
聚合函数执行时状态结构体,内含AggStatePerAgg等结构体



//在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;                
    //targetlist和quals中所有的Aggref
    List       *aggs;            
    //链表的大小(可以为0)
    int            numaggs;        
    //pertrans条目大小
    int            numtrans;        
    //Agg策略模式
    AggStrategy aggstrategy;    
    //agg-splitting模式,参见nodes.h
    AggSplit    aggsplit;        
    //指向当前步骤数据的指针
    AggStatePerPhase phase;        
    //步骤数(包括0)
    int            numphases;        
    //当前步骤
    int            current_phase;    
    //per-Aggref信息
    AggStatePerAgg peragg;        
    //per-Trans状态信息
    AggStatePerTrans pertrans;    
    //长生命周期数据的ExprContexts(hashtable)
    ExprContext *hashcontext;    
    ////长生命周期数据的ExprContexts(每一个GS使用)
    ExprContext **aggcontexts;    
    //输入表达式的ExprContext
    ExprContext *tmpcontext;    
#define FIELDNO_AGGSTATE_CURAGGCONTEXT 14
    //当前活跃的aggcontext
    ExprContext *curaggcontext; 
    //当前活跃的aggregate(如存在)
    AggStatePerAgg curperagg;    
#define FIELDNO_AGGSTATE_CURPERTRANS 16
    //当前活跃的trans state
    AggStatePerTrans curpertrans;    
    //输入结束?
    bool        input_done;        
    //Agg扫描结束?
    bool        agg_done;        
    //最后一个grouping set
    int            projected_set;    
#define FIELDNO_AGGSTATE_CURRENT_SET 20
    //将要解析的当前grouping set
    int            current_set;    
    //当前投影操作的分组列
    Bitmapset  *grouped_cols;    
    //倒序的分组列链表
    List       *all_grouped_cols;    
    
    //-------- 下面的列用于grouping set步骤数据
    //所有步骤中最大的sets大小
    int            maxsets;        
    //所有步骤的数组
    AggStatePerPhase phases;    
    //对于phases > 1,已排序的输入信息
    Tuplesortstate *sort_in;    
    //对于下一个步骤,输入已拷贝
    Tuplesortstate *sort_out;    
    //排序结果的slot
    TupleTableSlot *sort_slot;    
    
    //------- 下面的列用于AGG_PLAIN和AGG_SORTED模式:
    //per-group指针的grouping set编号数组
    AggStatePerGroup *pergroups;    
    //当前组的第一个元组拷贝
    HeapTuple    grp_firstTuple; 
    
    //--------- 下面的列用于AGG_HASHED和AGG_MIXED模式:
    //是否已填充hash表?
    bool        table_filled;    
    //hash桶数?
    int            num_hashes;
    //相应的哈希表数据数组
    AggStatePerHash perhash;    
    //per-group指针的grouping set编号数组
    AggStatePerGroup *hash_pergroup;    
    
    //---------- agg输入表达式解析支持
#define FIELDNO_AGGSTATE_ALL_PERGROUPS 34
    //首先是->pergroups,然后是hash_pergroup
    AggStatePerGroup *all_pergroups;    
    //投影实现机制
    ProjectionInfo *combinedproj;    
} AggState;

//nodeag .c支持的基本选项
#define AGGSPLITOP_COMBINE        0x01    
#define AGGSPLITOP_SKIPFINAL    0x02    
#define AGGSPLITOP_SERIALIZE    0x04    
#define AGGSPLITOP_DESERIALIZE    0x08    

//支持的操作模式
typedef enum AggSplit
{
    
    //基本 : 非split聚合
    AGGSPLIT_SIMPLE = 0,
    
    //部分聚合的初始步骤,序列化
    AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE,
    
    //部分聚合的最终步骤,反序列化
    AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE
} AggSplit;

//测试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)

AggStatePerAggData
per-aggregate信息,这个结构体包含了调用最终函数的信息,用以从状态值中产生一个最终的聚合结果.如果查询中有多个相同的Aggrefs,共享相同的per-agg数据.


typedef struct AggStatePerAggData
{
    
    Aggref       *aggref;
    
    //该agg应使用的状态值索引
    int            transno;
    
    //final function函数的Oid(可以是InvalidOid)
    Oid            finalfn_oid;
    
    FmgrInfo    finalfn;
    
    int            numFinalArgs;
    
    //所有直接参数表达式的ExprStates
    List       *aggdirectargs;
    
    int16        resulttypeLen;
    bool        resulttypeByVal;
    
    bool        shareable;
}            AggStatePerAggData;

AggStatePerTransData
聚合状态值信息(per aggregate state value information), 通过输入行调用转换函数更新聚合状态值的工作状态.该结构体不会存储从转换状态而来的用于产生最终聚合结果的相关信息,这些信息会存储在AggStatePerAggData中.


typedef struct AggStatePerTransData
{
    
    
    Aggref       *aggref;
    
    bool        aggshared;
    
    int            numInputs;
    
    int            numTransInputs;
    
    //转换或组合函数Oid
    Oid            transfn_oid;
    
    //序列化函数Oid或InvalidOid
    Oid            serialfn_oid;
    
    //反序列化函数Oid或InvalidOid
    Oid            deserialfn_oid;
    
    //状态值数据类型Oid
    Oid            aggtranstype;
    
    FmgrInfo    transfn;
    
    //序列化函数fmgr
    FmgrInfo    serialfn;
    
    //反序列化函数fmgr
    FmgrInfo    deserialfn;
    
    //派生于聚合的输入排序规则
    Oid            aggCollation;
    
    //排序列个数
    int            numSortCols;
    
    
    //在DISTINCT比较时需考虑的排序列数
    int            numDistinctCols;
    
    //重组排序信息
    AttrNumber *sortColIdx;
    Oid           *sortOperators;
    Oid           *sortCollations;
    bool       *sortNullsFirst;
    
    FmgrInfo    equalfnOne;
    ExprState  *equalfnMulti;
    
    Datum        initValue;
    bool        initValueIsNull;
    
    int16        inputtypeLen,
                transtypeLen;
    bool        inputtypeByVal,
                transtypeByVal;
    
    //当前输入的tuple
    TupleTableSlot *sortslot;    
    //用于多列DISTINCT
    TupleTableSlot *uniqslot;    
    //输入元组描述符
    TupleDesc    sortdesc;        
    
    //排序对象,仅用于DISTINCT/ORDER BY
    Tuplesortstate **sortstates;    
    
    FunctionCallInfoData transfn_fcinfo;
    
    //序列化和反序列化函数信息
    FunctionCallInfoData serialfn_fcinfo;
    FunctionCallInfoData deserialfn_fcinfo;
}            AggStatePerTransData;

AggStatePerGroupData
per-aggregate-per-group工作状态,这些工作状态值在第一个输入tuple group时初始化,后续在处理每个输入tuple时更新.


typedef struct AggStatePerGroupData
{
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE 0
    //当前转换值
    Datum        transValue;        
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL 1
    bool        transValueIsNull;
#define FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE 2
    //如transValue尚未设置,则为T
    bool        noTransValue;    
    
}            AggStatePerGroupData;

AggStatePerPhaseData
per-grouping-set-phase状态.Grouping sets会被分拆为多个”步骤”,每一个单独的步骤在输入上都会完成一轮处理.


typedef struct AggStatePerPhaseData
{
    //该步骤使用的策略
    AggStrategy aggstrategy;    
    //grouping sets个数,如无则为0
    int            numsets;        
    //grouping sets的大小
    int           *gset_lengths;    
    //rollup(上卷)列组
    Bitmapset **grouped_cols;    
    //返回等价的表达式,比较列序号作为索引
    ExprState **eqfunctions;    
    //对应步骤数据的Agg节点
    Agg           *aggnode;        
    //该步骤的输入排序Sort节点
    Sort       *sortnode;        
    //转换函数解析
    ExprState  *evaltrans;        
}            AggStatePerPhaseData;

AggStatePerHashData
per-hashtable状态.使用哈希进行grouping set,每一个grouping set都会有一个这样的结构体.


typedef struct AggStatePerHashData
{
    //每一个group都有一个条目的哈希表
    TupleHashTable hashtable;    
    //访问哈希表的迭代器
    TupleHashIterator hashiter; 
    //装载哈希表的slot
    TupleTableSlot *hashslot;    
    //per-grouping-field哈希函数
    FmgrInfo   *hashfunctions;    
    //per-grouping-field等价函数
    Oid           *eqfuncoids;        
    //哈希键列个数
    int            numCols;        
    //哈希表中的列数
    int            numhashGrpCols; 
    //请求哈希最大的列
    int            largestGrpColIdx;    
    //输入slot中的hash col索引数组
    AttrNumber *hashGrpColIdxInput; 
    //hashtbl元组索引数组
    AttrNumber *hashGrpColIdxHash;    
    //元素的Agg节点,用于numGroups等等
    Agg           *aggnode;        
}            AggStatePerHashData;

感谢各位的阅读,以上就是“PostgreSQL执行聚合函数所使用的数据结构有哪些”的内容了,经过本文的学习后,相信大家对PostgreSQL执行聚合函数所使用的数据结构有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯