怎样从SQL中分析和提取访问的字段信息?| OceanBase实践

当执行任意一条SELECT SQL语句时,我们如何能够分析出所访问的字段信息,并进一步判断结果集中的每一列数据具体来自于哪些数据库、表以及表中的哪些字段呢?本文将会详细阐述针对此问题的技术解决方案。

应用场景

从 SQL 中解析访问的原始字段信息有一定难度,但是非常有用。一个典型的应用就是动态数据脱敏。动态数据脱敏是指数据以明文形式存储在介质中,在查询的时候根据用户权限动态地将敏感数据进行脱敏后展示。例如执行以下 SQL 时,将结果集中涉及员工邮箱和薪资信息的列数据,按照不同列对应的脱敏算法做了脱敏处理。

​​​​​​​动态脱敏演示样例

问题定义

输入:SQL

输出:结果集中的每一列所涉及的数据库、表和字段信息

技术方案

SQL 语法解析

语法解析的目的是将 SQL 文本转化为抽象语法树(Abstract Syntax Tree, AST),方便后续通过编程形式进行分析处理。以 OceanBase MySQL 兼容模式为例,使用 ANTLR4 作为解析器生成器,从 此处 获取 .g4 语法文件。编译生成对应的 Parser,然后就可以基于 Visitor 访问 AST 从 SQL 中提取想要的信息了。举个例子,对于以下 SQL:

SELECT tb.col FROM tb WHERE col1='abc';

解析成的 AST 如下:1714100898其中,每个节点对应语法文件中定义的一个 Token。例如,语法文件中对 SELECT 子句的起始 Token 定义为select_expr_list,则可以从 select_expr_list 节点的子节点中获取 SELECT 子句中使用的列信息。可以发现,直接访问 AST 来提取 SQL 中的关键信息是比较困难和低效的,因为需要对语法文件和 AST 的结构有清晰的了解。因此,推荐使用 ob-sql-parser。它是开源的基于 ANTLR4 构建的 SQL 解析器,可以将 SQL 文本翻译成 Pojo 类,让程序员可以像操作普通 Java 对象一样处理 SQL。对于上面的 SQL,其处理后的对象结构如下:

SQL Text
  └──Statement: Select
       └──selectBody: SelectBody
            ├──selectItems: List<Projection>
            │    └──Projection
            |         └──column: Expression
            |              └──RelationReference: tb.col
            ├──froms: List<FromReference>
            │    └──NameReference: tb
            └──where: Expression
                 └──CompoundExpression: col1='abc'

SELECT 字段检测

一条完整的 SELECT 语句中有且仅有以下类型的子句:

  • FROM 子句
SELECT * FROM table1;
  • JOIN 子句
SELECT * FROM table1 JOIN table2;
  • SELECT 子句
SELECT col1, col2+col3, func(col4, col5) FROM table1;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值