首页 > 数据库 >【源码解析】postgresql having clause 是如何实现的 (2)

【源码解析】postgresql having clause 是如何实现的 (2)

时间:2023-08-11 21:01:05浏览次数:62  
标签:postgresql 23 clause 源码 vartype TARGETENTRY expr VAR resno

上一篇中,主要探究了 postgresql 源码层面是怎么实现聚合函数的。本篇将探究 having clause 是如何实现的。

setup

create table foo(a int, b int);
insert into foo select random() * i/2, random() * i from generate_series(10, 20) g(i);
select a, count(b) from foo group by a having count(b) > 1;

parser

image

the raw parse tree is:

(
   {RAWSTMT 
   :stmt 
      {SELECTSTMT 
      :targetList (
         {RESTARGET 
         :val 
            {COLUMNREF 
            :fields ("a")
            }
         }
         {RESTARGET 
         :val 
            {FUNCCALL 
            :funcname ("count")
            :args (
               {COLUMNREF 
               :fields ("b")
               :location 16
               }
            )
            }
         }
      )
      :fromClause (
         {RANGEVAR 
         :relname foo 
         }
      )
      :groupClause (
         {COLUMNREF 
         :fields ("a")
         }
      )
      :havingClause 
         {A_EXPR 
         :name (">")
         :lexpr 
            {FUNCCALL 
            :funcname ("count")
            :args (
               {COLUMNREF 
               :fields ("b")
               }
            )
            }
         :rexpr 
            {A_CONST 
            :val 1 
            }
         }
      }
   }
)

analyser

the query tree is:

{QUERY 
   :commandType 1 
   :rtable (
      {RANGETBLENTRY 
      :eref 
         {ALIAS 
         :aliasname foo 
         :colnames ("a" "b")
         }
      :rtekind 0 
      :relid 16398 
      :relkind r 
      }
   )
   :targetList (
      {TARGETENTRY 
      :expr 
         {VAR 
         :varno 1 
         :varattno 1 
         :vartype 23 
         }
      :resno 1 
      :resname a 
      :resorigtbl 16398 
      :resorigcol 1 
      }
      {TARGETENTRY 
      :expr 
         {AGGREF 
         :aggfnoid 2147 
         :aggtype 20 
         :args (
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 2 
               :vartype 23 
               }
            :resno 1 
            }
         )
         :aggkind n 
         }
      :resno 2 
      :resname count 
      }
   )
   :groupClause (
      {SORTGROUPCLAUSE 
      :tleSortGroupRef 1 
      :eqop 96 
      :sortop 97 
      :hashable true
      }
   )
   :havingQual 
      {OPEXPR 
      :opno 419 
      :opfuncid 477 
      :opresulttype 16 
      :args (
         {AGGREF 
         :aggfnoid 2147 
         :aggtype 20 
         :args (
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 2 
               :vartype 23 
               }
            :resno 1 
            }
         )
         :aggkind n 
         }
         {CONST 
         :consttype 23 
         :constlen 4 
         :constbyval true 
         :constvalue 4 [ 1 0 0 0 0 0 0 0 ]
         }
      )
      }
   }

rewritter

In this simple case, the rewritter does nothing on the query tree.

planner/optimizer

{PLANNEDSTMT 
   :commandType 1 
   :planTree 
      {AGG 
      :plan.targetlist (
         {TARGETENTRY 
         :expr 
            {VAR 
            :varno -2 
            :varattno 1 
            :vartype 23 
            }
         :resno 1 
         :resname a 
         :ressortgroupref 1 
         :resorigtbl 16404 
         :resorigcol 1 
         }
         {TARGETENTRY 
         :expr 
            {AGGREF 
            :aggfnoid 2147 
            :aggtype 20 
            :aggtranstype 20 
            :aggargtypes (o 23)
            :args (
               {TARGETENTRY 
               :expr 
                  {VAR 
                  :varno -2 
                  :varattno 2 
                  :vartype 23 
                  }
               :resno 1 
               }
            )
            }
         :resno 2 
         :resname count 
         }
      )
      :plan.qual (
         {OPEXPR 
         :opno 419 
         :opfuncid 477 
         :opresulttype 16 
         :args (
            {AGGREF 
            :aggfnoid 2147 
            :aggtype 20 
            :aggtranstype 20 
            :aggargtypes (o 23)
            :args (
               {TARGETENTRY 
               :expr 
                  {VAR 
                  :varno -2 
                  :varattno 2 
                  :vartype 23 
                  :varnosyn 1 
                  :varattnosyn 2 
                  }
               :resno 1 
               }
            )
            }
            {CONST 
            :consttype 23 
            :constlen 4 
            :constbyval true 
            :constvalue 4 [ 1 0 0 0 0 0 0 0 ]
            }
         )
         }
      )
      :plan.lefttree 
         {SEQSCAN 
         :scan.plan.targetlist (
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 1 
               :vartype 23 
               :varnosyn 1 
               :varattnosyn 1 
               }
            :resno 1 
            :ressortgroupref 1 
            }
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 2 
               :vartype 23 
               :varnosyn 1 
               :varattnosyn 2 
               }
            :resno 2 
            }
         )
         }
      :aggstrategy 2 
      :numCols 1 
      :grpColIdx ( 1)
      :grpOperators ( 96)
      :numGroups 200 
      }
   :rtable (
      {RANGETBLENTRY 
      :eref 
         {ALIAS 
         :aliasname foo 
         :colnames ("a" "b")
         }
      :rtekind 0 
      :relid 16404 
      :relkind r 
      }
   )
   :relationOids (o 16404)
   }

executor

For a sql statement with having clause, the function project_aggregate needs
check the qualification condition by function ExecQual. The ExecQual
function evaluates the conditional expression by following steps:

EEOP_AGGREF
EEOP_FUNCEXPR_STRICT
EEOP_QUAL
EEOP_DONE

标签:postgresql,23,clause,源码,vartype,TARGETENTRY,expr,VAR,resno
From: https://www.cnblogs.com/lddcool/p/17623926.html

相关文章

  • 【更新V2.0】葫芦侠3楼一键自动签到工具及源码(可云函数)
    搬运吾爱破解论坛,作者佚名RJ,项目地址:【更新V2.0】葫芦侠3楼一键自动签到工具及源码(可云函数)-『原创发布区』-吾爱破解-LCG-LSG|安卓破解|病毒分析|www.52pojie.cn写在前面玩3楼的想必大家都被各版块签到所苦恼吧!今天分享的一键自动签到工具及源码就能快速解决你的问......
  • android_HAL框架源码分析
    ANDROIDHALAlbertLuoandroidHAL是什么?为什么有它?硬件抽象层是介于android内核kernel和上层之间的抽象出来的一层结构。他是对linux驱动的一个封装,对上层提供统一接口,上层应用不必知道下层硬件具体怎么实现工作的,它屏蔽了底层的实现细节。它在整个android架构中的位置如下图所......
  • zlmediakit源码学习(扩展支持定时抽帧)
    使用了很长时间的zlmediakit流媒体服务,一直对其精妙高效的设计实现十分好奇。最好的学习就是去二次开发实现一些小功能,同时摸索框架的代码结构在参考了zlmediakit的录像功能后,分析模仿它的源码结构,实现定时抽帧的功能。抽帧之后可以:1)进行算法分析;2)重新编码实现转码功能;3)算法分析......
  • nginx源码分析之http解码实现
    分析nginx是如何解析并且存储http请求的。对非法甚至恶意请求的识别能力和处理方式。可以发现nginx采用状态机来解析http协议,有一定容错能力,但并不全面相关配置 跟解码有关的配置 merge_slashes 语法merge_slasheson|off默认值on上下文httpserver说明支持解析请求行时,合并相......
  • 如何在32位ubuntu11.10 下编译android 4.0.1源码和goldfish内核
    一准备工作 1安装javasdk6(1)从jdk官方网站http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u29-download-513648.html下载jdk-6u29-linux-i586.bin文件。(2)执行jdk安装文件 [html] viewplaincopy1.$chmoda+xjdk-6u29-linux-i586.bin2.$jdk......
  • PostgreSQL从小白到专家 - 第25讲:窗口函数
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。第25讲:窗口函数内容1:窗口函数如何定义内容2:专用窗口函......
  • java.sql.SQLFeatureNotSupportedException: 这个 org.postgresql.jdbc.PgResultSet.g
    具体报错为:Errorattemptingtogetcolumn'DISEASENAME'fromresultset.Cause:java.sql.SQLFeatureNotSupportedException:这个org.postgresql.jdbc.PgResultSet.getNString(int)方法尚未被实作。;这个org.postgresql.jdbc.PgResultSet.getNString(int)方法尚未被实......
  • 直播源码连麦技术功能分享,你要的这里全有
    在直播源码的开发设计中,主播可以和观众进行连麦,可以给观众更直接的参与感,还能有利于提升直播平台用户活跃度和粘性。那么直播源码连麦技术是如何实现的呢?直播源码连麦功能流程图如下:一.需要连麦的观众发起连麦请求,进入连麦申请列表。二.主播从麦序中选择一名或多名观众进行连麦,从而......
  • PostgreSQL索引分类
    PostgreSQ支持空间和倒排索引普通索引也就是二级索引索引和数据是分开存储的索引查找数据即需要访问索引,又需要访问表,而表的访问是随机I/O。查询效率o(nlog(n))哈希索引只能用用于==查看查询效率o(1)通用搜索树(GeneralizedSearchTree)GiSTR树(radixtre......
  • 【Hystrix技术指南】(7)故障切换的运作流程原理分析(含源码)
    推荐超值课程:点击获取背景介绍目前对于一些非核心操作,如增减库存后保存操作日志发送异步消息时(具体业务流程),一旦出现MQ服务异常时,会导致接口响应超时,因此可以考虑对非核心操作引入服务降级、服务隔离。Hystrix说明官方文档Hystrix是Netflix开源的一个容灾框架,解决当外部依......