diff --git a/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java b/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java index bf3f03f..44fb1b5 100644 --- a/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java +++ b/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java @@ -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); } /** diff --git a/tests/JDBC_API_Tester.java b/tests/JDBC_API_Tester.java index aea769e..76c4a09 100644 --- a/tests/JDBC_API_Tester.java +++ b/tests/JDBC_API_Tester.java @@ -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")); @@ -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(); @@ -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() {