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]