These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Doctrine\Tests\ORM\Tools\Pagination; |
||
4 | |||
5 | use Doctrine\DBAL\Platforms\MySqlPlatform; |
||
6 | use Doctrine\DBAL\Platforms\OraclePlatform; |
||
7 | use Doctrine\DBAL\Platforms\PostgreSqlPlatform; |
||
8 | use Doctrine\ORM\Query; |
||
9 | use Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker; |
||
10 | |||
11 | final class LimitSubqueryOutputWalkerTest extends PaginationTestCase |
||
12 | { |
||
13 | public function testLimitSubquery() : void |
||
14 | { |
||
15 | $query = $this->entityManager->createQuery( |
||
16 | 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); |
||
17 | $query->expireQueryCache(true); |
||
18 | $limitQuery = clone $query; |
||
19 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
20 | |||
21 | self::assertSame( |
||
22 | "SELECT DISTINCT id_0 FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, m0_.author_id AS author_id_5, m0_.category_id AS category_id_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSQL() |
||
23 | ); |
||
24 | } |
||
25 | |||
26 | View Code Duplication | public function testLimitSubqueryWithSortPg() : void |
|
27 | { |
||
28 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
29 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); |
||
30 | |||
31 | $query = $this->entityManager->createQuery( |
||
32 | 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title'); |
||
33 | $limitQuery = clone $query; |
||
34 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
35 | |||
36 | self::assertSame( |
||
37 | "SELECT DISTINCT id_0, MIN(sclr_5) AS dctrn_minrownum FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS sclr_5, m0_.author_id AS author_id_6, m0_.category_id AS category_id_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() |
||
38 | ); |
||
39 | |||
40 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
41 | } |
||
42 | |||
43 | View Code Duplication | public function testLimitSubqueryWithScalarSortPg() : void |
|
44 | { |
||
45 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
46 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); |
||
47 | |||
48 | $query = $this->entityManager->createQuery( |
||
49 | 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity' |
||
50 | ); |
||
51 | $limitQuery = clone $query; |
||
52 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
53 | |||
54 | self::assertSame( |
||
55 | "SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC", |
||
56 | $limitQuery->getSQL() |
||
57 | ); |
||
58 | |||
59 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
60 | } |
||
61 | |||
62 | View Code Duplication | public function testLimitSubqueryWithMixedSortPg() : void |
|
63 | { |
||
64 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
65 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); |
||
66 | |||
67 | $query = $this->entityManager->createQuery( |
||
68 | 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC' |
||
69 | ); |
||
70 | $limitQuery = clone $query; |
||
71 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
72 | |||
73 | self::assertSame( |
||
74 | "SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC", |
||
75 | $limitQuery->getSQL() |
||
76 | ); |
||
77 | |||
78 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
79 | } |
||
80 | |||
81 | View Code Duplication | public function testLimitSubqueryWithHiddenScalarSortPg() : void |
|
82 | { |
||
83 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
84 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); |
||
85 | |||
86 | $query = $this->entityManager->createQuery( |
||
87 | 'SELECT u, g, COUNT(g.id) AS hidden g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC' |
||
88 | ); |
||
89 | $limitQuery = clone $query; |
||
90 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
91 | |||
92 | self::assertSame( |
||
93 | "SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC", |
||
94 | $limitQuery->getSQL() |
||
95 | ); |
||
96 | |||
97 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
98 | } |
||
99 | |||
100 | public function testLimitSubqueryPg() : void |
||
101 | { |
||
102 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
103 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); |
||
104 | |||
105 | $this->testLimitSubquery(); |
||
106 | |||
107 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
108 | } |
||
109 | |||
110 | View Code Duplication | public function testLimitSubqueryWithSortOracle() : void |
|
111 | { |
||
112 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
113 | $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); |
||
114 | |||
115 | $query = $this->entityManager->createQuery( |
||
116 | 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title'); |
||
117 | $query->expireQueryCache(true); |
||
118 | $limitQuery = clone $query; |
||
119 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
120 | |||
121 | self::assertSame( |
||
122 | "SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS SCLR_5, m0_.author_id AS AUTHOR_ID_6, m0_.category_id AS CATEGORY_ID_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() |
||
123 | ); |
||
124 | |||
125 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
126 | } |
||
127 | |||
128 | View Code Duplication | public function testLimitSubqueryWithScalarSortOracle() : void |
|
129 | { |
||
130 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
131 | $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); |
||
132 | |||
133 | $query = $this->entityManager->createQuery( |
||
134 | 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity' |
||
135 | ); |
||
136 | $query->expireQueryCache(true); |
||
137 | $limitQuery = clone $query; |
||
138 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
139 | |||
140 | self::assertSame( |
||
141 | "SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC", |
||
142 | $limitQuery->getSQL() |
||
143 | ); |
||
144 | |||
145 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
146 | } |
||
147 | |||
148 | View Code Duplication | public function testLimitSubqueryWithMixedSortOracle() : void |
|
149 | { |
||
150 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
151 | $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); |
||
152 | |||
153 | $query = $this->entityManager->createQuery( |
||
154 | 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC' |
||
155 | ); |
||
156 | $query->expireQueryCache(true); |
||
157 | $limitQuery = clone $query; |
||
158 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
159 | |||
160 | self::assertSame( |
||
161 | "SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC", |
||
162 | $limitQuery->getSQL() |
||
163 | ); |
||
164 | |||
165 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
166 | } |
||
167 | |||
168 | View Code Duplication | public function testLimitSubqueryOracle() : void |
|
169 | { |
||
170 | $odp = $this->entityManager->getConnection()->getDatabasePlatform(); |
||
171 | $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); |
||
172 | |||
173 | $query = $this->entityManager->createQuery( |
||
174 | 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); |
||
175 | $query->expireQueryCache(true); |
||
176 | $limitQuery = clone $query; |
||
177 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
178 | |||
179 | self::assertSame( |
||
180 | "SELECT DISTINCT ID_0 FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, m0_.author_id AS AUTHOR_ID_5, m0_.category_id AS CATEGORY_ID_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSQL() |
||
181 | ); |
||
182 | |||
183 | $this->entityManager->getConnection()->setDatabasePlatform($odp); |
||
184 | } |
||
185 | |||
186 | View Code Duplication | public function testCountQueryMixedResultsWithName() : void |
|
187 | { |
||
188 | $query = $this->entityManager->createQuery( |
||
189 | 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); |
||
190 | $limitQuery = clone $query; |
||
191 | $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
192 | |||
193 | self::assertSame( |
||
194 | "SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, sum(a0_.name) AS sclr_2 FROM Author a0_) dctrn_result", $limitQuery->getSQL() |
||
195 | ); |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * @group DDC-3336 |
||
200 | */ |
||
201 | View Code Duplication | public function testCountQueryWithArithmeticOrderByCondition() : void |
|
202 | { |
||
203 | $query = $this->entityManager->createQuery( |
||
204 | 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY (1 - 1000) * 1 DESC' |
||
205 | ); |
||
206 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
207 | |||
208 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
209 | |||
210 | $this->assertSame( |
||
211 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, (1 - 1000) * 1 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1 FROM Author a0_) dctrn_result_inner ORDER BY (1 - 1000) * 1 DESC) dctrn_result', |
||
212 | $query->getSQL() |
||
213 | ); |
||
214 | } |
||
215 | |||
216 | View Code Duplication | public function testCountQueryWithComplexScalarOrderByItem() : void |
|
217 | { |
||
218 | $query = $this->entityManager->createQuery( |
||
219 | 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.image_height * a.image_width DESC' |
||
220 | ); |
||
221 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
0 ignored issues
–
show
|
|||
222 | |||
223 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
224 | |||
225 | $this->assertSame( |
||
226 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, image_height_2 * image_width_3 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.image_height AS image_height_2, a0_.image_width AS image_width_3, a0_.image_alt_desc AS image_alt_desc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result_inner ORDER BY image_height_2 * image_width_3 DESC) dctrn_result', |
||
227 | $query->getSQL() |
||
228 | ); |
||
229 | } |
||
230 | |||
231 | View Code Duplication | public function testCountQueryWithComplexScalarOrderByItemJoined() : void |
|
232 | { |
||
233 | $query = $this->entityManager->createQuery( |
||
234 | 'SELECT u FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.image_height * a.image_width DESC' |
||
235 | ); |
||
236 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection : Doctrine\Tests\Mocks\ConnectionMock . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
237 | |||
238 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
239 | |||
240 | $this->assertSame( |
||
241 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, image_height_1 * image_width_2 FROM (SELECT u0_.id AS id_0, a1_.image_height AS image_height_1, a1_.image_width AS image_width_2, a1_.user_id AS user_id_3 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY image_height_1 * image_width_2 DESC) dctrn_result', |
||
242 | $query->getSQL() |
||
243 | ); |
||
244 | } |
||
245 | |||
246 | View Code Duplication | public function testCountQueryWithComplexScalarOrderByItemJoinedWithPartial() : void |
|
247 | { |
||
248 | $query = $this->entityManager->createQuery( |
||
249 | 'SELECT u, partial a.{id, image_alt_desc} FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.image_height * a.image_width DESC' |
||
250 | ); |
||
251 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection : Doctrine\Tests\Mocks\ConnectionMock . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
252 | |||
253 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
254 | |||
255 | $this->assertSame( |
||
256 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, image_height_3 * image_width_4 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.image_alt_desc AS image_alt_desc_2, a1_.image_height AS image_height_3, a1_.image_width AS image_width_4, a1_.user_id AS user_id_5 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY image_height_3 * image_width_4 DESC) dctrn_result', |
||
257 | $query->getSQL() |
||
258 | ); |
||
259 | } |
||
260 | |||
261 | View Code Duplication | public function testCountQueryWithComplexScalarOrderByItemOracle() : void |
|
262 | { |
||
263 | $query = $this->entityManager->createQuery( |
||
264 | 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.image_height * a.image_width DESC' |
||
265 | ); |
||
266 | $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection : Doctrine\Tests\Mocks\ConnectionMock . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
267 | |||
268 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
269 | |||
270 | $this->assertSame( |
||
271 | 'SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.image AS IMAGE_1, a0_.image_height AS IMAGE_HEIGHT_2, a0_.image_width AS IMAGE_WIDTH_3, a0_.image_alt_desc AS IMAGE_ALT_DESC_4, ROW_NUMBER() OVER(ORDER BY a0_.image_height * a0_.image_width DESC) AS SCLR_5, a0_.user_id AS USER_ID_6 FROM Avatar a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC', |
||
272 | $query->getSQL() |
||
273 | ); |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * @group DDC-3434 |
||
278 | */ |
||
279 | View Code Duplication | public function testLimitSubqueryWithHiddenSelectionInOrderBy() : void |
|
280 | { |
||
281 | $query = $this->entityManager->createQuery( |
||
282 | 'SELECT a, a.name AS HIDDEN ord FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY ord DESC' |
||
283 | ); |
||
284 | |||
285 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
286 | |||
287 | self::assertSame( |
||
288 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, a0_.name AS name_2 FROM Author a0_) dctrn_result_inner ORDER BY name_2 DESC) dctrn_result', |
||
289 | $query->getSQL() |
||
290 | ); |
||
291 | } |
||
292 | |||
293 | View Code Duplication | public function testLimitSubqueryWithColumnWithSortDirectionInName() : void |
|
294 | { |
||
295 | $query = $this->entityManager->createQuery( |
||
296 | 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.image_alt_desc DESC' |
||
297 | ); |
||
298 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection : Doctrine\Tests\Mocks\ConnectionMock . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
299 | |||
300 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
301 | |||
302 | $this->assertSame( |
||
303 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, image_alt_desc_4 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.image_height AS image_height_2, a0_.image_width AS image_width_3, a0_.image_alt_desc AS image_alt_desc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result_inner ORDER BY image_alt_desc_4 DESC) dctrn_result', |
||
304 | $query->getSQL() |
||
305 | ); |
||
306 | } |
||
307 | |||
308 | View Code Duplication | public function testLimitSubqueryWithOrderByInnerJoined() : void |
|
309 | { |
||
310 | $query = $this->entityManager->createQuery( |
||
311 | 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b JOIN b.author a ORDER BY a.name ASC' |
||
312 | ); |
||
313 | |||
314 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
315 | |||
316 | self::assertSame( |
||
317 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_1 FROM (SELECT b0_.id AS id_0, a1_.name AS name_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_1 ASC) dctrn_result', |
||
318 | $query->getSQL() |
||
319 | ); |
||
320 | } |
||
321 | |||
322 | View Code Duplication | public function testLimitSubqueryWithOrderByAndSubSelectInWhereClauseMySql() : void |
|
323 | { |
||
324 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection : Doctrine\Tests\Mocks\ConnectionMock . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
325 | $query = $this->entityManager->createQuery( |
||
326 | 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b |
||
327 | WHERE ((SELECT COUNT(simple.id) FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost simple) = 1) |
||
328 | ORDER BY b.id DESC' |
||
329 | ); |
||
330 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
331 | |||
332 | self::assertSame( |
||
333 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.author_id AS author_id_1, b0_.category_id AS category_id_2 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_3 FROM BlogPost b1_) = 1)) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', |
||
334 | $query->getSQL() |
||
335 | ); |
||
336 | } |
||
337 | |||
338 | View Code Duplication | public function testLimitSubqueryWithOrderByAndSubSelectInWhereClausePgSql() : void |
|
339 | { |
||
340 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform()); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection : Doctrine\Tests\Mocks\ConnectionMock . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
341 | $query = $this->entityManager->createQuery( |
||
342 | 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b |
||
343 | WHERE ((SELECT COUNT(simple.id) FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost simple) = 1) |
||
344 | ORDER BY b.id DESC' |
||
345 | ); |
||
346 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
347 | |||
348 | self::assertSame( |
||
349 | 'SELECT DISTINCT id_0, MIN(sclr_1) AS dctrn_minrownum FROM (SELECT b0_.id AS id_0, ROW_NUMBER() OVER(ORDER BY b0_.id DESC) AS sclr_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_4 FROM BlogPost b1_) = 1)) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', |
||
350 | $query->getSQL() |
||
351 | ); |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * This tests ordering by property that has the 'declared' field. |
||
356 | */ |
||
357 | View Code Duplication | public function testLimitSubqueryOrderByFieldFromMappedSuperclass() : void |
|
358 | { |
||
359 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
360 | |||
361 | // now use the third one in query |
||
362 | $query = $this->entityManager->createQuery( |
||
363 | 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\Banner b ORDER BY b.id DESC' |
||
364 | ); |
||
365 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
366 | |||
367 | self::assertSame( |
||
368 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', |
||
369 | $query->getSQL() |
||
370 | ); |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * Tests order by on a subselect expression (mysql). |
||
375 | */ |
||
376 | View Code Duplication | public function testLimitSubqueryOrderBySubSelectOrderByExpression() : void |
|
377 | { |
||
378 | $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); |
||
379 | |||
380 | $query = $this->entityManager->createQuery( |
||
381 | 'SELECT a, |
||
382 | ( |
||
383 | SELECT MIN(bp.title) |
||
384 | FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost bp |
||
385 | WHERE bp.author = a |
||
386 | ) AS HIDDEN first_blog_post |
||
387 | FROM Doctrine\Tests\ORM\Tools\Pagination\Author a |
||
388 | ORDER BY first_blog_post DESC' |
||
389 | ); |
||
390 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
391 | |||
392 | self::assertSame( |
||
393 | 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, sclr_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result_inner ORDER BY sclr_2 DESC) dctrn_result', |
||
394 | $query->getSQL() |
||
395 | ); |
||
396 | } |
||
397 | |||
398 | /** |
||
399 | * Tests order by on a subselect expression invoking RowNumberOverFunction (postgres). |
||
400 | */ |
||
401 | View Code Duplication | public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg() : void |
|
402 | { |
||
403 | $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform()); |
||
404 | |||
405 | $query = $this->entityManager->createQuery( |
||
406 | 'SELECT a, |
||
407 | ( |
||
408 | SELECT MIN(bp.title) |
||
409 | FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost bp |
||
410 | WHERE bp.author = a |
||
411 | ) AS HIDDEN first_blog_post |
||
412 | FROM Doctrine\Tests\ORM\Tools\Pagination\Author a |
||
413 | ORDER BY first_blog_post DESC' |
||
414 | ); |
||
415 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
416 | |||
417 | self::assertSame( |
||
418 | 'SELECT DISTINCT id_0, MIN(sclr_4) AS dctrn_minrownum FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS sclr_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS sclr_4 FROM Author a0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', |
||
419 | $query->getSQL() |
||
420 | ); |
||
421 | } |
||
422 | |||
423 | /** |
||
424 | * Tests order by on a subselect expression invoking RowNumberOverFunction (oracle). |
||
425 | */ |
||
426 | View Code Duplication | public function testLimitSubqueryOrderBySubSelectOrderByExpressionOracle() : void |
|
427 | { |
||
428 | $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); |
||
429 | |||
430 | $query = $this->entityManager->createQuery( |
||
431 | 'SELECT a, |
||
432 | ( |
||
433 | SELECT MIN(bp.title) |
||
434 | FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost bp |
||
435 | WHERE bp.author = a |
||
436 | ) AS HIDDEN first_blog_post |
||
437 | FROM Doctrine\Tests\ORM\Tools\Pagination\Author a |
||
438 | ORDER BY first_blog_post DESC' |
||
439 | ); |
||
440 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
||
441 | |||
442 | self::assertSame( |
||
443 | 'SELECT DISTINCT ID_0, MIN(SCLR_4) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.name AS NAME_1, (SELECT MIN(m1_.title) AS SCLR_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS SCLR_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS SCLR_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS SCLR_4 FROM Author a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC', |
||
444 | $query->getSQL() |
||
445 | ); |
||
446 | } |
||
447 | } |
||
448 | |||
449 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: