Skip to content

Commit 657e013

Browse files
Mediagonegreg0ire
authored andcommitted
Fix Hidden fields triggering error when using getSingleScalarResult() (#8340)
* Fix Hidden fields triggering error when using getSingleScalarResult() Fixes #4257 HIDDEN fields was causing the "unicity" check to fail (NonUniqueResultException), because we was counting raw data instead of gathered row data. * Fix Coding Standards (7.4) * Fix Coding Standards (7.4) #2 * Fix Coding Standards (7.4) - Fix whitespaces * Fix Coding Standards (7.4) - Fix whitespaces in tests * Fix Coding Standards (7.4) - Fix more things * Refactor tests into separate methods * Fix Coding Standards (7.4) - Equals sign not aligned with surrounding assignments
1 parent 80d068d commit 657e013

File tree

2 files changed

+122
-46
lines changed

2 files changed

+122
-46
lines changed

lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ protected function hydrateAllData()
3232
throw new NonUniqueResultException('The query returned multiple rows. Change the query or use a different result function like getScalarResult().');
3333
}
3434

35-
if (count($data[key($data)]) > 1) {
35+
$result = $this->gatherScalarRowData($data[key($data)]);
36+
37+
if (count($result) > 1) {
3638
throw new NonUniqueResultException('The query returned a row containing multiple columns. Change the query or use a different result function like getScalarResult().');
3739
}
3840

39-
$result = $this->gatherScalarRowData($data[key($data)]);
40-
4141
return array_shift($result);
4242
}
4343
}

tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php

+119-43
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,127 @@
1414

1515
class SingleScalarHydratorTest extends HydrationTestCase
1616
{
17-
/** Result set provider for the HYDRATE_SINGLE_SCALAR tests */
18-
public static function singleScalarResultSetProvider(): array
17+
public static function validResultSetProvider()
1918
{
20-
return [
21-
// valid
22-
'valid' => [
23-
'name' => 'result1',
24-
'resultSet' => [
25-
['u__name' => 'romanb'],
19+
// SELECT u.name FROM CmsUser u WHERE u.id = 1
20+
yield [
21+
[
22+
['u__name' => 'romanb'],
23+
],
24+
'romanb',
25+
];
26+
27+
// SELECT u.id FROM CmsUser u WHERE u.id = 1
28+
yield [
29+
[
30+
['u__id' => '1'],
31+
],
32+
1,
33+
];
34+
35+
// SELECT
36+
// u.id,
37+
// COUNT(u.postsCount + u.likesCount) AS HIDDEN score
38+
// FROM CmsUser u
39+
// WHERE u.id = 1
40+
yield [
41+
[
42+
[
43+
'u__id' => '1',
44+
'score' => 10, // Ignored since not part of ResultSetMapping (cf. HIDDEN keyword)
2645
],
2746
],
28-
// valid
47+
1,
48+
];
49+
}
50+
51+
/**
52+
* @dataProvider validResultSetProvider
53+
*/
54+
public function testHydrateSingleScalarFromFieldMappingWithValidResultSet(array $resultSet, $expectedResult): void
55+
{
56+
$rsm = new ResultSetMapping();
57+
$rsm->addEntityResult(CmsUser::class, 'u');
58+
$rsm->addFieldResult('u', 'u__id', 'id');
59+
$rsm->addFieldResult('u', 'u__name', 'name');
60+
61+
$stmt = ArrayResultFactory::createFromArray($resultSet);
62+
$hydrator = new SingleScalarHydrator($this->entityManager);
63+
64+
$result = $hydrator->hydrateAll($stmt, $rsm);
65+
$this->assertEquals($expectedResult, $result);
66+
}
67+
68+
/**
69+
* @dataProvider validResultSetProvider
70+
*/
71+
public function testHydrateSingleScalarFromScalarMappingWithValidResultSet(array $resultSet, $expectedResult): void
72+
{
73+
$rsm = new ResultSetMapping();
74+
$rsm->addScalarResult('u__id', 'id', 'string');
75+
$rsm->addScalarResult('u__name', 'name', 'string');
76+
77+
$stmt = ArrayResultFactory::createFromArray($resultSet);
78+
$hydrator = new SingleScalarHydrator($this->entityManager);
79+
80+
$result = $hydrator->hydrateAll($stmt, $rsm);
81+
$this->assertEquals($expectedResult, $result);
82+
}
83+
84+
public static function invalidResultSetProvider()
85+
{
86+
// Single row (OK), multiple columns (NOT OK)
87+
yield [
2988
[
30-
'name' => 'result2',
31-
'resultSet' => [
32-
['u__id' => '1'],
89+
[
90+
'u__id' => '1',
91+
'u__name' => 'romanb',
3392
],
3493
],
35-
// invalid
94+
];
95+
96+
// Multiple rows (NOT OK), single column (OK)
97+
yield [
3698
[
37-
'name' => 'result3',
38-
'resultSet' => [
39-
[
40-
'u__id' => '1',
41-
'u__name' => 'romanb',
42-
],
99+
['u__id' => '1'],
100+
['u__id' => '2'],
101+
],
102+
];
103+
104+
// Multiple rows (NOT OK), single column with HIDDEN result (OK)
105+
yield [
106+
[
107+
[
108+
'u__id' => '1',
109+
'score' => 10, // Ignored since not part of ResultSetMapping
110+
],
111+
[
112+
'u__id' => '2',
113+
'score' => 10, // Ignored since not part of ResultSetMapping
43114
],
44115
],
45-
// invalid
116+
1,
117+
];
118+
119+
// Multiple row (NOT OK), multiple columns (NOT OK)
120+
yield [
46121
[
47-
'name' => 'result4',
48-
'resultSet' => [
49-
['u__id' => '1'],
50-
['u__id' => '2'],
122+
[
123+
'u__id' => '1',
124+
'u__name' => 'romanb',
125+
],
126+
[
127+
'u__id' => '2',
128+
'u__name' => 'romanb',
51129
],
52130
],
53131
];
54132
}
55133

56134
/**
57-
* select u.name from CmsUser u where u.id = 1
58-
*
59-
* @dataProvider singleScalarResultSetProvider
135+
* @dataProvider invalidResultSetProvider
60136
*/
61-
public function testHydrateSingleScalar($name, $resultSet): void
137+
public function testHydrateSingleScalarFromFieldMappingWithInvalidResultSet(array $resultSet): void
62138
{
63139
$rsm = new ResultSetMapping();
64140
$rsm->addEntityResult(CmsUser::class, 'u');
@@ -68,23 +144,23 @@ public function testHydrateSingleScalar($name, $resultSet): void
68144
$stmt = ArrayResultFactory::createFromArray($resultSet);
69145
$hydrator = new SingleScalarHydrator($this->entityManager);
70146

71-
if ($name === 'result1') {
72-
$result = $hydrator->hydrateAll($stmt, $rsm);
73-
self::assertEquals('romanb', $result);
74-
75-
return;
76-
}
147+
$this->expectException(NonUniqueResultException::class);
148+
$hydrator->hydrateAll($stmt, $rsm);
149+
}
77150

78-
if ($name === 'result2') {
79-
$result = $hydrator->hydrateAll($stmt, $rsm);
80-
self::assertEquals(1, $result);
151+
/**
152+
* @dataProvider invalidResultSetProvider
153+
*/
154+
public function testHydrateSingleScalarFromScalarMappingWithInvalidResultSet(array $resultSet): void
155+
{
156+
$rsm = new ResultSetMapping();
157+
$rsm->addScalarResult('u__id', 'id', 'string');
158+
$rsm->addScalarResult('u__name', 'name', 'string');
81159

82-
return;
83-
}
160+
$stmt = ArrayResultFactory::createFromArray($resultSet);
161+
$hydrator = new SingleScalarHydrator($this->entityManager);
84162

85-
if (in_array($name, ['result3', 'result4'], true)) {
86-
$this->expectException(NonUniqueResultException::class);
87-
$hydrator->hydrateAll($stmt, $rsm);
88-
}
163+
$this->expectException(NonUniqueResultException::class);
164+
$hydrator->hydrateAll($stmt, $rsm);
89165
}
90166
}

0 commit comments

Comments
 (0)