From d4d9a2ba3c5da1f16e66692350f0d234afe89e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Egidijus=20Jucevi=C4=8Dius?= Date: Tue, 4 Aug 2015 10:56:50 +0300 Subject: [PATCH] Support any ordering of fields in partial object query with embeddable [DDC-3864] --- lib/Doctrine/ORM/Query/Parser.php | 11 ++++++++++- .../Tests/ORM/Functional/ValueObjectsTest.php | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index 442dbac80..992a72e6a 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -1779,7 +1779,16 @@ class Parser $this->match(Lexer::T_OPEN_CURLY_BRACE); $this->match(Lexer::T_IDENTIFIER); - $partialFieldSet[] = $this->lexer->token['value']; + $field = $this->lexer->token['value']; + + // First field in partial expression might be embeddable property + while ($this->lexer->isNextToken(Lexer::T_DOT)) { + $this->match(Lexer::T_DOT); + $this->match(Lexer::T_IDENTIFIER); + $field .= '.'.$this->lexer->token['value']; + } + + $partialFieldSet[] = $field; while ($this->lexer->isNextToken(Lexer::T_COMMA)) { $this->match(Lexer::T_COMMA); diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php index f7137b18b..264ea4309 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php @@ -207,6 +207,22 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertNull($person->address->zip); $this->assertNull($person->address->country); $this->assertNull($person->name); + + // Clear the EM and prove that the embeddable can be the subject of a partial query regardless of attributes positions. + $this->_em->clear(); + + $dql = "SELECT PARTIAL p.{address.city, id} FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.name = :name"; + + $person = $this->_em->createQuery($dql) + ->setParameter('name', 'Karl') + ->getSingleResult(); + + // Selected field must be equal, all other fields must be null. + $this->assertEquals('Gosport', $person->address->city); + $this->assertNull($person->address->street); + $this->assertNull($person->address->zip); + $this->assertNull($person->address->country); + $this->assertNull($person->name); } public function testDqlWithNonExistentEmbeddableField()