1
0
mirror of synced 2025-02-02 21:41:45 +03:00

Fix discriminator resolution when using parameters

This commit is contained in:
Sergio Santoro 2017-06-24 13:35:44 +02:00
parent b1f7c59ed5
commit e91dcf8fb4
4 changed files with 58 additions and 23 deletions

View File

@ -371,6 +371,25 @@ final class Query extends AbstractQuery
$this->_em->getCache()->evictEntityRegion($className);
}
private function getAllDiscriminators(ClassMetadata $classMetadata)
{
// FIXME: this code is copied from SqlWalker->getAllDiscriminators()
$hierarchyClasses = $classMetadata->subClasses;
$hierarchyClasses[] = $classMetadata->name;
$discriminators = [];
foreach ($hierarchyClasses as $class) {
$currentMetadata = $this->getEntityManager()->getClassMetadata($class);
$currentDiscriminator = $currentMetadata->discriminatorValue;
if (null !== $currentDiscriminator) {
$discriminators[$currentDiscriminator] = null;
}
}
return $discriminators;
}
/**
* Processes query parameter mappings.
*
@ -398,6 +417,10 @@ final class Query extends AbstractQuery
$value = $value->getMetadataValue($rsm->metadataParameterMapping[$key]);
}
if (isset($rsm->discriminatorParameters[$key]) && $value instanceof ClassMetadata) {
$value = array_keys($this->getAllDiscriminators($value));
}
$value = $this->processParameterValue($value);
$type = ($parameter->getValue() === $value)
? $parameter->getType()

View File

@ -168,6 +168,13 @@ class ResultSetMapping
*/
public $metadataParameterMapping = [];
/**
* Contains query parameter names to be resolved as discriminator values
*
* @var array
*/
public $discriminatorParameters = [];
/**
* Adds an entity result to this ResultSetMapping.
*

View File

@ -2270,42 +2270,29 @@ class SqlWalker implements TreeWalker
}
/**
* @param ClassMetadataInfo $discrClass
* @param ClassMetadataInfo $rootClass
* @param AST\InstanceOfExpression $instanceOfExpr
* @return string The list in parentheses of valid child discriminators from the given class
* @throws QueryException
*/
private function getChildDiscriminatorsFromClassMetadata(ClassMetadataInfo $discrClass, AST\InstanceOfExpression $instanceOfExpr)
private function getChildDiscriminatorsFromClassMetadata(ClassMetadataInfo $rootClass, AST\InstanceOfExpression $instanceOfExpr)
{
$sqlParameterList = [];
$discriminators = [];
foreach ($instanceOfExpr->value as $parameter) {
if ($parameter instanceof AST\InputParameter) {
$this->rsm->addMetadataParameterMapping($parameter->name, 'discriminatorValue');
$sqlParameterList[] = $this->walkInputParameter($parameter);
$this->rsm->discriminatorParameters[$parameter->name] = $parameter->name;
$sqlParameterList[] = $this->walkInParameter($parameter);
continue;
}
$metadata = $this->em->getClassMetadata($parameter);
if ($metadata->getName() !== $discrClass->name && ! $metadata->getReflectionClass()->isSubclassOf($discrClass->name)) {
throw QueryException::instanceOfUnrelatedClass($parameter, $discrClass->name);
if ($metadata->getName() !== $rootClass->name && ! $metadata->getReflectionClass()->isSubclassOf($rootClass->name)) {
throw QueryException::instanceOfUnrelatedClass($parameter, $rootClass->name);
}
// Include discriminators for parameter class and its subclass
$hierarchyClasses = $metadata->subClasses;
$hierarchyClasses[] = $metadata->name;
foreach ($hierarchyClasses as $class) {
$currentMetadata = $this->em->getClassMetadata($class);
$currentDiscriminator = $currentMetadata->discriminatorValue;
if (null !== $currentDiscriminator) {
$discriminators[$currentDiscriminator] = null;
}
}
$discriminators = $discriminators + $this->getAllDiscriminators($metadata);
}
foreach (array_keys($discriminators) as $dis) {
@ -2314,4 +2301,23 @@ class SqlWalker implements TreeWalker
return '(' . implode(', ', $sqlParameterList) . ')';
}
private function getAllDiscriminators(ClassMetadata $classMetadata)
{
// FIXME: this code is identical to Query->getAllDiscriminators()
$hierarchyClasses = $classMetadata->subClasses;
$hierarchyClasses[] = $classMetadata->name;
$discriminators = [];
foreach ($hierarchyClasses as $class) {
$currentMetadata = $this->em->getClassMetadata($class);
$currentDiscriminator = $currentMetadata->discriminatorValue;
if (null !== $currentDiscriminator) {
$discriminators[$currentDiscriminator] = null;
}
}
return $discriminators;
}
}

View File

@ -72,10 +72,9 @@ class DDC1995Test extends \Doctrine\Tests\OrmFunctionalTestCase
->getResult();
$this->assertCount(1, $result1);
$this->assertCount(1, $result2);
$this->assertCount(2, $result2);
$this->assertInstanceOf(CompanyEmployee::class, $result1[0]);
$this->assertInstanceOf(CompanyPerson::class, $result2[0]);
$this->assertNotInstanceOf(CompanyEmployee::class, $result2[0]);
$this->assertContainsOnlyInstancesOf(CompanyPerson::class, $result2);
}
}