博客 / 詳情

返回

SQL 解析在 CloudQuery 中的應用

hi 好久不見!今天將為大家帶來一期乾貨滿滿的技術分享。

作為一款數據庫管控平台,大家通常認為 CloudQuery 的核心能力是對平台的管控,包括統一入口管理、權限體系、審計分析等,但實際上 CloudQuery 的核心技術點之一在於其獨特的 SQL 解析能力。

01SQL 解析功能界定

SQL 解析是指將結構化查詢語言( SQL 語句)轉換成可以被數據庫系統理解和執行的內部表示形式的過程。在執行 SQL 查詢之前,數據庫系統需要對查詢語句進行解析,以確定查詢語句的語法是否正確,是否存在語義錯誤,並生成執行計劃。

目前 SQL 解析工具有 Druid、JSqlParser、Apache Calcite、Presto 等,它們都提供了一些 API 用於分析 SQL 語句中的信息,比如獲取表名、列名等字段。但是上述工具提供的 SQL 解析功能通常封裝性比較強,擴展性不足,支持的數據源有限,在許多特殊場景下它們無法準確的給出 SQL 解析結果。

因此, CloudQuery 技術團隊選擇使用 ANTLR 作為 SQL 解析的引擎。ANTLR 作為 SQL 解析引擎具有很多優勢,它幫助我們構建高效、可擴展和易於維護的 SQL 解析器。

02SQL 解析原理介紹SQL

解析是將用户輸入的 SQL 語句轉換為數據庫能夠理解的結構化查詢語言的過程,與普通編程語言的解析無本質區別。主要分為詞法分析、語法分析、語義分析、優化、代碼生成這些步驟。SQL 解析的原理可以分為兩個主要階段:詞法分析和語法分析。詞法分析詞法分析是將 SQL 語句分解為一個個單獨的 Token,標識每一個關鍵字、符號或者其他語法元素的過程。詞法分析器會逐個讀取 SQL 語句中的字符,根據預定義好的規則組成不同的 Token,並將 Token 序列傳遞給下一個步驟。比如,下面是一個簡單的 SELECT 語句:
SELECT FirstName FROM Employee WHERE Department = 'Sales'

在進行詞法分析後,將生成的 Token 序列如下:

圖片' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)

語法分析語法分析是將 Token 序列轉換成語法分析樹,並進行語義分析、類型檢查等處理的過程。語法分析器會根據事先定義好的 SQL 語法規則,將 Token 序列轉換為語法分析樹,並對其進行分析,以確定 SQL 語句是否符合語法規範。

比如,針對上述 SELECT 語句,語法分析器會將其轉換為以下語法分析樹:
SELECT_STATEMENT/ | \ \SELECT COLUMN_LIST FROM WHERE| | |FirstName Employee Department = 'Sales'SQL

語句數據收集在經過詞法分析和語法分析的步驟後,我們就得到了一棵語法分析樹。我們要收集 SQL 語句中的表名、列名、表達式等信息,其實就是遍歷這個語法樹的各個節點,將想要獲取的信息保存下來。

在上面的語法樹中,我們通過訪問 COLUMN_LIST 節點可以獲取到語句中查詢的列名,通過 FROM 節點可以獲取到語句中查詢的表名,通過WHERE 節點可以獲取到語句中的查詢條件。有了這些信息,我們就可以基於這些信息做許多數據庫方面的功能,比如 SQL 語句權限管控、SQL 合法性檢查、SQL 高危操作檢查等。

03SQL 解析在 CloudQuery 中的應用

CloudQuery 很多功能的實現都離不開強大的 SQL 解析能力,SQL 解析是 CQ 穩步前行的一大基石。

SQL 高亮

在編輯框中輸入一條 SQL 語句,可以看到語句中的關鍵字部分 SELECT、FROM、WHERE 會被渲染成藍色,這其實就是上面講到的詞法分析的應用。

圖片' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)

在語句經過詞法分析後,語句會變成一系列 Token,Token 代表了語句中不同類型的字符。Token 大致上可以分為關鍵字、標識符、數字、字符串、註釋這幾種,然後編輯器就可以根據這幾種類別,將用户輸入的 SQL 語句進行着色。

語法提示

我們在輸入 SQL 的過程中,比如輸入下面的文本:SELECT * FROM SYS.通常輸入到這裏的時候,我們希望提示出 SYS 下面的一些信息來幫助我們快速寫完 SQL,比如提示出表名、視圖名、函數名等。目前 CloudQuery 在用户書寫 SQL 語句的過程中有完善的智能提示功能, 包括提示出關鍵字、表名、列名、函數名、子查詢別名等。這裏 SQL 的智能提示技術就是上面講到的語法分析的應用,當我們輸入 SELECT  FROM SYS. 的時候,其實已經經過語法分析構成了一棵語法樹,只是這棵語法樹不完整,CloudQuery 在用户輸入 SQL 語句時會實時遍歷語法樹,找出當前語法樹中缺失的節點,在例子中缺失的節點就是表名節點,由此可以得到我們當前提示信息應該是 SYS 下的表名或視圖名。

圖片

SQL 語句權限控制CloudQuery 使用基於角色的權限訪問控制體系,權限控制粒度可以詳細到每一種 SQL 語句、每一個數據庫對象。比如常用的 SELECT、UPDATE、DELETE、CREATE TABLE、CREATE FUNCTION、函數調用等語句。

這裏語句權限的控制就是 SQL 解析的重要應用場景,CloudQuery 在接收到用户輸入的 SQL 語句後,會經過上述的詞法分析和語法分析步驟,再遍歷語法樹收集 SQL 語句中的信息。在信息收集過程中,會提取出 SQL 語句中涉及到的所有表名、列名、別名、函數、查詢條件等信息,接下來會對這些信息做進一步加工處理,比如消除 TABLE 的別名、綁定列的來源表、對象的真實類型查詢等。

無權限的用户輸入下面的SQL語句,將會受到權限管控:SELECT * FROM "SYS"."ACCESS$" LEFT JOIN "SYS"."ACLMV$";DELETE FROM "CQ"."USER" WHERE ID = 1;CREATE OR REPLACE FUNCTION GET_UUID RETURN VARCHAR2 IS uuid VARCHAR2(32);BEGIN uuid := REPLACE(SYS_GUID(),'-','');RETURN uuid;END;BEGIN"CQ"."GET_UUID"();END;

圖片' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)

動態過濾數據行CloudQuery 支持數據行安全控制,行安全控制是 CloudQuery 的一項安全特性,它允許管理員定義基於行的安全規則,以限制用户在表中的訪問權限。使用行安全控制,可以根據用户的角色、組織、部門等信息來動態控制數據的可見性,從而增強數據庫的安全性。

CloudQuery 的行安全控制條件支持任意的 SQL 表達式、支持引用用户的任何參數值、支持引用系統級別的參數值、支持引用環境變量等。下面用一個例子説明行安全控制的使用場景: 存在一張業務數據表,其中有一個部門字段( dept ),管理員希望普通用户在查詢這張表裏的數據時,只能查詢到自己部門的數據。在 CloudQuery 可以通過給表配置行安全控制實現上面的需求,配置方式類似下面這樣:

DEPT = '${USER.DEPT}'上面配置中 DEPT 是表中的列名, ${USER.DEPT} 是引用用户的部門參數,在真正執行 SQL 時這裏會被替換成用户的真實部門值。

用户在執行下面的 SQL 語句時:SELECT FROM DEPT;最終執行的 SQL 會被修改成:SELECT FROM DEPT WHERE DEPT = 'dept1';行安全控制的實現方式也依賴於 SQL 解析,在經過前面所説的詞法分析、語法分析、SQL 語句信息收集這幾步後,我們可以收集到語句中的需要行過濾的表名,當然還要知道這個表名所在的 SELECT 語句的位置信息,以及所在 SELECT 語句中 FROM 的位置和WHERE條件的位置。通過這些信息,我們就可以對原始語句進行改寫。

以上就是 SQL 解析在 CloudQuery 中的基本應用,正是憑藉強大的 SQL 解析能力,CloudQuery 持續不斷地為用户提供穩定高效的操作體驗。

圖片

user avatar u_16163442 頭像 u_16163452 頭像 sphereex 頭像
3 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.