Gavin, The reason is that you need two “ingredients” to execute a query. You need the expression, and you need a connection. The expression is written in terms of relations, which have a fully-qualified path, “schema.subSchema.tableName”. But only the connection (to be precise, its root schema) contains the actual table objects.
Usually you get a RelRunner from a connection. RelRunners.run seems to offer a short-cut — it creates a dummy connection using “jdbc:calcite:”. But you get what you pay for. This connection is empty. Its root schema contains no sub-schemas, and no tables. It’s only good for executing statements that do not reference any tables. Sorry to hear that you had two days of frustration. Julian > On Jan 1, 2022, at 10:44 AM, Gavin Ray <[email protected]> wrote: > > After two days of banging my head against the wall, I figured it out! > > It only works if I run the query in the context of a "CalciteConnection", > and I use "connection.unwrap()" to create the "RelRunner". > > WRONG: > ========================== > val run = RelRunners.run(bestExp) > val resultSet = run.executeQuery() > > RIGHT: > ========================== > val runner = connection.unwrap(RelRunner::class.java) > val resultSet = runner.prepareStatement(bestExp).executeQuery() > > Why is this out of curiosity? > > I only figured this out by mimicking the "FrameworksTest" case below, > so I don't understand the "why". > > https://github.com/apache/calcite/blob/de847c38f3544f9c7282984f32dc1093bdb2fb60/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java#L342-L376 > > > > On Fri, Dec 31, 2021 at 6:22 PM Gavin Ray <[email protected]> wrote: > >> It appears to be because "getSubSchema" in >> "calcite.jdbc.CalciteSchema.SchemaPlusImpl" has a "subSchemaMap" that loses >> the "hr" schema and only contains "metadata" [0] >> >> But if I call the same function the map shows "hr" is present [1] which >> doesn't make sense to me >> >> [0]: https://imgur.com/djlkBVf >> [1]: https://imgur.com/eEOvjdS >> >> >> >> >> >> >> >> On Fri, Dec 31, 2021 at 5:20 PM Gavin Ray <[email protected]> wrote: >> >>> Unsure of where this is coming from/how to debug it. >>> (The code I am using is below, taken from Calcite examples) >>> >>> If I print out the sub-schema names of "rootSchema", and their tables, I >>> get: >>> >>> subSchemaNames: [hr, metadata] >>> "hr" subSchema table names: [depts, emps] >>> "metadata" subSchema table names: [COLUMNS, TABLES] >>> >>> So I am not certain what value is being passed that it would fail >>> a "schema.getSubSchema()" call, or where to put a breakpoint to debug >>> that. >>> >>> Does anyone spot something I'm doing that's clearly wrong, or have an idea >>> where I could look to find the code that's causing this? >>> >>> Stacktrace winds up at "Baz", so I think it's generated code >>> Thank you >>> =========================================================== >>> >>> fun main(args: Array<String>) { >>> val hr = Frameworks.createRootSchema(true).add("hr", >>> HrClusteredSchema()) >>> >>> val frameworkConfig: FrameworkConfig = Frameworks >>> .newConfigBuilder() >>> .parserConfig(SqlParser.config().withCaseSensitive(false)) >>> .defaultSchema(hr) >>> .build() >>> >>> Frameworks.withPlanner(::test, frameworkConfig) >>> } >>> >>> fun test(cluster: RelOptCluster, relOptSchema: RelOptSchema, rootSchema: >>> Schema) { >>> val planner = cluster.planner >>> val relBuilder: RelBuilder = >>> RelFactories.LOGICAL_BUILDER.create(cluster, relOptSchema) >>> >>> val relRoot: RelNode = // ... >>> val desiredTraits = >>> cluster.traitSet().replace(EnumerableConvention.INSTANCE) >>> val newRoot = cluster.planner.changeTraits(relRoot, desiredTraits) >>> >>> cluster.planner.root = newRoot >>> val bestExp = cluster.planner.findBestExp() >>> val run = RelRunners.run(bestExp) >>> val resultSet = run.executeQuery() >>> } >>> >>
