1
0
mirror of synced 2025-01-18 14:31:40 +03:00

Merge pull request #180 from asm89/innerjoin-on-fetch-eager

[DDC-1463] Inner join eagerly loaded entities if possible
This commit is contained in:
Benjamin Eberlei 2011-10-31 14:24:47 -07:00
commit 88bda9b0d5
2 changed files with 54 additions and 8 deletions

View File

@ -1001,27 +1001,26 @@ class BasicEntityPersister
$columnList .= $assoc2ColumnSQL;
}
}
$this->_selectJoinSql .= ' LEFT JOIN'; // TODO: Inner join when all join columns are NOT nullable.
$first = true;
if ($assoc['isOwningSide']) {
$this->_selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($assoc['joinColumns']);
$this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' ' . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) .' ON ';
foreach ($assoc['sourceToTargetKeyColumns'] AS $sourceCol => $targetCol) {
if ( ! $first) {
$this->_selectJoinSql .= ' AND ';
}
$this->_selectJoinSql .= $this->_getSQLTableAlias($assoc['sourceEntity']) . '.' . $sourceCol . ' = '
. $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias) . '.' . $targetCol . ' ';
$this->_selectJoinSql .= $this->_getSQLTableAlias($assoc['sourceEntity']) . '.' . $sourceCol . ' = '
. $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias) . '.' . $targetCol;
$first = false;
}
} else {
$eagerEntity = $this->_em->getClassMetadata($assoc['targetEntity']);
$owningAssoc = $eagerEntity->getAssociationMapping($assoc['mappedBy']);
$this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' '
$this->_selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($owningAssoc['joinColumns']);
$this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' '
. $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) . ' ON ';
foreach ($owningAssoc['sourceToTargetKeyColumns'] AS $sourceCol => $targetCol) {
@ -1030,7 +1029,7 @@ class BasicEntityPersister
}
$this->_selectJoinSql .= $this->_getSQLTableAlias($owningAssoc['sourceEntity'], $assocAlias) . '.' . $sourceCol . ' = '
. $this->_getSQLTableAlias($owningAssoc['targetEntity']) . '.' . $targetCol . ' ';
. $this->_getSQLTableAlias($owningAssoc['targetEntity']) . '.' . $targetCol;
$first = false;
}
}
@ -1499,6 +1498,24 @@ class BasicEntityPersister
return (bool) $this->_conn->fetchColumn($sql, $params);
}
/**
* Generates the appropriate join SQL for the given join column.
*
* @param array $joinColumns The join columns definition of an association.
* @return string LEFT JOIN if one of the columns is nullable, INNER JOIN otherwise.
*/
protected function getJoinSQLForJoinColumns($joinColumns)
{
// if one of the join columns is nullable, return left join
foreach($joinColumns as $joinColumn) {
if(isset($joinColumn['nullable']) && $joinColumn['nullable']){
return 'LEFT JOIN';
}
}
return 'INNER JOIN';
}
/**
* Gets an SQL column alias for a column name.
*

View File

@ -115,6 +115,34 @@ class OneToOneEagerLoadingTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $waggon->train);
$this->assertNotNull($waggon->train);
}
public function testEagerLoadWithNullableColumnsGeneratesLeftJoin()
{
$train = new Train();
$this->_em->persist($train);
$this->_em->flush();
$this->_em->clear();
$train = $this->_em->find(get_class($train), $train->id);
$this->assertEquals(
"SELECT t0.id AS id1, t0.driver_id AS driver_id2, t3.id AS id4, t3.name AS name5 FROM Train t0 LEFT JOIN TrainDriver t3 ON t0.driver_id = t3.id WHERE t0.id = ?",
$this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql']
);
}
public function testEagerLoadWithNonNullableColumnsGeneratesInnerJoin()
{
$waggon = new Waggon();
$this->_em->persist($waggon);
$this->_em->flush();
$this->_em->clear();
$waggon = $this->_em->find(get_class($waggon), $waggon->id);
$this->assertEquals(
"SELECT t0.id AS id1, t0.train_id AS train_id2, t3.id AS id4, t3.driver_id AS driver_id5 FROM Waggon t0 INNER JOIN Train t3 ON t0.train_id = t3.id WHERE t0.id = ?",
$this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql']
);
}
}
/**
@ -130,6 +158,7 @@ class Train
/**
* Owning side
* @OneToOne(targetEntity="TrainDriver", inversedBy="train", fetch="EAGER", cascade={"persist"})
* @JoinColumn(nullable=true)
*/
public $driver;
/**
@ -195,4 +224,4 @@ class Waggon
{
$this->train = $train;
}
}
}