in modules/spring-data-ext/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java [238:336]
private String parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(String query,
List<ParameterBinding> bindings,
Metadata queryMeta) {
int greatestParamIdx = tryFindGreatestParameterIndexIn(query);
boolean parametersShouldBeAccessedByIdx = greatestParamIdx != -1;
/*
* Prefer indexed access over named parameters if only SpEL Expression parameters are present.
*/
if (!parametersShouldBeAccessedByIdx && query.contains("?#{")) {
parametersShouldBeAccessedByIdx = true;
greatestParamIdx = 0;
}
SpelExtractor spelExtractor = createSpelExtractor(query, parametersShouldBeAccessedByIdx,
greatestParamIdx);
String resultingQry = spelExtractor.getQueryString();
Matcher matcher = PARAMETER_BINDING_PATTERN.matcher(resultingQry);
QuotationMap quotedAreas = new QuotationMap(resultingQry);
int expressionParamIdx = parametersShouldBeAccessedByIdx ? greatestParamIdx : 0;
boolean usesJpaStyleParameters = false;
while (matcher.find()) {
if (quotedAreas.isQuoted(matcher.start()))
continue;
String paramIdxStr = matcher.group(INDEXED_PARAMETER_GROUP);
String paramName = paramIdxStr != null ? null : matcher.group(NAMED_PARAMETER_GROUP);
Integer paramIdx = getParameterIndex(paramIdxStr);
String typeSrc = matcher.group(COMPARISION_TYPE_GROUP);
String expression = spelExtractor
.getParameter(paramName == null ? paramIdxStr : paramName);
String replacement = null;
Assert.isTrue(paramIdxStr != null || paramName != null,
() -> String.format("We need either a name or an index! Offending query string: %s", query));
expressionParamIdx++;
if (paramIdxStr != null && paramIdxStr.isEmpty()) {
queryMeta.usesJdbcStyleParameters = true;
paramIdx = expressionParamIdx;
}
else
usesJpaStyleParameters = true;
// named parameters (:param) will be untouched by spelExtractor, so replace them by ? as we don't
// know position. We also replace the indexed parameters because query arguments will be rearranged to
// suite the proper order considering parameter indexes.
if (paramName != null || paramIdx != null)
replacement = "?";
if (usesJpaStyleParameters && queryMeta.usesJdbcStyleParameters) {
throw new IllegalArgumentException(
"Mixing of ? (? or :myNamedParam) parameters and other forms like ?1 (SpEL espressions or "
+ "indexed) is not supported!. Please, if you are using expressions or "
+ "indexed params, replace all named parameters by expressions. Example :myNamedParam "
+ "by ?#{#myNamedParam}.");
}
switch (ParameterBindingType.of(typeSrc)) {
case LIKE:
Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2));
replacement = matcher.group(3);
if (paramIdx != null)
checkAndRegister(new LikeParameterBinding(paramIdx, likeType, expression), bindings);
else {
checkAndRegister(new LikeParameterBinding(paramName, likeType, expression), bindings);
replacement = expression != null ? ":" + paramName : matcher.group(5);
}
break;
case IN:
if (paramIdx != null)
checkAndRegister(new InParameterBinding(paramIdx, expression), bindings);
else
checkAndRegister(new InParameterBinding(paramName, expression), bindings);
break;
case AS_IS: // fall-through we don't need a special parameter binding for the given parameter.
default:
bindings.add(paramIdx != null
? new ParameterBinding(null, paramIdx, expression)
: new ParameterBinding(paramName, null, expression));
}
if (replacement != null)
resultingQry = replaceFirst(resultingQry, matcher.group(2), replacement);
}
return resultingQry;
}