Skip to content

Commit

Permalink
Merge pull request #886 from Strate/bugfix/join-with-condition-placem…
Browse files Browse the repository at this point in the history
…ent-fix

[DDC-1256] Fix applying ON/WITH conditions to first join in Class Table Inheritance
  • Loading branch information
guilhermeblanco committed Feb 17, 2014
2 parents 4382304 + 324f200 commit 0dbd742
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
36 changes: 27 additions & 9 deletions lib/Doctrine/ORM/Query/SqlWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,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.
Expand Down Expand Up @@ -928,7 +930,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):
Expand Down Expand Up @@ -980,20 +985,33 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi
$conditions[] = $filterExpr;
}

$sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ' . implode(' AND ', $conditions);
$targetTableJoin = array(
'table' => $targetTableName . ' ' . $targetTableAlias,
'condition' => implode(' AND ', $conditions),
);
break;

default:
throw new \BadMethodCallException('Type of association must be one of *_TO_ONE or MANY_TO_MANY');
}

// 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) . ')');

// FIXME: these should either be nested or all forced to be left joins (DDC-XXX)
if ($targetClass->isInheritanceTypeJoined()) {
$sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias);
$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'];
} else {
$sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition'] . $ctiJoins;
}
} else {
$sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition'];
}

if ($withCondition) {
$sql .= ' AND ' . $withCondition;
}

// Apply the indexes
Expand Down
2 changes: 1 addition & 1 deletion tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2065,7 +2065,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)
);
}
Expand Down

0 comments on commit 0dbd742

Please sign in to comment.