From 8d33ccced19bd2b7137fb37a661c407297748e46 Mon Sep 17 00:00:00 2001 From: Strate Date: Sun, 19 Jan 2014 20:56:24 +0400 Subject: [PATCH] Fix applying ON/WITH conditions to first join in Class Table Inheritance Now we build nested joins for CTI when using ON/WITH clause. --- lib/Doctrine/ORM/Query/SqlWalker.php | 31 +++++++++++++++---- .../ORM/Query/SelectSqlGenerationTest.php | 2 +- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 04f671c3f1b..bb20dcfd32f 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -892,6 +892,8 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi } } + $targetTableJoin = null; + // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot // be the owning side and previously we ensured that $assoc is always the owning side of the associations. // The owning side is necessary at this point because only it contains the JoinColumn information. @@ -926,7 +928,10 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi $conditions[] = $filterExpr; } - $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ' . implode(' AND ', $conditions); + $targetTableJoin = array( + 'table' => $targetTableName . ' ' . $targetTableAlias, + 'condition' => implode(' AND ', $conditions), + ); break; case ($assoc['type'] == ClassMetadata::MANY_TO_MANY): @@ -978,15 +983,29 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi $conditions[] = $filterExpr; } - $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ' . implode(' AND ', $conditions); + $targetTableJoin = array( + 'table' => $targetTableName . ' ' . $targetTableAlias, + 'condition' => implode(' AND ', $conditions), + ); break; } // Handle WITH clause - if ($condExpr !== null) { - // Phase 2 AST optimization: Skip processing of ConditionalExpression - // if only one ConditionalTerm is defined - $sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')'; + $withCondition = (null !== $condExpr) ? ('(' . $this->walkConditionalExpression($condExpr) . ')') : ''; + + if ($targetClass->isInheritanceTypeJoined()) { + $ctiJoins = $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias); + // If we have WITH condition, we need to build nested joins for target class table and cti joins + if ($withCondition) { + $sql .= '(' . $targetTableJoin['table'] . $ctiJoins . ') ON ' . $targetTableJoin['condition'] . ' AND ' . $withCondition; + } else { + $sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition'] . $ctiJoins; + } + } else { + $sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition']; + if ($withCondition) { + $sql .= ' AND ' . $withCondition; + } } // FIXME: these should either be nested or all forced to be left joins (DDC-XXX) diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 11c5e3aecc3..3467237be21 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -2058,7 +2058,7 @@ public function testClassTableInheritanceJoinWithConditionAppliesToBaseTable() { $this->assertSqlGeneration( 'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1', - 'SELECT c0_.id AS id0 FROM company_organizations c1_ INNER JOIN company_events c0_ ON c1_.id = c0_.org_id AND (c0_.id = ?) LEFT JOIN company_auctions c2_ ON c0_.id = c2_.id LEFT JOIN company_raffles c3_ ON c0_.id = c3_.id', + 'SELECT c0_.id AS id0 FROM company_organizations c1_ INNER JOIN (company_events c0_ LEFT JOIN company_auctions c2_ ON c0_.id = c2_.id LEFT JOIN company_raffles c3_ ON c0_.id = c3_.id) ON c1_.id = c0_.org_id AND (c0_.id = ?)', array(Query::HINT_FORCE_PARTIAL_LOAD => false) ); }