簡體   English   中英

Apache Calcite 在執行查詢時拋出異常(SchemaPlus.getSubSchema 返回 null)

[英]Apache Calcite throws exception when executing query (SchemaPlus.getSubSchema returns null)

[使用 Apache 方解石 1.30.0]

使用查詢: SELECT * FROM mydb.employees我可以看到當我relNode.explain(.. )*被擴展到數據庫的正確列中,所以我知道與數據庫的連接正在(某種程度上)按預期工作, 來自model.json架構。

LogicalProject(emp_no=[$0], birth_date=[$1], first_name=[$2], last_name=[$3], gender=[$4], hire_date=[$5]): rowcount = 100.0, cumulative cost = {200.0 rows, 701.0 cpu, 0.0 io}, id = 4
  JdbcTableScan(table=[[mydb, employees]]): rowcount = 100.0, cumulative cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 3

但是,如果我嘗試: ResultSet resultSet = run.executeQuery(); ,它拋出:

java.sql.SQLException: exception while executing query: Cannot invoke "org.apache.calcite.schema.SchemaPlus.unwrap(java.lang.Class)" because the return value of "org.apache.calcite.schema.SchemaPlus.getSubSchema(String)" is null

我從連接/模型/模式中遺漏了什么?

Model.json:

{
  version: '1.0',
  defaultSchema: 'mydb',
  schemas: [
    {
      name: 'mydb',
      type: 'custom',
      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
      operand: {
        jdbcDriver: 'com.mysql.jdbc.Driver',
        jdbcUrl: 'jdbc:mysql://127.0.0.1/mydb',
        jdbcUser: 'username',
        jdbcPassword: 'password'
      }
    }
  ]
}

主要代碼片段:

Properties properties = new Properties();
properties.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(), "true");
properties.setProperty(CalciteConnectionProperty.QUOTED_CASING.camelName(), Casing.UNCHANGED.name());
properties.setProperty(CalciteConnectionProperty.UNQUOTED_CASING.camelName(), Casing.UNCHANGED.name());


Connection connection = DriverManager.getConnection("jdbc:calcite:model=src/main/resources/model.json", properties);
CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
SchemaPlus rootSchema = calciteConnection.getRootSchema();

SqlParser.Config caseSensitiveParser = SqlParser.configBuilder().setUnquotedCasing(Casing.UNCHANGED).setQuotedCasing(Casing.UNCHANGED).setCaseSensitive(true).build();
FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
        .parserConfig(caseSensitiveParser)
        .defaultSchema(rootSchema)
        .build();

Planner planner = Frameworks.getPlanner(frameworkConfig);

String query = "SELECT * FROM mydb.employees";
SqlNode sqlNode = planner.parse(query);
SqlNode sqlNodeValidated = planner.validate(sqlNode);
RelRoot relRoot = planner.rel(sqlNodeValidated);
RelNode relNode = relRoot.project();
final RelWriter relWriter = new RelWriterImpl(new PrintWriter(System.out), SqlExplainLevel.ALL_ATTRIBUTES, false);
relNode.explain(relWriter);

PreparedStatement run = RelRunners.run(relNode);
ResultSet resultSet = run.executeQuery();

您需要從連接中解包 RelRunner 而不是使用虛擬連接,即RelRunners.run(relNode);

嘗試這個

RelRunner runner = connection.unwrap(RelRunner.class);
ResultSet resultSet = runner.prepareStatement(relNode).executeQuery();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM