Passed
Pull Request — master (#6476)
by Artem
09:07
created

testSelectForeignKeyPKWithoutFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Query;
6
7
use Doctrine\DBAL\LockMode;
8
use Doctrine\DBAL\Platforms\MySqlPlatform;
9
use Doctrine\DBAL\Platforms\OraclePlatform;
10
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
11
use Doctrine\DBAL\Platforms\SqlitePlatform;
12
use Doctrine\DBAL\Platforms\SQLServerPlatform;
13
use Doctrine\DBAL\Types\Type as DBALType;
14
use Doctrine\ORM\Annotation as ORM;
15
use Doctrine\ORM\Query as ORMQuery;
16
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
17
use Doctrine\ORM\Query\Lexer;
18
use Doctrine\ORM\Query\Parser;
19
use Doctrine\ORM\Query\QueryException;
20
use Doctrine\ORM\Query\SqlWalker;
21
use Doctrine\Tests\DbalTypes\NegativeToPositiveType;
22
use Doctrine\Tests\Models\CMS\CmsGroup;
23
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
24
use Doctrine\Tests\Models\Company\CompanyEmployee;
25
use Doctrine\Tests\Models\Company\CompanyPerson;
26
use Doctrine\Tests\OrmTestCase;
27
use Exception;
28
use function get_class;
29
30
class SelectSqlGenerationTest extends OrmTestCase
31
{
32
    private $em;
33
34
    protected function setUp() : void
35
    {
36
        $this->em = $this->getTestEntityManager();
37
    }
38
39
    /**
40
     * Assert a valid SQL generation.
41
     *
42
     * @param string $dqlToBeTested
43
     * @param string $sqlToBeConfirmed
44
     * @param array  $queryHints
45
     * @param array  $queryParams
46
     */
47
    public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = [], array $queryParams = [])
48
    {
49
        try {
50
            $query = $this->em->createQuery($dqlToBeTested);
51
52
            foreach ($queryParams as $name => $value) {
53
                $query->setParameter($name, $value);
54
            }
55
56
            $query
57
                ->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
58
                ->useQueryCache(false);
59
60
            foreach ($queryHints as $name => $value) {
61
                $query->setHint($name, $value);
62
            }
63
64
            $sqlGenerated = $query->getSQL();
65
66
            $query->free();
67
        } catch (Exception $e) {
68
            $this->fail($e->getMessage() . "\n" . $e->getTraceAsString());
69
        }
70
71
        self::assertEquals($sqlToBeConfirmed, $sqlGenerated);
72
    }
73
74
    /**
75
     * Asser an invalid SQL generation.
76
     *
77
     * @param string $dqlToBeTested
78
     * @param string $expectedException
79
     * @param array  $queryHints
80
     * @param array  $queryParams
81
     */
82
    public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = [], array $queryParams = [])
83
    {
84
        $this->expectException($expectedException);
85
86
        $query = $this->em->createQuery($dqlToBeTested);
87
88
        foreach ($queryParams as $name => $value) {
89
            $query->setParameter($name, $value);
90
        }
91
92
        $query
93
            ->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
94
            ->useQueryCache(false);
95
96
        foreach ($queryHints as $name => $value) {
97
            $query->setHint($name, $value);
98
        }
99
100
        $sql = $query->getSql();
101
        $query->free();
102
103
        // If we reached here, test failed
104
        $this->fail($sql);
105
    }
106
107
    /**
108
     * @group DDC-3697
109
     */
110
    public function testJoinWithRangeVariablePutsConditionIntoSqlWhereClause() : void
111
    {
112
        $this->assertSqlGeneration(
113
            'SELECT c.id FROM Doctrine\Tests\Models\Company\CompanyPerson c JOIN Doctrine\Tests\Models\Company\CompanyPerson r WHERE c.spouse = r AND r.id = 42',
114
            'SELECT t0."id" AS c0 FROM "company_persons" t0 INNER JOIN "company_persons" t1 WHERE t0."spouse_id" = t1."id" AND t1."id" = 42',
115
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
116
        );
117
    }
118
119
    /**
120
     * @group DDC-3697
121
     */
122
    public function testJoinWithRangeVariableAndInheritancePutsConditionIntoSqlWhereClause() : void
123
    {
124
        /*
125
         * Basically like the previous test, but this time load data for the inherited objects as well.
126
         * The important thing is that the ON clauses in LEFT JOINs only contain the conditions necessary to join the appropriate inheritance table
127
         * whereas the filtering condition must remain in the SQL WHERE clause.
128
         */
129
        $this->assertSqlGeneration(
130
            'SELECT c.id FROM Doctrine\Tests\Models\Company\CompanyPerson c JOIN Doctrine\Tests\Models\Company\CompanyPerson r WHERE c.spouse = r AND r.id = 42',
131
            'SELECT t0."id" AS c0 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id" INNER JOIN "company_persons" t3 LEFT JOIN "company_managers" t4 ON t3."id" = t4."id" LEFT JOIN "company_employees" t5 ON t3."id" = t5."id" WHERE t0."spouse_id" = t3."id" AND t3."id" = 42',
132
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
133
        );
134
    }
135
136
    public function testSupportsSelectForAllFields() : void
137
    {
138
        $this->assertSqlGeneration(
139
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
140
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0'
141
        );
142
    }
143
144
    public function testSupportsSelectForOneField() : void
145
    {
146
        $this->assertSqlGeneration(
147
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u',
148
            'SELECT t0."id" AS c0 FROM "cms_users" t0'
149
        );
150
    }
151
152
    public function testSupportsSelectForOneNestedField() : void
153
    {
154
        $this->assertSqlGeneration(
155
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
156
            'SELECT t0."id" AS c0 FROM "cms_articles" t1 INNER JOIN "cms_users" t0 ON t1."user_id" = t0."id"'
157
        );
158
    }
159
160
    public function testSupportsSelectForAllNestedField() : void
161
    {
162
        $this->assertSqlGeneration(
163
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
164
            'SELECT t0."id" AS c0, t0."topic" AS c1, t0."text" AS c2, t0."version" AS c3 FROM "cms_articles" t0 INNER JOIN "cms_users" t1 ON t0."user_id" = t1."id" ORDER BY t1."name" ASC'
165
        );
166
    }
167
168
    public function testNotExistsExpression() : void
169
    {
170
        $this->assertSqlGeneration(
171
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)',
172
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE NOT EXISTS (SELECT t1."phonenumber" FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = 1234)'
173
        );
174
    }
175
176
    public function testSupportsSelectForMultipleColumnsOfASingleComponent() : void
177
    {
178
        $this->assertSqlGeneration(
179
            'SELECT u.username, u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
180
            'SELECT t0."username" AS c0, t0."name" AS c1 FROM "cms_users" t0'
181
        );
182
    }
183
184
    public function testSupportsSelectUsingMultipleFromComponents() : void
185
    {
186
        $this->assertSqlGeneration(
187
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user',
188
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."phonenumber" AS c4 FROM "cms_users" t0, "cms_phonenumbers" t1 WHERE t0."id" = t1."user_id"'
189
        );
190
    }
191
192
    public function testSupportsJoinOnMultipleComponents() : void
193
    {
194
        $this->assertSqlGeneration(
195
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user',
196
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."phonenumber" AS c4 FROM "cms_users" t0 INNER JOIN "cms_phonenumbers" t1 ON (t0."id" = t1."user_id")'
197
        );
198
    }
199
200
    public function testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType() : void
201
    {
202
        $this->assertSqlGeneration(
203
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
204
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" INNER JOIN ("company_managers" t2 INNER JOIN "company_employees" t4 ON t2."id" = t4."id" INNER JOIN "company_persons" t3 ON t2."id" = t3."id") ON (t0."id" = t3."id")'
205
        );
206
207
        $this->assertSqlGeneration(
208
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
209
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" LEFT JOIN ("company_managers" t2 INNER JOIN "company_employees" t4 ON t2."id" = t4."id" INNER JOIN "company_persons" t3 ON t2."id" = t3."id") ON (t0."id" = t3."id")'
210
        );
211
212
        $this->assertSqlGeneration(
213
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson s LEFT JOIN Doctrine\Tests\Models\Company\CompanyEvent e WITH s.id = e.id',
214
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 INNER JOIN "company_employees" t1 ON t0."salesPerson_id" = t1."id" LEFT JOIN "company_persons" t2 ON t1."id" = t2."id" LEFT JOIN "company_events" t3 ON (t2."id" = t3."id") WHERE t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
215
        );
216
    }
217
218
    public function testSupportsSelectWithCollectionAssociationJoin() : void
219
    {
220
        $this->assertSqlGeneration(
221
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p',
222
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."phonenumber" AS c4 FROM "cms_users" t0 INNER JOIN "cms_phonenumbers" t1 ON t0."id" = t1."user_id"'
223
        );
224
    }
225
226
    public function testSupportsSelectWithSingleValuedAssociationJoin() : void
227
    {
228
        $this->assertSqlGeneration(
229
            'SELECT u, a FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a',
230
            'SELECT t0."id" AS c0, t0."username" AS c1, t1."id" AS c2 FROM "forum_users" t0 INNER JOIN "forum_avatars" t1 ON t0."avatar_id" = t1."id"'
231
        );
232
    }
233
234
    public function testSelectCorrelatedSubqueryComplexMathematicalExpression() : void
235
    {
236
        $this->assertSqlGeneration(
237
            'SELECT (SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = u.id) AS c FROM Doctrine\Tests\Models\CMS\CmsUser u',
238
            'SELECT (SELECT (count(t0."phonenumber") + 5) * 10 AS c1 FROM "cms_phonenumbers" t0 INNER JOIN "cms_users" t1 ON t0."user_id" = t1."id" WHERE t1."id" = t2."id") AS c0 FROM "cms_users" t2'
239
        );
240
    }
241
242
    public function testSelectComplexMathematicalExpression() : void
243
    {
244
        $this->assertSqlGeneration(
245
            'SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = ?1',
246
            'SELECT (count(t0."phonenumber") + 5) * 10 AS c0 FROM "cms_phonenumbers" t0 INNER JOIN "cms_users" t1 ON t0."user_id" = t1."id" WHERE t1."id" = ?'
247
        );
248
    }
249
250
    /* NOT (YET?) SUPPORTED.
251
       Can be supported if SimpleSelectExpression supports SingleValuedPathExpression instead of StateFieldPathExpression.
252
253
    public function testSingleAssociationPathExpressionInSubselect() : void
254
    {
255
        $this->assertSqlGeneration(
256
            'SELECT (SELECT p.user FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = u) user_id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
257
            'SELECT (SELECT t0."user_id" FROM "cms_phonenumbers" t0 WHERE t0."user_id" = t1."id") AS c0 FROM "cms_users" t1 WHERE t1."id" = ?'
258
        );
259
    }*/
260
261
    /**
262
     * @group DDC-1077
263
     */
264
    public function testConstantValueInSelect() : void
265
    {
266
        $this->assertSqlGeneration(
267
            'SELECT u.name, \'foo\' AS bar FROM Doctrine\Tests\Models\CMS\CmsUser u',
268
            'SELECT t0."name" AS c0, \'foo\' AS c1 FROM "cms_users" t0'
269
        );
270
    }
271
272
    public function testSupportsOrderByWithAscAsDefault() : void
273
    {
274
        $this->assertSqlGeneration(
275
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id',
276
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" ASC'
277
        );
278
    }
279
280
    public function testSupportsOrderByAsc() : void
281
    {
282
        $this->assertSqlGeneration(
283
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id asc',
284
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" ASC'
285
        );
286
    }
287
288
    public function testSupportsOrderByDesc() : void
289
    {
290
        $this->assertSqlGeneration(
291
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id desc',
292
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" DESC'
293
        );
294
    }
295
296
    public function testSupportsSelectDistinct() : void
297
    {
298
        $this->assertSqlGeneration(
299
            'SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
300
            'SELECT DISTINCT t0."name" AS c0 FROM "cms_users" t0'
301
        );
302
    }
303
304
    public function testSupportsAggregateFunctionInSelectedFields() : void
305
    {
306
        $this->assertSqlGeneration(
307
            'SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
308
            'SELECT COUNT(t0."id") AS c0 FROM "cms_users" t0 GROUP BY t0."id"'
309
        );
310
    }
311
312
    public function testSupportsAggregateFunctionWithSimpleArithmetic() : void
313
    {
314
        $this->assertSqlGeneration(
315
            'SELECT MAX(u.id + 4) * 2 FROM Doctrine\Tests\Models\CMS\CmsUser u',
316
            'SELECT MAX(t0."id" + 4) * 2 AS c0 FROM "cms_users" t0'
317
        );
318
    }
319
320
    /**
321
     * @group DDC-3276
322
     */
323
    public function testSupportsAggregateCountFunctionWithSimpleArithmeticMySql() : void
324
    {
325
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
326
327
        $this->assertSqlGeneration(
328
            'SELECT COUNT(CONCAT(u.id, u.name)) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
329
            'SELECT COUNT(CONCAT(t0.`id`, t0.`name`)) AS c0 FROM `cms_users` t0 GROUP BY t0.`id`'
330
        );
331
    }
332
333
    public function testSupportsWhereClauseWithPositionalParameter() : void
334
    {
335
        $this->assertSqlGeneration(
336
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.id = ?1',
337
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."id" = ?'
338
        );
339
    }
340
341
    public function testSupportsWhereClauseWithNamedParameter() : void
342
    {
343
        $this->assertSqlGeneration(
344
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name',
345
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."username" = ?'
346
        );
347
    }
348
349
    public function testSupportsWhereAndClauseWithNamedParameters() : void
350
    {
351
        $this->assertSqlGeneration(
352
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name and u.username = :name2',
353
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."username" = ? AND t0."username" = ?'
354
        );
355
    }
356
357
    public function testSupportsCombinedWhereClauseWithNamedParameter() : void
358
    {
359
        $this->assertSqlGeneration(
360
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where (u.username = :name OR u.username = :name2) AND u.id = :id',
361
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE (t0."username" = ? OR t0."username" = ?) AND t0."id" = ?'
362
        );
363
    }
364
365
    public function testSupportsAggregateFunctionInASelectDistinct() : void
366
    {
367
        $this->assertSqlGeneration(
368
            'SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u',
369
            'SELECT COUNT(DISTINCT t0."name") AS c0 FROM "cms_users" t0'
370
        );
371
    }
372
373
    /** Ticket #668 */
374
    public function testSupportsASqlKeywordInAStringLiteralParam() : void
375
    {
376
        $this->assertSqlGeneration(
377
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE \'%foo OR bar%\'',
378
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE t0."name" LIKE \'%foo OR bar%\''
379
        );
380
    }
381
382
    public function testSupportsArithmeticExpressionsInWherePart() : void
383
    {
384
        $this->assertSqlGeneration(
385
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000',
386
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE ((t0."id" + 5000) * t0."id" + 3) < 10000000'
387
        );
388
    }
389
390
    public function testSupportsMultipleEntitiesInFromClause() : void
391
    {
392
        $this->assertSqlGeneration(
393
            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u2 WHERE u.id = u2.id',
394
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."id" AS c4, t1."topic" AS c5, t1."text" AS c6, t1."version" AS c7 FROM "cms_users" t0, "cms_articles" t1 INNER JOIN "cms_users" t2 ON t1."user_id" = t2."id" WHERE t0."id" = t2."id"'
395
        );
396
    }
397
398
    public function testSupportsMultipleEntitiesInFromClauseUsingPathExpression() : void
399
    {
400
        $this->assertSqlGeneration(
401
            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.id = a.user',
402
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."id" AS c4, t1."topic" AS c5, t1."text" AS c6, t1."version" AS c7 FROM "cms_users" t0, "cms_articles" t1 WHERE t0."id" = t1."user_id"'
403
        );
404
    }
405
406
    public function testSupportsPlainJoinWithoutClause() : void
407
    {
408
        $this->assertSqlGeneration(
409
            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a',
410
            'SELECT t0."id" AS c0, t1."id" AS c1 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id"'
411
        );
412
413
        $this->assertSqlGeneration(
414
            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a',
415
            'SELECT t0."id" AS c0, t1."id" AS c1 FROM "cms_users" t0 INNER JOIN "cms_articles" t1 ON t0."id" = t1."user_id"'
416
        );
417
    }
418
419
    /**
420
     * @group DDC-135
421
     */
422
    public function testSupportsLeftJoinAndWithClauseRestriction() : void
423
    {
424
        $this->assertSqlGeneration(
425
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE \'%foo%\'',
426
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" LIKE \'%foo%\')'
427
        );
428
    }
429
430
    /**
431
     * @group DDC-135
432
     */
433
    public function testSupportsInnerJoinAndWithClauseRestriction() : void
434
    {
435
        $this->assertSqlGeneration(
436
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a WITH a.topic LIKE \'%foo%\'',
437
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 INNER JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" LIKE \'%foo%\')'
438
        );
439
    }
440
441
    /**
442
     * @group DDC-135
443
     * @group DDC-177
444
     */
445
    public function testJoinOnClauseNotYetSupportedThrowsException() : void
446
    {
447
        $this->expectException(QueryException::class);
448
449
        $query = $this->em->createQuery(
450
            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a ON a.topic LIKE \'%foo%\''
451
        );
452
453
        $query->getSql();
454
    }
455
456
    public function testSupportsMultipleJoins() : void
457
    {
458
        $this->assertSqlGeneration(
459
            'SELECT u.id, a.id, p.phonenumber, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c',
460
            'SELECT t0."id" AS c0, t1."id" AS c1, t2."phonenumber" AS c2, t3."id" AS c3 FROM "cms_users" t0 INNER JOIN "cms_articles" t1 ON t0."id" = t1."user_id" INNER JOIN "cms_phonenumbers" t2 ON t0."id" = t2."user_id" INNER JOIN "cms_comments" t3 ON t1."id" = t3."article_id"'
461
        );
462
    }
463
464
    public function testSupportsTrimFunction() : void
465
    {
466
        $this->assertSqlGeneration(
467
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING \' \' FROM u.name) = \'someone\'',
468
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE TRIM(TRAILING \' \' FROM t0."name") = \'someone\''
469
        );
470
    }
471
472
    /**
473
     * @group DDC-2668
474
     */
475
    public function testSupportsTrimLeadingZeroString() : void
476
    {
477
        $this->assertSqlGeneration(
478
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING \'0\' FROM u.name) != \'\'',
479
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE TRIM(TRAILING \'0\' FROM t0."name") <> \'\''
480
        );
481
    }
482
483
    /** Ticket 894 */
484
    public function testSupportsBetweenClauseWithPositionalParameters() : void
485
    {
486
        $this->assertSqlGeneration(
487
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2',
488
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE t0."id" BETWEEN ? AND ?'
489
        );
490
    }
491
492
    /**
493
     * @group DDC-1802
494
     */
495
    public function testSupportsNotBetweenForSizeFunction() : void
496
    {
497
        $this->assertSqlGeneration(
498
            'SELECT m.name FROM Doctrine\Tests\Models\StockExchange\Market m WHERE SIZE(m.stocks) NOT BETWEEN ?1 AND ?2',
499
            'SELECT t0."name" AS c0 FROM "exchange_markets" t0 WHERE (SELECT COUNT(*) FROM "exchange_stocks" t1 WHERE t1."market_id" = t0."id") NOT BETWEEN ? AND ?'
500
        );
501
    }
502
503
    public function testSupportsFunctionalExpressionsInWherePart() : void
504
    {
505
        $this->assertSqlGeneration(
506
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = \'someone\'',
507
            // String quoting in the SQL usually depends on the database platform.
508
            // This test works with a mock connection which uses ' for string quoting.
509
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE TRIM(t0."name") = \'someone\''
510
        );
511
    }
512
513
    public function testSupportsInstanceOfExpressionsInWherePart() : void
514
    {
515
        $this->assertSqlGeneration(
516
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee',
517
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (\'manager\', \'employee\')'
518
        );
519
    }
520
521
    public function testSupportsInstanceOfExpressionInWherePartWithMultipleValues() : void
522
    {
523
        // This also uses FQCNs starting with or without a backslash in the INSTANCE OF parameter
524
        $this->assertSqlGeneration(
525
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF (Doctrine\Tests\Models\Company\CompanyEmployee, \Doctrine\Tests\Models\Company\CompanyManager)',
526
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (\'manager\', \'employee\')'
527
        );
528
    }
529
530
    /**
531
     * @group DDC-1194
532
     */
533
    public function testSupportsInstanceOfExpressionsInWherePartPrefixedSlash() : void
534
    {
535
        $this->assertSqlGeneration(
536
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\Company\CompanyEmployee',
537
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (\'manager\', \'employee\')'
538
        );
539
    }
540
541
    /**
542
     * @group DDC-1194
543
     */
544
    public function testSupportsInstanceOfExpressionsInWherePartWithUnrelatedClass() : void
545
    {
546
        $this->assertInvalidSqlGeneration(
547
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\CMS\CmsUser',
548
            'Doctrine\\ORM\\Query\\QueryException'
549
        );
550
    }
551
552
    public function testSupportsInstanceOfExpressionsInWherePartInDeeperLevel() : void
553
    {
554
        $this->assertSqlGeneration(
555
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager',
556
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" WHERE t0."discr" IN (\'manager\')'
557
        );
558
    }
559
560
    public function testSupportsInstanceOfExpressionsInWherePartInDeepestLevel() : void
561
    {
562
        $this->assertSqlGeneration(
563
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyManager u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager',
564
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id" WHERE t0."discr" IN (\'manager\')'
565
        );
566
    }
567
568
    public function testSupportsInstanceOfExpressionsUsingInputParameterInWherePart() : void
569
    {
570
        $this->assertSqlGeneration(
571
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1',
572
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (?)',
573
            [],
574
            [1 => $this->em->getClassMetadata(CompanyEmployee::class)]
575
        );
576
    }
577
578
    /** Ticket #973 */
579
    public function testSupportsSingleValuedInExpressionWithoutSpacesInWherePart() : void
580
    {
581
        $this->assertSqlGeneration(
582
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IN(46)',
583
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE t0."email_id" IN (46)'
584
        );
585
    }
586
587
    public function testSupportsMultipleValuedInExpressionInWherePart() : void
588
    {
589
        $this->assertSqlGeneration(
590
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)',
591
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."id" IN (1, 2)'
592
        );
593
    }
594
595
    public function testSupportsNotInExpressionInWherePart() : void
596
    {
597
        $this->assertSqlGeneration(
598
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :id NOT IN (1)',
599
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE ? NOT IN (1)'
600
        );
601
    }
602
603
    /**
604
     * @group DDC-1802
605
     */
606
    public function testSupportsNotInExpressionForModFunction() : void
607
    {
608
        $this->assertSqlGeneration(
609
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE MOD(u.id, 5) NOT IN(1,3,4)',
610
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE MOD(t0."id", 5) NOT IN (1, 3, 4)'
611
        );
612
    }
613
614
    public function testInExpressionWithSingleValuedAssociationPathExpressionInWherePart() : void
615
    {
616
        $this->assertSqlGeneration(
617
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)',
618
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."avatar_id" IN (?, ?)'
619
        );
620
    }
621
622
    public function testCustomFunctionWithinInExpression() : void
623
    {
624
        $this->em->getConfiguration()->addCustomStringFunction('FOO', MyAbsFunction::class);
625
        $this->assertSqlGeneration(
626
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.username IN (FOO(\'Lo\'), \'Lo\', :name)',
627
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."username" IN (ABS(\'Lo\'), \'Lo\', ?)'
628
        );
629
    }
630
631
    public function testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide() : void
632
    {
633
        // We do not support SingleValuedAssociationPathExpression on inverse side
634
        $this->assertInvalidSqlGeneration(
635
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IN (?1, ?2)',
636
            'Doctrine\ORM\Query\QueryException'
637
        );
638
    }
639
640
    public function testSupportsConcatFunctionMysql() : void
641
    {
642
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
643
644
        $this->assertSqlGeneration(
645
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, \'s\') = ?1',
646
            'SELECT t0.`id` AS c0 FROM `cms_users` t0 WHERE CONCAT(t0.`name`, \'s\') = ?'
647
        );
648
649
        $this->assertSqlGeneration(
650
            'SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
651
            'SELECT CONCAT(t0.`id`, t0.`name`) AS c0 FROM `cms_users` t0 WHERE t0.`id` = ?'
652
        );
653
    }
654
655
    public function testSupportsConcatFunctionPgSql() : void
656
    {
657
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
658
659
        $this->assertSqlGeneration(
660
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, \'s\') = ?1',
661
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE t0."name" || \'s\' = ?'
662
        );
663
664
        $this->assertSqlGeneration(
665
            'SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
666
            'SELECT t0."id" || t0."name" AS c0 FROM "cms_users" t0 WHERE t0."id" = ?'
667
        );
668
    }
669
670
    public function testSupportsExistsExpressionInWherePartWithCorrelatedSubquery() : void
671
    {
672
        $this->assertSqlGeneration(
673
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = u.id)',
674
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT t1."phonenumber" FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = t0."id")'
675
        );
676
    }
677
678
    /**
679
     * @group DDC-593
680
     */
681
    public function testSubqueriesInComparisonExpression() : void
682
    {
683
        $this->assertSqlGeneration(
684
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id >= (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = :name)) AND (u.id <= (SELECT u3.id FROM Doctrine\Tests\Models\CMS\CmsUser u3 WHERE u3.name = :name))',
685
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" >= (SELECT t1."id" FROM "cms_users" t1 WHERE t1."name" = ?)) AND (t0."id" <= (SELECT t2."id" FROM "cms_users" t2 WHERE t2."name" = ?))'
686
        );
687
    }
688
689
    public function testSupportsMemberOfExpressionOneToMany() : void
690
    {
691
        // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...)
692
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
693
694
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
695
696
        $phone              = new CmsPhonenumber();
697
        $phone->phonenumber = 101;
698
        $q->setParameter('param', $phone);
699
700
        self::assertEquals(
701
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_phonenumbers" t1 WHERE t0."id" = t1."user_id" AND t1."phonenumber" = ?)',
702
            $q->getSql()
703
        );
704
    }
705
706
    public function testSupportsMemberOfExpressionManyToMany() : void
707
    {
708
        // "Get all users who are members of $group."
709
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
710
711
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
712
713
        $group     = new CmsGroup();
714
        $group->id = 101;
715
        $q->setParameter('param', $group);
716
717
        self::assertEquals(
718
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = ?)',
719
            $q->getSql()
720
        );
721
    }
722
723
    public function testSupportsMemberOfExpressionManyToManyParameterArray() : void
724
    {
725
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
726
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
727
728
        $group      = new CmsGroup();
729
        $group->id  = 101;
730
        $group2     = new CmsGroup();
731
        $group2->id = 105;
732
        $q->setParameter('param', [$group, $group2]);
733
734
        self::assertEquals(
735
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = ?)',
736
            $q->getSql()
737
        );
738
    }
739
740
    public function testSupportsMemberOfExpressionSelfReferencing() : void
741
    {
742
        // "Get all persons who have $person as a friend."
743
        // Tough one: Many-many self-referencing ("friends") with class table inheritance
744
        $q = $this->em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
745
746
        $person = new CompanyPerson();
747
748
        $unitOfWork = $this->em->getUnitOfWork();
749
        $persister  = $unitOfWork->getEntityPersister(get_class($person));
750
751
        $persister->setIdentifier($person, ['id' => 101]);
752
753
        $q->setParameter('param', $person);
754
755
        self::assertEquals(
756
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."title" AS c2, t2."salary" AS c3, t2."department" AS c4, t2."startDate" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t1."car_id" AS c8 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id" WHERE EXISTS (SELECT 1 FROM "company_persons_friends" t3 INNER JOIN "company_persons" t4 ON t3."friend_id" = t4."id" WHERE t3."person_id" = t0."id" AND t4."id" = ?)',
757
            $q->getSql()
758
        );
759
    }
760
761
    public function testSupportsMemberOfWithSingleValuedAssociation() : void
762
    {
763
        // Impossible example, but it illustrates the purpose
764
        $this->assertSqlGeneration(
765
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.email MEMBER OF u.groups',
766
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = t0."email_id")'
767
        );
768
    }
769
770
    public function testSupportsMemberOfWithIdentificationVariable() : void
771
    {
772
        // Impossible example, but it illustrates the purpose
773
        $this->assertSqlGeneration(
774
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u MEMBER OF u.groups',
775
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = t0."id")'
776
        );
777
    }
778
779
    public function testSupportsCurrentDateFunction() : void
780
    {
781
        $this->assertSqlGeneration(
782
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()',
783
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_datetime" > CURRENT_DATE',
784
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
785
        );
786
    }
787
788
    public function testSupportsCurrentTimeFunction() : void
789
    {
790
        $this->assertSqlGeneration(
791
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()',
792
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_time" > CURRENT_TIME',
793
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
794
        );
795
    }
796
797
    public function testSupportsCurrentTimestampFunction() : void
798
    {
799
        $this->assertSqlGeneration(
800
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()',
801
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_datetime" > CURRENT_TIMESTAMP',
802
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
803
        );
804
    }
805
806
    public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition() : void
807
    {
808
        $this->assertSqlGeneration(
809
            // DQL
810
            // The result of this query consists of all employees whose spouses are also employees.
811
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
812
                WHERE EXISTS (
813
                    SELECT spouseEmp
814
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
815
                    WHERE spouseEmp = emp.spouse)',
816
            // SQL
817
            'SELECT DISTINCT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0'
818
                . ' WHERE EXISTS ('
819
                    . 'SELECT t1."id" FROM "cms_employees" t1 WHERE t1."id" = t0."spouse_id"'
820
                    . ')'
821
        );
822
    }
823
824
    public function testExistsExpressionWithSimpleSelectReturningScalar() : void
825
    {
826
        $this->assertSqlGeneration(
827
            // DQL
828
            // The result of this query consists of all employees whose spouses are also employees.
829
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
830
                WHERE EXISTS (
831
                    SELECT 1
832
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
833
                    WHERE spouseEmp = emp.spouse)',
834
            // SQL
835
            'SELECT DISTINCT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0'
836
                . ' WHERE EXISTS ('
837
                    . 'SELECT 1 AS c2 FROM "cms_employees" t1 WHERE t1."id" = t0."spouse_id"'
838
                    . ')'
839
        );
840
    }
841
842
    public function testLimitFromQueryClass() : void
843
    {
844
        $q = $this->em
845
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
846
            ->setMaxResults(10);
847
848
        self::assertEquals(
849
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."email_id" AS c4 FROM "cms_users" t0 LIMIT 10',
850
            $q->getSql()
851
        );
852
    }
853
854
    public function testLimitAndOffsetFromQueryClass() : void
855
    {
856
        $q = $this->em
857
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
858
            ->setMaxResults(10)
859
            ->setFirstResult(0);
860
861
        // DBAL 2.8+ doesn't add OFFSET part when offset is 0
862
        self::assertThat(
863
            $q->getSql(),
864
            self::logicalOr(
865
                self::identicalTo('SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."email_id" AS c4 FROM "cms_users" t0 LIMIT 10'),
866
                self::identicalTo('SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."email_id" AS c4 FROM "cms_users" t0 LIMIT 10 OFFSET 0')
867
            )
868
        );
869
    }
870
871
    public function testSizeFunction() : void
872
    {
873
        $this->assertSqlGeneration(
874
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1',
875
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_phonenumbers" t1 WHERE t1."user_id" = t0."id") > 1'
876
        );
877
    }
878
879
    public function testSizeFunctionSupportsManyToMany() : void
880
    {
881
        $this->assertSqlGeneration(
882
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1',
883
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_users_groups" t1 WHERE t1."user_id" = t0."id") > 1'
884
        );
885
    }
886
887
    public function testEmptyCollectionComparisonExpression() : void
888
    {
889
        $this->assertSqlGeneration(
890
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY',
891
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_phonenumbers" t1 WHERE t1."user_id" = t0."id") = 0'
892
        );
893
        $this->assertSqlGeneration(
894
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS NOT EMPTY',
895
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_phonenumbers" t1 WHERE t1."user_id" = t0."id") > 0'
896
        );
897
    }
898
899
    public function testNestedExpressions() : void
900
    {
901
        $this->assertSqlGeneration(
902
            'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)',
903
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."id" > 10 AND t0."id" < 42 AND ((t0."id" * 2) > 5)'
904
        );
905
    }
906
907
    public function testNestedExpressions2() : void
908
    {
909
        $this->assertSqlGeneration(
910
            'select u from Doctrine\Tests\Models\CMS\CmsUser u where (u.id > 10) and (u.id < 42 and ((u.id * 2) > 5)) or u.id <> 42',
911
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" > 10) AND (t0."id" < 42 AND ((t0."id" * 2) > 5)) OR t0."id" <> 42'
912
        );
913
    }
914
915
    public function testNestedExpressions3() : void
916
    {
917
        $this->assertSqlGeneration(
918
            'select u from Doctrine\Tests\Models\CMS\CmsUser u where (u.id > 10) and (u.id between 1 and 10 or u.id in (1, 2, 3, 4, 5))',
919
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" > 10) AND (t0."id" BETWEEN 1 AND 10 OR t0."id" IN (1, 2, 3, 4, 5))'
920
        );
921
    }
922
923
    public function testOrderByCollectionAssociationSize() : void
924
    {
925
        $this->assertSqlGeneration(
926
            'select u, size(u.articles) as numArticles from Doctrine\Tests\Models\CMS\CmsUser u order by numArticles',
927
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT COUNT(*) FROM "cms_articles" t1 WHERE t1."user_id" = t0."id") AS c4 FROM "cms_users" t0 ORDER BY c4 ASC'
928
        );
929
    }
930
931
    public function testOrderBySupportsSingleValuedPathExpressionOwningSide() : void
932
    {
933
        $this->assertSqlGeneration(
934
            'select a from Doctrine\Tests\Models\CMS\CmsArticle a order by a.user',
935
            'SELECT t0."id" AS c0, t0."topic" AS c1, t0."text" AS c2, t0."version" AS c3 FROM "cms_articles" t0 ORDER BY t0."user_id" ASC'
936
        );
937
    }
938
939
    /**
940
     * @expectedException \Doctrine\ORM\Query\QueryException
941
     */
942
    public function testOrderBySupportsSingleValuedPathExpressionInverseSide() : void
943
    {
944
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u order by u.address');
945
946
        $q->getSQL();
947
    }
948
949
    public function testBooleanLiteralInWhereOnSqlite() : void
950
    {
951
        $this->em->getConnection()->setDatabasePlatform(new SqlitePlatform());
952
953
        $this->assertSqlGeneration(
954
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true',
955
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = 1'
956
        );
957
958
        $this->assertSqlGeneration(
959
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false',
960
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = 0'
961
        );
962
    }
963
964
    public function testBooleanLiteralInWhereOnPostgres() : void
965
    {
966
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
967
968
        $this->assertSqlGeneration(
969
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true',
970
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = true'
971
        );
972
973
        $this->assertSqlGeneration(
974
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false',
975
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = false'
976
        );
977
    }
978
979
    public function testSingleValuedAssociationFieldInWhere() : void
980
    {
981
        $this->assertSqlGeneration(
982
            'SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1',
983
            'SELECT t0."phonenumber" AS c0 FROM "cms_phonenumbers" t0 WHERE t0."user_id" = ?'
984
        );
985
    }
986
987
    public function testSingleValuedAssociationNullCheckOnOwningSide() : void
988
    {
989
        $this->assertSqlGeneration(
990
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user IS NULL',
991
            'SELECT t0."id" AS c0, t0."country" AS c1, t0."zip" AS c2, t0."city" AS c3 FROM "cms_addresses" t0 WHERE t0."user_id" IS NULL'
992
        );
993
    }
994
995
    /**
996
     * Null check on inverse side has to happen through explicit JOIN.
997
     * 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IS NULL'
998
     * where the CmsUser is the inverse side is not supported.
999
     */
1000
    public function testSingleValuedAssociationNullCheckOnInverseSide() : void
1001
    {
1002
        $this->assertSqlGeneration(
1003
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.address a WHERE a.id IS NULL',
1004
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_addresses" t1 ON t0."id" = t1."user_id" WHERE t1."id" IS NULL'
1005
        );
1006
    }
1007
1008
    /**
1009
     * @group DDC-339
1010
     * @group DDC-1572
1011
     */
1012
    public function testStringFunctionLikeExpression() : void
1013
    {
1014
        $this->assertSqlGeneration(
1015
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE \'%foo OR bar%\'',
1016
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") LIKE \'%foo OR bar%\''
1017
        );
1018
        $this->assertSqlGeneration(
1019
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str',
1020
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") LIKE ?'
1021
        );
1022
        $this->assertSqlGeneration(
1023
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), \'_moo\') LIKE :str',
1024
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(t0."name") || \'_moo\' LIKE ?'
1025
        );
1026
1027
        // DDC-1572
1028
        $this->assertSqlGeneration(
1029
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(u.name) LIKE UPPER(:str)',
1030
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(t0."name") LIKE UPPER(?)'
1031
        );
1032
        $this->assertSqlGeneration(
1033
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) LIKE UPPER(LOWER(:str))',
1034
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(LOWER(t0."name")) LIKE UPPER(LOWER(?))'
1035
        );
1036
        $this->assertSqlGeneration(
1037
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE u.name',
1038
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" LIKE t0."name")'
1039
        );
1040
    }
1041
1042
    /**
1043
     * @group DDC-1802
1044
     */
1045
    public function testStringFunctionNotLikeExpression() : void
1046
    {
1047
        $this->assertSqlGeneration(
1048
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) NOT LIKE \'%foo OR bar%\'',
1049
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") NOT LIKE \'%foo OR bar%\''
1050
        );
1051
1052
        $this->assertSqlGeneration(
1053
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) NOT LIKE UPPER(LOWER(:str))',
1054
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(LOWER(t0."name")) NOT LIKE UPPER(LOWER(?))'
1055
        );
1056
        $this->assertSqlGeneration(
1057
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic NOT LIKE u.name',
1058
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" NOT LIKE t0."name")'
1059
        );
1060
    }
1061
1062
    /**
1063
     * @group DDC-338
1064
     */
1065
    public function testOrderedCollectionFetchJoined() : void
1066
    {
1067
        $this->assertSqlGeneration(
1068
            'SELECT r, l FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.legs l',
1069
            'SELECT t0."id" AS c0, t1."id" AS c1, t1."departureDate" AS c2, t1."arrivalDate" AS c3 FROM "RoutingRoute" t0 INNER JOIN "RoutingRouteLegs" t2 ON t0."id" = t2."route_id" INNER JOIN "RoutingLeg" t1 ON t1."id" = t2."leg_id" ORDER BY t1."departureDate" ASC'
1070
        );
1071
    }
1072
1073
    public function testSubselectInSelect() : void
1074
    {
1075
        $this->assertSqlGeneration(
1076
            'SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = \'jon\'',
1077
            'SELECT t0."name" AS c0, (SELECT COUNT(t1."phonenumber") AS c2 FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = 1234) AS c1 FROM "cms_users" t0 WHERE t0."name" = \'jon\''
1078
        );
1079
    }
1080
1081
    /**
1082
     * @group locking
1083
     * @group DDC-178
1084
     */
1085
    public function testPessimisticWriteLockQueryHint() : void
1086
    {
1087
        if ($this->em->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) {
1088
            $this->markTestSkipped('SqLite does not support Row locking at all.');
1089
        }
1090
1091
        $this->assertSqlGeneration(
1092
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1093
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\' FOR UPDATE',
1094
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_WRITE]
1095
        );
1096
    }
1097
1098
    /**
1099
     * @group locking
1100
     * @group DDC-178
1101
     */
1102
    public function testPessimisticReadLockQueryHintPostgreSql() : void
1103
    {
1104
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
1105
1106
        $this->assertSqlGeneration(
1107
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1108
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\' FOR SHARE',
1109
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1110
        );
1111
    }
1112
1113
    /**
1114
     * @group DDC-1693
1115
     * @group locking
1116
     */
1117
    public function testLockModeNoneQueryHint() : void
1118
    {
1119
        $this->assertSqlGeneration(
1120
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1121
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\'',
1122
            [ORMQuery::HINT_LOCK_MODE => LockMode::NONE]
1123
        );
1124
    }
1125
1126
    /**
1127
     * @group DDC-430
1128
     */
1129
    public function testSupportSelectWithMoreThan10InputParameters() : void
1130
    {
1131
        $this->assertSqlGeneration(
1132
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1 OR u.id = ?2 OR u.id = ?3 OR u.id = ?4 OR u.id = ?5 OR u.id = ?6 OR u.id = ?7 OR u.id = ?8 OR u.id = ?9 OR u.id = ?10 OR u.id = ?11',
1133
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ?'
1134
        );
1135
    }
1136
1137
    /**
1138
     * @group locking
1139
     * @group DDC-178
1140
     */
1141
    public function testPessimisticReadLockQueryHintMySql() : void
1142
    {
1143
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
1144
1145
        $this->assertSqlGeneration(
1146
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1147
            'SELECT t0.`id` AS c0, t0.`status` AS c1, t0.`username` AS c2, t0.`name` AS c3 FROM `cms_users` t0 WHERE t0.`username` = \'gblanco\' LOCK IN SHARE MODE',
1148
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1149
        );
1150
    }
1151
1152
    /**
1153
     * @group locking
1154
     * @group DDC-178
1155
     */
1156
    public function testPessimisticReadLockQueryHintOracle() : void
1157
    {
1158
        $this->em->getConnection()->setDatabasePlatform(new OraclePlatform());
1159
1160
        $this->assertSqlGeneration(
1161
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1162
            'SELECT t0."id" AS C0, t0."status" AS C1, t0."username" AS C2, t0."name" AS C3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\' FOR UPDATE',
1163
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1164
        );
1165
    }
1166
1167
    /**
1168
     * @group DDC-431
1169
     */
1170
    public function testSupportToCustomDQLFunctions() : void
1171
    {
1172
        $config = $this->em->getConfiguration();
1173
        $config->addCustomNumericFunction('MYABS', MyAbsFunction::class);
1174
1175
        $this->assertSqlGeneration(
1176
            'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
1177
            'SELECT ABS(t0."phonenumber") AS c0 FROM "cms_phonenumbers" t0'
1178
        );
1179
1180
        $config->setCustomNumericFunctions([]);
1181
    }
1182
1183
    /**
1184
     * @group DDC-826
1185
     */
1186
    public function testMappedSuperclassAssociationJoin() : void
1187
    {
1188
        $this->assertSqlGeneration(
1189
            'SELECT f FROM Doctrine\Tests\Models\DirectoryTree\File f JOIN f.parentDirectory d WHERE f.id = ?1',
1190
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."extension" AS c2 FROM "file" t0 INNER JOIN "Directory" t1 ON t0."parentDirectory_id" = t1."id" WHERE t0."id" = ?'
1191
        );
1192
    }
1193
1194
    /**
1195
     * @group DDC-1053
1196
     */
1197
    public function testGroupBy() : void
1198
    {
1199
        $this->assertSqlGeneration(
1200
            'SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id',
1201
            'SELECT t0."id" AS c0, count(t1."id") AS c1 FROM "cms_groups" t0 INNER JOIN "cms_users_groups" t2 ON t0."id" = t2."group_id" INNER JOIN "cms_users" t1 ON t1."id" = t2."user_id" GROUP BY t0."id"'
1202
        );
1203
    }
1204
1205
    /**
1206
     * @group DDC-1053
1207
     */
1208
    public function testGroupByIdentificationVariable() : void
1209
    {
1210
        $this->assertSqlGeneration(
1211
            'SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g',
1212
            'SELECT t0."id" AS c0, t0."name" AS c1, count(t1."id") AS c2 FROM "cms_groups" t0 INNER JOIN "cms_users_groups" t2 ON t0."id" = t2."group_id" INNER JOIN "cms_users" t1 ON t1."id" = t2."user_id" GROUP BY t0."id", t0."name"'
1213
        );
1214
    }
1215
1216
    public function testCaseContainingNullIf() : void
1217
    {
1218
        $this->assertSqlGeneration(
1219
            'SELECT NULLIF(g.id, g.name) AS NullIfEqual FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1220
            'SELECT NULLIF(t0."id", t0."name") AS c0 FROM "cms_groups" t0'
1221
        );
1222
    }
1223
1224
    public function testCaseContainingCoalesce() : void
1225
    {
1226
        $this->assertSqlGeneration(
1227
            'SELECT COALESCE(NULLIF(u.name, \'\'), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u',
1228
            'SELECT COALESCE(NULLIF(t0."name", \'\'), t0."username") AS c0 FROM "cms_users" t0'
1229
        );
1230
    }
1231
1232
    /**
1233
     * Test that the right discriminator data is inserted in a subquery.
1234
     */
1235
    public function testSubSelectDiscriminator() : void
1236
    {
1237
        $this->assertSqlGeneration(
1238
            'SELECT u.name, (SELECT COUNT(cfc.id) total FROM Doctrine\Tests\Models\Company\CompanyFixContract cfc) as cfc_count FROM Doctrine\Tests\Models\CMS\CmsUser u',
1239
            'SELECT t0."name" AS c0, (SELECT COUNT(t1."id") AS c2 FROM "company_contracts" t1 WHERE t1."discr" IN (\'fix\')) AS c1 FROM "cms_users" t0'
1240
        );
1241
    }
1242
1243
    public function testIdVariableResultVariableReuse() : void
1244
    {
1245
        $exceptionThrown = false;
1246
1247
        try {
1248
            $query = $this->em->createQuery('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN (SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u)');
1249
1250
            $query->getSql();
1251
            $query->free();
1252
        } catch (Exception $e) {
1253
            $exceptionThrown = true;
1254
        }
1255
1256
        self::assertTrue($exceptionThrown);
1257
    }
1258
1259
    public function testSubSelectAliasesFromOuterQuery() : void
1260
    {
1261
        $this->assertSqlGeneration(
1262
            'SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo',
1263
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT t1."name" FROM "cms_users" t1 WHERE t1."id" = t0."id") AS c4 FROM "cms_users" t0'
1264
        );
1265
    }
1266
1267
    public function testSubSelectAliasesFromOuterQueryWithSubquery() : void
1268
    {
1269
        $this->assertSqlGeneration(
1270
            'SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id AND ui.name IN (SELECT uii.name FROM Doctrine\Tests\Models\CMS\CmsUser uii)) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo',
1271
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT t1."name" FROM "cms_users" t1 WHERE t1."id" = t0."id" AND t1."name" IN (SELECT t2."name" FROM "cms_users" t2)) AS c4 FROM "cms_users" t0'
1272
        );
1273
    }
1274
1275
    public function testSubSelectAliasesFromOuterQueryReuseInWhereClause() : void
1276
    {
1277
        $this->assertSqlGeneration(
1278
            'SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo WHERE bar = ?0',
1279
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT t1."name" FROM "cms_users" t1 WHERE t1."id" = t0."id") AS c4 FROM "cms_users" t0 WHERE c4 = ?'
1280
        );
1281
    }
1282
1283
    /**
1284
     * @group DDC-1298
1285
     */
1286
    public function testSelectForeignKeyPKWithoutFields() : void
1287
    {
1288
        $this->assertSqlGeneration(
1289
            'SELECT t, s, l FROM Doctrine\Tests\Models\DDC117\DDC117Link l INNER JOIN l.target t INNER JOIN l.source s',
1290
            'SELECT t0."article_id" AS c0, t0."title" AS c1, t1."article_id" AS c2, t1."title" AS c3, t2."source_id" AS c4, t2."target_id" AS c5 FROM "DDC117Link" t2 INNER JOIN "DDC117Article" t0 ON t2."target_id" = t0."article_id" INNER JOIN "DDC117Article" t1 ON t2."source_id" = t1."article_id"'
1291
        );
1292
    }
1293
1294
    public function testGeneralCaseWithSingleWhenClause() : void
1295
    {
1296
        $this->assertSqlGeneration(
1297
            'SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1298
            'SELECT t0."id" AS c0, CASE WHEN ((t0."id" / 2) > 18) THEN 1 ELSE 0 END AS c1 FROM "cms_groups" t0'
1299
        );
1300
    }
1301
1302
    public function testGeneralCaseWithMultipleWhenClause() : void
1303
    {
1304
        $this->assertSqlGeneration(
1305
            'SELECT g.id, CASE WHEN (g.id / 2 < 10) THEN 2 WHEN ((g.id / 2) > 20) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1306
            'SELECT t0."id" AS c0, CASE WHEN (t0."id" / 2 < 10) THEN 2 WHEN ((t0."id" / 2) > 20) THEN 1 ELSE 0 END AS c1 FROM "cms_groups" t0'
1307
        );
1308
    }
1309
1310
    public function testSimpleCaseWithSingleWhenClause() : void
1311
    {
1312
        $this->assertSqlGeneration(
1313
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = CASE g.name WHEN \'admin\' THEN 1 ELSE 2 END',
1314
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" = CASE t0."name" WHEN \'admin\' THEN 1 ELSE 2 END'
1315
        );
1316
    }
1317
1318
    public function testSimpleCaseWithMultipleWhenClause() : void
1319
    {
1320
        $this->assertSqlGeneration(
1321
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = (CASE g.name WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END)',
1322
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" = (CASE t0."name" WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END)'
1323
        );
1324
    }
1325
1326
    public function testGeneralCaseWithSingleWhenClauseInSubselect() : void
1327
    {
1328
        $this->assertSqlGeneration(
1329
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE WHEN ((g2.id / 2) > 18) THEN 2 ELSE 1 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1330
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE WHEN ((t1."id" / 2) > 18) THEN 2 ELSE 1 END AS c2 FROM "cms_groups" t1)'
1331
        );
1332
    }
1333
1334
    public function testGeneralCaseWithMultipleWhenClauseInSubselect() : void
1335
    {
1336
        $this->assertSqlGeneration(
1337
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE WHEN (g.id / 2 < 10) THEN 3 WHEN ((g.id / 2) > 20) THEN 2 ELSE 1 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1338
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE WHEN (t0."id" / 2 < 10) THEN 3 WHEN ((t0."id" / 2) > 20) THEN 2 ELSE 1 END AS c2 FROM "cms_groups" t1)'
1339
        );
1340
    }
1341
1342
    public function testSimpleCaseWithSingleWhenClauseInSubselect() : void
1343
    {
1344
        $this->assertSqlGeneration(
1345
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE g2.name WHEN \'admin\' THEN 1 ELSE 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1346
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE t1."name" WHEN \'admin\' THEN 1 ELSE 2 END AS c2 FROM "cms_groups" t1)'
1347
        );
1348
    }
1349
1350
    public function testSimpleCaseWithMultipleWhenClauseInSubselect() : void
1351
    {
1352
        $this->assertSqlGeneration(
1353
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE g2.name WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1354
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE t1."name" WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END AS c2 FROM "cms_groups" t1)'
1355
        );
1356
    }
1357
1358
    /**
1359
     * @group DDC-1696
1360
     */
1361
    public function testSimpleCaseWithStringPrimary() : void
1362
    {
1363
        $this->assertSqlGeneration(
1364
            'SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN \'Foo\' ELSE \'Bar\' END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1365
            'SELECT t0."id" AS c0, CASE WHEN ((t0."id" / 2) > 18) THEN \'Foo\' ELSE \'Bar\' END AS c1 FROM "cms_groups" t0'
1366
        );
1367
    }
1368
1369
    /**
1370
     * @group DDC-2205
1371
     */
1372
    public function testCaseNegativeValuesInThenExpression() : void
1373
    {
1374
        $this->assertSqlGeneration(
1375
            'SELECT CASE g.name WHEN \'admin\' THEN - 1 ELSE - 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1376
            'SELECT CASE t0."name" WHEN \'admin\' THEN -1 ELSE -2 END AS c0 FROM "cms_groups" t0'
1377
        );
1378
1379
        $this->assertSqlGeneration(
1380
            'SELECT CASE g.name WHEN \'admin\' THEN  - 2 WHEN \'guest\' THEN - 1 ELSE 0 END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1381
            'SELECT CASE t0."name" WHEN \'admin\' THEN -2 WHEN \'guest\' THEN -1 ELSE 0 END AS c0 FROM "cms_groups" t0'
1382
        );
1383
1384
        $this->assertSqlGeneration(
1385
            'SELECT CASE g.name WHEN \'admin\' THEN (- 1) ELSE (- 2) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1386
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-1) ELSE (-2) END AS c0 FROM "cms_groups" t0'
1387
        );
1388
1389
        $this->assertSqlGeneration(
1390
            'SELECT CASE g.name WHEN \'admin\' THEN ( - :value) ELSE ( + :value) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1391
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-?) ELSE (+?) END AS c0 FROM "cms_groups" t0'
1392
        );
1393
1394
        $this->assertSqlGeneration(
1395
            'SELECT CASE g.name WHEN \'admin\' THEN ( - g.id) ELSE ( + g.id) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1396
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-t0."id") ELSE (+t0."id") END AS c0 FROM "cms_groups" t0'
1397
        );
1398
    }
1399
1400
    public function testIdentityFunctionWithCompositePrimaryKey() : void
1401
    {
1402
        $this->assertSqlGeneration(
1403
            'SELECT IDENTITY(p.poi, \'long\') AS long FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1404
            'SELECT t0."poi_long" AS c0 FROM "navigation_photos" t0'
1405
        );
1406
1407
        $this->assertSqlGeneration(
1408
            'SELECT IDENTITY(p.poi, \'lat\') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1409
            'SELECT t0."poi_lat" AS c0 FROM "navigation_photos" t0'
1410
        );
1411
1412
        $this->assertSqlGeneration(
1413
            'SELECT IDENTITY(p.poi, \'long\') AS long, IDENTITY(p.poi, \'lat\') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1414
            'SELECT t0."poi_long" AS c0, t0."poi_lat" AS c1 FROM "navigation_photos" t0'
1415
        );
1416
1417
        $this->assertInvalidSqlGeneration(
1418
            'SELECT IDENTITY(p.poi, \'invalid\') AS invalid FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1419
            QueryException::class
1420
        );
1421
    }
1422
1423
    /**
1424
     * @group DDC-2519
1425
     */
1426
    public function testPartialWithAssociationIdentifier() : void
1427
    {
1428
        $this->assertSqlGeneration(
1429
            'SELECT PARTIAL l.{source, target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l',
1430
            'SELECT t0."iUserIdSource" AS c0, t0."iUserIdTarget" AS c1 FROM "legacy_users_reference" t0'
1431
        );
1432
1433
        $this->assertSqlGeneration(
1434
            'SELECT PARTIAL l.{description, source, target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l',
1435
            'SELECT t0."description" AS c0, t0."iUserIdSource" AS c1, t0."iUserIdTarget" AS c2 FROM "legacy_users_reference" t0'
1436
        );
1437
    }
1438
1439
    /**
1440
     * @group DDC-1339
1441
     */
1442
    public function testIdentityFunctionInSelectClause() : void
1443
    {
1444
        $this->assertSqlGeneration(
1445
            'SELECT IDENTITY(u.email) as email_id FROM Doctrine\Tests\Models\CMS\CmsUser u',
1446
            'SELECT t0."email_id" AS c0 FROM "cms_users" t0'
1447
        );
1448
    }
1449
1450
    public function testIdentityFunctionInJoinedSubclass() : void
1451
    {
1452
        //relation is in the subclass (CompanyManager) we are querying
1453
        $this->assertSqlGeneration(
1454
            'SELECT m, IDENTITY(m.car) as car_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1455
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t2."car_id" AS c6, t0."discr" AS c7 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"'
1456
        );
1457
1458
        //relation is in the base class (CompanyPerson).
1459
        $this->assertSqlGeneration(
1460
            'SELECT m, IDENTITY(m.spouse) as spouse_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1461
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."spouse_id" AS c6, t0."discr" AS c7 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"'
1462
        );
1463
    }
1464
1465
    /**
1466
     * @group DDC-1339
1467
     */
1468
    public function testIdentityFunctionDoesNotAcceptStateField() : void
1469
    {
1470
        $this->assertInvalidSqlGeneration(
1471
            'SELECT IDENTITY(u.name) as name FROM Doctrine\Tests\Models\CMS\CmsUser u',
1472
            QueryException::class
1473
        );
1474
    }
1475
1476
    /**
1477
     * @group DDC-1389
1478
     */
1479
    public function testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad() : void
1480
    {
1481
        $this->assertSqlGeneration(
1482
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1483
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."title" AS c2, t2."salary" AS c3, t2."department" AS c4, t2."startDate" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t1."car_id" AS c8 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id"',
1484
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1485
        );
1486
    }
1487
1488
    /**
1489
     * @group DDC-1389
1490
     */
1491
    public function testInheritanceTypeJoinInRootClassWithEnabledForcePartialLoad() : void
1492
    {
1493
        $this->assertSqlGeneration(
1494
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1495
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0',
1496
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1497
        );
1498
    }
1499
1500
    /**
1501
     * @group DDC-1389
1502
     */
1503
    public function testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad() : void
1504
    {
1505
        $this->assertSqlGeneration(
1506
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1507
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t2."car_id" AS c8 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" LEFT JOIN "company_managers" t2 ON t1."id" = t2."id"',
1508
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1509
        );
1510
    }
1511
1512
    /**
1513
     * @group DDC-1389
1514
     */
1515
    public function testInheritanceTypeJoinInChildClassWithEnabledForcePartialLoad() : void
1516
    {
1517
        $this->assertSqlGeneration(
1518
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1519
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id"',
1520
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1521
        );
1522
    }
1523
1524
    /**
1525
     * @group DDC-1389
1526
     */
1527
    public function testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad() : void
1528
    {
1529
        $this->assertSqlGeneration(
1530
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1531
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t2."car_id" AS c8 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"',
1532
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1533
        );
1534
    }
1535
1536
    /**
1537
     * @group DDC-1389
1538
     */
1539
    public function testInheritanceTypeJoinInLeafClassWithEnabledForcePartialLoad() : void
1540
    {
1541
        $this->assertSqlGeneration(
1542
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1543
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"',
1544
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1545
        );
1546
    }
1547
1548
    /**
1549
     * @group DDC-1389
1550
     */
1551
    public function testInheritanceTypeSingleTableInRootClassWithDisabledForcePartialLoad() : void
1552
    {
1553
        $this->assertSqlGeneration(
1554
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1555
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6, t0."salesPerson_id" AS c7 FROM "company_contracts" t0 WHERE t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')',
1556
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1557
        );
1558
    }
1559
1560
    /**
1561
     * @group DDC-1389
1562
     */
1563
    public function testInheritanceTypeSingleTableInRootClassWithEnabledForcePartialLoad() : void
1564
    {
1565
        $this->assertSqlGeneration(
1566
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1567
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 WHERE t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')',
1568
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1569
        );
1570
    }
1571
1572
    /**
1573
     * @group DDC-1389
1574
     */
1575
    public function testInheritanceTypeSingleTableInChildClassWithDisabledForcePartialLoad() : void
1576
    {
1577
        $this->assertSqlGeneration(
1578
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1579
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5, t0."salesPerson_id" AS c6 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexible\', \'flexultra\')',
1580
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1581
        );
1582
    }
1583
1584
    /**
1585
     * @group DDC-1389
1586
     */
1587
    public function testInheritanceTypeSingleTableInChildClassWithEnabledForcePartialLoad() : void
1588
    {
1589
        $this->assertSqlGeneration(
1590
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1591
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexible\', \'flexultra\')',
1592
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1593
        );
1594
    }
1595
1596
    /**
1597
     * @group DDC-1389
1598
     */
1599
    public function testInheritanceTypeSingleTableInLeafClassWithDisabledForcePartialLoad() : void
1600
    {
1601
        $this->assertSqlGeneration(
1602
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1603
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5, t0."salesPerson_id" AS c6 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexultra\')',
1604
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1605
        );
1606
    }
1607
1608
    /**
1609
     * @group DDC-1389
1610
     */
1611
    public function testInheritanceTypeSingleTableInLeafClassWithEnabledForcePartialLoad() : void
1612
    {
1613
        $this->assertSqlGeneration(
1614
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1615
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexultra\')',
1616
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1617
        );
1618
    }
1619
1620
    /**
1621
     * @group DDC-1161
1622
     */
1623
    public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias() : void
1624
    {
1625
        $this->assertSqlGeneration(
1626
            'SELECT p, pp FROM Doctrine\Tests\Models\Company\CompanyPerson p JOIN p.spouse pp',
1627
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."title" AS c2, t2."salary" AS c3, t2."department" AS c4, t2."startDate" AS c5, t3."id" AS c6, t3."name" AS c7, t4."title" AS c8, t5."salary" AS c9, t5."department" AS c10, t5."startDate" AS c11, t0."discr" AS c12, t0."spouse_id" AS c13, t1."car_id" AS c14, t3."discr" AS c15, t3."spouse_id" AS c16, t4."car_id" AS c17 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id" INNER JOIN "company_persons" t3 ON t0."spouse_id" = t3."id" LEFT JOIN "company_managers" t4 ON t3."id" = t4."id" LEFT JOIN "company_employees" t5 ON t3."id" = t5."id"',
1628
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1629
        );
1630
    }
1631
1632
    /**
1633
     * @group DDC-1384
1634
     */
1635
    public function testAliasDoesNotExceedPlatformDefinedLength() : void
1636
    {
1637
        $this->assertSqlGeneration(
1638
            'SELECT m FROM ' . __NAMESPACE__ . '\\DDC1384Model m',
1639
            'SELECT t0."aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" AS c0 FROM "DDC1384Model" t0'
1640
        );
1641
    }
1642
1643
    /**
1644
     * @group DDC-331
1645
     * @group DDC-1384
1646
     */
1647
    public function testIssue331() : void
1648
    {
1649
        $this->assertSqlGeneration(
1650
            'SELECT e.name FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1651
            'SELECT t0."name" AS c0 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id"'
1652
        );
1653
    }
1654
1655
    /**
1656
     * @group DDC-1435
1657
     */
1658
    public function testForeignKeyAsPrimaryKeySubselect() : void
1659
    {
1660
        $this->assertSqlGeneration(
1661
            'SELECT s FROM Doctrine\Tests\Models\DDC117\DDC117Article s WHERE EXISTS (SELECT r FROM Doctrine\Tests\Models\DDC117\DDC117Reference r WHERE r.source = s)',
1662
            'SELECT t0."article_id" AS c0, t0."title" AS c1 FROM "DDC117Article" t0 WHERE EXISTS (SELECT t1."source_id", t1."target_id" FROM "DDC117Reference" t1 WHERE t1."source_id" = t0."article_id")'
1663
        );
1664
    }
1665
1666
    /**
1667
     * @group DDC-1474
1668
     */
1669
    public function testSelectWithArithmeticExpressionBeforeField() : void
1670
    {
1671
        $this->assertSqlGeneration(
1672
            'SELECT - e.value AS value, e.id FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
1673
            'SELECT -t0."value" AS c0, t0."id" AS c1 FROM "DDC1474Entity" t0'
1674
        );
1675
1676
        $this->assertSqlGeneration(
1677
            'SELECT e.id, + e.value AS value FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
1678
            'SELECT t0."id" AS c0, +t0."value" AS c1 FROM "DDC1474Entity" t0'
1679
        );
1680
    }
1681
1682
    /**
1683
     * @group DDC-1430
1684
     */
1685
    public function testGroupByAllFieldsWhenObjectHasForeignKeys() : void
1686
    {
1687
        $this->assertSqlGeneration(
1688
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u',
1689
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 GROUP BY t0."id", t0."status", t0."username", t0."name", t0."email_id"'
1690
        );
1691
1692
        $this->assertSqlGeneration(
1693
            'SELECT e FROM Doctrine\Tests\Models\CMS\CmsEmployee e GROUP BY e',
1694
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0 GROUP BY t0."id", t0."name", t0."spouse_id"'
1695
        );
1696
    }
1697
1698
    /**
1699
     * @group DDC-1236
1700
     */
1701
    public function testGroupBySupportsResultVariable() : void
1702
    {
1703
        $this->assertSqlGeneration(
1704
            'SELECT u, u.status AS st FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY st',
1705
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."status" AS c4 FROM "cms_users" t0 GROUP BY t0."status"'
1706
        );
1707
    }
1708
1709
    /**
1710
     * @group DDC-1236
1711
     */
1712
    public function testGroupBySupportsIdentificationVariable() : void
1713
    {
1714
        $this->assertSqlGeneration(
1715
            'SELECT u AS user FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY user',
1716
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 GROUP BY c0, c1, c2, c3'
1717
        );
1718
    }
1719
1720
    /**
1721
     * @group DDC-1213
1722
     */
1723
    public function testSupportsBitComparison() : void
1724
    {
1725
        $this->assertSqlGeneration(
1726
            'SELECT BIT_OR(4,2), BIT_AND(4,2), u FROM Doctrine\Tests\Models\CMS\CmsUser u',
1727
            'SELECT (4 | 2) AS c0, (4 & 2) AS c1, t0."id" AS c2, t0."status" AS c3, t0."username" AS c4, t0."name" AS c5 FROM "cms_users" t0'
1728
        );
1729
        $this->assertSqlGeneration(
1730
            'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_OR(u.id,2) > 0',
1731
            'SELECT (t0."id" | 2) AS c0, (t0."id" & 2) AS c1 FROM "cms_users" t0 WHERE (t0."id" | 2) > 0'
1732
        );
1733
        $this->assertSqlGeneration(
1734
            'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_AND(u.id , 4) > 0',
1735
            'SELECT (t0."id" | 2) AS c0, (t0."id" & 2) AS c1 FROM "cms_users" t0 WHERE (t0."id" & 4) > 0'
1736
        );
1737
        $this->assertSqlGeneration(
1738
            'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_OR(u.id , 2) > 0 OR BIT_AND(u.id , 4) > 0',
1739
            'SELECT (t0."id" | 2) AS c0, (t0."id" & 2) AS c1 FROM "cms_users" t0 WHERE (t0."id" | 2) > 0 OR (t0."id" & 4) > 0'
1740
        );
1741
    }
1742
1743
    /**
1744
     * @group DDC-1539
1745
     */
1746
    public function testParenthesesOnTheLeftHandOfComparison() : void
1747
    {
1748
        $this->assertSqlGeneration(
1749
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where ( (u.id + u.id) * u.id ) > 100',
1750
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE ((t0."id" + t0."id") * t0."id") > 100'
1751
        );
1752
        $this->assertSqlGeneration(
1753
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where (u.id + u.id) * u.id > 100',
1754
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" + t0."id") * t0."id" > 100'
1755
        );
1756
        $this->assertSqlGeneration(
1757
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where 100 < (u.id + u.id) * u.id ',
1758
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE 100 < (t0."id" + t0."id") * t0."id"'
1759
        );
1760
    }
1761
1762
    public function testSupportsParenthesisExpressionInSubSelect() : void
1763
    {
1764
        $this->assertSqlGeneration(
1765
            'SELECT u.id, (SELECT (1000*SUM(subU.id)/SUM(subU.id)) FROM Doctrine\Tests\Models\CMS\CmsUser subU where subU.id = u.id) AS subSelect FROM Doctrine\Tests\Models\CMS\CmsUser u',
1766
            'SELECT t0."id" AS c0, (SELECT (1000 * SUM(t1."id") / SUM(t1."id")) FROM "cms_users" t1 WHERE t1."id" = t0."id") AS c1 FROM "cms_users" t0'
1767
        );
1768
    }
1769
1770
    /**
1771
     * @group DDC-1557
1772
     */
1773
    public function testSupportsSubSqlFunction() : void
1774
    {
1775
        $this->assertSqlGeneration(
1776
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1777
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."name" IN (SELECT TRIM(t1."name") AS c4 FROM "cms_users" t1)'
1778
        );
1779
        $this->assertSqlGeneration(
1780
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2  WHERE LOWER(u2.name) LIKE \'%fabio%\')',
1781
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."name" IN (SELECT TRIM(t1."name") AS c4 FROM "cms_users" t1 WHERE LOWER(t1."name") LIKE \'%fabio%\')'
1782
        );
1783
        $this->assertSqlGeneration(
1784
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT TRIM(IDENTITY(u2.email)) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1785
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IN (SELECT TRIM(t1."email_id") AS c4 FROM "cms_users" t1)'
1786
        );
1787
        $this->assertSqlGeneration(
1788
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT IDENTITY(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1789
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IN (SELECT t1."email_id" AS c4 FROM "cms_users" t1)'
1790
        );
1791
        $this->assertSqlGeneration(
1792
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) = ( SELECT SUM(u2.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1793
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COUNT(t0."id") = (SELECT SUM(t1."id") AS c4 FROM "cms_users" t1)'
1794
        );
1795
        $this->assertSqlGeneration(
1796
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) <= ( SELECT SUM(u2.id) + COUNT(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1797
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COUNT(t0."id") <= (SELECT SUM(t1."id") + COUNT(t1."email_id") AS c4 FROM "cms_users" t1)'
1798
        );
1799
    }
1800
1801
    /**
1802
     * @group DDC-1574
1803
     */
1804
    public function testSupportsNewOperator() : void
1805
    {
1806
        $this->assertSqlGeneration(
1807
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a',
1808
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."city" AS c2 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id"'
1809
        );
1810
1811
        $this->assertSqlGeneration(
1812
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.id + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a',
1813
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."id" + t0."id" AS c2 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id"'
1814
        );
1815
1816
        $this->assertSqlGeneration(
1817
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p)) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p',
1818
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."city" AS c2, COUNT(t3."phonenumber") AS c3 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id" INNER JOIN "cms_phonenumbers" t3 ON t0."id" = t3."user_id"'
1819
        );
1820
1821
        $this->assertSqlGeneration(
1822
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p) + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p',
1823
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."city" AS c2, COUNT(t3."phonenumber") + t0."id" AS c3 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id" INNER JOIN "cms_phonenumbers" t3 ON t0."id" = t3."user_id"'
1824
        );
1825
1826
        $this->assertSqlGeneration(
1827
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(a.id, a.country, a.city), new Doctrine\Tests\Models\CMS\CmsAddressDTO(u.name, e.email) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a ORDER BY u.name',
1828
            'SELECT t0."id" AS c0, t0."country" AS c1, t0."city" AS c2, t1."name" AS c3, t2."email" AS c4 FROM "cms_users" t1 INNER JOIN "cms_emails" t2 ON t1."email_id" = t2."id" INNER JOIN "cms_addresses" t0 ON t1."id" = t0."user_id" ORDER BY t1."name" ASC'
1829
        );
1830
1831
        $this->assertSqlGeneration(
1832
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(a.id, (SELECT 1 FROM Doctrine\Tests\Models\CMS\CmsUser su), a.country, a.city), new Doctrine\Tests\Models\CMS\CmsAddressDTO(u.name, e.email) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a ORDER BY u.name',
1833
            'SELECT t0."id" AS c0, (SELECT 1 AS c2 FROM "cms_users" t1) AS c1, t0."country" AS c3, t0."city" AS c4, t2."name" AS c5, t3."email" AS c6 FROM "cms_users" t2 INNER JOIN "cms_emails" t3 ON t2."email_id" = t3."id" INNER JOIN "cms_addresses" t0 ON t2."id" = t0."user_id" ORDER BY t2."name" ASC'
1834
        );
1835
    }
1836
1837
    /**
1838
     * @group DDC-2234
1839
     */
1840
    public function testWhereFunctionIsNullComparisonExpression() : void
1841
    {
1842
        $this->assertSqlGeneration(
1843
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IS NULL',
1844
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IS NULL'
1845
        );
1846
1847
        $this->assertSqlGeneration(
1848
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NULLIF(u.name, \'FabioBatSilva\') IS NULL AND IDENTITY(u.email) IS NOT NULL',
1849
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE NULLIF(t0."name", \'FabioBatSilva\') IS NULL AND t0."email_id" IS NOT NULL'
1850
        );
1851
1852
        $this->assertSqlGeneration(
1853
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IS NOT NULL',
1854
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IS NOT NULL'
1855
        );
1856
1857
        $this->assertSqlGeneration(
1858
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NULLIF(u.name, \'FabioBatSilva\') IS NOT NULL',
1859
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE NULLIF(t0."name", \'FabioBatSilva\') IS NOT NULL'
1860
        );
1861
1862
        $this->assertSqlGeneration(
1863
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(u.name, u.id) IS NOT NULL',
1864
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COALESCE(t0."name", t0."id") IS NOT NULL'
1865
        );
1866
1867
        $this->assertSqlGeneration(
1868
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(u.id, IDENTITY(u.email)) IS NOT NULL',
1869
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COALESCE(t0."id", t0."email_id") IS NOT NULL'
1870
        );
1871
1872
        $this->assertSqlGeneration(
1873
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(IDENTITY(u.email), NULLIF(u.name, \'FabioBatSilva\')) IS NOT NULL',
1874
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COALESCE(t0."email_id", NULLIF(t0."name", \'FabioBatSilva\')) IS NOT NULL'
1875
        );
1876
    }
1877
1878
    public function testCustomTypeValueSql() : void
1879
    {
1880
        if (DBALType::hasType('negative_to_positive')) {
1881
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1882
        } else {
1883
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1884
        }
1885
1886
        $this->assertSqlGeneration(
1887
            'SELECT p.customInteger FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
1888
            'SELECT -(t0."customInteger") AS c0 FROM "customtype_parents" t0 WHERE t0."id" = 1'
1889
        );
1890
    }
1891
1892
    public function testCustomTypeValueSqlIgnoresIdentifierColumn() : void
1893
    {
1894
        if (DBALType::hasType('negative_to_positive')) {
1895
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1896
        } else {
1897
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1898
        }
1899
1900
        $this->assertSqlGeneration(
1901
            'SELECT p.id FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
1902
            'SELECT t0."id" AS c0 FROM "customtype_parents" t0 WHERE t0."id" = 1'
1903
        );
1904
    }
1905
1906
    public function testCustomTypeValueSqlForAllFields() : void
1907
    {
1908
        if (DBALType::hasType('negative_to_positive')) {
1909
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1910
        } else {
1911
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1912
        }
1913
1914
        $this->assertSqlGeneration(
1915
            'SELECT p FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
1916
            'SELECT t0."id" AS c0, -(t0."customInteger") AS c1 FROM "customtype_parents" t0'
1917
        );
1918
    }
1919
1920
    public function testCustomTypeValueSqlForPartialObject() : void
1921
    {
1922
        if (DBALType::hasType('negative_to_positive')) {
1923
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1924
        } else {
1925
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1926
        }
1927
1928
        $this->assertSqlGeneration(
1929
            'SELECT partial p.{id, customInteger} FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
1930
            'SELECT t0."id" AS c0, -(t0."customInteger") AS c1 FROM "customtype_parents" t0'
1931
        );
1932
    }
1933
1934
    /**
1935
     * @group DDC-1529
1936
     */
1937
    public function testMultipleFromAndInheritanceCondition() : void
1938
    {
1939
        $this->assertSqlGeneration(
1940
            'SELECT fix, flex FROM Doctrine\Tests\Models\Company\CompanyFixContract fix, Doctrine\Tests\Models\Company\CompanyFlexContract flex',
1941
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t1."id" AS c3, t1."completed" AS c4, t1."hoursWorked" AS c5, t1."pricePerHour" AS c6, t1."maxPrice" AS c7, t0."discr" AS c8, t1."discr" AS c9 FROM "company_contracts" t0, "company_contracts" t1 WHERE (t0."discr" IN (\'fix\') AND t1."discr" IN (\'flexible\', \'flexultra\'))'
1942
        );
1943
    }
1944
1945
    /**
1946
     * @group DDC-775
1947
     */
1948
    public function testOrderByClauseSupportsSimpleArithmeticExpression() : void
1949
    {
1950
        $this->assertSqlGeneration(
1951
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.id + 1 ',
1952
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY t0."id" + 1 ASC'
1953
        );
1954
        $this->assertSqlGeneration(
1955
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY ( ( (u.id + 1) * (u.id - 1) ) / 2)',
1956
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY (((t0."id" + 1) * (t0."id" - 1)) / 2) ASC'
1957
        );
1958
        $this->assertSqlGeneration(
1959
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY ((u.id + 5000) * u.id + 3) ',
1960
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY ((t0."id" + 5000) * t0."id" + 3) ASC'
1961
        );
1962
    }
1963
1964
    public function testOrderByClauseSupportsFunction() : void
1965
    {
1966
        $this->assertSqlGeneration(
1967
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY CONCAT(u.username, u.name) ',
1968
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY t0."username" || t0."name" ASC'
1969
        );
1970
    }
1971
1972
    /**
1973
     * @group DDC-1719
1974
     */
1975
    public function testStripNonAlphanumericCharactersFromAlias() : void
1976
    {
1977
        $this->assertSqlGeneration(
1978
            'SELECT e FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e',
1979
            'SELECT t0."simple-entity-id" AS c0, t0."simple-entity-value" AS c1 FROM "not-a-simple-entity" t0'
1980
        );
1981
1982
        $this->assertSqlGeneration(
1983
            'SELECT e.value FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e ORDER BY e.value',
1984
            'SELECT t0."simple-entity-value" AS c0 FROM "not-a-simple-entity" t0 ORDER BY t0."simple-entity-value" ASC'
1985
        );
1986
1987
        $this->assertSqlGeneration(
1988
            'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e ORDER BY e.value',
1989
            'SELECT TRIM(t0."simple-entity-value") AS c0 FROM "not-a-simple-entity" t0 ORDER BY t0."simple-entity-value" ASC'
1990
        );
1991
    }
1992
1993
    /**
1994
     * @group DDC-2435
1995
     */
1996
    public function testColumnNameWithNumbersAndNonAlphanumericCharacters() : void
1997
    {
1998
        $this->assertSqlGeneration(
1999
            'SELECT e FROM Doctrine\Tests\Models\Quote\NumericEntity e',
2000
            'SELECT t0."1:1" AS c0, t0."2:2" AS c1 FROM "table" t0'
2001
        );
2002
2003
        $this->assertSqlGeneration(
2004
            'SELECT e.value FROM Doctrine\Tests\Models\Quote\NumericEntity e',
2005
            'SELECT t0."2:2" AS c0 FROM "table" t0'
2006
        );
2007
2008
        $this->assertSqlGeneration(
2009
            'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Quote\NumericEntity e',
2010
            'SELECT TRIM(t0."2:2") AS c0 FROM "table" t0'
2011
        );
2012
    }
2013
2014
    /**
2015
     * @group DDC-1845
2016
     */
2017
    public function testQuotedTableDeclaration() : void
2018
    {
2019
        $this->assertSqlGeneration(
2020
            'SELECT u FROM Doctrine\Tests\Models\Quote\User u',
2021
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1 FROM "quote-user" t0'
2022
        );
2023
    }
2024
2025
    /**
2026
     * @group DDC-1845
2027
     */
2028
    public function testQuotedWalkJoinVariableDeclaration() : void
2029
    {
2030
        $this->assertSqlGeneration(
2031
            'SELECT u, a FROM Doctrine\Tests\Models\Quote\User u JOIN u.address a',
2032
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1, t1."address-id" AS c2, t1."address-zip" AS c3, t1."type" AS c4 FROM "quote-user" t0 INNER JOIN "quote-address" t1 ON t0."user-id" = t1."user-id" AND t1."type" IN (\'simple\', \'full\')'
2033
        );
2034
2035
        $this->assertSqlGeneration(
2036
            'SELECT u, p FROM Doctrine\Tests\Models\Quote\User u JOIN u.phones p',
2037
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1, t1."phone-number" AS c2 FROM "quote-user" t0 INNER JOIN "quote-phone" t1 ON t0."user-id" = t1."user-id"'
2038
        );
2039
2040
        $this->assertSqlGeneration(
2041
            'SELECT u, g FROM Doctrine\Tests\Models\Quote\User u JOIN u.groups g',
2042
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1, t1."group-id" AS c2, t1."group-name" AS c3 FROM "quote-user" t0 INNER JOIN "quote-users-groups" t2 ON t0."user-id" = t2."user-id" INNER JOIN "quote-group" t1 ON t1."group-id" = t2."group-id"'
2043
        );
2044
2045
        $this->assertSqlGeneration(
2046
            'SELECT a, u FROM Doctrine\Tests\Models\Quote\Address a JOIN a.user u',
2047
            'SELECT t0."address-id" AS c0, t0."address-zip" AS c1, t1."user-id" AS c2, t1."user-name" AS c3, t0."type" AS c4 FROM "quote-address" t0 INNER JOIN "quote-user" t1 ON t0."user-id" = t1."user-id" WHERE t0."type" IN (\'simple\', \'full\')'
2048
        );
2049
2050
        $this->assertSqlGeneration(
2051
            'SELECT g, u FROM Doctrine\Tests\Models\Quote\Group g JOIN g.users u',
2052
            'SELECT t0."group-id" AS c0, t0."group-name" AS c1, t1."user-id" AS c2, t1."user-name" AS c3 FROM "quote-group" t0 INNER JOIN "quote-users-groups" t2 ON t0."group-id" = t2."group-id" INNER JOIN "quote-user" t1 ON t1."user-id" = t2."user-id"'
2053
        );
2054
2055
        $this->assertSqlGeneration(
2056
            'SELECT g, p FROM Doctrine\Tests\Models\Quote\Group g JOIN g.parent p',
2057
            'SELECT t0."group-id" AS c0, t0."group-name" AS c1, t1."group-id" AS c2, t1."group-name" AS c3 FROM "quote-group" t0 INNER JOIN "quote-group" t1 ON t0."parent-id" = t1."group-id"'
2058
        );
2059
    }
2060
2061
    /**
2062
     * @group DDC-2208
2063
     */
2064
    public function testCaseThenParameterArithmeticExpression() : void
2065
    {
2066
        $this->assertSqlGeneration(
2067
            'SELECT SUM(CASE WHEN e.salary <= :value THEN e.salary - :value WHEN e.salary >= :value THEN :value - e.salary ELSE 0 END) FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
2068
            'SELECT SUM(CASE WHEN t0."salary" <= ? THEN t0."salary" - ? WHEN t0."salary" >= ? THEN ? - t0."salary" ELSE 0 END) AS c0 FROM "company_employees" t0 INNER JOIN "company_persons" t1 ON t0."id" = t1."id"'
2069
        );
2070
2071
        $this->assertSqlGeneration(
2072
            'SELECT SUM(CASE WHEN e.salary <= :value THEN e.salary - :value WHEN e.salary >= :value THEN :value - e.salary ELSE e.salary + 0 END) FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
2073
            'SELECT SUM(CASE WHEN t0."salary" <= ? THEN t0."salary" - ? WHEN t0."salary" >= ? THEN ? - t0."salary" ELSE t0."salary" + 0 END) AS c0 FROM "company_employees" t0 INNER JOIN "company_persons" t1 ON t0."id" = t1."id"'
2074
        );
2075
2076
        $this->assertSqlGeneration(
2077
            'SELECT SUM(CASE WHEN e.salary <= :value THEN (e.salary - :value) WHEN e.salary >= :value THEN (:value - e.salary) ELSE (e.salary + :value) END) FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
2078
            'SELECT SUM(CASE WHEN t0."salary" <= ? THEN (t0."salary" - ?) WHEN t0."salary" >= ? THEN (? - t0."salary") ELSE (t0."salary" + ?) END) AS c0 FROM "company_employees" t0 INNER JOIN "company_persons" t1 ON t0."id" = t1."id"'
2079
        );
2080
    }
2081
2082
    /**
2083
     * @group DDC-2268
2084
     */
2085
    public function testCaseThenFunction() : void
2086
    {
2087
        $this->assertSqlGeneration(
2088
            'SELECT CASE WHEN LENGTH(u.name) <> 0 THEN CONCAT(u.id, u.name) ELSE u.id END AS name  FROM Doctrine\Tests\Models\CMS\CmsUser u',
2089
            'SELECT CASE WHEN LENGTH(t0."name") <> 0 THEN t0."id" || t0."name" ELSE t0."id" END AS c0 FROM "cms_users" t0'
2090
        );
2091
2092
        $this->assertSqlGeneration(
2093
            'SELECT CASE WHEN LENGTH(u.name) <> LENGTH(TRIM(u.name)) THEN TRIM(u.name) ELSE u.name END AS name  FROM Doctrine\Tests\Models\CMS\CmsUser u',
2094
            'SELECT CASE WHEN LENGTH(t0."name") <> LENGTH(TRIM(t0."name")) THEN TRIM(t0."name") ELSE t0."name" END AS c0 FROM "cms_users" t0'
2095
        );
2096
2097
        $this->assertSqlGeneration(
2098
            'SELECT CASE WHEN LENGTH(u.name) > :value THEN SUBSTRING(u.name, 0, :value) ELSE TRIM(u.name) END AS name  FROM Doctrine\Tests\Models\CMS\CmsUser u',
2099
            'SELECT CASE WHEN LENGTH(t0."name") > ? THEN SUBSTRING(t0."name" FROM 0 FOR ?) ELSE TRIM(t0."name") END AS c0 FROM "cms_users" t0'
2100
        );
2101
    }
2102
2103
    /**
2104
     * @group DDC-2268
2105
     */
2106
    public function testSupportsMoreThanTwoParametersInConcatFunctionMySql() : void
2107
    {
2108
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
2109
2110
        $this->assertSqlGeneration(
2111
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, \'s\') = ?1',
2112
            'SELECT t0.`id` AS c0 FROM `cms_users` t0 WHERE CONCAT(t0.`name`, t0.`status`, \'s\') = ?'
2113
        );
2114
2115
        $this->assertSqlGeneration(
2116
            'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
2117
            'SELECT CONCAT(t0.`id`, t0.`name`, t0.`status`) AS c0 FROM `cms_users` t0 WHERE t0.`id` = ?'
2118
        );
2119
    }
2120
2121
    /**
2122
     * @group DDC-2268
2123
     */
2124
    public function testSupportsMoreThanTwoParametersInConcatFunctionPgSql() : void
2125
    {
2126
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
2127
2128
        $this->assertSqlGeneration(
2129
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, \'s\') = ?1',
2130
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE t0."name" || t0."status" || \'s\' = ?'
2131
        );
2132
2133
        $this->assertSqlGeneration(
2134
            'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
2135
            'SELECT t0."id" || t0."name" || t0."status" AS c0 FROM "cms_users" t0 WHERE t0."id" = ?'
2136
        );
2137
    }
2138
2139
    /**
2140
     * @group DDC-2268
2141
     */
2142
    public function testSupportsMoreThanTwoParametersInConcatFunctionSqlServer() : void
2143
    {
2144
        $this->em->getConnection()->setDatabasePlatform(new SQLServerPlatform());
2145
2146
        $this->assertSqlGeneration(
2147
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, \'s\') = ?1',
2148
            'SELECT t0.[id] AS c0 FROM [cms_users] t0 WHERE (t0.[name] + t0.[status] + \'s\') = ?'
2149
        );
2150
2151
        $this->assertSqlGeneration(
2152
            'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
2153
            'SELECT (t0.[id] + t0.[name] + t0.[status]) AS c0 FROM [cms_users] t0 WHERE t0.[id] = ?'
2154
        );
2155
    }
2156
2157
    /**
2158
     * @group DDC-2188
2159
     */
2160
    public function testArithmeticPriority() : void
2161
    {
2162
        $this->assertSqlGeneration(
2163
            'SELECT 100/(2*2) FROM Doctrine\Tests\Models\CMS\CmsUser u',
2164
            'SELECT 100 / (2 * 2) AS c0 FROM "cms_users" t0'
2165
        );
2166
2167
        $this->assertSqlGeneration(
2168
            'SELECT (u.id / (u.id * 2)) FROM Doctrine\Tests\Models\CMS\CmsUser u',
2169
            'SELECT (t0."id" / (t0."id" * 2)) AS c0 FROM "cms_users" t0'
2170
        );
2171
2172
        $this->assertSqlGeneration(
2173
            'SELECT 100/(2*2) + (u.id / (u.id * 2)) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id / (u.id * 2)) > 0',
2174
            'SELECT 100 / (2 * 2) + (t0."id" / (t0."id" * 2)) AS c0 FROM "cms_users" t0 WHERE (t0."id" / (t0."id" * 2)) > 0'
2175
        );
2176
    }
2177
2178
    /**
2179
     * @group DDC-2475
2180
     */
2181
    public function testOrderByClauseShouldReplaceOrderByRelationMapping() : void
2182
    {
2183
        $this->assertSqlGeneration(
2184
            'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b',
2185
            'SELECT t0."id" AS c0, t1."id" AS c1, t1."passengerName" AS c2 FROM "RoutingRoute" t0 INNER JOIN "RoutingRouteBooking" t1 ON t0."id" = t1."route_id" ORDER BY t1."passengerName" ASC'
2186
        );
2187
2188
        $this->assertSqlGeneration(
2189
            'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b ORDER BY b.passengerName DESC',
2190
            'SELECT t0."id" AS c0, t1."id" AS c1, t1."passengerName" AS c2 FROM "RoutingRoute" t0 INNER JOIN "RoutingRouteBooking" t1 ON t0."id" = t1."route_id" ORDER BY t1."passengerName" DESC'
2191
        );
2192
    }
2193
2194
    /**
2195
     * @group DDC-1858
2196
     */
2197
    public function testHavingSupportIsNullExpression() : void
2198
    {
2199
        $this->assertSqlGeneration(
2200
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING u.username IS NULL',
2201
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING t0."username" IS NULL'
2202
        );
2203
2204
        $this->assertSqlGeneration(
2205
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING MAX(u.name) IS NULL',
2206
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING MAX(t0."name") IS NULL'
2207
        );
2208
    }
2209
2210
    /**
2211
     * @group DDC-2506
2212
     */
2213
    public function testClassTableInheritanceJoinWithConditionAppliesToBaseTable() : void
2214
    {
2215
        $this->assertSqlGeneration(
2216
            'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1',
2217
            'SELECT t0."id" AS c0 FROM "company_organizations" t1 INNER JOIN ("company_events" t0 LEFT JOIN "company_auctions" t2 ON t0."id" = t2."id" LEFT JOIN "company_raffles" t3 ON t0."id" = t3."id") ON t1."id" = t0."org_id" AND (t0."id" = ?)',
2218
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
2219
        );
2220
    }
2221
2222
    /**
2223
     * @group DDC-2235
2224
     */
2225
    public function testSingleTableInheritanceLeftJoinWithCondition() : void
2226
    {
2227
        // Regression test for the bug
2228
        $this->assertSqlGeneration(
2229
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id',
2230
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id" LEFT JOIN "company_contracts" t0 ON (t0."salesPerson_id" = t2."id") AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2231
        );
2232
    }
2233
2234
    /**
2235
     * @group DDC-2235
2236
     */
2237
    public function testSingleTableInheritanceLeftJoinWithConditionAndWhere() : void
2238
    {
2239
        // Ensure other WHERE predicates are passed through to the main WHERE clause
2240
        $this->assertSqlGeneration(
2241
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id WHERE e.salary > 1000',
2242
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id" LEFT JOIN "company_contracts" t0 ON (t0."salesPerson_id" = t2."id") AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\') WHERE t1."salary" > 1000'
2243
        );
2244
    }
2245
2246
    /**
2247
     * @group DDC-2235
2248
     */
2249
    public function testSingleTableInheritanceInnerJoinWithCondition() : void
2250
    {
2251
        // Test inner joins too
2252
        $this->assertSqlGeneration(
2253
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e INNER JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id',
2254
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id" INNER JOIN "company_contracts" t0 ON (t0."salesPerson_id" = t2."id") AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2255
        );
2256
    }
2257
2258
    /**
2259
     * @group DDC-2235
2260
     */
2261
    public function testSingleTableInheritanceLeftJoinNonAssociationWithConditionAndWhere() : void
2262
    {
2263
        // Test that the discriminator IN() predicate is still added into
2264
        // the where clause when not joining onto that table
2265
        $this->assertSqlGeneration(
2266
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c LEFT JOIN Doctrine\Tests\Models\Company\CompanyEmployee e WITH e.id = c.salesPerson WHERE c.completed = true',
2267
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 LEFT JOIN ("company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id") ON (t2."id" = t0."salesPerson_id") WHERE (t0."completed" = 1) AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2268
        );
2269
    }
2270
2271
    /**
2272
     * @group DDC-2235
2273
     */
2274
    public function testSingleTableInheritanceJoinCreatesOnCondition() : void
2275
    {
2276
        // Test that the discriminator IN() predicate is still added
2277
        // into the where clause when not joining onto a single table inheritance entity
2278
        // via a join association
2279
        $this->assertSqlGeneration(
2280
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson s WHERE c.completed = true',
2281
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 INNER JOIN "company_employees" t1 ON t0."salesPerson_id" = t1."id" LEFT JOIN "company_persons" t2 ON t1."id" = t2."id" WHERE (t0."completed" = 1) AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2282
        );
2283
    }
2284
2285
    /**
2286
     * @group DDC-2235
2287
     */
2288
    public function testSingleTableInheritanceCreatesOnConditionAndWhere() : void
2289
    {
2290
        // Test that when joining onto an entity using single table inheritance via
2291
        // a join association that the discriminator IN() predicate is placed
2292
        // into the ON clause of the join
2293
        $this->assertSqlGeneration(
2294
            'SELECT e, COUNT(c) FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN e.contracts c WHERE e.department = :department',
2295
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, COUNT(t2."id") AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" INNER JOIN "company_contract_employees" t3 ON t1."id" = t3."employee_id" INNER JOIN "company_contracts" t2 ON t2."id" = t3."contract_id" AND t2."discr" IN (\'fix\', \'flexible\', \'flexultra\') WHERE t1."department" = ?',
2296
            [],
2297
            ['department' => 'foobar']
2298
        );
2299
    }
2300
2301
    /**
2302
     * @group DDC-1858
2303
     */
2304
    public function testHavingSupportResultVariableInExpression() : void
2305
    {
2306
        $this->assertSqlGeneration(
2307
            'SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo IN (?1)',
2308
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING c0 IN (?)'
2309
        );
2310
    }
2311
2312
    /**
2313
     * @group DDC-1858
2314
     */
2315
    public function testHavingSupportResultVariableLikeExpression() : void
2316
    {
2317
        $this->assertSqlGeneration(
2318
            'SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo LIKE \'3\'',
2319
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING c0 LIKE \'3\''
2320
        );
2321
    }
2322
2323
    /**
2324
     * @group DDC-3085
2325
     */
2326
    public function testHavingSupportResultVariableNullComparisonExpression() : void
2327
    {
2328
        $this->assertSqlGeneration(
2329
            'SELECT u AS user, SUM(a.id) AS score FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN Doctrine\Tests\Models\CMS\CmsAddress a WITH a.user = u GROUP BY u HAVING score IS NOT NULL AND score >= 5',
2330
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, SUM(t1."id") AS c4 FROM "cms_users" t0 LEFT JOIN "cms_addresses" t1 ON (t1."user_id" = t0."id") GROUP BY t0."id", t0."status", t0."username", t0."name", t0."email_id" HAVING c4 IS NOT NULL AND c4 >= 5'
2331
        );
2332
    }
2333
2334
    /**
2335
     * @group DDC-1858
2336
     */
2337
    public function testHavingSupportResultVariableInAggregateFunction() : void
2338
    {
2339
        $this->assertSqlGeneration(
2340
            'SELECT COUNT(u.name) AS countName FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING countName IS NULL',
2341
            'SELECT COUNT(t0."name") AS c0 FROM "cms_users" t0 HAVING c0 IS NULL'
2342
        );
2343
    }
2344
2345
    /**
2346
     * GitHub issue #4764: https://github.com/doctrine/orm/issues/4764
2347
     *
2348
     * @group DDC-3907
2349
     * @dataProvider mathematicOperatorsProvider
2350
     */
2351
    public function testHavingRegressionUsingVariableWithMathOperatorsExpression($operator) : void
2352
    {
2353
        $this->assertSqlGeneration(
2354
            'SELECT COUNT(u.name) AS countName FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING 1 ' . $operator . ' countName > 0',
2355
            'SELECT COUNT(t0."name") AS c0 FROM "cms_users" t0 HAVING 1 ' . $operator . ' c0 > 0'
2356
        );
2357
    }
2358
2359
    /**
2360
     * @return array
2361
     */
2362
    public function mathematicOperatorsProvider()
2363
    {
2364
        return [['+'], ['-'], ['*'], ['/']];
2365
    }
2366
}
2367
2368
class MyAbsFunction extends FunctionNode
2369
{
2370
    public $simpleArithmeticExpression;
2371
2372
    public function getSql(SqlWalker $sqlWalker)
2373
    {
2374
        return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')';
2375
    }
2376
2377
    public function parse(Parser $parser)
2378
    {
2379
        $lexer = $parser->getLexer();
0 ignored issues
show
Unused Code introduced by
The assignment to $lexer is dead and can be removed.
Loading history...
2380
2381
        $parser->match(Lexer::T_IDENTIFIER);
2382
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
2383
2384
        $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
2385
2386
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
2387
    }
2388
}
2389
/**
2390
 * @ORM\Entity
2391
 */
2392
class DDC1384Model
2393
{
2394
    /**
2395
     * @ORM\Id
2396
     * @ORM\Column(type="integer")
2397
     * @ORM\GeneratedValue
2398
     */
2399
    protected $aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo;
2400
}
2401
2402
2403
/**
2404
 * @ORM\Entity
2405
 */
2406
class DDC1474Entity
2407
{
2408
    /**
2409
     * @ORM\Id
2410
     * @ORM\Column(type="integer")
2411
     * @ORM\GeneratedValue()
2412
     */
2413
    protected $id;
2414
2415
    /** @ORM\Column(type="float") */
2416
    private $value;
2417
2418
    /**
2419
     * @param string $float
2420
     */
2421
    public function __construct($float)
2422
    {
2423
        $this->value = $float;
0 ignored issues
show
Documentation Bug introduced by
The property $value was declared of type double, but $float is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
2424
    }
2425
2426
    /**
2427
     * @return int
2428
     */
2429
    public function getId()
2430
    {
2431
        return $this->id;
2432
    }
2433
2434
    /**
2435
     * @return float
2436
     */
2437
    public function getValue()
2438
    {
2439
        return $this->value;
2440
    }
2441
2442
    /**
2443
     * @param float $value
2444
     */
2445
    public function setValue($value)
2446
    {
2447
        $this->value = $value;
2448
    }
2449
}
2450