Apache|Apache Calcite进行SQL解析(java代码实例)
背景
当一个项目分了很多模块,很多个服务的时候,一些公共的配置就需要统一管理了,于是就有了元数据驱动!
简介
什么是Calcite?
是一款开源SQL解析工具, 可以将各种SQL语句解析成抽象语法树AST(Abstract Syntax Tree), 之后通过操作AST就可以把SQL中所要表达的算法与关系体现在具体代码之中。
Calcite能做啥?
- SQL 解析
- SQL 校验
- 查询优化
- SQL 生成器
- 数据连接
上代码:
SQL语句转化:
public static SqlNode parseStatement(String sql) {SqlParser parser = SqlParser.create(sql, config.getParserConfig()); try {return parser.parseQuery(); } catch (Exception e) {e.printStackTrace(); throw new UnsupportedOperationException("operation not allowed"); }}
解析Select中的表名:
private static Set extractSourceTableInSelectSql(SqlNode sqlNode, boolean fromOrJoin) {if (sqlNode == null) {return new HashSet<>(); }final SqlKind sqlKind = sqlNode.getKind(); if (SqlKind.SELECT.equals(sqlKind)) {SqlSelect selectNode = (SqlSelect) sqlNode; Set selectList = new HashSet<>(extractSourceTableInSelectSql(selectNode.getFrom(), true)); selectNode.getSelectList().getList().stream().filter(node -> node instanceof SqlCall).forEach(node -> selectList.addAll(extractSourceTableInSelectSql(node, false))); selectList.addAll(extractSourceTableInSelectSql(selectNode.getWhere(), false)); selectList.addAll(extractSourceTableInSelectSql(selectNode.getHaving(), false)); return selectList; if (SqlKind.JOIN.equals(sqlKind)) {SqlJoin sqlJoin = (SqlJoin) sqlNode; Set joinList = new HashSet<>(); joinList.addAll(extractSourceTableInSelectSql(sqlJoin.getLeft(), true)); joinList.addAll(extractSourceTableInSelectSql(sqlJoin.getRight(), true)); return joinList; if (SqlKind.AS.equals(sqlKind)) {SqlCall sqlCall = (SqlCall) sqlNode; return extractSourceTableInSelectSql(sqlCall.getOperandList().get(0), fromOrJoin); if (SqlKind.IDENTIFIER.equals(sqlKind)) {Set identifierList = new HashSet<>(); if (fromOrJoin) {SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode; identifierList.add(sqlIdentifier.toString()); }return identifierList; Set defaultList = new HashSet<>(); if (sqlNode instanceof SqlCall) {SqlCall call = (SqlCall) sqlNode; call.getOperandList().forEach(node -> defaultList.addAll(extractSourceTableInSelectSql(node, false))); return defaultList; }
解析Insert语句中的表名:
private static Set extractSourceTableInInsertSql(SqlNode sqlNode, boolean fromOrJoin) {SqlInsert sqlInsert = (SqlInsert) sqlNode; Set insertList = new HashSet<>(extractSourceTableInSelectSql(sqlInsert.getSource(), false)); final SqlNode targetTable = sqlInsert.getTargetTable(); if (targetTable instanceof SqlIdentifier) {insertList.add(((SqlIdentifier) targetTable).toString()); }return insertList; }
执行效果
private static final String sql0 = "SELECT MIN(relation_id) FROM tableA JOIN TableBGROUP BY account_instance_id, follow_account_instance_id HAVING COUNT(*)>1"; private static final String sql1 = "SELECT * FROM blog_user_relation a WHERE (a.account_instance_id,a.follow_account_instance_id) IN (SELECT account_instance_id,follow_account_instance_id FROM Blogs_info GROUP BY account_instance_id, follow_account_instance_id HAVING COUNT(*) > 1)"; private static final String sql2 = "select name from (select * from student)"; private static final String sql3 = "SELECT * FROM Student LEFT JOIN Grade ON Student.sID = Grade.gID\n" +"UNION\n" +"SELECT * FROM Student RIGHT JOIN Grade ON Student.sID = Grade.gID"; private static final String sql4 = "SELECT *\n" +"FROM teacher\n" +"WHERE birth = (SELECT MIN(birth)\n" +"FROM employee)"; private static final String sql5 = "SELECT sName\n" +"FROM Student\n" +"WHERE '450' NOT IN (SELECT courseID\n" +"FROM Course\n" +"WHERE sID = Student.sID)"; final SqlNode sqlNode0 = parseStatement(sql0); System.out.println("sqlNode0: " + extractSourceTableInSelectSql(sqlNode0, false));
结果为:
文章图片
【Apache|Apache Calcite进行SQL解析(java代码实例)】到此这篇关于Apache Calcite进行SQL解析的文章就介绍到这了,更多相关Apache Calcite解析内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Apache|Apache Log4j2 报核弹级漏洞快速修复方法
- 字节跳动基于 Apache Hudi 的多流拼接实践方案
- 数据分析|竞品分析
- 发现一个很nice的API调试工具!
- Python|使用python对全球最新疫情情况进行可视化地图绘制!
- Apache Impala架构解析及与Hive、SparkSQL的性能比较
- 超硬核解析!Apache|超硬核解析!Apache Hudi灵活的Payload机制
- 数据库上云实践(使用Ora2pg进行数据库迁移)
- Apache+tomcat实现应用服务器集群
- 周日直播|Apache|周日直播|Apache Pulsar 2.10.0 新特性解析