diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index c5c31d6a5..009a5fd9d 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -1815,7 +1815,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()