Я пытаюсь оптимизировать запрос из схемы JDB C (PostgreSQL), следуя этой записной книжке: https://github.com/michaelmior/calcite-notebooks/blob/master/query-optimization.ipynb
По сути, я пытаюсь оптимизировать запрос, который обращается к представлению, определенному в схеме JDB C. Однако, когда я пытаюсь выполнить оптимизированный план, я получаю исключение (подробнее см. Ниже).
У меня есть следующий файл модели:
{
"version": "1.0",
"defaultSchema": "tpch-view",
"schemas": [
{
"type": "jdbc",
"name": "tpch-jdbc",
"jdbcUser": "user",
"jdbcPassword": "pass",
"jdbcUrl": "jdbc:postgresql://localhost/db"
},
{
"name": "tpch-view",
"tables": [
{
"name": "nationview",
"type": "view",
"sql": "SELECT * from \"tpch-jdbc\".\"nation\""
}
]
}
]
}
Мой кальцитовый код выглядит так:
Connection connection = DriverManager.getConnection("jdbc:calcite:model=src/main/resources/model-jdbc.json");
CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
SchemaPlus mySchema = calciteConnection.getRootSchema().getSubSchema(connection.getSchema());
FrameworkConfig config = Frameworks.newConfigBuilder()
.defaultSchema(mySchema)
.build();
String query = "select * from \"nationview\"";
Planner planner = getPlanner(config);
SqlNode parse = planner.parse(query);
SqlNode validate = planner.validate(parse);
RelNode rel = planner.rel(validate).project();
HepProgram program = HepProgram.builder().build();
HepPlanner hepPlanner = new HepPlanner(program);
hepPlanner.setRoot(rel);
RelNode optimized = hepPlanner.findBestExp();
optimized.explain(rw);
RelOptCluster cluster = rel.getCluster();
VolcanoPlanner vplanner = (VolcanoPlanner) cluster.getPlanner();
RelTraitSet desiredTraits = cluster.traitSet().replace(EnumerableConvention.INSTANCE);
RelNode newRoot = vplanner.changeTraits(rel, desiredTraits);
vplanner.setRoot(newRoot);
RelNode optimized2 = vplanner.findBestExp();
optimized2.explain(rw);
ResultSet result = RelRunners.run(optimized2).executeQuery();
Я получаю следующее (соответственно, для планировщиков Hep и Volcano):
14:LogicalProject(n_nationkey=[$0], n_name=[$1], n_regionkey=[$2], n_comment=[$3])
10:JdbcTableScan(table=[[tpch-jdbc, nation]])
31:JdbcToEnumerableConverter
10:JdbcTableScan(table=[[tpch-jdbc, nation]])
Однако во время выполнения инструкции я получаю следующее исключение:
Exception in thread "main" java.sql.SQLException: exception while executing query: null
at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
at org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:577)
at org.apache.calcite.avatica.AvaticaPreparedStatement.executeQuery(AvaticaPreparedStatement.java:137)
at JDBCTest.main(JDBCTest.java:89)
Caused by: java.lang.NullPointerException
at Baz.bind(Unknown Source)
at org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:355)
at org.apache.calcite.jdbc.CalciteConnectionImpl.enumerable(CalciteConnectionImpl.java:316)
at org.apache.calcite.jdbc.CalciteMetaImpl._createIterable(CalciteMetaImpl.java:506)
at org.apache.calcite.jdbc.CalciteMetaImpl.createIterable(CalciteMetaImpl.java:497)
at org.apache.calcite.avatica.AvaticaResultSet.execute(AvaticaResultSet.java:182)
at org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:64)
at org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:43)
at org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:573)
... 2 more
Почему сбой при выполнении, несмотря на то, что процедура оптимизации прошла нормально? Когда я пытаюсь сделать то же самое с видом на схему CSV, выполнение работает нормально. Кроме того, когда я пытаюсь выполнить его таким образом (без оптимизации), он также работает нормально:
Statement stmt = calciteConnection.createStatement();
String query = "select * from \"nationview\"";
SqlParser parser = SqlParser.create(query);
ResultSet resultSet = stmt.executeQuery(query);
Я забыл включить что-то? Или мне нужны дополнительные параметры конфигурации для выполнения через JDB C?