Correctly validate mixed parameter bind marker usage.

We now inspect individual parameters instead of the resulting query whether the query contains JDBC-style bind markers. Previously, we inspected the final (rewritten) query which might have contained question marks in literals leading to improper validation failures.

Closes #3125
This commit is contained in:
Mark Paluch
2023-08-25 09:31:30 +02:00
parent 00ee738231
commit bdbab7120b
2 changed files with 26 additions and 11 deletions

View File

@@ -244,13 +244,6 @@ class StringQuery implements DeclaredQuery {
int currentIndex = 0;
boolean usesJpaStyleParameters = false;
if (JDBC_STYLE_PARAM.matcher(resultingQuery).find()) {
queryMeta.usesJdbcStyleParameters = true;
}
if (NUMBERED_STYLE_PARAM.matcher(resultingQuery).find() || NAMED_STYLE_PARAM.matcher(resultingQuery).find()) {
usesJpaStyleParameters = true;
}
while (matcher.find()) {
@@ -262,6 +255,19 @@ class StringQuery implements DeclaredQuery {
String parameterName = parameterIndexString != null ? null : matcher.group(NAMED_PARAMETER_GROUP);
Integer parameterIndex = getParameterIndex(parameterIndexString);
String match = matcher.group(0);
if (JDBC_STYLE_PARAM.matcher(match).find()) {
queryMeta.usesJdbcStyleParameters = true;
}
if (NUMBERED_STYLE_PARAM.matcher(match).find() || NAMED_STYLE_PARAM.matcher(match).find()) {
usesJpaStyleParameters = true;
}
if (usesJpaStyleParameters && queryMeta.usesJdbcStyleParameters) {
throw new IllegalArgumentException("Mixing of ? parameters and other forms like ?1 is not supported");
}
String typeSource = matcher.group(COMPARISION_TYPE_GROUP);
Assert.isTrue(parameterIndexString != null || parameterName != null,
() -> String.format("We need either a name or an index; Offending query string: %s", query));
@@ -273,9 +279,6 @@ class StringQuery implements DeclaredQuery {
parameterIndex = expressionParameterIndex;
}
if (usesJpaStyleParameters && queryMeta.usesJdbcStyleParameters) {
throw new IllegalArgumentException("Mixing of ? parameters and other forms like ?1 is not supported");
}
BindingIdentifier queryParameter;
if (parameterIndex != null) {

View File

@@ -629,7 +629,7 @@ class StringQueryUnitTests {
assertThat(query.getQueryString()).isEqualTo(queryString);
assertThat(query.hasParameterBindings()).isFalse();
assertThat(query.getParameterBindings()).isEmpty();
assertThat(query.usesJdbcStyleParameters()).isFalse();
}
@Test // DATAJPA-1318
@@ -667,6 +667,18 @@ class StringQueryUnitTests {
}
}
@Test // GH-3125
void questionMarkInStringLiteralWithParameters() {
String queryString = "SELECT CAST(REGEXP_SUBSTR(itp.template_as_txt, '(?<=templateId\\\\\\\\=)(\\\\\\\\d+)(?:\\\\\\\\R)') AS INT) AS templateId FROM foo itp WHERE bar = ?1 AND baz = 1";
StringQuery query = new StringQuery(queryString, false);
assertThat(query.getQueryString()).isEqualTo(queryString);
assertThat(query.hasParameterBindings()).isTrue();
assertThat(query.getParameterBindings()).hasSize(1);
assertThat(query.usesJdbcStyleParameters()).isFalse();
}
@Test // DATAJPA-1652
void usingPipesWithNamedParameter() {