diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java b/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java index 89745b762..aa64c87b8 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java @@ -531,36 +531,9 @@ private void setTypeDefinition(DTV dtv) { param.typeDefinition = SSType.DECIMAL.toString() + "(" + valueLength + "," + scale + ")"; } } else { - if (dtv.getJavaType() == JavaType.BIGDECIMAL && null != dtv.getSetterValue()) { - String[] plainValueArray - = ((BigDecimal) dtv.getSetterValue()).abs().toPlainString().split("\\."); - - // Precision is computed as opposed to using BigDecimal.precision(). This is because the - // BigDecimal method can lead to inaccurate results. - int calculatedPrecision; - - // If the string array has two parts, e.g .the input was a decimal, check if the first - // part is a 0. For BigDecimals with leading zeroes, the leading zero does not count towards - // precision. For all other decimals, we include the integer portion as part of the precision - // When the string array has just one part, we only look at that part to compute precision. - if (plainValueArray.length == 2) { - if (plainValueArray[0].length() == 1 && (Integer.parseInt(plainValueArray[0]) == 0)) { - calculatedPrecision = plainValueArray[1].length(); - } else { - calculatedPrecision = plainValueArray[0].length() + plainValueArray[1].length(); - } - } else { - calculatedPrecision = plainValueArray[0].length(); - } - - param.typeDefinition = SSType.DECIMAL.toString() + "(" + calculatedPrecision + "," + - (plainValueArray.length == 2 ? plainValueArray[1].length() : 0) + ")"; - } else { - param.typeDefinition = SSType.DECIMAL.toString() + "(" - + SQLServerConnection.MAX_DECIMAL_PRECISION + "," + scale + ")"; - } + param.typeDefinition = SSType.DECIMAL.toString() + "(" + + SQLServerConnection.MAX_DECIMAL_PRECISION + "," + scale + ")"; } - break; case MONEY: diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java index 3bf8e0b1c..76f764e41 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java @@ -1426,228 +1426,6 @@ public void testFailedToResumeTransaction() throws Exception { } } - /** - * Tests that big decimal values with a precision less than 38 hold their precision. Tests cases where scale is - * 38 (integer part is a 0) and less than 38 (integer part is a non-zero). - * - * @throws SQLException - * when an error occurs - */ - @Test - public void testSmallBigDecimalValuesForLossOfPrecision() throws SQLException { - try (Connection con = getConnection(); - Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) { - double bigDecimalLessThanOne = 0.1235; - double bigDecimalGreaterThanOne = 1.1235; - String query = "CREATE PROCEDURE " + procName - + " @col1Value decimal(4,4) OUTPUT, @col2Value decimal(5,4) OUTPUT AS BEGIN SET @col1Value = " - + bigDecimalLessThanOne + " SET @col2Value = " + bigDecimalGreaterThanOne + " END"; - stmt.execute(query); - - try (CallableStatement cstmt = con.prepareCall("{CALL " + procName + "(?, ?)}")) { - cstmt.registerOutParameter("col1Value", java.sql.Types.DECIMAL, "DECIMAL"); - cstmt.registerOutParameter("col2Value", java.sql.Types.DECIMAL, "DECIMAL"); - cstmt.execute(); - - // Previously, the leading 0 would be counted as part of the precision. This would lead to the actual - // value being stored as 0.123. - assertEquals(0, - cstmt.getObject("col1Value", BigDecimal.class).compareTo(BigDecimal.valueOf(bigDecimalLessThanOne))); - assertEquals(0, - cstmt.getObject("col2Value", BigDecimal.class).compareTo(BigDecimal.valueOf(bigDecimalGreaterThanOne))); - } - } - } - - /** - * Tests that big decimal values with a precision equal to 38 hold their precision. Tests cases where scale is - * 38 (integer part is a 0) and less than 38 (integer part is a non-zero). - * - * @throws SQLException - * when an error occurs - */ - @Test - public void testLongBigDecimalValuesForLossOfPrecision() throws SQLException { - try (Connection con = getConnection(); Statement stmt = con.createStatement()) { - stmt.executeUpdate("CREATE TABLE " + tableName + " (col1 decimal(38,38), col2 decimal(38,37))"); - - // col1 has maximum scale (38) with a leading zero, for a precision of 38. col2 has maximum scale (37) when - // using a lead integer other than zero, also resulting in a precision of 38. - stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(0.98432319763138435186412316842316874322, 1.9843231976313843518641231684231687432)"); - - try (PreparedStatement pstmt = con.prepareStatement("SELECT * FROM " + tableName)) { - - try (ResultSet rs = pstmt.executeQuery()) { - rs.next(); - assertEquals(new BigDecimal("0.98432319763138435186412316842316874322"), rs.getObject(1)); - assertEquals(new BigDecimal("1.9843231976313843518641231684231687432"), rs.getObject(2)); - } - } - } - } - - /** - * Tests result of math operation in prepared statement using subtraction - * - * @throws SQLException - * when an error occurs - */ - @Test - public void testMathBigDecimalSubtraction() throws SQLException { - try (Connection con = getConnection(); Statement stmt = con.createStatement()) { - stmt.executeUpdate("CREATE TABLE " + tableName + " (test_column decimal(10,5))"); - stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(99999.12345)"); - try (PreparedStatement pstmt = con.prepareStatement("SELECT (test_column - ?), " - + "(test_column - ?), (test_column - ?), (test_column - ?) FROM " + tableName)) { - BigDecimal value1 = new BigDecimal("1.5"); - pstmt.setObject(1, value1); - BigDecimal value2 = new BigDecimal("0"); - pstmt.setObject(2, value2); - BigDecimal value3 = new BigDecimal("99999.12345"); - pstmt.setObject(3, value3); - BigDecimal value4 = new BigDecimal("99999.2"); - pstmt.setObject(4, value4); - - BigDecimal base = new BigDecimal("99999.12345"); - BigDecimal expected1 = base.subtract(value1); - BigDecimal expected2 = base.subtract(value2); - BigDecimal expected3 = base.subtract(value3); - BigDecimal expected4 = base.subtract(value4); - - try (ResultSet rs = pstmt.executeQuery()) { - rs.next(); - assertEquals(expected1, rs.getObject(1)); - assertEquals(expected2, rs.getObject(2)); - assertEquals(expected3, rs.getObject(3)); - assertEquals(expected4, rs.getObject(4)); - } - } - } - } - - /** - * Tests result of math operation in prepared statement using addition - * - * @throws SQLException - * when an error occurs - */ - @Test - public void testMathBigDecimalAddition() throws SQLException { - try (Connection con = getConnection(); Statement stmt = con.createStatement()) { - stmt.executeUpdate("CREATE TABLE " + tableName + " (test_column decimal(10,5))"); - stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(99999.12345)"); - try (PreparedStatement pstmt = con.prepareStatement("SELECT (test_column + ?), " - + "(test_column + ?), (test_column + ?), (test_column + ?) FROM " + tableName)) { - BigDecimal value1 = new BigDecimal("1.5"); - pstmt.setObject(1, value1); - BigDecimal value2 = new BigDecimal("0"); - pstmt.setObject(2, value2); - BigDecimal value3 = new BigDecimal("99999.12345"); - pstmt.setObject(3, value3); - BigDecimal value4 = new BigDecimal("99999.2"); - pstmt.setObject(4, value4); - - BigDecimal base = new BigDecimal("99999.12345"); - BigDecimal expected1 = base.add(value1); - BigDecimal expected2 = base.add(value2); - BigDecimal expected3 = base.add(value3); - BigDecimal expected4 = base.add(value4); - - try (ResultSet rs = pstmt.executeQuery()) { - rs.next(); - assertEquals(expected1, rs.getObject(1)); - assertEquals(expected2, rs.getObject(2)); - assertEquals(expected3, rs.getObject(3)); - assertEquals(expected4, rs.getObject(4)); - } - } - } - } - - /** - * Tests result of math operation in prepared statement using multiplication - * - * @throws SQLException - * when an error occurs - */ - @Test - public void testMathBigDecimalMultiplication() throws SQLException { - try (Connection con = getConnection(); Statement stmt = con.createStatement()) { - stmt.executeUpdate("CREATE TABLE " + tableName + " (test_column decimal(10,5))"); - stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(99999.12345)"); - try (PreparedStatement pstmt = con.prepareStatement("SELECT (test_column * ?), " - + "(test_column * ?), (test_column * ?), (test_column * ?) FROM " + tableName)) { - BigDecimal value1 = new BigDecimal("1.5"); - pstmt.setObject(1, value1); - BigDecimal value2 = new BigDecimal("0"); - pstmt.setObject(2, value2); - BigDecimal value3 = new BigDecimal("99999.12345"); - pstmt.setObject(3, value3); - BigDecimal value4 = new BigDecimal("99999.2"); - pstmt.setObject(4, value4); - - BigDecimal base = new BigDecimal("99999.12345"); - BigDecimal expected1 = base.multiply(value1); - BigDecimal expected2 = base.multiply(value2); - BigDecimal expected3 = base.multiply(value3); - BigDecimal expected4 = base.multiply(value4); - - try (ResultSet rs = pstmt.executeQuery()) { - rs.next(); - assertEquals(expected1, rs.getObject(1)); - assertEquals(expected2, rs.getObject(2)); - assertEquals(expected3, rs.getObject(3)); - assertEquals(expected4, rs.getObject(4)); - } - } - } - } - - /** - * Tests result of math operation in prepared statement using division - * - * @throws SQLException - * when an error occurs - */ - @Test - public void testMathBigDecimalDivision() throws SQLException { - try (Connection con = getConnection(); Statement stmt = con.createStatement()) { - stmt.executeUpdate("CREATE TABLE " + tableName + " (test_column decimal(10,5))"); - stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(99999.12345)"); - try (PreparedStatement pstmt = con.prepareStatement("select (test_column / ?), " - + "(test_column / ?), (test_column / ?), (test_column / ?) FROM " + tableName)) { - - /* - * Division has some unique properties in sql server math operations. - * Notably in this case we cannot compare a result with an infinite trailing decimal - * and the returned value has an expanded precision. - */ - BigDecimal value1 = new BigDecimal("1.5"); - pstmt.setObject(1, value1); - BigDecimal value2 = new BigDecimal("0.1"); - pstmt.setObject(2, value2); - BigDecimal value3 = new BigDecimal("99999.12345"); - pstmt.setObject(3, value3); - BigDecimal value4 = new BigDecimal("1"); - pstmt.setObject(4, value4); - - BigDecimal base = new BigDecimal("99999.12345"); - BigDecimal expected1 = base.divide(value1, RoundingMode.HALF_UP); - BigDecimal expected2 = base.divide(value2, RoundingMode.HALF_UP); - BigDecimal expected3 = base.divide(value3, RoundingMode.HALF_UP); - BigDecimal expected4 = base.divide(value4, RoundingMode.HALF_UP); - - try (ResultSet rs = pstmt.executeQuery()) { - rs.next(); - assertEquals(0, expected1.compareTo((BigDecimal) rs.getObject(1))); - assertEquals(0, expected2.compareTo((BigDecimal) rs.getObject(2))); - assertEquals(0, expected3.compareTo((BigDecimal) rs.getObject(3))); - assertEquals(0, expected4.compareTo((BigDecimal) rs.getObject(4))); - } - } - } - } - /** * * @throws Exception