diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index a021f756c..2044932d6 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -340,7 +340,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface { // Verify & complete identifier mapping if ( ! $class->identifier && ! $class->isMappedSuperclass) { - throw MappingException::identifierRequired($className); + throw MappingException::identifierRequired($class->name); } // verify inheritance diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 2a9f58faf..7393ba893 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -359,13 +359,7 @@ class SqlWalker implements TreeWalker { $sql = $this->walkSelectClause($AST->selectClause); $sql .= $this->walkFromClause($AST->fromClause); - - if (($whereClause = $AST->whereClause) !== null) { - $sql .= $this->walkWhereClause($whereClause); - } else if (($discSql = $this->_generateDiscriminatorColumnConditionSQL($this->_rootAliases)) !== '') { - $sql .= ' WHERE ' . $discSql; - } - + $sql .= $this->walkWhereClause($AST->whereClause); $sql .= $AST->groupByClause ? $this->walkGroupByClause($AST->groupByClause) : ''; $sql .= $AST->havingClause ? $this->walkHavingClause($AST->havingClause) : ''; @@ -407,12 +401,7 @@ class SqlWalker implements TreeWalker { $this->_useSqlTableAliases = false; $sql = $this->walkUpdateClause($AST->updateClause); - - if (($whereClause = $AST->whereClause) !== null) { - $sql .= $this->walkWhereClause($whereClause); - } else if (($discSql = $this->_generateDiscriminatorColumnConditionSQL($this->_rootAliases)) !== '') { - $sql .= ' WHERE ' . $discSql; - } + $sql .= $this->walkWhereClause($AST->whereClause); return $sql; } @@ -427,12 +416,7 @@ class SqlWalker implements TreeWalker { $this->_useSqlTableAliases = false; $sql = $this->walkDeleteClause($AST->deleteClause); - - if (($whereClause = $AST->whereClause) !== null) { - $sql .= $this->walkWhereClause($whereClause); - } else if (($discSql = $this->_generateDiscriminatorColumnConditionSQL($this->_rootAliases)) !== '') { - $sql .= ' WHERE ' . $discSql; - } + $sql .= $this->walkWhereClause($AST->whereClause); return $sql; } @@ -1158,15 +1142,19 @@ class SqlWalker implements TreeWalker public function walkSubselect($subselect) { $useAliasesBefore = $this->_useSqlTableAliases; + $rootAliasesBefore = $this->_rootAliases; + + $this->_rootAliases = array(); // reset the rootAliases for the subselect $this->_useSqlTableAliases = true; $sql = $this->walkSimpleSelectClause($subselect->simpleSelectClause); $sql .= $this->walkSubselectFromClause($subselect->subselectFromClause); - $sql .= $subselect->whereClause ? $this->walkWhereClause($subselect->whereClause) : ''; + $sql .= $this->walkWhereClause($subselect->whereClause); $sql .= $subselect->groupByClause ? $this->walkGroupByClause($subselect->groupByClause) : ''; $sql .= $subselect->havingClause ? $this->walkHavingClause($subselect->havingClause) : ''; $sql .= $subselect->orderByClause ? $this->walkOrderByClause($subselect->orderByClause) : ''; + $this->_rootAliases = $rootAliasesBefore; // put the main aliases back $this->_useSqlTableAliases = $useAliasesBefore; return $sql; @@ -1193,6 +1181,8 @@ class SqlWalker implements TreeWalker $sql .= $class->getQuotedTableName($this->_platform) . ' ' . $this->getSQLTableAlias($class->table['name'], $dqlAlias); + $this->_rootAliases[] = $dqlAlias; + if ($class->isInheritanceTypeJoined()) { $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias); } @@ -1414,16 +1404,23 @@ class SqlWalker implements TreeWalker /** * Walks down a WhereClause AST node, thereby generating the appropriate SQL. + * WhereClause or not, the appropriate discriminator sql is added. * * @param WhereClause * @return string The SQL. */ public function walkWhereClause($whereClause) { + $condSql = null !== $whereClause ? $this->walkConditionalExpression($whereClause->conditionalExpression) : ''; $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_rootAliases); - $condSql = $this->walkConditionalExpression($whereClause->conditionalExpression); - return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql); + if ($condSql) { + return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql); + } else if ($discrSql) { + return ' WHERE ' . $discrSql; + } + + return ''; } /** diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index deffb9232..ad5ce1329 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -922,6 +922,49 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase "SELECT COALESCE(NULLIF(c0_.name, ''), c0_.username) AS sclr0 FROM cms_users c0_" ); } + + /** + * Test that the right discriminator data is inserted in a subquery. + */ + public function testSubSelectDiscriminator() + { + $this->assertSqlGeneration( + "SELECT u.name, (SELECT COUNT(cfc.id) total FROM Doctrine\Tests\Models\Company\CompanyFixContract cfc) as cfc_count FROM Doctrine\Tests\Models\CMS\CmsUser u", + "SELECT c0_.name AS name0, (SELECT COUNT(c1_.id) AS dctrn__total FROM company_contracts c1_ WHERE c1_.discr IN ('fix')) AS sclr1 FROM cms_users c0_" + ); + } + + public function testIdVariableResultVariableReuse() + { + $exceptionThrown = false; + try { + $query = $this->_em->createQuery("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN (SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u)"); + + $query->getSql(); + $query->free(); + } catch (\Exception $e) { + $exceptionThrown = true; + } + + $this->assertTrue($exceptionThrown); + + } + + public function testSubSelectAliasesFromOuterQuery() + { + $this->assertSqlGeneration( + "SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo", + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id) AS sclr4 FROM cms_users c0_" + ); + } + + public function testSubSelectAliasesFromOuterQueryWithSubquery() + { + $this->assertSqlGeneration( + "SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id AND ui.name IN (SELECT uii.name FROM Doctrine\Tests\Models\CMS\CmsUser uii)) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo", + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id AND c1_.name IN (SELECT c2_.name FROM cms_users c2_)) AS sclr4 FROM cms_users c0_" + ); + } }