Skip to content

Commit 7c8a528

Browse files
authored
Merge pull request #12211 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2 parents 40fedad + 64cd5ca commit 7c8a528

File tree

5 files changed

+129
-15
lines changed

5 files changed

+129
-15
lines changed

src/AbstractQuery.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
1919
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
2020
use Doctrine\ORM\Query\Parameter;
21-
use Doctrine\ORM\Query\QueryException;
2221
use Doctrine\ORM\Query\ResultSetMapping;
2322
use Doctrine\Persistence\Mapping\MappingException;
2423
use LogicException;
@@ -865,10 +864,6 @@ public function toIterable(
865864
throw new LogicException('Uninitialized result set mapping.');
866865
}
867866

868-
if ($rsm->isMixed && count($rsm->scalarMappings) > 0) {
869-
throw QueryException::iterateWithMixedResultNotAllowed();
870-
}
871-
872867
$stmt = $this->_doExecute();
873868

874869
return $this->em->newHydrator($this->hydrationMode)->toIterable($stmt, $rsm, $this->hints);

src/Internal/Hydration/AbstractHydrator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
use function array_map;
2424
use function array_merge;
2525
use function count;
26+
use function current;
2627
use function end;
2728
use function in_array;
2829
use function is_array;
30+
use function is_object;
2931
use function ksort;
3032

3133
/**
@@ -126,8 +128,10 @@ final public function toIterable(Result $stmt, ResultSetMapping $resultSetMappin
126128
} else {
127129
yield from $result;
128130
}
129-
} else {
131+
} elseif (is_object(current($result))) {
130132
yield $result;
133+
} else {
134+
yield array_merge(...$result);
131135
}
132136
}
133137
} finally {

tests/Tests/ORM/Functional/QueryTest.php

Lines changed: 120 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,128 @@ public function testToIterableWithMultipleSelectElements(): void
403403
}
404404
}
405405

406-
public function testToIterableWithMixedResultIsNotAllowed(): void
406+
public function testToIterableWithMixedResultEntityScalars(): void
407407
{
408-
$this->expectException(QueryException::class);
409-
$this->expectExceptionMessage('Iterating a query with mixed results (using scalars) is not supported.');
408+
$author = new CmsUser();
409+
$author->name = 'Ben';
410+
$author->username = 'beberlei';
410411

411-
$query = $this->_em->createQuery('select a, a.topic from ' . CmsArticle::class . ' a');
412-
$query->toIterable();
412+
$article1 = new CmsArticle();
413+
$article1->topic = 'Doctrine 2';
414+
$article1->text = 'This is an introduction to Doctrine 2.';
415+
$article1->setAuthor($author);
416+
417+
$article2 = new CmsArticle();
418+
$article2->topic = 'Symfony 2';
419+
$article2->text = 'This is an introduction to Symfony 2.';
420+
$article2->setAuthor($author);
421+
422+
$article3 = new CmsArticle();
423+
$article3->topic = 'lala 2';
424+
$article3->text = 'This is an introduction to Symfony 2.';
425+
$article3->setAuthor($author);
426+
427+
$this->_em->persist($article1);
428+
$this->_em->persist($article2);
429+
$this->_em->persist($article3);
430+
$this->_em->persist($author);
431+
432+
$this->_em->flush();
433+
$this->_em->clear();
434+
435+
$query = $this->_em->createQuery('select a, a.topic, a.text from ' . CmsArticle::class . ' a');
436+
$result = $query->toIterable();
437+
438+
$it = iterator_to_array($result);
439+
$this->assertCount(3, $it);
440+
$this->assertEquals('Doctrine 2', $it[0]['topic']);
441+
$this->assertEquals('Doctrine 2', $it[0][0]->topic);
442+
$this->assertEquals('lala 2', $it[2]['topic']);
443+
$this->assertEquals('lala 2', $it[2][0]->topic);
444+
}
445+
446+
public function testToIterableWithMixedResultArbitraryJoinsScalars(): void
447+
{
448+
$author = new CmsUser();
449+
$author->name = 'Ben';
450+
$author->username = 'beberlei';
451+
452+
$article1 = new CmsArticle();
453+
$article1->topic = 'Doctrine 2';
454+
$article1->text = 'This is an introduction to Doctrine 2.';
455+
$article1->setAuthor($author);
456+
457+
$article2 = new CmsArticle();
458+
$article2->topic = 'Symfony 2';
459+
$article2->text = 'This is an introduction to Symfony 2.';
460+
$article2->setAuthor($author);
461+
462+
$article3 = new CmsArticle();
463+
$article3->topic = 'lala 2';
464+
$article3->text = 'This is an introduction to Symfony 2.';
465+
$article3->setAuthor($author);
466+
467+
$this->_em->persist($article1);
468+
$this->_em->persist($article2);
469+
$this->_em->persist($article3);
470+
$this->_em->persist($author);
471+
472+
$this->_em->flush();
473+
$this->_em->clear();
474+
475+
$query = $this->_em->createQuery('select a, u, a.topic, a.text from ' . CmsArticle::class . ' a, ' . CmsUser::class . ' u WHERE a.user = u ');
476+
$result = $query->toIterable();
477+
478+
$it = iterator_to_array($result);
479+
480+
$this->assertCount(3, $it);
481+
$this->assertEquals('Doctrine 2', $it[0]['topic']);
482+
$this->assertEquals('Doctrine 2', $it[0][0]->topic);
483+
$this->assertEquals('beberlei', $it[0][1]->username);
484+
$this->assertEquals('lala 2', $it[2]['topic']);
485+
$this->assertEquals('lala 2', $it[2][0]->topic);
486+
$this->assertEquals('beberlei', $it[2][1]->username);
487+
}
488+
489+
public function testToIterableWithMixedResultScalarsOnly(): void
490+
{
491+
$author = new CmsUser();
492+
$author->name = 'Ben';
493+
$author->username = 'beberlei';
494+
495+
$article1 = new CmsArticle();
496+
$article1->topic = 'Doctrine 2';
497+
$article1->text = 'This is an introduction to Doctrine 2.';
498+
$article1->setAuthor($author);
499+
500+
$article2 = new CmsArticle();
501+
$article2->topic = 'Symfony 2';
502+
$article2->text = 'This is an introduction to Symfony 2.';
503+
$article2->setAuthor($author);
504+
505+
$article3 = new CmsArticle();
506+
$article3->topic = 'lala 2';
507+
$article3->text = 'This is an introduction to Symfony 2.';
508+
$article3->setAuthor($author);
509+
510+
$this->_em->persist($article1);
511+
$this->_em->persist($article2);
512+
$this->_em->persist($article3);
513+
$this->_em->persist($author);
514+
515+
$this->_em->flush();
516+
$this->_em->clear();
517+
518+
$query = $this->_em->createQuery('select a.topic, a.text from ' . CmsArticle::class . ' a ');
519+
$result = $query->toIterable();
520+
521+
$it = iterator_to_array($result);
522+
523+
$this->assertEquals([
524+
['topic' => 'Doctrine 2', 'text' => 'This is an introduction to Doctrine 2.'],
525+
['topic' => 'Symfony 2', 'text' => 'This is an introduction to Symfony 2.'],
526+
['topic' => 'lala 2', 'text' => 'This is an introduction to Symfony 2.'],
527+
], $it);
413528
}
414529

415530
public function testIterateResultClearEveryCycle(): void

tests/Tests/ORM/Query/ExprTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,9 @@ public function testExpressionGetter(): void
415415
self::assertEquals(['foo DESC', 'bar ASC'], $group->getParts());
416416

417417
// Join
418-
$join = new Join(Join::INNER_JOIN, 'f.bar', 'b', Join::ON, 'b.bar_id = 1', 'b.bar_id');
418+
$join = new Join(Join::INNER_JOIN, 'f.bar', 'b', Join::WITH, 'b.bar_id = 1', 'b.bar_id');
419419
self::assertEquals(Join::INNER_JOIN, $join->getJoinType());
420-
self::assertEquals(Join::ON, $join->getConditionType());
420+
self::assertEquals(Join::WITH, $join->getConditionType());
421421
self::assertEquals('b.bar_id = 1', $join->getCondition());
422422
self::assertEquals('b.bar_id', $join->getIndexBy());
423423
self::assertEquals('f.bar', $join->getJoin());

tests/Tests/ORM/QueryBuilderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,11 @@ public function testComplexInnerJoinWithComparisonCondition(): void
160160
$qb
161161
->select('u', 'a')
162162
->from(CmsUser::class, 'u')
163-
->innerJoin('u.articles', 'a', Join::ON, $qb->expr()->eq('u.id', 'a.author_id'));
163+
->innerJoin(CmsArticle::class, 'a', Join::ON, $qb->expr()->eq('u.id', 'a.author_id'));
164164

165165
$this->assertValidQueryBuilder(
166166
$qb,
167-
'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a ON u.id = a.author_id',
167+
'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN Doctrine\Tests\Models\CMS\CmsArticle a ON u.id = a.author_id',
168168
);
169169
}
170170

0 commit comments

Comments
 (0)