From 88f389ce16f38321a7544f3b558c1ecfb2b90845 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Fri, 6 Dec 2024 21:32:50 +0530 Subject: [PATCH 01/25] Stored procedure call returns wrong BigDecimal scale. Set scale value dynamically for DECIMAL output parameters in registerOutParameter method. This change retrieves the scale from the ParameterMetaData and applies it to the DECIMAL output parameter. This provides a more flexible approach for handling DECIMAL data types. As an alternative, users can directly call registerOutParameter(index, sqlType, scale) to specify the scale explicitly. --- .../sqlserver/jdbc/SQLServerCallableStatement.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index e6e42ada6..4ac19815a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -23,6 +23,7 @@ import java.sql.SQLXML; import java.sql.Time; import java.sql.Timestamp; +import java.sql.ParameterMetaData; import java.text.MessageFormat; import java.time.LocalDateTime; import java.util.Calendar; @@ -150,6 +151,16 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti case microsoft.sql.Types.DATETIMEOFFSET: param.setOutScale(7); break; + case java.sql.Types.DECIMAL: + ParameterMetaData parameterMetaData = this.getParameterMetaData(); + if (parameterMetaData != null) { + try { + // Fetch scale from metadata for DECIMAL type + int scale = parameterMetaData.getScale(index); + param.setOutScale(scale); + } + } + break; default: break; } From 1afdc01d00b62b8e1c5dff18261e19007cf67700 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Fri, 6 Dec 2024 21:40:40 +0530 Subject: [PATCH 02/25] Removed try block --- .../sqlserver/jdbc/SQLServerCallableStatement.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 4ac19815a..070fc7d9a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -154,11 +154,9 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti case java.sql.Types.DECIMAL: ParameterMetaData parameterMetaData = this.getParameterMetaData(); if (parameterMetaData != null) { - try { - // Fetch scale from metadata for DECIMAL type - int scale = parameterMetaData.getScale(index); - param.setOutScale(scale); - } + // Fetch scale from metadata for DECIMAL type + int scale = parameterMetaData.getScale(index); + param.setOutScale(scale); } break; default: From 7edfbb539fc76388655374ec590ab9d803b4a8a7 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Fri, 6 Dec 2024 21:49:48 +0530 Subject: [PATCH 03/25] Added try-catch block --- .../sqlserver/jdbc/SQLServerCallableStatement.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 070fc7d9a..9808e8c1e 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -154,9 +154,11 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti case java.sql.Types.DECIMAL: ParameterMetaData parameterMetaData = this.getParameterMetaData(); if (parameterMetaData != null) { - // Fetch scale from metadata for DECIMAL type - int scale = parameterMetaData.getScale(index); - param.setOutScale(scale); + try { + // Fetch scale from metadata for DECIMAL type + int scale = parameterMetaData.getScale(index); + param.setOutScale(scale); + } catch (SQLException e) {} } break; default: From 95a8c7cddd9baa082493a747d751f4d40b77b9ba Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Sat, 7 Dec 2024 02:49:52 +0530 Subject: [PATCH 04/25] Updated testJdbc41CallableStatementMethods test case for BigDecimal class. --- .../sqlserver/jdbc/unit/statement/StatementTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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 9c814916d..b7fea527d 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 @@ -1195,15 +1195,14 @@ public void testJdbc41CallableStatementMethods() throws Exception { assertEquals("2017-05-19 10:47:15.1234567 +02:00", cstmt.getObject("col14Value", microsoft.sql.DateTimeOffset.class).toString()); - // BigDecimal#equals considers the number of decimal places (OutParams always return 4 decimal - // digits rounded up) - assertEquals(0, cstmt.getObject(15, BigDecimal.class).compareTo(new BigDecimal("0.1235"))); + // BigDecimal#equals considers the number of decimal places (OutParams always return full precision as specified in the DB schema) + assertEquals(0, cstmt.getObject(15, BigDecimal.class).compareTo(new BigDecimal("0.123456789"))); assertEquals(0, - cstmt.getObject("col15Value", BigDecimal.class).compareTo(new BigDecimal("0.1235"))); + cstmt.getObject("col15Value", BigDecimal.class).compareTo(new BigDecimal("0.123456789"))); - assertEquals(0, cstmt.getObject(16, BigDecimal.class).compareTo(new BigDecimal("0.1235"))); + assertEquals(0, cstmt.getObject(16, BigDecimal.class).compareTo(new BigDecimal("0.1234567890123456789012345678901234567"))); assertEquals(0, - cstmt.getObject("col16Value", BigDecimal.class).compareTo(new BigDecimal("0.1235"))); + cstmt.getObject("col16Value", BigDecimal.class).compareTo(new BigDecimal("0.1234567890123456789012345678901234567"))); } } } From cfac904d06e57565025dad206fda153031762f4f Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 12:49:06 +0530 Subject: [PATCH 05/25] Added test case to validate the BigDecimal precision. --- .../jdbc/unit/statement/StatementTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) 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 b7fea527d..029ba5b83 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 @@ -1207,6 +1207,61 @@ public void testJdbc41CallableStatementMethods() throws Exception { } } + @Test + public void testBigDecimalPrecision() throws SQLException { + try (Connection connection = getConnection()) { + String createProceduresSQL = """ + create procedure test_bigdecimal_3 + @big_decimal_type decimal(15, 3), + @big_decimal_type_o decimal(15, 3) output + as + begin + set @big_decimal_type_o = @big_decimal_type; + end; + """; + try (Statement stmt = connection.createStatement()) { + stmt.execute(createProceduresSQL); + } + + // Test for DECIMAL(15, 3) + String callSQL1 = "{call test_bigdecimal_3(100.241, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL1)) { + call.registerOutParameter(1, Types.DECIMAL); + call.execute(); + BigDecimal actual1 = call.getBigDecimal(1); + assertEquals(new BigDecimal("100.241"), actual1); + } + + createProceduresSQL = """ + create procedure test_bigdecimal_5 + @big_decimal_type decimal(15, 5), + @big_decimal_type_o decimal(15, 5) output + as + begin + set @big_decimal_type_o = @big_decimal_type; + end; + """; + try (Statement stmt = connection.createStatement()) { + stmt.execute(createProceduresSQL); + } + + // Test for DECIMAL(15, 5) + String callSQL2 = "{call test_bigdecimal_5(100.24112, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL2)) { + call.registerOutParameter(1, Types.DECIMAL); + call.execute(); + BigDecimal actual2 = call.getBigDecimal(1); + assertEquals(new BigDecimal("100.24112"), actual2); + } + + // Clean up: Drop the stored procedures after the test + String dropProcedureSQL = "DROP PROCEDURE IF EXISTS test_bigdecimal_3, test_bigdecimal_5"; + try (Statement stmt = connection.createStatement()) { + stmt.execute(dropProcedureSQL); + } + } + } + @AfterEach public void terminate() throws Exception { try (Connection con = getConnection(); Statement stmt = con.createStatement()) { From 547fbdb9b2dc94f010c56e8f59f8e39a3bb06530 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 13:07:21 +0530 Subject: [PATCH 06/25] Updated stored procedure statement test. --- .../jdbc/unit/statement/StatementTest.java | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) 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 029ba5b83..3e0a66ccf 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 @@ -1209,16 +1209,14 @@ public void testJdbc41CallableStatementMethods() throws Exception { @Test public void testBigDecimalPrecision() throws SQLException { - try (Connection connection = getConnection()) { - String createProceduresSQL = """ - create procedure test_bigdecimal_3 - @big_decimal_type decimal(15, 3), - @big_decimal_type_o decimal(15, 3) output - as - begin - set @big_decimal_type_o = @big_decimal_type; - end; - """; + String createProceduresSQL = "create procedure test_bigdecimal_3\n" + + " @big_decimal_type decimal(15, 3),\n" + + " @big_decimal_type_o decimal(15, 3) output\n" + + "as\n" + + "begin\n" + + " set @big_decimal_type_o = @big_decimal_type;\n" + + "end;\n"; + try (Statement stmt = connection.createStatement()) { stmt.execute(createProceduresSQL); } @@ -1232,15 +1230,13 @@ public void testBigDecimalPrecision() throws SQLException { assertEquals(new BigDecimal("100.241"), actual1); } - createProceduresSQL = """ - create procedure test_bigdecimal_5 - @big_decimal_type decimal(15, 5), - @big_decimal_type_o decimal(15, 5) output - as - begin - set @big_decimal_type_o = @big_decimal_type; - end; - """; + createProceduresSQL = "create procedure test_bigdecimal_5\n" + + " @big_decimal_type decimal(15, 5),\n" + + " @big_decimal_type_o decimal(15, 5) output\n" + + "as\n" + + "begin\n" + + " set @big_decimal_type_o = @big_decimal_type;\n" + + "end;\n"; try (Statement stmt = connection.createStatement()) { stmt.execute(createProceduresSQL); } From 5ab3a878c6b1c42a922655e9d98608feaab7b646 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 13:21:40 +0530 Subject: [PATCH 07/25] Fixed pipeline failure --- .../microsoft/sqlserver/jdbc/unit/statement/StatementTest.java | 1 + 1 file changed, 1 insertion(+) 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 3e0a66ccf..0f2d5b96f 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 @@ -1209,6 +1209,7 @@ public void testJdbc41CallableStatementMethods() throws Exception { @Test public void testBigDecimalPrecision() throws SQLException { + try (Connection connection = getConnection()) { String createProceduresSQL = "create procedure test_bigdecimal_3\n" + " @big_decimal_type decimal(15, 3),\n" + " @big_decimal_type_o decimal(15, 3) output\n" + From 74cb96b5f05a1078ba47f7eda18775ca8503d800 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 16:53:41 +0530 Subject: [PATCH 08/25] Added 'warning' level log in case of failure while fetching scale for DECIMAL type parameter. --- .../microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 9808e8c1e..edf2e5552 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -158,7 +158,9 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti // Fetch scale from metadata for DECIMAL type int scale = parameterMetaData.getScale(index); param.setOutScale(scale); - } catch (SQLException e) {} + } catch (SQLException e) { + loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); + } } break; default: From 3108729f797df6ea6eddbbb1ef694de7b4f93f6f Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 18:52:43 +0530 Subject: [PATCH 09/25] throws SQLServerException --- .../microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index edf2e5552..d584a3fde 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -159,7 +159,8 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti int scale = parameterMetaData.getScale(index); param.setOutScale(scale); } catch (SQLException e) { - loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); + loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); + SQLServerException.makeFromDriverError(connection, this, e.getMessage(), null, false); } } break; From c5bd4f7a9c68196086e096af5f05df3d26ae5026 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 19:03:55 +0530 Subject: [PATCH 10/25] Throw SQLServerException on failure. --- .../microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index d584a3fde..87f4aeafb 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -160,7 +160,7 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti param.setOutScale(scale); } catch (SQLException e) { loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); - SQLServerException.makeFromDriverError(connection, this, e.getMessage(), null, false); + throw new SQLServerException(SQLServerException.getErrString("R_metaDataErrorForParameter"), null, 0, e); } } break; From e8cb028244cd8388769647af15a294da52a18429 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 20:36:26 +0530 Subject: [PATCH 11/25] Added test case testRegisterOutParameterWithDecimalException --- .../jdbc/unit/statement/StatementTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 0f2d5b96f..2fb8de956 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 @@ -41,6 +41,7 @@ import org.junit.runner.RunWith; import com.microsoft.sqlserver.jdbc.RandomUtil; +import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement; import com.microsoft.sqlserver.jdbc.SQLServerConnection; import com.microsoft.sqlserver.jdbc.SQLServerDataSource; import com.microsoft.sqlserver.jdbc.SQLServerException; @@ -1259,6 +1260,25 @@ public void testBigDecimalPrecision() throws SQLException { } } + @Test + public void testRegisterOutParameterWithDecimalException() throws SQLException { + try (Connection conn = getConnection()) { + String sql = "{call some_procedure(?)}"; + CallableStatement stmt = conn.prepareCall(sql); + + stmt.registerOutParameter(1, Types.DECIMAL); + SQLServerCallableStatement sqlServerStmt = (SQLServerCallableStatement) stmt; + + try { + sqlServerStmt.registerOutParameter(1, Types.DECIMAL); + fail("Expected SQLServerException to be thrown"); + } catch (SQLServerException e) { + assertTrue(e.getCause() instanceof SQLException); + assertEquals("Error fetching scale", e.getCause().getMessage()); + } + } + } + @AfterEach public void terminate() throws Exception { try (Connection con = getConnection(); Statement stmt = con.createStatement()) { From 9474346f473b2b2088d8d5c4de08627bdda81728 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 21:08:38 +0530 Subject: [PATCH 12/25] Fixed pipeline failure --- .../jdbc/unit/statement/StatementTest.java | 19 ------------------- 1 file changed, 19 deletions(-) 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 2fb8de956..f82ee43c6 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 @@ -1260,25 +1260,6 @@ public void testBigDecimalPrecision() throws SQLException { } } - @Test - public void testRegisterOutParameterWithDecimalException() throws SQLException { - try (Connection conn = getConnection()) { - String sql = "{call some_procedure(?)}"; - CallableStatement stmt = conn.prepareCall(sql); - - stmt.registerOutParameter(1, Types.DECIMAL); - SQLServerCallableStatement sqlServerStmt = (SQLServerCallableStatement) stmt; - - try { - sqlServerStmt.registerOutParameter(1, Types.DECIMAL); - fail("Expected SQLServerException to be thrown"); - } catch (SQLServerException e) { - assertTrue(e.getCause() instanceof SQLException); - assertEquals("Error fetching scale", e.getCause().getMessage()); - } - } - } - @AfterEach public void terminate() throws Exception { try (Connection con = getConnection(); Statement stmt = con.createStatement()) { From a963b3a7bb4d83fcd8fcb6fe35f0ad6dc44a26b0 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 9 Dec 2024 21:09:20 +0530 Subject: [PATCH 13/25] Updated SQLServerCallableStatement.java --- .../com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 87f4aeafb..37c0f32f8 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -160,7 +160,6 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti param.setOutScale(scale); } catch (SQLException e) { loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); - throw new SQLServerException(SQLServerException.getErrString("R_metaDataErrorForParameter"), null, 0, e); } } break; From 54cb79ae03b97094b801faeb4d42d3aef915442e Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Tue, 10 Dec 2024 18:27:31 +0530 Subject: [PATCH 14/25] removed test case. --- .../jdbc/unit/statement/StatementTest.java | 52 ------------------- 1 file changed, 52 deletions(-) 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 f82ee43c6..e03bdf019 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 @@ -1208,58 +1208,6 @@ public void testJdbc41CallableStatementMethods() throws Exception { } } - @Test - public void testBigDecimalPrecision() throws SQLException { - try (Connection connection = getConnection()) { - String createProceduresSQL = "create procedure test_bigdecimal_3\n" + - " @big_decimal_type decimal(15, 3),\n" + - " @big_decimal_type_o decimal(15, 3) output\n" + - "as\n" + - "begin\n" + - " set @big_decimal_type_o = @big_decimal_type;\n" + - "end;\n"; - - try (Statement stmt = connection.createStatement()) { - stmt.execute(createProceduresSQL); - } - - // Test for DECIMAL(15, 3) - String callSQL1 = "{call test_bigdecimal_3(100.241, ?)}"; - try (CallableStatement call = connection.prepareCall(callSQL1)) { - call.registerOutParameter(1, Types.DECIMAL); - call.execute(); - BigDecimal actual1 = call.getBigDecimal(1); - assertEquals(new BigDecimal("100.241"), actual1); - } - - createProceduresSQL = "create procedure test_bigdecimal_5\n" + - " @big_decimal_type decimal(15, 5),\n" + - " @big_decimal_type_o decimal(15, 5) output\n" + - "as\n" + - "begin\n" + - " set @big_decimal_type_o = @big_decimal_type;\n" + - "end;\n"; - try (Statement stmt = connection.createStatement()) { - stmt.execute(createProceduresSQL); - } - - // Test for DECIMAL(15, 5) - String callSQL2 = "{call test_bigdecimal_5(100.24112, ?)}"; - try (CallableStatement call = connection.prepareCall(callSQL2)) { - call.registerOutParameter(1, Types.DECIMAL); - call.execute(); - BigDecimal actual2 = call.getBigDecimal(1); - assertEquals(new BigDecimal("100.24112"), actual2); - } - - // Clean up: Drop the stored procedures after the test - String dropProcedureSQL = "DROP PROCEDURE IF EXISTS test_bigdecimal_3, test_bigdecimal_5"; - try (Statement stmt = connection.createStatement()) { - stmt.execute(dropProcedureSQL); - } - } - } - @AfterEach public void terminate() throws Exception { try (Connection con = getConnection(); Statement stmt = con.createStatement()) { From 8522231f75f8ccee56385d5c9db7b36e54f2c473 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Tue, 10 Dec 2024 18:32:28 +0530 Subject: [PATCH 15/25] Removed unused import. --- .../microsoft/sqlserver/jdbc/unit/statement/StatementTest.java | 1 - 1 file changed, 1 deletion(-) 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 e03bdf019..b7fea527d 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 @@ -41,7 +41,6 @@ import org.junit.runner.RunWith; import com.microsoft.sqlserver.jdbc.RandomUtil; -import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement; import com.microsoft.sqlserver.jdbc.SQLServerConnection; import com.microsoft.sqlserver.jdbc.SQLServerDataSource; import com.microsoft.sqlserver.jdbc.SQLServerException; From 54b68c3679fa625912213c1edd29973b20b68ddc Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Tue, 10 Dec 2024 19:27:32 +0530 Subject: [PATCH 16/25] Created BigDecimalPrecisionTest.java file --- .../statement/BigDecimalPrecisionTest.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java new file mode 100644 index 000000000..be020e4d3 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java @@ -0,0 +1,90 @@ +package com.microsoft.sqlserver.jdbc.unit.statement; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.microsoft.sqlserver.jdbc.RandomUtil; +import com.microsoft.sqlserver.testframework.AbstractSQLGenerator; +import com.microsoft.sqlserver.testframework.AbstractTest; + +public class BigDecimalPrecisionTest extends AbstractTest { + + String procName1 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_3")); + String procName2 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_5")); + + @BeforeEach + public void init() throws SQLException { + try (Connection connection = getConnection()) { + String createProcedureSQL1 = "CREATE PROCEDURE " + procName1 + "\n" + + " @big_decimal_type decimal(15, 3),\n" + + " @big_decimal_type_o decimal(15, 3) OUTPUT\n" + + "AS\n" + + "BEGIN\n" + + " SET @big_decimal_type_o = @big_decimal_type;\n" + + "END;"; + String createProcedureSQL2 = "CREATE PROCEDURE " + procName2 + "\n" + + " @big_decimal_type decimal(15, 5),\n" + + " @big_decimal_type_o decimal(15, 5) OUTPUT\n" + + "AS\n" + + "BEGIN\n" + + " SET @big_decimal_type_o = @big_decimal_type;\n" + + "END;"; + + try (Statement stmt = connection.createStatement()) { + stmt.execute(createProcedureSQL1); + stmt.execute(createProcedureSQL2); + } + } + } + + @AfterEach + public void terminate() throws SQLException { + try (Connection connection = getConnection()) { + try (Statement stmt = connection.createStatement()) { + String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2; + stmt.execute(dropProcedureSQL); + } + } + } + + @Test + @Tag("BigDecimal") + public void testBigDecimalPrecision() throws SQLException { + try (Connection connection = getConnection()) { + // Test for DECIMAL(15, 3) + String callSQL1 = "{call " + procName1 + "(100.241, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL1)) { + call.registerOutParameter(1, Types.DECIMAL); + call.execute(); + BigDecimal actual1 = call.getBigDecimal(1); + assertEquals(new BigDecimal("100.241"), actual1); + } + + // Test for DECIMAL(15, 5) + String callSQL2 = "{call " + procName2 + "(100.24112, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL2)) { + call.registerOutParameter(1, Types.DECIMAL); + call.execute(); + BigDecimal actual2 = call.getBigDecimal(1); + assertEquals(new BigDecimal("100.24112"), actual2); + } + } + } + + @BeforeAll + public static void setupTests() throws Exception { + setConnection(); + } +} From f87ad13d258ebd19417a37f40b8141b5a3d7d1f6 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Wed, 11 Dec 2024 14:37:27 +0530 Subject: [PATCH 17/25] Fix: Throw SQLServerException with detailed message for metadata retrieval failure --- .../com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 37c0f32f8..87f4aeafb 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -160,6 +160,7 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti param.setOutScale(scale); } catch (SQLException e) { loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); + throw new SQLServerException(SQLServerException.getErrString("R_metaDataErrorForParameter"), null, 0, e); } } break; From e83f1638db6a7f962b03691962df330ece3d0630 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Wed, 11 Dec 2024 14:42:36 +0530 Subject: [PATCH 18/25] Add test for BigDecimal precision failure when fetching scale metadata. --- .../statement/BigDecimalPrecisionTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java index be020e4d3..864e28b37 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java @@ -1,6 +1,8 @@ package com.microsoft.sqlserver.jdbc.unit.statement; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.sql.CallableStatement; @@ -83,6 +85,22 @@ public void testBigDecimalPrecision() throws SQLException { } } + @Test + @Tag("BigDecimalFailure") + public void testBigDecimalPrecisionFailure() throws SQLException { + try (Connection connection = getConnection()) { + String callSQL1 = "{call " + procName1 + "(100.241, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL1)) { + call.registerOutParameter(1, Types.DECIMAL); + SQLException thrownException = assertThrows(SQLException.class, () -> { + call.execute(); + call.getBigDecimal(1); + }); + assertTrue(thrownException.getMessage().contains("R_metaDataErrorForParameter")); + } + } + } + @BeforeAll public static void setupTests() throws Exception { setConnection(); From 63d0de25315af84e623175cd1616ac216c7e6f2f Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Wed, 11 Dec 2024 15:49:45 +0530 Subject: [PATCH 19/25] Update SQLServerCallableStatement.java --- .../com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 87f4aeafb..37c0f32f8 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -160,7 +160,6 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti param.setOutScale(scale); } catch (SQLException e) { loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); - throw new SQLServerException(SQLServerException.getErrString("R_metaDataErrorForParameter"), null, 0, e); } } break; From 075e11b8ef4b489dbe7eba62c2c453cb1608e2f6 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Wed, 11 Dec 2024 15:50:42 +0530 Subject: [PATCH 20/25] Update BigDecimalPrecisionTest.java --- .../statement/BigDecimalPrecisionTest.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java index 864e28b37..be020e4d3 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java @@ -1,8 +1,6 @@ package com.microsoft.sqlserver.jdbc.unit.statement; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.sql.CallableStatement; @@ -85,22 +83,6 @@ public void testBigDecimalPrecision() throws SQLException { } } - @Test - @Tag("BigDecimalFailure") - public void testBigDecimalPrecisionFailure() throws SQLException { - try (Connection connection = getConnection()) { - String callSQL1 = "{call " + procName1 + "(100.241, ?)}"; - try (CallableStatement call = connection.prepareCall(callSQL1)) { - call.registerOutParameter(1, Types.DECIMAL); - SQLException thrownException = assertThrows(SQLException.class, () -> { - call.execute(); - call.getBigDecimal(1); - }); - assertTrue(thrownException.getMessage().contains("R_metaDataErrorForParameter")); - } - } - } - @BeforeAll public static void setupTests() throws Exception { setConnection(); From 78bd95b7af0cf987765d96e37e3d04ee9b1ed012 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 16 Dec 2024 12:50:39 +0530 Subject: [PATCH 21/25] Drop stored procedure if it exists in init() --- .../jdbc/unit/statement/BigDecimalPrecisionTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java index be020e4d3..926dfb921 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java @@ -27,6 +27,9 @@ public class BigDecimalPrecisionTest extends AbstractTest { @BeforeEach public void init() throws SQLException { try (Connection connection = getConnection()) { + String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2; + stmt.execute(dropProcedureSQL); + String createProcedureSQL1 = "CREATE PROCEDURE " + procName1 + "\n" + " @big_decimal_type decimal(15, 3),\n" + " @big_decimal_type_o decimal(15, 3) OUTPUT\n" + @@ -41,7 +44,6 @@ public void init() throws SQLException { "BEGIN\n" + " SET @big_decimal_type_o = @big_decimal_type;\n" + "END;"; - try (Statement stmt = connection.createStatement()) { stmt.execute(createProcedureSQL1); stmt.execute(createProcedureSQL2); From 4f3c020e5f7c2dfd61a3b8500db32ae127afef66 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Mon, 16 Dec 2024 13:08:22 +0530 Subject: [PATCH 22/25] Update BigDecimalPrecisionTest.java --- .../jdbc/unit/statement/BigDecimalPrecisionTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java index 926dfb921..3aac27300 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java @@ -28,7 +28,9 @@ public class BigDecimalPrecisionTest extends AbstractTest { public void init() throws SQLException { try (Connection connection = getConnection()) { String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2; - stmt.execute(dropProcedureSQL); + try (Statement stmt = connection.createStatement()) { + stmt.execute(dropProcedureSQL); + } String createProcedureSQL1 = "CREATE PROCEDURE " + procName1 + "\n" + " @big_decimal_type decimal(15, 3),\n" + From ebf50932a6890eeb727cb7dc19c894c0766648f1 Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Fri, 20 Dec 2024 14:29:03 +0530 Subject: [PATCH 23/25] Added detailed comments to the `registerOutParameter` method to explain the dynamic handling of DECIMAL output parameters. --- .../microsoft/sqlserver/jdbc/SQLServerCallableStatement.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 37c0f32f8..9e59c6691 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -152,6 +152,9 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti param.setOutScale(7); break; case java.sql.Types.DECIMAL: + // Dynamically handle the scale for DECIMAL output parameters. + // The scale for the DECIMAL type is fetched from the ParameterMetaData. + // This provides flexibility to automatically apply the correct scale as per the database metadata. ParameterMetaData parameterMetaData = this.getParameterMetaData(); if (parameterMetaData != null) { try { From bf9df80252494b9f322b6ea62787245b46f33c3c Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Tue, 7 Jan 2025 18:13:28 +0530 Subject: [PATCH 24/25] updated as per review comments --- .../jdbc/SQLServerCallableStatement.java | 1 + .../statement/BigDecimalPrecisionTest.java | 94 ---------------- .../jdbc/unit/statement/StatementTest.java | 106 ++++++++++++++++++ 3 files changed, 107 insertions(+), 94 deletions(-) delete mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java index 9e59c6691..8e40c2fca 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java @@ -163,6 +163,7 @@ public void registerOutParameter(int index, int sqlType) throws SQLServerExcepti param.setOutScale(scale); } catch (SQLException e) { loggerExternal.warning("Failed to fetch scale for DECIMAL type parameter at index " + index + ": " + e.getMessage()); + throw new SQLServerException(SQLServerException.getErrString("R_InvalidScale"), null, 0, e); } } break; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java deleted file mode 100644 index 3aac27300..000000000 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BigDecimalPrecisionTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.microsoft.sqlserver.jdbc.unit.statement; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.math.BigDecimal; -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import com.microsoft.sqlserver.jdbc.RandomUtil; -import com.microsoft.sqlserver.testframework.AbstractSQLGenerator; -import com.microsoft.sqlserver.testframework.AbstractTest; - -public class BigDecimalPrecisionTest extends AbstractTest { - - String procName1 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_3")); - String procName2 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_5")); - - @BeforeEach - public void init() throws SQLException { - try (Connection connection = getConnection()) { - String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2; - try (Statement stmt = connection.createStatement()) { - stmt.execute(dropProcedureSQL); - } - - String createProcedureSQL1 = "CREATE PROCEDURE " + procName1 + "\n" + - " @big_decimal_type decimal(15, 3),\n" + - " @big_decimal_type_o decimal(15, 3) OUTPUT\n" + - "AS\n" + - "BEGIN\n" + - " SET @big_decimal_type_o = @big_decimal_type;\n" + - "END;"; - String createProcedureSQL2 = "CREATE PROCEDURE " + procName2 + "\n" + - " @big_decimal_type decimal(15, 5),\n" + - " @big_decimal_type_o decimal(15, 5) OUTPUT\n" + - "AS\n" + - "BEGIN\n" + - " SET @big_decimal_type_o = @big_decimal_type;\n" + - "END;"; - try (Statement stmt = connection.createStatement()) { - stmt.execute(createProcedureSQL1); - stmt.execute(createProcedureSQL2); - } - } - } - - @AfterEach - public void terminate() throws SQLException { - try (Connection connection = getConnection()) { - try (Statement stmt = connection.createStatement()) { - String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2; - stmt.execute(dropProcedureSQL); - } - } - } - - @Test - @Tag("BigDecimal") - public void testBigDecimalPrecision() throws SQLException { - try (Connection connection = getConnection()) { - // Test for DECIMAL(15, 3) - String callSQL1 = "{call " + procName1 + "(100.241, ?)}"; - try (CallableStatement call = connection.prepareCall(callSQL1)) { - call.registerOutParameter(1, Types.DECIMAL); - call.execute(); - BigDecimal actual1 = call.getBigDecimal(1); - assertEquals(new BigDecimal("100.241"), actual1); - } - - // Test for DECIMAL(15, 5) - String callSQL2 = "{call " + procName2 + "(100.24112, ?)}"; - try (CallableStatement call = connection.prepareCall(callSQL2)) { - call.registerOutParameter(1, Types.DECIMAL); - call.execute(); - BigDecimal actual2 = call.getBigDecimal(1); - assertEquals(new BigDecimal("100.24112"), actual2); - } - } - } - - @BeforeAll - public static void setupTests() throws Exception { - setConnection(); - } -} 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 b7fea527d..0da7566cd 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 @@ -2691,4 +2691,110 @@ public void terminate() throws Exception { } } } + + @Nested + @Tag(Constants.xAzureSQLDW) + public class BigDecimalPrecisionTest { + + private static String procName1 = AbstractSQLGenerator + .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_3")); + private static String procName2 = AbstractSQLGenerator + .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_5")); + private static String procNameMaxScale = AbstractSQLGenerator + .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_max_scale")); + private static String procNameMaxPrecision = AbstractSQLGenerator + .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_max_precision")); + + @BeforeEach + public void init() throws SQLException { + try (Connection connection = getConnection()) { + String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2 + ", " + + procNameMaxScale + ", " + procNameMaxPrecision; + try (Statement stmt = connection.createStatement()) { + stmt.execute(dropProcedureSQL); + } + + String createProcedureSQL1 = "CREATE PROCEDURE " + procName1 + "\n" + + " @big_decimal_type decimal(15, 3),\n" + + " @big_decimal_type_o decimal(15, 3) OUTPUT\n" + "AS\n" + "BEGIN\n" + + " SET @big_decimal_type_o = @big_decimal_type;\n" + "END;"; + String createProcedureSQL2 = "CREATE PROCEDURE " + procName2 + "\n" + + " @big_decimal_type decimal(15, 5),\n" + + " @big_decimal_type_o decimal(15, 5) OUTPUT\n" + "AS\n" + "BEGIN\n" + + " SET @big_decimal_type_o = @big_decimal_type;\n" + "END;"; + String createProcedureMaxScale = "CREATE PROCEDURE " + procNameMaxScale + "\n" + + " @big_decimal_type decimal(38, 38),\n" + + " @big_decimal_type_o decimal(38, 38) OUTPUT\n" + "AS\n" + "BEGIN\n" + + " SET @big_decimal_type_o = @big_decimal_type;\n" + "END;"; + String createProcedureMaxPrecision = "CREATE PROCEDURE " + procNameMaxPrecision + "\n" + + " @big_decimal_type decimal(38, 0),\n" + + " @big_decimal_type_o decimal(38, 0) OUTPUT\n" + "AS\n" + "BEGIN\n" + + " SET @big_decimal_type_o = @big_decimal_type;\n" + "END;"; + + try (Statement stmt = connection.createStatement()) { + stmt.execute(createProcedureSQL1); + stmt.execute(createProcedureSQL2); + stmt.execute(createProcedureMaxScale); + stmt.execute(createProcedureMaxPrecision); + } + } + } + + @AfterEach + public void terminate() throws SQLException { + try (Connection connection = getConnection()) { + try (Statement stmt = connection.createStatement()) { + String dropProcedureSQL = "DROP PROCEDURE IF EXISTS " + procName1 + ", " + procName2 + ", " + + procNameMaxScale + ", " + procNameMaxPrecision; + stmt.execute(dropProcedureSQL); + } + } + } + + @Test + @Tag("BigDecimal") + public void testBigDecimalPrecision() throws SQLException { + try (Connection connection = getConnection()) { + // Test for DECIMAL(15, 3) + String callSQL1 = "{call " + procName1 + "(100.241, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL1)) { + call.registerOutParameter(1, Types.DECIMAL); + call.execute(); + BigDecimal actual1 = call.getBigDecimal(1); + assertEquals(new BigDecimal("100.241"), actual1); + } + + // Test for DECIMAL(15, 5) + String callSQL2 = "{call " + procName2 + "(100.24112, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQL2)) { + call.registerOutParameter(1, Types.DECIMAL); + call.execute(); + BigDecimal actual2 = call.getBigDecimal(1); + assertEquals(new BigDecimal("100.24112"), actual2); + } + + // Test for DECIMAL(38, 38) + String callSQLMaxScale = "{call " + procNameMaxScale + "(?, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQLMaxScale)) { + BigDecimal maxScaleValue = new BigDecimal("0." + "1".repeat(38)); + call.setBigDecimal(1, maxScaleValue); + call.registerOutParameter(2, Types.DECIMAL); + call.execute(); + BigDecimal actualMaxScale = call.getBigDecimal(2); + assertEquals(maxScaleValue, actualMaxScale, "DECIMAL(38, 38) max scale test failed"); + } + + // Test for DECIMAL(38, 0) + String callSQLMaxPrecision = "{call " + procNameMaxPrecision + "(?, ?)}"; + try (CallableStatement call = connection.prepareCall(callSQLMaxPrecision)) { + BigDecimal maxPrecisionValue = new BigDecimal("9".repeat(38)); + call.setBigDecimal(1, maxPrecisionValue); + call.registerOutParameter(2, Types.DECIMAL); + call.execute(); + BigDecimal actualMaxPrecision = call.getBigDecimal(2); + assertEquals(maxPrecisionValue, actualMaxPrecision, "DECIMAL(38, 0) max precision test failed"); + } + } + } + } } From b2d7c070d9a0817f262dad74b6ce8c395adc371e Mon Sep 17 00:00:00 2001 From: Ananya Garg Date: Tue, 7 Jan 2025 18:26:40 +0530 Subject: [PATCH 25/25] fixed build failure --- .../sqlserver/jdbc/unit/statement/StatementTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 0da7566cd..e1b8f0627 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 @@ -2696,13 +2696,13 @@ public void terminate() throws Exception { @Tag(Constants.xAzureSQLDW) public class BigDecimalPrecisionTest { - private static String procName1 = AbstractSQLGenerator + private final String procName1 = AbstractSQLGenerator .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_3")); - private static String procName2 = AbstractSQLGenerator + private final String procName2 = AbstractSQLGenerator .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_5")); - private static String procNameMaxScale = AbstractSQLGenerator + private final String procNameMaxScale = AbstractSQLGenerator .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_max_scale")); - private static String procNameMaxPrecision = AbstractSQLGenerator + private final String procNameMaxPrecision = AbstractSQLGenerator .escapeIdentifier(RandomUtil.getIdentifier("test_bigdecimal_max_precision")); @BeforeEach