postgresql-jdbc.git / summary / log / commit / refs
commit 9b8a3ffd8a952a55be28d14cb80a23fdbb955133
Author: Dave Cramer <davecramer@gmail.com>
Commit: GitHub <noreply@github.com>
Date: Tue Nov 12 22:03:51 2019 +0000
fix: issue 716 getTypeInfo() may not return data in the order specified in Oracle documentation (#1506)
this replaces PR #910 as it was stale and easier to replace than fix. Original work by @zemian
.../java/org/postgresql/jdbc/PgDatabaseMetaData.java | 19 ++++++++++++++++++-
.../main/java/org/postgresql/util/ByteConverter.java | 19 +++++++++++++++++++
.../postgresql/test/jdbc4/DatabaseMetaDataTest.java | 13 +++++++++++++
3 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
index 56d13506..ef3ac750 100644
--- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
+++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
@@ -9,11 +9,13 @@ import org.postgresql.core.BaseStatement;
import org.postgresql.core.Field;
import org.postgresql.core.Oid;
import org.postgresql.core.ServerVersion;
+import org.postgresql.util.ByteConverter;
import org.postgresql.util.GT;
import org.postgresql.util.JdbcBlackHole;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
+import java.math.BigInteger;
import java.sql.Array;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
@@ -24,6 +26,9 @@ import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
+
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -2247,7 +2252,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData {
connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.typeSearchable));
while (rs.next()) {
- byte[][] tuple = new byte[18][];
+ byte[][] tuple = new byte[19][];
String typname = rs.getString(1);
int typeOid = (int) rs.getLong(2);
@@ -2255,6 +2260,10 @@ public class PgDatabaseMetaData implements DatabaseMetaData {
int sqlType = connection.getTypeInfo().getSQLType(typname);
tuple[1] =
connection.encodeString(Integer.toString(sqlType));
+
+ /* this is just for sorting below, the result set never sees this */
+ tuple[18] = BigInteger.valueOf(sqlType).toByteArray();
+
tuple[2] = connection
.encodeString(Integer.toString(connection.getTypeInfo().getMaximumPrecision(typeOid)));
@@ -2300,6 +2309,14 @@ public class PgDatabaseMetaData implements DatabaseMetaData {
rs.close();
stmt.close();
+ Collections.sort(v, new Comparator<byte[][]>() {
+ @Override
+ public int compare(byte[][] o1, byte[][] o2) {
+ int i1 = ByteConverter.bytesToInt(o1[18]);
+ int i2 = ByteConverter.bytesToInt(o2[18]);
+ return (i1 < i2) ? -1 : ((i1 == i2) ? 0 : 1);
+ }
+ });
return ((BaseStatement) createMetaDataStatement()).createDriverResultSet(f, v);
}
diff --git a/pgjdbc/src/main/java/org/postgresql/util/ByteConverter.java b/pgjdbc/src/main/java/org/postgresql/util/ByteConverter.java
index 5464236c..f1188977 100644
--- a/pgjdbc/src/main/java/org/postgresql/util/ByteConverter.java
+++ b/pgjdbc/src/main/java/org/postgresql/util/ByteConverter.java
@@ -16,6 +16,25 @@ public class ByteConverter {
// prevent instantiation of static helper class
}
+ /**
+ * Convert a variable length array of bytes to an integer
+ * @param bytes array of bytes that can be decoded as an integer
+ * @return integer
+ */
+ public static int bytesToInt(byte []bytes) {
+ if ( bytes.length == 1 ) {
+ return (int)bytes[0];
+ }
+ if ( bytes.length == 2 ) {
+ return int2(bytes, 0);
+ }
+ if ( bytes.length == 4 ) {
+ return int4(bytes, 0);
+ } else {
+ throw new IllegalArgumentException("Argument bytes is empty");
+ }
+ }
+
/**
* Parses a long value from the byte array.
*
diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java
index 813a777f..a22f42ae 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java
@@ -232,4 +232,17 @@ public class DatabaseMetaDataTest {
stmt.execute("DROP FUNCTION getfunc_f3(int, varchar)");
}
}
+
+ @Test
+ public void testSortedDataTypes() throws SQLException {
+ // https://github.com/pgjdbc/pgjdbc/issues/716
+ DatabaseMetaData dbmd = conn.getMetaData();
+ ResultSet rs = dbmd.getTypeInfo();
+ int lastType = Integer.MIN_VALUE;
+ while (rs.next()) {
+ int type = rs.getInt("DATA_TYPE");
+ assertTrue(lastType <= type);
+ lastType = type;
+ }
+ }
}
[parent: c67b0b0b667a]