Skip to content

Commit

Permalink
fix getColumnPrecision for Numeric when scale and precision not speci…
Browse files Browse the repository at this point in the history
…fied fixes: Issue #2188 (#2203)
  • Loading branch information
davecramer committed Jul 2, 2021
1 parent 8f42bf9 commit 70f576c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Added

### Fixed
fix getColumnPrecision for Numeric when scale and precision not specified fixes: Issue #2188
- Fix: refreshRow made the row readOnly. Fixes Issue #2193

[42.2.22] (2021-06-16 10:09:33 -0400)
Expand Down
16 changes: 9 additions & 7 deletions pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
Expand Up @@ -1647,7 +1647,7 @@ base type (-1 if base type does not use a typmod). -1 if this type is not a doma
} else {
decimalDigits = connection.getTypeInfo().getScale(typeOid, typeMod);
columnSize = connection.getTypeInfo().getPrecision(typeOid, typeMod);
if (columnSize == 0) {
if ( sqlType != Types.NUMERIC && columnSize == 0 ) {
columnSize = connection.getTypeInfo().getDisplaySize(typeOid, typeMod);
}
}
Expand Down Expand Up @@ -1680,17 +1680,18 @@ base type (-1 if base type does not use a typmod). -1 if this type is not a doma
tuple[18] = null; // SCOPE_CATLOG
tuple[19] = null; // SCOPE_SCHEMA
tuple[20] = null; // SCOPE_TABLE
tuple[21] = baseTypeOid == 0
tuple[21] = baseTypeOid == 0 // SOURCE_DATA_TYPE
? null
: connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(baseTypeOid))); // SOURCE_DATA_TYPE
: connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(baseTypeOid)));

String autoinc = "NO";
if (defval != null && defval.contains("nextval(") || identity != null) {
autoinc = "YES";
}
tuple[22] = connection.encodeString(autoinc);
tuple[22] = connection.encodeString(autoinc); // IS_AUTOINCREMENT

// there is no way to tell if the value was actually autogenerated.
tuple[23] = connection.encodeString("");
tuple[23] = connection.encodeString(""); // IS_AUTOGENERATED

v.add(new Tuple(tuple));
}
Expand Down Expand Up @@ -2064,16 +2065,17 @@ public ResultSet getBestRowIdentifier(
while (rs.next()) {
byte[] @Nullable [] tuple = new byte[8][];
int typeOid = (int) rs.getLong("atttypid");
int sqlType = connection.getTypeInfo().getSQLType(typeOid);
int typeMod = rs.getInt("atttypmod");
int decimalDigits = connection.getTypeInfo().getScale(typeOid, typeMod);
int columnSize = connection.getTypeInfo().getPrecision(typeOid, typeMod);
if (columnSize == 0) {
if ( sqlType != Types.NUMERIC && columnSize == 0) {
columnSize = connection.getTypeInfo().getDisplaySize(typeOid, typeMod);
}
tuple[0] = connection.encodeString(Integer.toString(scope));
tuple[1] = rs.getBytes("attname");
tuple[2] =
connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(typeOid)));
connection.encodeString(Integer.toString(sqlType));
tuple[3] = connection.encodeString(connection.getTypeInfo().getPGType(typeOid));
tuple[4] = connection.encodeString(Integer.toString(columnSize));
tuple[5] = null; // unused
Expand Down
Expand Up @@ -73,6 +73,7 @@ public void setUp() throws Exception {
}
TestUtil.createTable(con, "metadatatest",
"id int4, name text, updated timestamptz, colour text, quest text");
TestUtil.createTable(con, "precision_test", "implicit_precision numeric");
TestUtil.dropSequence(con, "sercoltest_b_seq");
TestUtil.dropSequence(con, "sercoltest_c_seq");
TestUtil.createTable(con, "sercoltest", "a int, b serial, c bigserial");
Expand Down Expand Up @@ -130,6 +131,7 @@ public void tearDown() throws Exception {
TestUtil.dropTable(con, "sercoltest");
TestUtil.dropSequence(con, "sercoltest_b_seq");
TestUtil.dropSequence(con, "sercoltest_c_seq");
TestUtil.dropTable(con, "precision_test");
TestUtil.dropTable(con, "\"a\\\"");
TestUtil.dropTable(con, "\"a'\"");
TestUtil.dropTable(con, "arraytable");
Expand Down Expand Up @@ -495,6 +497,16 @@ public void testForeignKeys() throws Exception {
TestUtil.closeDB(con1);
}

@Test
public void testNumericPrecision() throws SQLException {
DatabaseMetaData dbmd = con.getMetaData();
assertNotNull(dbmd);
ResultSet rs = dbmd.getColumns(null, "public", "precision_test", "%");
assertTrue("It should have a row for the first column", rs.next());
assertEquals("The column size should be zero", 0, rs.getInt("COLUMN_SIZE"));
assertFalse("It should have a single column", rs.next());
}

@Test
public void testColumns() throws SQLException {
// At the moment just test that no exceptions are thrown KJ
Expand Down

0 comments on commit 70f576c

Please sign in to comment.