Skip to content
Permalink
Browse files
fix: allow DatabaseMetaData.getColumns to describe an unset scale (#1716
)

getColumns returns a 0 for the scale of a Decimal or Numeric column when the
scale is 0, and when the scale is null. The caller can then not differentiate
between a 0 or a null without another query.

This change replaces the 0 in the ResultSet for scale with a null when describing
an unscaled Decimal or Numeric column. getInt will still convert the null to a 0,
but the caller can then use wasNull() to find out if the underlying value was 0
or null.

This addresses Issue 1712. It is a breaking change, but if the correct getter
(getInt) is used for the column, there is no difference. Other getters may behave
differently.

Signed-off-by: crwr45 <charlie.wheelerrobinson@gmail.com>
  • Loading branch information
crwr45 committed Feb 25, 2020
1 parent 25eb32c commit 30843e45edc1e2bac499df2d1576c2db4d3d3309
Showing 2 changed files with 61 additions and 1 deletion.
@@ -1636,7 +1636,12 @@ base type (-1 if base type does not use a typmod). -1 if this type is not a doma
}
}
tuple[6] = connection.encodeString(Integer.toString(columnSize));
tuple[8] = connection.encodeString(Integer.toString(decimalDigits));
// Give null for an unset scale on Decimal and Numeric columns
if (((sqlType == Types.NUMERIC) || (sqlType == Types.DECIMAL)) && (typeMod == -1)) {
tuple[8] = null;
} else {
tuple[8] = connection.encodeString(Integer.toString(decimalDigits));
}

// Everything is base 10 unless we override later.
tuple[9] = connection.encodeString("10");
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2007, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.test.jdbc42;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.postgresql.test.TestUtil;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;

public class DatabaseMetaDataTest {

private Connection conn;

@Before
public void setUp() throws Exception {
conn = TestUtil.openDB();
TestUtil.createTable(conn, "decimaltest", "a decimal, b decimal(10, 5)");
}

@After
public void tearDown() throws Exception {
TestUtil.dropTable(conn, "decimaltest");
TestUtil.closeDB(conn);
}

@Test
public void testGetColumnsForNullScale() throws Exception {
DatabaseMetaData dbmd = conn.getMetaData();

ResultSet rs = dbmd.getColumns("%", "%", "decimaltest", "%");
assertTrue(rs.next());
assertEquals("a", rs.getString("COLUMN_NAME"));
assertEquals(0, rs.getInt("DECIMAL_DIGITS"));
assertTrue(rs.wasNull());

assertTrue(rs.next());
assertEquals("b", rs.getString("COLUMN_NAME"));
assertEquals(5, rs.getInt("DECIMAL_DIGITS"));
assertFalse(rs.wasNull());

assertTrue(!rs.next());
}
}

0 comments on commit 30843e4

Please sign in to comment.