vlsi opened a new pull request, #5322: URL: https://github.com/apache/calcite/pull/5322
Jira: [CALCITE-7848](https://issues.apache.org/jira/browse/CALCITE-7848), plus a regression test for [CALCITE-3557](https://issues.apache.org/jira/browse/CALCITE-3557). ## Why For a nested collection of INTEGER, such as `select array[array[1, 2], array[3, 4]]`, `ResultSet.getObject` returns a `java.sql.Array` whose `getArray()` throws `ClassCastException: class org.apache.calcite.avatica.util.ArrayImpl cannot be cast to class java.lang.Integer`. The same happens for `multiset[multiset[...]]`, `multiset[array[...]]` and `array[multiset[...]]`; `getString` returns the right value, and VARCHAR elements work. Reproduced with calcite-core 1.42.0 and on main. Through the remote driver, a query that returns a collection of INTEGER does not execute at all: `AbstractService.finagle` tries to change the column's rep from `PRIMITIVE_INT` to `NUMBER`, and `ColumnMetaData.ArrayType.setRep` throws `UnsupportedOperationException`. ## What `CalcitePrepareImpl.avaticaType` gave each `ArrayType` the rep of its component's Java class (since CALCITE-910), so `INTEGER ARRAY` carried `PRIMITIVE_INT`, and `ArrayImpl.getArray` of the outer collection took the primitive-int branch for the inner `ArrayImpl` values. The fix passes `Rep.ARRAY` or `Rep.MULTISET`, which is how Avatica's own `ArrayAccessorTest.resultSetFromMultisetArray` describes a nested collection. Fixing this in Avatica's `ArrayImpl` instead would need an Avatica release and would still leave the remote driver failing in `finagle`. The first commit is the end-to-end test from #2790 by @JiajunBernoulli, without its `Bug.CALCITE_3557_FIXED` guard. CALCITE-3557 was fixed in Avatica 1.23.0, but nothing in Calcite ran these queries; with that Avatica fix reverted, 4 of its 6 cases fail. ## What the caller sees - `getObject(i).getArray()` on a collection of INTEGER ARRAY or MULTISET returns an `Object[]` of `java.sql.Array` whose `getArray()` returns `int[]`, instead of throwing `ClassCastException`. - The remote driver executes a query that returns a collection of a numeric type, instead of failing with `UnsupportedOperationException`. ## Verification - `JdbcTest.testGetArrayOfNestedCollection` (new): all four nesting shapes fail without the fix and pass with it. - `CalciteRemoteDriverTest.testRemoteIntegerCollections` (new): fails without the fix with `UnsupportedOperationException`, passes with it. - `./gradlew :core:test` with the fix: 16891 tests, none failed. ## Scope - Through the remote driver, `getString` on `multiset[multiset[1, 2]]` still throws `ClassCastException` (`java.util.ArrayList` cannot be cast to `java.lang.Integer`). That query could not run remotely before this change at all; it is not fixed here. - `MaterializationService` passes the top-level column rep to `CloneSchema.createCloneTable`, so a single-column materialization of a collection column now gets `java.sql.Array` or `List` as its element class instead of the component's primitive class. No test covers it, and I found no code that depends on the old value. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
