Skip to content

Commit

Permalink
Improve and optimize PreparedStatement.setBigDecimal() implementation…
Browse files Browse the repository at this point in the history
…. It now checks on null input parameter to prevent NPE. Also removed code to trim leading zero's.

Extended BugDecimalRound_Bug_3561() test with more values, including a null input parameter.
  • Loading branch information
mvdvm committed Apr 18, 2024
1 parent 4a33572 commit c162b4d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 21 deletions.
33 changes: 14 additions & 19 deletions src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -564,29 +564,24 @@ public void setAsciiStream(final int parameterIndex, final InputStream x, final
* @throws SQLException if a database access error occurs
*/
@Override
public void setBigDecimal(final int parameterIndex, BigDecimal x) throws SQLException {
public void setBigDecimal(final int parameterIndex, final BigDecimal x) throws SQLException
{
if (x == null) {
setValue(parameterIndex, "NULL");
return;
}

// get array position
final int i = getParamIdx(parameterIndex);
// round to the scale of the DB specification:
final BigDecimal decval = x.setScale(scale[i], java.math.RoundingMode.HALF_UP);
final String decvalStr = decval.toPlainString();

// round to the scale of the DB:
x = x.setScale(scale[i], java.math.RoundingMode.HALF_UP);

// if precision is now greater than that of the db, throw an error:
if (x.precision() > digits[i]) {
throw new SQLDataException("DECIMAL value exceeds allowed digits/scale: " + x.toPlainString() + " (" + digits[i] + "/" + scale[i] + ")", "22003");
// if precision is now greater than that of the DB specification, throw an error:
if (decval.precision() > digits[i]) {
throw new SQLDataException("DECIMAL value '" + decvalStr + "' exceeds allowed digits,scale: (" + digits[i] + "," + scale[i] + ")", "22003");
}

// MonetDB doesn't like leading 0's, since it counts them as part of
// the precision, so let's strip them off. (But be careful not to do
// this to the exact number "0".) Also strip off trailing
// numbers that are inherent to the double representation.
String xStr = x.toPlainString();
final int dot = xStr.indexOf('.');
if (dot >= 0)
xStr = xStr.substring(0, Math.min(xStr.length(), dot + 1 + scale[i]));
while (xStr.startsWith("0") && xStr.length() > 1)
xStr = xStr.substring(1);
setValue(parameterIndex, xStr);
setValue(parameterIndex, decvalStr);
}

/**
Expand Down
37 changes: 35 additions & 2 deletions tests/JDBC_API_Tester.java
Original file line number Diff line number Diff line change
Expand Up @@ -5586,7 +5586,7 @@ private void BugDecimalRound_Bug_3561() {
ResultSet rs = null;
try {
stmt1 = con.createStatement();
stmt1.executeUpdate("CREATE TABLE bug3561 (d decimal(14,4))");
stmt1.executeUpdate("CREATE TABLE bug3561 (d decimal(7,4))");

pst = con.prepareStatement("INSERT INTO bug3561 VALUES (?)");
pst.setBigDecimal(1, new BigDecimal("112.125"));
Expand All @@ -5595,6 +5595,29 @@ private void BugDecimalRound_Bug_3561() {
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal("0.012345"));
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal(0.0/10000000)); // 0.0000
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal(2.0/3)); // 0.666666667
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal(11.0/7)); // 1.571428571
pst.executeUpdate();
// repeat for negative values
pst.setBigDecimal(1, new BigDecimal("-0112.125"));
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal("-0212.12345"));
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal("-0.012345"));
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal(0.0/-10000000)); // 0.0000
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal(-2.0/3)); // -0.666666667
pst.executeUpdate();
pst.setBigDecimal(1, new BigDecimal(-11.0/7)); // -1.571428571
pst.executeUpdate();
// check what happens if null is used
pst.setBigDecimal(1, null);
pst.executeUpdate();

pst.close();

stmt2 = con.createStatement();
Expand All @@ -5618,7 +5641,17 @@ private void BugDecimalRound_Bug_3561() {
compareExpectedOutput("BugDecimalRound_Bug_3561",
"112.1250\n" +
"212.1235\n" +
"0.0123\n");
"0.0123\n" +
"0.0000\n" +
"0.6667\n" +
"1.5714\n" +
"-112.1250\n" +
"-212.1235\n" +
"-0.0123\n" +
"0.0000\n" +
"-0.6667\n" +
"-1.5714\n" +
"null\n");
}

private void BugExecuteUpdate_Bug_3350() {
Expand Down

0 comments on commit c162b4d

Please sign in to comment.