jstastny-cz commented on code in PR #2328:
URL: 
https://github.com/apache/incubator-kie-kogito-apps/pull/2328#discussion_r3333246135


##########
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:
   Right, there are 2 subselects each joining the same tables - why not to 
merge the conditions into a single EXISTS query? And adjust AND/OR combinations 
accordingly.
   Would be
   `SELECT ... FROM processes p_0 WHERE NOT EXISTS (SELECT 1 FROM processes p1 
JOIN nodes n1 ON p1.id=n1.id WHERE p_0.id=p1.id AND (n1.name='Technical 
Interview' OR n1.type='ErrorNode`)`?
   
   so in simplified WHERE NOT EXISTS (both conditions via OR), similarly for 
positive filters, why isn't it the same approach, also single subselect (which 
results in the join anyways) and then combine the filters in a single set.
   
   Having said that - can't actually be both positive and negative filters 
handled within the same single subquery using EXISTS by just inverting the 
conditions for the negative?



-- 
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]

Reply via email to