在了解了窗口函数实现原理 spark、hive中窗口函数实现原理复盘 和 sparksql比hivesql优化的点(窗口函数)之后,今天又撸了一遍hive sql 中窗口函数的源码实现,写个笔记记录一下。

简单来说,窗口查询有两个步骤:将记录分割成多个分区;然后在各个分区上调用窗口函数。

传统的 UDAF 函数只能为每个分区返回一条记录,而我们需要的是不仅仅输入数据是一张表,输出数据也是一张表(table-in, table-out),因此 Hive 社区引入了分区表函数 Partitioned Table Function (PTF)。

1、代码流转图

PTF 运行在分区之上、能够处理分区中的记录并输出多行结果的函数。

hive会把QueryBlock,翻译为执行操作树OperatorTree,其中每个operator都会有三个重要的方法:

  • initializeOp()  --初始化算子

  • process()    --执行每一行数据

  • forward()   --把处理好的每一行数据发送到下个Operator

当遇到窗口函数时,会生成PTFOperator,PTFOperator 依赖PTFInvocation读取已经排好序的数据,创建相应的输入分区:PTFPartition inputPart;

WindowTableFunction 负责管理窗口帧、调用窗口函数(UDAF)、并将结果写入输出分区: PTFPartition outputPart。

2、其它细节

PTFOperator.process(Object row, int tag)-->PTFInvocation.processRow(row)

void processRow(Object row) throws HiveException {  if ( isStreaming() ) {    handleOutputRows(tabFn.processRow(row));  } else {    inputPart.append(row);     //主要操作就是把数据 append到 ptfpartition中,这里的partition与map-reduce中的分区不同,map-reduce分区是按照key的hash分,而这里是要把相同的key要放在同一个ptfpartition,方便后续的windowfunction操作  }}

真正对数据的操作是当相同的key完全放入同一个ptfpartition之后,时机就是finishPartition:

void finishPartition() throws HiveException {  if ( isStreaming() ) {    handleOutputRows(tabFn.finishPartition());  } else {    if ( tabFn.canIterateOutput() ) {      outputPartRowsItr = inputPart == null ? null :        tabFn.iterator(inputPart.iterator());    } else {      outputPart = inputPart == null ? null : tabFn.execute(inputPart);       //这里TableFunctionEvaluator      outputPartRowsItr = outputPart == null ? null : outputPart.iterator();    }    if ( next != null ) {      if (!next.isStreaming() && !isOutputIterator() ) {        next.inputPart = outputPart;      } else {        if ( outputPartRowsItr != null ) {          while(outputPartRowsItr.hasNext() ) {            next.processRow(outputPartRowsItr.next());          }        }      }    }  }  if ( next != null ) {    next.finishPartition();  } else {    if (!isStreaming() ) {      if ( outputPartRowsItr != null ) {        while(outputPartRowsItr.hasNext() ) {          forward(outputPartRowsItr.next(), outputObjInspector);        }      }    }  }}

还有一个雷区,PTFPartition append():

public void append(Object o) throws HiveException {  if ( elems.rowCount() == Integer.MAX_VALUE ) {    //当一个ptfpartition加入的条数等于Integer.MAX_VALUE时会抛异常    throw new HiveException(String.format("Cannot add more than %d elements to a PTFPartition",        Integer.MAX_VALUE));  }  @SuppressWarnings("unchecked")  List<Object> l = (List<Object>)      ObjectInspectorUtils.copyToStandardObject(o, inputOI, ObjectInspectorCopyOption.WRITABLE);  elems.addRow(l);}

需要把相同key的数据完全放入一个ptfPartition进行操作,这时对加入的的条数做了限制,不能>=Integer.MAX_VALUE(21亿),这块需要注意。

我是小萝卜算子

在成为最厉害最厉害最厉害的道路上

很高兴认识你

~~ enjoy ~~

hive窗口函数_Hive sql窗口函数源码分析相关推荐

  1. RedBase SQL解析源码分析

    @原创文章,转载请注明: 转载自 镜中影的技术博客 本文链接地址: RedBase SQL解析源码分析) URL:http://blog.csdn.net/linkpark1904/article/d ...

  2. OpenGauss SQL解析源码分析

    OpenGauss SQL解析源码分析 SQL 引擎简介: SQL引擎整个编译的过程如下图所示,在编译的过程中需要对输入的SQL语言进行词法分析.语法分析.语义分析,从而生成逻辑执行计划,逻辑执行计划 ...

  3. 开源数据库OpenGauss的SQL解析源码分析

    首发于:blog: openGauss official blog - Gitee.com 一.   OpenGauss数据库体系概述 openGauss是关系型数据库,采用客户端/服务器,单进程多线 ...

  4. 【参赛作品16】openGauss SQL解析源码分析

    作者:梅氵 SQL 引擎简介: SQL引擎整个编译的过程如下图所示,在编译的过程中需要对输入的SQL语言进行词法分析.语法分析.语义分析,从而生成逻辑执行计划,逻辑执行计划经过代数优化和代价优化之后, ...

  5. MyBatis原理分析之四:一次SQL查询的源码分析

    上回我们讲到Mybatis加载相关的配置文件进行初始化,这回我们讲一下一次SQL查询怎么进行的. 准备工作 Mybatis完成一次SQL查询需要使用的代码如下: Java代码   String res ...

  6. 原理分析之四:一次SQL查询的源码分析

    上回我们讲到Mybatis加载相关的配置文件进行初始化,这回我们讲一下一次SQL查询怎么进行的. 准备工作 Mybatis完成一次SQL查询需要使用的代码如下: Java代码   String res ...

  7. MyBatis 源码分析 - SQL 的执行过程

    本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析.运 ...

  8. DVWA平台漏洞测试与源码分析(一)SQL注入

    DVWA平台是初学网络安全者了解十大漏洞的有效途径,此平台收集了当前威胁网络安全的最常见的十大漏洞,并且为各位初学者提供了靶场实验环境,我们可以利用此平台进行各种攻击实验,从而丰富自己对于Web安全的 ...

  9. [pig4cloud框架源码分析] 03 - MyBatis中的sql语句日志打印

    文章目录 导读 pig4cloud框架配置 Mybatis Log Plugin 插件开启方式 插件说明 [TODO]源码分析 拦截器方案实现sql日志查看 参考资料 导读 使用MyBatis开发过程 ...

最新文章

  1. 写那么多年Java,还不知道啥是Java agent 的必须看一下!
  2. 机器学习集成学习与模型融合!
  3. 《C程序设计的抽象思维》1.9编程练习
  4. ASP.NET MVC 防止 CSRF 的方法
  5. Metasploit之渗透安卓实战
  6. python元类的使用_Python 元类使用讲解
  7. iOS消息推送整体流程
  8. java模拟摇摆小球程序代码_Android实现左右摆动的球体动画效果
  9. 【nginx笔记】系统参数设置-使Nginx支持更多并发请求的TCP网络参数
  10. Linux总结篇 linux命令 虚拟机 - (二)
  11. Javaweb项目在线学习平台系统(Spring+SpringMVC+MyBatis)
  12. 整理了100个必备的 Python 函数,值得收藏
  13. matlab把数据乘,【excel怎么相乘】如何把EXCLE数据导入到MATLAB中
  14. java中CAE画实心圆的参数_java绘图中RenderingHints 参数
  15. 安装工程造价课程设计_安装工程造价课程设计心得体会及建议
  16. CentOS7下 SVN版本控制的安装(包括yum与非yum)的步骤记录。
  17. win10网络计算机打不开,win10网络和internet设置打不开怎么办_win10网络设置打不开无法打开的解决方法...
  18. CentOS 7 源码编译安装 Nginx
  19. pythontext函数用法汇总_Python - Text Summarization
  20. 基于Yocto构建嵌入式Linux系统U-boot、kernel内核、rootfs文件系统

热门文章

  1. CentOS 7 安装版本管理 GitLab
  2. JavaScript从入门到放弃 -(四)E5 新增方法
  3. Could not load TestContextBootstrapper [null]. Specify @BootstrapWith‘s ‘value‘ attribute...
  4. mysql获取用户权限api_AnalyticDB MySQL服务关联角色
  5. android 主流分辨率是多少,android 屏幕分辨率问题
  6. 项目的ar指什么_AR眼镜显示测评标准解读——概述
  7. Linux相关配置 集群免密码登录配置
  8. linux定时任务每两天执行,Linux定时任务 crontab每秒执行 实现2种方法
  9. 椭圆形中间一个大写的v_静安区椭圆形桥梁空心板橡胶气囊,方形桥梁板橡胶气囊_冠桥橡胶...
  10. 速卖通手机端怎样加入html,如何正确使用速卖通手机版的关联营销模板