jsqlparser - 失败了,不支持 hive 语法
hive-exec ,用 ParseDriver 和 ast token , 失败了,复杂语法不支持(奇怪,hive 服务器难道不是用的这个解析吗)
这里有一些 使用案例,人家用的好好的,可能是我们的姿势不对,待研究
优步 Uber 的queryparser,使用 haskell 语言开发,没有maven jar 包可用,算了,咱也不熟悉
gsp - general sql parser ,商业收费,测试案例jar包可以下载和执行,说明源码也是可用的。
翻看源码,发现其中使用了 dbeaver 的 jkiss 等package, 明显是"借鉴了" dbeaver 开源git 上 的一部分代码。
github java demo source code解析 hive simple example
TGSqlParser sqlparser = new TGSqlParser(EDbVendor.dbvhive);
sqlparser.sqltext = "SELEct 1" ;
int ret = sqlparser.parse();
if (ret == 0){
for(int i=0;i 虽然功能很强大,但是尚未研究透怎么移植到 项目中 。 有人说可以直接build 到项目中,待研究
自定义解析代码,需要自己写解析逻辑 ,比如 。 这个 太费时间了,毕竟bug多,有成型的持续团队维护的最好了。
此博主老铁非常彪悍,自定义实现了语法,提取tableName 和column ,但是其他功能没有,还得手写,有些遗憾了 ,表示很钦佩该老铁
alibaba druid
经过不断迭代,已经解决了很多 hive解析的bug,比如 2020年的create tablebug支持的db type 多,impala ,hive ,oracle 等等都支持 。缺点就是捆绑销售,1个jar 包高大全的 datasource 全家桶。我们只是想要 parser 而已。老版本的 sql 解析会有bug,但是新版本的已经解决。测试了 一些复杂 语句,都能正确 解析。
对比 hive 本身的 parser ast 的操作,还需要自己分析 token,实在是太那个了。
二者对比参考代码
@Test
public void testDruidSqlParser() throws ParseException {
String sql = "FROM (SELECt p.datekey datekey, p.userid userid, c.clienttype FROM detail.usersequence_client c JOIN fact.orderpayment p ON p.orderid = c.orderid JOIN default.user du ON du.userid = p.userid WHERe p.datekey = 20131118 ) base INSERT OVERWRITE TABLE `test`.`customer_kpi` SELECT base.datekey, base.clienttype, count(distinct base.userid) buyer_count GROUP BY base.datekey, base.clienttype";
final SQLStatementParser hive = SQLParserUtils.createSQLStatementParser(sql, DbType.hive);
final SQLStatement statement = hive.parseStatement();
System.out.println(statement);
// as you can see , using this parseDriver will cause an error
ParseDriver pd = new ParseDriver();
ASTNode ast = pd.parse(sql);
System.out.println(ast.dump());
}
7. 更多使用案例: hive ,mysql
public static List parseStatements(String sql, String dbType) {
try {
return SQLUtils.parseStatements(sql, dbType);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("SQL格式错误");
}
}
public static void format(String sql, String dbType) {
String sqlFormat = SQLUtils.format(sql, dbType);
if (sql.equals(sqlFormat)) {
throw new RuntimeException("SQL格式错误");
}
}
血缘关系解析,详见地址



