fix(intersystems): read out-of-range integers via BigDecimal
This commit is contained in:
4 files changed
+94
-8
No files matched your search
@@ -67,10 +67,22 @@ public final class IrisAgent extends ConfiguredJdbcAgent {
|
||||
|
||||
@Override
|
||||
protected Object resultValue(ResultSet rs, int index, int sqlType) {
|
||||
if (sqlType == Types.OTHER) {
|
||||
return unchecked(() -> JdbcExecutor.normalizeResultValue(rs.getObject(index)));
|
||||
switch (sqlType) {
|
||||
case Types.BIGINT:
|
||||
case Types.INTEGER:
|
||||
case Types.SMALLINT:
|
||||
case Types.TINYINT:
|
||||
// InterSystems can expose values outside the Java primitive range
|
||||
// implied by its JDBC metadata. Preserve them without narrowing.
|
||||
return unchecked(() -> {
|
||||
Object value = rs.getBigDecimal(index);
|
||||
return rs.wasNull() ? null : value;
|
||||
});
|
||||
case Types.OTHER:
|
||||
return unchecked(() -> JdbcExecutor.normalizeResultValue(rs.getObject(index)));
|
||||
default:
|
||||
return super.resultValue(rs, index, sqlType);
|
||||
}
|
||||
return super.resultValue(rs, index, sqlType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -76,8 +77,38 @@ class IrisAgentTest {
|
||||
assertEquals(Collections.singletonList("getObject"), calls);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readsOutOfRangeIntegerThroughBigDecimal() {
|
||||
BigDecimal valueOutsideIntegerRange = new BigDecimal("2147483648");
|
||||
List<String> calls = new ArrayList<>();
|
||||
ResultSet resultSet = proxy(ResultSet.class, (method, args) -> {
|
||||
if ("getBigDecimal".equals(method.getName())) {
|
||||
calls.add("getBigDecimal");
|
||||
return valueOutsideIntegerRange;
|
||||
}
|
||||
if (method.getName().startsWith("get")) {
|
||||
calls.add(method.getName());
|
||||
throw new SQLException("Numeric value out of range");
|
||||
}
|
||||
if ("wasNull".equals(method.getName())) {
|
||||
return false;
|
||||
}
|
||||
return defaultValue(method.getReturnType());
|
||||
});
|
||||
|
||||
Object value = new IrisAgent().resultValue(resultSet, 1, Types.INTEGER);
|
||||
|
||||
assertEquals(valueOutsideIntegerRange, value);
|
||||
assertEquals(Collections.singletonList("getBigDecimal"), calls);
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesStringPathForStandardValues() {
|
||||
assertStringPath(Types.VARCHAR);
|
||||
assertStringPath(Types.LONGVARCHAR);
|
||||
}
|
||||
|
||||
private static void assertStringPath(int sqlType) {
|
||||
List<String> calls = new ArrayList<>();
|
||||
ResultSet resultSet = proxy(ResultSet.class, (method, args) -> {
|
||||
if ("getString".equals(method.getName())) {
|
||||
@@ -90,7 +121,7 @@ class IrisAgentTest {
|
||||
return defaultValue(method.getReturnType());
|
||||
});
|
||||
|
||||
Object value = new IrisAgent().resultValue(resultSet, 1, Types.VARCHAR);
|
||||
Object value = new IrisAgent().resultValue(resultSet, 1, sqlType);
|
||||
|
||||
assertEquals("ordinary", value);
|
||||
assertEquals(Collections.singletonList("getString"), calls);
|
||||
|
||||
Reference in new issue
Block a user