Skip to content

Commit

Permalink
collection: auto merge join conditions for the same table (alias) [refs
Browse files Browse the repository at this point in the history
  • Loading branch information
hrach committed Nov 22, 2021
1 parent f0b0479 commit b076881
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/Collection/Functions/JunctionFunctionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@

use Nextras\Dbal\QueryBuilder\QueryBuilder;
use Nextras\Orm\Collection\Helpers\DbalExpressionResult;
use Nextras\Orm\Collection\Helpers\DbalJoinEntry;
use Nextras\Orm\Collection\Helpers\DbalQueryBuilderHelper;
use Nextras\Orm\Collection\Helpers\IDbalAggregator;
use function array_unshift;
use function count;


/**
Expand Down Expand Up @@ -43,6 +46,7 @@ protected function normalizeFunctions(array $args): array

/**
* @param string $dbalModifier either %or or %and dbal modifier
* @param array<int|string, mixed> $args
*/
protected function processQueryBuilderExpressionWithModifier(
string $dbalModifier,
Expand All @@ -66,11 +70,52 @@ protected function processQueryBuilderExpressionWithModifier(

return new DbalExpressionResult(
[$dbalModifier, $processedArgs],
$joins,
$this->rewriteJoins($dbalModifier, $joins),
null,
$isHavingClause,
null,
null
);
}


/**
* @param array<DbalJoinEntry> $joins
* @return array<DbalJoinEntry>
*/
protected function rewriteJoins(string $dbalModifier, array $joins): array
{
if (count($joins) === 0) return [];

/** @var array<array<DbalJoinEntry>> $aggregated */
$aggregated = [];
foreach ($joins as $join) {
$aggregated[$join->toAlias][] = $join;
}

$merged = [];
foreach ($aggregated as $sameJoins) {
if (count($sameJoins) === 1) {
$merged[] = $sameJoins[0];
} else {
$first = $sameJoins[0];
$args = [];
foreach ($sameJoins as $sameJoin) {
$joinArgs = $sameJoin->onArgs;
array_unshift($joinArgs, $sameJoin->onExpression);
$args[] = $joinArgs;
}
$merged[] = new DbalJoinEntry(
$first->toExpression,
$first->toArgs,
$first->toAlias,
$dbalModifier,
[$args],
$first->conventions
);
}
}

return $merged;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace NextrasTests\Orm\Integration\Relationships;


use Nextras\Dbal\IConnection;
use Nextras\Orm\Collection\ICollection;
use Nextras\Orm\Relationships\HasMany;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,19 @@ class RelationshipOneHasManyTest extends DataTestCase
]);
Assert::same(1, $books->countStored());
}


public function testSameTableJoinWithImplicitAggregation(): void
{
$books = $this->orm->books->findBy([
ICollection::OR,
['tags->id' => [1]],
['tags->id' => null], // no match
]);

Assert::same(1, $books->countStored());
Assert::same(1, $books->count());
}
}


Expand Down

0 comments on commit b076881

Please sign in to comment.