/** * Add required JOINs to resulting Query Builder. * * @param QueryBuilder $qb * @param array $parts * @return bool */ protected function addJoins(QueryBuilder $qb, array $parts) { // Collect list of tables which should be added to new query $requiredToJoin = $this->qbTools->getUsedTableAliases($parts['where']); $requiredToJoin = array_merge($requiredToJoin, $this->qbTools->getUsedTableAliases($parts['groupBy'])); $requiredToJoin = array_merge($requiredToJoin, $this->qbTools->getUsedTableAliases($parts['having'])); $requiredToJoin = array_merge($requiredToJoin, $this->qbTools->getUsedJoinAliases($parts['join'], $requiredToJoin, $this->rootAlias)); $requiredToJoin = array_diff(array_unique($requiredToJoin), array($this->rootAlias)); /** @var Expr\Join $join */ $hasJoins = false; foreach ($parts['join'][$this->rootAlias] as $join) { $alias = $join->getAlias(); // To count results number join all tables with inner join and required to tables if ($join->getJoinType() == Expr\Join::INNER_JOIN || in_array($alias, $requiredToJoin)) { $hasJoins = true; $condition = $this->qbTools->replaceAliasesWithFields($join->getCondition()); $condition = $this->qbTools->replaceAliasesWithJoinPaths($condition); if ($join->getJoinType() == Expr\Join::INNER_JOIN) { $qb->innerJoin($join->getJoin(), $alias, $join->getConditionType(), $condition, $join->getIndexBy()); } else { $qb->leftJoin($join->getJoin(), $alias, $join->getConditionType(), $condition, $join->getIndexBy()); } } } return $hasJoins; }
/** * Add required JOINs to resulting Query Builder. * * @param QueryBuilder $optimizedQueryBuilder * @param array $originalQueryParts */ protected function addJoins(QueryBuilder $optimizedQueryBuilder, array $originalQueryParts) { // Collect list of tables which should be added to new query $whereAliases = $this->qbTools->getUsedTableAliases($originalQueryParts['where']); $groupByAliases = $this->qbTools->getUsedTableAliases($originalQueryParts['groupBy']); $havingAliases = $this->qbTools->getUsedTableAliases($originalQueryParts['having']); $joinAliases = array_merge($whereAliases, $groupByAliases, $havingAliases); $joinAliases = array_unique($joinAliases); // this joins cannot be removed outside of this class $requiredJoinAliases = $joinAliases; $joinAliases = array_merge($joinAliases, $this->getNonSymmetricJoinAliases($originalQueryParts['from'], $originalQueryParts['join'], $groupByAliases)); $rootAliases = []; /** @var Expr\From $from */ foreach ($originalQueryParts['from'] as $from) { $rootAliases[] = $from->getAlias(); $joinAliases = array_merge($joinAliases, $this->qbTools->getUsedJoinAliases($originalQueryParts['join'], $joinAliases, $from->getAlias())); } $allAliases = $this->context->getAliases(); $joinAliases = array_intersect(array_diff(array_unique($joinAliases), $rootAliases), $allAliases); $requiredJoinAliases = array_intersect(array_diff($requiredJoinAliases, $rootAliases), $allAliases); $joinAliases = $this->dispatchQueryOptimizationEvent($joinAliases, $requiredJoinAliases); foreach ($rootAliases as $rootAlias) { if (!isset($originalQueryParts['join'][$rootAlias])) { continue; } /** @var Expr\Join $join */ foreach ($originalQueryParts['join'][$rootAlias] as $join) { $alias = $join->getAlias(); // To count results number join all tables with inner join and required to tables if ($join->getJoinType() === Expr\Join::INNER_JOIN || in_array($alias, $joinAliases, true)) { $condition = $this->qbTools->replaceAliasesWithFields($join->getCondition()); $condition = $this->qbTools->replaceAliasesWithJoinPaths($condition); if ($join->getJoinType() === Expr\Join::INNER_JOIN) { $optimizedQueryBuilder->innerJoin($join->getJoin(), $alias, $join->getConditionType(), $condition, $join->getIndexBy()); } else { $optimizedQueryBuilder->leftJoin($join->getJoin(), $alias, $join->getConditionType(), $condition, $join->getIndexBy()); } } } } }