diff --git a/query/src/main/kotlin/jetbrains/exodus/query/SortEngine.kt b/query/src/main/kotlin/jetbrains/exodus/query/SortEngine.kt index 749e6cbcd..0844fd43d 100644 --- a/query/src/main/kotlin/jetbrains/exodus/query/SortEngine.kt +++ b/query/src/main/kotlin/jetbrains/exodus/query/SortEngine.kt @@ -21,6 +21,7 @@ import jetbrains.exodus.entitystore.EntityIterable import jetbrains.exodus.entitystore.orientdb.OEntityIterable import jetbrains.exodus.entitystore.orientdb.OVertexEntity import jetbrains.exodus.entitystore.orientdb.iterate.OEntityIterableBase +import jetbrains.exodus.entitystore.orientdb.iterate.link.OMultipleEntitiesIterable import jetbrains.exodus.query.metadata.ModelMetaData open class SortEngine { @@ -68,7 +69,7 @@ open class SortEngine { source: Iterable, asc: Boolean ): Iterable { - if (source is OEntityIterable) { + if (source is OEntityIterable && source !is OMultipleEntitiesIterable) { val txn = queryEngine.persistentStore.andCheckCurrentTransaction return txn.sort(entityType, "${OVertexEntity.edgeClassName(linkName)}.$propName", source.unwrap(), asc) } else { diff --git a/query/src/test/kotlin/jetbrains/exodus/query/OQueryEngineTest.kt b/query/src/test/kotlin/jetbrains/exodus/query/OQueryEngineTest.kt index 0afbd65f3..b18c3f386 100644 --- a/query/src/test/kotlin/jetbrains/exodus/query/OQueryEngineTest.kt +++ b/query/src/test/kotlin/jetbrains/exodus/query/OQueryEngineTest.kt @@ -22,6 +22,7 @@ import jetbrains.exodus.entitystore.Entity import jetbrains.exodus.entitystore.EntityIterable import jetbrains.exodus.entitystore.orientdb.OStoreTransaction import jetbrains.exodus.entitystore.orientdb.iterate.OEntityIterableBase +import jetbrains.exodus.entitystore.orientdb.iterate.link.OMultipleEntitiesIterable import jetbrains.exodus.entitystore.orientdb.testutil.* import jetbrains.exodus.query.metadata.EntityMetaData import jetbrains.exodus.query.metadata.ModelMetaData @@ -53,7 +54,13 @@ class OQueryEngineTest( it.id.typeId >= 0 } InMemoryEntityIterable(filteringSequence.asIterable(), currentTx, engine) - }, "InMemory") + }, "InMemory"), + arrayOf({ engine: QueryEngine, currentTx: OStoreTransaction -> + val filteringSequence = engine.instantiateGetAll(Issues.CLASS).asSequence().filter { + it.id.typeId >= 0 + } + OMultipleEntitiesIterable(currentTx, filteringSequence.toList()) + }, "MultipleEntitiesIterable") ) } } @@ -644,6 +651,37 @@ class OQueryEngineTest( } } + @Test + fun `should query by property sorted`() { + // Given + val test = givenTestCase() + + val metadata = givenModelMetadata().withEntityMetaData(Issues.CLASS) + val engine = givenOQueryEngine(metadata) + + // When + withStoreTx { tx -> + val sortByPropertyAsc = SortByProperty( + null, // child node + "name", // link property name + true // ascending + ) + val issuesAsc = engine.query(iterableGetter(engine, tx), Issues.CLASS, sortByPropertyAsc) + + val sortByLinkPropertyDesc = SortByProperty( + null, // child node + "name", // link property name + false // descending + ) + val issuesDesc = engine.query(iterableGetter(engine, tx), Issues.CLASS, sortByLinkPropertyDesc) + + // Then + // As sorted by project name + assertOrderedNamesExactly(issuesDesc, "issue3", "issue2", "issue1") + assertOrderedNamesExactly(issuesAsc, "issue1", "issue2", "issue3") + } + } + private fun assertOrderedNamesExactly(result: Iterable, vararg names: String) { assertThat(result.map { it.getProperty("name") }).containsExactly(*names).inOrder() }