Skip to content

Commit

Permalink
Merge pull request #730 from FgForrest/728-referenced-entity-sorting-…
Browse files Browse the repository at this point in the history
…doesnt-work-correctly-if-language-is-part-of-the-query

fix(#728): Referenced entity sorting doesn't work correctly if langua…
  • Loading branch information
novoj authored Nov 4, 2024
2 parents a962b4a + 0b32a81 commit c61d6de
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,12 @@ private static void sortAndFilterSubList(
final ReferenceDecorator[] filteredReferences = Arrays.stream(references, start, end)
.filter(it -> referenceFilter.test(entityPrimaryKey, it))
.toArray(ReferenceDecorator[]::new);
Arrays.sort(filteredReferences, referenceComparator);

for (int i = start; i < end; i++) {
final int filteredIndex = i - start;
references[i] = filteredReferences.length > filteredIndex ? filteredReferences[filteredIndex] : null;
}
Arrays.sort(references, start, end, referenceComparator);
}
nonSortedReferenceCount = referenceComparator.getNonSortedReferenceCount();
start = start + (end - nonSortedReferenceCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* | __/\ V /| | || (_| | |_| | |_) |
* \___| \_/ |_|\__\__,_|____/|____/
*
* Copyright (c) 2023
* Copyright (c) 2023-2024
*
* Licensed under the Business Source License, Version 1.1 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -123,7 +123,7 @@ private SortableAttributeCompoundSchema(
* Part of PRIVATE API, because we need to ensure the `attributeSchemaProvider` always provide the same and correct
* attribute schemas from the same entity schema version.
*/
public boolean isLocalized(@Nonnull Function<String, AttributeSchema> attributeSchemaProvider) {
public boolean isLocalized(@Nonnull Function<String, ? extends AttributeSchemaContract> attributeSchemaProvider) {
if (this.memoizedLocalized == null) {
this.memoizedLocalized = attributeElements
.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.evitadb.api.requestResponse.schema.NamedSchemaContract;
import io.evitadb.api.requestResponse.schema.SortableAttributeCompoundSchemaContract;
import io.evitadb.api.requestResponse.schema.SortableAttributeCompoundSchemaContract.AttributeElement;
import io.evitadb.api.requestResponse.schema.dto.SortableAttributeCompoundSchema;
import io.evitadb.core.query.AttributeSchemaAccessor.AttributeTrait;
import io.evitadb.core.query.sort.EntityComparator;
import io.evitadb.core.query.sort.OrderByVisitor;
Expand Down Expand Up @@ -159,14 +160,18 @@ public void createComparator(@Nonnull AttributeNatural attributeNatural, @Nonnul
) {
if (orderDirection == ASC) {
comparator = new ReferencePredecessorComparator(
attributeOrCompoundName, locale, orderByVisitor,
attributeOrCompoundName,
attributeSchema.isLocalized() ? locale : null,
orderByVisitor,
ChainIndex::getAscendingOrderRecordsSupplier,
(ref1, ref2) -> ref1.primaryKey() == ref2.primaryKey(),
(epk, referenceKey) -> epk
);
} else {
comparator = new ReferencePredecessorComparator(
attributeOrCompoundName, locale, orderByVisitor,
attributeOrCompoundName,
attributeSchema.isLocalized() ? locale : null,
orderByVisitor,
ChainIndex::getDescendingOrderRecordsSupplier,
(ref1, ref2) -> ref1.primaryKey() == ref2.primaryKey(),
(epk, referenceKey) -> epk
Expand All @@ -177,28 +182,36 @@ public void createComparator(@Nonnull AttributeNatural attributeNatural, @Nonnul
) {
if (orderDirection == ASC) {
comparator = new ReferencePredecessorComparator(
attributeOrCompoundName, locale, orderByVisitor,
attributeOrCompoundName,
attributeSchema.isLocalized() ? locale : null,
orderByVisitor,
ChainIndex::getAscendingOrderRecordsSupplier,
(ref1, ref2) -> true,
(epk, referenceKey) -> referenceKey.primaryKey()
);
} else {
comparator = new ReferencePredecessorComparator(
attributeOrCompoundName, locale, orderByVisitor,
attributeOrCompoundName,
attributeSchema.isLocalized() ? locale : null,
orderByVisitor,
ChainIndex::getDescendingOrderRecordsSupplier,
(ref1, ref2) -> true,
(epk, referenceKey) -> referenceKey.primaryKey()
);
}
} else if (attributeOrCompoundSchema instanceof SortableAttributeCompoundSchemaContract compoundSchemaContract) {
} else if (attributeOrCompoundSchema instanceof SortableAttributeCompoundSchema compoundSchemaContract) {
comparator = new ReferenceCompoundAttributeComparator(
compoundSchemaContract, locale,
compoundSchemaContract,
compoundSchemaContract.isLocalized(orderByVisitor::getAttributeSchema) ? locale : null,
orderByVisitor::getAttributeSchema,
orderDirection
);
} else if (attributeOrCompoundSchema instanceof AttributeSchemaContract attributeSchema) {
comparator = new ReferenceAttributeComparator(
attributeOrCompoundName, attributeSchema.getPlainType(), locale, orderDirection
attributeOrCompoundName,
attributeSchema.getPlainType(),
attributeSchema.isLocalized() ? locale : null,
orderDirection
);
} else {
throw new GenericEvitaInternalError("Unsupported attribute schema type: " + attributeOrCompoundSchema);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,11 @@ private IntHashSet getNonSortedReferences() {
* if not found in the cache.
*/
private int getRecordPosition(@Nonnull ReferenceKey referenceKey) {
final int pkToLookup = primaryKeyResolver.applyAsInt(this.entityPrimaryKey, referenceKey);
final int pkToLookup = this.primaryKeyResolver.applyAsInt(this.entityPrimaryKey, referenceKey);
final int position = this.pkToRecordPositionCache.getOrDefault(pkToLookup, -1);
if (position == -1) {
final ChainIndex chainIndex = this.referenceOrderByVisitor.getChainIndex(this.entityPrimaryKey, referenceKey, attributeKey).orElse(null);
final SortedRecordsProvider sortedRecordsSupplier = chainIndex == null ? SortedRecordsProvider.EMPTY : sortedRecordsSupplierProvider.apply(chainIndex);
final ChainIndex chainIndex = this.referenceOrderByVisitor.getChainIndex(this.entityPrimaryKey, referenceKey, this.attributeKey).orElse(null);
final SortedRecordsProvider sortedRecordsSupplier = chainIndex == null ? SortedRecordsProvider.EMPTY : this.sortedRecordsSupplierProvider.apply(chainIndex);
final int index = sortedRecordsSupplier.getAllRecords().indexOf(pkToLookup);
final int computedPosition = index < 0 ? -2 : sortedRecordsSupplier.getRecordPositions()[index];
this.pkToRecordPositionCache.put(pkToLookup, computedPosition);
Expand Down

0 comments on commit c61d6de

Please sign in to comment.