初步剖析Calicite执行链路(源码入手)
点击上方蓝字关注我们


介绍
calcite是使用javcc+FreeMarker集成的,借助FreeMarker支持用户自定义自己的语义、语法分析及处理,扩展性极强。
calcite基于javacc扩展的解析SQL的实现在core包中:

前置知识学习:03、编译原理实践 – JavaCC解析表达式并生成抽象语法树、自定义Calcite的SQL语法后再来尝试阅读源码
关于Parser.jj中的${xxx}来源
变量参数均来自:

例如:${parser.class}指的就是自定义类名

入口是什么?
我们在使用calcite解析的时候是如下代码操作的:
public static void main(String[] args) throws SqlParseException { // 解析配置 - mysql设置 SqlParser.Config mysqlConfig = SqlParser.configBuilder() // 定义解析工厂 .setParserFactory(SqlParserImpl.FACTORY) .setLex(Lex.MYSQL) .build(); // 创建解析器 SqlParser parser = SqlParser.create("", mysqlConfig); // Sql语句 String sql = "xxx"; // 解析sql SqlNode sqlNode = parser.parseQuery(sql); System.out.println(sqlNode.toSqlString(OracleSqlDialect.DEFAULT));}
核心代码:parseQuery(sql)方法
public SqlNode parseQuery(String sql) throws SqlParseException { this.parser.ReInit(new StringReader(sql)); //1 return this.parseQuery();}public SqlNode parseQuery() throws SqlParseException { try { //2、自定义parseSqlStmtEof return this.parser.parseSqlStmtEof(); } catch (Throwable var2) { Throwable ex = var2; throw this.handleException(ex); }}
这个parseSqlStmtEof()从何而来?Parser.jj中定义好的


看下下面解析实现:可以看到优先匹配的是我们自定义部分

parser.statementParserMethods
对应的就是config.fmpp中配置的:

自定义模板替换

模板替换:



END

扫码二维码
获取更多精彩
感谢您的关注

夜雨聆风
