GopikaReghunath commented on code in PR #2328:
URL:
https://github.com/apache/incubator-kie-kogito-apps/pull/2328#discussion_r3372256829
##########
data-index/data-index-storage/data-index-storage-jpa-common/src/main/java/org/kie/kogito/index/jpa/storage/JPAQuery.java:
##########
@@ -110,23 +121,80 @@ public List<T> execute() {
return (List<T>)
query.getResultList().stream().map(mapper).collect(toList());
}
- protected Function<AttributeFilter<?>, Predicate>
filterPredicateFunction(Root<E> root, CriteriaBuilder builder) {
+ /**
+ * Determines if DISTINCT is needed based on whether the query uses
collection attributes
+ * that would result in JOINs and potential duplicate rows.
+ */
+ private boolean needsDistinct() {
+ if (filters == null || filters.isEmpty()) {
+ return false;
+ }
+ return filters.stream().anyMatch(this::filterNeedsDistinct);
+ }
+
+ /**
+ * Recursively checks if a filter needs DISTINCT due to collection
operations or attributes.
+ */
+ private boolean filterNeedsDistinct(AttributeFilter<?> filter) {
+ return switch (filter.getCondition()) {
+ case CONTAINS, CONTAINS_ALL, CONTAINS_ANY ->
+ // Collection operations on collection attributes need DISTINCT
+ filter.getAttribute() != null &&
isCollectionAttribute(filter.getAttribute());
+ case AND, OR -> {
+ // Check nested filters recursively
+ List<AttributeFilter<?>> nestedFilters =
(List<AttributeFilter<?>>) filter.getValue();
+ yield
nestedFilters.stream().anyMatch(this::filterNeedsDistinct);
+ }
+ case NOT -> filterNeedsDistinct((AttributeFilter<?>)
filter.getValue());
+ case EQUAL, LIKE, IN, GT, GTE, LT, LTE, BETWEEN, IS_NULL, NOT_NULL
->
+ // These operations on collection attributes need DISTINCT
+ filter.getAttribute() != null &&
isCollectionAttribute(filter.getAttribute());
+ default -> false;
+ };
+ }
+
+ protected Function<AttributeFilter<?>, Predicate>
filterPredicateFunction(Root<E> root, CriteriaBuilder builder, CriteriaQuery<?>
criteriaQuery) {
return filter -> jsonPredicateBuilder.filter(b ->
filter.isJson()).map(b -> b.buildPredicate(filter, root, builder))
- .orElseGet(() -> buildPredicateFunction(filter, root,
builder));
+ .orElseGet(() -> buildPredicateFunction(filter, root, builder,
criteriaQuery));
}
- protected final Predicate buildPredicateFunction(AttributeFilter filter,
Root<E> root, CriteriaBuilder builder) {
+ protected final Predicate buildPredicateFunction(AttributeFilter filter,
Root<E> root, CriteriaBuilder builder, CriteriaQuery<?> criteriaQuery) {
Review Comment:
@jstastny-cz I tried merging multiple NOT EXISTS subqueries into a single
one but was causing issues with NOT CONTAINS ALL and was giving unexpected
response for example:
Task has comment with id 243672d5-44a2-423b-901e-1f4130373ebe
Query: NOT CONTAINS_ALL [243672d5-44a2-423b-901e-1f4130373ebe,
another-comment-id]
Expected: Return task (missing another-comment-id)
this was resulting in a query : `NOT EXISTS(... JOIN c1_0 ... JOIN c2_0
WHERE (c1_0.id=? OR c2_0.id=?))` which return Returns 0 items hence followed
`NOT EXISTS(... JOIN c1_0 WHERE c1_0.id=?) OR NOT EXISTS(... JOIN c2_0 WHERE
c2_0.id=?)` and for maintaining the uniformity kept the same for other NOT
conditions and for positive cases the current implementation reuses the
existing getAttributePath(). Let me know if you have more thoughts
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]