• PgSQL-执行器机制-Unique算子


    PgSQL-执行器机制-Unique算子

    PgSQL中输出去重的元组有多种方法,比如通过HashAgg或者GroupAgg。这里我们介绍第三种方法,通过Unique算子来完成这个功能。当然语句上可以是:select distinct(id1) from t;

    1、ExecUnique

    执行器执行算子的函数都是ExecXXX,其中XXX代表某个算子。Unique算子的执行是由函数ExecUnqiue完成,当然这个函数执行的前提是Unique节点的子节点传来的元组是有序的,比如子节点是Sort算子。

    执行逻辑比较简单:

    1. ExecUnique
    2. outerPlan = outerPlanState(node);//子计划节点
    3. resultTupleSlot = node->ps.ps_ResultTupleSlot;//返回的元组存在此处
    4. for (;;){//for循环找到最后一个重复的值
    5. slot = ExecProcNode(outerPlan);//从子节点拉取数据
    6. if (TupIsNull(slot)){//子节点拉取完
    7. return NULL;//执行结束
    8. }
    9. //总是返回第一个元组,第一个元组时resultTupleSlot为空
    10. if (TupIsNull(resultTupleSlot))
    11. break;
    12. //后面相同的记录进行Qual比较
    13. econtext->ecxt_innertuple = slot;
    14. econtext->ecxt_outertuple = resultTupleSlot;
    15. if (!ExecQualAndReset(node->eqfunction, econtext))
    16. break;//直到元组不同时结束循环
    17. }
    18. //将获取的元组拷贝到resultTupleSlot中并返回
    19. return ExecCopySlot(resultTupleSlot, slot);

    1)获取第一个元组时,node->ps.ps_ResultTupleSlot中没有数值,即为NULL

    2)从子节点拉取一个元组值,此时直接中断循环,将该元组值赋值给node->ps.ps_ResultTupleSlot并返回

    3)再次迭代进入ExecUnique函数,node->ps.ps_ResultTupleSlot仍旧是上次保存的元组值,不为空。For循环从子节点再拉取一个元组值,需要和上次保存的值进行比较,若相同则继续循环拉取下个值进行比较,直到和node->ps.ps_ResultTupleSlot值不相等

    4)退出循环后,将下一组的第一个值保存到node->ps.ps_ResultTupleSlot返回。

    这样就完成了数值的去重,这里重申下,使用ExecUnique的前提是子节点的元组是有序的。

    2、ExecQualAndReset

    看下实现的关键函数ExecQualAndReset,该函数通过表达式计算完成数值比较。

    表达式的计算步骤为ExprState *eqfunction。由函数ExecInitUnique进行初始化:

    5b6e880528482b4218c5889dfea7447b.png

  • 相关阅读:
    使用Nginx可视化管理工具+Cpolar在本地搭建服务器并实现远程访问【内网穿透】
    pycharm创建py文件时自动添加基础信息--模板
    【排序算法】快速排序
    瑞合信LED字幕WiFi卡使用教程(8.0版)
    vue高德地图(二):获取并标记用户位置
    如何将项目上线到云服务器
    【无标题】
    【Java面试】Zookeeper中的Watch机制的原理?
    Java基础:设计模式之原型模式
    [机缘参悟-90]:《本质思考》- 本质思考的9个陷阱
  • 原文地址:https://blog.csdn.net/yanzongshuai/article/details/134086351