Apache Calcite在执行查询(SchemaPlus. sql)时抛出异常.getSubSchema返回null



[Using Apache Calcite 1.30.0]

使用query: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

连接/模型/模式中缺少什么?

模型。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();

最新更新