Merge pull request #6392 from Jean85/pr_1441_rebased
Correct DQL `INSTANCE OF` to filter all possible child classes
This commit is contained in:
commit
1a0bb82e1d
@ -27,6 +27,7 @@ use Doctrine\ORM\Query\QueryException;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Query\ParameterTypeInferer;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Utility\HierarchyDiscriminatorResolver;
|
||||
|
||||
/**
|
||||
* A Query object represents a DQL query.
|
||||
@ -398,6 +399,10 @@ final class Query extends AbstractQuery
|
||||
$value = $value->getMetadataValue($rsm->metadataParameterMapping[$key]);
|
||||
}
|
||||
|
||||
if (isset($rsm->discriminatorParameters[$key]) && $value instanceof ClassMetadata) {
|
||||
$value = array_keys(HierarchyDiscriminatorResolver::resolveDiscriminatorsForClass($value, $this->_em));
|
||||
}
|
||||
|
||||
$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.
|
||||
*
|
||||
|
@ -25,6 +25,7 @@ use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\Utility\HierarchyDiscriminatorResolver;
|
||||
use Doctrine\ORM\Utility\PersisterHelper;
|
||||
|
||||
/**
|
||||
@ -37,7 +38,6 @@ use Doctrine\ORM\Utility\PersisterHelper;
|
||||
* @author Alexander <iam.asm89@gmail.com>
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
* @since 2.0
|
||||
* @todo Rename: SQLWalker
|
||||
*/
|
||||
class SqlWalker implements TreeWalker
|
||||
{
|
||||
@ -2035,6 +2035,7 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*/
|
||||
public function walkInstanceOfExpression($instanceOfExpr)
|
||||
{
|
||||
@ -2052,36 +2053,7 @@ class SqlWalker implements TreeWalker
|
||||
}
|
||||
|
||||
$sql .= $class->discriminatorColumn['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN ');
|
||||
|
||||
$sqlParameterList = [];
|
||||
|
||||
foreach ($instanceOfExpr->value as $parameter) {
|
||||
if ($parameter instanceof AST\InputParameter) {
|
||||
$this->rsm->addMetadataParameterMapping($parameter->name, 'discriminatorValue');
|
||||
|
||||
$sqlParameterList[] = $this->walkInputParameter($parameter);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get name from ClassMetadata to resolve aliases.
|
||||
$entityClassName = $this->em->getClassMetadata($parameter)->name;
|
||||
$discriminatorValue = $class->discriminatorValue;
|
||||
|
||||
if ($entityClassName !== $class->name) {
|
||||
$discrMap = array_flip($class->discriminatorMap);
|
||||
|
||||
if ( ! isset($discrMap[$entityClassName])) {
|
||||
throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
|
||||
}
|
||||
|
||||
$discriminatorValue = $discrMap[$entityClassName];
|
||||
}
|
||||
|
||||
$sqlParameterList[] = $this->conn->quote($discriminatorValue);
|
||||
}
|
||||
|
||||
$sql .= '(' . implode(', ', $sqlParameterList) . ')';
|
||||
$sql .= $this->getChildDiscriminatorsFromClassMetadata($discrClass, $instanceOfExpr);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
@ -2315,4 +2287,37 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
return $resultAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 $rootClass, AST\InstanceOfExpression $instanceOfExpr): string
|
||||
{
|
||||
$sqlParameterList = [];
|
||||
$discriminators = [];
|
||||
foreach ($instanceOfExpr->value as $parameter) {
|
||||
if ($parameter instanceof AST\InputParameter) {
|
||||
$this->rsm->discriminatorParameters[$parameter->name] = $parameter->name;
|
||||
$sqlParameterList[] = $this->walkInParameter($parameter);
|
||||
continue;
|
||||
}
|
||||
|
||||
$metadata = $this->em->getClassMetadata($parameter);
|
||||
|
||||
if ($metadata->getName() !== $rootClass->name && ! $metadata->getReflectionClass()->isSubclassOf($rootClass->name)) {
|
||||
throw QueryException::instanceOfUnrelatedClass($parameter, $rootClass->name);
|
||||
}
|
||||
|
||||
$discriminators += HierarchyDiscriminatorResolver::resolveDiscriminatorsForClass($metadata, $this->em);
|
||||
}
|
||||
|
||||
foreach (array_keys($discriminators) as $dis) {
|
||||
$sqlParameterList[] = $this->conn->quote($dis);
|
||||
}
|
||||
|
||||
return '(' . implode(', ', $sqlParameterList) . ')';
|
||||
}
|
||||
}
|
||||
|
41
lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php
Normal file
41
lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\ORM\Utility;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* @internal This class exists only to avoid code duplication, do not reuse it externally
|
||||
*/
|
||||
final class HierarchyDiscriminatorResolver
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is needed to make INSTANCEOF work correctly with inheritance: if the class at hand has inheritance,
|
||||
* it extracts all the discriminators from the child classes and returns them
|
||||
*/
|
||||
public static function resolveDiscriminatorsForClass(
|
||||
ClassMetadata $rootClassMetadata,
|
||||
EntityManagerInterface $entityManager
|
||||
): array {
|
||||
$hierarchyClasses = $rootClassMetadata->subClasses;
|
||||
$hierarchyClasses[] = $rootClassMetadata->name;
|
||||
|
||||
$discriminators = [];
|
||||
|
||||
foreach ($hierarchyClasses as $class) {
|
||||
$currentMetadata = $entityManager->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);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class Ticket4646InstanceOfAbstractTest extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema([
|
||||
$this->_em->getClassMetadata(PersonTicket4646Abstract::class),
|
||||
$this->_em->getClassMetadata(EmployeeTicket4646Abstract::class),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testInstanceOf(): void
|
||||
{
|
||||
$this->_em->persist(new EmployeeTicket4646Abstract());
|
||||
$this->_em->flush();
|
||||
|
||||
$dql = 'SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646Abstract p
|
||||
WHERE p INSTANCE OF Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646Abstract';
|
||||
$query = $this->_em->createQuery($dql);
|
||||
$result = $query->getResult();
|
||||
|
||||
self::assertCount(1, $result);
|
||||
self::assertContainsOnlyInstancesOf(PersonTicket4646Abstract::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_abstract_test_person")
|
||||
* @InheritanceType(value="JOINED")
|
||||
* @DiscriminatorColumn(name="kind", type="string")
|
||||
* @DiscriminatorMap(value={
|
||||
* "employee": EmployeeTicket4646Abstract::class
|
||||
* })
|
||||
*/
|
||||
abstract class PersonTicket4646Abstract
|
||||
{
|
||||
/**
|
||||
* @Id()
|
||||
* @GeneratedValue()
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_abstract_test_employee")
|
||||
*/
|
||||
class EmployeeTicket4646Abstract extends PersonTicket4646Abstract
|
||||
{
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class Ticket4646InstanceOfMultiLevelTest extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema([
|
||||
$this->_em->getClassMetadata(PersonTicket4646MultiLevel::class),
|
||||
$this->_em->getClassMetadata(EmployeeTicket4646MultiLevel::class),
|
||||
$this->_em->getClassMetadata(EngineerTicket4646MultiLevel::class),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testInstanceOf(): void
|
||||
{
|
||||
$this->_em->persist(new PersonTicket4646MultiLevel());
|
||||
$this->_em->persist(new EmployeeTicket4646MultiLevel());
|
||||
$this->_em->persist(new EngineerTicket4646MultiLevel());
|
||||
$this->_em->flush();
|
||||
|
||||
$dql = 'SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646MultiLevel p
|
||||
WHERE p INSTANCE OF Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646MultiLevel';
|
||||
$query = $this->_em->createQuery($dql);
|
||||
$result = $query->getResult();
|
||||
|
||||
self::assertCount(3, $result);
|
||||
self::assertContainsOnlyInstancesOf(PersonTicket4646MultiLevel::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_multi_level_test_person")
|
||||
* @InheritanceType(value="JOINED")
|
||||
* @DiscriminatorColumn(name="kind", type="string")
|
||||
* @DiscriminatorMap(value={
|
||||
* "person": "Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646MultiLevel",
|
||||
* "employee": "Doctrine\Tests\ORM\Functional\Ticket\EmployeeTicket4646MultiLevel",
|
||||
* "engineer": "Doctrine\Tests\ORM\Functional\Ticket\EngineerTicket4646MultiLevel",
|
||||
* })
|
||||
*/
|
||||
class PersonTicket4646MultiLevel
|
||||
{
|
||||
/**
|
||||
* @Id()
|
||||
* @GeneratedValue()
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_multi_level_employee")
|
||||
*/
|
||||
class EmployeeTicket4646MultiLevel extends PersonTicket4646MultiLevel
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_multi_level_engineer")
|
||||
*/
|
||||
class EngineerTicket4646MultiLevel extends EmployeeTicket4646MultiLevel
|
||||
{
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class Ticket4646InstanceOfParametricTest extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema([
|
||||
$this->_em->getClassMetadata(PersonTicket4646Parametric::class),
|
||||
$this->_em->getClassMetadata(EmployeeTicket4646Parametric::class),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testInstanceOf(): void
|
||||
{
|
||||
$this->_em->persist(new PersonTicket4646Parametric());
|
||||
$this->_em->persist(new EmployeeTicket4646Parametric());
|
||||
$this->_em->flush();
|
||||
$dql = 'SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646Parametric p
|
||||
WHERE p INSTANCE OF :parameter';
|
||||
$query = $this->_em->createQuery($dql);
|
||||
$query->setParameter(
|
||||
'parameter',
|
||||
$this->_em->getClassMetadata(PersonTicket4646Parametric::class)
|
||||
);
|
||||
$result = $query->getResult();
|
||||
self::assertCount(2, $result);
|
||||
self::assertContainsOnlyInstancesOf(PersonTicket4646Parametric::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_parametric_person")
|
||||
* @InheritanceType(value="JOINED")
|
||||
* @DiscriminatorColumn(name="kind", type="string")
|
||||
* @DiscriminatorMap(value={
|
||||
* "person": "Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646Parametric",
|
||||
* "employee": "Doctrine\Tests\ORM\Functional\Ticket\EmployeeTicket4646Parametric"
|
||||
* })
|
||||
*/
|
||||
class PersonTicket4646Parametric
|
||||
{
|
||||
/**
|
||||
* @Id()
|
||||
* @GeneratedValue()
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_parametric_employee")
|
||||
*/
|
||||
class EmployeeTicket4646Parametric extends PersonTicket4646Parametric
|
||||
{
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class Ticket4646InstanceOfTest extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema([
|
||||
$this->_em->getClassMetadata(PersonTicket4646::class),
|
||||
$this->_em->getClassMetadata(EmployeeTicket4646::class),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testInstanceOf(): void
|
||||
{
|
||||
$this->_em->persist(new PersonTicket4646());
|
||||
$this->_em->persist(new EmployeeTicket4646());
|
||||
$this->_em->flush();
|
||||
|
||||
$dql = 'SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646 p
|
||||
WHERE p INSTANCE OF Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646';
|
||||
$query = $this->_em->createQuery($dql);
|
||||
$result = $query->getResult();
|
||||
|
||||
self::assertCount(2, $result);
|
||||
self::assertContainsOnlyInstancesOf(PersonTicket4646::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_test_person")
|
||||
* @InheritanceType(value="JOINED")
|
||||
* @DiscriminatorColumn(name="kind", type="string")
|
||||
* @DiscriminatorMap(value={
|
||||
* "person": "Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646",
|
||||
* "employee": "Doctrine\Tests\ORM\Functional\Ticket\EmployeeTicket4646"
|
||||
* })
|
||||
*/
|
||||
class PersonTicket4646
|
||||
{
|
||||
/**
|
||||
* @Id()
|
||||
* @GeneratedValue()
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_test_employee")
|
||||
*/
|
||||
class EmployeeTicket4646 extends PersonTicket4646
|
||||
{
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class Ticket4646MultipleInstanceOfWithMultipleParametersTest extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema([
|
||||
$this->_em->getClassMetadata(PersonTicket4646Multiple::class),
|
||||
$this->_em->getClassMetadata(EmployeeTicket4646Multiple::class),
|
||||
$this->_em->getClassMetadata(ManagerTicket4646Multiple::class),
|
||||
$this->_em->getClassMetadata(InternTicket4646Multiple::class),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testInstanceOf(): void
|
||||
{
|
||||
$this->_em->persist(new PersonTicket4646Multiple());
|
||||
$this->_em->persist(new EmployeeTicket4646Multiple());
|
||||
$this->_em->persist(new ManagerTicket4646Multiple());
|
||||
$this->_em->persist(new InternTicket4646Multiple());
|
||||
$this->_em->flush();
|
||||
|
||||
$dql = 'SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646Multiple p
|
||||
WHERE p INSTANCE OF (Doctrine\Tests\ORM\Functional\Ticket\EmployeeTicket4646Multiple, Doctrine\Tests\ORM\Functional\Ticket\InternTicket4646Multiple)';
|
||||
$query = $this->_em->createQuery($dql);
|
||||
$result = $query->getResult();
|
||||
|
||||
self::assertCount(2, $result);
|
||||
self::assertContainsOnlyInstancesOf(PersonTicket4646Multiple::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_test_multiple_person")
|
||||
* @InheritanceType(value="JOINED")
|
||||
* @DiscriminatorColumn(name="kind", type="string")
|
||||
* @DiscriminatorMap(value={
|
||||
* "person": "Doctrine\Tests\ORM\Functional\Ticket\PersonTicket4646Multiple",
|
||||
* "employee": "Doctrine\Tests\ORM\Functional\Ticket\EmployeeTicket4646Multiple",
|
||||
* "manager": "Doctrine\Tests\ORM\Functional\Ticket\ManagerTicket4646Multiple",
|
||||
* "intern": "Doctrine\Tests\ORM\Functional\Ticket\InternTicket4646Multiple"
|
||||
* })
|
||||
*/
|
||||
class PersonTicket4646Multiple
|
||||
{
|
||||
/**
|
||||
* @Id()
|
||||
* @GeneratedValue()
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_test_multiple_employee")
|
||||
*/
|
||||
class EmployeeTicket4646Multiple extends PersonTicket4646Multiple
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_test_multiple_manager")
|
||||
*/
|
||||
class ManagerTicket4646Multiple extends PersonTicket4646Multiple
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="instance_of_test_multiple_intern")
|
||||
*/
|
||||
class InternTicket4646Multiple extends PersonTicket4646Multiple
|
||||
{
|
||||
}
|
@ -500,7 +500,7 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee",
|
||||
"SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')"
|
||||
"SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('manager', 'employee')"
|
||||
);
|
||||
}
|
||||
|
||||
@ -509,7 +509,7 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
// This also uses FQCNs starting with or without a backslash in the INSTANCE OF parameter
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF (Doctrine\Tests\Models\Company\CompanyEmployee, \Doctrine\Tests\Models\Company\CompanyManager)",
|
||||
"SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('employee', 'manager')"
|
||||
"SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('manager', 'employee')"
|
||||
);
|
||||
}
|
||||
|
||||
@ -520,7 +520,7 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\Company\CompanyEmployee",
|
||||
"SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')"
|
||||
"SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('manager', 'employee')"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Utility;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Utility\HierarchyDiscriminatorResolver;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class HierarchyDiscriminatorResolverTest extends TestCase
|
||||
{
|
||||
public function testResolveDiscriminatorsForClass()
|
||||
{
|
||||
$childClassMetadata = new ClassMetadata('ChildEntity');
|
||||
$childClassMetadata->name = 'Some\Class\Child\Name';
|
||||
$childClassMetadata->discriminatorValue = 'child-discriminator';
|
||||
|
||||
$classMetadata = new ClassMetadata('Entity');
|
||||
$classMetadata->subClasses = [$childClassMetadata->name];
|
||||
$classMetadata->name = 'Some\Class\Name';
|
||||
$classMetadata->discriminatorValue = 'discriminator';
|
||||
|
||||
$em = $this->prophesize(EntityManagerInterface::class);
|
||||
$em->getClassMetadata($classMetadata->name)
|
||||
->shouldBeCalled()
|
||||
->willReturn($classMetadata);
|
||||
$em->getClassMetadata($childClassMetadata->name)
|
||||
->shouldBeCalled()
|
||||
->willReturn($childClassMetadata);
|
||||
|
||||
$discriminators = HierarchyDiscriminatorResolver::resolveDiscriminatorsForClass($classMetadata, $em->reveal());
|
||||
|
||||
$this->assertCount(2, $discriminators);
|
||||
$this->assertArrayHasKey($classMetadata->discriminatorValue, $discriminators);
|
||||
$this->assertArrayHasKey($childClassMetadata->discriminatorValue, $discriminators);
|
||||
}
|
||||
|
||||
public function testResolveDiscriminatorsForClassWithNoSubclasses()
|
||||
{
|
||||
$classMetadata = new ClassMetadata('Entity');
|
||||
$classMetadata->subClasses = [];
|
||||
$classMetadata->name = 'Some\Class\Name';
|
||||
$classMetadata->discriminatorValue = 'discriminator';
|
||||
|
||||
$em = $this->prophesize(EntityManagerInterface::class);
|
||||
$em->getClassMetadata($classMetadata->name)
|
||||
->shouldBeCalled()
|
||||
->willReturn($classMetadata);
|
||||
|
||||
$discriminators = HierarchyDiscriminatorResolver::resolveDiscriminatorsForClass($classMetadata, $em->reveal());
|
||||
|
||||
$this->assertCount(1, $discriminators);
|
||||
$this->assertArrayHasKey($classMetadata->discriminatorValue, $discriminators);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user