mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(jdbc): preserve multi-bit values when reading booleans
This commit is contained in:
@@ -3026,11 +3026,24 @@ public final class DbxJdbcPlugin {
|
||||
int index,
|
||||
boolean preserveOracleDateTime
|
||||
) throws SQLException {
|
||||
int columnType = meta.getColumnType(index);
|
||||
|
||||
if (columnType == Types.BOOLEAN) {
|
||||
boolean boolValue = rs.getBoolean(index);
|
||||
if (!rs.wasNull()) {
|
||||
return boolValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Object value = rs.getObject(index);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof byte[] bytes) {
|
||||
if (columnType == Types.BIT && bytes.length == 1 && (bytes[0] == 't' || bytes[0] == 'f')) {
|
||||
return bytes[0] == 't';
|
||||
}
|
||||
return binaryToHex(bytes);
|
||||
}
|
||||
if (value instanceof Clob clob) {
|
||||
|
||||
@@ -425,6 +425,39 @@ final class DbxJdbcPluginTest {
|
||||
assertEquals("GaussDB CLOB 中文内容", method.invoke(null, rs, columnMeta(Types.CLOB), 1, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void readValueConvertsGaussDbBooleanBytesWithoutCollapsingMultiBitValues() throws Exception {
|
||||
Method method = DbxJdbcPlugin.class.getDeclaredMethod(
|
||||
"readValue",
|
||||
ResultSet.class,
|
||||
ResultSetMetaData.class,
|
||||
int.class,
|
||||
boolean.class
|
||||
);
|
||||
method.setAccessible(true);
|
||||
|
||||
assertEquals(true, method.invoke(null, objectResultSet(new byte[] { 't' }), columnMeta(Types.BIT), 1, false));
|
||||
assertEquals(false, method.invoke(null, objectResultSet(new byte[] { 'f' }), columnMeta(Types.BIT), 1, false));
|
||||
assertEquals(null, method.invoke(null, objectResultSet(null), columnMeta(Types.BIT), 1, false));
|
||||
assertEquals("0x0102", method.invoke(null, objectResultSet(new byte[] { 1, 2 }), columnMeta(Types.BIT), 1, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void readValueUsesJdbcBooleanAccessForBooleanColumns() throws Exception {
|
||||
Method method = DbxJdbcPlugin.class.getDeclaredMethod(
|
||||
"readValue",
|
||||
ResultSet.class,
|
||||
ResultSetMetaData.class,
|
||||
int.class,
|
||||
boolean.class
|
||||
);
|
||||
method.setAccessible(true);
|
||||
|
||||
assertEquals(true, method.invoke(null, booleanResultSet(true), columnMeta(Types.BOOLEAN), 1, false));
|
||||
assertEquals(false, method.invoke(null, booleanResultSet(false), columnMeta(Types.BOOLEAN), 1, false));
|
||||
assertEquals(null, method.invoke(null, booleanResultSet(null), columnMeta(Types.BOOLEAN), 1, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeQueryPreservesOracleDateTimeComponent() throws Exception {
|
||||
List<String> calls = new ArrayList<>();
|
||||
@@ -2192,6 +2225,29 @@ final class DbxJdbcPluginTest {
|
||||
);
|
||||
}
|
||||
|
||||
private static ResultSet objectResultSet(Object value) {
|
||||
return (ResultSet) Proxy.newProxyInstance(
|
||||
DbxJdbcPluginTest.class.getClassLoader(),
|
||||
new Class<?>[] { ResultSet.class },
|
||||
(proxy, method, args) -> switch (method.getName()) {
|
||||
case "getObject" -> value;
|
||||
default -> defaultValue(method.getReturnType());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static ResultSet booleanResultSet(Boolean value) {
|
||||
return (ResultSet) Proxy.newProxyInstance(
|
||||
DbxJdbcPluginTest.class.getClassLoader(),
|
||||
new Class<?>[] { ResultSet.class },
|
||||
(proxy, method, args) -> switch (method.getName()) {
|
||||
case "getBoolean" -> Boolean.TRUE.equals(value);
|
||||
case "wasNull" -> value == null;
|
||||
default -> defaultValue(method.getReturnType());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static DatabaseMetaData tableTypesMeta(String... types) {
|
||||
return (DatabaseMetaData) Proxy.newProxyInstance(
|
||||
DbxJdbcPluginTest.class.getClassLoader(),
|
||||
|
||||
Reference in New Issue
Block a user