From 64b2ecfefc8a6db94a0ec931dfc1e8012a5eb8a2 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Thu, 4 Apr 2013 20:20:23 +0200 Subject: [PATCH] [DDC-2224] Rewrite instanceof feature with parameter needle ClassMetadata breaks caching of queries. --- lib/Doctrine/ORM/AbstractQuery.php | 4 +++ lib/Doctrine/ORM/Query/SqlWalker.php | 29 +++++++------------ tests/Doctrine/Tests/ORM/Query/QueryTest.php | 12 ++++++++ .../ORM/Query/SelectSqlGenerationTest.php | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 52f6ef507..18d563b10 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -284,6 +284,10 @@ abstract class AbstractQuery } } + if ($value instanceof Mapping\ClassMetadata) { + return $value->name; + } + return $value; } diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 30a39924e..08d5e0cda 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -1932,31 +1932,22 @@ class SqlWalker implements TreeWalker foreach ($instanceOfExpr->value as $parameter) { if ($parameter instanceof AST\InputParameter) { - // We need to modify the parameter value to be its correspondent mapped value - $dqlParamKey = $parameter->name; - $dqlParam = $this->query->getParameter($dqlParamKey); - $paramValue = $this->query->processParameterValue($dqlParam->getValue()); - - if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) { - throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue)); - } - - $entityClassName = $paramValue->name; + $sqlParameterList[] = $this->walkInputParameter($parameter); } else { // Get name from ClassMetadata to resolve aliases. $entityClassName = $this->em->getClassMetadata($parameter)->name; - } - if ($entityClassName == $class->name) { - $sqlParameterList[] = $this->conn->quote($class->discriminatorValue); - } else { - $discrMap = array_flip($class->discriminatorMap); + if ($entityClassName == $class->name) { + $sqlParameterList[] = $this->conn->quote($class->discriminatorValue); + } else { + $discrMap = array_flip($class->discriminatorMap); - if (!isset($discrMap[$entityClassName])) { - throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName); + if (!isset($discrMap[$entityClassName])) { + throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName); + } + + $sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]); } - - $sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]); } } diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Doctrine/Tests/ORM/Query/QueryTest.php index de160d096..9617fa873 100644 --- a/tests/Doctrine/Tests/ORM/Query/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Query/QueryTest.php @@ -163,4 +163,16 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('cities', $parameter->getName()); $this->assertEquals($cities, $parameter->getValue()); } + + /** + * @group DDC-2224 + */ + public function testProcessParameterValueClassMetadata() + { + $query = $this->_em->createQuery("SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)"); + $this->assertEquals( + 'Doctrine\Tests\Models\CMS\CmsAddress', + $query->processParameterValue($this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress')) + ); + } } diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index fccacbdab..cb4aac47e 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -482,7 +482,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase { $this->assertSqlGeneration( "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1", - "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')", + "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN (?)", array(), array(1 => $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee')) ); }