From e4a01197299f2ce357ffb41bcb9130be24928783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Novotn=C3=BD?= Date: Wed, 18 Dec 2024 13:49:25 +0100 Subject: [PATCH] fix: scopes are not passed to nested queries --- .../api/requestResponse/EvitaRequest.java | 84 ++++++++++--------- .../core/query/ReferencedEntityFetcher.java | 15 +++- .../ExtraResultPlanningVisitor.java | 5 +- .../reference/EntityHavingTranslator.java | 4 +- 4 files changed, 61 insertions(+), 47 deletions(-) diff --git a/evita_api/src/main/java/io/evitadb/api/requestResponse/EvitaRequest.java b/evita_api/src/main/java/io/evitadb/api/requestResponse/EvitaRequest.java index fed1d8f57..85c946e36 100644 --- a/evita_api/src/main/java/io/evitadb/api/requestResponse/EvitaRequest.java +++ b/evita_api/src/main/java/io/evitadb/api/requestResponse/EvitaRequest.java @@ -80,46 +80,46 @@ public class EvitaRequest { private final String entityType; private final Locale implicitLocale; @Getter private final Class expectedType; - private int[] primaryKeys; + @Nullable private int[] primaryKeys; private boolean localeExamined; - private Locale locale; - private Boolean requiredLocales; - private Set requiredLocaleSet; + @Nullable private Locale locale; + @Nullable private Boolean requiredLocales; + @Nullable private Set requiredLocaleSet; private QueryPriceMode queryPriceMode; private Boolean priceValidInTimeSet; - private OffsetDateTime priceValidInTime; + @Nullable private OffsetDateTime priceValidInTime; private Boolean requiresEntity; - private Boolean requiresParent; - private HierarchyContent parentContent; - private EntityFetch entityRequirement; - private Boolean entityAttributes; - private Set entityAttributeSet; - private Boolean entityAssociatedData; - private Set entityAssociatedDataSet; - private Boolean entityReference; - private PriceContentMode entityPrices; + @Nullable private Boolean requiresParent; + @Nullable private HierarchyContent parentContent; + @Nullable private EntityFetch entityRequirement; + @Nullable private Boolean entityAttributes; + @Nullable private Set entityAttributeSet; + @Nullable private Boolean entityAssociatedData; + @Nullable private Set entityAssociatedDataSet; + @Nullable private Boolean entityReference; + @Nullable private PriceContentMode entityPrices; private Boolean currencySet; - private Currency currency; + @Nullable private Currency currency; private Boolean requiresPriceLists; private String[] priceLists; private String[] additionalPriceLists; - private Integer start; - private ConditionalGap[] conditionalGaps; - private Map hierarchyWithin; - private Boolean requiredWithinHierarchy; - private Boolean requiresHierarchyStatistics; - private Boolean requiresHierarchyParents; - private Integer limit; - private EvitaRequest.ResultForm resultForm; - private Map facetGroupConjunction; - private Map facetGroupDisjunction; - private Map facetGroupNegation; + @Nullable private Integer start; + @Nullable private ConditionalGap[] conditionalGaps; + @Nullable private Map hierarchyWithin; + @Nullable private Boolean requiredWithinHierarchy; + @Nullable private Boolean requiresHierarchyStatistics; + @Nullable private Boolean requiresHierarchyParents; + @Nullable private Integer limit; + @Nullable private EvitaRequest.ResultForm resultForm; + @Nullable private Map facetGroupConjunction; + @Nullable private Map facetGroupDisjunction; + @Nullable private Map facetGroupNegation; private Boolean queryTelemetryRequested; - private EnumSet debugModes; + @Nullable private EnumSet debugModes; private Scope[] scopesAsArray; - private Set scopes; - private Map entityFetchRequirements; - private RequirementContext defaultReferenceRequirement; + @Nullable private Set scopes; + @Nullable private Map entityFetchRequirements; + @Nullable private RequirementContext defaultReferenceRequirement; /** * Parses the requirement context from the passed {@link ReferenceContent} and {@link AttributeContent}. @@ -269,9 +269,10 @@ public EvitaRequest( public EvitaRequest( @Nonnull EvitaRequest evitaRequest, @Nonnull String entityType, - @Nonnull FilterBy filterBy, + @Nullable FilterBy filterBy, @Nullable OrderBy orderBy, - @Nullable Locale locale + @Nullable Locale locale, + @Nullable Set scopes ) { this.requiresEntity = true; @@ -877,20 +878,20 @@ public Map getReferenceEntityFetch() { */ @Nullable public HierarchyFilterConstraint getHierarchyWithin(@Nullable String referenceName) { - if (requiredWithinHierarchy == null) { - if (query.getFilterBy() == null) { - hierarchyWithin = Collections.emptyMap(); + if (this.requiredWithinHierarchy == null) { + if (this.query.getFilterBy() == null) { + this.hierarchyWithin = Collections.emptyMap(); } else { - hierarchyWithin = new HashMap<>(); + this.hierarchyWithin = new HashMap<>(); QueryUtils.findConstraints( query.getFilterBy(), HierarchyFilterConstraint.class ) - .forEach(it -> hierarchyWithin.put(it.getReferenceName().orElse(null), it)); + .forEach(it -> this.hierarchyWithin.put(it.getReferenceName().orElse(null), it)); } - requiredWithinHierarchy = true; + this.requiredWithinHierarchy = true; } - return hierarchyWithin.get(referenceName); + return this.hierarchyWithin == null ? null : this.hierarchyWithin.get(referenceName); } /** @@ -916,11 +917,12 @@ public EvitaRequest deriveCopyWith( @Nonnull String entityType, @Nullable FilterBy filterConstraint, @Nullable OrderBy orderConstraint, - @Nullable Locale locale + @Nullable Locale locale, + @Nonnull Set scopes ) { return new EvitaRequest( this, - entityType, filterConstraint, orderConstraint, locale + entityType, filterConstraint, orderConstraint, locale, scopes ); } diff --git a/evita_engine/src/main/java/io/evitadb/core/query/ReferencedEntityFetcher.java b/evita_engine/src/main/java/io/evitadb/core/query/ReferencedEntityFetcher.java index e61f8c13f..baa91b35e 100644 --- a/evita_engine/src/main/java/io/evitadb/core/query/ReferencedEntityFetcher.java +++ b/evita_engine/src/main/java/io/evitadb/core/query/ReferencedEntityFetcher.java @@ -696,8 +696,11 @@ private static void initializeComparatorFromGlobalIndex( final OrderBy orderBy = new OrderBy(entityOrderBy.getChildren()); final QueryPlanningContext nestedQueryContext = targetEntityCollection.createQueryContext( evitaRequest.deriveCopyWith( - targetEntityCollection.getEntityType(), null, orderBy, - entityNestedQueryComparator.getLocale() + targetEntityCollection.getEntityType(), + null, + orderBy, + entityNestedQueryComparator.getLocale(), + evitaRequest.getScopes() ), evitaSession ); @@ -718,7 +721,13 @@ private static void initializeComparatorFromGlobalIndex( final OrderBy orderBy = new OrderBy(entityGroupOrderBy.getChildren()); final QueryPlanningContext nestedQueryContext = targetEntityGroupCollection.createQueryContext( - evitaRequest.deriveCopyWith(targetEntityGroupCollection.getEntityType(), null, orderBy, entityNestedQueryComparator.getLocale()), + evitaRequest.deriveCopyWith( + targetEntityGroupCollection.getEntityType(), + null, + orderBy, + entityNestedQueryComparator.getLocale(), + evitaRequest.getScopes() + ), evitaSession ); diff --git a/evita_engine/src/main/java/io/evitadb/core/query/extraResult/ExtraResultPlanningVisitor.java b/evita_engine/src/main/java/io/evitadb/core/query/extraResult/ExtraResultPlanningVisitor.java index bb6275659..40fb5ef85 100644 --- a/evita_engine/src/main/java/io/evitadb/core/query/extraResult/ExtraResultPlanningVisitor.java +++ b/evita_engine/src/main/java/io/evitadb/core/query/extraResult/ExtraResultPlanningVisitor.java @@ -397,6 +397,7 @@ public NestedContextSorter createSorter( QueryPhase.PLANNING_SORT, stepDescriptionSupplier ); + final Set scopes = getProcessingScope().getScopes(); // we have to create and trap the nested query context here to carry it along with the sorter // otherwise the sorter will target and use the incorrectly originally queried (prefetched) entities final QueryPlanningContext nestedQueryContext = entityCollection.createQueryContext( @@ -405,12 +406,12 @@ public NestedContextSorter createSorter( entityType, null, new OrderBy(orderBy.getChildren()), - this.queryContext.getLocale() + this.queryContext.getLocale(), + scopes ), this.queryContext.getEvitaSession() ); - final Set scopes = getProcessingScope().getScopes(); final GlobalEntityIndex[] entityIndexes = scopes.stream() .map(scope -> entityCollection.getIndexByKeyIfExists(new EntityIndexKey(EntityIndexType.GLOBAL, scope))) .map(GlobalEntityIndex.class::cast) diff --git a/evita_engine/src/main/java/io/evitadb/core/query/filter/translator/reference/EntityHavingTranslator.java b/evita_engine/src/main/java/io/evitadb/core/query/filter/translator/reference/EntityHavingTranslator.java index b70ee9cb0..e937c2643 100644 --- a/evita_engine/src/main/java/io/evitadb/core/query/filter/translator/reference/EntityHavingTranslator.java +++ b/evita_engine/src/main/java/io/evitadb/core/query/filter/translator/reference/EntityHavingTranslator.java @@ -61,6 +61,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.Objects; import java.util.function.Function; @@ -130,7 +131,8 @@ private static List planNestedQuery( .orElse(null), ofNullable(entityNestedQueryComparator) .map(EntityNestedQueryComparator::getLocale) - .orElse(null) + .orElse(null), + EnumSet.of(globalIndex.getIndexKey().scope()) ), filterByVisitor.getEvitaSession() );