NamedParameterUtils.parseSqlStatement should parse :{x} style parameter correctly
In my opinion, we should parse ":{x}" style parameter as "x" is parameter using "NamedParameterUtils.parseSqlStatement",
so the condition "j - i > 2" is the correct condition, not "j - i > 3", because if "i" is the index of
":" in ":{x}", and "j" is the index of "}" in ":{x}", "j - i == 3" is true.
Also add a test case for SPR-16663.
(cherry picked from commit 82cb5db)
This commit is contained in:
committed by
Juergen Hoeller
parent
6e4bbac6f7
commit
f3dd22da5b
@@ -40,6 +40,16 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class NamedParameterUtils {
|
||||
|
||||
/**
|
||||
* Set of characters that qualify as comment or quotes starting characters.
|
||||
*/
|
||||
private static final String[] START_SKIP = new String[] {"'", "\"", "--", "/*"};
|
||||
|
||||
/**
|
||||
* Set of characters that at are the corresponding comment or quotes ending characters.
|
||||
*/
|
||||
private static final String[] STOP_SKIP = new String[] {"'", "\"", "\n", "*/"};
|
||||
|
||||
/**
|
||||
* Set of characters that qualify as parameter separators,
|
||||
* indicating that a parameter name in a SQL String has ended.
|
||||
@@ -47,18 +57,6 @@ public abstract class NamedParameterUtils {
|
||||
private static final char[] PARAMETER_SEPARATORS =
|
||||
new char[] {'"', '\'', ':', '&', ',', ';', '(', ')', '|', '=', '+', '-', '*', '%', '/', '\\', '<', '>', '^'};
|
||||
|
||||
/**
|
||||
* Set of characters that qualify as comment or quotes starting characters.
|
||||
*/
|
||||
private static final String[] START_SKIP =
|
||||
new String[] {"'", "\"", "--", "/*"};
|
||||
|
||||
/**
|
||||
* Set of characters that at are the corresponding comment or quotes ending characters.
|
||||
*/
|
||||
private static final String[] STOP_SKIP =
|
||||
new String[] {"'", "\"", "\n", "*/"};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Core methods used by NamedParameterJdbcTemplate and SqlQuery/SqlUpdate
|
||||
@@ -109,7 +107,7 @@ public abstract class NamedParameterUtils {
|
||||
String parameter = null;
|
||||
if (j < statement.length && c == ':' && statement[j] == '{') {
|
||||
// :{x} style parameter
|
||||
while (j < statement.length && !('}' == statement[j])) {
|
||||
while (j < statement.length && '}' != statement[j]) {
|
||||
j++;
|
||||
if (':' == statement[j] || '{' == statement[j]) {
|
||||
throw new InvalidDataAccessApiUsageException("Parameter name contains invalid character '" +
|
||||
@@ -120,7 +118,7 @@ public abstract class NamedParameterUtils {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"Non-terminated named parameter declaration at position " + i + " in statement: " + sql);
|
||||
}
|
||||
if (j - i > 3) {
|
||||
if (j - i > 2) {
|
||||
parameter = sql.substring(i + 2, j);
|
||||
namedParameterCount = addNewNamedParameter(namedParameters, namedParameterCount, parameter);
|
||||
totalParameterCount = addNamedParameter(parameterList, totalParameterCount, escapes, i, j + 1, parameter);
|
||||
@@ -200,7 +198,7 @@ public abstract class NamedParameterUtils {
|
||||
if (statement[position] == START_SKIP[i].charAt(0)) {
|
||||
boolean match = true;
|
||||
for (int j = 1; j < START_SKIP[i].length(); j++) {
|
||||
if (!(statement[position + j] == START_SKIP[i].charAt(j))) {
|
||||
if (statement[position + j] != START_SKIP[i].charAt(j)) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
@@ -216,7 +214,7 @@ public abstract class NamedParameterUtils {
|
||||
// last comment not closed properly
|
||||
return statement.length;
|
||||
}
|
||||
if (!(statement[m + n] == STOP_SKIP[i].charAt(n))) {
|
||||
if (statement[m + n] != STOP_SKIP[i].charAt(n)) {
|
||||
endMatch = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -253,6 +253,18 @@ public class NamedParameterUtilsTests {
|
||||
assertEquals(expectedSql2, finalSql2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseSqlStatementWithSingleLetterInBrackets() {
|
||||
String expectedSql = "select foo from bar where baz = b?z";
|
||||
String sql = "select foo from bar where baz = b:{p}z";
|
||||
|
||||
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
assertEquals(1, parsedSql.getParameterNames().size());
|
||||
assertEquals("p", parsedSql.getParameterNames().get(0));
|
||||
String finalSql = NamedParameterUtils.substituteNamedParameters(parsedSql, null);
|
||||
assertEquals(expectedSql, finalSql);
|
||||
}
|
||||
|
||||
@Test // SPR-2544
|
||||
public void parseSqlStatementWithLogicalAnd() {
|
||||
String expectedSql = "xxx & yyyy";
|
||||
|
||||
Reference in New Issue
Block a user