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

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

我使用以下代码设置了一个简单的Apache Calcite规划器,遇到了一个特殊的问题:

  1. SqlParser.Config parserConfig = SqlParser.configBuilder()
  2. .setCaseSensitive(false)
  3. .setUnquotedCasing(Casing.UNCHANGED)
  4. .setQuotedCasing(Casing.UNCHANGED)
  5. .setConformance(SqlConformanceEnum.BABEL)
  6. .build();
  7. FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
  8. .parserConfig(parserConfig)
  9. .operatorTable(SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable(
  10. SqlLibrary.POSTGRESQL))
  11. .sqlValidatorConfig(SqlValidator.Config.DEFAULT.withIdentifierExpansion(true))
  12. .defaultSchema(connection.getRootSchema().getSubSchema(defaultSchema))
  13. .build();
  14. Planner planner = Frameworks.getPlanner(frameworkConfig);

现在,我尝试使用我创建的规划器(SqlNode parsedQuery = planner.parse(sql);)解析以下查询:

  1. SELECT lineitem.l_shipdate :: text AS l_shipdate
  2. FROM lineitem

查询在PostgreSQL中执行时没有任何问题。然而,当试图用方解石解析它时,我遇到了以下异常:

  1. Exception in thread "main" org.apache.calcite.sql.parser.SqlParseException: Encountered ":" at line 1, column 28.
  2. Was expecting one of:
  3. "UESCAPE" ...
  4. <QUOTED_STRING> ...
  5. ")" ...
  6. "," ...
  7. "." ...
  8. "NOT" ...
  9. "IN" ...
  10. "<" ...
  11. "<=" ...
  12. ">" ...
  13. ">=" ...
  14. "=" ...
  15. "<>" ...
  16. "!=" ...
  17. "BETWEEN" ...
  18. "LIKE" ...
  19. "ILIKE" ...
  20. "RLIKE" ...
  21. "SIMILAR" ...
  22. "+" ...
  23. "-" ...
  24. "*" ...
  25. "/" ...
  26. "%" ...
  27. "||" ...
  28. "AND" ...
  29. "OR" ...
  30. "IS" ...
  31. "MEMBER" ...
  32. "SUBMULTISET" ...
  33. "CONTAINS" ...
  34. "OVERLAPS" ...
  35. "EQUALS" ...
  36. "PRECEDES" ...
  37. "SUCCEEDS" ...
  38. "IMMEDIATELY" ...
  39. "MULTISET" ...
  40. "[" ...
  41. "FORMAT" ...
  42. at org.apache.calcite.sql.parser.impl.SqlParserImpl.convertException(SqlParserImpl.java:408)
  43. at org.apache.calcite.sql.parser.impl.SqlParserImpl.normalizeException(SqlParserImpl.java:154)
  44. at org.apache.calcite.sql.parser.SqlParser.handleException(SqlParser.java:159)
  45. at org.apache.calcite.sql.parser.SqlParser.parseQuery(SqlParser.java:174)
  46. at org.apache.calcite.sql.parser.SqlParser.parseStmt(SqlParser.java:199)
  47. at org.apache.calcite.prepare.PlannerImpl.parse(PlannerImpl.java:216)
  48. at org.apache.calcite.tools.Planner.parse(Planner.java:50)
  49. at de.tub.dima.mascara.parser.Parser.getLogicalPlan(Parser.java:67)
  50. 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是一个补充配置,它可以微调解析器和验证器的行为,无论下面使用的是哪个解析器实现。

相关问题