protected function fetchByTwoPassStrategy(QueryBuilder $builder, array $values, IEntityPreloadContainer $preloadContainer = NULL) { $builder = clone $builder; $targetPrimaryKey = $this->targetMapper->getStorageReflection()->getStoragePrimaryKey(); $isComposite = count($targetPrimaryKey) !== 1; foreach (array_unique(array_merge($targetPrimaryKey, [$this->joinStorageKey])) as $key) { $builder->addSelect("[{$key}]"); } $sqls = $args = []; foreach ($values as $primaryValue) { $builderPart = clone $builder; $builderPart->andWhere("%column = %any", $this->joinStorageKey, $primaryValue); $sqls[] = $builderPart->getQuerySQL(); $args = array_merge($args, $builderPart->getQueryParameters()); } $query = '(' . implode(') UNION ALL (', $sqls) . ')'; $result = $this->connection->queryArgs($query, $args); $map = $ids = []; if ($isComposite) { foreach ($result as $row) { $id = []; foreach ($targetPrimaryKey as $key) { $id[] = $row->{$key}; } $ids[] = $id; $map[$row->{$this->joinStorageKey}][] = implode(',', $id); } } else { $targetPrimaryKey = $targetPrimaryKey[0]; foreach ($result as $row) { $ids[] = $row->{$targetPrimaryKey}; $map[$row->{$this->joinStorageKey}][] = $row->{$targetPrimaryKey}; } } if (count($ids) === 0) { return new EntityIterator([], $preloadContainer); } if ($isComposite) { $builder = $this->targetMapper->builder(); $builder->andWhere('%column[] IN %any', $targetPrimaryKey, $ids); $entitiesResult = []; $collection = $this->targetMapper->toCollection($builder); foreach ($collection as $entity) { $entitiesResult[implode(',', $entity->getValue('id'))] = $entity; } } else { $entitiesResult = $this->targetRepository->findBy([$targetPrimaryKey => $ids])->fetchPairs($targetPrimaryKey, NULL); } $entities = []; foreach ($map as $joiningStorageKey => $primaryValues) { foreach ($primaryValues as $primaryValue) { $entity = $entitiesResult[$primaryValue]; $entities[$entity->getRawValue($this->metadata->relationship->property)][] = $entity; } } return new EntityIterator($entities, $preloadContainer); }