postgresql 铸造操作员:不被Apache Calcite解析

rqdpfwrv  于 2023-10-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(255)

我使用以下代码设置了一个简单的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.BABELSqlConformanceEnum.BIG_QUERY等,但仍然没有成功。这个问题令人困惑,因为应该支持这种类型的运算符(如documentation中所示)。
我很感激你能提供的任何帮助。在此先谢谢您!
编辑:我删除了关于我创建的UDF的信息,因为它与解析强制转换运算符的问题无关::

zfycwa2u

zfycwa2u1#

Apache Calcite有三个内置的解析器实现:

  • SqlParserImpl(默认值,严格遵循SQL标准的SQL语句解析器)
  • SqlDdlParserImpl(语法分析器,用于语法分析语句;这些不是标准化的,所以它们不在默认解析器中)
  • SqlBabelParserImpl(解析器,用于解析不属于SQL标准的具有更特殊语法的SQL语句)

解析器实现可以通过调用以下方法之一来选择:

  • 配置#withParserFactory
  • ConfigBuilder#setParserFactory(已弃用)

在本例中,您使用的是Postgres强制转换运算符'::',它是在CALCITE-2843中的Babel解析器中引入的,因此在本例中,您必须将SqlBabelParserImpl.FACTORY传递给上面的一个方法。
SqlCon是一个补充配置,它可以微调解析器和验证器的行为,无论下面使用的是哪个解析器实现。

相关问题