diff --git a/src/ORM/Association/Loader/SelectLoader.php b/src/ORM/Association/Loader/SelectLoader.php index f3be34f52fe..b4c88b336e7 100644 --- a/src/ORM/Association/Loader/SelectLoader.php +++ b/src/ORM/Association/Loader/SelectLoader.php @@ -404,7 +404,8 @@ protected function _buildSubquery(Query $query): Query $filterQuery->contain([], true); $filterQuery->setValueBinder(new ValueBinder()); - if (!$filterQuery->clause('limit')) { + // Ignore limit if there is no order since we need all rows to find matches + if (!$filterQuery->clause('limit') || !$filterQuery->clause('order')) { $filterQuery->limit(null); $filterQuery->order([], true); $filterQuery->offset(null); diff --git a/tests/TestCase/ORM/Association/HasManyTest.php b/tests/TestCase/ORM/Association/HasManyTest.php index 33db4741d27..0c16b71160a 100644 --- a/tests/TestCase/ORM/Association/HasManyTest.php +++ b/tests/TestCase/ORM/Association/HasManyTest.php @@ -680,6 +680,51 @@ public function testValueBinderUpdateOnSubQueryStrategy() $this->assertCount(2, $authorsAndArticles->get('articles')); } + /** + * Tests using subquery strategy when parent query + * that contains limit without order. + */ + public function testSubqueryWithLimit() + { + $Authors = $this->getTableLocator()->get('Authors'); + $Authors->hasMany('Articles', [ + 'strategy' => Association::STRATEGY_SUBQUERY, + ]); + + $query = $Authors->find(); + $result = $query + ->contain('Articles') + ->first(); + + if (in_array($result->name, ['mariano', 'larry'])) { + $this->assertNotEmpty($result->articles); + } else { + $this->assertEmpty($result->articles); + } + } + + /** + * Tests using subquery strategy when parent query + * that contains limit with order. + */ + public function testSubqueryWithLimitAndOrder() + { + $Authors = $this->getTableLocator()->get('Authors'); + $Authors->hasMany('Articles', [ + 'strategy' => Association::STRATEGY_SUBQUERY, + ]); + + $query = $Authors->find(); + $result = $query + ->contain('Articles') + ->order(['name' => 'ASC']) + ->limit(2) + ->toArray(); + + $this->assertCount(0, $result[0]->articles); + $this->assertCount(1, $result[1]->articles); + } + /** * Assertion method for order by clause contents. *