Fix discriminator resolution when using parameters
This commit is contained in:
parent
b1f7c59ed5
commit
e91dcf8fb4
@ -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()
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user