Okay… so more digging in this area throws up some more weirdness. Executing the following query (via prepared statement):
INSERT INTO “foo” (KEY, "cell") values (?, ?) where: TABLE_NAME=foo; COLUMN_NAME=KEY; DATA_TYPE=-5; TYPE_NAME=JavaType(long) NOT NULL; TABLE_NAME=foo; COLUMN_NAME=cell; DATA_TYPE=-3; TYPE_NAME=JavaType(class [B); seems to be impossible. Avatica wants to be passed a byte[] through setObject or setBytes… which it hard casts and then wraps in a ByteString. The type inference in Calcite infers the type that ultimately propagates in to the EnumerableCalc as byte[] though so generates an cast of the ByteString back to a byte[]. java.lang.ClassCastException: class org.apache.calcite.avatica.util.ByteString cannot be cast to class [B (org.apache.calcite.avatica.util.ByteString is in unnamed module of loader 'app'; [B is in module java.base of loader 'bootstrap') at Baz$2.apply(Unknown Source) at org.apache.calcite.linq4j.EnumerableDefaults.longCount(EnumerableDefaults.java:2373) at org.apache.calcite.linq4j.EnumerableDefaults.count(EnumerableDefaults.java:397) at org.apache.calcite.linq4j.DefaultEnumerable.count(DefaultEnumerable.java:187) at Baz.bind(Unknown Source) at org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:363) at org.apache.calcite.jdbc.CalciteConnectionImpl.enumerable(CalciteConnectionImpl.java:325) at org.apache.calcite.jdbc.CalciteMetaImpl._createIterable(CalciteMetaImpl.java:585) at org.apache.calcite.jdbc.CalciteMetaImpl.execute(CalciteMetaImpl.java:715) at org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:551) Unfortunately there are just too many places this could be “fixed” and I lack the necessary context to know if I’m using something wrong or if a fix is needed, and if so which layer of code is dropping the ball. Thanks, Chris From: Chris Dennis <chris.w.den...@ibm.com.INVALID> Date: Friday, March 21, 2025 at 4:13 PM To: dev@calcite.apache.org <dev@calcite.apache.org> Subject: [EXTERNAL] Type Discrepancies between PreparedStatement, and row RelDataType Hi All, Trying to figure out what’s amiss in my Calcite based driver and whether there are bugs in this area in Avatica/Calcite or if I’m using something wrong. I have a table in a database that reports its columns as: JavaType(long) NOT NULL (BIGINT), JavaType(class java.lang.Character) (CHAR) I then build a prepared statement against the same connection: INSERT INTO foo (KEY, \"character\") values (?, ?) The parameter metadata reports the parameter types as: java.lang.Object (BIGINT). java.lang.Object (CHAR) The Enumerable node that is input to my adapters part of the graph reports its row type as: RecordType(JavaType(class java.lang.Long) KEY, JavaType(class java.lang.Character) character) At code generation I’m then presented with a field that claims it’s a java.lang.Character, but at runtime I get a ClassCastException because arbitrary java types (notably Strings) are getting all the way through from the JDBC PreparedStatement unmodified. My understanding of the JDBC spec says that the parameter values should get converted, at but it’s not clear to me who’s responsibility that is. Anyone have any thoughts on where I should look first? Thanks, Chris