Skip to content

Commit 73ec483

Browse files
Convert PHP to SQL for new object expression (doctrine#8062)
1 parent 8d67eec commit 73ec483

File tree

2 files changed

+90
-5
lines changed

2 files changed

+90
-5
lines changed

lib/Doctrine/ORM/Query/SqlWalker.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use Doctrine\ORM\Query;
2828
use Doctrine\ORM\Utility\HierarchyDiscriminatorResolver;
2929
use Doctrine\ORM\Utility\PersisterHelper;
30+
use function trim;
3031

3132
/**
3233
* The SqlWalker is a TreeWalker that walks over a DQL AST and constructs
@@ -1553,12 +1554,20 @@ public function walkNewObject($newObjectExpression, $newObjectResultAlias=null)
15531554
break;
15541555

15551556
case ($e instanceof AST\PathExpression):
1556-
$dqlAlias = $e->identificationVariable;
1557-
$qComp = $this->queryComponents[$dqlAlias];
1558-
$class = $qComp['metadata'];
1559-
$fieldType = $class->fieldMappings[$e->field]['type'];
1557+
$dqlAlias = $e->identificationVariable;
1558+
$qComp = $this->queryComponents[$dqlAlias];
1559+
$class = $qComp['metadata'];
1560+
$fieldType = $class->fieldMappings[$e->field]['type'];
1561+
$fieldName = $e->field;
1562+
$fieldMapping = $class->fieldMappings[$fieldName];
1563+
$col = trim($e->dispatch($this));
1564+
1565+
if (isset($fieldMapping['requireSQLConversion'])) {
1566+
$type = Type::getType($fieldType);
1567+
$col = $type->convertToPHPValueSQL($col, $this->platform);
1568+
}
15601569

1561-
$sqlSelectExpressions[] = trim($e->dispatch($this)) . ' AS ' . $columnAlias;
1570+
$sqlSelectExpressions[] = $col . ' AS ' . $columnAlias;
15621571
break;
15631572

15641573
case ($e instanceof AST\Literal):
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Tests\ORM\Functional\Ticket;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
use Doctrine\Tests\OrmTestCase;
10+
use function sprintf;
11+
12+
/**
13+
* @group GH8061
14+
*/
15+
final class GH8061Test extends OrmTestCase
16+
{
17+
public static function setUpBeforeClass() : void
18+
{
19+
Type::addType('GH8061Type', GH8061Type::class);
20+
}
21+
22+
public function testConvertToPHPValueSQLForNewObjectExpression() : void
23+
{
24+
$dql = 'SELECT NEW ' . GH8061Class::class . '(e.field) FROM ' . GH8061Entity::class . ' e';
25+
$entityManager = $this->_getTestEntityManager();
26+
$query = $entityManager->createQuery($dql);
27+
28+
self::assertRegExp('/SELECT DatabaseFunction\(\w+\.field\) AS /', $query->getSQL());
29+
}
30+
}
31+
32+
/**
33+
* @Entity
34+
*/
35+
final class GH8061Entity
36+
{
37+
/** @Id @Column(type="integer") @GeneratedValue */
38+
public $id;
39+
40+
/** @Column(type="GH8061Type") */
41+
public $field;
42+
}
43+
44+
final class GH8061Type extends Type
45+
{
46+
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) : string
47+
{
48+
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
49+
}
50+
51+
public function getName() : string
52+
{
53+
return 'GH8061';
54+
}
55+
56+
public function canRequireSQLConversion() : bool
57+
{
58+
return true;
59+
}
60+
61+
public function convertToPHPValueSQL($sqlExpr, $platform) : string
62+
{
63+
return sprintf('DatabaseFunction(%s)', $sqlExpr);
64+
}
65+
}
66+
67+
final class GH8061Class
68+
{
69+
/** @var string */
70+
public $field;
71+
72+
public function __construct(string $field)
73+
{
74+
$this->field = $field;
75+
}
76+
}

0 commit comments

Comments
 (0)