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);
|
$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.
|
* Processes query parameter mappings.
|
||||||
*
|
*
|
||||||
@ -398,6 +417,10 @@ final class Query extends AbstractQuery
|
|||||||
$value = $value->getMetadataValue($rsm->metadataParameterMapping[$key]);
|
$value = $value->getMetadataValue($rsm->metadataParameterMapping[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($rsm->discriminatorParameters[$key]) && $value instanceof ClassMetadata) {
|
||||||
|
$value = array_keys($this->getAllDiscriminators($value));
|
||||||
|
}
|
||||||
|
|
||||||
$value = $this->processParameterValue($value);
|
$value = $this->processParameterValue($value);
|
||||||
$type = ($parameter->getValue() === $value)
|
$type = ($parameter->getValue() === $value)
|
||||||
? $parameter->getType()
|
? $parameter->getType()
|
||||||
|
@ -168,6 +168,13 @@ class ResultSetMapping
|
|||||||
*/
|
*/
|
||||||
public $metadataParameterMapping = [];
|
public $metadataParameterMapping = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains query parameter names to be resolved as discriminator values
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $discriminatorParameters = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an entity result to this ResultSetMapping.
|
* 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
|
* @param AST\InstanceOfExpression $instanceOfExpr
|
||||||
* @return string The list in parentheses of valid child discriminators from the given class
|
* @return string The list in parentheses of valid child discriminators from the given class
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
private function getChildDiscriminatorsFromClassMetadata(ClassMetadataInfo $discrClass, AST\InstanceOfExpression $instanceOfExpr)
|
private function getChildDiscriminatorsFromClassMetadata(ClassMetadataInfo $rootClass, AST\InstanceOfExpression $instanceOfExpr)
|
||||||
{
|
{
|
||||||
$sqlParameterList = [];
|
$sqlParameterList = [];
|
||||||
$discriminators = [];
|
$discriminators = [];
|
||||||
foreach ($instanceOfExpr->value as $parameter) {
|
foreach ($instanceOfExpr->value as $parameter) {
|
||||||
if ($parameter instanceof AST\InputParameter) {
|
if ($parameter instanceof AST\InputParameter) {
|
||||||
$this->rsm->addMetadataParameterMapping($parameter->name, 'discriminatorValue');
|
$this->rsm->discriminatorParameters[$parameter->name] = $parameter->name;
|
||||||
|
$sqlParameterList[] = $this->walkInParameter($parameter);
|
||||||
$sqlParameterList[] = $this->walkInputParameter($parameter);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata = $this->em->getClassMetadata($parameter);
|
$metadata = $this->em->getClassMetadata($parameter);
|
||||||
|
|
||||||
if ($metadata->getName() !== $discrClass->name && ! $metadata->getReflectionClass()->isSubclassOf($discrClass->name)) {
|
if ($metadata->getName() !== $rootClass->name && ! $metadata->getReflectionClass()->isSubclassOf($rootClass->name)) {
|
||||||
throw QueryException::instanceOfUnrelatedClass($parameter, $discrClass->name);
|
throw QueryException::instanceOfUnrelatedClass($parameter, $rootClass->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include discriminators for parameter class and its subclass
|
$discriminators = $discriminators + $this->getAllDiscriminators($metadata);
|
||||||
$hierarchyClasses = $metadata->subClasses;
|
|
||||||
$hierarchyClasses[] = $metadata->name;
|
|
||||||
|
|
||||||
foreach ($hierarchyClasses as $class) {
|
|
||||||
$currentMetadata = $this->em->getClassMetadata($class);
|
|
||||||
$currentDiscriminator = $currentMetadata->discriminatorValue;
|
|
||||||
|
|
||||||
if (null !== $currentDiscriminator) {
|
|
||||||
$discriminators[$currentDiscriminator] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (array_keys($discriminators) as $dis) {
|
foreach (array_keys($discriminators) as $dis) {
|
||||||
@ -2314,4 +2301,23 @@ class SqlWalker implements TreeWalker
|
|||||||
|
|
||||||
return '(' . implode(', ', $sqlParameterList) . ')';
|
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();
|
->getResult();
|
||||||
|
|
||||||
$this->assertCount(1, $result1);
|
$this->assertCount(1, $result1);
|
||||||
$this->assertCount(1, $result2);
|
$this->assertCount(2, $result2);
|
||||||
|
|
||||||
$this->assertInstanceOf(CompanyEmployee::class, $result1[0]);
|
$this->assertInstanceOf(CompanyEmployee::class, $result1[0]);
|
||||||
$this->assertInstanceOf(CompanyPerson::class, $result2[0]);
|
$this->assertContainsOnlyInstancesOf(CompanyPerson::class, $result2);
|
||||||
$this->assertNotInstanceOf(CompanyEmployee::class, $result2[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user