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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: Calcite在大数据系统中有着广泛的运用, 比如Apache Flink, Apache Drill等都大量使用了Calcite,理解Calcite的原理可以说已经成为理解大数据系统中SQL访问层实现原理的必备条件之一。本文就为大家详细介绍如何基于Calcite框架的SQL语法扩展探索使之更符合你的业务需求,以及扩展SQL在数栈产品的应用实践。对该技术感兴趣的同学点进文章阅读哦

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=szalykfz

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

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
目录
相关文章
|
3月前
|
SQL 数据采集 自然语言处理
NL2SQL之DB-GPT-Hub<详解篇>:text2sql任务的微调框架和基准对比
NL2SQL之DB-GPT-Hub<详解篇>:text2sql任务的微调框架和基准对比
|
2月前
|
SQL 监控 安全
Flask 框架防止 SQL 注入攻击的方法
通过综合运用以上多种措施,Flask 框架可以有效地降低 SQL 注入攻击的风险,保障应用的安全稳定运行。同时,持续的安全评估和改进也是确保应用长期安全的重要环节。
155 71
|
11天前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
1月前
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
106 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
5月前
|
SQL Java 数据库
建模底层逻辑问题之ORM框架建模中,执行SQL的过程中被抽象和组织是如何实现的
建模底层逻辑问题之ORM框架建模中,执行SQL的过程中被抽象和组织是如何实现的
|
1月前
|
SQL 安全 Java
除了Flask框架,还有哪些框架能防止SQL注入攻击?
这些框架都在安全方面有着较好的表现,通过它们的内置机制和安全特性,可以有效地降低 SQL 注入攻击的风险。然而,无论使用哪个框架,开发者都需要具备良好的安全意识,正确配置和使用框架提供的安全功能,以确保应用的安全可靠。同时,持续关注安全更新和漏洞修复也是非常重要的。
47 7
|
2月前
|
SQL 开发框架 .NET
突破T-SQL限制:利用CLR集成扩展RDS SQL Server的功能边界
CLR集成为SQL Server提供了强大的扩展能力,突破了T-SQL的限制,极大地拓展了SQL 的应用场景,如:复杂字符串处理、高性能计算、图像处理、机器学习集成、自定义加密解密等,使开发人员能够利用 .NET Framework的丰富功能来处理复杂的数据库任务。
|
2月前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
67 4
|
2月前
|
SQL 存储 关系型数据库
SQL `CREATE DATABASE` 语法
【11月更文挑战第10天】
70 3
|
2月前
|
SQL 关系型数据库 数据库
sql语法
【10月更文挑战第26天】sql语法
42 5