Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
hrach committed Mar 8, 2024
1 parent b91957f commit b6f90d6
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
18 changes: 17 additions & 1 deletion src/Mapper/Dbal/RelationshipMapperManyHasMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Nextras\Orm\Entity\IEntityHasPreloadContainer;
use Nextras\Orm\Entity\Reflection\PropertyMetadata;
use Nextras\Orm\Exception\LogicException;
use Nextras\Orm\Exception\NotSupportedException;
use Nextras\Orm\Mapper\IRelationshipMapperManyHasMany;
use function array_keys;
use function array_merge;
Expand Down Expand Up @@ -138,6 +139,9 @@ private function fetchByTwoPassStrategy(QueryBuilder $builder, array $values): M
/** @var literal-string $targetTable */
$targetTable = DbalQueryBuilderHelper::getAlias($this->joinTable);

$hasJoins = $builder->getClause('join')[0] !== null;
$hasOrderBy = $builder->getClause('order')[0] !== null;

$builder = clone $builder;
$builder->joinLeft(
"%table AS %table",
Expand All @@ -148,18 +152,30 @@ private function fetchByTwoPassStrategy(QueryBuilder $builder, array $values): M
"$targetTable.{$this->primaryKeyTo}",
"{$sourceTable}." . $this->targetMapper->getConventions()->getStoragePrimaryKey()[0],
);

$builder->select('%column', "$targetTable.$this->primaryKeyTo");
$builder->addSelect('%column', "$targetTable.$this->primaryKeyFrom");
if ($builder->getClause('having')[0] !== null) {

if ($hasJoins && !$hasOrderBy) {
$builder->addGroupBy('%column', "$targetTable.$this->primaryKeyTo");
$builder->addGroupBy('%column', "$targetTable.$this->primaryKeyFrom");
}

if ($builder->hasLimitOffsetClause()) {
if ($hasJoins && $hasOrderBy) {
throw new NotSupportedException(
"Relationship cannot be fetched as it combines has-many joins, ORDER BY and LIMIT clause.",
);
}
$result = $this->processMultiResult($builder, $values, $targetTable);

} else {
$builder->andWhere('%column IN %any', "$targetTable.$this->primaryKeyFrom", $values);
if ($hasJoins && $hasOrderBy) {
$builder = $this->connection->createQueryBuilder()
->select('DISTINCT *')
->from('(' . $builder->getQuerySql() . ')', '__tmp', ...$builder->getQueryParameters());
}
$result = $this->connection->queryByQueryBuilder($builder);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ class RelationshipManyHasManyTest extends DataTestCase

$books = $tag->books->findBy([
'author->tagFollowers->author->id' => 1,
]);
])->orderBy('title');
Assert::same(1, $books->count());
Assert::same(1, $books->countStored());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SELECT "tags".* FROM "tags" AS "tags" WHERE (("tags"."id" = 1));
SELECT "books_x_tags"."book_id", "books_x_tags"."tag_id" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE ((("author"."id" = 1))) AND ("books_x_tags"."tag_id" IN (1));
SELECT "books_x_tags"."book_id", "books_x_tags"."tag_id" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE ((("author"."id" = 1))) AND ("books_x_tags"."tag_id" IN (1)) GROUP BY "books_x_tags"."book_id", "books_x_tags"."tag_id";
SELECT "books".* FROM "books" AS "books" WHERE (("books"."id" IN (1)));
SELECT "books_x_tags"."tag_id", COUNT(DISTINCT "books_x_tags"."book_id") AS "count" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE ((("author"."id" = 1))) AND ("books_x_tags"."tag_id" IN (1)) GROUP BY "books_x_tags"."tag_id";
SELECT "books_x_tags"."book_id", "books_x_tags"."tag_id" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "tag_followers" AS "author_tagFollowers_any" ON ("author"."id" = "author_tagFollowers_any"."author_id") LEFT JOIN "public"."authors" AS "author_tagFollowers_author_any" ON (("author_tagFollowers_any"."author_id" = "author_tagFollowers_author_any"."id") AND "author_tagFollowers_author_any"."id" = 1) LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE "books_x_tags"."tag_id" IN (1) GROUP BY "books"."id", "books_x_tags"."book_id", "books_x_tags"."tag_id" HAVING ((COUNT("author_tagFollowers_author_any"."id") > 0));
SELECT DISTINCT * FROM (SELECT "books_x_tags"."book_id", "books_x_tags"."tag_id" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "tag_followers" AS "author_tagFollowers_any" ON ("author"."id" = "author_tagFollowers_any"."author_id") LEFT JOIN "public"."authors" AS "author_tagFollowers_author_any" ON ("author_tagFollowers_any"."author_id" = "author_tagFollowers_author_any"."id") LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE ((("author_tagFollowers_author_any"."id" = 1))) AND ("books_x_tags"."tag_id" IN (1)) ORDER BY "books"."title" ASC) AS "__tmp";
SELECT "books".* FROM "books" AS "books" WHERE (("books"."id" IN (1)));
SELECT "books_x_tags"."tag_id", COUNT(DISTINCT "books_x_tags"."book_id") AS "count" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "tag_followers" AS "author_tagFollowers_any" ON ("author"."id" = "author_tagFollowers_any"."author_id") LEFT JOIN "public"."authors" AS "author_tagFollowers_author_any" ON (("author_tagFollowers_any"."author_id" = "author_tagFollowers_author_any"."id") AND "author_tagFollowers_author_any"."id" = 1) LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE "books_x_tags"."tag_id" IN (1) GROUP BY "books"."id", "books_x_tags"."tag_id" HAVING ((COUNT("author_tagFollowers_author_any"."id") > 0));
SELECT "books_x_tags"."tag_id", COUNT(DISTINCT "books_x_tags"."book_id") AS "count" FROM "books" AS "books" LEFT JOIN "public"."authors" AS "author" ON ("books"."author_id" = "author"."id") LEFT JOIN "tag_followers" AS "author_tagFollowers_any" ON ("author"."id" = "author_tagFollowers_any"."author_id") LEFT JOIN "public"."authors" AS "author_tagFollowers_author_any" ON ("author_tagFollowers_any"."author_id" = "author_tagFollowers_author_any"."id") LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books_x_tags"."book_id" = "books"."id") WHERE ((("author_tagFollowers_author_any"."id" = 1))) AND ("books_x_tags"."tag_id" IN (1)) GROUP BY "books_x_tags"."tag_id";

0 comments on commit b6f90d6

Please sign in to comment.