Skip to content

Commit 8ade82e

Browse files
authored
Wrong JDBC type for timestampz (eclipse-vertx#1138)
Fixes eclipse-vertx#1124 Oracle returns a int type which does not match `JDBCType.TIMESTAMP_WITH_TIMEZONE` when the column's DB type is TIMESTAMPZ. Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
1 parent ae3708f commit 8ade82e

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleColumnDesc.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2011-2022 Contributors to the Eclipse Foundation
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License 2.0 which is available at
@@ -10,17 +10,34 @@
1010
*/
1111
package io.vertx.oracleclient.impl;
1212

13+
import io.netty.util.collection.IntObjectHashMap;
14+
import io.netty.util.collection.IntObjectMap;
1315
import io.vertx.sqlclient.desc.ColumnDescriptor;
1416
import io.vertx.sqlclient.impl.RowDesc;
17+
import oracle.sql.TIMESTAMPTZ;
1518

1619
import java.sql.JDBCType;
1720
import java.sql.ResultSetMetaData;
1821
import java.sql.SQLException;
1922
import java.util.ArrayList;
23+
import java.util.HashMap;
2024
import java.util.List;
25+
import java.util.Map;
2126

2227
public class OracleColumnDesc implements ColumnDescriptor {
2328

29+
private static final IntObjectMap<JDBCType> TYPES_BY_VENDOR_TYPE_NUMBER;
30+
private static final Map<String, JDBCType> TYPES_BY_CLASSNAME;
31+
32+
static {
33+
TYPES_BY_VENDOR_TYPE_NUMBER = new IntObjectHashMap<>();
34+
for (JDBCType type : JDBCType.values()) {
35+
TYPES_BY_VENDOR_TYPE_NUMBER.put(type.getVendorTypeNumber(), type);
36+
}
37+
TYPES_BY_CLASSNAME = new HashMap<>();
38+
TYPES_BY_CLASSNAME.put(TIMESTAMPTZ.class.getName(), JDBCType.TIMESTAMP_WITH_TIMEZONE);
39+
}
40+
2441
public static RowDesc rowDesc(ResultSetMetaData metaData) throws SQLException {
2542
int cols = metaData.getColumnCount();
2643
List<String> columnNames = new ArrayList<>(cols);
@@ -37,18 +54,19 @@ public static RowDesc rowDesc(ResultSetMetaData metaData) throws SQLException {
3754
private final JDBCType type;
3855

3956
public OracleColumnDesc(ResultSetMetaData md, int idx) throws SQLException {
40-
this.name = md.getColumnLabel(idx);
41-
this.typeName = md.getColumnTypeName(idx);
42-
this.type = find(md.getColumnType(idx));
57+
name = md.getColumnLabel(idx);
58+
typeName = md.getColumnTypeName(idx);
59+
type = find(md, idx);
4360
}
4461

45-
private static JDBCType find(int vendorTypeNumber) {
46-
for (JDBCType jdbcType : JDBCType.values()) {
47-
if (jdbcType.getVendorTypeNumber() == vendorTypeNumber) {
48-
return jdbcType;
62+
private JDBCType find(ResultSetMetaData md, int idx) throws SQLException {
63+
JDBCType res;
64+
if ((res = TYPES_BY_VENDOR_TYPE_NUMBER.get(md.getColumnType(idx))) == null) {
65+
if ((res = TYPES_BY_CLASSNAME.get(md.getColumnClassName(idx))) == null) {
66+
res = JDBCType.OTHER;
4967
}
5068
}
51-
return JDBCType.OTHER;
69+
return res;
5270
}
5371

5472
@Override

vertx-oracle-client/src/test/java/io/vertx/oracleclient/test/OracleQueriesTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2011-2022 Contributors to the Eclipse Foundation
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License 2.0 which is available at
@@ -16,12 +16,14 @@
1616
import io.vertx.oracleclient.OraclePool;
1717
import io.vertx.oracleclient.test.junit.OracleRule;
1818
import io.vertx.sqlclient.PoolOptions;
19+
import io.vertx.sqlclient.desc.ColumnDescriptor;
1920
import org.junit.After;
2021
import org.junit.Before;
2122
import org.junit.ClassRule;
2223
import org.junit.Test;
2324
import org.junit.runner.RunWith;
2425

26+
import java.sql.JDBCType;
2527
import java.time.OffsetDateTime;
2628

2729
import static java.time.temporal.ChronoUnit.MINUTES;
@@ -51,6 +53,9 @@ public void testCurrentTimestampType(TestContext ctx) {
5153
Object value = rows.iterator().next().getValue(0);
5254
assertThat(value, is(instanceOf(OffsetDateTime.class)));
5355
assertEquals(0, MINUTES.between((OffsetDateTime) value, OffsetDateTime.now()));
56+
ColumnDescriptor descriptor = rows.columnDescriptors().get(0);
57+
ctx.assertEquals("TIMESTAMP WITH TIME ZONE", descriptor.typeName());
58+
ctx.assertEquals(JDBCType.TIMESTAMP_WITH_TIMEZONE, descriptor.jdbcType());
5459
});
5560
}));
5661
}

0 commit comments

Comments
 (0)