From 7c5f6df4d692d908cfa8b82e64446cfeaaa4ce65 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 fdbda109b063c32d0a1268ba3cf0732c4e404fcd 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 4ab4e5c8e2ade85782f93ff99da52650cb7df6f0 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 44e3aaf3c2eaf35eab95f61e0c80173501ee599b 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 0c0b4f186a63ac32ee89d6cecd262072a93cdc74 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 3c2256f95cdb13139cd2c5a603b58f629077506e 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 a09a497a37410eb4ec2b7abe4fa3cccb845be54c 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 c5312748785b515f9e28b1a29949cfc3751149de 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 95c962833f28d973be33f6b359715fe18e74a6cd 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 d4859f1cd602f2a1fab66b79dedfcd22ca541924 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 1506f626898bea851d011cbf1cee0fc50c39319c 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 82546f7bb115e142624c428106149e3ec386cc9f 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 e58a9b7b1831b87bbec4e2d6405735225d727a44 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 5815afade41300d49e57295cc6eebd1c84de6fa6 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 66d8aad2acfadee1e8135af4ff70a3a5fdf38a7b 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 9581f6b3a8a8496fa43e8bfc02eb33e2b29965ab 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 28e4505abdbb9dc0942ef0440829ab9facdf5a53 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 a07e707986255b2ccb5106ef53545c16f3840e69 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 33e6d00572c21e681ef13968e8968f27bb5b590a 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 222dddc4ba6a841aa6bb88d5b8922ba3254c9456 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 67064f51af03233a9a60d2f4569479c0f9796715 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 6379d57aa620c6e52b40972e28df25ead7cd4256 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 ed0ff76cbed47cf1a8c986e29692eea9eb4aa1a8 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 d6e4e2bb1470a2ad9b89ca613ec9ad6ba8274046 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 cb7d65a21bd5950b334089d1b2da8b31c2fb5c0c 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