, U> Path dot(A attribute) {
* @return
*/
public , U> Path dot(P attribute) {
- return new Path(add(attribute));
+ return new Path<>(add(attribute));
}
private List> add(Attribute, ?> attribute) {
Assert.notNull(attribute, "Attribute must not be null");
- List> newAttributes = new ArrayList>(attributes.size() + 1);
+ List> newAttributes = new ArrayList<>(attributes.size() + 1);
newAttributes.addAll(attributes);
newAttributes.add(attribute);
return newAttributes;
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java
index 501d3a6444..d2bd3039ad 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java
@@ -57,13 +57,9 @@ class JpaPersistentPropertyImpl extends AnnotationBasedPersistentProperty> annotations = new HashSet<>();
- annotations.add(OneToMany.class);
- annotations.add(OneToOne.class);
- annotations.add(ManyToMany.class);
- annotations.add(ManyToOne.class);
+ Set> annotations;
- ASSOCIATION_ANNOTATIONS = Collections.unmodifiableSet(annotations);
+ ASSOCIATION_ANNOTATIONS = Set.of(OneToMany.class, OneToOne.class, ManyToMany.class, ManyToOne.class);
annotations = new HashSet<>();
annotations.add(Id.class);
@@ -107,7 +103,7 @@ public JpaPersistentPropertyImpl(JpaMetamodel metamodel, Property property,
this.associationTargetType = detectAssociationTargetType();
this.updateable = detectUpdatability();
- this.isIdProperty = Lazy.of(() -> ID_ANNOTATIONS.stream().anyMatch(it -> isAnnotationPresent(it)) //
+ this.isIdProperty = Lazy.of(() -> ID_ANNOTATIONS.stream().anyMatch(this::isAnnotationPresent) //
|| metamodel.isSingleIdAttribute(getOwner().getType(), getName(), getType()));
this.isEntity = Lazy.of(() -> metamodel.isMappedType(getActualType()));
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java
new file mode 100644
index 0000000000..4f85f48a62
--- /dev/null
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * JPA specific support projection support.
+ */
+@org.springframework.lang.NonNullApi
+package org.springframework.data.jpa.projection;
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/Temporal.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/Temporal.java
index 7668ccd33f..245983b766 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/Temporal.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/Temporal.java
@@ -30,10 +30,12 @@
*
* @author Thomas Darimont
* @author Oliver Gierke
+ * @deprecated since 4.0. Please use {@literal java.time} types instead.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Documented
+@Deprecated(since = "4.0", forRemoval = true)
public @interface Temporal {
/**
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java
index 9c83985546..657778b260 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java
@@ -93,9 +93,7 @@ public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, Stri
return query.deriveCountQuery(method.getCountQueryProjection());
});
- this.countParameterBinder = Lazy.of(() -> {
- return this.createBinder(this.countQuery.get());
- });
+ this.countParameterBinder = Lazy.of(() -> this.createBinder(this.countQuery.get()));
this.queryRewriter = queryRewriter;
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlCountQueryTransformer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlCountQueryTransformer.java
index aec9763fa0..2d458b91fa 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlCountQueryTransformer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlCountQueryTransformer.java
@@ -43,7 +43,7 @@ class EqlCountQueryTransformer extends EqlQueryRenderer {
}
@Override
- public QueryRendererBuilder visitSelect_statement(EqlParser.Select_statementContext ctx) {
+ public QueryTokenStream visitSelect_statement(EqlParser.Select_statementContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -93,7 +93,7 @@ public QueryTokenStream visitSelect_clause(EqlParser.Select_clauseContext ctx) {
return builder;
}
- private QueryRendererBuilder getDistinctCountSelection(QueryTokenStream selectionListbuilder) {
+ private QueryTokenStream getDistinctCountSelection(QueryTokenStream selectionListbuilder) {
QueryRendererBuilder nested = new QueryRendererBuilder();
CountSelectionTokenStream countSelection = CountSelectionTokenStream.create(selectionListbuilder);
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlQueryRenderer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlQueryRenderer.java
index 17e6e51a55..43f66ee2cb 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlQueryRenderer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlQueryRenderer.java
@@ -23,6 +23,7 @@
import org.antlr.v4.runtime.tree.ParseTree;
import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
+import org.springframework.util.ObjectUtils;
/**
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that renders an EQL query without making any changes.
@@ -77,30 +78,8 @@ public QueryTokenStream visitSelect_statement(EqlParser.Select_statementContext
builder.appendExpression(visit(ctx.orderby_clause()));
}
- for (int i = 0; i < ctx.setOperator().size(); i++) {
-
- builder.appendExpression(visit(ctx.setOperator(i)));
- builder.appendExpression(visit(ctx.select_statement(i)));
- }
-
- return builder;
- }
-
- @Override
- public QueryTokenStream visitSetOperator(EqlParser.SetOperatorContext ctx) {
-
- QueryRendererBuilder builder = QueryRenderer.builder();
-
- if (ctx.UNION() != null) {
- builder.append(QueryTokens.expression(ctx.UNION()));
- } else if (ctx.INTERSECT() != null) {
- builder.append(QueryTokens.expression(ctx.INTERSECT()));
- } else if (ctx.EXCEPT() != null) {
- builder.append(QueryTokens.expression(ctx.EXCEPT()));
- }
-
- if (ctx.ALL() != null) {
- builder.append(QueryTokens.expression(ctx.ALL()));
+ if (ctx.set_fuction() != null) {
+ builder.appendExpression(visit(ctx.set_fuction()));
}
return builder;
@@ -184,13 +163,8 @@ public QueryTokenStream visitIdentification_variable_declaration(
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.range_variable_declaration()));
-
- ctx.join().forEach(joinContext -> {
- builder.append(visit(joinContext));
- });
- ctx.fetch_join().forEach(fetchJoinContext -> {
- builder.append(visit(fetchJoinContext));
- });
+ builder.appendExpression(QueryTokenStream.concat(ctx.join(), this::visit, TOKEN_SPACE));
+ builder.appendExpression(QueryTokenStream.concat(ctx.fetch_join(), this::visit, TOKEN_SPACE));
return builder;
}
@@ -226,9 +200,11 @@ public QueryTokenStream visitJoin(EqlParser.JoinContext ctx) {
if (ctx.AS() != null) {
builder.append(QueryTokens.expression(ctx.AS()));
}
+
if (ctx.identification_variable() != null) {
builder.appendExpression(visit(ctx.identification_variable()));
}
+
if (ctx.join_condition() != null) {
builder.appendExpression(visit(ctx.join_condition()));
}
@@ -291,8 +267,7 @@ public QueryTokenStream visitJoin_condition(EqlParser.Join_conditionContext ctx)
}
@Override
- public QueryTokenStream visitJoin_association_path_expression(
- EqlParser.Join_association_path_expressionContext ctx) {
+ public QueryTokenStream visitJoin_association_path_expression(EqlParser.Join_association_path_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -304,31 +279,25 @@ public QueryTokenStream visitJoin_association_path_expression(
builder.appendExpression(visit(ctx.join_single_valued_path_expression()));
}
} else {
- if (ctx.join_collection_valued_path_expression() != null) {
+ QueryRendererBuilder nested = QueryRenderer.builder();
- QueryRendererBuilder nested = QueryRenderer.builder();
+ if (ctx.join_collection_valued_path_expression() != null) {
- nested.append(QueryTokens.token(ctx.TREAT()));
- nested.append(TOKEN_OPEN_PAREN);
- nested.appendInline(visit(ctx.join_collection_valued_path_expression()));
+ nested.appendExpression(visit(ctx.join_collection_valued_path_expression()));
nested.append(QueryTokens.expression(ctx.AS()));
- nested.appendInline(visit(ctx.subtype()));
- nested.append(TOKEN_CLOSE_PAREN);
+ nested.appendExpression(visit(ctx.subtype()));
- builder.appendExpression(nested);
} else if (ctx.join_single_valued_path_expression() != null) {
- QueryRendererBuilder nested = QueryRenderer.builder();
-
- nested.append(QueryTokens.token(ctx.TREAT()));
- nested.append(TOKEN_OPEN_PAREN);
- nested.appendInline(visit(ctx.join_single_valued_path_expression()));
+ nested.appendExpression(visit(ctx.join_single_valued_path_expression()));
nested.append(QueryTokens.expression(ctx.AS()));
- nested.appendInline(visit(ctx.subtype()));
- nested.append(TOKEN_CLOSE_PAREN);
-
- builder.appendExpression(nested);
+ nested.appendExpression(visit(ctx.subtype()));
}
+
+ builder.append(QueryTokens.token(ctx.TREAT()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(nested);
+ builder.append(TOKEN_CLOSE_PAREN);
}
return builder;
@@ -450,8 +419,7 @@ public QueryTokenStream visitSingle_valued_path_expression(EqlParser.Single_valu
}
@Override
- public QueryTokenStream visitGeneral_identification_variable(
- EqlParser.General_identification_variableContext ctx) {
+ public QueryTokenStream visitGeneral_identification_variable(EqlParser.General_identification_variableContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -494,12 +462,15 @@ public QueryTokenStream visitSimple_subpath(EqlParser.Simple_subpathContext ctx)
public QueryTokenStream visitTreated_subpath(EqlParser.Treated_subpathContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
+ nested.appendExpression(visit(ctx.general_subpath()));
+ nested.append(QueryTokens.expression(ctx.AS()));
+ nested.appendExpression(visit(ctx.subtype()));
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendInline(visit(ctx.general_subpath()));
- builder.append(QueryTokens.expression(ctx.AS()));
- builder.appendInline(visit(ctx.subtype()));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -612,7 +583,7 @@ public QueryTokenStream visitNew_value(EqlParser.New_valueContext ctx) {
} else if (ctx.simple_entity_expression() != null) {
return visit(ctx.simple_entity_expression());
} else if (ctx.NULL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.NULL()));
+ return QueryTokenStream.ofToken(ctx.NULL());
} else {
return QueryRenderer.builder();
}
@@ -719,19 +690,19 @@ public QueryTokenStream visitConstructor_expression(EqlParser.Constructor_expres
@Override
public QueryTokenStream visitConstructor_item(EqlParser.Constructor_itemContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.single_valued_path_expression() != null) {
- builder.append(visit(ctx.single_valued_path_expression()));
+ return visit(ctx.single_valued_path_expression());
} else if (ctx.scalar_expression() != null) {
- builder.append(visit(ctx.scalar_expression()));
+ return visit(ctx.scalar_expression());
} else if (ctx.aggregate_expression() != null) {
- builder.append(visit(ctx.aggregate_expression()));
+ return visit(ctx.aggregate_expression());
} else if (ctx.identification_variable() != null) {
- builder.append(visit(ctx.identification_variable()));
+ return visit(ctx.identification_variable());
+ } else if (ctx.literal() != null) {
+ return visit(ctx.literal());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
@@ -852,15 +823,15 @@ public QueryTokenStream visitOrderby_item(EqlParser.Orderby_itemContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.state_field_path_expression() != null) {
- builder.append(visit(ctx.state_field_path_expression()));
+ builder.appendExpression(visit(ctx.state_field_path_expression()));
} else if (ctx.general_identification_variable() != null) {
- builder.append(visit(ctx.general_identification_variable()));
+ builder.appendExpression(visit(ctx.general_identification_variable()));
} else if (ctx.result_variable() != null) {
- builder.append(visit(ctx.result_variable()));
+ builder.appendExpression(visit(ctx.result_variable()));
} else if (ctx.string_expression() != null) {
- builder.append(visit(ctx.string_expression()));
+ builder.appendExpression(visit(ctx.string_expression()));
} else if (ctx.scalar_expression() != null) {
- builder.append(visit(ctx.scalar_expression()));
+ builder.appendExpression(visit(ctx.scalar_expression()));
}
if (ctx.ASC() != null) {
@@ -882,12 +853,44 @@ public QueryTokenStream visitNullsPrecedence(EqlParser.NullsPrecedenceContext ct
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(TOKEN_NULLS);
+ builder.append(QueryTokens.expression(ctx.NULLS()));
if (ctx.FIRST() != null) {
- builder.append(TOKEN_FIRST);
+ builder.append(QueryTokens.expression(ctx.FIRST()));
} else if (ctx.LAST() != null) {
- builder.append(TOKEN_LAST);
+ builder.append(QueryTokens.expression(ctx.LAST()));
+ }
+
+ return builder;
+ }
+
+ @Override
+ public QueryTokenStream visitSet_fuction(EqlParser.Set_fuctionContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ if (ctx.setOperator() != null) {
+ builder.append(visit(ctx.setOperator()));
+ }
+
+ builder.appendExpression(visit(ctx.select_statement()));
+
+ return builder;
+ }
+
+ @Override
+ public QueryTokenStream visitSetOperator(EqlParser.SetOperatorContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ if (ctx.INTERSECT() != null) {
+ builder.append(QueryTokens.expression(ctx.INTERSECT()));
+ } else if (ctx.UNION() != null) {
+ builder.append(QueryTokens.expression(ctx.UNION()));
+ } else if (ctx.EXCEPT() != null) {
+ builder.append(QueryTokens.expression(ctx.EXCEPT()));
+ } else if (ctx.ALL() != null) {
+ builder.append(QueryTokens.expression(ctx.ALL()));
}
return builder;
@@ -992,81 +995,82 @@ public QueryTokenStream visitSimple_select_expression(EqlParser.Simple_select_ex
@Override
public QueryTokenStream visitScalar_expression(EqlParser.Scalar_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.arithmetic_expression() != null) {
- builder.append(visit(ctx.arithmetic_expression()));
+ return visit(ctx.arithmetic_expression());
} else if (ctx.string_expression() != null) {
- builder.append(visit(ctx.string_expression()));
+ return visit(ctx.string_expression());
} else if (ctx.enum_expression() != null) {
- builder.append(visit(ctx.enum_expression()));
+ return visit(ctx.enum_expression());
} else if (ctx.datetime_expression() != null) {
- builder.append(visit(ctx.datetime_expression()));
+ return visit(ctx.datetime_expression());
} else if (ctx.boolean_expression() != null) {
- builder.append(visit(ctx.boolean_expression()));
+ return visit(ctx.boolean_expression());
} else if (ctx.case_expression() != null) {
- builder.append(visit(ctx.case_expression()));
+ return visit(ctx.case_expression());
} else if (ctx.entity_type_expression() != null) {
- builder.append(visit(ctx.entity_type_expression()));
+ return visit(ctx.entity_type_expression());
+ } else if (ctx.cast_function() != null) {
+ return (visit(ctx.cast_function()));
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitConditional_expression(EqlParser.Conditional_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.conditional_expression() != null) {
- builder.append(visit(ctx.conditional_expression()));
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ builder.appendExpression(visit(ctx.conditional_expression()));
builder.append(QueryTokens.expression(ctx.OR()));
- builder.append(visit(ctx.conditional_term()));
+ builder.appendExpression(visit(ctx.conditional_term()));
+
+ return builder;
} else {
- builder.append(visit(ctx.conditional_term()));
+ return visit(ctx.conditional_term());
}
-
- return builder;
}
@Override
public QueryTokenStream visitConditional_term(EqlParser.Conditional_termContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.conditional_term() != null) {
- builder.append(visit(ctx.conditional_term()));
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ builder.appendExpression(visit(ctx.conditional_term()));
builder.append(QueryTokens.expression(ctx.AND()));
- builder.append(visit(ctx.conditional_factor()));
+ builder.appendExpression(visit(ctx.conditional_factor()));
+
+ return builder;
} else {
- builder.append(visit(ctx.conditional_factor()));
+ return visit(ctx.conditional_factor());
}
-
- return builder;
}
@Override
public QueryTokenStream visitConditional_factor(EqlParser.Conditional_factorContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.NOT() != null) {
+ QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.NOT()));
+ builder.appendExpression(visit(ctx.conditional_primary()));
+ return builder;
}
- builder.append(visit(ctx.conditional_primary()));
-
- return builder;
+ return visit(ctx.conditional_primary());
}
@Override
public QueryTokenStream visitConditional_primary(EqlParser.Conditional_primaryContext ctx) {
+ if (ctx.simple_cond_expression() != null) {
+ return visit(ctx.simple_cond_expression());
+ }
+
QueryRendererBuilder builder = QueryRenderer.builder();
- if (ctx.simple_cond_expression() != null) {
- builder.append(visit(ctx.simple_cond_expression()));
- } else if (ctx.conditional_expression() != null) {
+ if (ctx.conditional_expression() != null) {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.conditional_expression()));
@@ -1079,27 +1083,25 @@ public QueryTokenStream visitConditional_primary(EqlParser.Conditional_primaryCo
@Override
public QueryTokenStream visitSimple_cond_expression(EqlParser.Simple_cond_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.comparison_expression() != null) {
- builder.append(visit(ctx.comparison_expression()));
+ return visit(ctx.comparison_expression());
} else if (ctx.between_expression() != null) {
- builder.append(visit(ctx.between_expression()));
+ return visit(ctx.between_expression());
} else if (ctx.in_expression() != null) {
- builder.append(visit(ctx.in_expression()));
+ return visit(ctx.in_expression());
} else if (ctx.like_expression() != null) {
- builder.append(visit(ctx.like_expression()));
+ return visit(ctx.like_expression());
} else if (ctx.null_comparison_expression() != null) {
- builder.append(visit(ctx.null_comparison_expression()));
+ return visit(ctx.null_comparison_expression());
} else if (ctx.empty_collection_comparison_expression() != null) {
- builder.append(visit(ctx.empty_collection_comparison_expression()));
+ return visit(ctx.empty_collection_comparison_expression());
} else if (ctx.collection_member_expression() != null) {
- builder.append(visit(ctx.collection_member_expression()));
+ return visit(ctx.collection_member_expression());
} else if (ctx.exists_expression() != null) {
- builder.append(visit(ctx.exists_expression()));
+ return visit(ctx.exists_expression());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
@@ -1109,7 +1111,7 @@ public QueryTokenStream visitBetween_expression(EqlParser.Between_expressionCont
if (ctx.arithmetic_expression(0) != null) {
- builder.append(visit(ctx.arithmetic_expression(0)));
+ builder.appendExpression(visit(ctx.arithmetic_expression(0)));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1135,7 +1137,7 @@ public QueryTokenStream visitBetween_expression(EqlParser.Between_expressionCont
} else if (ctx.datetime_expression(0) != null) {
- builder.append(visit(ctx.datetime_expression(0)));
+ builder.appendExpression(visit(ctx.datetime_expression(0)));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1156,10 +1158,10 @@ public QueryTokenStream visitIn_expression(EqlParser.In_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.state_valued_path_expression() != null) {
- builder.append(visit(ctx.state_valued_path_expression()));
+ builder.appendExpression(visit(ctx.state_valued_path_expression()));
}
if (ctx.type_discriminator() != null) {
- builder.append(visit(ctx.type_discriminator()));
+ builder.appendExpression(visit(ctx.type_discriminator()));
}
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1172,7 +1174,6 @@ public QueryTokenStream visitIn_expression(EqlParser.In_expressionContext ctx) {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(QueryTokenStream.concat(ctx.in_item(), this::visit, TOKEN_COMMA));
-
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.subquery() != null) {
@@ -1189,15 +1190,13 @@ public QueryTokenStream visitIn_expression(EqlParser.In_expressionContext ctx) {
@Override
public QueryTokenStream visitIn_item(EqlParser.In_itemContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.literal() != null) {
- builder.append(visit(ctx.literal()));
+ return visit(ctx.literal());
} else if (ctx.single_valued_input_parameter() != null) {
- builder.append(visit(ctx.single_valued_input_parameter()));
+ return visit(ctx.single_valued_input_parameter());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
@@ -1205,7 +1204,8 @@ public QueryTokenStream visitLike_expression(EqlParser.Like_expressionContext ct
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.string_expression()));
+ builder.appendExpression(visit(ctx.string_expression()));
+
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
}
@@ -1227,11 +1227,11 @@ public QueryTokenStream visitNull_comparison_expression(EqlParser.Null_compariso
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.single_valued_path_expression() != null) {
- builder.append(visit(ctx.single_valued_path_expression()));
+ builder.appendExpression(visit(ctx.single_valued_path_expression()));
} else if (ctx.input_parameter() != null) {
- builder.append(visit(ctx.input_parameter()));
+ builder.appendExpression(visit(ctx.input_parameter()));
} else if (ctx.nullif_expression() != null) {
- builder.append(visit(ctx.nullif_expression()));
+ builder.appendExpression(visit(ctx.nullif_expression()));
}
if (ctx.op != null) {
@@ -1253,7 +1253,7 @@ public QueryTokenStream visitEmpty_collection_comparison_expression(
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.collection_valued_path_expression()));
+ builder.appendExpression(visit(ctx.collection_valued_path_expression()));
builder.append(QueryTokens.expression(ctx.IS()));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1268,7 +1268,7 @@ public QueryTokenStream visitCollection_member_expression(EqlParser.Collection_m
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.entity_or_value_expression()));
+ builder.appendExpression(visit(ctx.entity_or_value_expression()));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
}
@@ -1284,34 +1284,30 @@ public QueryTokenStream visitCollection_member_expression(EqlParser.Collection_m
@Override
public QueryTokenStream visitEntity_or_value_expression(EqlParser.Entity_or_value_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.single_valued_object_path_expression() != null) {
- builder.append(visit(ctx.single_valued_object_path_expression()));
+ return visit(ctx.single_valued_object_path_expression());
} else if (ctx.state_field_path_expression() != null) {
- builder.append(visit(ctx.state_field_path_expression()));
+ return visit(ctx.state_field_path_expression());
} else if (ctx.simple_entity_or_value_expression() != null) {
- builder.append(visit(ctx.simple_entity_or_value_expression()));
+ return visit(ctx.simple_entity_or_value_expression());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitSimple_entity_or_value_expression(
EqlParser.Simple_entity_or_value_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.identification_variable() != null) {
- builder.append(visit(ctx.identification_variable()));
+ return visit(ctx.identification_variable());
} else if (ctx.input_parameter() != null) {
- builder.append(visit(ctx.input_parameter()));
+ return visit(ctx.input_parameter());
} else if (ctx.literal() != null) {
- builder.append(visit(ctx.literal()));
+ return visit(ctx.literal());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
@@ -1356,13 +1352,13 @@ public QueryTokenStream visitStringComparison(EqlParser.StringComparisonContext
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.appendInline(visit(ctx.string_expression(0)));
- builder.append(visit(ctx.comparison_operator()));
+ builder.appendExpression(visit(ctx.string_expression(0)));
+ builder.appendExpression(visit(ctx.comparison_operator()));
if (ctx.string_expression(1) != null) {
- builder.append(visit(ctx.string_expression(1)));
+ builder.appendExpression(visit(ctx.string_expression(1)));
} else {
- builder.append(visit(ctx.all_or_any_expression()));
+ builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1377,9 +1373,9 @@ public QueryTokenStream visitBooleanComparison(EqlParser.BooleanComparisonContex
builder.append(QueryTokens.ventilated(ctx.op));
if (ctx.boolean_expression(1) != null) {
- builder.append(visit(ctx.boolean_expression(1)));
+ builder.appendExpression(visit(ctx.boolean_expression(1)));
} else {
- builder.append(visit(ctx.all_or_any_expression()));
+ builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1399,9 +1395,9 @@ public QueryTokenStream visitEnumComparison(EqlParser.EnumComparisonContext ctx)
builder.append(QueryTokens.ventilated(ctx.op));
if (ctx.enum_expression(1) != null) {
- builder.append(visit(ctx.enum_expression(1)));
+ builder.appendExpression(visit(ctx.enum_expression(1)));
} else {
- builder.append(visit(ctx.all_or_any_expression()));
+ builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1416,9 +1412,9 @@ public QueryTokenStream visitDatetimeComparison(EqlParser.DatetimeComparisonCont
builder.append(QueryTokens.ventilated(ctx.comparison_operator().op));
if (ctx.datetime_expression(1) != null) {
- builder.append(visit(ctx.datetime_expression(1)));
+ builder.appendExpression(visit(ctx.datetime_expression(1)));
} else {
- builder.append(visit(ctx.all_or_any_expression()));
+ builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1433,9 +1429,9 @@ public QueryTokenStream visitEntityComparison(EqlParser.EntityComparisonContext
builder.append(QueryTokens.expression(ctx.op));
if (ctx.entity_expression(1) != null) {
- builder.append(visit(ctx.entity_expression(1)));
+ builder.appendExpression(visit(ctx.entity_expression(1)));
} else {
- builder.append(visit(ctx.all_or_any_expression()));
+ builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1446,13 +1442,13 @@ public QueryTokenStream visitArithmeticComparison(EqlParser.ArithmeticComparison
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.arithmetic_expression(0)));
- builder.append(visit(ctx.comparison_operator()));
+ builder.appendExpression(visit(ctx.arithmetic_expression(0)));
+ builder.appendExpression(visit(ctx.comparison_operator()));
if (ctx.arithmetic_expression(1) != null) {
- builder.append(visit(ctx.arithmetic_expression(1)));
+ builder.appendExpression(visit(ctx.arithmetic_expression(1)));
} else {
- builder.append(visit(ctx.all_or_any_expression()));
+ builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1465,7 +1461,7 @@ public QueryTokenStream visitEntityTypeComparison(EqlParser.EntityTypeComparison
builder.appendInline(visit(ctx.entity_type_expression(0)));
builder.append(QueryTokens.ventilated(ctx.op));
- builder.append(visit(ctx.entity_type_expression(1)));
+ builder.appendExpression(visit(ctx.entity_type_expression(1)));
return builder;
}
@@ -1484,42 +1480,37 @@ public QueryTokenStream visitRegexpComparison(EqlParser.RegexpComparisonContext
@Override
public QueryTokenStream visitComparison_operator(EqlParser.Comparison_operatorContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.ventilated(ctx.op));
+ return QueryTokenStream.ofToken(ctx.op);
}
@Override
public QueryTokenStream visitArithmetic_expression(EqlParser.Arithmetic_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.arithmetic_expression() != null) {
+ QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.arithmetic_expression()));
- builder.append(QueryTokens.expression(ctx.op));
+ builder.append(QueryTokens.ventilated(ctx.op));
builder.append(visit(ctx.arithmetic_term()));
+ return builder;
} else {
- builder.append(visit(ctx.arithmetic_term()));
+ return visit(ctx.arithmetic_term());
}
-
- return builder;
}
@Override
public QueryTokenStream visitArithmetic_term(EqlParser.Arithmetic_termContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.arithmetic_term() != null) {
-
+ QueryRendererBuilder builder = QueryRenderer.builder();
builder.appendInline(visit(ctx.arithmetic_term()));
builder.append(QueryTokens.ventilated(ctx.op));
builder.append(visit(ctx.arithmetic_factor()));
+ return builder;
} else {
- builder.append(visit(ctx.arithmetic_factor()));
+ return visit(ctx.arithmetic_factor());
}
-
- return builder;
}
@Override
@@ -1530,7 +1521,8 @@ public QueryTokenStream visitArithmetic_factor(EqlParser.Arithmetic_factorContex
if (ctx.op != null) {
builder.append(QueryTokens.token(ctx.op));
}
- builder.appendInline(visit(ctx.arithmetic_primary()));
+
+ builder.append(visit(ctx.arithmetic_primary()));
return builder;
}
@@ -1595,6 +1587,11 @@ public QueryTokenStream visitString_expression(EqlParser.String_expressionContex
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.subquery()));
builder.append(TOKEN_CLOSE_PAREN);
+ } else if (!ObjectUtils.isEmpty(ctx.string_expression())) {
+
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_DOUBLE_PIPE);
+ builder.appendExpression(visit(ctx.string_expression(1)));
}
return builder;
@@ -1682,45 +1679,39 @@ public QueryTokenStream visitEnum_expression(EqlParser.Enum_expressionContext ct
@Override
public QueryTokenStream visitEntity_expression(EqlParser.Entity_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.single_valued_object_path_expression() != null) {
- builder.append(visit(ctx.single_valued_object_path_expression()));
+ return visit(ctx.single_valued_object_path_expression());
} else if (ctx.simple_entity_expression() != null) {
- builder.append(visit(ctx.simple_entity_expression()));
+ return visit(ctx.simple_entity_expression());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitSimple_entity_expression(EqlParser.Simple_entity_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.identification_variable() != null) {
- builder.append(visit(ctx.identification_variable()));
+ return visit(ctx.identification_variable());
} else if (ctx.input_parameter() != null) {
- builder.append(visit(ctx.input_parameter()));
+ return visit(ctx.input_parameter());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitEntity_type_expression(EqlParser.Entity_type_expressionContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.type_discriminator() != null) {
- builder.append(visit(ctx.type_discriminator()));
+ return visit(ctx.type_discriminator());
} else if (ctx.entity_type_literal() != null) {
- builder.append(visit(ctx.entity_type_literal()));
+ return visit(ctx.entity_type_literal());
} else if (ctx.input_parameter() != null) {
- builder.append(visit(ctx.input_parameter()));
+ return visit(ctx.input_parameter());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
@@ -1895,7 +1886,7 @@ public QueryTokenStream visitFunctions_returning_strings(EqlParser.Functions_ret
builder.append(QueryTokens.token(ctx.SUBSTRING()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(visit(ctx.string_expression(0)));
builder.append(TOKEN_COMMA);
builder.appendInline(QueryTokenStream.concat(ctx.arithmetic_expression(), this::visit, TOKEN_COMMA));
builder.append(TOKEN_CLOSE_PAREN);
@@ -1903,16 +1894,19 @@ public QueryTokenStream visitFunctions_returning_strings(EqlParser.Functions_ret
builder.append(QueryTokens.token(ctx.TRIM()));
builder.append(TOKEN_OPEN_PAREN);
+
+ QueryRendererBuilder nested = QueryRenderer.builder();
if (ctx.trim_specification() != null) {
- builder.appendExpression(visit(ctx.trim_specification()));
+ nested.appendExpression(visit(ctx.trim_specification()));
}
if (ctx.trim_character() != null) {
- builder.appendExpression(visit(ctx.trim_character()));
+ nested.appendExpression(visit(ctx.trim_character()));
}
if (ctx.FROM() != null) {
- builder.append(QueryTokens.expression(ctx.FROM()));
+ nested.append(QueryTokens.expression(ctx.FROM()));
}
- builder.appendInline(visit(ctx.string_expression(0)));
+ nested.append(visit(ctx.string_expression(0)));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.LOWER() != null) {
@@ -1924,7 +1918,30 @@ public QueryTokenStream visitFunctions_returning_strings(EqlParser.Functions_ret
builder.append(QueryTokens.token(ctx.UPPER()));
builder.append(TOKEN_OPEN_PAREN);
+ builder.append(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.LEFT() != null) {
+ builder.append(QueryTokens.token(ctx.LEFT()));
+ builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.arithmetic_expression(0)));
+ builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.RIGHT() != null) {
+ builder.append(QueryTokens.token(ctx.RIGHT()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.arithmetic_expression(0)));
+ builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.REPLACE() != null) {
+ builder.append(QueryTokens.token(ctx.REPLACE()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.string_expression(1)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.string_expression(2)));
builder.append(TOKEN_CLOSE_PAREN);
}
@@ -1935,11 +1952,11 @@ public QueryTokenStream visitFunctions_returning_strings(EqlParser.Functions_ret
public QueryTokenStream visitTrim_specification(EqlParser.Trim_specificationContext ctx) {
if (ctx.LEADING() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.LEADING()));
+ return QueryTokenStream.ofToken(ctx.LEADING());
} else if (ctx.TRAILING() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.TRAILING()));
+ return QueryTokenStream.ofToken(ctx.TRAILING());
} else {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.BOTH()));
+ return QueryTokenStream.ofToken(ctx.BOTH());
}
}
@@ -1952,9 +1969,9 @@ public QueryTokenStream visitCast_function(EqlParser.Cast_functionContext ctx) {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.single_valued_path_expression()));
builder.append(TOKEN_SPACE);
- builder.appendInline(visit(ctx.identification_variable()));
+ builder.appendInline(QueryTokenStream.concat(ctx.identification_variable(), this::visit, TOKEN_SPACE));
- if (ctx.numeric_literal() != null) {
+ if (!ObjectUtils.isEmpty(ctx.numeric_literal())) {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(QueryTokenStream.concat(ctx.numeric_literal(), this::visit, TOKEN_COMMA));
@@ -1991,12 +2008,15 @@ public QueryTokenStream visitFunction_invocation(EqlParser.Function_invocationCo
public QueryTokenStream visitExtract_datetime_field(EqlParser.Extract_datetime_fieldContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
+ nested.appendExpression(visit(ctx.datetime_field()));
+ nested.append(QueryTokens.expression(ctx.FROM()));
+ nested.appendExpression(visit(ctx.datetime_expression()));
builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendExpression(visit(ctx.datetime_field()));
- builder.append(QueryTokens.expression(ctx.FROM()));
- builder.appendInline(visit(ctx.datetime_expression()));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -2011,12 +2031,15 @@ public QueryTokenStream visitDatetime_field(EqlParser.Datetime_fieldContext ctx)
public QueryTokenStream visitExtract_datetime_part(EqlParser.Extract_datetime_partContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
+ nested.appendExpression(visit(ctx.datetime_part()));
+ nested.append(QueryTokens.expression(ctx.FROM()));
+ nested.appendExpression(visit(ctx.datetime_expression()));
builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendExpression(visit(ctx.datetime_part()));
- builder.append(QueryTokens.expression(ctx.FROM()));
- builder.appendInline(visit(ctx.datetime_expression()));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -2055,16 +2078,21 @@ public QueryTokenStream visitCase_expression(EqlParser.Case_expressionContext ct
}
}
+ @Override
+ public QueryRendererBuilder visitType_literal(EqlParser.Type_literalContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+ ctx.children.forEach(it -> builder.append(QueryTokens.expression(it.getText())));
+ return builder;
+ }
+
@Override
public QueryTokenStream visitGeneral_case_expression(EqlParser.General_case_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.CASE()));
-
- ctx.when_clause().forEach(whenClauseContext -> {
- builder.appendExpression(visit(whenClauseContext));
- });
+ builder.appendExpression(QueryTokenStream.concat(ctx.when_clause(), this::visit, TOKEN_SPACE));
builder.append(QueryTokens.expression(ctx.ELSE()));
builder.appendExpression(visit(ctx.scalar_expression()));
@@ -2079,9 +2107,9 @@ public QueryTokenStream visitWhen_clause(EqlParser.When_clauseContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.WHEN()));
- builder.append(visit(ctx.conditional_expression()));
+ builder.appendExpression(visit(ctx.conditional_expression()));
builder.append(QueryTokens.expression(ctx.THEN()));
- builder.append(visit(ctx.scalar_expression()));
+ builder.appendExpression(visit(ctx.scalar_expression()));
return builder;
}
@@ -2092,14 +2120,11 @@ public QueryTokenStream visitSimple_case_expression(EqlParser.Simple_case_expres
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.CASE()));
- builder.append(visit(ctx.case_operand()));
-
- ctx.simple_when_clause().forEach(simpleWhenClauseContext -> {
- builder.append(visit(simpleWhenClauseContext));
- });
+ builder.appendExpression(visit(ctx.case_operand()));
+ builder.appendExpression(QueryTokenStream.concat(ctx.simple_when_clause(), this::visit, TOKEN_SPACE));
builder.append(QueryTokens.expression(ctx.ELSE()));
- builder.append(visit(ctx.scalar_expression()));
+ builder.appendExpression(visit(ctx.scalar_expression()));
builder.append(QueryTokens.expression(ctx.END()));
return builder;
@@ -2160,11 +2185,11 @@ public QueryTokenStream visitNullif_expression(EqlParser.Nullif_expressionContex
public QueryTokenStream visitTrim_character(EqlParser.Trim_characterContext ctx) {
if (ctx.CHARACTER() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
} else if (ctx.character_valued_input_parameter() != null) {
return visit(ctx.character_valued_input_parameter());
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
@@ -2172,11 +2197,13 @@ public QueryTokenStream visitTrim_character(EqlParser.Trim_characterContext ctx)
public QueryTokenStream visitIdentification_variable(EqlParser.Identification_variableContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
+ return QueryTokenStream.ofToken(ctx.IDENTIFICATION_VARIABLE());
+ } else if (ctx.type_literal() != null) {
+ return visit(ctx.type_literal());
} else if (ctx.f != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.f));
+ return QueryTokenStream.ofToken(ctx.f);
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
@@ -2188,23 +2215,23 @@ public QueryTokenStream visitConstructor_name(EqlParser.Constructor_nameContext
@Override
public QueryTokenStream visitLiteral(EqlParser.LiteralContext ctx) {
- QueryRendererBuilder builder = QueryRenderer.builder();
-
if (ctx.STRINGLITERAL() != null) {
- builder.append(QueryTokens.expression(ctx.STRINGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRINGLITERAL());
+ } else if (ctx.JAVASTRINGLITERAL() != null) {
+ return QueryTokenStream.ofToken(ctx.JAVASTRINGLITERAL());
} else if (ctx.INTLITERAL() != null) {
- builder.append(QueryTokens.expression(ctx.INTLITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTLITERAL());
} else if (ctx.FLOATLITERAL() != null) {
- builder.append(QueryTokens.expression(ctx.FLOATLITERAL()));
+ return QueryTokenStream.ofToken(ctx.FLOATLITERAL());
} else if (ctx.LONGLITERAL() != null) {
- builder.append(QueryTokens.expression(ctx.LONGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.LONGLITERAL());
} else if (ctx.boolean_literal() != null) {
- builder.append(visit(ctx.boolean_literal()));
+ return visit(ctx.boolean_literal());
} else if (ctx.entity_type_literal() != null) {
- builder.append(visit(ctx.entity_type_literal()));
+ return visit(ctx.entity_type_literal());
}
- return builder;
+ return QueryTokenStream.empty();
}
@Override
@@ -2239,13 +2266,13 @@ public QueryTokenStream visitPattern_value(EqlParser.Pattern_valueContext ctx) {
public QueryTokenStream visitDate_time_timestamp_literal(EqlParser.Date_time_timestamp_literalContext ctx) {
if (ctx.STRINGLITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.STRINGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRINGLITERAL());
} else if (ctx.DATELITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.DATELITERAL()));
+ return QueryTokenStream.ofToken(ctx.DATELITERAL());
} else if (ctx.TIMELITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.TIMELITERAL()));
+ return QueryTokenStream.ofToken(ctx.TIMELITERAL());
} else if (ctx.TIMESTAMPLITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.TIMESTAMPLITERAL()));
+ return QueryTokenStream.ofToken(ctx.TIMESTAMPLITERAL());
} else {
return QueryRenderer.builder();
}
@@ -2258,20 +2285,20 @@ public QueryTokenStream visitEntity_type_literal(EqlParser.Entity_type_literalCo
@Override
public QueryTokenStream visitEscape_character(EqlParser.Escape_characterContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
}
@Override
public QueryTokenStream visitNumeric_literal(EqlParser.Numeric_literalContext ctx) {
if (ctx.INTLITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.INTLITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTLITERAL());
} else if (ctx.FLOATLITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.FLOATLITERAL()));
+ return QueryTokenStream.ofToken(ctx.FLOATLITERAL());
} else if (ctx.LONGLITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.LONGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.LONGLITERAL());
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
@@ -2279,11 +2306,11 @@ public QueryTokenStream visitNumeric_literal(EqlParser.Numeric_literalContext ct
public QueryTokenStream visitBoolean_literal(EqlParser.Boolean_literalContext ctx) {
if (ctx.TRUE() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.TRUE()));
+ return QueryTokenStream.ofToken(ctx.TRUE());
} else if (ctx.FALSE() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.FALSE()));
+ return QueryTokenStream.ofToken(ctx.FALSE());
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
@@ -2296,11 +2323,11 @@ public QueryTokenStream visitEnum_literal(EqlParser.Enum_literalContext ctx) {
public QueryTokenStream visitString_literal(EqlParser.String_literalContext ctx) {
if (ctx.CHARACTER() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
} else if (ctx.STRINGLITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.STRINGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRINGLITERAL());
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
@@ -2337,7 +2364,7 @@ public QueryTokenStream visitCollection_value_field(EqlParser.Collection_value_f
@Override
public QueryTokenStream visitEntity_name(EqlParser.Entity_nameContext ctx) {
- return QueryTokenStream.concat(ctx.reserved_word(), this::visit, QueryRenderer::inline, TOKEN_DOT);
+ return QueryTokenStream.concat(ctx.reserved_word(), this::visit, TOKEN_DOT);
}
@Override
@@ -2368,26 +2395,25 @@ public QueryTokenStream visitFunction_name(EqlParser.Function_nameContext ctx) {
}
@Override
- public QueryTokenStream visitCharacter_valued_input_parameter(
- EqlParser.Character_valued_input_parameterContext ctx) {
+ public QueryTokenStream visitCharacter_valued_input_parameter(EqlParser.Character_valued_input_parameterContext ctx) {
if (ctx.CHARACTER() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
} else if (ctx.input_parameter() != null) {
return visit(ctx.input_parameter());
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
@Override
public QueryTokenStream visitReserved_word(EqlParser.Reserved_wordContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
+ return QueryTokenStream.ofToken(ctx.IDENTIFICATION_VARIABLE());
} else if (ctx.f != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.f));
+ return QueryTokenStream.ofToken(ctx.f);
} else {
- return QueryRenderer.builder();
+ return QueryTokenStream.empty();
}
}
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlSortedQueryTransformer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlSortedQueryTransformer.java
index ed14e9afdf..23e75a20ee 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlSortedQueryTransformer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlSortedQueryTransformer.java
@@ -23,7 +23,6 @@
import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
-import org.springframework.util.ObjectUtils;
/**
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that transforms a parsed EQL query by applying
@@ -50,7 +49,7 @@ class EqlSortedQueryTransformer extends EqlQueryRenderer {
}
@Override
- public QueryRendererBuilder visitSelect_statement(EqlParser.Select_statementContext ctx) {
+ public QueryTokenStream visitSelect_statement(EqlParser.Select_statementContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -69,18 +68,16 @@ public QueryRendererBuilder visitSelect_statement(EqlParser.Select_statementCont
builder.appendExpression(visit(ctx.having_clause()));
}
- doVisitOrderBy(builder, ctx, ObjectUtils.isEmpty(ctx.setOperator()) ? this.sort : Sort.unsorted());
-
- for (int i = 0; i < ctx.setOperator().size(); i++) {
-
- builder.appendExpression(visit(ctx.setOperator(i)));
- builder.appendExpression(visit(ctx.select_statement(i)));
+ if (ctx.set_fuction() != null) {
+ builder.appendExpression(visit(ctx.set_fuction()));
+ } else {
+ doVisitOrderBy(builder, ctx);
}
return builder;
}
- private void doVisitOrderBy(QueryRendererBuilder builder, EqlParser.Select_statementContext ctx, Sort sort) {
+ private void doVisitOrderBy(QueryRendererBuilder builder, EqlParser.Select_statementContext ctx) {
if (ctx.orderby_clause() != null) {
QueryTokenStream existingOrder = visit(ctx.orderby_clause());
@@ -113,7 +110,7 @@ public QueryTokenStream visitSelect_item(EqlParser.Select_itemContext ctx) {
QueryTokenStream tokens = super.visitSelect_item(ctx);
if (ctx.result_variable() != null && !tokens.isEmpty()) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
@@ -125,7 +122,7 @@ public QueryTokenStream visitJoin(EqlParser.JoinContext ctx) {
QueryTokenStream tokens = super.visitJoin(ctx);
if (!tokens.isEmpty()) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java
index 311fdce1d3..3d6ef20a95 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java
@@ -107,7 +107,7 @@ public QueryTokenStream visitQueryExpression(HqlParser.QueryExpressionContext ct
@Override
public QueryTokenStream visitWithClause(HqlParser.WithClauseContext ctx) {
- QueryRendererBuilder builder = QueryRendererBuilder.from(TOKEN_WITH);
+ QueryRendererBuilder builder = QueryRendererBuilder.builder(TOKEN_WITH);
builder.append(QueryTokenStream.concatExpressions(ctx.cte(), this::visit, TOKEN_COMMA));
return builder;
@@ -668,7 +668,7 @@ public QueryTokenStream visitGroupedItem(HqlParser.GroupedItemContext ctx) {
if (ctx.identifier() != null) {
return visit(ctx.identifier());
} else if (ctx.INTEGER_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.INTEGER_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTEGER_LITERAL());
} else if (ctx.expression() != null) {
return visit(ctx.expression());
} else {
@@ -700,7 +700,7 @@ public QueryTokenStream visitSortExpression(HqlParser.SortExpressionContext ctx)
if (ctx.identifier() != null) {
return visit(ctx.identifier());
} else if (ctx.INTEGER_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.INTEGER_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTEGER_LITERAL());
} else if (ctx.expression() != null) {
return visit(ctx.expression());
} else {
@@ -712,9 +712,9 @@ public QueryTokenStream visitSortExpression(HqlParser.SortExpressionContext ctx)
public QueryTokenStream visitSortDirection(HqlParser.SortDirectionContext ctx) {
if (ctx.ASC() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.ASC()));
+ return QueryTokenStream.ofToken(ctx.ASC());
} else if (ctx.DESC() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.DESC()));
+ return QueryTokenStream.ofToken(ctx.DESC());
} else {
return QueryTokenStream.empty();
}
@@ -778,9 +778,9 @@ public QueryTokenStream visitFetchClause(HqlParser.FetchClauseContext ctx) {
}
if (ctx.parameterOrIntegerLiteral() != null) {
- builder.append(visit(ctx.parameterOrIntegerLiteral()));
+ builder.appendExpression(visit(ctx.parameterOrIntegerLiteral()));
} else if (ctx.parameterOrNumberLiteral() != null) {
- builder.append(visit(ctx.parameterOrNumberLiteral()));
+ builder.appendExpression(visit(ctx.parameterOrNumberLiteral()));
}
if (ctx.ROW() != null) {
@@ -1029,13 +1029,13 @@ public QueryTokenStream visitSetOperator(HqlParser.SetOperatorContext ctx) {
public QueryTokenStream visitLiteral(HqlParser.LiteralContext ctx) {
if (ctx.NULL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.NULL()));
+ return QueryTokenStream.ofToken(ctx.NULL());
} else if (ctx.booleanLiteral() != null) {
return visit(ctx.booleanLiteral());
} else if (ctx.JAVA_STRING_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.JAVA_STRING_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.JAVA_STRING_LITERAL());
} else if (ctx.STRING_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.STRING_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRING_LITERAL());
} else if (ctx.numericLiteral() != null) {
return visit(ctx.numericLiteral());
} else if (ctx.dateTimeLiteral() != null) {
@@ -1051,9 +1051,9 @@ public QueryTokenStream visitLiteral(HqlParser.LiteralContext ctx) {
public QueryTokenStream visitBooleanLiteral(HqlParser.BooleanLiteralContext ctx) {
if (ctx.TRUE() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.TRUE()));
+ return QueryTokenStream.ofToken(ctx.TRUE());
} else if (ctx.FALSE() != null) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.FALSE()));
+ return QueryTokenStream.ofToken(ctx.FALSE());
} else {
return QueryTokenStream.empty();
}
@@ -1063,19 +1063,19 @@ public QueryTokenStream visitBooleanLiteral(HqlParser.BooleanLiteralContext ctx)
public QueryTokenStream visitNumericLiteral(HqlParser.NumericLiteralContext ctx) {
if (ctx.INTEGER_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.INTEGER_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTEGER_LITERAL());
} else if (ctx.LONG_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.LONG_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.LONG_LITERAL());
} else if (ctx.BIG_INTEGER_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.BIG_INTEGER_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.BIG_INTEGER_LITERAL());
} else if (ctx.FLOAT_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.FLOAT_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.FLOAT_LITERAL());
} else if (ctx.DOUBLE_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.DOUBLE_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.DOUBLE_LITERAL());
} else if (ctx.BIG_DECIMAL_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.BIG_DECIMAL_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.BIG_DECIMAL_LITERAL());
} else if (ctx.HEX_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.HEX_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.HEX_LITERAL());
} else {
return QueryTokenStream.empty();
}
@@ -1130,25 +1130,25 @@ public QueryTokenStream visitDateTimeLiteral(HqlParser.DateTimeLiteralContext ct
public QueryTokenStream visitDatetimeField(HqlParser.DatetimeFieldContext ctx) {
if (ctx.YEAR() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.YEAR()));
+ return QueryTokenStream.ofToken(ctx.YEAR());
} else if (ctx.MONTH() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.MONTH()));
+ return QueryTokenStream.ofToken(ctx.MONTH());
} else if (ctx.DAY() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.DAY()));
+ return QueryTokenStream.ofToken(ctx.DAY());
} else if (ctx.WEEK() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.WEEK()));
+ return QueryTokenStream.ofToken(ctx.WEEK());
} else if (ctx.QUARTER() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.QUARTER()));
+ return QueryTokenStream.ofToken(ctx.QUARTER());
} else if (ctx.HOUR() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.HOUR()));
+ return QueryTokenStream.ofToken(ctx.HOUR());
} else if (ctx.MINUTE() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.MINUTE()));
+ return QueryTokenStream.ofToken(ctx.MINUTE());
} else if (ctx.SECOND() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.SECOND()));
+ return QueryTokenStream.ofToken(ctx.SECOND());
} else if (ctx.NANOSECOND() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.NANOSECOND()));
+ return QueryTokenStream.ofToken(ctx.NANOSECOND());
} else if (ctx.EPOCH() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.EPOCH()));
+ return QueryTokenStream.ofToken(ctx.EPOCH());
} else {
return QueryTokenStream.empty();
}
@@ -1226,7 +1226,7 @@ public QueryTokenStream visitTimeZoneField(HqlParser.TimeZoneFieldContext ctx) {
@Override
public QueryTokenStream visitDateOrTimeField(HqlParser.DateOrTimeFieldContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.DATE() != null ? ctx.DATE() : ctx.TIME()));
+ return QueryTokenStream.ofToken(ctx.DATE() != null ? ctx.DATE() : ctx.TIME());
}
@Override
@@ -1239,11 +1239,7 @@ public QueryTokenStream visitBinaryLiteral(HqlParser.BinaryLiteralContext ctx) {
} else if (ctx.HEX_LITERAL() != null) {
builder.append(TOKEN_OPEN_BRACE);
-
- builder.append(QueryTokenStream.concat(ctx.HEX_LITERAL(), it -> {
- return QueryRendererBuilder.from(QueryTokens.token(it));
- }, TOKEN_COMMA));
-
+ builder.append(QueryTokenStream.concat(ctx.HEX_LITERAL(), QueryTokenStream::ofToken, TOKEN_COMMA));
builder.append(TOKEN_CLOSE_BRACE);
}
@@ -1390,7 +1386,7 @@ public QueryTokenStream visitToDurationExpression(HqlParser.ToDurationExpression
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.expression()));
+ builder.appendExpression(visit(ctx.expression()));
builder.appendExpression(visit(ctx.datetimeField()));
return builder;
@@ -1401,7 +1397,7 @@ public QueryTokenStream visitFromDurationExpression(HqlParser.FromDurationExpres
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.expression()));
+ builder.appendExpression(visit(ctx.expression()));
builder.append(QueryTokens.expression(ctx.BY()));
builder.appendExpression(visit(ctx.datetimeField()));
@@ -1812,12 +1808,12 @@ public QueryTokenStream visitPadFunction(HqlParser.PadFunctionContext ctx) {
@Override
public QueryTokenStream visitPadSpecification(HqlParser.PadSpecificationContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.LEADING() != null ? ctx.LEADING() : ctx.TRAILING()));
+ return QueryTokenStream.ofToken(ctx.LEADING() != null ? ctx.LEADING() : ctx.TRAILING());
}
@Override
public QueryTokenStream visitPadCharacter(HqlParser.PadCharacterContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.STRING_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRING_LITERAL());
}
@Override
@@ -1829,12 +1825,16 @@ public QueryTokenStream visitPadLength(HqlParser.PadLengthContext ctx) {
public QueryTokenStream visitPositionFunction(HqlParser.PositionFunctionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
builder.append(QueryTokens.token(ctx.POSITION()));
builder.append(TOKEN_OPEN_PAREN);
- builder.append(visit(ctx.positionFunctionPatternArgument()));
- builder.append(QueryTokens.expression(ctx.IN()));
- builder.appendInline(visit(ctx.positionFunctionStringArgument()));
+
+ nested.appendExpression(visit(ctx.positionFunctionPatternArgument()));
+ nested.append(QueryTokens.expression(ctx.IN()));
+ nested.append(visit(ctx.positionFunctionStringArgument()));
+
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -1857,7 +1857,7 @@ public QueryTokenStream visitOverlayFunction(HqlParser.OverlayFunctionContext ct
builder.append(QueryTokens.token(ctx.OVERLAY()));
builder.append(TOKEN_OPEN_PAREN);
- builder.append(visit(ctx.overlayFunctionStringArgument()));
+ builder.appendExpression(visit(ctx.overlayFunctionStringArgument()));
builder.append(QueryTokens.expression(ctx.PLACING()));
builder.append(visit(ctx.overlayFunctionReplacementArgument()));
builder.append(QueryTokens.expression(ctx.FROM()));
@@ -2091,7 +2091,7 @@ public QueryTokenStream visitRollup(HqlParser.RollupContext ctx) {
@Override
public QueryTokenStream visitFormat(HqlParser.FormatContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.STRING_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRING_LITERAL());
}
@Override
@@ -2153,7 +2153,7 @@ public QueryTokenStream visitJpaNonstandardFunctionName(HqlParser.JpaNonstandard
return visit(ctx.identifier());
}
- return QueryRendererBuilder.from(QueryTokens.token(ctx.STRING_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRING_LITERAL());
}
@Override
@@ -2652,10 +2652,7 @@ public QueryTokenStream visitSimpleCaseExpression(HqlParser.SimpleCaseExpression
builder.append(QueryTokens.expression(ctx.CASE()));
builder.append(visit(ctx.expressionOrPredicate(0)));
-
- ctx.caseWhenExpressionClause().forEach(caseWhenExpressionClauseContext -> {
- builder.append(visit(caseWhenExpressionClauseContext));
- });
+ builder.appendExpression(QueryTokenStream.concat(ctx.caseWhenExpressionClause(), this::visit, TOKEN_SPACE));
if (ctx.ELSE() != null) {
@@ -2898,7 +2895,7 @@ public QueryTokenStream visitCastTarget(HqlParser.CastTargetContext ctx) {
@Override
public QueryTokenStream visitCastTargetType(HqlParser.CastTargetTypeContext ctx) {
- return QueryRendererBuilder.from(QueryTokens.expression(ctx.fullTargetName));
+ return QueryTokenStream.from(QueryTokens.token(ctx.fullTargetName));
}
@Override
@@ -2915,7 +2912,7 @@ public QueryTokenStream visitExtractFunction(HqlParser.ExtractFunctionContext ct
nested.appendExpression(visit(ctx.extractField()));
nested.append(QueryTokens.expression(ctx.FROM()));
- nested.append(visit(ctx.expression()));
+ nested.appendExpression(visit(ctx.expression()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
@@ -3005,7 +3002,7 @@ public QueryTokenStream visitTrimSpecification(HqlParser.TrimSpecificationContex
public QueryTokenStream visitTrimCharacter(HqlParser.TrimCharacterContext ctx) {
if (ctx.STRING_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.STRING_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRING_LITERAL());
}
return visit(ctx.parameter());
@@ -3155,11 +3152,11 @@ public QueryTokenStream visitToOneFkReference(HqlParser.ToOneFkReferenceContext
public QueryTokenStream visitElementValueQuantifier(HqlParser.ElementValueQuantifierContext ctx) {
if (ctx.ELEMENT() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.ELEMENT()));
+ return QueryTokenStream.ofToken(ctx.ELEMENT());
}
if (ctx.VALUE() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.VALUE()));
+ return QueryTokenStream.ofToken(ctx.VALUE());
}
return QueryTokenStream.empty();
@@ -3169,11 +3166,11 @@ public QueryTokenStream visitElementValueQuantifier(HqlParser.ElementValueQuanti
public QueryTokenStream visitIndexKeyQuantifier(HqlParser.IndexKeyQuantifierContext ctx) {
if (ctx.INDEX() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.INDEX()));
+ return QueryTokenStream.ofToken(ctx.INDEX());
}
if (ctx.KEY() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.KEY()));
+ return QueryTokenStream.ofToken(ctx.KEY());
}
return QueryTokenStream.empty();
@@ -3517,11 +3514,10 @@ public QueryTokenStream visitExistsExpression(HqlParser.ExistsExpressionContext
public QueryTokenStream visitInstantiationTarget(HqlParser.InstantiationTargetContext ctx) {
if (ctx.LIST() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.LIST()));
+ return QueryTokenStream.ofToken(ctx.LIST());
} else if (ctx.MAP() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.MAP()));
+ return QueryTokenStream.ofToken(ctx.MAP());
} else if (ctx.simplePath() != null) {
-
return visit(ctx.simplePath());
} else {
return QueryTokenStream.empty();
@@ -3557,7 +3553,7 @@ public QueryTokenStream visitParameterOrIntegerLiteral(HqlParser.ParameterOrInte
if (ctx.parameter() != null) {
return visit(ctx.parameter());
} else if (ctx.INTEGER_LITERAL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.INTEGER_LITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTEGER_LITERAL());
} else {
return QueryTokenStream.empty();
}
@@ -3623,15 +3619,15 @@ public QueryTokenStream visitIdentifier(HqlParser.IdentifierContext ctx) {
if (ctx.nakedIdentifier() != null) {
return visit(ctx.nakedIdentifier());
} else if (ctx.FULL() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.FULL()));
+ return QueryTokenStream.ofToken(ctx.FULL());
} else if (ctx.LEFT() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.LEFT()));
+ return QueryTokenStream.ofToken(ctx.LEFT());
} else if (ctx.INNER() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.INNER()));
+ return QueryTokenStream.ofToken(ctx.INNER());
} else if (ctx.OUTER() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.OUTER()));
+ return QueryTokenStream.ofToken(ctx.OUTER());
} else if (ctx.RIGHT() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.RIGHT()));
+ return QueryTokenStream.ofToken(ctx.RIGHT());
}
return QueryTokenStream.empty();
@@ -3641,11 +3637,11 @@ public QueryTokenStream visitIdentifier(HqlParser.IdentifierContext ctx) {
public QueryTokenStream visitNakedIdentifier(HqlParser.NakedIdentifierContext ctx) {
if (ctx.IDENTIFIER() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.IDENTIFIER()));
+ return QueryTokenStream.ofToken(ctx.IDENTIFIER());
} else if (ctx.QUOTED_IDENTIFIER() != null) {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.QUOTED_IDENTIFIER()));
+ return QueryTokenStream.ofToken(ctx.QUOTED_IDENTIFIER());
} else {
- return QueryRendererBuilder.from(QueryTokens.token(ctx.f));
+ return QueryTokenStream.ofToken(ctx.f);
}
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlSortedQueryTransformer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlSortedQueryTransformer.java
index b6b8853f93..256e4a443e 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlSortedQueryTransformer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlSortedQueryTransformer.java
@@ -87,7 +87,7 @@ public QueryTokenStream visitJoinPath(HqlParser.JoinPathContext ctx) {
QueryTokenStream tokens = super.visitJoinPath(ctx);
if (ctx.variable() != null && !isSubquery(ctx)) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
@@ -99,7 +99,7 @@ public QueryTokenStream visitJoinSubquery(HqlParser.JoinSubqueryContext ctx) {
QueryTokenStream tokens = super.visitJoinSubquery(ctx);
if (ctx.variable() != null && !tokens.isEmpty() && !isSubquery(ctx)) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
@@ -111,7 +111,7 @@ public QueryTokenStream visitVariable(HqlParser.VariableContext ctx) {
QueryTokenStream tokens = super.visitVariable(ctx);
if (ctx.identifier() != null && !tokens.isEmpty() && !isSubquery(ctx)) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java
index 1686148603..c7a76502f9 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java
@@ -98,7 +98,8 @@ public JSqlParserQueryEnhancer(DeclaredQuery query) {
/**
* Parses a query string with JSqlParser.
*
- * @param query the query to parse
+ * @param sql the query to parse
+ * @param classOfT the query to parse
* @return the parsed query
*/
static T parseStatement(String sql, Class classOfT) {
@@ -502,7 +503,7 @@ private static boolean onlyASingleColumnProjection(List> projectio
*
*/
enum ParsedType {
- DELETE, UPDATE, SELECT, INSERT, MERGE, OTHER;
+ DELETE, UPDATE, SELECT, INSERT, MERGE, OTHER
}
/**
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaParameters.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaParameters.java
index d40895ab78..9f42ebf970 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaParameters.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaParameters.java
@@ -88,6 +88,8 @@ public boolean hasLimitingParameters() {
public static class JpaParameter extends Parameter {
private final @Nullable Temporal annotation;
+
+ @SuppressWarnings("deprecation")
private @Nullable TemporalType temporalType;
/**
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java
index 82482cd99c..b6dd20cd47 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java
@@ -16,7 +16,6 @@
package org.springframework.data.jpa.repository.query;
import jakarta.persistence.EntityManager;
-import jakarta.persistence.NoResultException;
import jakarta.persistence.Query;
import jakarta.persistence.StoredProcedureQuery;
@@ -87,13 +86,7 @@ public Object execute(AbstractJpaQuery query, JpaParametersParameterAccessor acc
Assert.notNull(query, "AbstractJpaQuery must not be null");
Assert.notNull(accessor, "JpaParametersParameterAccessor must not be null");
- Object result;
-
- try {
- result = doExecute(query, accessor);
- } catch (NoResultException e) {
- return null;
- }
+ Object result = doExecute(query, accessor);
if (result == null) {
return null;
@@ -221,7 +214,7 @@ static class SingleEntityExecution extends JpaQueryExecution {
@Override
protected Object doExecute(AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {
- return query.createQuery(accessor).getSingleResult();
+ return query.createQuery(accessor).getSingleResultOrNull();
}
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java
index 8ca7a007df..affcee14c8 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java
@@ -143,7 +143,8 @@ private static class DeclaredQueryLookupStrategy extends AbstractQueryLookupStra
*
* @param em must not be {@literal null}.
* @param queryMethodFactory must not be {@literal null}.
- * @param evaluationContextProvider must not be {@literal null}.
+ * @param delegate must not be {@literal null}.
+ * @param queryRewriterProvider must not be {@literal null}.
*/
public DeclaredQueryLookupStrategy(EntityManager em, JpaQueryMethodFactory queryMethodFactory,
ValueExpressionDelegate delegate, QueryRewriterProvider queryRewriterProvider) {
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlCountQueryTransformer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlCountQueryTransformer.java
index 2adac83e9b..faad242941 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlCountQueryTransformer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlCountQueryTransformer.java
@@ -42,7 +42,7 @@ class JpqlCountQueryTransformer extends JpqlQueryRenderer {
}
@Override
- public QueryRenderer.QueryRendererBuilder visitSelect_statement(JpqlParser.Select_statementContext ctx) {
+ public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -58,6 +58,9 @@ public QueryRenderer.QueryRendererBuilder visitSelect_statement(JpqlParser.Selec
if (ctx.having_clause() != null) {
builder.appendExpression(visit(ctx.having_clause()));
}
+ if (ctx.set_fuction() != null) {
+ builder.appendExpression(visit(ctx.set_fuction()));
+ }
return builder;
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java
index 287b397384..6c1817946b 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java
@@ -848,9 +848,7 @@ public String getAlias(Origin source) {
*/
public String getAlias(Origin source) {
- return aliases.computeIfAbsent(source, it -> JpqlQueryBuilder.getAlias(source.getName(), s -> {
- return !aliases.containsValue(s);
- }, () -> "join_" + (counter++)));
+ return aliases.computeIfAbsent(source, it -> JpqlQueryBuilder.getAlias(source.getName(), s -> !aliases.containsValue(s), () -> "join_" + (counter++)));
}
/**
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java
index f743d50669..593e25e579 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java
@@ -24,7 +24,10 @@
import org.springframework.data.jpa.repository.query.JpqlParser.NullsPrecedenceContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Reserved_wordContext;
+import org.springframework.data.jpa.repository.query.JpqlParser.Set_fuctionContext;
+import org.springframework.data.jpa.repository.query.JpqlParser.Type_literalContext;
import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
+import org.springframework.util.ObjectUtils;
/**
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that renders a JPQL query without making any changes.
@@ -79,6 +82,10 @@ public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext
builder.appendExpression(visit(ctx.orderby_clause()));
}
+ if (ctx.set_fuction() != null) {
+ builder.appendExpression(visit(ctx.set_fuction()));
+ }
+
return builder;
}
@@ -146,15 +153,10 @@ public QueryTokenStream visitIdentification_variable_declaration(
JpqlParser.Identification_variable_declarationContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.appendExpression(visit(ctx.range_variable_declaration()));
- ctx.join().forEach(joinContext -> {
- builder.append(visit(joinContext));
- });
-
- ctx.fetch_join().forEach(fetchJoinContext -> {
- builder.append(visit(fetchJoinContext));
- });
+ builder.append(visit(ctx.range_variable_declaration()));
+ builder.appendExpression(QueryTokenStream.concat(ctx.join(), this::visit, TOKEN_SPACE));
+ builder.appendExpression(QueryTokenStream.concat(ctx.fetch_join(), this::visit, TOKEN_SPACE));
return builder;
}
@@ -180,14 +182,19 @@ public QueryTokenStream visitJoin(JpqlParser.JoinContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.join_spec()));
- builder.append(visit(ctx.join_association_path_expression()));
+ builder.appendExpression(visit(ctx.join_spec()));
+ builder.appendExpression(visit(ctx.join_association_path_expression()));
+
if (ctx.AS() != null) {
builder.append(QueryTokens.expression(ctx.AS()));
}
- builder.append(visit(ctx.identification_variable()));
+
+ if (ctx.identification_variable() != null) {
+ builder.appendExpression(visit(ctx.identification_variable()));
+ }
+
if (ctx.join_condition() != null) {
- builder.append(visit(ctx.join_condition()));
+ builder.appendExpression(visit(ctx.join_condition()));
}
return builder;
@@ -198,9 +205,19 @@ public QueryTokenStream visitFetch_join(JpqlParser.Fetch_joinContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(visit(ctx.join_spec()));
+ builder.appendExpression(visit(ctx.join_spec()));
builder.append(QueryTokens.expression(ctx.FETCH()));
- builder.append(visit(ctx.join_association_path_expression()));
+ builder.appendExpression(visit(ctx.join_association_path_expression()));
+
+ if (ctx.AS() != null) {
+ builder.append(QueryTokens.expression(ctx.AS()));
+ }
+ if (ctx.identification_variable() != null) {
+ builder.appendExpression(visit(ctx.identification_variable()));
+ }
+ if (ctx.join_condition() != null) {
+ builder.appendExpression(visit(ctx.join_condition()));
+ }
return builder;
}
@@ -251,23 +268,25 @@ public QueryTokenStream visitJoin_association_path_expression(
builder.appendExpression(visit(ctx.join_single_valued_path_expression()));
}
} else {
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
if (ctx.join_collection_valued_path_expression() != null) {
- builder.append(QueryTokens.token(ctx.TREAT()));
- builder.append(TOKEN_OPEN_PAREN);
- builder.appendInline(visit(ctx.join_collection_valued_path_expression()));
- builder.append(QueryTokens.expression(ctx.AS()));
- builder.appendInline(visit(ctx.subtype()));
- builder.append(TOKEN_CLOSE_PAREN);
+ nested.appendExpression(visit(ctx.join_collection_valued_path_expression()));
+ nested.append(QueryTokens.expression(ctx.AS()));
+ nested.appendExpression(visit(ctx.subtype()));
+
} else if (ctx.join_single_valued_path_expression() != null) {
- builder.append(QueryTokens.token(ctx.TREAT()));
- builder.append(TOKEN_OPEN_PAREN);
- builder.appendInline(visit(ctx.join_single_valued_path_expression()));
- builder.append(QueryTokens.expression(ctx.AS()));
- builder.appendInline(visit(ctx.subtype()));
- builder.append(TOKEN_CLOSE_PAREN);
+ nested.appendExpression(visit(ctx.join_single_valued_path_expression()));
+ nested.append(QueryTokens.expression(ctx.AS()));
+ nested.appendExpression(visit(ctx.subtype()));
}
+
+ builder.append(QueryTokens.token(ctx.TREAT()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(nested);
+ builder.append(TOKEN_CLOSE_PAREN);
}
return builder;
@@ -427,12 +446,15 @@ public QueryTokenStream visitSimple_subpath(JpqlParser.Simple_subpathContext ctx
public QueryTokenStream visitTreated_subpath(JpqlParser.Treated_subpathContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
+ nested.appendExpression(visit(ctx.general_subpath()));
+ nested.append(QueryTokens.expression(ctx.AS()));
+ nested.appendExpression(visit(ctx.subtype()));
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendInline(visit(ctx.general_subpath()));
- builder.append(QueryTokens.expression(ctx.AS()));
- builder.appendInline(visit(ctx.subtype()));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -544,7 +566,7 @@ public QueryTokenStream visitNew_value(JpqlParser.New_valueContext ctx) {
} else if (ctx.simple_entity_expression() != null) {
return visit(ctx.simple_entity_expression());
} else if (ctx.NULL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.NULL()));
+ return QueryTokenStream.ofToken(ctx.NULL());
} else {
return QueryTokenStream.empty();
}
@@ -791,8 +813,7 @@ public QueryTokenStream visitOrderby_item(JpqlParser.Orderby_itemContext ctx) {
if (ctx.ASC() != null) {
builder.append(QueryTokens.expression(ctx.ASC()));
- }
- if (ctx.DESC() != null) {
+ } else if (ctx.DESC() != null) {
builder.append(QueryTokens.expression(ctx.DESC()));
}
@@ -808,12 +829,44 @@ public QueryTokenStream visitNullsPrecedence(NullsPrecedenceContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(TOKEN_NULLS);
+ builder.append(QueryTokens.expression(ctx.NULLS()));
if (ctx.FIRST() != null) {
- builder.append(TOKEN_FIRST);
+ builder.append(QueryTokens.expression(ctx.FIRST()));
} else if (ctx.LAST() != null) {
- builder.append(TOKEN_LAST);
+ builder.append(QueryTokens.expression(ctx.LAST()));
+ }
+
+ return builder;
+ }
+
+ @Override
+ public QueryTokenStream visitSet_fuction(Set_fuctionContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ if (ctx.setOperator() != null) {
+ builder.append(visit(ctx.setOperator()));
+ }
+
+ builder.appendExpression(visit(ctx.select_statement()));
+
+ return builder;
+ }
+
+ @Override
+ public QueryTokenStream visitSetOperator(JpqlParser.SetOperatorContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ if (ctx.INTERSECT() != null) {
+ builder.append(QueryTokens.expression(ctx.INTERSECT()));
+ } else if (ctx.UNION() != null) {
+ builder.append(QueryTokens.expression(ctx.UNION()));
+ } else if (ctx.EXCEPT() != null) {
+ builder.append(QueryTokens.expression(ctx.EXCEPT()));
+ } else if (ctx.ALL() != null) {
+ builder.append(QueryTokens.expression(ctx.ALL()));
}
return builder;
@@ -931,6 +984,8 @@ public QueryTokenStream visitScalar_expression(JpqlParser.Scalar_expressionConte
return visit(ctx.case_expression());
} else if (ctx.entity_type_expression() != null) {
return visit(ctx.entity_type_expression());
+ } else if (ctx.cast_function() != null) {
+ return (visit(ctx.cast_function()));
}
return QueryTokenStream.empty();
@@ -1154,9 +1209,11 @@ public QueryTokenStream visitNull_comparison_expression(JpqlParser.Null_comparis
}
builder.append(QueryTokens.expression(ctx.IS()));
+
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
}
+
builder.append(QueryTokens.expression(ctx.NULL()));
return builder;
@@ -1339,7 +1396,7 @@ public QueryTokenStream visitComparison_expression(JpqlParser.Comparison_express
@Override
public QueryTokenStream visitComparison_operator(JpqlParser.Comparison_operatorContext ctx) {
- return QueryRenderer.from(QueryTokens.token(ctx.op));
+ return QueryTokenStream.ofToken(ctx.op);
}
@Override
@@ -1410,6 +1467,8 @@ public QueryTokenStream visitArithmetic_primary(JpqlParser.Arithmetic_primaryCon
builder.append(visit(ctx.aggregate_expression()));
} else if (ctx.case_expression() != null) {
builder.append(visit(ctx.case_expression()));
+ } else if (ctx.cast_function() != null) {
+ builder.append(visit(ctx.cast_function()));
} else if (ctx.function_invocation() != null) {
builder.append(visit(ctx.function_invocation()));
} else if (ctx.subquery() != null) {
@@ -1446,6 +1505,11 @@ public QueryTokenStream visitString_expression(JpqlParser.String_expressionConte
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.subquery()));
builder.append(TOKEN_CLOSE_PAREN);
+ } else if (!ObjectUtils.isEmpty(ctx.string_expression())) {
+
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_DOUBLE_PIPE);
+ builder.appendExpression(visit(ctx.string_expression(1)));
}
return builder;
@@ -1689,6 +1753,8 @@ public QueryTokenStream visitFunctions_returning_numerics(JpqlParser.Functions_r
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.identification_variable()));
builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.extract_datetime_field() != null) {
+ builder.append(visit(ctx.extract_datetime_field()));
}
return builder;
@@ -1716,6 +1782,8 @@ public QueryTokenStream visitFunctions_returning_datetime(JpqlParser.Functions_r
} else if (ctx.DATETIME() != null) {
builder.append(QueryTokens.expression(ctx.DATETIME()));
}
+ } else if (ctx.extract_datetime_part() != null) {
+ builder.append(visit(ctx.extract_datetime_part()));
}
return builder;
@@ -1737,22 +1805,26 @@ public QueryTokenStream visitFunctions_returning_strings(JpqlParser.Functions_re
builder.append(QueryTokens.token(ctx.SUBSTRING()));
builder.append(TOKEN_OPEN_PAREN);
builder.append(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
builder.appendInline(QueryTokenStream.concat(ctx.arithmetic_expression(), this::visit, TOKEN_COMMA));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.TRIM() != null) {
builder.append(QueryTokens.token(ctx.TRIM()));
builder.append(TOKEN_OPEN_PAREN);
+
+ QueryRendererBuilder nested = QueryRenderer.builder();
if (ctx.trim_specification() != null) {
- builder.appendExpression(visit(ctx.trim_specification()));
+ nested.appendExpression(visit(ctx.trim_specification()));
}
if (ctx.trim_character() != null) {
- builder.appendExpression(visit(ctx.trim_character()));
+ nested.appendExpression(visit(ctx.trim_character()));
}
if (ctx.FROM() != null) {
- builder.append(QueryTokens.expression(ctx.FROM()));
+ nested.append(QueryTokens.expression(ctx.FROM()));
}
- builder.append(visit(ctx.string_expression(0)));
+ nested.append(visit(ctx.string_expression(0)));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.LOWER() != null) {
@@ -1766,6 +1838,29 @@ public QueryTokenStream visitFunctions_returning_strings(JpqlParser.Functions_re
builder.append(TOKEN_OPEN_PAREN);
builder.append(visit(ctx.string_expression(0)));
builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.LEFT() != null) {
+ builder.append(QueryTokens.token(ctx.LEFT()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.arithmetic_expression(0)));
+ builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.RIGHT() != null) {
+ builder.append(QueryTokens.token(ctx.RIGHT()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.arithmetic_expression(0)));
+ builder.append(TOKEN_CLOSE_PAREN);
+ } else if (ctx.REPLACE() != null) {
+ builder.append(QueryTokens.token(ctx.REPLACE()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(visit(ctx.string_expression(0)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.string_expression(1)));
+ builder.append(TOKEN_COMMA);
+ builder.appendInline(visit(ctx.string_expression(2)));
+ builder.append(TOKEN_CLOSE_PAREN);
}
return builder;
@@ -1775,14 +1870,36 @@ public QueryTokenStream visitFunctions_returning_strings(JpqlParser.Functions_re
public QueryTokenStream visitTrim_specification(JpqlParser.Trim_specificationContext ctx) {
if (ctx.LEADING() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.LEADING()));
+ return QueryTokenStream.ofToken(ctx.LEADING());
} else if (ctx.TRAILING() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.TRAILING()));
+ return QueryTokenStream.ofToken(ctx.TRAILING());
} else {
- return QueryRenderer.from(QueryTokens.expression(ctx.BOTH()));
+ return QueryTokenStream.ofToken(ctx.BOTH());
}
}
+ @Override
+ public QueryTokenStream visitCast_function(JpqlParser.Cast_functionContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+
+ builder.append(QueryTokens.token(ctx.CAST()));
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(visit(ctx.single_valued_path_expression()));
+ builder.append(TOKEN_SPACE);
+ builder.appendInline(QueryTokenStream.concat(ctx.identification_variable(), this::visit, TOKEN_SPACE));
+
+ if (!ObjectUtils.isEmpty(ctx.numeric_literal())) {
+
+ builder.append(TOKEN_OPEN_PAREN);
+ builder.appendInline(QueryTokenStream.concat(ctx.numeric_literal(), this::visit, TOKEN_COMMA));
+ builder.append(TOKEN_CLOSE_PAREN);
+ }
+ builder.append(TOKEN_CLOSE_PAREN);
+
+ return builder;
+ }
+
@Override
public QueryTokenStream visitFunction_invocation(JpqlParser.Function_invocationContext ctx) {
@@ -1804,12 +1921,15 @@ public QueryTokenStream visitFunction_invocation(JpqlParser.Function_invocationC
public QueryTokenStream visitExtract_datetime_field(JpqlParser.Extract_datetime_fieldContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
+ nested.appendExpression(visit(ctx.datetime_field()));
+ nested.append(QueryTokens.expression(ctx.FROM()));
+ nested.appendExpression(visit(ctx.datetime_expression()));
- builder.append(QueryTokens.expression(ctx.EXTRACT()));
+ builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendExpression(visit(ctx.datetime_field()));
- builder.append(QueryTokens.expression(ctx.FROM()));
- builder.appendInline(visit(ctx.datetime_expression()));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -1824,12 +1944,15 @@ public QueryTokenStream visitDatetime_field(JpqlParser.Datetime_fieldContext ctx
public QueryTokenStream visitExtract_datetime_part(JpqlParser.Extract_datetime_partContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
+ QueryRendererBuilder nested = QueryRenderer.builder();
+
+ nested.appendExpression(visit(ctx.datetime_part()));
+ nested.append(QueryTokens.expression(ctx.FROM()));
+ nested.appendExpression(visit(ctx.datetime_expression()));
- builder.append(QueryTokens.expression(ctx.EXTRACT()));
+ builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
- builder.appendExpression(visit(ctx.datetime_part()));
- builder.append(QueryTokens.expression(ctx.FROM()));
- builder.append(visit(ctx.datetime_expression()));
+ builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -1868,6 +1991,14 @@ public QueryTokenStream visitCase_expression(JpqlParser.Case_expressionContext c
}
}
+ @Override
+ public QueryRendererBuilder visitType_literal(Type_literalContext ctx) {
+
+ QueryRendererBuilder builder = QueryRenderer.builder();
+ ctx.children.forEach(it -> builder.append(QueryTokens.expression(it.getText())));
+ return builder;
+ }
+
@Override
public QueryTokenStream visitGeneral_case_expression(JpqlParser.General_case_expressionContext ctx) {
@@ -1953,7 +2084,7 @@ public QueryTokenStream visitNullif_expression(JpqlParser.Nullif_expressionConte
QueryRendererBuilder builder = QueryRenderer.builder();
- builder.append(QueryTokens.expression(ctx.NULLIF()));
+ builder.append(QueryTokens.token(ctx.NULLIF()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.scalar_expression(0)));
builder.append(TOKEN_COMMA);
@@ -1967,7 +2098,7 @@ public QueryTokenStream visitNullif_expression(JpqlParser.Nullif_expressionConte
public QueryTokenStream visitTrim_character(JpqlParser.Trim_characterContext ctx) {
if (ctx.CHARACTER() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
} else if (ctx.character_valued_input_parameter() != null) {
return visit(ctx.character_valued_input_parameter());
} else {
@@ -1979,9 +2110,11 @@ public QueryTokenStream visitTrim_character(JpqlParser.Trim_characterContext ctx
public QueryTokenStream visitIdentification_variable(JpqlParser.Identification_variableContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
+ return QueryTokenStream.ofToken(ctx.IDENTIFICATION_VARIABLE());
+ } else if (ctx.type_literal() != null) {
+ return visit(ctx.type_literal());
} else if (ctx.f != null) {
- return QueryRenderer.from(QueryTokens.token(ctx.f));
+ return QueryTokenStream.ofToken(ctx.f);
} else {
return QueryTokenStream.empty();
}
@@ -1996,15 +2129,15 @@ public QueryTokenStream visitConstructor_name(JpqlParser.Constructor_nameContext
public QueryTokenStream visitLiteral(JpqlParser.LiteralContext ctx) {
if (ctx.STRINGLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.STRINGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRINGLITERAL());
} else if (ctx.JAVASTRINGLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.JAVASTRINGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.JAVASTRINGLITERAL());
} else if (ctx.INTLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.INTLITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTLITERAL());
} else if (ctx.FLOATLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.FLOATLITERAL()));
+ return QueryTokenStream.ofToken(ctx.FLOATLITERAL());
} else if (ctx.LONGLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.LONGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.LONGLITERAL());
} else if (ctx.boolean_literal() != null) {
return visit(ctx.boolean_literal());
} else if (ctx.entity_type_literal() != null) {
@@ -2039,7 +2172,18 @@ public QueryTokenStream visitPattern_value(JpqlParser.Pattern_valueContext ctx)
@Override
public QueryTokenStream visitDate_time_timestamp_literal(JpqlParser.Date_time_timestamp_literalContext ctx) {
- return QueryRenderer.from(QueryTokens.expression(ctx.STRINGLITERAL()));
+
+ if (ctx.STRINGLITERAL() != null) {
+ return QueryTokenStream.ofToken(ctx.STRINGLITERAL());
+ } else if (ctx.DATELITERAL() != null) {
+ return QueryTokenStream.ofToken(ctx.DATELITERAL());
+ } else if (ctx.TIMELITERAL() != null) {
+ return QueryTokenStream.ofToken(ctx.TIMELITERAL());
+ } else if (ctx.TIMESTAMPLITERAL() != null) {
+ return QueryTokenStream.ofToken(ctx.TIMESTAMPLITERAL());
+ } else {
+ return QueryRenderer.builder();
+ }
}
@Override
@@ -2049,18 +2193,18 @@ public QueryTokenStream visitEntity_type_literal(JpqlParser.Entity_type_literalC
@Override
public QueryTokenStream visitEscape_character(JpqlParser.Escape_characterContext ctx) {
- return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
}
@Override
public QueryTokenStream visitNumeric_literal(JpqlParser.Numeric_literalContext ctx) {
if (ctx.INTLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.token(ctx.INTLITERAL()));
+ return QueryTokenStream.ofToken(ctx.INTLITERAL());
} else if (ctx.FLOATLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.token(ctx.FLOATLITERAL()));
+ return QueryTokenStream.ofToken(ctx.FLOATLITERAL());
} else if (ctx.LONGLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.token(ctx.LONGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.LONGLITERAL());
} else {
return QueryTokenStream.empty();
}
@@ -2070,9 +2214,9 @@ public QueryTokenStream visitNumeric_literal(JpqlParser.Numeric_literalContext c
public QueryTokenStream visitBoolean_literal(JpqlParser.Boolean_literalContext ctx) {
if (ctx.TRUE() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.TRUE()));
+ return QueryTokenStream.ofToken(ctx.TRUE());
} else if (ctx.FALSE() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.FALSE()));
+ return QueryTokenStream.ofToken(ctx.FALSE());
} else {
return QueryTokenStream.empty();
}
@@ -2087,9 +2231,9 @@ public QueryTokenStream visitEnum_literal(JpqlParser.Enum_literalContext ctx) {
public QueryTokenStream visitString_literal(JpqlParser.String_literalContext ctx) {
if (ctx.CHARACTER() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
} else if (ctx.STRINGLITERAL() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.STRINGLITERAL()));
+ return QueryTokenStream.ofToken(ctx.STRINGLITERAL());
} else {
return QueryTokenStream.empty();
}
@@ -2128,7 +2272,7 @@ public QueryTokenStream visitCollection_value_field(JpqlParser.Collection_value_
@Override
public QueryTokenStream visitEntity_name(JpqlParser.Entity_nameContext ctx) {
- return QueryTokenStream.concat(ctx.reserved_word(), this::visitReserved_word, TOKEN_DOT);
+ return QueryTokenStream.concat(ctx.reserved_word(), this::visit, TOKEN_DOT);
}
@Override
@@ -2163,7 +2307,7 @@ public QueryTokenStream visitCharacter_valued_input_parameter(
JpqlParser.Character_valued_input_parameterContext ctx) {
if (ctx.CHARACTER() != null) {
- return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
+ return QueryTokenStream.ofToken(ctx.CHARACTER());
} else if (ctx.input_parameter() != null) {
return visit(ctx.input_parameter());
} else {
@@ -2174,9 +2318,9 @@ public QueryTokenStream visitCharacter_valued_input_parameter(
@Override
public QueryTokenStream visitReserved_word(Reserved_wordContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
- return QueryRenderer.from(QueryTokens.token(ctx.IDENTIFICATION_VARIABLE()));
+ return QueryTokenStream.ofToken(ctx.IDENTIFICATION_VARIABLE());
} else if (ctx.f != null) {
- return QueryRenderer.from(QueryTokens.token(ctx.f));
+ return QueryTokenStream.ofToken(ctx.f);
} else {
return QueryTokenStream.empty();
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlSortedQueryTransformer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlSortedQueryTransformer.java
index a545171bbf..196fbcff1e 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlSortedQueryTransformer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlSortedQueryTransformer.java
@@ -67,7 +67,11 @@ public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext
builder.appendExpression(visit(ctx.having_clause()));
}
- doVisitOrderBy(builder, ctx);
+ if(ctx.set_fuction() != null) {
+ builder.appendExpression(visit(ctx.set_fuction()));
+ } else {
+ doVisitOrderBy(builder, ctx);
+ }
return builder;
}
@@ -105,7 +109,7 @@ public QueryTokenStream visitSelect_item(JpqlParser.Select_itemContext ctx) {
QueryTokenStream tokens = super.visitSelect_item(ctx);
if (ctx.result_variable() != null && !tokens.isEmpty()) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
@@ -117,9 +121,10 @@ public QueryTokenStream visitJoin(JpqlParser.JoinContext ctx) {
QueryTokenStream tokens = super.visitJoin(ctx);
if (!tokens.isEmpty()) {
- transformerSupport.registerAlias(tokens.getLast());
+ transformerSupport.registerAlias(tokens.getRequiredLast());
}
return tokens;
}
+
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java
index 5d4d8acb5f..a9f38dcebc 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java
@@ -138,7 +138,7 @@ public Sort createSort(Sort sort, JpaEntityInformation, ?> entity) {
}
/**
- * Reverse scrolling variant applying {@link Direction#Backward}. In reverse scrolling, we need to flip directions for
+ * Reverse scrolling variant applying {@link Direction#BACKWARD}. In reverse scrolling, we need to flip directions for
* the actual query so that we do not get everything from the top position and apply the limit but rather flip the
* sort direction, apply the limit and then reverse the result to restore the actual sort order.
*/
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java
index 259343e9c7..ecd4d63ee0 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java
@@ -653,7 +653,7 @@ static MethodInvocationArgument ofParameter(@Nullable String name, @Nullable Int
/**
* Creates a {@link MethodInvocationArgument} object for {@code position}.
*
- * @param position the parameter position (1-based) from the method invocation.
+ * @param parameter the parameter from the method invocation.
* @return {@link MethodInvocationArgument} object for {@code position}.
*/
static MethodInvocationArgument ofParameter(Parameter parameter) {
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java
index de3256baa3..9fd7817a7e 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java
@@ -273,17 +273,12 @@ public Object prepare(@Nullable Object value) {
if (String.class.equals(parameterType) && !noWildcards) {
- switch (type) {
- case STARTING_WITH:
- return String.format("%s%%", escape.escape(value.toString()));
- case ENDING_WITH:
- return String.format("%%%s", escape.escape(value.toString()));
- case CONTAINING:
- case NOT_CONTAINING:
- return String.format("%%%s%%", escape.escape(value.toString()));
- default:
- return value;
- }
+ return switch (type) {
+ case STARTING_WITH -> String.format("%s%%", escape.escape(value.toString()));
+ case ENDING_WITH -> String.format("%%%s", escape.escape(value.toString()));
+ case CONTAINING, NOT_CONTAINING -> String.format("%%%s%%", escape.escape(value.toString()));
+ default -> value;
+ };
}
return Collection.class.isAssignableFrom(parameterType) //
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java
index 4844060aa3..4b5f530d0b 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java
@@ -93,7 +93,6 @@ static QueryParameterSetterFactory forSynthetic() {
*
* @param parser must not be {@literal null}.
* @param evaluationContextProvider must not be {@literal null}.
- * @param parameters must not be {@literal null}.
* @return a {@link QueryParameterSetterFactory} that can handle
* {@link org.springframework.expression.spel.standard.SpelExpression}s.
*/
@@ -170,7 +169,6 @@ private static class ExpressionBasedQueryParameterSetterFactory extends QueryPar
/**
* @param parser must not be {@literal null}.
* @param evaluationContextProvider must not be {@literal null}.
- * @param parameters must not be {@literal null}.
*/
ExpressionBasedQueryParameterSetterFactory(ValueExpressionParser parser,
ValueEvaluationContextProvider evaluationContextProvider) {
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryRenderer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryRenderer.java
index 87fe53e050..6d116a33c9 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryRenderer.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryRenderer.java
@@ -20,9 +20,9 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.function.Function;
import java.util.stream.Stream;
+import org.springframework.lang.Nullable;
import org.springframework.util.CompositeIterator;
/**
@@ -44,9 +44,6 @@ abstract class QueryRenderer implements QueryTokenStream {
/**
* Creates a QueryRenderer from a {@link QueryToken}.
- *
- * @param token
- * @return
*/
static QueryRenderer from(QueryToken token) {
return QueryRenderer.from(Collections.singletonList(token));
@@ -54,9 +51,6 @@ static QueryRenderer from(QueryToken token) {
/**
* Creates a QueryRenderer from a collection of {@link QueryToken}.
- *
- * @param tokens
- * @return
*/
static QueryRenderer from(Collection extends QueryToken> tokens) {
List tokensToUse = new ArrayList<>(Math.max(tokens.size(), 32));
@@ -66,9 +60,6 @@ static QueryRenderer from(Collection extends QueryToken> tokens) {
/**
* Creates a QueryRenderer from a {@link QueryTokenStream}.
- *
- * @param tokens
- * @return
*/
static QueryRenderer from(QueryTokenStream tokens) {
@@ -85,8 +76,6 @@ static QueryRenderer from(QueryTokenStream tokens) {
/**
* Creates a new empty {@link QueryRenderer}.
- *
- * @return
*/
public static QueryRenderer empty() {
return EmptyQueryRenderer.INSTANCE;
@@ -94,8 +83,6 @@ public static QueryRenderer empty() {
/**
* Creates a new {@link QueryRendererBuilder}.
- *
- * @return
*/
static QueryRendererBuilder builder() {
return new QueryRendererBuilder();
@@ -144,14 +131,11 @@ static String render(Iterable tokenStream) {
results.append(token.value());
}
- return results.toString();
+ return results != null ? results.toString() : "";
}
/**
* Append a {@link QueryRenderer} to create a composed renderer.
- *
- * @param tokens
- * @return
*/
QueryRenderer append(QueryTokenStream tokens) {
@@ -180,7 +164,7 @@ public String toString() {
return render();
}
- public static QueryRenderer expression(QueryTokenStream tokenStream) {
+ public static QueryRenderer ofExpression(QueryTokenStream tokenStream) {
if (tokenStream instanceof QueryRendererBuilder builder) {
tokenStream = builder.current;
@@ -258,9 +242,6 @@ String render() {
/**
* Append a {@link QueryRenderer} to create a composed renderer.
- *
- * @param tokens
- * @return
*/
QueryRenderer append(QueryTokenStream tokens) {
@@ -290,6 +271,7 @@ QueryRenderer append(QueryTokenStream tokens) {
}
@Override
+ @Nullable
public QueryToken getLast() {
for (int i = nested.size() - 1; i > -1; i--) {
@@ -386,11 +368,13 @@ public List toList() {
}
@Override
+ @Nullable
public QueryToken getFirst() {
return tokens.isEmpty() ? null : tokens.get(0);
}
@Override
+ @Nullable
public QueryToken getLast() {
return tokens.isEmpty() ? null : tokens.get(tokens.size() - 1);
}
@@ -407,7 +391,7 @@ public boolean isEmpty() {
@Override
public boolean isExpression() {
- return !tokens.isEmpty() && getLast().isExpression();
+ return !tokens.isEmpty() && getRequiredLast().isExpression();
}
/**
@@ -418,7 +402,7 @@ public boolean isExpression() {
*/
static String render(Object tokens) {
- if (tokens instanceof Collection tpr) {
+ if (tokens instanceof Collection> tpr) {
return render(tpr);
}
@@ -454,11 +438,13 @@ public Iterator iterator() {
}
@Override
+ @Nullable
public QueryToken getFirst() {
return tokens.getFirst();
}
@Override
+ @Nullable
public QueryToken getLast() {
return tokens.getLast();
}
@@ -475,7 +461,7 @@ public boolean isEmpty() {
@Override
public boolean isExpression() {
- return !tokens.isEmpty() && tokens.getLast().isExpression();
+ return !tokens.isEmpty() && tokens.getRequiredLast().isExpression();
}
}
@@ -486,68 +472,13 @@ static class QueryRendererBuilder implements QueryTokenStream {
protected QueryRenderer current = QueryRenderer.empty();
- /**
- * Compose a {@link QueryRendererBuilder} from a collection of inline elements that can be mapped to
- * {@link QueryRendererBuilder}.
- *
- * @param elements
- * @param visitor
- * @param separator
- * @return
- * @param
- */
- public static QueryRendererBuilder concat(Collection elements, Function visitor,
- QueryToken separator) {
- return concat(elements, visitor, QueryRendererBuilder::toInline, separator);
- }
-
- /**
- * Compose a {@link QueryRendererBuilder} from a collection of expression elements that can be mapped to
- * {@link QueryRendererBuilder}.
- *
- * @param elements
- * @param visitor
- * @param separator
- * @return
- * @param
- */
- public static QueryRendererBuilder concatExpressions(Collection elements,
- Function visitor, QueryToken separator) {
- return concat(elements, visitor, QueryRendererBuilder::toExpression, separator);
- }
-
- /**
- * Compose a {@link QueryRendererBuilder} from a collection of elements that can be mapped to
- * {@link QueryRendererBuilder}.
- *
- * @param elements
- * @param visitor
- * @param postProcess post-processing function to convert {@link QueryRendererBuilder} into {@link QueryRenderer}.
- * @param separator
- * @return
- * @param
- */
- public static QueryRendererBuilder concat(Collection elements, Function visitor,
- Function postProcess, QueryToken separator) {
-
- QueryRendererBuilder builder = new QueryRendererBuilder();
- for (T element : elements) {
- if (!builder.isEmpty()) {
- builder.append(separator);
- }
- builder.append(postProcess.apply(visitor.apply(element)));
- }
-
- return builder;
- }
-
/**
* Create and initialize a QueryRendererBuilder from a {@link QueryTokens.SimpleQueryToken}.
*
* @param token
* @return
*/
- public static QueryRendererBuilder from(QueryToken token) {
+ public static QueryRendererBuilder builder(QueryToken token) {
return new QueryRendererBuilder().append(token);
}
@@ -627,7 +558,7 @@ QueryRendererBuilder appendExpression(QueryTokenStream tokens) {
return this;
}
- current = current.append(QueryRenderer.expression(tokens));
+ current = current.append(QueryRenderer.ofExpression(tokens));
return this;
}
@@ -643,11 +574,13 @@ public Stream stream() {
}
@Override
+ @Nullable
public QueryToken getFirst() {
return current.getFirst();
}
@Override
+ @Nullable
public QueryToken getLast() {
return current.getLast();
}
@@ -657,11 +590,6 @@ public boolean isExpression() {
return current.isExpression();
}
- /**
- * Return whet the builder is empty.
- *
- * @return
- */
@Override
public boolean isEmpty() {
return current.isEmpty();
@@ -686,19 +614,6 @@ public QueryRenderer build() {
return current;
}
- QueryRenderer toExpression() {
-
- if (current instanceof ExpressionRenderer) {
- return current;
- }
-
- return QueryRenderer.expression(current);
- }
-
- public QueryRenderer toInline() {
- return new InlineRenderer(current);
- }
-
}
private static class InlineRenderer extends QueryRenderer {
@@ -730,11 +645,13 @@ public Iterator iterator() {
}
@Override
+ @Nullable
public QueryToken getFirst() {
return delegate.getFirst();
}
@Override
+ @Nullable
public QueryToken getLast() {
return delegate.getLast();
}
@@ -784,11 +701,13 @@ public Iterator iterator() {
}
@Override
+ @Nullable
public QueryToken getFirst() {
return delegate.getFirst();
}
@Override
+ @Nullable
public QueryToken getLast() {
return delegate.getLast();
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java
index 233711d797..9b97836ab9 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java
@@ -16,10 +16,14 @@
package org.springframework.data.jpa.repository.query;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.NoSuchElementException;
import java.util.function.Function;
-import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
import org.springframework.data.util.Streamable;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
@@ -35,13 +39,35 @@ interface QueryTokenStream extends Streamable {
/**
* Creates an empty stream.
- *
- * @return
*/
static QueryTokenStream empty() {
return EmptyQueryTokenStream.INSTANCE;
}
+ /**
+ * Creates a QueryTokenStream from a {@link QueryToken}.
+ * @since 4.0
+ */
+ static QueryTokenStream from(QueryToken token) {
+ return QueryRenderer.from(Collections.singletonList(token));
+ }
+
+ /**
+ * Creates an token QueryRenderer from an AST {@link TerminalNode}.
+ * @since 4.0
+ */
+ static QueryTokenStream ofToken(TerminalNode node) {
+ return from(QueryTokens.token(node));
+ }
+
+ /**
+ * Creates an token QueryRenderer from an AST {@link Token}.
+ * @since 4.0
+ */
+ static QueryTokenStream ofToken(Token node) {
+ return from(QueryTokens.token(node));
+ }
+
/**
* Compose a {@link QueryTokenStream} from a collection of inline elements.
*
@@ -55,10 +81,6 @@ static QueryTokenStream concat(Collection elements, Function QueryTokenStream justAs(Collection elements, Function converter) {
- return concat(elements, it-> QueryRendererBuilder.from(converter.apply(it)), QueryRenderer::inline, QueryTokens.TOKEN_SPACE);
- }
-
/**
* Compose a {@link QueryTokenStream} from a collection of expression elements.
*
@@ -69,7 +91,7 @@ static QueryTokenStream justAs(Collection elements, Function QueryTokenStream concatExpressions(Collection elements, Function visitor,
QueryToken separator) {
- return concat(elements, visitor, QueryRenderer::expression, separator);
+ return concat(elements, visitor, QueryRenderer::ofExpression, separator);
}
/**
@@ -127,6 +149,21 @@ default QueryToken getFirst() {
return it.hasNext() ? it.next() : null;
}
+ /**
+ * @return the required first query token or throw {@link java.util.NoSuchElementException} if empty.
+ * @since 4.0
+ */
+ default QueryToken getRequiredFirst() {
+
+ QueryToken first = getFirst();
+
+ if (first == null) {
+ throw new NoSuchElementException("No token in the stream");
+ }
+
+ return first;
+ }
+
/**
* @return the last query token or {@code null} if empty.
*/
@@ -135,6 +172,21 @@ default QueryToken getLast() {
return CollectionUtils.lastElement(toList());
}
+ /**
+ * @return the required last query token or throw {@link java.util.NoSuchElementException} if empty.
+ * @since 4.0
+ */
+ default QueryToken getRequiredLast() {
+
+ QueryToken last = getLast();
+
+ if (last == null) {
+ throw new NoSuchElementException("No token in the stream");
+ }
+
+ return last;
+ }
+
/**
* @return {@code true} if this stream represents a query expression.
*/
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokens.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokens.java
index 80df0b3300..cfbaf20ba8 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokens.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokens.java
@@ -31,7 +31,6 @@ class QueryTokens {
/**
* Commonly use tokens.
*/
- static final QueryToken TOKEN_NONE = token("");
static final QueryToken TOKEN_COMMA = token(", ");
static final QueryToken TOKEN_SPACE = token(" ");
static final QueryToken TOKEN_DOT = token(".");
@@ -56,15 +55,9 @@ class QueryTokens {
static final QueryToken TOKEN_WITH = expression("WITH");
static final QueryToken TOKEN_NOT = expression("NOT");
static final QueryToken TOKEN_MATERIALIZED = expression("materialized");
- static final QueryToken TOKEN_NULLS = expression("NULLS");
- static final QueryToken TOKEN_FIRST = expression("FIRST");
- static final QueryToken TOKEN_LAST = expression("LAST");
/**
* Creates a {@link QueryToken token} from an ANTLR {@link TerminalNode}.
- *
- * @param node
- * @return
*/
static QueryToken token(TerminalNode node) {
return token(node.getText());
@@ -72,9 +65,6 @@ static QueryToken token(TerminalNode node) {
/**
* Creates a {@link QueryToken token} from an ANTLR {@link Token}.
- *
- * @param token
- * @return
*/
static QueryToken token(Token token) {
return token(token.getText());
@@ -82,9 +72,6 @@ static QueryToken token(Token token) {
/**
* Creates a {@link QueryToken token} from a string {@code token}.
- *
- * @param token
- * @return
*/
static QueryToken token(String token) {
return new SimpleQueryToken(token);
@@ -92,9 +79,6 @@ static QueryToken token(String token) {
/**
* Creates a ventilated token that is embedded in spaces.
- *
- * @param token
- * @return
*/
static QueryToken ventilated(Token token) {
return new SimpleQueryToken(" " + token.getText() + " ");
@@ -102,9 +86,6 @@ static QueryToken ventilated(Token token) {
/**
* Creates a {@link QueryToken expression} from an ANTLR {@link TerminalNode}.
- *
- * @param node
- * @return
*/
static QueryToken expression(TerminalNode node) {
return expression(node.getText());
@@ -112,9 +93,6 @@ static QueryToken expression(TerminalNode node) {
/**
* Creates a {@link QueryToken expression} from an ANTLR {@link Token}.
- *
- * @param token
- * @return
*/
static QueryToken expression(Token token) {
return expression(token.getText());
@@ -122,9 +100,6 @@ static QueryToken expression(Token token) {
/**
* Creates a {@link QueryToken token} from a string {@code expression}.
- *
- * @param expression
- * @return
*/
static QueryToken expression(String expression) {
return new ExpressionToken(expression);
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java
index e625c9460f..302da71f18 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java
@@ -29,6 +29,7 @@
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
+import jakarta.persistence.criteria.Nulls;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.Attribute.PersistentAttributeType;
@@ -292,9 +293,8 @@ public static String applySorting(String query, Sort sort, @Nullable String alia
Set selectionAliases = getFunctionAliases(query);
selectionAliases.addAll(getFieldAliases(query));
- String orderClauses = sort.stream()
- .map(order -> getOrderClause(joinAliases, selectionAliases, alias, order))
- .collect(Collectors.joining(", "));
+ String orderClauses = sort.stream().map(order -> getOrderClause(joinAliases, selectionAliases, alias, order))
+ .collect(Collectors.joining(", "));
builder.append(orderClauses);
@@ -753,18 +753,25 @@ private static jakarta.persistence.criteria.Order toJpaOrder(Order order, From
PropertyPath property = PropertyPath.from(order.getProperty(), from.getJavaType());
Expression> expression = toExpressionRecursively(from, property);
- if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
- throw new UnsupportedOperationException("Applying Null Precedence using Criteria Queries is not yet supported.");
- }
+ Nulls nulls = toNulls(order.getNullHandling());
if (order.isIgnoreCase() && String.class.equals(expression.getJavaType())) {
Expression upper = cb.lower((Expression) expression);
- return order.isAscending() ? cb.asc(upper) : cb.desc(upper);
+ return order.isAscending() ? cb.asc(upper, nulls) : cb.desc(upper, nulls);
} else {
- return order.isAscending() ? cb.asc(expression) : cb.desc(expression);
+ return order.isAscending() ? cb.asc(expression, nulls) : cb.desc(expression, nulls);
}
}
+ private static Nulls toNulls(Sort.NullHandling nullHandling) {
+
+ return switch (nullHandling) {
+ case NULLS_LAST -> Nulls.LAST;
+ case NULLS_FIRST -> Nulls.FIRST;
+ case NATIVE -> Nulls.NONE;
+ };
+ }
+
static Expression toExpressionRecursively(From, ?> from, PropertyPath property) {
return toExpressionRecursively(from, property, false);
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java
index 16fa3c30e0..b044191b54 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java
@@ -84,23 +84,13 @@ private void validateQuery(String query, String errorMessage, Object... argument
return;
}
- EntityManager validatingEm = null;
-
- try {
- validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager();
- validatingEm.createQuery(query);
-
- } catch (RuntimeException e) {
-
- // Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider
- // https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17
- throw new IllegalArgumentException(String.format(errorMessage, arguments), e);
-
- } finally {
-
- if (validatingEm != null) {
- validatingEm.close();
- }
- }
+ try (EntityManager validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager()) {
+ validatingEm.createQuery(query);
+ } catch (RuntimeException e) {
+
+ // Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider
+ // https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17
+ throw new IllegalArgumentException(String.format(errorMessage, arguments), e);
+ }
}
}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java
index 471ede0403..e531262ce1 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java
@@ -304,25 +304,17 @@ String parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(String que
: ParameterOrigin.ofExpression(expression);
BindingIdentifier targetBinding = queryParameter;
- Function bindingFactory;
- switch (ParameterBindingType.of(typeSource)) {
+ Function bindingFactory = switch (ParameterBindingType.of(typeSource)) {
+ case LIKE -> {
- case LIKE:
+ Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2));
+ yield (identifier) -> new LikeParameterBinding(identifier, origin, likeType);
+ }
+ case IN -> (identifier) -> new InParameterBinding(identifier, origin); // fall-through we don't need a special parameter queryParameter for the given parameter.
+ default -> (identifier) -> new ParameterBinding(identifier, origin);
+ };
- Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2));
- bindingFactory = (identifier) -> new LikeParameterBinding(identifier, origin, likeType);
- break;
-
- case IN:
- bindingFactory = (identifier) -> new InParameterBinding(identifier, origin);
- break;
-
- case AS_IS: // fall-through we don't need a special parameter queryParameter for the given parameter.
- default:
- bindingFactory = (identifier) -> new ParameterBinding(identifier, origin);
- }
-
- if (origin.isExpression()) {
+ if (origin.isExpression()) {
parameterBindings.register(bindingFactory.apply(queryParameter));
} else {
targetBinding = parameterBindings.register(queryParameter, origin, bindingFactory);
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java
index 1036ce24dd..457f4a1104 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java
@@ -19,7 +19,6 @@
import jakarta.persistence.EntityManager;
import jakarta.persistence.LockModeType;
-import jakarta.persistence.NoResultException;
import jakarta.persistence.Parameter;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
@@ -433,12 +432,7 @@ public Page findAll(Pageable pageable) {
@Override
public Optional findOne(Specification spec) {
-
- try {
- return Optional.of(getQuery(spec, Sort.unsorted()).setMaxResults(2).getSingleResult());
- } catch (NoResultException e) {
- return Optional.empty();
- }
+ return Optional.ofNullable(getQuery(spec, Sort.unsorted()).setMaxResults(2).getSingleResultOrNull());
}
@Override
@@ -540,13 +534,10 @@ private R doFindBy(Specification spec, Class domainClass,
@Override
public Optional findOne(Example example) {
- try {
- return Optional
- .of(getQuery(new ExampleSpecification<>(example, escapeCharacter), example.getProbeType(), Sort.unsorted())
- .setMaxResults(2).getSingleResult());
- } catch (NoResultException e) {
- return Optional.empty();
- }
+ TypedQuery query = getQuery(new ExampleSpecification<>(example, escapeCharacter), example.getProbeType(),
+ Sort.unsorted()).setMaxResults(2);
+
+ return Optional.ofNullable(query.getSingleResultOrNull());
}
@Override
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java
index 8415d67959..06f454e24c 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java
@@ -193,7 +193,7 @@ private Set scanForMappingFileLocations() {
* @param uri
* @return
*/
- private static String getResourcePath(URI uri) throws IOException {
+ private static String getResourcePath(URI uri) {
if (uri.isOpaque()) {
// e.g. jar:file:/foo/lib/somelib.jar!/com/acme/orm.xml
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java
index 7a5fb05c0d..a8cec7ab1e 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java
@@ -20,9 +20,9 @@
import jakarta.persistence.EntityManager;
+import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
-import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@@ -54,6 +54,7 @@
* @author Oliver Gierke
* @author Jens Schauder
* @author Krzysztof Krason
+ * @author Christoph Strobl
*/
@ExtendWith(SpringExtension.class)
@Transactional
@@ -111,13 +112,13 @@ void shouldAllowUseOfDynamicSpelParametersInUpdateQueries() {
em.detach(thomas);
em.detach(auditor);
- FixedDate.INSTANCE.setDate(new Date());
+ FixedDate.INSTANCE.setDate(Instant.now());
SampleSecurityContextHolder.getCurrent().setPrincipal(thomas);
auditableUserRepository.updateAllNamesToUpperCase();
// DateTime now = new DateTime(FixedDate.INSTANCE.getDate());
- LocalDateTime now = LocalDateTime.ofInstant(FixedDate.INSTANCE.getDate().toInstant(), ZoneId.systemDefault());
+ LocalDateTime now = LocalDateTime.ofInstant(FixedDate.INSTANCE.getDate(), ZoneId.systemDefault());
List users = auditableUserRepository.findAll();
for (AuditableUser user : users) {
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java
index b3c76d25b1..40f3c87379 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java
@@ -106,7 +106,8 @@ void testNamedOutputParameter() {
new Employee(4, "Gabriel"));
}
- @DisabledOnHibernate("6")
+ @DisabledOnHibernate(value = "7",
+ disabledReason = "class org.hibernate.metamodel.model.domain.internal.EntityTypeImpl cannot be cast to class org.hibernate.query.OutputableType (org.hibernate.metamodel.model.domain.internal.EntityTypeImpl and org.hibernate.query.OutputableType are in unnamed module of loader 'app')")
@Test // 2256
void testSingleEntityFromResultSet() {
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlComplianceTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlComplianceTests.java
index bbfbffe1ab..02ac17b66d 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlComplianceTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlComplianceTests.java
@@ -20,14 +20,16 @@
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.data.jpa.repository.query.QueryRenderer.TokenRenderer;
/**
* Tests built around examples of EQL found in the EclipseLink's docs at
* https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL
- * With the exception of {@literal MOD} which is defined as {@literal MOD(arithmetic_expression , arithmetic_expression)},
- * but shown in tests as {@literal MOD(arithmetic_expression ? arithmetic_expression)}.
- *
+ * With the exception of {@literal MOD} which is defined as
+ * {@literal MOD(arithmetic_expression , arithmetic_expression)}, but shown in tests as
+ * {@literal MOD(arithmetic_expression ? arithmetic_expression)}.
* IMPORTANT: Purely verifies the parser without any transformations.
*
* @author Greg Turnquist
@@ -101,6 +103,7 @@ void joinFetch() {
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address");
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address a ORDER BY a.city");
+ assertQuery("SELECT e FROM Employee e JOIN FETCH e.address AS a ORDER BY a.city");
}
@Test
@@ -121,6 +124,21 @@ void subselectsInFromClause() {
"SELECT e, c.city FROM Employee e, (SELECT DISTINCT a.city FROM Address a) c WHERE e.address.city = c.city");
}
+ @Test // GH-3277
+ void numericLiterals() {
+
+ assertQuery("SELECT e FROM Employee e WHERE e.id = 1234");
+ assertQuery("SELECT e FROM Employee e WHERE e.id = 1234L");
+ assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14");
+ assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14F");
+ assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14e32D");
+ }
+
+ @Test // GH-3308
+ void newWithStrings() {
+ assertQuery("select new com.example.demo.SampleObject(se.id, se.sampleValue, \"java\") from SampleEntity se");
+ }
+
@Test
void orderByClause() {
@@ -414,4 +432,53 @@ void isNullAndIsNotNull() {
assertQuery("SELECT e FROM Employee e WHERE (e.active IS NOT null OR e.active = true)");
assertQuery("SELECT e FROM Employee e WHERE (e.active IS NOT NULL OR e.active = true)");
}
+
+ @Test // GH-3496
+ void lateralShouldBeAValidParameter() {
+
+ assertQuery("select e from Employee e where e.lateral = :_lateral");
+ assertQuery("select te from TestEntity te where te.lateral = :lateral");
+ }
+
+ @Test // GH-3136
+ void intersect() {
+
+ assertQuery("""
+ SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode1
+ INTERSECT SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode2
+ """);
+ }
+
+ @Test // GH-3136
+ void except() {
+
+ assertQuery("""
+ SELECT e FROM Employee e
+ EXCEPT SELECT e FROM Employee e WHERE e.salary > e.manager.salary
+ """);
+ }
+
+ @ParameterizedTest // GH-3136
+ @ValueSource(strings = { "STRING", "INTEGER", "FLOAT", "DOUBLE" })
+ void cast(String targetType) {
+ assertQuery("SELECT CAST(e.salary AS %s) FROM Employee e".formatted(targetType));
+ }
+
+ @ParameterizedTest // GH-3136
+ @ValueSource(strings = { "LEFT", "RIGHT" })
+ void leftRightStringFunctions(String keyword) {
+ assertQuery("SELECT %s(e.name, 3) FROM Employee e".formatted(keyword));
+ }
+
+ @Test // GH-3136
+ void replaceStringFunctions() {
+ assertQuery("SELECT REPLACE(e.name, 'o', 'a') FROM Employee e");
+ assertQuery("SELECT REPLACE(e.name, ' ', '_') FROM Employee e");
+ }
+
+ @Test // GH-3136
+ void stringConcatWithPipes() {
+ assertQuery("SELECT e.firstname || e.lastname AS name FROM Employee e");
+ }
+
}
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java
index 91a4bb761e..7588619f23 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java
@@ -1017,6 +1017,59 @@ void powerShouldBeLegalInAQuery() {
assertQuery("select e.power.id from MyEntity e");
}
+ @Test // GH-3136
+ void doublePipeShouldBeValidAsAStringConcatOperator() {
+
+ assertQuery("""
+ select e.name || ' ' || e.title
+ from Employee e
+ """);
+ }
+
+ @Test // GH-3136
+ void combinedSelectStatementsShouldWork() {
+
+ assertQuery("""
+ select e from Employee e where e.last_name = 'Baggins'
+ intersect
+ select e from Employee e where e.first_name = 'Samwise'
+ union
+ select e from Employee e where e.home = 'The Shire'
+ except
+ select e from Employee e where e.home = 'Isengard'
+ """);
+ }
+
+ @Disabled
+ @Test // GH-3136
+ void additionalStringOperationsShouldWork() {
+
+ assertQuery("""
+ select
+ replace(e.name, 'Baggins', 'Proudfeet'),
+ left(e.role, 4),
+ right(e.home, 5),
+ cast(e.distance_from_home, int)
+ from Employee e
+ """);
+ }
+
+ @Test // GH-3136
+ void orderByWithNullsFirstOrLastShouldWork() {
+
+ assertQuery("""
+ select a
+ from Element a
+ order by mutationAm desc nulls first
+ """);
+
+ assertQuery("""
+ select a
+ from Element a
+ order by mutationAm desc nulls last
+ """);
+ }
+
@ParameterizedTest // GH-3342
@ValueSource(strings = { "select 1 from User u", "select -1 from User u", "select +1 from User u",
"select +1 * -100 from User u", "select count(u) * -0.7f from User u",
@@ -1040,10 +1093,4 @@ void entityNameWithPackageContainingReservedWord(String reservedWord) {
assertQuery(source);
}
- @Test // GH-3496
- void lateralShouldBeAValidParameter() {
-
- assertQuery("select e from Employee e where e.lateral = :_lateral");
- assertQuery("select te from TestEntity te where te.lateral = :lateral");
- }
}
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlSpecificationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlSpecificationTests.java
index b6ed4fc8b8..81a104c953 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlSpecificationTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlSpecificationTests.java
@@ -281,7 +281,7 @@ void fromClauseDowncastingExample1() {
assertQuery("""
SELECT b.name, b.ISBN
FROM Order o JOIN TREAT(o.product AS Book) b
- """);
+ """);
}
@Test
@@ -290,7 +290,7 @@ void fromClauseDowncastingExample2() {
assertQuery("""
SELECT e FROM Employee e JOIN TREAT(e.projects AS LargeProject) lp
WHERE lp.budget > 1000
- """);
+ """);
}
/**
@@ -305,7 +305,7 @@ void fromClauseDowncastingExample3_SPEC_BUG() {
WHERE TREAT(p AS LargeProject).budget > 1000
OR TREAT(p AS SmallProject).name LIKE 'Persist%'
OR p.description LIKE "cost overrun"
- """);
+ """);
}
@Test
@@ -316,7 +316,7 @@ void fromClauseDowncastingExample3fixed() {
WHERE TREAT(p AS LargeProject).budget > 1000
OR TREAT(p AS SmallProject).name LIKE 'Persist%'
OR p.description LIKE 'cost overrun'
- """);
+ """);
}
@Test
@@ -326,7 +326,39 @@ void fromClauseDowncastingExample4() {
SELECT e FROM Employee e
WHERE TREAT(e AS Exempt).vacationDays > 10
OR TREAT(e AS Contractor).hours > 100
- """);
+ """);
+ }
+
+ @Test // GH-3136
+ void substring() {
+
+ assertQuery("select substring(c.number, 1, 2) " + //
+ "from Call c");
+
+ assertQuery("select substring(c.number, 1) " + //
+ "from Call c");
+ }
+
+ @Test // GH-3136
+ void currentDateFunctions() {
+
+ assertQuery("select CURRENT_DATE " + //
+ "from Call c ");
+
+ assertQuery("select CURRENT_TIME " + //
+ "from Call c ");
+
+ assertQuery("select CURRENT_TIMESTAMP " + //
+ "from Call c ");
+
+ assertQuery("select LOCAL_DATE " + //
+ "from Call c ");
+
+ assertQuery("select LOCAL_TIME " + //
+ "from Call c ");
+
+ assertQuery("select LOCAL_DATETIME " + //
+ "from Call c ");
}
@Test
@@ -390,7 +422,7 @@ void allExample() {
WHERE emp.salary > ALL (SELECT m.salary
FROM Manager m
WHERE m.department = emp.department)
- """);
+ """);
}
@Test
@@ -402,7 +434,7 @@ void existsSubSelectExample2() {
WHERE EXISTS (SELECT spouseEmp
FROM Employee spouseEmp
WHERE spouseEmp = emp.spouse)
- """);
+ """);
}
@Test
@@ -470,7 +502,7 @@ void updateCaseExample1() {
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
- """);
+ """);
}
@Test
@@ -483,7 +515,7 @@ void updateCaseExample2() {
WHEN 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
- """);
+ """);
}
@Test
@@ -523,7 +555,7 @@ void theRest() {
SELECT e
FROM Employee e
WHERE TYPE(e) IN (Exempt, Contractor)
- """);
+ """);
}
@Test
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java
index 067a3adbe4..5eb578b498 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java
@@ -1646,42 +1646,36 @@ void hqlQueries() {
@Test // GH-2962
void orderByWithNullsFirstOrLastShouldWork() {
- assertThatNoException().isThrownBy(() -> {
- parseWithoutChanges("""
- select a,
- case
- when a.geaendertAm is null then a.erstelltAm
- else a.geaendertAm end as mutationAm
- from Element a
- where a.erstelltDurch = :variable
- order by mutationAm desc nulls first
- """);
- });
-
- assertThatNoException().isThrownBy(() -> {
- parseWithoutChanges("""
- select a,
- case
- when a.geaendertAm is null then a.erstelltAm
- else a.geaendertAm end as mutationAm
- from Element a
- where a.erstelltDurch = :variable
- order by mutationAm desc nulls last
- """);
- });
+ assertQuery("""
+ select a,
+ case
+ when a.geaendertAm is null then a.erstelltAm
+ else a.geaendertAm end as mutationAm
+ from Element a
+ where a.erstelltDurch = :variable
+ order by mutationAm desc nulls first
+ """);
+
+ assertQuery("""
+ select a,
+ case
+ when a.geaendertAm is null then a.erstelltAm
+ else a.geaendertAm end as mutationAm
+ from Element a
+ where a.erstelltDurch = :variable
+ order by mutationAm desc nulls last
+ """);
}
@Test // GH-2964
void roundFunctionShouldWorkLikeAnyOtherFunction() {
- assertThatNoException().isThrownBy(() -> {
- parseWithoutChanges("""
- select round(count(ri) * 100 / max(ri.receipt.positions), 0) as perc
- from StockOrderItem oi
- right join StockReceiptItem ri
- on ri.article = oi.article
- """);
- });
+ assertQuery("""
+ select round(count(ri) * 100 / max(ri.receipt.positions), 0) as perc
+ from StockOrderItem oi
+ right join StockReceiptItem ri
+ on ri.article = oi.article
+ """);
}
@Test // GH-3711
@@ -1831,6 +1825,42 @@ void powerShouldBeLegalInAQuery() {
assertQuery("select e.power.id from MyEntity e");
}
+ @Test // GH-3136
+ void doublePipeShouldBeValidAsAStringConcatOperator() {
+
+ assertQuery("""
+ select e.name || ' ' || e.title
+ from Employee e
+ """);
+ }
+
+ @Test // GH-3136
+ void additionalStringOperationsShouldWork() {
+
+ assertQuery("""
+ select
+ replace(e.name, 'Baggins', 'Proudfeet'),
+ left(e.role, 4),
+ right(e.home, 5),
+ cast(e.distance_from_home, int)
+ from Employee e
+ """);
+ }
+
+ @Test // GH-3136
+ void combinedSelectStatementsShouldWork() {
+
+ assertQuery("""
+ select e from Employee e where e.last_name = 'Baggins'
+ intersect
+ select e from Employee e where e.first_name = 'Samwise'
+ union
+ select e from Employee e where e.home = 'The Shire'
+ except
+ select e from Employee e where e.home = 'Isengard'
+ """);
+ }
+
@Test // GH-3219
void extractFunctionShouldSupportAdditionalExtensions() {
@@ -1883,4 +1913,16 @@ void entityNameWithPackageContainingReservedWord(String reservedWord) {
String source = "select new com.company.%s.thing.stuff.ClassName(e.id) from Experience e".formatted(reservedWord);
assertQuery(source);
}
+
+ @ParameterizedTest // GH-3136
+ @ValueSource(strings = {"LEFT", "RIGHT"})
+ void leftRightStringFunctions(String keyword) {
+ assertQuery("SELECT %s(e.name, 3) FROM Employee e".formatted(keyword));
+ }
+
+ @Test // GH-3136
+ void replaceStringFunctions() {
+ assertQuery("SELECT REPLACE(e.name, 'o', 'a') FROM Employee e");
+ assertQuery("SELECT REPLACE(e.name, ' ', '_') FROM Employee e");
+ }
}
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlComplianceTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlComplianceTests.java
index aadf2c2589..b0ec7cbb1a 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlComplianceTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlComplianceTests.java
@@ -20,6 +20,8 @@
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
/**
* Test to verify compliance of {@link JpqlParser} with standard SQL. Other than {@link JpqlSpecificationTests} tests in
@@ -27,6 +29,7 @@
* suffix.
*
* @author Christoph Strobl
+ * @author Mark Paluch
*/
class JpqlComplianceTests {
@@ -55,6 +58,52 @@ private String reduceWhitespace(String original) {
.trim();
}
+ @Test
+ void selectQueries() {
+
+ assertQuery("Select e FROM Employee e WHERE e.salary > 100000");
+ assertQuery("Select e FROM Employee e WHERE e.id = :id");
+ assertQuery("Select MAX(e.salary) FROM Employee e");
+ assertQuery("Select e.firstName FROM Employee e");
+ assertQuery("Select e.firstName, e.lastName FROM Employee e");
+ }
+
+ @Test
+ void selectClause() {
+
+ assertQuery("SELECT COUNT(e) FROM Employee e");
+ assertQuery("SELECT MAX(e.salary) FROM Employee e");
+ assertQuery("SELECT NEW com.acme.reports.EmpReport(e.firstName, e.lastName, e.salary) FROM Employee e");
+ }
+
+ @Test
+ void fromClause() {
+
+ assertQuery("SELECT e FROM Employee e");
+ assertQuery("SELECT e, a FROM Employee e, MailingAddress a WHERE e.address = a.address");
+ assertQuery("SELECT e FROM com.acme.Employee e");
+ }
+
+ @Test
+ void join() {
+
+ assertQuery("SELECT e FROM Employee e JOIN e.address a WHERE a.city = :city");
+ assertQuery("SELECT e FROM Employee e JOIN e.projects p JOIN e.projects p2 WHERE p.name = :p1 AND p2.name = :p2");
+ }
+
+ @Test
+ void joinFetch() {
+
+ assertQuery("SELECT e FROM Employee e JOIN FETCH e.address");
+ assertQuery("SELECT e FROM Employee e JOIN FETCH e.address a ORDER BY a.city");
+ assertQuery("SELECT e FROM Employee e JOIN FETCH e.address AS a ORDER BY a.city");
+ }
+
+ @Test
+ void leftJoin() {
+ assertQuery("SELECT e FROM Employee e LEFT JOIN e.address a ORDER BY a.city");
+ }
+
@Test // GH-3277
void numericLiterals() {
@@ -70,4 +119,210 @@ void newWithStrings() {
assertQuery("select new com.example.demo.SampleObject(se.id, se.sampleValue, \"java\") from SampleEntity se");
}
+ @Test
+ void orderByClause() {
+
+ assertQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC"); // Typo in EQL document
+ assertQuery("SELECT e FROM Employee e LEFT JOIN e.manager m ORDER BY m.lastName NULLS FIRST");
+ assertQuery("SELECT e FROM Employee e ORDER BY e.address");
+ }
+
+ @Test
+ void groupByClause() {
+
+ assertQuery("SELECT AVG(e.salary), e.address.city FROM Employee e GROUP BY e.address.city");
+ assertQuery("SELECT e, COUNT(p) FROM Employee e LEFT JOIN e.projects p GROUP BY e");
+ }
+
+ @Test
+ void havingClause() {
+ assertQuery(
+ "SELECT AVG(e.salary), e.address.city FROM Employee e GROUP BY e.address.city HAVING AVG(e.salary) > 100000");
+ }
+
+ @Test // GH-3136
+ void union() {
+
+ assertQuery("""
+ SELECT MAX(e.salary) FROM Employee e WHERE e.address.city = :city1
+ UNION SELECT MAX(e.salary) FROM Employee e WHERE e.address.city = :city2
+ """);
+ assertQuery("""
+ SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode1
+ INTERSECT SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode2
+ """);
+ assertQuery("""
+ SELECT e FROM Employee e
+ EXCEPT SELECT e FROM Employee e WHERE e.salary > e.manager.salary
+ """);
+ }
+
+ @Test
+ void whereClause() {
+ // TBD
+ }
+
+ @Test
+ void updateQueries() {
+ assertQuery("UPDATE Employee e SET e.salary = 60000 WHERE e.salary = 50000");
+ }
+
+ @Test
+ void deleteQueries() {
+ assertQuery("DELETE FROM Employee e WHERE e.department IS NULL");
+ }
+
+ @Test
+ void literals() {
+
+ assertQuery("SELECT e FROM Employee e WHERE e.name = 'Bob'");
+ assertQuery("SELECT e FROM Employee e WHERE e.id = 1234");
+ assertQuery("SELECT e FROM Employee e WHERE e.id = 1234L");
+ assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14F");
+ assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14e32D");
+ assertQuery("SELECT e FROM Employee e WHERE e.active = TRUE");
+ assertQuery("SELECT e FROM Employee e WHERE e.startDate = {d'2012-01-03'}");
+ assertQuery("SELECT e FROM Employee e WHERE e.startTime = {t'09:00:00'}");
+ assertQuery("SELECT e FROM Employee e WHERE e.version = {ts'2012-01-03 09:00:00.000000001'}");
+ assertQuery("SELECT e FROM Employee e WHERE e.gender = org.acme.Gender.MALE");
+ assertQuery("UPDATE Employee e SET e.manager = NULL WHERE e.manager = :manager");
+ }
+
+ @Test
+ void functionsInSelect() {
+
+ assertQuery("SELECT e.salary - 1000 FROM Employee e");
+ assertQuery("SELECT e.salary + 1000 FROM Employee e");
+ assertQuery("SELECT e.salary * 2 FROM Employee e");
+ assertQuery("SELECT e.salary * 2.0 FROM Employee e");
+ assertQuery("SELECT e.salary / 2 FROM Employee e");
+ assertQuery("SELECT e.salary / 2.0 FROM Employee e");
+ assertQuery("SELECT ABS(e.salary - e.manager.salary) FROM Employee e");
+ assertQuery(
+ "select e from Employee e where case e.firstName when 'Bob' then 'Robert' when 'Jill' then 'Gillian' else '' end = 'Robert'");
+ assertQuery(
+ "select case when e.firstName = 'Bob' then 'Robert' when e.firstName = 'Jill' then 'Gillian' else '' end from Employee e where e.firstName = 'Bob' or e.firstName = 'Jill'");
+ assertQuery(
+ "select e from Employee e where case when e.firstName = 'Bob' then 'Robert' when e.firstName = 'Jill' then 'Gillian' else '' end = 'Robert'");
+ assertQuery("SELECT COALESCE(e.salary, 0) FROM Employee e");
+ assertQuery("SELECT CONCAT(e.firstName, ' ', e.lastName) FROM Employee e");
+ assertQuery("SELECT e.name, CURRENT_DATE FROM Employee e");
+ assertQuery("SELECT e.name, CURRENT_TIME FROM Employee e");
+ assertQuery("SELECT e.name, CURRENT_TIMESTAMP FROM Employee e");
+ assertQuery("SELECT LENGTH(e.lastName) FROM Employee e");
+ assertQuery("SELECT LOWER(e.lastName) FROM Employee e");
+ assertQuery("SELECT MOD(e.hoursWorked, 8) FROM Employee e");
+ assertQuery("SELECT NULLIF(e.salary, 0) FROM Employee e");
+ assertQuery("SELECT SQRT(o.RESULT) FROM Output o");
+ assertQuery("SELECT SUBSTRING(e.lastName, 0, 2) FROM Employee e");
+ assertQuery(
+ "SELECT TRIM(TRAILING FROM e.lastName), TRIM(e.lastName), TRIM(LEADING '-' FROM e.lastName) FROM Employee e");
+ assertQuery("SELECT UPPER(e.lastName) FROM Employee e");
+ assertQuery("SELECT CAST(e.salary NUMERIC(10, 2)) FROM Employee e");
+ assertQuery("SELECT EXTRACT(YEAR FROM e.startDate) FROM Employee e");
+ }
+
+ @Test
+ void functionsInWhere() {
+
+ assertQuery("SELECT e FROM Employee e WHERE e.salary - 1000 > 0");
+ assertQuery("SELECT e FROM Employee e WHERE e.salary + 1000 > 0");
+ assertQuery("SELECT e FROM Employee e WHERE e.salary * 2 > 0");
+ assertQuery("SELECT e FROM Employee e WHERE e.salary * 2.0 > 0.0");
+ assertQuery("SELECT e FROM Employee e WHERE e.salary / 2 > 0");
+ assertQuery("SELECT e FROM Employee e WHERE e.salary / 2.0 > 0.0");
+ assertQuery("SELECT e FROM Employee e WHERE ABS(e.salary - e.manager.salary) > 0");
+ assertQuery("SELECT e FROM Employee e WHERE COALESCE(e.salary, 0) > 0");
+ assertQuery("SELECT e FROM Employee e WHERE CONCAT(e.firstName, ' ', e.lastName) = 'Bilbo'");
+ assertQuery("SELECT e FROM Employee e WHERE CURRENT_DATE > CURRENT_TIME");
+ assertQuery("SELECT e FROM Employee e WHERE CURRENT_TIME > CURRENT_TIMESTAMP");
+ assertQuery("SELECT e FROM Employee e WHERE LENGTH(e.lastName) > 0");
+ assertQuery("SELECT e FROM Employee e WHERE LOWER(e.lastName) = 'bilbo'");
+ assertQuery("SELECT e FROM Employee e WHERE MOD(e.hoursWorked, 8) > 0");
+ assertQuery("SELECT e FROM Employee e WHERE SQRT(o.RESULT) > 0.0");
+ assertQuery("SELECT e FROM Employee e WHERE SUBSTRING(e.lastName, 0, 2) = 'Bilbo'");
+ assertQuery("SELECT e FROM Employee e WHERE TRIM(TRAILING FROM e.lastName) = 'Bilbo'");
+ assertQuery("SELECT e FROM Employee e WHERE TRIM(e.lastName) = 'Bilbo'");
+ assertQuery("SELECT e FROM Employee e WHERE TRIM(LEADING '-' FROM e.lastName) = 'Bilbo'");
+ assertQuery("SELECT e FROM Employee e WHERE UPPER(e.lastName) = 'BILBO'");
+ assertQuery("SELECT e FROM Employee e WHERE CAST(e.salary NUMERIC(10, 2)) > 0.0");
+ assertQuery("SELECT e FROM Employee e WHERE EXTRACT(YEAR FROM e.startDate) = '2023'");
+ }
+
+ @Test
+ void specialOperators() {
+
+ assertQuery("SELECT toDo FROM Employee e JOIN e.toDoList toDo WHERE INDEX(toDo) = 1");
+ assertQuery("SELECT p FROM Employee e JOIN e.priorities p WHERE KEY(p) = 'high'");
+ assertQuery("SELECT e FROM Employee e WHERE SIZE(e.managedEmployees) < 2");
+ assertQuery("SELECT e FROM Employee e WHERE e.managedEmployees IS EMPTY");
+ assertQuery("SELECT e FROM Employee e WHERE 'write code' MEMBER OF e.responsibilities");
+ assertQuery("SELECT p FROM Project p WHERE TYPE(p) = LargeProject");
+
+ /**
+ * NOTE: The following query has been altered to properly align with EclipseLink test code despite NOT matching
+ * their ref docs. See https://github.com/eclipse-ee4j/eclipselink/issues/1949 for more details.
+ */
+ assertQuery("SELECT e FROM Employee e JOIN TREAT(e.projects AS LargeProject) p WHERE p.budget > 1000000");
+
+ assertQuery("SELECT p FROM Phone p WHERE FUNCTION('TO_NUMBER', p.areaCode) > 613");
+ }
+
+ @Test // GH-3314
+ void isNullAndIsNotNull() {
+
+ assertQuery("SELECT e FROM Employee e WHERE (e.active IS null OR e.active = true)");
+ assertQuery("SELECT e FROM Employee e WHERE (e.active IS NULL OR e.active = true)");
+ assertQuery("SELECT e FROM Employee e WHERE (e.active IS NOT null OR e.active = true)");
+ assertQuery("SELECT e FROM Employee e WHERE (e.active IS NOT NULL OR e.active = true)");
+ }
+
+ @Test // GH-3496
+ void lateralShouldBeAValidParameter() {
+
+ assertQuery("select e from Employee e where e.lateral = :_lateral");
+ assertQuery("select te from TestEntity te where te.lateral = :lateral");
+ }
+
+ @Test // GH-3136
+ void intersect() {
+
+ assertQuery("""
+ SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode1
+ INTERSECT SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode2
+ """);
+ }
+
+ @Test // GH-3136
+ void except() {
+
+ assertQuery("""
+ SELECT e FROM Employee e
+ EXCEPT SELECT e FROM Employee e WHERE e.salary > e.manager.salary
+ """);
+ }
+
+ @ParameterizedTest // GH-3136
+ @ValueSource(strings = { "STRING", "INTEGER", "FLOAT", "DOUBLE" })
+ void cast(String targetType) {
+ assertQuery("SELECT CAST(e.salary AS %s) FROM Employee e".formatted(targetType));
+ }
+
+ @ParameterizedTest // GH-3136
+ @ValueSource(strings = { "LEFT", "RIGHT" })
+ void leftRightStringFunctions(String keyword) {
+ assertQuery("SELECT %s(e.name, 3) FROM Employee e".formatted(keyword));
+ }
+
+ @Test // GH-3136
+ void replaceStringFunctions() {
+ assertQuery("SELECT REPLACE(e.name, 'o', 'a') FROM Employee e");
+ assertQuery("SELECT REPLACE(e.name, ' ', '_') FROM Employee e");
+ }
+
+ @Test // GH-3136
+ void stringConcatWithPipes() {
+ assertQuery("SELECT e.firstname || e.lastname AS name FROM Employee e");
+ }
+
}
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java
index c50f07c596..3ec9ab7c9b 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java
@@ -1010,6 +1010,59 @@ void powerShouldBeLegalInAQuery() {
assertQuery("select e.power.id from MyEntity e");
}
+ @Test // GH-3136
+ void doublePipeShouldBeValidAsAStringConcatOperator() {
+
+ assertQuery("""
+ select e.name || ' ' || e.title
+ from Employee e
+ """);
+ }
+
+ @Test // GH-3136
+ void combinedSelectStatementsShouldWork() {
+
+ assertQuery("""
+ select e from Employee e where e.last_name = 'Baggins'
+ intersect
+ select e from Employee e where e.first_name = 'Samwise'
+ union
+ select e from Employee e where e.home = 'The Shire'
+ except
+ select e from Employee e where e.home = 'Isengard'
+ """);
+ }
+
+ @Disabled
+ @Test // GH-3136
+ void additionalStringOperationsShouldWork() {
+
+ assertQuery("""
+ select
+ replace(e.name, 'Baggins', 'Proudfeet'),
+ left(e.role, 4),
+ right(e.home, 5),
+ cast(e.distance_from_home, int)
+ from Employee e
+ """);
+ }
+
+ @Test // GH-3136
+ void orderByWithNullsFirstOrLastShouldWork() {
+
+ assertQuery("""
+ select a
+ from Element a
+ order by mutationAm desc nulls first
+ """);
+
+ assertQuery("""
+ select a
+ from Element a
+ order by mutationAm desc nulls last
+ """);
+ }
+
@ParameterizedTest // GH-3342
@ValueSource(strings = { "select 1 as value from User u", "select -1 as value from User u",
"select +1 as value from User u", "select +1 * -100 as value from User u",
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryTransformerTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryTransformerTests.java
index c2de2ca015..8cbb80df43 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryTransformerTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryTransformerTests.java
@@ -784,6 +784,15 @@ void sortingRecognizesJoinAliases() {
""");
}
+ @Test // GH-3427
+ void sortShouldBeAppendedToFullSelectOnlyInCaseOfSetOperator() {
+
+ String source = "SELECT tb FROM Test tb WHERE (tb.type='A') UNION SELECT tb FROM Test tb WHERE (tb.type='B')";
+ String target = createQueryFor(source, Sort.by("Type").ascending());
+
+ assertThat(target).isEqualTo("SELECT tb FROM Test tb WHERE (tb.type = 'A') UNION SELECT tb FROM Test tb WHERE (tb.type = 'B') order by tb.Type asc");
+ }
+
static Stream queriesWithReservedWordsAsIdentifiers() {
return Stream.of( //
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlSpecificationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlSpecificationTests.java
index f32a9d1c75..7fae0bf044 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlSpecificationTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlSpecificationTests.java
@@ -21,6 +21,7 @@
import org.antlr.v4.runtime.CommonTokenStream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+
import org.springframework.data.jpa.repository.query.QueryRenderer.TokenRenderer;
/**
@@ -333,6 +334,38 @@ OR TREAT(e AS Contractor).hours > 100
""");
}
+ @Test // GH-3136
+ void substring() {
+
+ assertQuery("select substring(c.number, 1, 2) " + //
+ "from Call c");
+
+ assertQuery("select substring(c.number, 1) " + //
+ "from Call c");
+ }
+
+ @Test // GH-3136
+ void currentDateFunctions() {
+
+ assertQuery("select CURRENT_DATE " + //
+ "from Call c ");
+
+ assertQuery("select CURRENT_TIME " + //
+ "from Call c ");
+
+ assertQuery("select CURRENT_TIMESTAMP " + //
+ "from Call c ");
+
+ assertQuery("select LOCAL_DATE " + //
+ "from Call c ");
+
+ assertQuery("select LOCAL_TIME " + //
+ "from Call c ");
+
+ assertQuery("select LOCAL_DATETIME " + //
+ "from Call c ");
+ }
+
@Test
void pathExpressionsNamedParametersExample() {
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsIntegrationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsIntegrationTests.java
index 59eb5f8667..1c7adc781d 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsIntegrationTests.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsIntegrationTests.java
@@ -32,6 +32,7 @@
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
+import jakarta.persistence.criteria.Nulls;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.spi.PersistenceProvider;
import jakarta.persistence.spi.PersistenceProviderResolver;
@@ -314,8 +315,8 @@ void toOrdersCanSortByJoinColumn() {
assertThat(orders).hasSize(1);
}
- @Test // GH-3529
- void nullPrecedenceThroughCriteriaApiNotYetSupported() {
+ @Test // GH-3529, GH-3587
+ void queryUtilsConsidersNullPrecedence() {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery(User.class);
@@ -324,8 +325,10 @@ void nullPrecedenceThroughCriteriaApiNotYetSupported() {
Sort sort = Sort.by(Sort.Order.desc("manager").nullsFirst());
- assertThatExceptionOfType(UnsupportedOperationException.class)
- .isThrownBy(() -> QueryUtils.toOrders(sort, join, builder));
+ List orders = QueryUtils.toOrders(sort, join, builder);
+ for (jakarta.persistence.criteria.Order order : orders) {
+ assertThat(order.getNullPrecedence()).isEqualTo(Nulls.FIRST);
+ }
}
/**
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java
index 76896ece7a..042713219d 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java
@@ -544,7 +544,7 @@ List findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntity
List findRolesAndFirstnameBy();
- @Query(value = "FROM User u")
+ @Query(value = "SELECT u FROM User u")
List findIdOnly();
// DATAJPA-1172
@@ -643,13 +643,13 @@ List findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntity
List findAllInterfaceProjectedBy();
// GH-2045, GH-425
- @Query("select concat(?1,u.id,?2) as id from #{#entityName} u")
+ @Query("select concat(?1,u.id,?2) as identifier from #{#entityName} u")
List findAllAndSortByFunctionResultPositionalParameter(
@Param("positionalParameter1") String positionalParameter1,
@Param("positionalParameter2") String positionalParameter2, Sort sort);
// GH-2045, GH-425
- @Query("select concat(:namedParameter1,u.id,:namedParameter2) as id from #{#entityName} u")
+ @Query("select concat(:namedParameter1,u.id,:namedParameter2) as identifier from #{#entityName} u")
List findAllAndSortByFunctionResultNamedParameter(@Param("namedParameter1") String namedParameter1,
@Param("namedParameter2") String namedParameter2, Sort sort);
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/FixedDate.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/FixedDate.java
index 377874e48c..fc930b94d5 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/FixedDate.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/FixedDate.java
@@ -15,24 +15,25 @@
*/
package org.springframework.data.jpa.util;
-import java.util.Date;
+import java.time.Instant;
/**
- * Holds a fixed {@link Date} value to use in components that have no direct connection.
+ * Holds a fixed {@link Instant} value to use in components that have no direct connection.
*
* @author Thomas Darimont
+ * @author Christoph Strobl
*/
public enum FixedDate {
INSTANCE;
- private Date fixedDate;
+ private Instant fixedDate;
- public void setDate(Date date) {
+ public void setDate(Instant date) {
this.fixedDate = date;
}
- public Date getDate() {
+ public Instant getDate() {
return fixedDate;
}
}
diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/TestMetaModel.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/TestMetaModel.java
index a755ba222b..822365b65a 100644
--- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/TestMetaModel.java
+++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/util/TestMetaModel.java
@@ -43,13 +43,13 @@ public class TestMetaModel implements Metamodel {
private final Set> managedTypes;
private final Lazy entityManagerFactory = Lazy.of(this::init);
private final Lazy metamodel = Lazy.of(() -> entityManagerFactory.get().getMetamodel());
- private Lazy enityManager = Lazy.of(() -> entityManagerFactory.get().createEntityManager());
+ private final Lazy entityManager = Lazy.of(() -> entityManagerFactory.get().createEntityManager());
- TestMetaModel(Set> managedTypes) {
+ private TestMetaModel(Set> managedTypes) {
this("dynamic-tests", managedTypes);
}
- TestMetaModel(String persistenceUnit, Set> managedTypes) {
+ private TestMetaModel(String persistenceUnit, Set> managedTypes) {
this.persistenceUnit = persistenceUnit;
this.managedTypes = managedTypes;
}
@@ -66,6 +66,11 @@ public EntityType entity(Class cls) {
return metamodel.get().entity(cls);
}
+ @Override
+ public EntityType> entity(String s) {
+ return metamodel.get().entity(s);
+ }
+
public ManagedType managedType(Class cls) {
return metamodel.get().managedType(cls);
}
@@ -87,7 +92,7 @@ public Set> getEmbeddables() {
}
public EntityManager entityManager() {
- return enityManager.get();
+ return entityManager.get();
}
EntityManagerFactory init() {
diff --git a/spring-data-jpa/src/test/resources/META-INF/orm.xml b/spring-data-jpa/src/test/resources/META-INF/orm.xml
index 820a9cced2..65f0ef28fe 100644
--- a/spring-data-jpa/src/test/resources/META-INF/orm.xml
+++ b/spring-data-jpa/src/test/resources/META-INF/orm.xml
@@ -1,8 +1,8 @@
-
+
diff --git a/spring-data-jpa/src/test/resources/META-INF/persistence-jmh.xml b/spring-data-jpa/src/test/resources/META-INF/persistence-jmh.xml
index 60c6b5c97a..a78eb59468 100644
--- a/spring-data-jpa/src/test/resources/META-INF/persistence-jmh.xml
+++ b/spring-data-jpa/src/test/resources/META-INF/persistence-jmh.xml
@@ -14,9 +14,10 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-
+
org.hibernate.jpa.HibernatePersistenceProvider
org.springframework.data.jpa.domain.AbstractPersistable
diff --git a/spring-data-jpa/src/test/resources/META-INF/persistence.xml b/spring-data-jpa/src/test/resources/META-INF/persistence.xml
index 4f904373c3..35a8715991 100644
--- a/spring-data-jpa/src/test/resources/META-INF/persistence.xml
+++ b/spring-data-jpa/src/test/resources/META-INF/persistence.xml
@@ -1,5 +1,8 @@
-
+
org.springframework.data.jpa.domain.AbstractPersistable
org.springframework.data.jpa.domain.AbstractAuditable
diff --git a/spring-data-jpa/src/test/resources/META-INF/persistence2.xml b/spring-data-jpa/src/test/resources/META-INF/persistence2.xml
index f4f7adb6b2..a93617de58 100644
--- a/spring-data-jpa/src/test/resources/META-INF/persistence2.xml
+++ b/spring-data-jpa/src/test/resources/META-INF/persistence2.xml
@@ -1,7 +1,8 @@
-
+
org.springframework.data.jpa.domain.sample.AnnotatedAuditableUser
org.springframework.data.jpa.domain.sample.AuditableRole
diff --git a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/mapping.xml b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/mapping.xml
index 87f3460858..634c42b966 100644
--- a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/mapping.xml
+++ b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/mapping.xml
@@ -1,2 +1,5 @@
-
+
diff --git a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module1/module1-orm.xml b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module1/module1-orm.xml
index da1ce9a7d4..634c42b966 100644
--- a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module1/module1-orm.xml
+++ b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module1/module1-orm.xml
@@ -1,3 +1,5 @@
-
-
+
diff --git a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module2/module2-orm.xml b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module2/module2-orm.xml
index da1ce9a7d4..634c42b966 100644
--- a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module2/module2-orm.xml
+++ b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/module2/module2-orm.xml
@@ -1,3 +1,5 @@
-
-
+
diff --git a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence.xml b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence.xml
index ad1460bad7..f75fea5ba3 100644
--- a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence.xml
+++ b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence.xml
@@ -1,5 +1,8 @@
-
+
foo.xml
org.springframework.data.jpa.domain.sample.User
diff --git a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence2.xml b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence2.xml
index 962748440b..1666022d07 100644
--- a/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence2.xml
+++ b/spring-data-jpa/src/test/resources/org/springframework/data/jpa/support/persistence2.xml
@@ -1,5 +1,8 @@
-
+
bar.xml
org.springframework.data.jpa.domain.sample.Role
diff --git a/spring-data-jpa/src/test/resources/simple-persistence/simple-persistence.xml b/spring-data-jpa/src/test/resources/simple-persistence/simple-persistence.xml
index 9caa71259a..706d5fb919 100644
--- a/spring-data-jpa/src/test/resources/simple-persistence/simple-persistence.xml
+++ b/spring-data-jpa/src/test/resources/simple-persistence/simple-persistence.xml
@@ -1,5 +1,8 @@
-
+
true