Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Hydration / ObjectHydratorTest.php
1 <?php
2
3 namespace Doctrine\Tests\ORM\Hydration;
4
5 use Doctrine\Tests\Mocks\HydratorMockStatement;
6 use Doctrine\ORM\Query\ResultSetMapping;
7 use Doctrine\ORM\Proxy\ProxyFactory;
8 use Doctrine\ORM\Mapping\AssociationMapping;
9 use Doctrine\ORM\Mapping\ClassMetadata;
10 use Doctrine\ORM\Query;
11
12 use Doctrine\Tests\Models\CMS\CmsUser;
13
14 require_once __DIR__ . '/../../TestInit.php';
15
16 class ObjectHydratorTest extends HydrationTestCase
17 {
18     public function provideDataForUserEntityResult()
19     {
20         return array(
21             array(0),
22             array('user'),
23         );
24     }
25
26     public function provideDataForMultipleRootEntityResult()
27     {
28         return array(
29             array(0, 0),
30             array('user', 0),
31             array(0, 'article'),
32             array('user', 'article'),
33         );
34     }
35
36     public function provideDataForProductEntityResult()
37     {
38         return array(
39             array(0),
40             array('product'),
41         );
42     }
43
44     /**
45      * SELECT PARTIAL u.{id,name}
46      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
47      */
48     public function testSimpleEntityQuery()
49     {
50         $rsm = new ResultSetMapping;
51         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
52         $rsm->addFieldResult('u', 'u__id', 'id');
53         $rsm->addFieldResult('u', 'u__name', 'name');
54
55         // Faked result set
56         $resultSet = array(
57             array(
58                 'u__id' => '1',
59                 'u__name' => 'romanb'
60             ),
61             array(
62                 'u__id' => '2',
63                 'u__name' => 'jwage'
64             )
65         );
66
67         $stmt     = new HydratorMockStatement($resultSet);
68         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
69         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
70
71         $this->assertEquals(2, count($result));
72
73         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]);
74         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1]);
75
76         $this->assertEquals(1, $result[0]->id);
77         $this->assertEquals('romanb', $result[0]->name);
78
79         $this->assertEquals(2, $result[1]->id);
80         $this->assertEquals('jwage', $result[1]->name);
81     }
82
83     /**
84      * SELECT PARTIAL u.{id,name} AS user
85      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
86      */
87     public function testSimpleEntityQueryWithAliasedUserEntity()
88     {
89         $rsm = new ResultSetMapping;
90         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
91         $rsm->addFieldResult('u', 'u__id', 'id');
92         $rsm->addFieldResult('u', 'u__name', 'name');
93
94         // Faked result set
95         $resultSet = array(
96             array(
97                 'u__id' => '1',
98                 'u__name' => 'romanb'
99             ),
100             array(
101                 'u__id' => '2',
102                 'u__name' => 'jwage'
103             )
104         );
105
106         $stmt     = new HydratorMockStatement($resultSet);
107         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
108         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
109
110         $this->assertEquals(2, count($result));
111
112         $this->assertArrayHasKey('user', $result[0]);
113         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]['user']);
114
115         $this->assertArrayHasKey('user', $result[1]);
116         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1]['user']);
117
118         $this->assertEquals(1, $result[0]['user']->id);
119         $this->assertEquals('romanb', $result[0]['user']->name);
120
121         $this->assertEquals(2, $result[1]['user']->id);
122         $this->assertEquals('jwage', $result[1]['user']->name);
123     }
124
125     /**
126      * SELECT PARTIAL u.{id, name}, PARTIAL a.{id, topic}
127      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
128      */
129     public function testSimpleMultipleRootEntityQuery()
130     {
131         $rsm = new ResultSetMapping;
132         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
133         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a');
134         $rsm->addFieldResult('u', 'u__id', 'id');
135         $rsm->addFieldResult('u', 'u__name', 'name');
136         $rsm->addFieldResult('a', 'a__id', 'id');
137         $rsm->addFieldResult('a', 'a__topic', 'topic');
138
139         // Faked result set
140         $resultSet = array(
141             array(
142                 'u__id' => '1',
143                 'u__name' => 'romanb',
144                 'a__id' => '1',
145                 'a__topic' => 'Cool things.'
146             ),
147             array(
148                 'u__id' => '2',
149                 'u__name' => 'jwage',
150                 'a__id' => '2',
151                 'a__topic' => 'Cool things II.'
152             )
153         );
154
155         $stmt     = new HydratorMockStatement($resultSet);
156         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
157         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
158
159         $this->assertEquals(4, count($result));
160
161         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]);
162         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1]);
163         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[2]);
164         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[3]);
165
166         $this->assertEquals(1, $result[0]->id);
167         $this->assertEquals('romanb', $result[0]->name);
168
169         $this->assertEquals(1, $result[1]->id);
170         $this->assertEquals('Cool things.', $result[1]->topic);
171
172         $this->assertEquals(2, $result[2]->id);
173         $this->assertEquals('jwage', $result[2]->name);
174
175         $this->assertEquals(2, $result[3]->id);
176         $this->assertEquals('Cool things II.', $result[3]->topic);
177     }
178
179     /**
180      * SELECT PARTIAL u.{id, name} AS user, PARTIAL a.{id, topic}
181      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
182      */
183     public function testSimpleMultipleRootEntityQueryWithAliasedUserEntity()
184     {
185         $rsm = new ResultSetMapping;
186         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
187         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a');
188         $rsm->addFieldResult('u', 'u__id', 'id');
189         $rsm->addFieldResult('u', 'u__name', 'name');
190         $rsm->addFieldResult('a', 'a__id', 'id');
191         $rsm->addFieldResult('a', 'a__topic', 'topic');
192
193         // Faked result set
194         $resultSet = array(
195             array(
196                 'u__id' => '1',
197                 'u__name' => 'romanb',
198                 'a__id' => '1',
199                 'a__topic' => 'Cool things.'
200             ),
201             array(
202                 'u__id' => '2',
203                 'u__name' => 'jwage',
204                 'a__id' => '2',
205                 'a__topic' => 'Cool things II.'
206             )
207         );
208
209         $stmt     = new HydratorMockStatement($resultSet);
210         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
211         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
212
213         $this->assertEquals(4, count($result));
214
215         $this->assertArrayHasKey('user', $result[0]);
216         $this->assertArrayNotHasKey(0, $result[0]);
217         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]['user']);
218         $this->assertEquals(1, $result[0]['user']->id);
219         $this->assertEquals('romanb', $result[0]['user']->name);
220
221         $this->assertArrayHasKey(0, $result[1]);
222         $this->assertArrayNotHasKey('user', $result[1]);
223         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1][0]);
224         $this->assertEquals(1, $result[1][0]->id);
225         $this->assertEquals('Cool things.', $result[1][0]->topic);
226
227         $this->assertArrayHasKey('user', $result[2]);
228         $this->assertArrayNotHasKey(0, $result[2]);
229         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[2]['user']);
230         $this->assertEquals(2, $result[2]['user']->id);
231         $this->assertEquals('jwage', $result[2]['user']->name);
232
233         $this->assertArrayHasKey(0, $result[3]);
234         $this->assertArrayNotHasKey('user', $result[3]);
235         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[3][0]);
236         $this->assertEquals(2, $result[3][0]->id);
237         $this->assertEquals('Cool things II.', $result[3][0]->topic);
238     }
239
240     /**
241      * SELECT PARTIAL u.{id, name}, PARTIAL a.{id, topic} AS article
242      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
243      */
244     public function testSimpleMultipleRootEntityQueryWithAliasedArticleEntity()
245     {
246         $rsm = new ResultSetMapping;
247         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
248         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a', 'article');
249         $rsm->addFieldResult('u', 'u__id', 'id');
250         $rsm->addFieldResult('u', 'u__name', 'name');
251         $rsm->addFieldResult('a', 'a__id', 'id');
252         $rsm->addFieldResult('a', 'a__topic', 'topic');
253
254         // Faked result set
255         $resultSet = array(
256             array(
257                 'u__id' => '1',
258                 'u__name' => 'romanb',
259                 'a__id' => '1',
260                 'a__topic' => 'Cool things.'
261             ),
262             array(
263                 'u__id' => '2',
264                 'u__name' => 'jwage',
265                 'a__id' => '2',
266                 'a__topic' => 'Cool things II.'
267             )
268         );
269
270         $stmt     = new HydratorMockStatement($resultSet);
271         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
272         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
273
274         $this->assertEquals(4, count($result));
275
276         $this->assertArrayHasKey(0, $result[0]);
277         $this->assertArrayNotHasKey('article', $result[0]);
278         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][0]);
279         $this->assertEquals(1, $result[0][0]->id);
280         $this->assertEquals('romanb', $result[0][0]->name);
281
282         $this->assertArrayHasKey('article', $result[1]);
283         $this->assertArrayNotHasKey(0, $result[1]);
284         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1]['article']);
285         $this->assertEquals(1, $result[1]['article']->id);
286         $this->assertEquals('Cool things.', $result[1]['article']->topic);
287
288         $this->assertArrayHasKey(0, $result[2]);
289         $this->assertArrayNotHasKey('article', $result[2]);
290         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[2][0]);
291         $this->assertEquals(2, $result[2][0]->id);
292         $this->assertEquals('jwage', $result[2][0]->name);
293
294         $this->assertArrayHasKey('article', $result[3]);
295         $this->assertArrayNotHasKey(0, $result[3]);
296         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[3]['article']);
297         $this->assertEquals(2, $result[3]['article']->id);
298         $this->assertEquals('Cool things II.', $result[3]['article']->topic);
299     }
300
301     /**
302      * SELECT PARTIAL u.{id, name} AS user, PARTIAL a.{id, topic} AS article
303      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
304      */
305     public function testSimpleMultipleRootEntityQueryWithAliasedEntities()
306     {
307         $rsm = new ResultSetMapping;
308         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
309         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a', 'article');
310         $rsm->addFieldResult('u', 'u__id', 'id');
311         $rsm->addFieldResult('u', 'u__name', 'name');
312         $rsm->addFieldResult('a', 'a__id', 'id');
313         $rsm->addFieldResult('a', 'a__topic', 'topic');
314
315         // Faked result set
316         $resultSet = array(
317             array(
318                 'u__id' => '1',
319                 'u__name' => 'romanb',
320                 'a__id' => '1',
321                 'a__topic' => 'Cool things.'
322             ),
323             array(
324                 'u__id' => '2',
325                 'u__name' => 'jwage',
326                 'a__id' => '2',
327                 'a__topic' => 'Cool things II.'
328             )
329         );
330
331         $stmt     = new HydratorMockStatement($resultSet);
332         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
333         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
334
335         $this->assertEquals(4, count($result));
336
337         $this->assertArrayHasKey('user', $result[0]);
338         $this->assertArrayNotHasKey('article', $result[0]);
339         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]['user']);
340         $this->assertEquals(1, $result[0]['user']->id);
341         $this->assertEquals('romanb', $result[0]['user']->name);
342
343         $this->assertArrayHasKey('article', $result[1]);
344         $this->assertArrayNotHasKey('user', $result[1]);
345         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1]['article']);
346         $this->assertEquals(1, $result[1]['article']->id);
347         $this->assertEquals('Cool things.', $result[1]['article']->topic);
348
349         $this->assertArrayHasKey('user', $result[2]);
350         $this->assertArrayNotHasKey('article', $result[2]);
351         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[2]['user']);
352         $this->assertEquals(2, $result[2]['user']->id);
353         $this->assertEquals('jwage', $result[2]['user']->name);
354
355         $this->assertArrayHasKey('article', $result[3]);
356         $this->assertArrayNotHasKey('user', $result[3]);
357         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[3]['article']);
358         $this->assertEquals(2, $result[3]['article']->id);
359         $this->assertEquals('Cool things II.', $result[3]['article']->topic);
360     }
361
362     /**
363      * SELECT PARTIAL u.{id, status}, COUNT(p.phonenumber) numPhones
364      *   FROM User u
365      *   JOIN u.phonenumbers p
366      *  GROUP BY u.id
367      *
368      * @dataProvider provideDataForUserEntityResult
369      */
370     public function testMixedQueryNormalJoin($userEntityKey)
371     {
372         $rsm = new ResultSetMapping;
373         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
374         $rsm->addFieldResult('u', 'u__id', 'id');
375         $rsm->addFieldResult('u', 'u__status', 'status');
376         $rsm->addScalarResult('sclr0', 'numPhones');
377
378         // Faked result set
379         $resultSet = array(
380             //row1
381             array(
382                 'u__id' => '1',
383                 'u__status' => 'developer',
384                 'sclr0' => '2',
385             ),
386             array(
387                 'u__id' => '2',
388                 'u__status' => 'developer',
389                 'sclr0' => '1',
390             )
391         );
392
393         $stmt     = new HydratorMockStatement($resultSet);
394         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
395         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
396
397         $this->assertEquals(2, count($result));
398
399         $this->assertInternalType('array', $result);
400         $this->assertInternalType('array', $result[0]);
401         $this->assertInternalType('array', $result[1]);
402
403         // first user => 2 phonenumbers
404         $this->assertEquals(2, $result[0]['numPhones']);
405         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][$userEntityKey]);
406
407         // second user => 1 phonenumber
408         $this->assertEquals(1, $result[1]['numPhones']);
409         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1][$userEntityKey]);
410     }
411
412     /**
413      * SELECT PARTIAL u.{id, status}, PARTIAL p.{phonenumber}, UPPER(u.name) nameUpper
414      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
415      *   JOIN u.phonenumbers p
416      *
417      * @dataProvider provideDataForUserEntityResult
418      */
419     public function testMixedQueryFetchJoin($userEntityKey)
420     {
421         $rsm = new ResultSetMapping;
422         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
423         $rsm->addJoinedEntityResult(
424             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
425             'p',
426             'u',
427             'phonenumbers'
428         );
429         $rsm->addFieldResult('u', 'u__id', 'id');
430         $rsm->addFieldResult('u', 'u__status', 'status');
431         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
432         $rsm->addScalarResult('sclr0', 'nameUpper');
433
434         // Faked result set
435         $resultSet = array(
436             //row1
437             array(
438                 'u__id' => '1',
439                 'u__status' => 'developer',
440                 'p__phonenumber' => '42',
441                 'sclr0' => 'ROMANB',
442             ),
443             array(
444                 'u__id' => '1',
445                 'u__status' => 'developer',
446                 'p__phonenumber' => '43',
447                 'sclr0' => 'ROMANB',
448             ),
449             array(
450                 'u__id' => '2',
451                 'u__status' => 'developer',
452                 'p__phonenumber' => '91',
453                 'sclr0' => 'JWAGE',
454             )
455         );
456
457         $stmt     = new HydratorMockStatement($resultSet);
458         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
459         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
460
461         $this->assertEquals(2, count($result));
462
463         $this->assertInternalType('array', $result);
464         $this->assertInternalType('array', $result[0]);
465         $this->assertInternalType('array', $result[1]);
466
467         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][$userEntityKey]);
468         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->phonenumbers);
469         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[0][$userEntityKey]->phonenumbers[0]);
470
471         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1][$userEntityKey]);
472         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[1][$userEntityKey]->phonenumbers);
473         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[0][$userEntityKey]->phonenumbers[1]);
474
475         // first user => 2 phonenumbers
476         $this->assertEquals(2, count($result[0][$userEntityKey]->phonenumbers));
477         $this->assertEquals('ROMANB', $result[0]['nameUpper']);
478
479         // second user => 1 phonenumber
480         $this->assertEquals(1, count($result[1][$userEntityKey]->phonenumbers));
481         $this->assertEquals('JWAGE', $result[1]['nameUpper']);
482
483         $this->assertEquals(42, $result[0][$userEntityKey]->phonenumbers[0]->phonenumber);
484         $this->assertEquals(43, $result[0][$userEntityKey]->phonenumbers[1]->phonenumber);
485         $this->assertEquals(91, $result[1][$userEntityKey]->phonenumbers[0]->phonenumber);
486     }
487
488     /**
489      * SELECT u, p, UPPER(u.name) nameUpper
490      *   FROM User u
491      *        INDEX BY u.id
492      *   JOIN u.phonenumbers p
493      *        INDEX BY p.phonenumber
494      *
495      * @dataProvider provideDataForUserEntityResult
496      */
497     public function testMixedQueryFetchJoinCustomIndex($userEntityKey)
498     {
499         $rsm = new ResultSetMapping;
500         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
501         $rsm->addJoinedEntityResult(
502             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
503             'p',
504             'u',
505             'phonenumbers'
506         );
507         $rsm->addFieldResult('u', 'u__id', 'id');
508         $rsm->addFieldResult('u', 'u__status', 'status');
509         $rsm->addScalarResult('sclr0', 'nameUpper');
510         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
511         $rsm->addIndexBy('u', 'id');
512         $rsm->addIndexBy('p', 'phonenumber');
513
514         // Faked result set
515         $resultSet = array(
516             //row1
517             array(
518                 'u__id' => '1',
519                 'u__status' => 'developer',
520                 'sclr0' => 'ROMANB',
521                 'p__phonenumber' => '42',
522             ),
523             array(
524                 'u__id' => '1',
525                 'u__status' => 'developer',
526                 'sclr0' => 'ROMANB',
527                 'p__phonenumber' => '43',
528             ),
529             array(
530                 'u__id' => '2',
531                 'u__status' => 'developer',
532                 'sclr0' => 'JWAGE',
533                 'p__phonenumber' => '91'
534             )
535         );
536
537
538         $stmt     = new HydratorMockStatement($resultSet);
539         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
540         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
541
542         $this->assertEquals(2, count($result));
543
544         $this->assertInternalType('array', $result);
545         $this->assertInternalType('array', $result[1]);
546         $this->assertInternalType('array', $result[2]);
547
548         // test the scalar values
549         $this->assertEquals('ROMANB', $result[1]['nameUpper']);
550         $this->assertEquals('JWAGE', $result[2]['nameUpper']);
551
552         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1][$userEntityKey]);
553         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[2][$userEntityKey]);
554         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[1][$userEntityKey]->phonenumbers);
555
556         // first user => 2 phonenumbers. notice the custom indexing by user id
557         $this->assertEquals(2, count($result[1][$userEntityKey]->phonenumbers));
558
559         // second user => 1 phonenumber. notice the custom indexing by user id
560         $this->assertEquals(1, count($result[2][$userEntityKey]->phonenumbers));
561
562         // test the custom indexing of the phonenumbers
563         $this->assertTrue(isset($result[1][$userEntityKey]->phonenumbers['42']));
564         $this->assertTrue(isset($result[1][$userEntityKey]->phonenumbers['43']));
565         $this->assertTrue(isset($result[2][$userEntityKey]->phonenumbers['91']));
566     }
567
568     /**
569      * SELECT u, p, UPPER(u.name) nameUpper, a
570      *   FROM User u
571      *   JOIN u.phonenumbers p
572      *   JOIN u.articles a
573      *
574      * @dataProvider provideDataForUserEntityResult
575      */
576     public function testMixedQueryMultipleFetchJoin($userEntityKey)
577     {
578         $rsm = new ResultSetMapping;
579         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
580         $rsm->addJoinedEntityResult(
581             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
582             'p',
583             'u',
584             'phonenumbers'
585         );
586         $rsm->addJoinedEntityResult(
587             'Doctrine\Tests\Models\CMS\CmsArticle',
588             'a',
589             'u',
590             'articles'
591         );
592         $rsm->addFieldResult('u', 'u__id', 'id');
593         $rsm->addFieldResult('u', 'u__status', 'status');
594         $rsm->addScalarResult('sclr0', 'nameUpper');
595         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
596         $rsm->addFieldResult('a', 'a__id', 'id');
597         $rsm->addFieldResult('a', 'a__topic', 'topic');
598
599         // Faked result set
600         $resultSet = array(
601             //row1
602             array(
603                 'u__id' => '1',
604                 'u__status' => 'developer',
605                 'sclr0' => 'ROMANB',
606                 'p__phonenumber' => '42',
607                 'a__id' => '1',
608                 'a__topic' => 'Getting things done!'
609             ),
610             array(
611                 'u__id' => '1',
612                 'u__status' => 'developer',
613                 'sclr0' => 'ROMANB',
614                 'p__phonenumber' => '43',
615                 'a__id' => '1',
616                 'a__topic' => 'Getting things done!'
617             ),
618             array(
619                 'u__id' => '1',
620                 'u__status' => 'developer',
621                 'sclr0' => 'ROMANB',
622                 'p__phonenumber' => '42',
623                 'a__id' => '2',
624                 'a__topic' => 'ZendCon'
625             ),
626             array(
627                 'u__id' => '1',
628                 'u__status' => 'developer',
629                 'sclr0' => 'ROMANB',
630                 'p__phonenumber' => '43',
631                 'a__id' => '2',
632                 'a__topic' => 'ZendCon'
633             ),
634             array(
635                 'u__id' => '2',
636                 'u__status' => 'developer',
637                 'sclr0' => 'JWAGE',
638                 'p__phonenumber' => '91',
639                 'a__id' => '3',
640                 'a__topic' => 'LINQ'
641             ),
642             array(
643                 'u__id' => '2',
644                 'u__status' => 'developer',
645                 'sclr0' => 'JWAGE',
646                 'p__phonenumber' => '91',
647                 'a__id' => '4',
648                 'a__topic' => 'PHP6'
649             ),
650         );
651
652         $stmt     = new HydratorMockStatement($resultSet);
653         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
654         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
655
656         $this->assertEquals(2, count($result));
657
658         $this->assertTrue(is_array($result));
659         $this->assertTrue(is_array($result[0]));
660         $this->assertTrue(is_array($result[1]));
661
662         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][$userEntityKey]);
663         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->phonenumbers);
664         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[0][$userEntityKey]->phonenumbers[0]);
665         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[0][$userEntityKey]->phonenumbers[1]);
666         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->articles);
667         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[0][$userEntityKey]->articles[0]);
668         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[0][$userEntityKey]->articles[1]);
669
670         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1][$userEntityKey]);
671         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[1][$userEntityKey]->phonenumbers);
672         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[1][$userEntityKey]->phonenumbers[0]);
673         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1][$userEntityKey]->articles[0]);
674         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1][$userEntityKey]->articles[1]);
675     }
676
677     /**
678      * SELECT u, p, UPPER(u.name) nameUpper, a, c
679      *   FROM User u
680      *   JOIN u.phonenumbers p
681      *   JOIN u.articles a
682      *   LEFT JOIN a.comments c
683      *
684      * @dataProvider provideDataForUserEntityResult
685      */
686     public function testMixedQueryMultipleDeepMixedFetchJoin($userEntityKey)
687     {
688         $rsm = new ResultSetMapping;
689         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
690         $rsm->addJoinedEntityResult(
691             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
692             'p',
693             'u',
694             'phonenumbers'
695         );
696         $rsm->addJoinedEntityResult(
697             'Doctrine\Tests\Models\CMS\CmsArticle',
698             'a',
699             'u',
700             'articles'
701         );
702         $rsm->addJoinedEntityResult(
703             'Doctrine\Tests\Models\CMS\CmsComment',
704             'c',
705             'a',
706             'comments'
707         );
708         $rsm->addFieldResult('u', 'u__id', 'id');
709         $rsm->addFieldResult('u', 'u__status', 'status');
710         $rsm->addScalarResult('sclr0', 'nameUpper');
711         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
712         $rsm->addFieldResult('a', 'a__id', 'id');
713         $rsm->addFieldResult('a', 'a__topic', 'topic');
714         $rsm->addFieldResult('c', 'c__id', 'id');
715         $rsm->addFieldResult('c', 'c__topic', 'topic');
716
717         // Faked result set
718         $resultSet = array(
719             //row1
720             array(
721                 'u__id' => '1',
722                 'u__status' => 'developer',
723                 'sclr0' => 'ROMANB',
724                 'p__phonenumber' => '42',
725                 'a__id' => '1',
726                 'a__topic' => 'Getting things done!',
727                 'c__id' => '1',
728                 'c__topic' => 'First!'
729             ),
730             array(
731                 'u__id' => '1',
732                 'u__status' => 'developer',
733                 'sclr0' => 'ROMANB',
734                 'p__phonenumber' => '43',
735                 'a__id' => '1',
736                 'a__topic' => 'Getting things done!',
737                 'c__id' => '1',
738                 'c__topic' => 'First!'
739             ),
740             array(
741                 'u__id' => '1',
742                 'u__status' => 'developer',
743                 'sclr0' => 'ROMANB',
744                 'p__phonenumber' => '42',
745                 'a__id' => '2',
746                 'a__topic' => 'ZendCon',
747                 'c__id' => null,
748                 'c__topic' => null
749             ),
750             array(
751                 'u__id' => '1',
752                 'u__status' => 'developer',
753                 'sclr0' => 'ROMANB',
754                 'p__phonenumber' => '43',
755                 'a__id' => '2',
756                 'a__topic' => 'ZendCon',
757                 'c__id' => null,
758                 'c__topic' => null
759             ),
760             array(
761                 'u__id' => '2',
762                 'u__status' => 'developer',
763                 'sclr0' => 'JWAGE',
764                 'p__phonenumber' => '91',
765                 'a__id' => '3',
766                 'a__topic' => 'LINQ',
767                 'c__id' => null,
768                 'c__topic' => null
769             ),
770             array(
771                 'u__id' => '2',
772                 'u__status' => 'developer',
773                 'sclr0' => 'JWAGE',
774                 'p__phonenumber' => '91',
775                 'a__id' => '4',
776                 'a__topic' => 'PHP6',
777                 'c__id' => null,
778                 'c__topic' => null
779             ),
780         );
781
782         $stmt     = new HydratorMockStatement($resultSet);
783         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
784         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
785
786         $this->assertEquals(2, count($result));
787
788         $this->assertTrue(is_array($result));
789         $this->assertTrue(is_array($result[0]));
790         $this->assertTrue(is_array($result[1]));
791
792         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][$userEntityKey]);
793         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1][$userEntityKey]);
794
795         // phonenumbers
796         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->phonenumbers);
797         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[0][$userEntityKey]->phonenumbers[0]);
798         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[0][$userEntityKey]->phonenumbers[1]);
799
800         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[1][$userEntityKey]->phonenumbers);
801         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsPhonenumber', $result[1][$userEntityKey]->phonenumbers[0]);
802
803         // articles
804         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->articles);
805         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[0][$userEntityKey]->articles[0]);
806         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[0][$userEntityKey]->articles[1]);
807
808         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1][$userEntityKey]->articles[0]);
809         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsArticle', $result[1][$userEntityKey]->articles[1]);
810
811         // article comments
812         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->articles[0]->comments);
813         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsComment', $result[0][$userEntityKey]->articles[0]->comments[0]);
814
815         // empty comment collections
816         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0][$userEntityKey]->articles[1]->comments);
817         $this->assertEquals(0, count($result[0][$userEntityKey]->articles[1]->comments));
818
819         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[1][$userEntityKey]->articles[0]->comments);
820         $this->assertEquals(0, count($result[1][$userEntityKey]->articles[0]->comments));
821         $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[1][$userEntityKey]->articles[1]->comments);
822         $this->assertEquals(0, count($result[1][$userEntityKey]->articles[1]->comments));
823     }
824
825     /**
826      * Tests that the hydrator does not rely on a particular order of the rows
827      * in the result set.
828      *
829      * DQL:
830      * select c, b from Doctrine\Tests\Models\Forum\ForumCategory c inner join c.boards b
831      * order by c.position asc, b.position asc
832      *
833      * Checks whether the boards are correctly assigned to the categories.
834      *
835      * The 'evil' result set that confuses the object population is displayed below.
836      *
837      * c.id  | c.position | c.name   | boardPos | b.id | b.category_id (just for clarity)
838      *  1    | 0          | First    | 0        |   1  | 1
839      *  2    | 0          | Second   | 0        |   2  | 2   <--
840      *  1    | 0          | First    | 1        |   3  | 1
841      *  1    | 0          | First    | 2        |   4  | 1
842      */
843     public function testEntityQueryCustomResultSetOrder()
844     {
845         $rsm = new ResultSetMapping;
846         $rsm->addEntityResult('Doctrine\Tests\Models\Forum\ForumCategory', 'c');
847         $rsm->addJoinedEntityResult(
848             'Doctrine\Tests\Models\Forum\ForumBoard',
849             'b',
850             'c',
851             'boards'
852         );
853         $rsm->addFieldResult('c', 'c__id', 'id');
854         $rsm->addFieldResult('c', 'c__position', 'position');
855         $rsm->addFieldResult('c', 'c__name', 'name');
856         $rsm->addFieldResult('b', 'b__id', 'id');
857         $rsm->addFieldResult('b', 'b__position', 'position');
858
859         // Faked result set
860         $resultSet = array(
861             array(
862                 'c__id' => '1',
863                 'c__position' => '0',
864                 'c__name' => 'First',
865                 'b__id' => '1',
866                 'b__position' => '0',
867                 //'b__category_id' => '1'
868             ),
869             array(
870                 'c__id' => '2',
871                 'c__position' => '0',
872                 'c__name' => 'Second',
873                 'b__id' => '2',
874                 'b__position' => '0',
875                 //'b__category_id' => '2'
876             ),
877             array(
878                 'c__id' => '1',
879                 'c__position' => '0',
880                 'c__name' => 'First',
881                 'b__id' => '3',
882                 'b__position' => '1',
883                 //'b__category_id' => '1'
884             ),
885             array(
886                 'c__id' => '1',
887                 'c__position' => '0',
888                 'c__name' => 'First',
889                 'b__id' => '4',
890                 'b__position' => '2',
891                 //'b__category_id' => '1'
892             )
893         );
894
895         $stmt     = new HydratorMockStatement($resultSet);
896         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
897         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
898
899         $this->assertEquals(2, count($result));
900
901         $this->assertInstanceOf('Doctrine\Tests\Models\Forum\ForumCategory', $result[0]);
902         $this->assertInstanceOf('Doctrine\Tests\Models\Forum\ForumCategory', $result[1]);
903
904         $this->assertTrue($result[0] !== $result[1]);
905
906         $this->assertEquals(1, $result[0]->getId());
907         $this->assertEquals(2, $result[1]->getId());
908
909         $this->assertTrue(isset($result[0]->boards));
910         $this->assertEquals(3, count($result[0]->boards));
911
912         $this->assertTrue(isset($result[1]->boards));
913         $this->assertEquals(1, count($result[1]->boards));
914     }
915
916     /**
917      * SELECT PARTIAL u.{id,name}
918      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
919      *
920      * @group DDC-644
921      */
922     public function testSkipUnknownColumns()
923     {
924         $rsm = new ResultSetMapping;
925         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
926         $rsm->addFieldResult('u', 'u__id', 'id');
927         $rsm->addFieldResult('u', 'u__name', 'name');
928
929         // Faked result set
930         $resultSet = array(
931             array(
932                 'u__id' => '1',
933                 'u__name' => 'romanb',
934                 'foo' => 'bar', // unknown!
935             ),
936         );
937
938         $stmt     = new HydratorMockStatement($resultSet);
939         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
940         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
941
942         $this->assertEquals(1, count($result));
943         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]);
944     }
945
946     /**
947      * SELECT u.id, u.name
948      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
949      *
950      * @dataProvider provideDataForUserEntityResult
951      */
952     public function testScalarQueryWithoutResultVariables($userEntityKey)
953     {
954         $rsm = new ResultSetMapping;
955         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
956         $rsm->addScalarResult('sclr0', 'id');
957         $rsm->addScalarResult('sclr1', 'name');
958
959         // Faked result set
960         $resultSet = array(
961             array(
962                 'sclr0' => '1',
963                 'sclr1' => 'romanb'
964             ),
965             array(
966                 'sclr0' => '2',
967                 'sclr1' => 'jwage'
968             )
969         );
970
971         $stmt     = new HydratorMockStatement($resultSet);
972         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
973         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
974
975         $this->assertEquals(2, count($result));
976
977         $this->assertInternalType('array', $result[0]);
978         $this->assertInternalType('array', $result[1]);
979
980         $this->assertEquals(1, $result[0]['id']);
981         $this->assertEquals('romanb', $result[0]['name']);
982
983         $this->assertEquals(2, $result[1]['id']);
984         $this->assertEquals('jwage', $result[1]['name']);
985     }
986
987     /**
988      * SELECT p
989      *   FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p
990      */
991     public function testCreatesProxyForLazyLoadingWithForeignKeys()
992     {
993         $rsm = new ResultSetMapping;
994         $rsm->addEntityResult('Doctrine\Tests\Models\ECommerce\ECommerceProduct', 'p');
995         $rsm->addFieldResult('p', 'p__id', 'id');
996         $rsm->addFieldResult('p', 'p__name', 'name');
997         $rsm->addMetaResult('p', 'p__shipping_id', 'shipping_id');
998
999         // Faked result set
1000         $resultSet = array(
1001             array(
1002                 'p__id' => '1',
1003                 'p__name' => 'Doctrine Book',
1004                 'p__shipping_id' => 42
1005             )
1006         );
1007
1008         $proxyInstance = new \Doctrine\Tests\Models\ECommerce\ECommerceShipping();
1009
1010         // mocking the proxy factory
1011         $proxyFactory = $this->getMock('Doctrine\ORM\Proxy\ProxyFactory', array('getProxy'), array(), '', false, false, false);
1012         $proxyFactory->expects($this->once())
1013                      ->method('getProxy')
1014                      ->with($this->equalTo('Doctrine\Tests\Models\ECommerce\ECommerceShipping'), array('id' => 42))
1015                      ->will($this->returnValue($proxyInstance));
1016
1017         $this->_em->setProxyFactory($proxyFactory);
1018
1019         // configuring lazy loading
1020         $metadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
1021         $metadata->associationMappings['shipping']['fetch'] = ClassMetadata::FETCH_LAZY;
1022
1023         $stmt     = new HydratorMockStatement($resultSet);
1024         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1025         $result   = $hydrator->hydrateAll($stmt, $rsm);
1026
1027         $this->assertEquals(1, count($result));
1028
1029         $this->assertInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $result[0]);
1030     }
1031
1032     /**
1033      * SELECT p AS product
1034      *   FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p
1035      */
1036     public function testCreatesProxyForLazyLoadingWithForeignKeysWithAliasedProductEntity()
1037     {
1038         $rsm = new ResultSetMapping;
1039         $rsm->addEntityResult('Doctrine\Tests\Models\ECommerce\ECommerceProduct', 'p', 'product');
1040         $rsm->addFieldResult('p', 'p__id', 'id');
1041         $rsm->addFieldResult('p', 'p__name', 'name');
1042         $rsm->addMetaResult('p', 'p__shipping_id', 'shipping_id');
1043
1044         // Faked result set
1045         $resultSet = array(
1046             array(
1047                 'p__id' => '1',
1048                 'p__name' => 'Doctrine Book',
1049                 'p__shipping_id' => 42
1050             )
1051         );
1052
1053         $proxyInstance = new \Doctrine\Tests\Models\ECommerce\ECommerceShipping();
1054
1055         // mocking the proxy factory
1056         $proxyFactory = $this->getMock('Doctrine\ORM\Proxy\ProxyFactory', array('getProxy'), array(), '', false, false, false);
1057         $proxyFactory->expects($this->once())
1058                      ->method('getProxy')
1059                      ->with($this->equalTo('Doctrine\Tests\Models\ECommerce\ECommerceShipping'), array('id' => 42))
1060                      ->will($this->returnValue($proxyInstance));
1061
1062         $this->_em->setProxyFactory($proxyFactory);
1063
1064         // configuring lazy loading
1065         $metadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
1066         $metadata->associationMappings['shipping']['fetch'] = ClassMetadata::FETCH_LAZY;
1067
1068         $stmt     = new HydratorMockStatement($resultSet);
1069         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1070         $result   = $hydrator->hydrateAll($stmt, $rsm);
1071
1072         $this->assertEquals(1, count($result));
1073
1074         $this->assertInternalType('array', $result[0]);
1075         $this->assertInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $result[0]['product']);
1076     }
1077
1078     /**
1079      * SELECT PARTIAL u.{id, status}, PARTIAL a.{id, topic}, PARTIAL c.{id, topic}
1080      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1081      *   LEFT JOIN u.articles a
1082      *   LEFT JOIN a.comments c
1083      */
1084     public function testChainedJoinWithEmptyCollections()
1085     {
1086         $rsm = new ResultSetMapping;
1087         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
1088         $rsm->addJoinedEntityResult(
1089             'Doctrine\Tests\Models\CMS\CmsArticle',
1090             'a',
1091             'u',
1092             'articles'
1093         );
1094         $rsm->addJoinedEntityResult(
1095             'Doctrine\Tests\Models\CMS\CmsComment',
1096             'c',
1097             'a',
1098             'comments'
1099         );
1100         $rsm->addFieldResult('u', 'u__id', 'id');
1101         $rsm->addFieldResult('u', 'u__status', 'status');
1102         $rsm->addFieldResult('a', 'a__id', 'id');
1103         $rsm->addFieldResult('a', 'a__topic', 'topic');
1104         $rsm->addFieldResult('c', 'c__id', 'id');
1105         $rsm->addFieldResult('c', 'c__topic', 'topic');
1106
1107         // Faked result set
1108         $resultSet = array(
1109             //row1
1110             array(
1111                 'u__id' => '1',
1112                 'u__status' => 'developer',
1113                 'a__id' => null,
1114                 'a__topic' => null,
1115                 'c__id' => null,
1116                 'c__topic' => null
1117             ),
1118             array(
1119                 'u__id' => '2',
1120                 'u__status' => 'developer',
1121                 'a__id' => null,
1122                 'a__topic' => null,
1123                 'c__id' => null,
1124                 'c__topic' => null
1125             ),
1126         );
1127
1128         $stmt     = new HydratorMockStatement($resultSet);
1129         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1130         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1131
1132         $this->assertEquals(2, count($result));
1133
1134         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]);
1135         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1]);
1136
1137         $this->assertEquals(0, $result[0]->articles->count());
1138         $this->assertEquals(0, $result[1]->articles->count());
1139     }
1140
1141     /**
1142      * SELECT PARTIAL u.{id, status} AS user, PARTIAL a.{id, topic}, PARTIAL c.{id, topic}
1143      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1144      *   LEFT JOIN u.articles a
1145      *   LEFT JOIN a.comments c
1146      */
1147     public function testChainedJoinWithEmptyCollectionsWithAliasedUserEntity()
1148     {
1149         $rsm = new ResultSetMapping;
1150         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
1151         $rsm->addJoinedEntityResult(
1152             'Doctrine\Tests\Models\CMS\CmsArticle',
1153             'a',
1154             'u',
1155             'articles'
1156         );
1157         $rsm->addJoinedEntityResult(
1158             'Doctrine\Tests\Models\CMS\CmsComment',
1159             'c',
1160             'a',
1161             'comments'
1162         );
1163         $rsm->addFieldResult('u', 'u__id', 'id');
1164         $rsm->addFieldResult('u', 'u__status', 'status');
1165         $rsm->addFieldResult('a', 'a__id', 'id');
1166         $rsm->addFieldResult('a', 'a__topic', 'topic');
1167         $rsm->addFieldResult('c', 'c__id', 'id');
1168         $rsm->addFieldResult('c', 'c__topic', 'topic');
1169
1170         // Faked result set
1171         $resultSet = array(
1172             //row1
1173             array(
1174                 'u__id' => '1',
1175                 'u__status' => 'developer',
1176                 'a__id' => null,
1177                 'a__topic' => null,
1178                 'c__id' => null,
1179                 'c__topic' => null
1180             ),
1181             array(
1182                 'u__id' => '2',
1183                 'u__status' => 'developer',
1184                 'a__id' => null,
1185                 'a__topic' => null,
1186                 'c__id' => null,
1187                 'c__topic' => null
1188             ),
1189         );
1190
1191         $stmt     = new HydratorMockStatement($resultSet);
1192         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1193         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1194
1195         $this->assertEquals(2, count($result));
1196
1197         $this->assertInternalType('array', $result[0]);
1198         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]['user']);
1199
1200         $this->assertInternalType('array', $result[1]);
1201         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1]['user']);
1202
1203         $this->assertEquals(0, $result[0]['user']->articles->count());
1204         $this->assertEquals(0, $result[1]['user']->articles->count());
1205     }
1206
1207     /**
1208      * SELECT PARTIAL u.{id,status}, a.id, a.topic, c.id as cid, c.topic as ctopic
1209      *   FROM CmsUser u
1210      *   LEFT JOIN u.articles a
1211      *   LEFT JOIN a.comments c
1212      *
1213      * @group bubu
1214      * @dataProvider provideDataForUserEntityResult
1215      */
1216     /*public function testChainedJoinWithScalars($userEntityKey)
1217     {
1218         $rsm = new ResultSetMapping;
1219         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1220         $rsm->addFieldResult('u', 'u__id', 'id');
1221         $rsm->addFieldResult('u', 'u__status', 'status');
1222         $rsm->addScalarResult('a__id', 'id');
1223         $rsm->addScalarResult('a__topic', 'topic');
1224         $rsm->addScalarResult('c__id', 'cid');
1225         $rsm->addScalarResult('c__topic', 'ctopic');
1226
1227         // Faked result set
1228         $resultSet = array(
1229             //row1
1230             array(
1231                 'u__id' => '1',
1232                 'u__status' => 'developer',
1233                 'a__id' => '1',
1234                 'a__topic' => 'The First',
1235                 'c__id' => '1',
1236                 'c__topic' => 'First Comment'
1237             ),
1238             array(
1239                 'u__id' => '1',
1240                 'u__status' => 'developer',
1241                 'a__id' => '1',
1242                 'a__topic' => 'The First',
1243                 'c__id' => '2',
1244                 'c__topic' => 'Second Comment'
1245             ),
1246             array(
1247                 'u__id' => '1',
1248                 'u__status' => 'developer',
1249                 'a__id' => '42',
1250                 'a__topic' => 'The Answer',
1251                 'c__id' => null,
1252                 'c__topic' => null
1253             ),
1254         );
1255
1256         $stmt     = new HydratorMockStatement($resultSet);
1257         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1258         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1259
1260         \Doctrine\Common\Util\Debug::dump($result, 3);
1261
1262         $this->assertEquals(1, count($result));
1263
1264         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][$userEntityKey]); // User object
1265         $this->assertEquals(42, $result[0]['id']);
1266         $this->assertEquals('The First', $result[0]['topic']);
1267         $this->assertEquals(1, $result[0]['cid']);
1268         $this->assertEquals('First Comment', $result[0]['ctopic']);
1269     }*/
1270
1271     /**
1272      * SELECT PARTIAL u.{id, name}
1273      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1274      */
1275     public function testResultIteration()
1276     {
1277         $rsm = new ResultSetMapping;
1278         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
1279         $rsm->addFieldResult('u', 'u__id', 'id');
1280         $rsm->addFieldResult('u', 'u__name', 'name');
1281
1282         // Faked result set
1283         $resultSet = array(
1284             array(
1285                 'u__id' => '1',
1286                 'u__name' => 'romanb'
1287             ),
1288             array(
1289                 'u__id' => '2',
1290                 'u__name' => 'jwage'
1291             )
1292         );
1293
1294         $stmt           = new HydratorMockStatement($resultSet);
1295         $hydrator       = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1296         $iterableResult = $hydrator->iterate($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1297         $rowNum         = 0;
1298
1299         while (($row = $iterableResult->next()) !== false) {
1300             $this->assertEquals(1, count($row));
1301             $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $row[0]);
1302
1303             if ($rowNum == 0) {
1304                 $this->assertEquals(1, $row[0]->id);
1305                 $this->assertEquals('romanb', $row[0]->name);
1306             } else if ($rowNum == 1) {
1307                 $this->assertEquals(2, $row[0]->id);
1308                 $this->assertEquals('jwage', $row[0]->name);
1309             }
1310
1311             ++$rowNum;
1312         }
1313     }
1314
1315     /**
1316      * SELECT PARTIAL u.{id, name}
1317      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1318      */
1319     public function testResultIterationWithAliasedUserEntity()
1320     {
1321         $rsm = new ResultSetMapping;
1322         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
1323         $rsm->addFieldResult('u', 'u__id', 'id');
1324         $rsm->addFieldResult('u', 'u__name', 'name');
1325
1326         // Faked result set
1327         $resultSet = array(
1328             array(
1329                 'u__id' => '1',
1330                 'u__name' => 'romanb'
1331             ),
1332             array(
1333                 'u__id' => '2',
1334                 'u__name' => 'jwage'
1335             )
1336         );
1337
1338         $stmt           = new HydratorMockStatement($resultSet);
1339         $hydrator       = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1340         $iterableResult = $hydrator->iterate($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1341         $rowNum         = 0;
1342
1343         while (($row = $iterableResult->next()) !== false) {
1344             $this->assertEquals(1, count($row));
1345             $this->assertArrayHasKey(0, $row);
1346             $this->assertArrayHasKey('user', $row[0]);
1347             $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $row[0]['user']);
1348
1349             if ($rowNum == 0) {
1350                 $this->assertEquals(1, $row[0]['user']->id);
1351                 $this->assertEquals('romanb', $row[0]['user']->name);
1352             } else if ($rowNum == 1) {
1353                 $this->assertEquals(2, $row[0]['user']->id);
1354                 $this->assertEquals('jwage', $row[0]['user']->name);
1355             }
1356
1357             ++$rowNum;
1358         }
1359     }
1360
1361     /**
1362      * Checks if multiple joined multiple-valued collections is hydrated correctly.
1363      *
1364      * SELECT PARTIAL u.{id, status}, PARTIAL g.{id, name}, PARTIAL p.{phonenumber}
1365      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1366      *
1367      * @group DDC-809
1368      */
1369     public function testManyToManyHydration()
1370     {
1371         $rsm = new ResultSetMapping;
1372         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
1373         $rsm->addFieldResult('u', 'u__id', 'id');
1374         $rsm->addFieldResult('u', 'u__name', 'name');
1375         $rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsGroup', 'g', 'u', 'groups');
1376         $rsm->addFieldResult('g', 'g__id', 'id');
1377         $rsm->addFieldResult('g', 'g__name', 'name');
1378         $rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p', 'u', 'phonenumbers');
1379         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
1380
1381         // Faked result set
1382         $resultSet = array(
1383             array(
1384                 'u__id' => '1',
1385                 'u__name' => 'romanb',
1386                 'g__id' => '3',
1387                 'g__name' => 'TestGroupB',
1388                 'p__phonenumber' => 1111,
1389             ),
1390             array(
1391                 'u__id' => '1',
1392                 'u__name' => 'romanb',
1393                 'g__id' => '5',
1394                 'g__name' => 'TestGroupD',
1395                 'p__phonenumber' => 1111,
1396             ),
1397             array(
1398                 'u__id' => '1',
1399                 'u__name' => 'romanb',
1400                 'g__id' => '3',
1401                 'g__name' => 'TestGroupB',
1402                 'p__phonenumber' => 2222,
1403             ),
1404             array(
1405                 'u__id' => '1',
1406                 'u__name' => 'romanb',
1407                 'g__id' => '5',
1408                 'g__name' => 'TestGroupD',
1409                 'p__phonenumber' => 2222,
1410             ),
1411             array(
1412                 'u__id' => '2',
1413                 'u__name' => 'jwage',
1414                 'g__id' => '2',
1415                 'g__name' => 'TestGroupA',
1416                 'p__phonenumber' => 3333,
1417             ),
1418             array(
1419                 'u__id' => '2',
1420                 'u__name' => 'jwage',
1421                 'g__id' => '3',
1422                 'g__name' => 'TestGroupB',
1423                 'p__phonenumber' => 3333,
1424             ),
1425             array(
1426                 'u__id' => '2',
1427                 'u__name' => 'jwage',
1428                 'g__id' => '4',
1429                 'g__name' => 'TestGroupC',
1430                 'p__phonenumber' => 3333,
1431             ),
1432             array(
1433                 'u__id' => '2',
1434                 'u__name' => 'jwage',
1435                 'g__id' => '5',
1436                 'g__name' => 'TestGroupD',
1437                 'p__phonenumber' => 3333,
1438             ),
1439             array(
1440                 'u__id' => '2',
1441                 'u__name' => 'jwage',
1442                 'g__id' => '2',
1443                 'g__name' => 'TestGroupA',
1444                 'p__phonenumber' => 4444,
1445             ),
1446             array(
1447                 'u__id' => '2',
1448                 'u__name' => 'jwage',
1449                 'g__id' => '3',
1450                 'g__name' => 'TestGroupB',
1451                 'p__phonenumber' => 4444,
1452             ),
1453             array(
1454                 'u__id' => '2',
1455                 'u__name' => 'jwage',
1456                 'g__id' => '4',
1457                 'g__name' => 'TestGroupC',
1458                 'p__phonenumber' => 4444,
1459             ),
1460             array(
1461                 'u__id' => '2',
1462                 'u__name' => 'jwage',
1463                 'g__id' => '5',
1464                 'g__name' => 'TestGroupD',
1465                 'p__phonenumber' => 4444,
1466             ),
1467         );
1468
1469         $stmt     = new HydratorMockStatement($resultSet);
1470         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1471         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1472
1473         $this->assertEquals(2, count($result));
1474
1475         $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsUser', $result);
1476
1477         $this->assertEquals(2, count($result[0]->groups));
1478         $this->assertEquals(2, count($result[0]->phonenumbers));
1479
1480         $this->assertEquals(4, count($result[1]->groups));
1481         $this->assertEquals(2, count($result[1]->phonenumbers));
1482     }
1483
1484     /**
1485      * Checks if multiple joined multiple-valued collections is hydrated correctly.
1486      *
1487      * SELECT PARTIAL u.{id, status} As user, PARTIAL g.{id, name}, PARTIAL p.{phonenumber}
1488      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1489      *
1490      * @group DDC-809
1491      */
1492     public function testManyToManyHydrationWithAliasedUserEntity()
1493     {
1494         $rsm = new ResultSetMapping;
1495         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
1496         $rsm->addFieldResult('u', 'u__id', 'id');
1497         $rsm->addFieldResult('u', 'u__name', 'name');
1498         $rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsGroup', 'g', 'u', 'groups');
1499         $rsm->addFieldResult('g', 'g__id', 'id');
1500         $rsm->addFieldResult('g', 'g__name', 'name');
1501         $rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p', 'u', 'phonenumbers');
1502         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
1503
1504         // Faked result set
1505         $resultSet = array(
1506             array(
1507                 'u__id' => '1',
1508                 'u__name' => 'romanb',
1509                 'g__id' => '3',
1510                 'g__name' => 'TestGroupB',
1511                 'p__phonenumber' => 1111,
1512             ),
1513             array(
1514                 'u__id' => '1',
1515                 'u__name' => 'romanb',
1516                 'g__id' => '5',
1517                 'g__name' => 'TestGroupD',
1518                 'p__phonenumber' => 1111,
1519             ),
1520             array(
1521                 'u__id' => '1',
1522                 'u__name' => 'romanb',
1523                 'g__id' => '3',
1524                 'g__name' => 'TestGroupB',
1525                 'p__phonenumber' => 2222,
1526             ),
1527             array(
1528                 'u__id' => '1',
1529                 'u__name' => 'romanb',
1530                 'g__id' => '5',
1531                 'g__name' => 'TestGroupD',
1532                 'p__phonenumber' => 2222,
1533             ),
1534             array(
1535                 'u__id' => '2',
1536                 'u__name' => 'jwage',
1537                 'g__id' => '2',
1538                 'g__name' => 'TestGroupA',
1539                 'p__phonenumber' => 3333,
1540             ),
1541             array(
1542                 'u__id' => '2',
1543                 'u__name' => 'jwage',
1544                 'g__id' => '3',
1545                 'g__name' => 'TestGroupB',
1546                 'p__phonenumber' => 3333,
1547             ),
1548             array(
1549                 'u__id' => '2',
1550                 'u__name' => 'jwage',
1551                 'g__id' => '4',
1552                 'g__name' => 'TestGroupC',
1553                 'p__phonenumber' => 3333,
1554             ),
1555             array(
1556                 'u__id' => '2',
1557                 'u__name' => 'jwage',
1558                 'g__id' => '5',
1559                 'g__name' => 'TestGroupD',
1560                 'p__phonenumber' => 3333,
1561             ),
1562             array(
1563                 'u__id' => '2',
1564                 'u__name' => 'jwage',
1565                 'g__id' => '2',
1566                 'g__name' => 'TestGroupA',
1567                 'p__phonenumber' => 4444,
1568             ),
1569             array(
1570                 'u__id' => '2',
1571                 'u__name' => 'jwage',
1572                 'g__id' => '3',
1573                 'g__name' => 'TestGroupB',
1574                 'p__phonenumber' => 4444,
1575             ),
1576             array(
1577                 'u__id' => '2',
1578                 'u__name' => 'jwage',
1579                 'g__id' => '4',
1580                 'g__name' => 'TestGroupC',
1581                 'p__phonenumber' => 4444,
1582             ),
1583             array(
1584                 'u__id' => '2',
1585                 'u__name' => 'jwage',
1586                 'g__id' => '5',
1587                 'g__name' => 'TestGroupD',
1588                 'p__phonenumber' => 4444,
1589             ),
1590         );
1591
1592         $stmt     = new HydratorMockStatement($resultSet);
1593         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1594         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1595
1596         $this->assertEquals(2, count($result));
1597
1598         $this->assertInternalType('array', $result[0]);
1599         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]['user']);
1600         $this->assertInternalType('array', $result[1]);
1601         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[1]['user']);
1602
1603         $this->assertEquals(2, count($result[0]['user']->groups));
1604         $this->assertEquals(2, count($result[0]['user']->phonenumbers));
1605
1606         $this->assertEquals(4, count($result[1]['user']->groups));
1607         $this->assertEquals(2, count($result[1]['user']->phonenumbers));
1608     }
1609
1610     /**
1611      * SELECT PARTIAL u.{id, status}, UPPER(u.name) as nameUpper
1612      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1613      *
1614      * @group DDC-1358
1615      * @dataProvider provideDataForUserEntityResult
1616      */
1617     public function testMissingIdForRootEntity($userEntityKey)
1618     {
1619         $rsm = new ResultSetMapping;
1620         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1621         $rsm->addFieldResult('u', 'u__id', 'id');
1622         $rsm->addFieldResult('u', 'u__status', 'status');
1623         $rsm->addScalarResult('sclr0', 'nameUpper');
1624
1625         // Faked result set
1626         $resultSet = array(
1627             //row1
1628             array(
1629                 'u__id' => '1',
1630                 'u__status' => 'developer',
1631                 'sclr0' => 'ROMANB',
1632             ),
1633             array(
1634                 'u__id' => null,
1635                 'u__status' => null,
1636                 'sclr0' => 'ROMANB',
1637             ),
1638             array(
1639                 'u__id' => '2',
1640                 'u__status' => 'developer',
1641                 'sclr0' => 'JWAGE',
1642             ),
1643             array(
1644                 'u__id' => null,
1645                 'u__status' => null,
1646                 'sclr0' => 'JWAGE',
1647             ),
1648         );
1649
1650         $stmt     = new HydratorMockStatement($resultSet);
1651         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1652         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1653
1654         $this->assertEquals(4, count($result), "Should hydrate four results.");
1655
1656         $this->assertEquals('ROMANB', $result[0]['nameUpper']);
1657         $this->assertEquals('ROMANB', $result[1]['nameUpper']);
1658         $this->assertEquals('JWAGE', $result[2]['nameUpper']);
1659         $this->assertEquals('JWAGE', $result[3]['nameUpper']);
1660
1661         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0][$userEntityKey]);
1662         $this->assertNull($result[1][$userEntityKey]);
1663
1664         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[2][$userEntityKey]);
1665         $this->assertNull($result[3][$userEntityKey]);
1666     }
1667
1668     /**
1669      * SELECT PARTIAL u.{id, status}, PARTIAL p.{phonenumber}, UPPER(u.name) AS nameUpper
1670      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1671      *   LEFT JOIN u.phonenumbers u
1672      *
1673      * @group DDC-1358
1674      * @dataProvider provideDataForUserEntityResult
1675      */
1676     public function testMissingIdForCollectionValuedChildEntity($userEntityKey)
1677     {
1678         $rsm = new ResultSetMapping;
1679         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1680         $rsm->addJoinedEntityResult(
1681             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
1682             'p',
1683             'u',
1684             'phonenumbers'
1685         );
1686         $rsm->addFieldResult('u', 'u__id', 'id');
1687         $rsm->addFieldResult('u', 'u__status', 'status');
1688         $rsm->addScalarResult('sclr0', 'nameUpper');
1689         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
1690
1691         // Faked result set
1692         $resultSet = array(
1693             //row1
1694             array(
1695                 'u__id' => '1',
1696                 'u__status' => 'developer',
1697                 'sclr0' => 'ROMANB',
1698                 'p__phonenumber' => '42',
1699             ),
1700             array(
1701                 'u__id' => '1',
1702                 'u__status' => 'developer',
1703                 'sclr0' => 'ROMANB',
1704                 'p__phonenumber' => null
1705             ),
1706             array(
1707                 'u__id' => '2',
1708                 'u__status' => 'developer',
1709                 'sclr0' => 'JWAGE',
1710                 'p__phonenumber' => '91'
1711             ),
1712             array(
1713                 'u__id' => '2',
1714                 'u__status' => 'developer',
1715                 'sclr0' => 'JWAGE',
1716                 'p__phonenumber' => null
1717             )
1718         );
1719
1720         $stmt     = new HydratorMockStatement($resultSet);
1721         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1722         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1723
1724         $this->assertEquals(2, count($result));
1725
1726         $this->assertEquals(1, $result[0][$userEntityKey]->phonenumbers->count());
1727         $this->assertEquals(1, $result[1][$userEntityKey]->phonenumbers->count());
1728     }
1729
1730     /**
1731      * SELECT PARTIAL u.{id, status}, PARTIAL a.{id, city}, UPPER(u.name) AS nameUpper
1732      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1733      *   JOIN u.address a
1734      *
1735      * @group DDC-1358
1736      * @dataProvider provideDataForUserEntityResult
1737      */
1738     public function testMissingIdForSingleValuedChildEntity($userEntityKey)
1739     {
1740         $rsm = new ResultSetMapping;
1741         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1742         $rsm->addJoinedEntityResult(
1743             'Doctrine\Tests\Models\CMS\CmsAddress',
1744             'a',
1745             'u',
1746             'address'
1747         );
1748         $rsm->addFieldResult('u', 'u__id', 'id');
1749         $rsm->addFieldResult('u', 'u__status', 'status');
1750         $rsm->addScalarResult('sclr0', 'nameUpper');
1751         $rsm->addFieldResult('a', 'a__id', 'id');
1752         $rsm->addFieldResult('a', 'a__city', 'city');
1753         $rsm->addMetaResult('a', 'user_id', 'user_id');
1754
1755         // Faked result set
1756         $resultSet = array(
1757             //row1
1758             array(
1759                 'u__id' => '1',
1760                 'u__status' => 'developer',
1761                 'sclr0' => 'ROMANB',
1762                 'a__id' => 1,
1763                 'a__city' => 'Berlin',
1764             ),
1765             array(
1766                 'u__id' => '2',
1767                 'u__status' => 'developer',
1768                 'sclr0' => 'BENJAMIN',
1769                 'a__id' => null,
1770                 'a__city' => null,
1771             ),
1772         );
1773
1774         $stmt     = new HydratorMockStatement($resultSet);
1775         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1776         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1777
1778         $this->assertEquals(2, count($result));
1779
1780         $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsAddress', $result[0][$userEntityKey]->address);
1781         $this->assertNull($result[1][$userEntityKey]->address);
1782     }
1783
1784     /**
1785      * SELECT PARTIAL u.{id, status}, UPPER(u.name) AS nameUpper
1786      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1787      *        INDEX BY u.id
1788      *
1789      * @group DDC-1385
1790      * @dataProvider provideDataForUserEntityResult
1791      */
1792     public function testIndexByAndMixedResult($userEntityKey)
1793     {
1794         $rsm = new ResultSetMapping;
1795         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1796         $rsm->addFieldResult('u', 'u__id', 'id');
1797         $rsm->addFieldResult('u', 'u__status', 'status');
1798         $rsm->addScalarResult('sclr0', 'nameUpper');
1799         $rsm->addIndexBy('u', 'id');
1800
1801         // Faked result set
1802         $resultSet = array(
1803             //row1
1804             array(
1805                 'u__id' => '1',
1806                 'u__status' => 'developer',
1807                 'sclr0' => 'ROMANB',
1808             ),
1809             array(
1810                 'u__id' => '2',
1811                 'u__status' => 'developer',
1812                 'sclr0' => 'JWAGE',
1813             ),
1814         );
1815
1816         $stmt     = new HydratorMockStatement($resultSet);
1817         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1818         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1819
1820         $this->assertEquals(2, count($result));
1821
1822         $this->assertTrue(isset($result[1]));
1823         $this->assertEquals(1, $result[1][$userEntityKey]->id);
1824
1825         $this->assertTrue(isset($result[2]));
1826         $this->assertEquals(2, $result[2][$userEntityKey]->id);
1827     }
1828
1829     /**
1830      * SELECT UPPER(u.name) AS nameUpper
1831      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1832      *
1833      * @group DDC-1385
1834      * @dataProvider provideDataForUserEntityResult
1835      */
1836     public function testIndexByScalarsOnly($userEntityKey)
1837     {
1838         $rsm = new ResultSetMapping;
1839         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1840         $rsm->addScalarResult('sclr0', 'nameUpper');
1841         $rsm->addIndexByScalar('sclr0');
1842
1843         // Faked result set
1844         $resultSet = array(
1845             //row1
1846             array(
1847                 'sclr0' => 'ROMANB',
1848             ),
1849             array(
1850                 'sclr0' => 'JWAGE',
1851             ),
1852         );
1853
1854         $stmt     = new HydratorMockStatement($resultSet);
1855         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1856         $result   = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
1857
1858         $this->assertEquals(
1859             array(
1860                 'ROMANB' => array('nameUpper' => 'ROMANB'),
1861                 'JWAGE'  => array('nameUpper' => 'JWAGE')
1862             ),
1863             $result
1864         );
1865     }
1866
1867
1868     /**
1869      * @group DDC-1470
1870      *
1871      * @expectedException \Doctrine\ORM\Internal\Hydration\HydrationException
1872      * @expectedExceptionMessage The meta mapping for the discriminator column "c_discr" is missing for "Doctrine\Tests\Models\Company\CompanyFixContract" using the DQL alias "c".
1873      */
1874     public function testMissingMetaMappingException()
1875     {
1876         $rsm = new ResultSetMapping;
1877
1878         $rsm->addEntityResult('Doctrine\Tests\Models\Company\CompanyFixContract', 'c');
1879         $rsm->addJoinedEntityResult('Doctrine\Tests\Models\Company\CompanyEmployee', 'e', 'c', 'salesPerson');
1880
1881         $rsm->addFieldResult('c', 'c__id', 'id');
1882         $rsm->setDiscriminatorColumn('c', 'c_discr');
1883
1884         $resultSet = array(
1885               array(
1886                   'c__id'   => '1',
1887                   'c_discr' => 'fix',
1888               ),
1889          );
1890
1891         $stmt     = new HydratorMockStatement($resultSet);
1892         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1893         $hydrator->hydrateAll($stmt, $rsm);
1894     }
1895
1896     /**
1897      * @group DDC-1470
1898      *
1899      * @expectedException \Doctrine\ORM\Internal\Hydration\HydrationException
1900      * @expectedExceptionMessage The discriminator column "discr" is missing for "Doctrine\Tests\Models\Company\CompanyEmployee" using the DQL alias "e".
1901      */
1902     public function testMissingDiscriminatorColumnException()
1903     {
1904         $rsm = new ResultSetMapping;
1905
1906         $rsm->addEntityResult('Doctrine\Tests\Models\Company\CompanyFixContract', 'c');
1907         $rsm->addJoinedEntityResult('Doctrine\Tests\Models\Company\CompanyEmployee', 'e', 'c', 'salesPerson');
1908
1909         $rsm->addFieldResult('c', 'c__id', 'id');
1910         $rsm->addMetaResult('c', 'c_discr', 'discr');
1911         $rsm->setDiscriminatorColumn('c', 'c_discr');
1912
1913         $rsm->addFieldResult('e', 'e__id', 'id');
1914         $rsm->addFieldResult('e', 'e__name', 'name');
1915         $rsm->addMetaResult('e ', 'e_discr', 'discr');
1916         $rsm->setDiscriminatorColumn('e', 'e_discr');
1917
1918         $resultSet = array(
1919               array(
1920                   'c__id'   => '1',
1921                   'c_discr' => 'fix',
1922                   'e__id'   => '1',
1923                   'e__name' => 'Fabio B. Silva'
1924               ),
1925          );
1926
1927         $stmt     = new HydratorMockStatement($resultSet);
1928         $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
1929         $hydrator->hydrateAll($stmt, $rsm);
1930     }
1931 }