diff --git a/lib/Doctrine/ORM/QueryBuilder.php b/lib/Doctrine/ORM/QueryBuilder.php index 13d041e2b..b78ed59d0 100644 --- a/lib/Doctrine/ORM/QueryBuilder.php +++ b/lib/Doctrine/ORM/QueryBuilder.php @@ -96,6 +96,12 @@ class QueryBuilder */ private $_maxResults = null; + /** + * Keeps root entity alias names for join entities + * @var array + */ + private $joinRootAliases = array(); + /** * Initializes a new QueryBuilder that uses the given EntityManager. * @@ -234,10 +240,22 @@ class QueryBuilder * @deprecated Please use $qb->getRootAliases() instead. * @return string $rootAlias */ - public function getRootAlias() + public function getRootAlias($rootAlias = null, $alias = null) { - $aliases = $this->getRootAliases(); - return $aliases[0]; + if ( ! is_null($rootAlias) && in_array($rootAlias, $this->getRootAliases())) { + // Do nothing + } elseif ( ! is_null($rootAlias) && isset($this->joinRootAliases[$rootAlias])) { + $rootAlias = $this->joinRootAliases[$rootAlias]; + } else { + $aliases = $this->getRootAliases(); + $rootAlias = $aliases[0]; + } + + if ( ! is_null($alias)) { + $this->joinRootAliases[$alias] = $rootAlias; + } + + return $rootAlias; } /** @@ -669,9 +687,7 @@ class QueryBuilder { $rootAlias = substr($join, 0, strpos($join, '.')); - if ( ! in_array($rootAlias, $this->getRootAliases())) { - $rootAlias = $this->getRootAlias(); - } + $rootAlias = $this->getRootAlias($rootAlias, $alias); $join = new Expr\Join( Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition, $indexBy @@ -705,9 +721,7 @@ class QueryBuilder { $rootAlias = substr($join, 0, strpos($join, '.')); - if ( ! in_array($rootAlias, $this->getRootAliases())) { - $rootAlias = $this->getRootAlias(); - } + $rootAlias = $this->getRootAlias($rootAlias, $alias); $join = new Expr\Join( Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition, $indexBy diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1757Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1757Test.php new file mode 100644 index 000000000..703142003 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1757Test.php @@ -0,0 +1,102 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1757A'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1757B'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1757C'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1757D'), + )); + } catch(\Exception $ignored) {} + } + + public function testFailingCase() + { + $qb = $this->_em->createQueryBuilder(); + /* @var $qb \Doctrine\ORM\QueryBuilder */ + + $qb->select('_a') + ->from(__NAMESPACE__ . '\DDC1757A', '_a') + ->from(__NAMESPACE__ . '\DDC1757B', '_b') + ->join('_b.c', '_c') + ->join('_c.d', '_d'); + + $q = $qb->getQuery(); + $dql = $q->getDQL(); + $q->getResult(); + } +} + +/** + * @Entity + */ +class DDC1757A +{ + /** + * @Column(type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + private $id; +} + +/** + * @Entity + */ +class DDC1757B +{ + /** + * @Column(type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @OneToOne(targetEntity="DDC1757C") + */ + private $c; +} + +/** + * @Entity + */ +class DDC1757C +{ + /** + * @Column(type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + public $id; + + /** + * @OneToOne(targetEntity="DDC1757D") + */ + private $d; +} + +/** + * @Entity + */ +class DDC1757D +{ + /** + * @Column(type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + public $id; +}