Skip to content

Commit c6d8aec

Browse files
authored
Merge pull request #9326 from kimhemsoe/rsm-custom-type
Add support for custom types with requireSQLConversion and ResultSetMappingBuilder::generateSelectClause()
2 parents fdd3d11 + f508a4b commit c6d8aec

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Doctrine\ORM\Query;
66

7+
use Doctrine\DBAL\Types\Type;
78
use Doctrine\ORM\EntityManagerInterface;
89
use Doctrine\ORM\Internal\SQLResultCasing;
910
use Doctrine\ORM\Mapping\ClassMetadataInfo;
@@ -432,19 +433,26 @@ public function generateSelectClause($tableAliases = [])
432433
foreach ($this->columnOwnerMap as $columnName => $dqlAlias) {
433434
$tableAlias = $tableAliases[$dqlAlias] ?? $dqlAlias;
434435

435-
if ($sql) {
436+
if ($sql !== '') {
436437
$sql .= ', ';
437438
}
438439

439-
$sql .= $tableAlias . '.';
440-
441440
if (isset($this->fieldMappings[$columnName])) {
442-
$class = $this->em->getClassMetadata($this->declaringClasses[$columnName]);
443-
$sql .= $class->fieldMappings[$this->fieldMappings[$columnName]]['columnName'];
441+
$class = $this->em->getClassMetadata($this->declaringClasses[$columnName]);
442+
$fieldName = $this->fieldMappings[$columnName];
443+
$classFieldMapping = $class->fieldMappings[$fieldName];
444+
$columnSql = $tableAlias . '.' . $classFieldMapping['columnName'];
445+
446+
if (isset($classFieldMapping['requireSQLConversion']) && $classFieldMapping['requireSQLConversion'] === true) {
447+
$type = Type::getType($classFieldMapping['type']);
448+
$columnSql = $type->convertToPHPValueSQL($columnSql, $this->em->getConnection()->getDatabasePlatform());
449+
}
450+
451+
$sql .= $columnSql;
444452
} elseif (isset($this->metaMappings[$columnName])) {
445-
$sql .= $this->metaMappings[$columnName];
453+
$sql .= $tableAlias . '.' . $this->metaMappings[$columnName];
446454
} elseif (isset($this->discriminatorColumns[$dqlAlias])) {
447-
$sql .= $this->discriminatorColumns[$dqlAlias];
455+
$sql .= $tableAlias . '.' . $this->discriminatorColumns[$dqlAlias];
448456
}
449457

450458
$sql .= ' AS ' . $columnName;

tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66

77
use Doctrine\Common\Collections\ArrayCollection;
88
use Doctrine\DBAL\Platforms\AbstractPlatform;
9+
use Doctrine\DBAL\Types\Type as DBALType;
910
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
1011
use Doctrine\ORM\Internal\Hydration\HydrationException;
1112
use Doctrine\ORM\Internal\SQLResultCasing;
1213
use Doctrine\ORM\PersistentCollection;
1314
use Doctrine\ORM\Query\Parameter;
1415
use Doctrine\ORM\Query\ResultSetMapping;
1516
use Doctrine\ORM\Query\ResultSetMappingBuilder;
17+
use Doctrine\Tests\DbalTypes\UpperCaseStringType;
1618
use Doctrine\Tests\Models\CMS\CmsAddress;
1719
use Doctrine\Tests\Models\CMS\CmsEmail;
1820
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
@@ -22,6 +24,7 @@
2224
use Doctrine\Tests\Models\Company\CompanyFixContract;
2325
use Doctrine\Tests\Models\Company\CompanyFlexContract;
2426
use Doctrine\Tests\Models\Company\CompanyPerson;
27+
use Doctrine\Tests\Models\CustomType\CustomTypeUpperCase;
2528
use Doctrine\Tests\Models\DDC3899\DDC3899FixContract;
2629
use Doctrine\Tests\Models\DDC3899\DDC3899User;
2730
use Doctrine\Tests\OrmFunctionalTestCase;
@@ -796,4 +799,38 @@ public function testGenerateSelectClauseWithDiscriminatorColumn(): void
796799

797800
$this->assertSQLEquals('u1.id as id, c1.discr as discr', $selectClause);
798801
}
802+
803+
public function testGenerateSelectClauseWithCustomTypeUsingEntityFromClassMetadata(): void
804+
{
805+
if (DBALType::hasType('upper_case_string')) {
806+
DBALType::overrideType('upper_case_string', UpperCaseStringType::class);
807+
} else {
808+
DBALType::addType('upper_case_string', UpperCaseStringType::class);
809+
}
810+
811+
$rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
812+
813+
$rsm->addRootEntityFromClassMetadata(CustomTypeUpperCase::class, 'ct');
814+
815+
$selectClause = $rsm->generateSelectClause(['ct' => 'ct1']);
816+
817+
$this->assertSQLEquals('ct1.id as id0, lower(ct1.lowercasestring) as lowercasestring1, lower(ct1.named_lower_case_string) as named_lower_case_string2', $selectClause);
818+
}
819+
820+
public function testGenerateSelectClauseWithCustomTypeUsingAddFieldResult(): void
821+
{
822+
if (DBALType::hasType('upper_case_string')) {
823+
DBALType::overrideType('upper_case_string', UpperCaseStringType::class);
824+
} else {
825+
DBALType::addType('upper_case_string', UpperCaseStringType::class);
826+
}
827+
828+
$rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
829+
$rsm->addEntityResult(CustomTypeUpperCase::class, 'ct');
830+
$rsm->addFieldResult('ct', $this->getSQLResultCasing($this->platform, 'lowercasestring'), 'lowerCaseString');
831+
832+
$selectClause = $rsm->generateSelectClause(['ct' => 'ct1']);
833+
834+
$this->assertSQLEquals('lower(ct1.lowercasestring) as lowercasestring', $selectClause);
835+
}
799836
}

0 commit comments

Comments
 (0)