sqlparserx-core 是 SqlParserX 的核心解析模块。它在 Druid 语法树的基础上,针对不同数据源提供了统一的扩展解析能力:只需传入 SQL 与数据源类型,即可获得表、函数、字段血缘、表血缘等结构化结果。
- 面向数据源扩展:基于数据源实现差异化解析,同一套 API 覆盖多方言 SQL。
- 统一解析能力,包含:
- 解析表
- 解析函数
- 解析字段血缘
- 解析表血缘
package com.dtstack.sqlparserx.core; import com.dtstack.sqlparserx.core.enums.SqlParserDataSourceType; import com.dtstack.sqlparserx.core.parser.ISqlParser; import com.dtstack.sqlparserx.core.parser.SqlParserFactory; import com.dtstack.sqlparserx.core.parser.base.lineage.column.Column; import com.dtstack.sqlparserx.core.parser.base.lineage.column.ColumnLineageResult; import com.dtstack.sqlparserx.core.parser.base.lineage.domain.TableLineage; import com.dtstack.sqlparserx.core.parser.base.lineage.table.TableLineageResult; import com.dtstack.sqlparserx.core.parser.base.table.domain.ParseTableResult; import org.junit.Test; import java.util.*; public class READMETest { @Test public void demoTest() { // 准备sql String sql = getSql(); // 1、获取到sqlparser解析器 // 方式一:工厂方式获取 ISqlParser sqlParser = SqlParserFactory.getSqlParser(SqlParserDataSourceType.MYSQL); // 方式二:直接new // MySqlParser mySqlParser = new MySqlParser(); // 2、实现解析功能 // 2.1、解析表 ParseTableResult parseTableResult = sqlParser.parseTables(sql); System.out.println("====解析表===="); System.out.println(parseTableResult.getMainTable());// 获取主表 System.out.println(parseTableResult.getAllTableName()); // 获取解析到的所有表 // Set<Table> allTables = parseTableResult.getAllTables(); // for (Table allTable : allTables) { // System.out.println(allTable.getCatalog()); // System.out.println(allTable.getDb()); // System.out.println(allTable.getName()); // } // 2.2、解析字段血缘 System.out.println("\n====解析字段血缘===="); // 针对select * from table 场景,可传入tableColumnsMap封装真实的表字段信息 Map<String, List<Column>> tableColumnsMap = new HashMap<String, List<Column>>(){ { this.put("users", Arrays.asList(new Column("id", 0) , new Column("name", 1) )); this.put("orders", Arrays.asList(new Column("amount", 0) , new Column("id", 1) )); } }; ColumnLineageResult columnLineageResult = sqlParser.parseColumnLineages(sql, tableColumnsMap); columnLineageResult.printColumnLineage(); // 2.3、解析表血缘 System.out.println("\n====解析表血缘===="); TableLineageResult tableLineageResult = sqlParser.parseTableLineages(sql); List<TableLineage> tableLineages = tableLineageResult.getTableLineages(); System.out.println(tableLineages); // 2.4、解析函数 System.out.println("\n====解析函数===="); Set<String> functions = sqlParser.parseFunction(sql); System.out.println(functions); } public String getSql() { return "CREATE TABLE user_order_summary AS\n" + "SELECT\n" + " u.id as user_id,\n" + " u.name,\n" + " SUM(o.amount) as total_amount,\n" + " COUNT(o.id) as order_count\n" + "FROM users u JOIN orders o ON u.id = o.user_id\n" + "GROUP BY u.id, u.name"; } }
SqlParserX 采用分层设计,便于解耦与按数据源定制解析逻辑:
- 语法解析层:位于
sqlparserx-syntax模块,基于 Druid 负责 SQL 语法、Lexer/Parser 和 AST 解析扩展。 - 解析业务层:位于本模块(
sqlparserx-core),基于语法层输出的 AST 负责面向业务场景的解析能力。
分层的目的:
- 解耦:语法解析与业务解析职责分离。
- 可扩展:不同数据源可重写相应的解析实现。
主要场景:当 sqlparserx-syntax 语法层针对某个数据源扩展了 Lexer、Parser 或 AST 节点时,sqlparserx-core 中对应数据源的业务解析实现也应同步扩展维护。
以 MySQL 为例,语法解析层在 sqlparserx-syntax 中自定义了 MySqlRenameTableStatement,而通用的 ParseTableClient 并未处理该节点。此时可在如下包目录下:
com.dtstack.sqlparserx.core.parser.base.table.client.mysql
自定义一个 MySqlParseTableClient 类,继承 ParseTableClient 并重写 parseTables 方法,额外对 MySqlRenameTableStatement 进行解析处理即可。