我使用以下代码设置了一个简单的Apache Calcite规划器,遇到了一个特殊的问题:
SqlParser.Config parserConfig = SqlParser.configBuilder()
.setCaseSensitive(false)
.setUnquotedCasing(Casing.UNCHANGED)
.setQuotedCasing(Casing.UNCHANGED)
.setConformance(SqlConformanceEnum.BABEL)
.build();
FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
.parserConfig(parserConfig)
.operatorTable(SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable(
SqlLibrary.POSTGRESQL))
.sqlValidatorConfig(SqlValidator.Config.DEFAULT.withIdentifierExpansion(true))
.defaultSchema(connection.getRootSchema().getSubSchema(defaultSchema))
.build();
Planner planner = Frameworks.getPlanner(frameworkConfig);
现在,我尝试使用我创建的规划器(SqlNode parsedQuery = planner.parse(sql);
)解析以下查询:
SELECT lineitem.l_shipdate :: text AS l_shipdate
FROM lineitem
查询在PostgreSQL中执行时没有任何问题。然而,当试图用方解石解析它时,我遇到了以下异常:
Exception in thread "main" org.apache.calcite.sql.parser.SqlParseException: Encountered ":" at line 1, column 28.
Was expecting one of:
"UESCAPE" ...
<QUOTED_STRING> ...
")" ...
"," ...
"." ...
"NOT" ...
"IN" ...
"<" ...
"<=" ...
">" ...
">=" ...
"=" ...
"<>" ...
"!=" ...
"BETWEEN" ...
"LIKE" ...
"ILIKE" ...
"RLIKE" ...
"SIMILAR" ...
"+" ...
"-" ...
"*" ...
"/" ...
"%" ...
"||" ...
"AND" ...
"OR" ...
"IS" ...
"MEMBER" ...
"SUBMULTISET" ...
"CONTAINS" ...
"OVERLAPS" ...
"EQUALS" ...
"PRECEDES" ...
"SUCCEEDS" ...
"IMMEDIATELY" ...
"MULTISET" ...
"[" ...
"FORMAT" ...
at org.apache.calcite.sql.parser.impl.SqlParserImpl.convertException(SqlParserImpl.java:408)
at org.apache.calcite.sql.parser.impl.SqlParserImpl.normalizeException(SqlParserImpl.java:154)
at org.apache.calcite.sql.parser.SqlParser.handleException(SqlParser.java:159)
at org.apache.calcite.sql.parser.SqlParser.parseQuery(SqlParser.java:174)
at org.apache.calcite.sql.parser.SqlParser.parseStmt(SqlParser.java:199)
at org.apache.calcite.prepare.PlannerImpl.parse(PlannerImpl.java:216)
at org.apache.calcite.tools.Planner.parse(Planner.java:50)
at de.tub.dima.mascara.parser.Parser.getLogicalPlan(Parser.java:67)
at de.tub.dima.mascara.Playground.main(Playground.java:34)
我尝试将解析器的一致性设置为多个值,例如SqlConformanceEnum.BABEL
、SqlConformanceEnum.BIG_QUERY
等,但仍然没有成功。这个问题令人困惑,因为应该支持这种类型的运算符(如documentation中所示)。
我很感激你能提供的任何帮助。在此先谢谢您!
编辑:我删除了关于我创建的UDF的信息,因为它与解析强制转换运算符的问题无关::
1条答案
按热度按时间zfycwa2u1#
Apache Calcite有三个内置的解析器实现:
解析器实现可以通过调用以下方法之一来选择:
在本例中,您使用的是Postgres强制转换运算符'::',它是在CALCITE-2843中的Babel解析器中引入的,因此在本例中,您必须将
SqlBabelParserImpl.FACTORY
传递给上面的一个方法。SqlCon是一个补充配置,它可以微调解析器和验证器的行为,无论下面使用的是哪个解析器实现。