Permalink
Browse files

fix: Add fallback to setObject(int, Object) for Number (#812)

Add a fallback to the PgPreparedStatement.setObject(int, Object) method
which handles Number types. This allows support for BigInteger and
similar types (f.e. AtomicLong) which are not explicitly mentioned by
JDBC.

This fallback operates by invoking toString() on the Number, which is
the same method used by setBigDecimal(int, BigDecimal). Also,
setBigDecimal(int, BigDecimal) does now invoke setNumber(int, Number)
because they work the same way.

The tracking bug is #810.
  • Loading branch information...
RobertZenz authored and davecramer committed May 19, 2017
1 parent 9022862 commit 5b9edb7dfb1b281bffedf7c9f2583f2df354c0ea
@@ -345,12 +345,7 @@ public void setDouble(int parameterIndex, double x) throws SQLException {
}
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
checkClosed();
if (x == null) {
setNull(parameterIndex, Types.DECIMAL);
} else {
bindLiteral(parameterIndex, x.toString(), Oid.NUMERIC);
}
setNumber(parameterIndex, x);
}
public void setString(int parameterIndex, String x) throws SQLException {
@@ -515,6 +510,15 @@ private void setMap(int parameterIndex, Map<?, ?> x) throws SQLException {
}
}
private void setNumber(int parameterIndex, Number x) throws SQLException {
checkClosed();
if (x == null) {
setNull(parameterIndex, Types.DECIMAL);
} else {
bindLiteral(parameterIndex, x.toString(), Oid.NUMERIC);
}
}
@Override
public void setObject(int parameterIndex, Object in, int targetSqlType, int scale)
throws SQLException {
@@ -962,6 +966,8 @@ public void setObject(int parameterIndex, Object x) throws SQLException {
//#endif
} else if (x instanceof Map) {
setMap(parameterIndex, (Map<?, ?>) x);
} else if (x instanceof Number) {
setNumber(parameterIndex, (Number) x);
} else {
// Can't infer a type.
throw new PSQLException(GT.tr(
@@ -27,6 +27,7 @@
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -35,6 +36,7 @@
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicLong;
@RunWith(Parameterized.class)
@@ -1092,6 +1094,66 @@ public void testSetObjectBigDecimalWithScale() throws SQLException {
pstruncate.close();
}
@Test
public void testSetObjectWithBigDecimal() throws SQLException {
TestUtil.createTempTable(con, "number_fallback",
"n1 numeric");
PreparedStatement psinsert = con.prepareStatement("insert into number_fallback values(?)");
PreparedStatement psselect = con.prepareStatement("select n1 from number_fallback");
psinsert.setObject(1, new BigDecimal("733"));
psinsert.execute();
ResultSet rs = psselect.executeQuery();
assertTrue(rs.next());
assertTrue(
"expected 733, but received " + rs.getBigDecimal(1),
new BigDecimal("733").compareTo(rs.getBigDecimal(1)) == 0);
psinsert.close();
psselect.close();
}
@Test
public void testSetObjectNumberFallbackWithBigInteger() throws SQLException {
TestUtil.createTempTable(con, "number_fallback",
"n1 numeric");
PreparedStatement psinsert = con.prepareStatement("insert into number_fallback values(?)");
PreparedStatement psselect = con.prepareStatement("select n1 from number_fallback");
psinsert.setObject(1, new BigInteger("733"));
psinsert.execute();
ResultSet rs = psselect.executeQuery();
assertTrue(rs.next());
assertTrue(
"expected 733, but received " + rs.getBigDecimal(1),
new BigDecimal("733").compareTo(rs.getBigDecimal(1)) == 0);
psinsert.close();
psselect.close();
}
@Test
public void testSetObjectNumberFallbackWithAtomicLong() throws SQLException {
TestUtil.createTempTable(con, "number_fallback",
"n1 numeric");
PreparedStatement psinsert = con.prepareStatement("insert into number_fallback values(?)");
PreparedStatement psselect = con.prepareStatement("select n1 from number_fallback");
psinsert.setObject(1, new AtomicLong(733));
psinsert.execute();
ResultSet rs = psselect.executeQuery();
assertTrue(rs.next());
assertTrue(
"expected 733, but received " + rs.getBigDecimal(1),
new BigDecimal("733").compareTo(rs.getBigDecimal(1)) == 0);
psinsert.close();
psselect.close();
}
@Test
public void testUnknownSetObject() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("INSERT INTO intervaltable(i) VALUES (?)");

0 comments on commit 5b9edb7

Please sign in to comment.