You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by "sandynz (via GitHub)" <gi...@apache.org> on 2025/12/05 11:54:12 UTC
[I] HashModShardingAlgorithm depends on shardingValue.hashCode() might cause some issues [shardingsphere]
sandynz opened a new issue, #37282:
URL: https://github.com/apache/shardingsphere/issues/37282
Related code:
```
HashModShardingAlgorithm.java
private long hashShardingValue(final Object shardingValue) {
return Math.abs((long) shardingValue.hashCode());
}
```
### Possible issue 1
`java.lang.Number` sub-classes might have different `hashCode()` implementation, e.g.
```
println("Integer.valueOf(-1).hashCode(): " + Integer.valueOf(-1).hashCode())
println("Long.valueOf(-1).hashCode(): " + Long.valueOf(-1).hashCode())
println("BigInteger.valueOf(-1).hashCode(): " + BigInteger.valueOf(-1).hashCode())
-- result
Integer.valueOf(-1).hashCode(): -1
Long.valueOf(-1).hashCode(): 0
BigInteger.valueOf(-1).hashCode(): -1
```
Eexample table: `t_order`.
Sharding rule:
```
rules:
- !SHARDING
autoTables:
t_order:
actualDataSources: ds_0,ds_1
shardingStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: auto_mod
keyGenerateStrategy:
column: user_id
keyGeneratorName: snowflake
shardingAlgorithms:
auto_mod:
type: HASH_MOD
props:
sharding-count: 2
keyGenerators:
snowflake:
type: SNOWFLAKE
```
Insert record with Integer sharding key value, then query with Long sharding key value, ResultSet return empty result.
Test code:
```
@Test
void assertHashModSetLongOnIntColumnWorks() throws SQLException {
try (Connection connection = DriverManager.getConnection("jdbc:shardingsphere:classpath:config/driver/foo-driver-fixture.yaml")) {
assertThat(connection, isA(ShardingSphereConnection.class));
try (Statement statement = connection.createStatement()) {
statement.execute("DROP TABLE IF EXISTS t_order");
statement.execute("CREATE TABLE t_order (order_id INT PRIMARY KEY, user_id INT)");
}
int value = -1;
try (PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO t_order (order_id, user_id) VALUES (?, ?)")) {
preparedStatement.setObject(1, value); // Insert with Integer value
preparedStatement.setObject(2, 101);
int updatedCount = preparedStatement.executeUpdate();
assertThat(updatedCount, is(1));
}
try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM t_order WHERE order_id = ?")) {
preparedStatement.setObject(1, value); // Query with Integer value, related record could be queried out
ResultSet resultSet = preparedStatement.executeQuery();
assertTrue(resultSet.next()); // Pass
assertThat(resultSet.getInt(1), is(value)); // Pass
resultSet.close();
}
try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM t_order WHERE order_id = ?")) {
preparedStatement.setObject(1, (long) value); // Query with Long value, related record could NOT be queried out
ResultSet resultSet = preparedStatement.executeQuery();
assertTrue(resultSet.next()); // WRONG
assertThat(resultSet.getInt(1), is(value));
resultSet.close();
}
}
}
```
It was submitted in https://github.com/apache/shardingsphere/pull/37281/files
The similar test code, use raw MySQL JDBC driver, test on MySQL, it works.
### Possible issue 2
If different vendors JRE or different versions of JRE have different `hashCode()` implementation, then when JRE vendor or version is changed, it'll cause different routing for the same sharding value.
--
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: notifications-unsubscribe@shardingsphere.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] HashModShardingAlgorithm depends on shardingValue.hashCode() might cause some issues [shardingsphere]
Posted by "ym0506 (via GitHub)" <gi...@apache.org>.
ym0506 commented on issue #37282:
URL: https://github.com/apache/shardingsphere/issues/37282#issuecomment-3994519497
I opened PR #38326 for this issue.
Summary:
- Normalize / values in integer range to integer semantics before hashing, so equal numeric values (for example ) route consistently across numeric Java types.
- Keep existing behavior for out-of-range values to minimize compatibility impact.
- Add regression tests and update to use as an end-to-end verification case.
--
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: notifications-unsubscribe@shardingsphere.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] HashModShardingAlgorithm depends on shardingValue.hashCode() might cause some issues [shardingsphere]
Posted by "terrymanu (via GitHub)" <gi...@apache.org>.
terrymanu closed issue #37282: HashModShardingAlgorithm depends on shardingValue.hashCode() might cause some issues
URL: https://github.com/apache/shardingsphere/issues/37282
--
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: notifications-unsubscribe@shardingsphere.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] HashModShardingAlgorithm depends on shardingValue.hashCode() might cause some issues [shardingsphere]
Posted by "ym0506 (via GitHub)" <gi...@apache.org>.
ym0506 commented on issue #37282:
URL: https://github.com/apache/shardingsphere/issues/37282#issuecomment-3984512418
I reproduced this issue on current master, and the behavior matches the report: HASH_MOD uses shardingValue.hashCode(), so the same numeric value can route differently by Java type (for example Integer(-1) vs Long(-1)).
I’d like to take this issue and open a PR.
Planned changes:
Normalize Number sharding values to a canonical numeric form before hashing, so equal numeric values route consistently across Integer/Long/BigInteger, while keeping non-Number behavior unchanged.
Add regression tests in HashModShardingAlgorithmTest for mixed numeric types with the same value.
Update ShardingSphereDriverTest#assertHashModSetLongOnIntColumnWorks to use -1 (remove the current TODO) as an end-to-end verification.
I will start implementing it.
--
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: notifications-unsubscribe@shardingsphere.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org