PgSQL-执行器机制-Unique算子

PgSQL-执行器机制-Unique算子

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

1、ExecUnique

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

执行逻辑比较简单:

php 复制代码
ExecUnique
  outerPlan = outerPlanState(node);//子计划节点
  resultTupleSlot = node->ps.ps_ResultTupleSlot;//返回的元组存在此处
  for (;;){//for循环找到最后一个重复的值
    slot = ExecProcNode(outerPlan);//从子节点拉取数据
    if (TupIsNull(slot)){//子节点拉取完
      return NULL;//执行结束
    }
    //总是返回第一个元组,第一个元组时resultTupleSlot为空
    if (TupIsNull(resultTupleSlot))
      break;
    //后面相同的记录进行Qual比较
    econtext->ecxt_innertuple = slot;
    econtext->ecxt_outertuple = resultTupleSlot;
    if (!ExecQualAndReset(node->eqfunction, econtext))
      break;//直到元组不同时结束循环
  }
  //将获取的元组拷贝到resultTupleSlot中并返回
  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进行初始化:

相关推荐
大圣编程1 小时前
Java 多维数组详解
java·开发语言
万法若空4 小时前
【算法-查找】查找算法
java·数据结构·算法
DianSan_ERP4 小时前
电商架构演进:如何在高并发场景下实现多平台API的标准化履约?
运维·前端·网络·安全·架构·自动化
恒5394 小时前
Linux文件系统I
linux·运维·服务器
阿成学长_Cain4 小时前
Linux ipcs 命令超全详解:查看共享内存 / 消息队列 / 信号量,IPC 运维必备
linux·运维·服务器·网络·数据库
黯然神伤8884 小时前
AlmaLinux设置软件下载源
linux·alma
青瓦梦滋5 小时前
协议定制/序列化-反序列化(Linux视角)
linux·服务器·网络·c++
HZZD_HZZD6 小时前
DL/T 645-2026新国标深度解读与智能电表协议适配实战:从帧结构变化到Java采集器升级的全链路改造方案
java·开发语言
碎_浪7 小时前
给键盘党的英语记忆工具:我做了一款「打字背单词」桌面应用
前端·程序员·ai编程
阿成学长_Cain8 小时前
Linux dirs命令详解|Bash目录堆栈管理快速切换目录实战教程
linux·运维·前端·数据库