使用Calcite解析Sql做维表关联(一)

点击箭头处“蓝色字”,关注我们哦!!维表关联是离线计算或者实时计算里面常见的一种处理逻辑,常常用于字段补齐、规则过滤等,一般情况下维表数据放在MySql等数据库里面,对于离线计算直接通过...
摘要由CSDN通过智能技术生成


点击箭头处“蓝色字”,关注我们哦!!

维表关联是离线计算或者实时计算里面常见的一种处理逻辑,常常用于字段补齐、规则过滤等,一般情况下维表数据放在MySql等数据库里面,对于离线计算直接通过ETL方式加载到Hive表中,然后通过sql方式关联查询即可,但是对于实时计算中Flink、SparkStreaming的表都是抽象的、虚拟的表,那么就没法使用加载方式完成。透过维表服务系列里面讲到的维表关联都是使用编码方式完成,使用Map或者AsyncIO方式完成,但是这种硬编码方式开发效率很低,特别是在实时数仓里面,我们希望能够使用跟离线一样sql方式完成维表关联操作。

在Flink1.9中提供了使用sql化方式完成维表关联,只需要实现LookupableTableSource接口即可,可以实现同步或者异步关联。在1.9之前就需要自己实现sql语法解析,然后在转换为API方式,对上层提供sql语法。看一个sql语句:

select * from orders o join gdsInfo g on o.gdsId=g.gdsId

orders表示流表,gdsInfo 表示维表。根据sql解析顺序先 from 部分、然后where 部分、最后select,那么对于join 方式,相当于join生成了一张临时表,然后去select 这张临时表,因此可以确认

sql解析流程:

1. 识别出流表与维表
2. 解析join部分,生成临时表

3. select 临时表

现在使用calcite解析这条语句

public class ParseDemo {


    public static void main(String[] args) {
        //假设gdsInfo就是维表
        String sql = "select * from orders o join gdsInfo g on o.gdsId=g.gdsId";


        SqlParser.Config config = SqlParser.configBuilder().setLex(Lex.MYSQL).build();
        SqlParser sqlParser = SqlParser.create(sql, conf
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Calcite是一个开源的SQL解析和优化引擎,它提供了一个SQL测试框架,可以用来测试各种SQL语句的正确性和性能。 要使用CalciteSQL测试库,需要按照以下步骤进行操作: 1. 克隆Calcite的代码库到本地,并进入到`calcite/core`目录下; 2. 使用Maven构建Calcite的测试库:`mvn clean install -DskipTests -Pskip-spark,skip-flink`; 3. 进入到`calcite-core/target`目录下,可以看到生成了一个`calcite-core-XXX-tests.jar`文件; 4. 将这个jar文件添加到你的项目依赖中; 5. 在你的测试代码中,使用`org.apache.calcite.test.CalciteAssert`类提供的API来执行SQL语句的测试。 以下是一个简单的示例: ```java @Test public void testSql() { final String sql = "SELECT empno, ename FROM emp WHERE deptno = 10"; final String expected = "EMPNO=7369; ENAME=SMITH\n" + "EMPNO=7499; ENAME=ALLEN\n" + "EMPNO=7521; ENAME=WARD\n" + "EMPNO=7566; ENAME=JONES\n" + "EMPNO=7654; ENAME=MARTIN\n" + "EMPNO=7698; ENAME=BLAKE\n" + "EMPNO=7782; ENAME=CLARK\n" + "EMPNO=7839; ENAME=KING\n" + "EMPNO=7844; ENAME=TURNER\n" + "EMPNO=7876; ENAME=ADAMS\n" + "EMPNO=7900; ENAME=JAMES\n" + "EMPNO=7934; ENAME=MILLER\n"; CalciteAssert.that() .with("model", "inline:" + "{\n" + " version: '1.0',\n" + " defaultSchema: 'SCOTT',\n" + " schemas: [\n" + " {\n" + " type: 'custom',\n" + " name: 'SCOTT',\n" + " factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',\n" + " operand: {\n" + " jdbcDriver: 'org.hsqldb.jdbcDriver',\n" + " jdbcUrl: 'jdbc:hsqldb:res:/org/apache/calcite/test/Scott.sql',\n" + " jdbcUser: '',\n" + " jdbcPassword: ''\n" + " }\n" + " }\n" + " ]\n" + "}") .query(sql) .returns(expected); } ``` 这个示例中,我们使用了`CalciteAssert`类提供的`that()`方法来创建一个测试实例,然后使用`with()`方法来设置数据源的模型,使用`query()`方法来执行SQL语句,最后使用`returns()`方法来验证查询结果是否符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值