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]

Reply via email to