The same code works in Java/Scala so there must be a quirk or small
deviation in my Kotlin code.
I'll chalk this one up to user error.
Here's the working Java implementation:
--------------------------------------------------------------------
public class CalciteSchemaManager {
public static final CalciteConnection connection =
((Supplier<CalciteConnection>) () -> {
try {
Class.forName("org.apache.calcite.jdbc.Driver");
return
DriverManager.getConnection(Driver.CONNECT_STRING_PREFIX).unwrap(CalciteConnection.class);
} catch {}
}).get();
public static final SchemaPlus rootSchema = connection.getRootSchema();
public static final FrameworkConfig frameworkConfig =
Frameworks.newConfigBuilder()
.defaultSchema(connection.getRootSchema())
.parserConfig(SqlParser.config().withCaseSensitive(false))
.build();
public static ResultSet executeQuery(RelNode relRoot) {
relRoot.getCluster().getPlanner().setRoot(
relRoot.getCluster().getPlanner().changeTraits(
relRoot,
relRoot.getCluster().traitSet().replace(EnumerableConvention.INSTANCE)
)
);
RelNode bestExp = relRoot.getCluster().getPlanner().findBestExp();
return
connection.createPrepareContext().getRelRunner().prepareStatement(bestExp).executeQuery();
}
public static ResultSet executeQuery(String sql) {
return executeQuery(CalciteUtilsJava.parseSql(sql,
frameworkConfig));
}
}
On Sun, Jan 16, 2022 at 4:50 PM Gavin Ray <[email protected]> wrote:
> I hate to bother with such a small question but I feel like I've hit a wall
> after spending most of yesterday on it.
>
> I get this when trying to execute a RelNode expression as a query, it
> seems to
> be because the "SchemaPlusImpl" throws "UnsupportedException" for the
> "snapshot"
> function.
>
>
> https://github.com/apache/calcite/blob/4bc916619fd286b2c0cc4d5c653c96a68801d74e/core/src/main/java/org/apache/calcite/jdbc/CalciteSchema.java#L654-L656
>
> Not sure why/where "snapshot" is being called:
>
> ------------------------------------------------------------------------------
> java.sql.SQLException: Error while preparing plan
> [EnumerableTableScan(table=[[fake_database, hr, emps]]) ]
> at org.apache.calcite.avatica.Helper.createException(Helper.java:56) at
> org.apache.calcite.avatica.Helper.createException(Helper.java:41) at
>
> org.apache.calcite.jdbc.CalciteConnectionImpl.prepareStatement_(CalciteConnectionImpl.java:239)
> at
>
> org.apache.calcite.jdbc.CalciteConnectionImpl.access$100(CalciteConnectionImpl.java:101)
> at
>
> org.apache.calcite.jdbc.CalciteConnectionImpl$2.prepareStatement(CalciteConnectionImpl.java:188)
> at SchemaManager.executeQuery(SchemaManager.kt:83)
>
> Caused by: java.lang.UnsupportedOperationException
> at
>
> org.apache.calcite.jdbc.CalciteSchema$SchemaPlusImpl.snapshot(CalciteSchema.java:655)
> at
>
> org.apache.calcite.jdbc.CachingCalciteSchema.snapshot(CachingCalciteSchema.java:260)
>
>
> ------------------------------------------------------------------------------
> The code I am using to execute the query is:
>
> object SchemaManager {
> val calciteConnection: CalciteConnection = run {
> val connection = DriverManager.getConnection("jdbc:calcite:")
> connection.unwrap(CalciteConnection::class.java)
> }
> val runner: RelRunner = calciteConnection.unwrap(RelRunner::class.java)
> val rootSchema: SchemaPlus = calciteConnection.rootSchema
>
> fun executeQuery(relRoot: RelNode): ResultSet {
> val optPlanner = relRoot.cluster.planner val desiredTraits =
> relRoot.cluster.traitSet().replace(EnumerableConvention.INSTANCE)
> optPlanner.root = optPlanner.changeTraits(relRoot, desiredTraits)
> val
> bestExp = optPlanner.findBestExp()
>
> return runner.prepareStatement(bestExp).use { it.executeQuery() }
> }
> }
>