vlsi opened a new pull request, #5364: URL: https://github.com/apache/calcite/pull/5364
Fixes [CALCITE-7893](https://issues.apache.org/jira/browse/CALCITE-7893). ## Why `SqlTypeMappingRules.Builder#add` used the caller's set as the key of a Guava `LoadingCache`. `SqlTypeAssignmentRule` and `SqlTypeCoercionRule` pass one `HashSet` that they clear and refill between calls, so every cache entry was keyed by the same mutable object. A set whose hash code equaled an earlier set's received the earlier set's source types. `SqlTypeName` is an enum, so the hash code of a set is a sum of identity hash codes, and whether two sets collide changes from one JVM run to the next. With `-XX:+UnlockExperimentalVMOptions -XX:hashCode=2`, which makes every identity hash code 1, TIME becomes assignable from DATE only: `CAST(DATE '1243-12-01' AS TIME)` passes validation, and user-defined functions resolve to the wrong overload or to none (`No match found for function signature timeFun(<TIME>)`). 41 tests in `:core:test` fail that way ([CI run](https://github.com/vlsi/calcite/actions/runs/40321987597) from the [CALCITE-7892](https://issues.apache.org/jira/browse/CALCITE-7892) trial). ## What `Builder#add` copies the set with `Sets.immutableEnumSet` before using it as a key and interns equal sets in a plain `HashMap`. The builder is filled once, in a static initializer, so it needs neither eviction nor thread safety. The validation path reads the same `Map<SqlTypeName, ImmutableSet<SqlTypeName>>` with `ImmutableEnumSet` values as before. ## Verification `SqlTypeUtilTest#testTypeMappingBuilderKeepsSourceTypesOfReusedSet` (new) forces the collision with a `HashSet` whose `hashCode()` is constant. It fails without the fix with `but: was <{DATE=[DATE], TIME=[TIME]}>` expected, `<{DATE=[DATE], TIME=[DATE]}>` actual, and needs no JVM option. With the fix, all 17089 tests of `:core:test` pass under `-XX:hashCode=2` on JDK 21: ```bash cat > hash.gradle <<'G' allprojects { tasks.withType(Test).configureEach { jvmArgs '-XX:+UnlockExperimentalVMOptions', '-XX:hashCode=2' } } G ./gradlew -I hash.gradle :core:test ``` Adding a `hashCode=2` axis to CI is left to CALCITE-7892. 🤖 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]
