Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed regression with specifying arg names in call syntax #2480

Merged
merged 8 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)

## [12.8.0] Stable Release
- No changes since previous release
### Fixed issues
- Fixed regression with specifying argument names in callable statement syntax [#2480](https://github.com/microsoft/mssql-jdbc/pull/2480)

## [12.7.1] Preview Release
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,12 @@ private void setPreparedStatementHandle(int handle) {

/**
* Regex for JDBC 'call' escape syntax
*
* Matches {[? =] call sproc ([@arg =] ?, [@arg =] ?, [@arg =] ? ...)}
*/
private static final Pattern callEscapePattern = Pattern
.compile("^\\s*(?i)\\{(\\s*\\??\\s*=?\\s*)call [^\\(\\)]+\\s*((\\(\\s*\\?\\s*(,\\s*\\?\\s*)*\\))?|\\(\\))\\s*}");
.compile("^\\s*(?i)\\{(\\s*\\??\\s*=?\\s*)call [^\\(\\)]+\\s*" +
tkyc marked this conversation as resolved.
Show resolved Hide resolved
"((\\(\\s*(.+\\s*=\\s*)?\\?\\s*(,\\s*\\?\\s*)*\\))?|\\(\\))\\s*}");

/**
* Regex for 'exec' escape syntax
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.TimeZone;
import java.util.UUID;

import org.junit.Assert;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
Expand Down Expand Up @@ -57,6 +58,8 @@ public class CallableStatementTest extends AbstractTest {
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_inputParams_SP"));
private static String conditionalSproc = AbstractSQLGenerator
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_conditionalSproc"));
private static String simpleRetValSproc = AbstractSQLGenerator
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_simpleSproc"));
private static String getObjectLocalDateTimeProcedureName = AbstractSQLGenerator
.escapeIdentifier(RandomUtil.getIdentifier("CallableStatementTest_getObjectLocalDateTime_SP"));
private static String getObjectOffsetDateTimeProcedureName = AbstractSQLGenerator
Expand Down Expand Up @@ -100,6 +103,7 @@ public static void setupTest() throws Exception {
TestUtils.dropProcedureIfExists(outOfOrderSproc, stmt);
TestUtils.dropProcedureIfExists(byParamNameSproc, stmt);
TestUtils.dropProcedureIfExists(conditionalSproc, stmt);
TestUtils.dropProcedureIfExists(simpleRetValSproc, stmt);
TestUtils.dropFunctionIfExists(userDefinedFunction, stmt);
TestUtils.dropUserDefinedTypeIfExists(manyParamUserDefinedType, stmt);
TestUtils.dropProcedureIfExists(manyParamProc, stmt);
Expand All @@ -119,6 +123,7 @@ public static void setupTest() throws Exception {
createOutOfOrderSproc();
createByParamNameSproc();
createConditionalProcedure();
createSimpleRetValSproc();
createUserDefinedFunction();
}
}
Expand Down Expand Up @@ -1197,6 +1202,21 @@ public void testCallableStatementDefaultValues() throws SQLException {
}
}

@Test
public void testCallableStatementSetByAnnotatedArgs() throws SQLException {
String call = "{? = call " + simpleRetValSproc + " (@Arg1 = ?)}";
int expectedValue = 1; // The sproc should return this value

try (CallableStatement cstmt = connection.prepareCall(call)) {
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.setInt(1, 2);
cstmt.setString(2, "foo");
cstmt.execute();

Assert.assertEquals(expectedValue, cstmt.getInt(1));
}
}

@Test
@Tag(Constants.reqExternalSetup)
@Tag(Constants.xAzureSQLDB)
Expand Down Expand Up @@ -1305,6 +1325,7 @@ public static void cleanup() throws SQLException {
TestUtils.dropProcedureIfExists(byParamNameSproc, stmt);
TestUtils.dropProcedureIfExists(currentTimeProc, stmt);
TestUtils.dropProcedureIfExists(conditionalSproc, stmt);
TestUtils.dropProcedureIfExists(simpleRetValSproc, stmt);
TestUtils.dropFunctionIfExists(userDefinedFunction, stmt);
}
}
Expand Down Expand Up @@ -1373,6 +1394,13 @@ private static void createConditionalProcedure() throws SQLException {
}
}

private static void createSimpleRetValSproc() throws SQLException {
String sql = "CREATE PROCEDURE " + simpleRetValSproc + " (@Arg1 VARCHAR(128)) AS DECLARE @ReturnCode INT RETURN 1";
try (Statement stmt = connection.createStatement()) {
stmt.execute(sql);
}
}

private static void createTableManyParams() throws SQLException {
String type = manyParamUserDefinedType;
String sql = "CREATE TABLE" + manyParamsTable + " (c1 " + type + " null, " + "c2 " + type + " null, " + "c3 "
Expand Down