看这篇就够了丨基于Calcite框架的SQL语法扩展探索

码农不哭
• 阅读 830

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框架的SQL语法扩展探索

Calcite的用途

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

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

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编译成自定义的解析器源码,整体流程如下图所示:

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

扩展SQL实现

● 工程目录

看这篇就够了丨基于Calcite框架的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:

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
02

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
03

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

-> 定义变量

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
主要定义了三个boolean类型的变量,isOffsetLimit表示offset limit 语法,isLimitOffset表示limit offset语法,isOnlyLimit表示limit count、limit start count语法。

-> 定义处理逻辑

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

-> 返回自定义SqlNode

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
针对符合上面的三个boolean条件时,使用自定义ExtendSqlOrderBy的扩展类。

04

parserImpl.ftl 定义扩展的SqlNode ExtendDollarVariable:

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
05

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
06

扩展SqlNode实现:

-> 变量实现sqlNode

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索
看这篇就够了丨基于Calcite框架的SQL语法扩展探索

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

扩展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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

● 扩展like %${var}%

-> 生成API

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

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

看这篇就够了丨基于Calcite框架的SQL语法扩展探索

总结规划

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

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

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

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

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

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

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

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
SQL优化器原理
摘要:在MaxCompute中,Join操作符的实现算法之一名为"HashJoin",其实现原理是,把小表的数据全部读入内存中,并拷贝多份分发到大表数据所在机器,在map阶段直接扫描大表数据与内存中的小表数据进行匹配。    这是MaxCompute有关SQL优化器原理的系列文章之一。我们会陆续推出SQL优化器有关优化规则和框架
李志宽 李志宽
4年前
SQL入门:什么是SQL,如何开始学习SQL?
前言:在我们的日常生活中,我们使用大量的应用程序、小工具和设备。每秒都会产生大量的数据。SQL提供了处理此类数据的标准方法。通过本文,我将向您解释什么是SQL及其演变的概念。本文将讨论以下主题:传统文件系统的问题自从计算机时代开始,数据存储就已经成为人们关注的主要问题之一。以前,我们通常将数据存储在基于文件的系统中,这会导致数据管理不当。尽管看起来组织得很
徐小夕 徐小夕
4年前
2年vue项目实战经验汇总
前言vue作为前端主流的3大框架之一,目前在国内有着非常广泛的应用,由于其轻量和自底向上的渐进式设计思想,使其不仅仅被应用于PC系统,对于移动端,桌面软件(electronjs)等也有广泛的应用,与此诞生的优秀的开源框架比如elementUI,iView,antdesignvue等也极大的降低了开发者的开发成本,并极大的提高了开发效率。笔者最初接触v
Wesley13 Wesley13
3年前
MySQL binlog2sql实现MySQL误操作的恢复
对于MySQL数据库中的误操作删除数据的恢复问题,可以使用基于MySQL中binlog做到类似于闪回或者生成反向操作的SQL语句来实现,是MySQL中一个非常实用的功能。原理不难理解,基于MySQL的row格式的binlog中,记录历史的增删改SQL信息,基于此解析出来对应的SQL语句(回滚的话就是反向的SQL语句)。在格式为binlog格式为r
Stella981 Stella981
3年前
Netty学习(3):文件操作
概述在Netty学习(2)中,我们先浅浅认识了NIO的3大核心组件,现在就让我们针对其深入学习,通过一些简单的文件操作来深入理解其中的Buffer和Channel的概念。文件写入将内存中的数据写入到文件中,如果文件不存在,那么就新建文件。//数据文件privat
Easter79 Easter79
3年前
Tensorflow应用之LSTM
学习RNN时原理理解起来不难,但是用TensorFlow去实现时被它各种数据的shape弄得晕头转向。现在就结合一个情感分析的案例来了解一下LSTM的操作流程。一、深度学习在自然语言处理中的应用自然语言处理是教会机器如何去处理或者读懂人类语言的系统,主要应用领域:对话系统聊天机器人(小冰)情感分析对一段文本进
Stella981 Stella981
3年前
Apache Calcite项目简介
文章导读:1.什么是Calcite?2.Calcite的主要功能?3.如何快速使用Calcite?什么是CalciteApacheCalcite是一个动态数据管理框架,它具备很多典型数据库管理系统的功能,比如SQL解析、SQL校验、SQL查询优化、SQL生成以及数据连接查询等,但是又省略了一些关键的功能,比如C
Wesley13 Wesley13
3年前
Mysql事务处理
事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!   删除的SQL语句deletefromuserinfowhere~~~d
数据堂 数据堂
2年前
自然语言理解数据与大语言模型的关系
自然语言理解数据在大语言模型中扮演着至关重要的角色。大语言模型是一种能够理解和生成自然语言的计算机程序,能够识别和学习语言中的规律和模式。自然语言理解数据是通过对自然语言进行标注和注释而生成的数据,其中包含了语法、语义、上下文、情感等信息。这些数据可以帮助
Vitess全局唯一ID生成的实现方案 | 京东云技术团队
为了标识一段数据,通常我们会为其指定一个唯一id,比如利用MySQL数据库中的自增主键。但是当数据量非常大时,仅靠数据库的自增主键是远远不够的,并且对于分布式数据库只依赖MySQL的自增id无法满足全局唯一的需求。因此,产生了多种解决方案,如UUID,Sn
数据堂 数据堂
1年前
大模型数据集:揭秘AI背后的魔法世界
一、引言在人工智能的奇幻世界中,大模型数据集如同神秘的魔法书,蕴藏着无尽的智慧与力量。它们为AI注入了生命,使其具备了理解和改变世界的能力。今天,就让我们一起揭开大模型数据集的神秘面纱,探索其背后的魔法世界吧!二、大模型数据集:智慧的宝库大模型数据集就如同
码农不哭
码农不哭
Lv1
红尘飘不到,时有水禽啼。
文章
2
粉丝
0
获赞
0