calcite查询mysql_利用calcite查找sql语句中的原始列

本文探讨了如何利用Calcite在查询前改写SQL,以解决数据脱敏的问题。通过分析Calcite的词法和语法分析过程,找到校验SQL列的逻辑,并着重介绍了如何定位和改写SQL中的原始列,以达到在执行前添加UDF函数的目的,降低对原有代码的侵入性。
摘要由CSDN通过智能技术生成

曾经遇到这么个需求,大致描述一下就是需要改写原始的sql语句,为其中的某些字段加上udf函数。

比如说:

select name from emps where id = 1;

正常执行结果为:

xiaowang

name属于敏感信息,需要进行脱敏处理,并将其配置了脱敏策略,比如脱敏策略是:

hash_func(col,1,5,*),将前五位设置为*号。

那么执行这条sql语句查询结果为*****ang。

如果是在sql的执行计划中,查找的某个列,再去查找策略,再返回到执行计划。

这样会对原先的代码侵入性很多,而且不同的数据存储如果想接入这套脱敏的都需要自己实现一遍。比如Hive,SparkSql等。

正好因为接触过一点calcite,所以来分析一下,看能不能将这个问题简化,在一开始将sql语句改写,再去数据库中执行改写后的语句。这样能够解耦脱敏服务和数据存储组件。

改写为:

select hash_func(name,1,5,*) name from emps where id = 1;

所以问题就变成了如何查找sql语句中的原始列。

我们知道,在sql执行之前,有词法分析和语法分析。

就是先将sql解析成AST,再去和数据库的元信息进行校验。

比如,输入一条错误的sql语句:

select names from emps;

执行calcite中

org.apache.calcite.test.CsvTest#testSelectSingleProjectGz

@Test public void testSelectSingleProjectGz() throws SQLException {

sql("smart", "select names from EMPS").ok();

}

这条测试用例。将name 改为names。会报以下的错:

java.lang.RuntimeException: java.sql.SQLException: Error while executing SQL "select names from EMPS": From line 1, column 8 to line 1, column 12: Column 'NAMES' not found in any table

at org.apache.calcite.test.CsvTest$Fluent.ok(CsvTest.java:1054)

at org.apache.calcite.test.CsvTest.testSelectSingleProjectGz(CsvTest.java:183)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

at org.junit.internal.runners.s

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值