Skip to content

Commit 9307051

Browse files
authored
Fixed CallableStatement default value regression (#2452)
* Fixed default value regression for cstmts * Adjusted regex * Test update * Updated test p2 * Updated regex
1 parent 9754078 commit 9307051

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private void setPreparedStatementHandle(int handle) {
139139
* Regex for JDBC 'call' escape syntax
140140
*/
141141
private static final Pattern callEscapePattern = Pattern
142-
.compile("^\\s*(?i)\\{(\\s*\\??\\s*=?\\s*)call (.+)\\s*\\(?\\?*,?\\)?\\s*}\\s*$");
142+
.compile("^\\s*(?i)\\{(\\s*\\??\\s*=?\\s*)call [^\\(\\)]+\\s*(\\(\\s*\\?\\s*(,\\s*\\?\\s*)*\\))?\\s*}");
143143

144144
/**
145145
* Regex for 'exec' escape syntax

src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ protected Object[][] getContents() {
4242
{"R_givenValueType", "The given value of type"},
4343
{"R_lengthTruncated", " The inserted length is truncated or not correct!"},
4444
{"R_timeValueTruncated", " The time value is truncated or not correct!"},
45+
{"R_nullPointerExceptionFromResultSet", "Cannot invoke \"java.sql.ResultSet.next()\" because \"rs\" is null"},
4546
{"R_invalidErrorMessage", "Invalid Error Message: "},
4647
{"R_kerberosNativeGSSFailure",
4748
"No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)"},

src/test/java/com/microsoft/sqlserver/jdbc/callablestatement/CallableStatementTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class CallableStatementTest extends AbstractTest {
5555
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_setNull_SP"));
5656
private static String inputParamsProcedureName = AbstractSQLGenerator
5757
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_inputParams_SP"));
58+
private static String conditionalSproc = AbstractSQLGenerator
59+
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_conditionalSproc"));
5860
private static String getObjectLocalDateTimeProcedureName = AbstractSQLGenerator
5961
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_getObjectLocalDateTime_SP"));
6062
private static String getObjectOffsetDateTimeProcedureName = AbstractSQLGenerator
@@ -97,6 +99,7 @@ public static void setupTest() throws Exception {
9799
TestUtils.dropProcedureIfExists(zeroParamSproc, stmt);
98100
TestUtils.dropProcedureIfExists(outOfOrderSproc, stmt);
99101
TestUtils.dropProcedureIfExists(byParamNameSproc, stmt);
102+
TestUtils.dropProcedureIfExists(conditionalSproc, stmt);
100103
TestUtils.dropFunctionIfExists(userDefinedFunction, stmt);
101104
TestUtils.dropUserDefinedTypeIfExists(manyParamUserDefinedType, stmt);
102105
TestUtils.dropProcedureIfExists(manyParamProc, stmt);
@@ -115,6 +118,7 @@ public static void setupTest() throws Exception {
115118
createProcedureZeroParams();
116119
createOutOfOrderSproc();
117120
createByParamNameSproc();
121+
createConditionalProcedure();
118122
createUserDefinedFunction();
119123
}
120124
}
@@ -1150,6 +1154,38 @@ public void testExecDocumentedSystemStoredProceduresIndexedParameters() throws S
11501154
}
11511155
}
11521156

1157+
@Test
1158+
public void testCallableStatementDefaultValues() throws SQLException {
1159+
String call0 = "{call " + conditionalSproc + " (?, ?, 1)}";
1160+
String call1 = "{call " + conditionalSproc + " (?, ?, 2)}";
1161+
int expectedValue = 5; // The sproc should return this value
1162+
1163+
try (CallableStatement cstmt = connection.prepareCall(call0)) {
1164+
cstmt.setInt(1, 1);
1165+
cstmt.setInt(2, 2);
1166+
cstmt.execute();
1167+
ResultSet rs = cstmt.getResultSet();
1168+
rs.next();
1169+
fail(TestResource.getResource("R_expectedFailPassed"));
1170+
1171+
} catch (Exception e) {
1172+
String msg = e.getMessage();
1173+
assertTrue(TestResource
1174+
.getResource("R_nullPointerExceptionFromResultSet").equalsIgnoreCase(msg)
1175+
|| msg == null);
1176+
}
1177+
1178+
try (CallableStatement cstmt = connection.prepareCall(call1)) {
1179+
cstmt.setInt(1, 1);
1180+
cstmt.setInt(2, 2);
1181+
cstmt.execute();
1182+
ResultSet rs = cstmt.getResultSet();
1183+
rs.next();
1184+
1185+
assertEquals(Integer.toString(expectedValue), rs.getString(1));
1186+
}
1187+
}
1188+
11531189
@Test
11541190
@Tag(Constants.reqExternalSetup)
11551191
@Tag(Constants.xAzureSQLDB)
@@ -1257,6 +1293,7 @@ public static void cleanup() throws SQLException {
12571293
TestUtils.dropProcedureIfExists(outOfOrderSproc, stmt);
12581294
TestUtils.dropProcedureIfExists(byParamNameSproc, stmt);
12591295
TestUtils.dropProcedureIfExists(currentTimeProc, stmt);
1296+
TestUtils.dropProcedureIfExists(conditionalSproc, stmt);
12601297
TestUtils.dropFunctionIfExists(userDefinedFunction, stmt);
12611298
}
12621299
}
@@ -1317,6 +1354,14 @@ private static void createProcedureCurrentTime() throws SQLException {
13171354
}
13181355
}
13191356

1357+
private static void createConditionalProcedure() throws SQLException {
1358+
String sql = "CREATE PROCEDURE " + conditionalSproc + " @param0 INT, @param1 INT, @maybe bigint = 2 " +
1359+
"AS BEGIN IF @maybe >= 2 BEGIN SELECT 5 END END";
1360+
try (Statement stmt = connection.createStatement()) {
1361+
stmt.execute(sql);
1362+
}
1363+
}
1364+
13201365
private static void createTableManyParams() throws SQLException {
13211366
String type = manyParamUserDefinedType;
13221367
String sql = "CREATE TABLE" + manyParamsTable + " (c1 " + type + " null, " + "c2 " + type + " null, " + "c3 "

0 commit comments

Comments
 (0)