• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/orm/query/queryhelper.php
  • Класс: BitrixMainORMQueryQueryHelper
  • Вызов: QueryHelper::decompose
static function decompose(Query $query, $fairLimit = true, $separateRelations = true)
{
	$entity = $query->getEntity();
	$primaryNames = $entity->getPrimaryArray();
	$originalSelect = $query->getSelect();

	if ($fairLimit)
	{
		// select distinct primary
		$query->setSelect($entity->getPrimaryArray());
		$query->setDistinct();

		$rows = $query->fetchAll();

		// return empty result
		if (empty($rows))
		{
			return $query->getEntity()->createCollection();
		}

		// reset query
		$query = $entity->getDataClass()::query();
		$query->setSelect($originalSelect);
		$query->where(static::getPrimaryFilter($primaryNames, $rows));
	}

	// more than one OneToMany or ManyToMany
	if ($separateRelations)
	{
		$commonSelect = [];
		$dividedSelect = [];

		foreach ($originalSelect as $selectItem)
		{
			// init query with select item
			$selQuery = $entity->getDataClass()::query();
			$selQuery->addSelect($selectItem);
			$selQuery->getQuery(true);

			// check for relations
			foreach ($selQuery->getChains() as $chain)
			{
				if ($chain->hasBackReference())
				{
					$dividedSelect[] = $selectItem;
					continue 2;
				}
			}

			$commonSelect[] = $selectItem;
		}

		if (empty($commonSelect))
		{
			$commonSelect = $query->getEntity()->getPrimaryArray();
		}

		// common query
		$query->setSelect($commonSelect);
	}

	/** @var Collection $collection query data */
	$collection = $query->fetchCollection();

	if (!empty($dividedSelect) && $collection->count())
	{
		// custom identity map & collect primaries
		$im = new IdentityMap;
		$primaryValues = [];

		foreach ($collection as $object)
		{
			$im->put($object);

			$primaryValues[] = $object->primary;
		}

		$primaryFilter = static::getPrimaryFilter($primaryNames, $primaryValues);

		// select relations
		foreach ($dividedSelect as $selectItem)
		{
			$result = $entity->getDataClass()::query()
				->addSelect($selectItem)
				->where($primaryFilter)
				->exec();

			$result->setIdentityMap($im);
			$result->fetchCollection();
		}
	}

	return $collection;
}