admin管理员组文章数量:1657207
PgSQL
PgSQL-执行器机制-Unique算子
PgSQL中输出去重的元组有多种方法,比如通过HashAgg或者GroupAgg。这里我们介绍第三种方法,通过Unique算子来完成这个功能。当然语句上可以是:select distinct(id1) from t;
1、ExecUnique
执行器执行算子的函数都是ExecXXX,其中XXX代表某个算子。Unique算子的执行是由函数ExecUnqiue完成,当然这个函数执行的前提是Unique节点的子节点传来的元组是有序的,比如子节点是Sort算子。
执行逻辑比较简单:
ExecUniqueouterPlan = 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进行初始化:
本文标签: PgSQL
版权声明:本文标题:PgSQL 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1717030446a529124.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论