Calcite在大数据系统中有着广泛的运用, 比如Apache Flink, Apache Drill等都大量使用了Calcite,理解Calcite的原理可以说已经成为理解大数据系统中SQL访问层实现原理的必备条件之一。

但是不少人在学习Calcite的过程中都发现关于Calcite的实践案例其实很少,本文就将为大家详细介绍如何基于Calcite框架的SQL语法扩展探索使之更符合你的业务需求,以及扩展SQL在数栈产品的应用实践。

Calcite介绍及用途

Calcite介绍

Apache Calcite是一个动态的数据管理框架,本身不涉及任何物理存储信息,而是专注在SQL解析、基于关系代数的查询优化,通过扩展方式来对接底层存储。

目前Apache Calcite被应用在广泛的数据开源系统中,比如Apache Hive、Apache Phoenix、Apache Flink等。

Calcite的用途

Calcite提供了ANSI标准SQL的解析,以及各种SQL 方言,针对来自于不同数据源的复杂SQL,在Calcite中会把SQL解析成SqlNode语法树结构,然后根据得到的语法树转换成自定义Node,通过自定义Node解析获取到表的字段信息、以及表信息、血缘等相关信息。

下图展示了一部分对外提供的接口信息:

sqlparser 解析模块主要提供了以下几种功能 :

• 解析SQL包含的所有表、字段信息

• 解析SQL的udf函数

• 解析SQL的血缘信息,包括表级血缘、字段血缘

• 解析自定义SqlNode

• api服务变量解析替换

SQL语法扩展

了解完Calcite是什么以及用途后,下面为大家分享Calcite SQL语法扩展的相关内容。

SQL语法扩展背景

在 sqlparser 中进行sql解析的场景中,有两种情况需要使用到自定义扩展,一是Calcite不支持的一些语法;二是在一些场景中存在sql中带有${var}自定义变量语法。

那么针对上面的这两种情况,Calcite的自定义扩展是如何实现的呢?自定义扩展主要涉及到以下三个文件:

• Parser.jj:Parser.jj是一个Calcite核心的语法和词法文件,基于Apache FreeMaker模版,该模版包含着变量,这些变量在编译时可以被替换

• parserImpl.ftl:提供自定义SQL语句、literals、dataType的实现方法

• config.fmpp:该文件是FMPP的配置文件,提供了SQL语句、literals、dataType的接口扩展入口

Calcite使用javacc作为语法解析器,freemaker作为模版,把parserImpls.ftl、config.fmpp、Parser.jj模版合成最终的语法词法文件,最终通过javacc编译成自定义的解析器源码,整体流程如下图所示:

扩展SQL实现

● 工程目录

● 扩展sql实现案例

支持以下limit相关语法以及数字可以写成${var}形式:

-> limit count, limit start count

-> limit count offset start

-> offset start limit count

在原生的Calcite解析是支持limit count语法的,但是由于返回SqlOrderBy对象内部类Operator的unparse方法在SQL输出过程中对原始SQL进行了改写,因此需要使用扩展SQL得到正确的SQL。

下面介绍一个limit offset语法扩展样例,扩展SQL如下:

select id, name from test where id > 3 order by id desc limit 1 offset ${offset_val}

整体流程如下:

01

Parser.jj 定义${var}变量的token词法DOLLAR_VARIABLE:



02

Parser.jj 扩展的变量方法接入,下面方法会在解析到limit、offset关键字后面的一个词时进行调用:



03

Parser.jj limit offset在select语法的核心处理逻辑:

-> 定义变量



主要定义了三个boolean类型的变量,isOffsetLimit表示offset limit 语法,isLimitOffset表示limit offset语法,isOnlyLimit表示limit count、limit start count语法。

-> 定义处理逻辑

-> 返回自定义SqlNode



针对符合上面的三个boolean条件时,使用自定义ExtendSqlOrderBy的扩展类。

04

parserImpl.ftl 定义扩展的SqlNode ExtendDollarVariable:



05

config.fmpp 定义包以及扩展实现类的import:



06

扩展SqlNode实现:

-> 变量实现sqlNode

-> 扩展limit实现类ExtendSqlOrderBy,该类实现了SqlOrderBy,并在此基础扩展了limit的SqlNode,以及isOffsetLimit、isLimitOffset、isOnlyLimit三个boolean标识limit的不同语法



通过上面的这些步骤后,最后解析生成的SqlNode语法树如下所示:

扩展SQL在数栈的应用

目前袋鼠云的底层sqlparser sql解析涉及的子产品应用包括API数据服务离线开发客户数据洞察(标签)实时开发等,虽然大部分针对Calcite的SQL语法扩展相对于上层的产品应用感知不是很明显,但是扩展SQL还是解决了一些痛点,主要如下:

• 逐渐替换底层采用了多种解析工具解析的情况,使维护更简单,减少bug的产生

• 解决一些不支持的语法,避免在上层业务层做处理或者在底层做一些特殊处理

以在API数据服务后续接入的like语法改造为例为大家进行分享,目前的API数据服务中支持like ${var}语法,在执行测试中通过传递like语法来确定执行的模糊匹配方式,例如%xx、xx%、%xx%。

收到客户提出的优化like语法场景,袋鼠云本着客户第一的原则,这种合理的优化需求是采纳的。SQL支持like%${var}、${var}%、%${var}%,这样在执行测试中就不需要输入%了,目前扩展SQL语法已经支持这种优化的like语法,预计在2023年上半年会接入进去,下面通过API数据服务展示当前like SQL和扩展后的SQL差异:

● 当前like ${var}处理

-> 生成API

-> 测试执行,模糊匹配需要输入%

● 扩展like %${var}%

-> 生成API

-> 测试执行,由于在SQL阶段已经写了模糊匹配方式,因此可以直接输入值

总结规划

相信通过上面的案例后,大家对于Calcite扩展SQL语法的流程应该有了大致的了解,目前在袋鼠云的业务场景中已经扩展了许多语法,在未来还有一些工作需要进行优化:

• 丰富SQL语法,实现不同数据源扩展SQL语法的隔离

• 逐渐通过SQL语法扩展替换掉底层Calcite和druid共同解析的场景,避免维护多套相同的解析,减少线上问题产生

最后如果是初步接触Calcite SQL语法扩展的同学们,建议先熟悉javacc语法。

地址:https://javacc.github.io/javacc/

想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szbky

同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:30537511,项目地址:https://github.com/DTStack

看这篇就够了丨基于Calcite框架的SQL语法扩展探索的更多相关文章

  1. .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.html 本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新 ...

  2. Vue学习看这篇就够

    Vue -渐进式JavaScript框架 介绍 vue 中文网 vue github Vue.js 是一套构建用户界面(UI)的渐进式JavaScript框架 库和框架的区别 我们所说的前端框架与库的 ...

  3. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  4. React入门看这篇就够了

    摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所有. React 背景介绍 React 入门实例教程 React 起源于 ...

  5. net core体系-web应用程序-4asp.net core2.0 项目实战(CMS)-第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了   原文链接:https://www.cnblogs.com/yilezhu/p/9985451.ht ...

  6. [转]React入门看这篇就够了

    摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所有. React 背景介绍 React 入门实例教程 React 起源于 ...

  7. .Net6 微服务之Polly入门看这篇就够了

    前言 O(∩_∩)O 大家好!书接上文,本文将会继续建立在 .Net6 使用 Ocelot + Consul 看这篇就够了 项目的基础上进行Polly的介绍,然后这篇文章只是个人学习与分享,不喜勿喷, ...

  8. .Net6 微服务之Ocelot+IdentityServer4入门看这篇就够了

    前言 .Net 6 使用 Consul 实现服务注册与发现 看这篇就够了.Net6 使用 Ocelot + Consul 看这篇就够了.Net6 微服务之Polly入门看这篇就够了 书接上文,本文将继 ...

  9. ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

    引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...

  10. 想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!

    想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!   很多通信系统发展到某种程度都会有小型化的趋势.一方面小型化可以让系统更加轻便和有效,另一方面,日益发展的IC**技术可以用更低的成本生产 ...

随机推荐

  1. CDH6.3.2下安装部署Qualitis数据质量分析的计算服务Linkis1.3.2

    快速搭建Qualitis手册 一.基础软件安装 Gradle (4.6) MySQL (5.5+) JDK (1.8.0_141) Linkis(1.0.0+), 必装Spark引擎.如何安装Link ...

  2. ATT&CK实战系列(三)红日靶场3

    本次打靶练习是一个黑盒测试.没有密码,我们的目标是拿到域控制器的权限,并找到其中的重要文件. 网络拓扑 网卡设置 centos为出网机,第一次运行,需重新获取桥接模式网卡ip. 需重启网络服务serv ...

  3. post数据到第三方,中文乱码

    1.项目中发现 测试环境 推送正文,数据正常 2.生产到腾讯云之后,中文推送过去乱码,但是post 接口的 时候,指定了 编码格式. 3.后查看日志,发现日志中记录的中文就是乱码 4.排查cs代码文件 ...

  4. MySQL查询当前连接数的语句

    1. 查看当前总连接数 SHOW STATUS LIKE 'Threads_connected'; 返回当前建立的连接总数 2. 查看最大连接数配置 SHOW VARIABLES LIKE 'max_ ...

  5. Lua程序设计笔记

    未学:第10章URL编码及以后的示例 13章位和字节 Lua语言基础 一组命令或表达式组成的序列叫chunk程序段,因为Lua语言可以被用作数据定义语言,chunk的大小没有限制,几MB的程序段也很常 ...

  6. 【JVM之内存与垃圾回收篇】本地方法栈

    本地方法栈 Java 虚拟机栈于管理 Java 方法的调用,而本地方法栈用于管理本地方法的调用. 本地方法栈,也是线程私有的. 允许被实现成固定或者是可动态扩展的内存大小.(在内存溢出方面是相同的) ...

  7. 【软件】DVDStyler报错找不到VOB文件

    DVDStyler失败报错找不到VOB文件 零.错误如下 ERR: 2 opening input video file "D:\Minuhy\Desktop\dvd\t\dvd-cache ...

  8. python tkinker答题工具简易实现

    分享一个简单的python tkinker实现的答题工具,效果参见https://www.bilibili.com/video/BV13e4y1E71d/ 点击查看代码 import tkinter ...

  9. 🎀隧道代理ip使用

    简介 隧道代理(Tunnel Proxy)是一种特殊的代理服务,它的工作方式是在客户端与远程服务器之间建立一条"隧道".这种技术常被用来绕过网络限制或提高网络安全性. 主要功能 I ...

  10. eolinker取数组数据合并成一个数据的方法

    有时候遇到数据存在某一个数组中,类似下图结构,而用到这些数据的接口又需要一个数据集合,比如这样[14224, 14223]. 思路使用后置脚本,创建一个集合,把这两项数据取出来来,然后放到集合里,脚本 ...