Skip to content

Commit

Permalink
FIX Use ORM functions to perform eager loading instead of raw query
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevinn1109 committed Dec 16, 2024
1 parent bd7c2af commit 53e7761
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions src/ORM/DataList.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\Debug;
use SilverStripe\ORM\Queries\SQLConditionGroup;
use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\View\ViewableData;
use Exception;
use InvalidArgumentException;
Expand Down Expand Up @@ -1349,6 +1350,10 @@ private function fetchEagerLoadManyMany(
$fetchList = $relationList->forForeignID($parentIDs);
$fetchList = $this->manipulateEagerLoadingQuery($fetchList, $relationChain, $relationType);
$fetchedRows = $fetchList->getFinalisedQuery();
$query = $fetchList->dataQuery()->query();
$fetchedOrderBy = $query->getOrderBy();
$childTables = $query->queriedTables();
$childTable = reset($childTables);

foreach ($fetchedRows as $row) {
$fetchedRowsArray[$row['ID']] = $row;
Expand All @@ -1361,15 +1366,18 @@ private function fetchEagerLoadManyMany(
$joinRows = [];
if (!empty($parentIDs) && !empty($fetchedIDs)) {
$fetchedIDsAsString = implode(',', $fetchedIDs);
$joinRows = DB::query(
'SELECT * FROM "' . $joinTable
$joinRows = SQLSelect::create()
// Only select join columns to avoid ambiguity with joined child table columns
->setSelect('"' . $joinTable . '".' . "*")
->setFrom('"' . $joinTable . '"')
// Only get joins relevant for the parent list
. '" WHERE "' . $parentIDField . '" IN (' . implode(',', $parentIDs) . ')'
// Exclude any children that got filtered out
. ' AND ' . $childIDField . ' IN (' . $fetchedIDsAsString . ')'
// Respect sort order of fetched items
. ' ORDER BY FIELD(' . $childIDField . ', ' . $fetchedIDsAsString . ')'
);
->addWhere('"' . $joinTable . '"."' . $parentIDField . '" IN (' . implode(',', $parentIDs) . ')')
// Exclude children that got filtered out
->addWhere('"' . $joinTable . '"."' . $childIDField . '" IN (' . $fetchedIDsAsString . ')')
// Respect sort order of fetched children by joining child table and using its order by clause
->addLeftJoin($childTable, "$childTable.ID = $joinTable.$childIDField")
->setOrderBy($fetchedOrderBy)
->execute();
}

// Store the children in an EagerLoadedList against the correct parent
Expand Down

0 comments on commit 53e7761

Please sign in to comment.