diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java index e7b5c4472f..75f0a63c18 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java @@ -14,6 +14,7 @@ import org.postgresql.util.PSQLException; import org.postgresql.util.PSQLState; +import java.io.IOException; import java.sql.Array; import java.sql.Connection; import java.sql.DatabaseMetaData; @@ -24,6 +25,8 @@ 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; @@ -2227,6 +2230,20 @@ public ResultSet getTypeInfo() throws SQLException { rs.close(); stmt.close(); + // Per JDBC API, we should sort result by SqlType value + Collections.sort(v, new Comparator() { + @Override + public int compare(byte[][] o1, byte[][] o2) { + try { + int i1 = Integer.parseInt(connection.getEncoding().decode(o1[1])); + int i2 = Integer.parseInt(connection.getEncoding().decode(o2[1])); + return (i1 < i2) ? -1 : ((i1 == i2) ? 0 : 1); + } catch (IOException e) { + return -1; // Should not happen, but if we do, we should avoid breaking the operation. + } + } + }); + return ((BaseStatement) createMetaDataStatement()).createDriverResultSet(f, v); } 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 734ace443e..78ea5ded50 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java @@ -80,4 +80,18 @@ public void testGetSchemas() throws SQLException { assertNull(rs.getString("TABLE_CATALOG")); assertTrue(!rs.next()); } + + @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; + } + rs.close(); + } }