diff --git a/driver/src/main/java/com/consol/citrus/db/driver/statement/StatementComposer.java b/driver/src/main/java/com/consol/citrus/db/driver/statement/StatementComposer.java index 0463b4a..c9650f0 100644 --- a/driver/src/main/java/com/consol/citrus/db/driver/statement/StatementComposer.java +++ b/driver/src/main/java/com/consol/citrus/db/driver/statement/StatementComposer.java @@ -34,13 +34,23 @@ String composeStatement(final String statement, final StatementParameters parame private Collection determineParameterOrder(final String statement, final StatementParameters parameters) { - final Pattern parameterPattern = Pattern.compile("(:[a-zA-Z]+|\\?)"); + /* + Regex explanation: + The intended group to catch is the group of variables in the sql statement. + In case of a callable statement, it is possible that the statement starts with a '? = ' + indicating a out parameter of the statement. This parameter should be ignored concerning variable + replacement. That is why the first group catches the '? = ' (if existing) and the second group catches + named and unnamed variable references within the rest of the sql statement. + This is why the first group should be ignored due variable substitution while the second group contains all + variables to replace + */ + final Pattern parameterPattern = Pattern.compile("^(\\? ?=)+|(:[a-zA-Z]+|\\?)"); final Matcher parameterMatcher = parameterPattern.matcher(statement); final LinkedList orderedParameterList = new LinkedList<>(); for(int matchIndex = 1; parameterMatcher.find(); matchIndex++){ - final String parameterPlaceholder = parameterMatcher.group(1); + final String parameterPlaceholder = parameterMatcher.group(2); if(parameterPlaceholder != null) { orderedParameterList.add( getParameterValue(parameters, parameterPlaceholder, matchIndex)); diff --git a/driver/src/test/java/com/consol/citrus/db/driver/statement/StatementComposerTest.java b/driver/src/test/java/com/consol/citrus/db/driver/statement/StatementComposerTest.java index 50d207c..0540725 100644 --- a/driver/src/test/java/com/consol/citrus/db/driver/statement/StatementComposerTest.java +++ b/driver/src/test/java/com/consol/citrus/db/driver/statement/StatementComposerTest.java @@ -91,4 +91,35 @@ public void testNoVariableMappingPreservesPlaceholder(){ //THEN assertEquals(composedStatement, expectedComposedStatement); } + + @Test + public void TestCallableStatementParameterAreReplacedCorrectly(){ + + //GIVEN + final String statement = "CALL someClobFunction(?,:foo)"; + final StatementParameters statementParameters = new StatementParameters(); + statementParameters.setParameter("foo", "bar"); + statementParameters.setParameter(1, "foobar"); + final String expectedComposedStatement = statement + " - (foobar,bar)"; + + //WHEN + final String composedStatement = statementComposer.composeStatement(statement, statementParameters); + + //THEN + assertEquals(composedStatement, expectedComposedStatement); + } + + @Test + public void testReturnValuesOfCallableStatementsAreParsedCorrectly(){ + + //GIVEN + final String statement = "? = CALL someFunction(?)"; + final String expectedComposedStatement = statement + " - (?)"; + + //WHEN + final String composedStatement = statementComposer.composeStatement(statement, new StatementParameters()); + + //THEN + assertEquals(composedStatement, expectedComposedStatement); + } } \ No newline at end of file