Skip to content

Commit

Permalink
relationships: prepare columns to be later optionally included in gro…
Browse files Browse the repository at this point in the history
…uping [closes #548]
  • Loading branch information
hrach committed Mar 6, 2022
1 parent 1d3b57d commit 4c4310f
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 11 deletions.
3 changes: 1 addition & 2 deletions src/Collection/Aggregations/CountAggregator.php
Expand Up @@ -76,13 +76,12 @@ public function aggregateExpression(
);

$primaryKey = $join->conventions->getStoragePrimaryKey()[0];
$groupBy = $expression->groupBy;

return new DbalExpressionResult(
'COUNT(%table.%column) >= %i AND COUNT(%table.%column) <= %i',
[$join->toAlias, $primaryKey, $this->atLeast, $join->toAlias, $primaryKey, $this->atMost],
$joins,
$groupBy,
$expression->groupBy,
null,
true,
null,
Expand Down
6 changes: 4 additions & 2 deletions src/Collection/DbalCollection.php
Expand Up @@ -332,8 +332,8 @@ public function getQueryBuilder(): QueryBuilder
null
);
$joins = $expression->joins;
$groupBy = $expression->groupBy;
if ($expression->isHavingClause) {
$groupBy = $expression->groupBy;
$this->queryBuilder->andHaving($expression->expression, ...$expression->args);
} else {
$this->queryBuilder->andWhere($expression->expression, ...$expression->args);
Expand All @@ -343,7 +343,9 @@ public function getQueryBuilder(): QueryBuilder

foreach ($this->ordering as [$expression, $direction]) {
$joins = array_merge($joins, $expression->joins);
$groupBy = array_merge($groupBy, $expression->groupBy);
if ($expression->isHavingClause) {
$groupBy = array_merge($groupBy, $expression->groupBy);
}
$orderingExpression = $helper->processOrderDirection($expression, $direction);
$this->queryBuilder->addOrderBy('%ex', $orderingExpression);
}
Expand Down
1 change: 1 addition & 0 deletions src/Collection/Helpers/DbalExpressionResult.php
Expand Up @@ -38,6 +38,7 @@ class DbalExpressionResult

/**
* List of arguments possible to pass to %ex modifier.
* Those grouping expressions are applied iff the $isHavingClause is true.
* @var array<array<mixed>>
*/
public $groupBy;
Expand Down
12 changes: 6 additions & 6 deletions src/Collection/Helpers/DbalQueryBuilderHelper.php
Expand Up @@ -322,12 +322,6 @@ private function processTokens(
}
}

if ($makeDistinct) {
$groupBy = $this->makeDistinct($builder, $this->mapper);
} else {
$groupBy = [];
}

$propertyMetadata = $currentEntityMetadata->getProperty($lastToken);
if ($propertyMetadata->wrapper === EmbeddableContainer::class) {
$propertyExpression = implode('->', array_merge($tokens, [$lastToken]));
Expand All @@ -342,6 +336,12 @@ private function processTokens(
$propertyPrefixTokens
);

if ($makeDistinct) {
$groupBy = $this->makeDistinct($builder, $this->mapper);
} else {
$groupBy = [['%column', $column]];
}

return new DbalExpressionResult(
'%column',
[$column],
Expand Down
Expand Up @@ -143,6 +143,16 @@ class RelationshipManyHasOneTest extends DataTestCase
}
Assert::equal(['Nextras publisher A', 'Nextras publisher C'], $publishers);
}


public function testProperAggregation(): void
{
$books = $this->orm->books->findBy([
'tags->id' => 1,
'publisher->name' => 'Nextras publisher A',
]);
Assert::same($books->count(), 1);
}
}


Expand Down
@@ -0,0 +1 @@
SELECT "books".* FROM "books" AS "books" LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books"."id" = "books_x_tags"."book_id") LEFT JOIN "tags" AS "tags_any" ON (("books_x_tags"."tag_id" = "tags_any"."id") AND "tags_any"."id" = 1) LEFT JOIN "publishers" AS "publisher" ON ("books"."publisher_id" = "publisher"."publisher_id") GROUP BY "books"."id", "publisher"."name" HAVING ((COUNT("tags_any"."id") > 0) AND ("publisher"."name" = 'Nextras publisher A'));
@@ -1,3 +1,3 @@
SELECT "publishers".* FROM "publishers" AS "publishers" WHERE (("publishers"."publisher_id" = 1));
SELECT "publisher_id", COUNT(DISTINCT "count") as "count" FROM (SELECT "books".*, "books"."id" AS "count" FROM "books" AS "books" LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books"."id" = "books_x_tags"."book_id") LEFT JOIN "tags" AS "tags_any" ON (("books_x_tags"."tag_id" = "tags_any"."id") AND "tags_any"."id" = 1) WHERE "books"."publisher_id" IN (1) GROUP BY "books"."id" HAVING ((COUNT("tags_any"."id") > 0))) AS "temp" GROUP BY "publisher_id";
SELECT "publisher_id", COUNT(DISTINCT "count") as "count" FROM (SELECT "books".*, "books"."id" AS "count" FROM "books" AS "books" LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books"."id" = "books_x_tags"."book_id") LEFT JOIN "tags" AS "tags_any" ON (("books_x_tags"."tag_id" = "tags_any"."id") AND "tags_any"."id" = 1) WHERE "books"."publisher_id" IN (1) GROUP BY "books"."id" HAVING (("books"."title" = 'Book 1') OR (COUNT("tags_any"."id") > 0))) AS "temp" GROUP BY "publisher_id";
SELECT "publisher_id", COUNT(DISTINCT "count") as "count" FROM (SELECT "books".*, "books"."id" AS "count" FROM "books" AS "books" LEFT JOIN "books_x_tags" AS "books_x_tags" ON ("books"."id" = "books_x_tags"."book_id") LEFT JOIN "tags" AS "tags_any" ON (("books_x_tags"."tag_id" = "tags_any"."id") AND "tags_any"."id" = 1) WHERE "books"."publisher_id" IN (1) GROUP BY "books"."title", "books"."id" HAVING (("books"."title" = 'Book 1') OR (COUNT("tags_any"."id") > 0))) AS "temp" GROUP BY "publisher_id";

0 comments on commit 4c4310f

Please sign in to comment.