diff --git a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php index 65618a9ef7d..4643012846c 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php +++ b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Query; +use Doctrine\DBAL\Types\Type; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Internal\SQLResultCasing; use Doctrine\ORM\Mapping\ClassMetadataInfo; @@ -16,6 +17,7 @@ use function sprintf; use function strpos; use function strtolower; +use function var_dump; /** * A ResultSetMappingBuilder uses the EntityManager to automatically populate entity fields. @@ -432,19 +434,26 @@ public function generateSelectClause($tableAliases = []) foreach ($this->columnOwnerMap as $columnName => $dqlAlias) { $tableAlias = $tableAliases[$dqlAlias] ?? $dqlAlias; - if ($sql) { + if ($sql !== '') { $sql .= ', '; } - $sql .= $tableAlias . '.'; - if (isset($this->fieldMappings[$columnName])) { - $class = $this->em->getClassMetadata($this->declaringClasses[$columnName]); - $sql .= $class->fieldMappings[$this->fieldMappings[$columnName]]['columnName']; + $class = $this->em->getClassMetadata($this->declaringClasses[$columnName]); + $fieldName = $this->fieldMappings[$columnName]; + $classFieldMapping = $class->fieldMappings[$fieldName]; + $columnSql = $tableAlias . '.' . $classFieldMapping['columnName']; + + if (isset($classFieldMapping['requireSQLConversion']) && $classFieldMapping['requireSQLConversion'] === true) { + $type = Type::getType($classFieldMapping['type']); + $columnSql = $type->convertToPHPValueSQL($columnSql, $this->em->getConnection()->getDatabasePlatform()); + } + + $sql .= $columnSql; } elseif (isset($this->metaMappings[$columnName])) { - $sql .= $this->metaMappings[$columnName]; + $sql .= $tableAlias . '.' . $this->metaMappings[$columnName]; } elseif (isset($this->discriminatorColumns[$dqlAlias])) { - $sql .= $this->discriminatorColumns[$dqlAlias]; + $sql .= $tableAlias . '.' . $this->discriminatorColumns[$dqlAlias]; } $sql .= ' AS ' . $columnName; diff --git a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php b/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php index f69c91867e9..ff773413695 100644 --- a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php @@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type as DBALType; use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\Internal\Hydration\HydrationException; use Doctrine\ORM\Internal\SQLResultCasing; @@ -13,6 +14,7 @@ use Doctrine\ORM\Query\Parameter; use Doctrine\ORM\Query\ResultSetMapping; use Doctrine\ORM\Query\ResultSetMappingBuilder; +use Doctrine\Tests\DbalTypes\UpperCaseStringType; use Doctrine\Tests\Models\CMS\CmsAddress; use Doctrine\Tests\Models\CMS\CmsEmail; use Doctrine\Tests\Models\CMS\CmsPhonenumber; @@ -22,6 +24,7 @@ use Doctrine\Tests\Models\Company\CompanyFixContract; use Doctrine\Tests\Models\Company\CompanyFlexContract; use Doctrine\Tests\Models\Company\CompanyPerson; +use Doctrine\Tests\Models\CustomType\CustomTypeUpperCase; use Doctrine\Tests\Models\DDC3899\DDC3899FixContract; use Doctrine\Tests\Models\DDC3899\DDC3899User; use Doctrine\Tests\OrmFunctionalTestCase; @@ -796,4 +799,38 @@ public function testGenerateSelectClauseWithDiscriminatorColumn(): void $this->assertSQLEquals('u1.id as id, c1.discr as discr', $selectClause); } + + public function testGenerateSelectClauseWithCustomTypeUsingEntityFromClassMetadata(): void + { + if (DBALType::hasType('upper_case_string')) { + DBALType::overrideType('upper_case_string', UpperCaseStringType::class); + } else { + DBALType::addType('upper_case_string', UpperCaseStringType::class); + } + + $rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT); + + $rsm->addRootEntityFromClassMetadata(CustomTypeUpperCase::class, 'ct'); + + $selectClause = $rsm->generateSelectClause(['ct' => 'ct1']); + + $this->assertSQLEquals('ct1.id as id0, lower(ct1.lowercasestring) as lowercasestring1, lower(ct1.named_lower_case_string) as named_lower_case_string2', $selectClause); + } + + public function testGenerateSelectClauseWithCustomTypeUsingAddFieldResult(): void + { + if (DBALType::hasType('upper_case_string')) { + DBALType::overrideType('upper_case_string', UpperCaseStringType::class); + } else { + DBALType::addType('upper_case_string', UpperCaseStringType::class); + } + + $rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT); + $rsm->addEntityResult(CustomTypeUpperCase::class, 'ct'); + $rsm->addFieldResult('ct', $this->getSQLResultCasing($this->platform, 'lowercasestring'), 'lowerCaseString'); + + $selectClause = $rsm->generateSelectClause(['ct' => 'ct1']); + + $this->assertSQLEquals('lower(ct1.lowercasestring) as lowercasestring', $selectClause); + } }