看這篇就夠了丨基於Calcite框架的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=szkyzg
同時,歡迎對大資料開源專案有興趣的同學加入「袋鼠雲開源框架釘釘技術qun」,交流最新開源技術資訊,qun號碼:30537511,專案地址:https://github.com/DTStack
- 從5分鐘到60秒,袋鼠雲數棧在熱重啟技術上的提效探索之路
- 詳細剖析|袋鼠雲數棧前端框架Antd 3.x 升級 4.x 的踩坑之路
- Teradata在華落幕,國產化崛起,袋鼠雲數棧會是更好的選擇嗎?
- 大資料應用場景下,標籤策略如何實現價值最大化?
- 袋鼠雲數棧UI5.0煥新升級,全新設計語言DT Design,更懂視覺更懂你!
- 一看就懂!任務提交的資源判斷在Taier中的實踐
- 看這篇就夠了丨基於Calcite框架的SQL語法擴充套件探索
- 無監控,不運維!深入淺出介紹ChengYing監控設計和使用
- DAG任務排程系統 Taier 演進之道,探究DataSourceX 模組
- 數字孿生賦能智慧港口解決方案,助力港口數字化轉型
- Iceberg在袋鼠雲的探索及實踐
- Kerberos身份驗證在ChunJun中的落地實踐
- 從資料治理到資料應用,製造業企業如何突破數字化轉型困境丨行業方案
- 行業方案 | 新規落地,企業集團財務公司如何構建數智財務體系?
- 資料安全新戰場,EasyMR為企業築起“安全防線”
- ChunJun框架在資料還原上的探索和實踐 | Hadoop Meetup精彩回顧
- 開源直播課丨大資料整合框架ChunJun類載入器隔離方案探索及實踐
- 啟用資料價值,探究DataOps下的資料架構及其實踐丨DTVision開發治理篇
- 實用五步法教會你指標體系的設計與加工
- 他來了!袋鼠雲大資料基礎平臺EasyMR正式上線