如何使用Apache Calcite解析PostgreSQL的JSON运算符->>
Calcite Babel解析PostgreSQL JSON运算符
->>失败的解决方案 问题背景
使用Calcite 1.37.0的SqlBabelParserImpl解析包含PostgreSQL JSON运算符->>的SQL时触发解析异常,而::类型转换运算符可以正常解析。
环境与代码信息
- Calcite版本:1.37.0(calcite-core、calcite-babel)
- 待解析SQL:
select global_config::json->>'bgColor' from config where id = 5
- 解析代码:
SqlParser.Config parserConfig = SqlParser.config() .withCaseSensitive(false) .withQuotedCasing(Casing.TO_UPPER) .withConformance(SqlConformanceEnum.BABEL) .withParserFactory(SqlBabelParserImpl.FACTORY); SqlParser sqlParser = SqlParser.create(querySql, parserConfig); SqlNode sqlNode = sqlParser.parseQuery();
- 异常信息:
Caused by: org.apache.calcite.sql.parser.babel.ParseException: Encountered "->" at line 1, column 27. Was expecting one of: <EOF> "ORDER" ... "LIMIT" ... "OFFSET" ... "FETCH" ... "," ... "FROM" ... <IDENTIFIER> ... <HYPHENATED_IDENTIFIER> ... <QUOTED_IDENTIFIER> ... <BACK_QUOTED_IDENTIFIER> ... <BIG_QUERY_BACK_QUOTED_IDENTIFIER> ... <BRACKET_QUOTED_IDENTIFIER> ... <UNICODE_QUOTED_IDENTIFIER> ... <QUOTED_STRING> ... "UNION" ... "INTERSECT" ... "EXCEPT" ... "MINUS" ... "IN" ... "<" ... "<=" ... ">" ... ">=" ... "=" ... "<>" ... "!=" ... "!" ... "~" ... "::" ... "<=>" ... "+" ... "-" ... "*" ... "/" ... "%" ... "||" ... "[" ... "." ... at org.apache.calcite.sql.parser.babel.SqlBabelParserImpl.generateParseException(SqlBabelParserImpl.java:40236) at org.apache.calcite.sql.parser.babel.SqlBabelParserImpl.jj_consume_token(SqlBabelParserImpl.java:40044) at org.apache.calcite.sql.parser.babel.SqlBabelParserImpl.SqlStmtEof(SqlBabelParserImpl.java:1116) at org.apache.calcite.sql.parser.babel.SqlBabelParserImpl.parseSqlStmtEof(SqlBabelParserImpl.java:217) at org.apache.calcite.sql.parser.SqlParser.parseQuery(SqlParser.java:172) ... 1 more
可行解决方案
1. 升级Calcite版本
Calcite 1.37.0的Babel解析器对PostgreSQL的JSON运算符支持不完整,后续版本(如1.40.0及以上)已经修复了这个问题。直接升级依赖版本即可:
<dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-core</artifactId> <version>1.40.0</version> </dependency> <dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-babel</artifactId> <version>1.40.0</version> </dependency>
升级后无需修改原有解析代码,就能正常解析->>运算符。
2. 替换运算符为等价函数
如果暂时无法升级版本,可以把->>替换成PostgreSQL原生的json_extract_path_text函数,两者功能完全一致:
select json_extract_path_text(global_config::json, 'bgColor') from config where id = 5
这个SQL在PostgreSQL中可以正常执行,同时Calcite 1.37.0的Babel解析器也能正确解析。
3. 自定义解析器扩展(进阶)
如果必须保留原运算符且不能升级版本,可以自定义Calcite解析器:
- 继承
SqlBabelParserImpl,添加->>运算符的语法解析规则 - 将自定义的解析器工厂注册到解析配置中
这种方法需要熟悉Calcite基于JavaCC的解析器生成机制,实现成本较高,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者tavis yi
相关产品推荐
相关产品推荐

