This is an automated email from the ASF dual-hosted git repository. johnthuss pushed a commit to branch ics17 in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 9ed6dacd4f820dfa121646769e216bfe6982e0f2 Author: John Huss <[email protected]> AuthorDate: Wed Sep 4 09:21:45 2019 -0500 Use IN expression for disjointById prefetches where possible. Makes generated SQL more consistent, and performs better generally. --- .../cayenne/access/HierarchicalObjectResolver.java | 45 ++++++++++++++-------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java b/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java index 201f304..70d1186 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java @@ -34,10 +34,12 @@ import org.apache.cayenne.query.QueryMetadata; import org.apache.cayenne.reflect.ClassDescriptor; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * Processes a number of DataRow sets corresponding to a given prefetch tree, resolving @@ -207,23 +209,32 @@ class HierarchicalObjectResolver { List<DbJoin> joins, Set<List<Object>> values) { Expression allJoinsQualifier; if(currentQuery != null) { - Expression[] qualifiers = new Expression[values.size()]; - int i = 0; - for(List<Object> joinValues : values) { - allJoinsQualifier = null; - for(int j=0; j<joins.size(); j++) { - Expression joinQualifier = ExpressionFactory - .matchDbExp(pathPrefix + joins.get(j).getTargetName(), joinValues.get(j)); - if (allJoinsQualifier == null) { - allJoinsQualifier = joinQualifier; - } else { - allJoinsQualifier = allJoinsQualifier.andExp(joinQualifier); - } - } - qualifiers[i++] = allJoinsQualifier; - } - - currentQuery.orQualifier(ExpressionFactory.joinExp(Expression.OR, qualifiers)); + int maxIdQualifierSize = context.getParentDataDomain().getMaxIdQualifierSize(); + List<Object> flatValues = joins.size() == 1 && maxIdQualifierSize > 0 + ? values.stream().map(list -> list.get(0)).collect(Collectors.toList()) + : Collections.emptyList(); + if (joins.size() == 1 && maxIdQualifierSize > 0 && flatValues.size() <= maxIdQualifierSize) { + Expression exp = ExpressionFactory.inDbExp(pathPrefix + joins.get(0).getTargetName(), flatValues); + currentQuery.orQualifier(exp); + } else { + Expression[] qualifiers = new Expression[values.size()]; + int i = 0; + for(List<Object> joinValues : values) { + allJoinsQualifier = null; + for(int j=0; j<joins.size(); j++) { + Expression joinQualifier = ExpressionFactory + .matchDbExp(pathPrefix + joins.get(j).getTargetName(), joinValues.get(j)); + if (allJoinsQualifier == null) { + allJoinsQualifier = joinQualifier; + } else { + allJoinsQualifier = allJoinsQualifier.andExp(joinQualifier); + } + } + qualifiers[i++] = allJoinsQualifier; + } + + currentQuery.orQualifier(ExpressionFactory.joinExp(Expression.OR, qualifiers)); + } } }
