Completed
Pull Request — master (#6476)
by Artem
11:15
created

testCustomFunctionWithinInExpression()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
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 function get_class;
28
29
class SelectSqlGenerationTest extends OrmTestCase
30
{
31
    private $em;
32
33
    protected function setUp() : void
34
    {
35
        $this->em = $this->getTestEntityManager();
36
    }
37
38
    /**
39
     * Assert a valid SQL generation.
40
     *
41
     * @param string $dqlToBeTested
42
     * @param string $sqlToBeConfirmed
43
     * @param array  $queryHints
44
     * @param array  $queryParams
45
     */
46
    public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = [], array $queryParams = [])
47
    {
48
        try {
49
            $query = $this->em->createQuery($dqlToBeTested);
50
51
            foreach ($queryParams as $name => $value) {
52
                $query->setParameter($name, $value);
53
            }
54
55
            $query
56
                ->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
57
                ->useQueryCache(false)
58
            ;
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
97
        foreach ($queryHints as $name => $value) {
98
            $query->setHint($name, $value);
99
        }
100
101
        $sql = $query->getSql();
102
        $query->free();
103
104
        // If we reached here, test failed
105
        $this->fail($sql);
106
    }
107
108
    /**
109
     * @group DDC-3697
110
     */
111
    public function testJoinWithRangeVariablePutsConditionIntoSqlWhereClause() : void
112
    {
113
        $this->assertSqlGeneration(
114
            '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',
115
            'SELECT t0."id" AS c0 FROM "company_persons" t0 INNER JOIN "company_persons" t1 WHERE t0."spouse_id" = t1."id" AND t1."id" = 42',
116
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
117
        );
118
    }
119
120
    /**
121
     * @group DDC-3697
122
     */
123
    public function testJoinWithRangeVariableAndInheritancePutsConditionIntoSqlWhereClause() : void
124
    {
125
        /*
126
         * Basically like the previous test, but this time load data for the inherited objects as well.
127
         * The important thing is that the ON clauses in LEFT JOINs only contain the conditions necessary to join the appropriate inheritance table
128
         * whereas the filtering condition must remain in the SQL WHERE clause.
129
         */
130
        $this->assertSqlGeneration(
131
            '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',
132
            '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',
133
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
134
        );
135
    }
136
137
    public function testSupportsSelectForAllFields() : void
138
    {
139
        $this->assertSqlGeneration(
140
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
141
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0'
142
        );
143
    }
144
145
    public function testSupportsSelectForOneField() : void
146
    {
147
        $this->assertSqlGeneration(
148
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u',
149
            'SELECT t0."id" AS c0 FROM "cms_users" t0'
150
        );
151
    }
152
153
    public function testSupportsSelectForOneNestedField() : void
154
    {
155
        $this->assertSqlGeneration(
156
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
157
            'SELECT t0."id" AS c0 FROM "cms_articles" t1 INNER JOIN "cms_users" t0 ON t1."user_id" = t0."id"'
158
        );
159
    }
160
161
    public function testSupportsSelectForAllNestedField() : void
162
    {
163
        $this->assertSqlGeneration(
164
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
165
            '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'
166
        );
167
    }
168
169
    public function testNotExistsExpression() : void
170
    {
171
        $this->assertSqlGeneration(
172
            '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)',
173
            '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)'
174
        );
175
    }
176
177
    public function testSupportsSelectForMultipleColumnsOfASingleComponent() : void
178
    {
179
        $this->assertSqlGeneration(
180
            'SELECT u.username, u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
181
            'SELECT t0."username" AS c0, t0."name" AS c1 FROM "cms_users" t0'
182
        );
183
    }
184
185
    public function testSupportsSelectUsingMultipleFromComponents() : void
186
    {
187
        $this->assertSqlGeneration(
188
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user',
189
            '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"'
190
        );
191
    }
192
193
    public function testSupportsJoinOnMultipleComponents() : void
194
    {
195
        $this->assertSqlGeneration(
196
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user',
197
            '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")'
198
        );
199
    }
200
201
    public function testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType() : void
202
    {
203
        $this->assertSqlGeneration(
204
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
205
            '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")'
206
        );
207
208
        $this->assertSqlGeneration(
209
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
210
            '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")'
211
        );
212
213
        $this->assertSqlGeneration(
214
            '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',
215
            '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\')'
216
        );
217
    }
218
219
    public function testSupportsSelectWithCollectionAssociationJoin() : void
220
    {
221
        $this->assertSqlGeneration(
222
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p',
223
            '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"'
224
        );
225
    }
226
227
    public function testSupportsSelectWithSingleValuedAssociationJoin() : void
228
    {
229
        $this->assertSqlGeneration(
230
            'SELECT u, a FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a',
231
            '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"'
232
        );
233
    }
234
235
    public function testSelectCorrelatedSubqueryComplexMathematicalExpression() : void
236
    {
237
        $this->assertSqlGeneration(
238
            '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',
239
            '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'
240
        );
241
    }
242
243
    public function testSelectComplexMathematicalExpression() : void
244
    {
245
        $this->assertSqlGeneration(
246
            'SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = ?1',
247
            '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" = ?'
248
        );
249
    }
250
251
    /* NOT (YET?) SUPPORTED.
252
       Can be supported if SimpleSelectExpression supports SingleValuedPathExpression instead of StateFieldPathExpression.
253
254
    public function testSingleAssociationPathExpressionInSubselect() : void
255
    {
256
        $this->assertSqlGeneration(
257
            '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',
258
            'SELECT (SELECT t0."user_id" FROM "cms_phonenumbers" t0 WHERE t0."user_id" = t1."id") AS c0 FROM "cms_users" t1 WHERE t1."id" = ?'
259
        );
260
    }*/
261
262
    /**
263
     * @group DDC-1077
264
     */
265
    public function testConstantValueInSelect() : void
266
    {
267
        $this->assertSqlGeneration(
268
            'SELECT u.name, \'foo\' AS bar FROM Doctrine\Tests\Models\CMS\CmsUser u',
269
            'SELECT t0."name" AS c0, \'foo\' AS c1 FROM "cms_users" t0'
270
        );
271
    }
272
273
    public function testSupportsOrderByWithAscAsDefault() : void
274
    {
275
        $this->assertSqlGeneration(
276
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id',
277
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" ASC'
278
        );
279
    }
280
281
    public function testSupportsOrderByAsc() : void
282
    {
283
        $this->assertSqlGeneration(
284
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id asc',
285
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" ASC'
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
626
        $this->assertSqlGeneration(
627
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.username IN (FOO(\'Lo\'), \'Lo\', :name)',
628
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."username" IN (ABS(\'Lo\'), \'Lo\', ?)'
629
        );
630
    }
631
632
    public function testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide() : void
633
    {
634
        // We do not support SingleValuedAssociationPathExpression on inverse side
635
        $this->assertInvalidSqlGeneration(
636
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IN (?1, ?2)',
637
            'Doctrine\ORM\Query\QueryException'
638
        );
639
    }
640
641
    public function testSupportsConcatFunctionMysql() : void
642
    {
643
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
644
645
        $this->assertSqlGeneration(
646
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, \'s\') = ?1',
647
            'SELECT t0.`id` AS c0 FROM `cms_users` t0 WHERE CONCAT(t0.`name`, \'s\') = ?'
648
        );
649
650
        $this->assertSqlGeneration(
651
            'SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
652
            'SELECT CONCAT(t0.`id`, t0.`name`) AS c0 FROM `cms_users` t0 WHERE t0.`id` = ?'
653
        );
654
    }
655
656
    public function testSupportsConcatFunctionPgSql() : void
657
    {
658
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
659
660
        $this->assertSqlGeneration(
661
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, \'s\') = ?1',
662
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE t0."name" || \'s\' = ?'
663
        );
664
665
        $this->assertSqlGeneration(
666
            'SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
667
            'SELECT t0."id" || t0."name" AS c0 FROM "cms_users" t0 WHERE t0."id" = ?'
668
        );
669
    }
670
671
    public function testSupportsExistsExpressionInWherePartWithCorrelatedSubquery() : void
672
    {
673
        $this->assertSqlGeneration(
674
            '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)',
675
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT t1."phonenumber" FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = t0."id")'
676
        );
677
    }
678
679
    /**
680
     * @group DDC-593
681
     */
682
    public function testSubqueriesInComparisonExpression() : void
683
    {
684
        $this->assertSqlGeneration(
685
            '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))',
686
            '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" = ?))'
687
        );
688
    }
689
690
    public function testSupportsMemberOfExpressionOneToMany() : void
691
    {
692
        // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...)
693
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
694
695
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
696
697
        $phone              = new CmsPhonenumber();
698
        $phone->phonenumber = 101;
699
        $q->setParameter('param', $phone);
700
701
        self::assertEquals(
702
            '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" = ?)',
703
            $q->getSql()
704
        );
705
    }
706
707
    public function testSupportsMemberOfExpressionManyToMany() : void
708
    {
709
        // "Get all users who are members of $group."
710
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
711
712
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
713
714
        $group     = new CmsGroup();
715
        $group->id = 101;
716
        $q->setParameter('param', $group);
717
718
        self::assertEquals(
719
            '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" = ?)',
720
            $q->getSql()
721
        );
722
    }
723
724
    public function testSupportsMemberOfExpressionManyToManyParameterArray() : void
725
    {
726
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
727
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
728
729
        $group      = new CmsGroup();
730
        $group->id  = 101;
731
        $group2     = new CmsGroup();
732
        $group2->id = 105;
733
        $q->setParameter('param', [$group, $group2]);
734
735
        self::assertEquals(
736
            '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" = ?)',
737
            $q->getSql()
738
        );
739
    }
740
741
    public function testSupportsMemberOfExpressionSelfReferencing() : void
742
    {
743
        // "Get all persons who have $person as a friend."
744
        // Tough one: Many-many self-referencing ("friends") with class table inheritance
745
        $q = $this->em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
746
747
        $person = new CompanyPerson();
748
749
        $unitOfWork = $this->em->getUnitOfWork();
750
        $persister  = $unitOfWork->getEntityPersister(get_class($person));
751
752
        $persister->setIdentifier($person, ['id' => 101]);
753
754
        $q->setParameter('param', $person);
755
756
        self::assertEquals(
757
            '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" = ?)',
758
            $q->getSql()
759
        );
760
    }
761
762
    public function testSupportsMemberOfWithSingleValuedAssociation() : void
763
    {
764
        // Impossible example, but it illustrates the purpose
765
        $this->assertSqlGeneration(
766
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.email MEMBER OF u.groups',
767
            '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")'
768
        );
769
    }
770
771
    public function testSupportsMemberOfWithIdentificationVariable() : void
772
    {
773
        // Impossible example, but it illustrates the purpose
774
        $this->assertSqlGeneration(
775
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u MEMBER OF u.groups',
776
            '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")'
777
        );
778
    }
779
780
    public function testSupportsCurrentDateFunction() : void
781
    {
782
        $this->assertSqlGeneration(
783
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()',
784
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_datetime" > CURRENT_DATE',
785
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
786
        );
787
    }
788
789
    public function testSupportsCurrentTimeFunction() : void
790
    {
791
        $this->assertSqlGeneration(
792
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()',
793
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_time" > CURRENT_TIME',
794
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
795
        );
796
    }
797
798
    public function testSupportsCurrentTimestampFunction() : void
799
    {
800
        $this->assertSqlGeneration(
801
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()',
802
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_datetime" > CURRENT_TIMESTAMP',
803
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
804
        );
805
    }
806
807
    public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition() : void
808
    {
809
        $this->assertSqlGeneration(
810
            // DQL
811
            // The result of this query consists of all employees whose spouses are also employees.
812
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
813
                WHERE EXISTS (
814
                    SELECT spouseEmp
815
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
816
                    WHERE spouseEmp = emp.spouse)',
817
            // SQL
818
            'SELECT DISTINCT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0'
819
                . ' WHERE EXISTS ('
820
                    . 'SELECT t1."id" FROM "cms_employees" t1 WHERE t1."id" = t0."spouse_id"'
821
                    . ')'
822
        );
823
    }
824
825
    public function testExistsExpressionWithSimpleSelectReturningScalar() : void
826
    {
827
        $this->assertSqlGeneration(
828
            // DQL
829
            // The result of this query consists of all employees whose spouses are also employees.
830
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
831
                WHERE EXISTS (
832
                    SELECT 1
833
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
834
                    WHERE spouseEmp = emp.spouse)',
835
            // SQL
836
            'SELECT DISTINCT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0'
837
                . ' WHERE EXISTS ('
838
                    . 'SELECT 1 AS c2 FROM "cms_employees" t1 WHERE t1."id" = t0."spouse_id"'
839
                    . ')'
840
        );
841
    }
842
843
    public function testLimitFromQueryClass() : void
844
    {
845
        $q = $this->em
846
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
847
            ->setMaxResults(10);
848
849
        self::assertEquals(
850
            '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',
851
            $q->getSql()
852
        );
853
    }
854
855
    public function testLimitAndOffsetFromQueryClass() : void
856
    {
857
        $q = $this->em
858
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
859
            ->setMaxResults(10)
860
            ->setFirstResult(0);
861
862
        // DBAL 2.8+ doesn't add OFFSET part when offset is 0
863
        self::assertThat(
864
            $q->getSql(),
865
            self::logicalOr(
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'),
867
                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')
868
            )
869
        );
870
    }
871
872
    public function testSizeFunction() : void
873
    {
874
        $this->assertSqlGeneration(
875
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1',
876
            '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'
877
        );
878
    }
879
880
    public function testSizeFunctionSupportsManyToMany() : void
881
    {
882
        $this->assertSqlGeneration(
883
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1',
884
            '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'
885
        );
886
    }
887
888
    public function testEmptyCollectionComparisonExpression() : void
889
    {
890
        $this->assertSqlGeneration(
891
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY',
892
            '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'
893
        );
894
        $this->assertSqlGeneration(
895
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS NOT EMPTY',
896
            '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'
897
        );
898
    }
899
900
    public function testNestedExpressions() : void
901
    {
902
        $this->assertSqlGeneration(
903
            'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)',
904
            '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)'
905
        );
906
    }
907
908
    public function testNestedExpressions2() : void
909
    {
910
        $this->assertSqlGeneration(
911
            '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',
912
            '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'
913
        );
914
    }
915
916
    public function testNestedExpressions3() : void
917
    {
918
        $this->assertSqlGeneration(
919
            '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))',
920
            '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))'
921
        );
922
    }
923
924
    public function testOrderByCollectionAssociationSize() : void
925
    {
926
        $this->assertSqlGeneration(
927
            'select u, size(u.articles) as numArticles from Doctrine\Tests\Models\CMS\CmsUser u order by numArticles',
928
            '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'
929
        );
930
    }
931
932
    public function testOrderBySupportsSingleValuedPathExpressionOwningSide() : void
933
    {
934
        $this->assertSqlGeneration(
935
            'select a from Doctrine\Tests\Models\CMS\CmsArticle a order by a.user',
936
            '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'
937
        );
938
    }
939
940
    /**
941
     * @expectedException \Doctrine\ORM\Query\QueryException
942
     */
943
    public function testOrderBySupportsSingleValuedPathExpressionInverseSide() : void
944
    {
945
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u order by u.address');
946
947
        $q->getSQL();
948
    }
949
950
    public function testBooleanLiteralInWhereOnSqlite() : void
951
    {
952
        $this->em->getConnection()->setDatabasePlatform(new SqlitePlatform());
953
954
        $this->assertSqlGeneration(
955
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true',
956
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = 1'
957
        );
958
959
        $this->assertSqlGeneration(
960
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false',
961
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = 0'
962
        );
963
    }
964
965
    public function testBooleanLiteralInWhereOnPostgres() : void
966
    {
967
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
968
969
        $this->assertSqlGeneration(
970
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true',
971
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = true'
972
        );
973
974
        $this->assertSqlGeneration(
975
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false',
976
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = false'
977
        );
978
    }
979
980
    public function testSingleValuedAssociationFieldInWhere() : void
981
    {
982
        $this->assertSqlGeneration(
983
            'SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1',
984
            'SELECT t0."phonenumber" AS c0 FROM "cms_phonenumbers" t0 WHERE t0."user_id" = ?'
985
        );
986
    }
987
988
    public function testSingleValuedAssociationNullCheckOnOwningSide() : void
989
    {
990
        $this->assertSqlGeneration(
991
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user IS NULL',
992
            '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'
993
        );
994
    }
995
996
    /**
997
     * Null check on inverse side has to happen through explicit JOIN.
998
     * 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IS NULL'
999
     * where the CmsUser is the inverse side is not supported.
1000
     */
1001
    public function testSingleValuedAssociationNullCheckOnInverseSide() : void
1002
    {
1003
        $this->assertSqlGeneration(
1004
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.address a WHERE a.id IS NULL',
1005
            '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'
1006
        );
1007
    }
1008
1009
    /**
1010
     * @group DDC-339
1011
     * @group DDC-1572
1012
     */
1013
    public function testStringFunctionLikeExpression() : void
1014
    {
1015
        $this->assertSqlGeneration(
1016
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE \'%foo OR bar%\'',
1017
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") LIKE \'%foo OR bar%\''
1018
        );
1019
        $this->assertSqlGeneration(
1020
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str',
1021
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") LIKE ?'
1022
        );
1023
        $this->assertSqlGeneration(
1024
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), \'_moo\') LIKE :str',
1025
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(t0."name") || \'_moo\' LIKE ?'
1026
        );
1027
1028
        // DDC-1572
1029
        $this->assertSqlGeneration(
1030
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(u.name) LIKE UPPER(:str)',
1031
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(t0."name") LIKE UPPER(?)'
1032
        );
1033
        $this->assertSqlGeneration(
1034
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) LIKE UPPER(LOWER(:str))',
1035
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(LOWER(t0."name")) LIKE UPPER(LOWER(?))'
1036
        );
1037
        $this->assertSqlGeneration(
1038
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE u.name',
1039
            '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")'
1040
        );
1041
    }
1042
1043
    /**
1044
     * @group DDC-1802
1045
     */
1046
    public function testStringFunctionNotLikeExpression() : void
1047
    {
1048
        $this->assertSqlGeneration(
1049
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) NOT LIKE \'%foo OR bar%\'',
1050
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") NOT LIKE \'%foo OR bar%\''
1051
        );
1052
1053
        $this->assertSqlGeneration(
1054
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) NOT LIKE UPPER(LOWER(:str))',
1055
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(LOWER(t0."name")) NOT LIKE UPPER(LOWER(?))'
1056
        );
1057
        $this->assertSqlGeneration(
1058
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic NOT LIKE u.name',
1059
            '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")'
1060
        );
1061
    }
1062
1063
    /**
1064
     * @group DDC-338
1065
     */
1066
    public function testOrderedCollectionFetchJoined() : void
1067
    {
1068
        $this->assertSqlGeneration(
1069
            'SELECT r, l FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.legs l',
1070
            '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'
1071
        );
1072
    }
1073
1074
    public function testSubselectInSelect() : void
1075
    {
1076
        $this->assertSqlGeneration(
1077
            '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\'',
1078
            '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\''
1079
        );
1080
    }
1081
1082
    /**
1083
     * @group locking
1084
     * @group DDC-178
1085
     */
1086
    public function testPessimisticWriteLockQueryHint() : void
1087
    {
1088
        if ($this->em->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) {
1089
            $this->markTestSkipped('SqLite does not support Row locking at all.');
1090
        }
1091
1092
        $this->assertSqlGeneration(
1093
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1094
            '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',
1095
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_WRITE]
1096
        );
1097
    }
1098
1099
    /**
1100
     * @group locking
1101
     * @group DDC-178
1102
     */
1103
    public function testPessimisticReadLockQueryHintPostgreSql() : void
1104
    {
1105
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
1106
1107
        $this->assertSqlGeneration(
1108
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1109
            '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',
1110
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1111
        );
1112
    }
1113
1114
    /**
1115
     * @group DDC-1693
1116
     * @group locking
1117
     */
1118
    public function testLockModeNoneQueryHint() : void
1119
    {
1120
        $this->assertSqlGeneration(
1121
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1122
            '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\'',
1123
            [ORMQuery::HINT_LOCK_MODE => LockMode::NONE]
1124
        );
1125
    }
1126
1127
    /**
1128
     * @group DDC-430
1129
     */
1130
    public function testSupportSelectWithMoreThan10InputParameters() : void
1131
    {
1132
        $this->assertSqlGeneration(
1133
            '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',
1134
            '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" = ?'
1135
        );
1136
    }
1137
1138
    /**
1139
     * @group locking
1140
     * @group DDC-178
1141
     */
1142
    public function testPessimisticReadLockQueryHintMySql() : void
1143
    {
1144
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
1145
1146
        $this->assertSqlGeneration(
1147
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1148
            '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',
1149
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1150
        );
1151
    }
1152
1153
    /**
1154
     * @group locking
1155
     * @group DDC-178
1156
     */
1157
    public function testPessimisticReadLockQueryHintOracle() : void
1158
    {
1159
        $this->em->getConnection()->setDatabasePlatform(new OraclePlatform());
1160
1161
        $this->assertSqlGeneration(
1162
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1163
            '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',
1164
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1165
        );
1166
    }
1167
1168
    /**
1169
     * @group DDC-431
1170
     */
1171
    public function testSupportToCustomDQLFunctions() : void
1172
    {
1173
        $config = $this->em->getConfiguration();
1174
        $config->addCustomNumericFunction('MYABS', MyAbsFunction::class);
1175
1176
        $this->assertSqlGeneration(
1177
            'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
1178
            'SELECT ABS(t0."phonenumber") AS c0 FROM "cms_phonenumbers" t0'
1179
        );
1180
1181
        $config->setCustomNumericFunctions([]);
1182
    }
1183
1184
    /**
1185
     * @group DDC-826
1186
     */
1187
    public function testMappedSuperclassAssociationJoin() : void
1188
    {
1189
        $this->assertSqlGeneration(
1190
            'SELECT f FROM Doctrine\Tests\Models\DirectoryTree\File f JOIN f.parentDirectory d WHERE f.id = ?1',
1191
            '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" = ?'
1192
        );
1193
    }
1194
1195
    /**
1196
     * @group DDC-1053
1197
     */
1198
    public function testGroupBy() : void
1199
    {
1200
        $this->assertSqlGeneration(
1201
            'SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id',
1202
            '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"'
1203
        );
1204
    }
1205
1206
    /**
1207
     * @group DDC-1053
1208
     */
1209
    public function testGroupByIdentificationVariable() : void
1210
    {
1211
        $this->assertSqlGeneration(
1212
            'SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g',
1213
            '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"'
1214
        );
1215
    }
1216
1217
    public function testCaseContainingNullIf() : void
1218
    {
1219
        $this->assertSqlGeneration(
1220
            'SELECT NULLIF(g.id, g.name) AS NullIfEqual FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1221
            'SELECT NULLIF(t0."id", t0."name") AS c0 FROM "cms_groups" t0'
1222
        );
1223
    }
1224
1225
    public function testCaseContainingCoalesce() : void
1226
    {
1227
        $this->assertSqlGeneration(
1228
            'SELECT COALESCE(NULLIF(u.name, \'\'), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u',
1229
            'SELECT COALESCE(NULLIF(t0."name", \'\'), t0."username") AS c0 FROM "cms_users" t0'
1230
        );
1231
    }
1232
1233
    /**
1234
     * Test that the right discriminator data is inserted in a subquery.
1235
     */
1236
    public function testSubSelectDiscriminator() : void
1237
    {
1238
        $this->assertSqlGeneration(
1239
            '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',
1240
            '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'
1241
        );
1242
    }
1243
1244
    public function testIdVariableResultVariableReuse() : void
1245
    {
1246
        $exceptionThrown = false;
1247
1248
        try {
1249
            $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)');
1250
1251
            $query->getSql();
1252
            $query->free();
1253
        } catch (\Exception $e) {
1254
            $exceptionThrown = true;
1255
        }
1256
1257
        self::assertTrue($exceptionThrown);
1258
    }
1259
1260
    public function testSubSelectAliasesFromOuterQuery() : void
1261
    {
1262
        $this->assertSqlGeneration(
1263
            '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',
1264
            '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'
1265
        );
1266
    }
1267
1268
    public function testSubSelectAliasesFromOuterQueryWithSubquery() : void
1269
    {
1270
        $this->assertSqlGeneration(
1271
            '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',
1272
            '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'
1273
        );
1274
    }
1275
1276
    public function testSubSelectAliasesFromOuterQueryReuseInWhereClause() : void
1277
    {
1278
        $this->assertSqlGeneration(
1279
            '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',
1280
            '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 = ?'
1281
        );
1282
    }
1283
1284
    /**
1285
     * @group DDC-1298
1286
     */
1287
    public function testSelectForeignKeyPKWithoutFields() : void
1288
    {
1289
        $this->assertSqlGeneration(
1290
            'SELECT t, s, l FROM Doctrine\Tests\Models\DDC117\DDC117Link l INNER JOIN l.target t INNER JOIN l.source s',
1291
            '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"'
1292
        );
1293
    }
1294
1295
    public function testGeneralCaseWithSingleWhenClause() : void
1296
    {
1297
        $this->assertSqlGeneration(
1298
            'SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1299
            'SELECT t0."id" AS c0, CASE WHEN ((t0."id" / 2) > 18) THEN 1 ELSE 0 END AS c1 FROM "cms_groups" t0'
1300
        );
1301
    }
1302
1303
    public function testGeneralCaseWithMultipleWhenClause() : void
1304
    {
1305
        $this->assertSqlGeneration(
1306
            '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',
1307
            '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'
1308
        );
1309
    }
1310
1311
    public function testSimpleCaseWithSingleWhenClause() : void
1312
    {
1313
        $this->assertSqlGeneration(
1314
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = CASE g.name WHEN \'admin\' THEN 1 ELSE 2 END',
1315
            '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'
1316
        );
1317
    }
1318
1319
    public function testSimpleCaseWithMultipleWhenClause() : void
1320
    {
1321
        $this->assertSqlGeneration(
1322
            '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)',
1323
            '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)'
1324
        );
1325
    }
1326
1327
    public function testGeneralCaseWithSingleWhenClauseInSubselect() : void
1328
    {
1329
        $this->assertSqlGeneration(
1330
            '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)',
1331
            '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)'
1332
        );
1333
    }
1334
1335
    public function testGeneralCaseWithMultipleWhenClauseInSubselect() : void
1336
    {
1337
        $this->assertSqlGeneration(
1338
            '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)',
1339
            '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)'
1340
        );
1341
    }
1342
1343
    public function testSimpleCaseWithSingleWhenClauseInSubselect() : void
1344
    {
1345
        $this->assertSqlGeneration(
1346
            '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)',
1347
            '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)'
1348
        );
1349
    }
1350
1351
    public function testSimpleCaseWithMultipleWhenClauseInSubselect() : void
1352
    {
1353
        $this->assertSqlGeneration(
1354
            '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)',
1355
            '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)'
1356
        );
1357
    }
1358
1359
    /**
1360
     * @group DDC-1696
1361
     */
1362
    public function testSimpleCaseWithStringPrimary() : void
1363
    {
1364
        $this->assertSqlGeneration(
1365
            'SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN \'Foo\' ELSE \'Bar\' END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1366
            'SELECT t0."id" AS c0, CASE WHEN ((t0."id" / 2) > 18) THEN \'Foo\' ELSE \'Bar\' END AS c1 FROM "cms_groups" t0'
1367
        );
1368
    }
1369
1370
    /**
1371
     * @group DDC-2205
1372
     */
1373
    public function testCaseNegativeValuesInThenExpression() : void
1374
    {
1375
        $this->assertSqlGeneration(
1376
            'SELECT CASE g.name WHEN \'admin\' THEN - 1 ELSE - 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1377
            'SELECT CASE t0."name" WHEN \'admin\' THEN -1 ELSE -2 END AS c0 FROM "cms_groups" t0'
1378
        );
1379
1380
        $this->assertSqlGeneration(
1381
            'SELECT CASE g.name WHEN \'admin\' THEN  - 2 WHEN \'guest\' THEN - 1 ELSE 0 END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1382
            'SELECT CASE t0."name" WHEN \'admin\' THEN -2 WHEN \'guest\' THEN -1 ELSE 0 END AS c0 FROM "cms_groups" t0'
1383
        );
1384
1385
        $this->assertSqlGeneration(
1386
            'SELECT CASE g.name WHEN \'admin\' THEN (- 1) ELSE (- 2) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1387
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-1) ELSE (-2) END AS c0 FROM "cms_groups" t0'
1388
        );
1389
1390
        $this->assertSqlGeneration(
1391
            'SELECT CASE g.name WHEN \'admin\' THEN ( - :value) ELSE ( + :value) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1392
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-?) ELSE (+?) END AS c0 FROM "cms_groups" t0'
1393
        );
1394
1395
        $this->assertSqlGeneration(
1396
            'SELECT CASE g.name WHEN \'admin\' THEN ( - g.id) ELSE ( + g.id) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1397
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-t0."id") ELSE (+t0."id") END AS c0 FROM "cms_groups" t0'
1398
        );
1399
    }
1400
1401
    public function testIdentityFunctionWithCompositePrimaryKey() : void
1402
    {
1403
        $this->assertSqlGeneration(
1404
            'SELECT IDENTITY(p.poi, \'long\') AS long FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1405
            'SELECT t0."poi_long" AS c0 FROM "navigation_photos" t0'
1406
        );
1407
1408
        $this->assertSqlGeneration(
1409
            'SELECT IDENTITY(p.poi, \'lat\') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1410
            'SELECT t0."poi_lat" AS c0 FROM "navigation_photos" t0'
1411
        );
1412
1413
        $this->assertSqlGeneration(
1414
            'SELECT IDENTITY(p.poi, \'long\') AS long, IDENTITY(p.poi, \'lat\') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1415
            'SELECT t0."poi_long" AS c0, t0."poi_lat" AS c1 FROM "navigation_photos" t0'
1416
        );
1417
1418
        $this->assertInvalidSqlGeneration(
1419
            'SELECT IDENTITY(p.poi, \'invalid\') AS invalid FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1420
            QueryException::class
1421
        );
1422
    }
1423
1424
    /**
1425
     * @group DDC-2519
1426
     */
1427
    public function testPartialWithAssociationIdentifier() : void
1428
    {
1429
        $this->assertSqlGeneration(
1430
            'SELECT PARTIAL l.{source, target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l',
1431
            'SELECT t0."iUserIdSource" AS c0, t0."iUserIdTarget" AS c1 FROM "legacy_users_reference" t0'
1432
        );
1433
1434
        $this->assertSqlGeneration(
1435
            'SELECT PARTIAL l.{description, source, target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l',
1436
            'SELECT t0."description" AS c0, t0."iUserIdSource" AS c1, t0."iUserIdTarget" AS c2 FROM "legacy_users_reference" t0'
1437
        );
1438
    }
1439
1440
    /**
1441
     * @group DDC-1339
1442
     */
1443
    public function testIdentityFunctionInSelectClause() : void
1444
    {
1445
        $this->assertSqlGeneration(
1446
            'SELECT IDENTITY(u.email) as email_id FROM Doctrine\Tests\Models\CMS\CmsUser u',
1447
            'SELECT t0."email_id" AS c0 FROM "cms_users" t0'
1448
        );
1449
    }
1450
1451
    public function testIdentityFunctionInJoinedSubclass() : void
1452
    {
1453
        //relation is in the subclass (CompanyManager) we are querying
1454
        $this->assertSqlGeneration(
1455
            'SELECT m, IDENTITY(m.car) as car_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1456
            '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"'
1457
        );
1458
1459
        //relation is in the base class (CompanyPerson).
1460
        $this->assertSqlGeneration(
1461
            'SELECT m, IDENTITY(m.spouse) as spouse_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1462
            '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"'
1463
        );
1464
    }
1465
1466
    /**
1467
     * @group DDC-1339
1468
     */
1469
    public function testIdentityFunctionDoesNotAcceptStateField() : void
1470
    {
1471
        $this->assertInvalidSqlGeneration(
1472
            'SELECT IDENTITY(u.name) as name FROM Doctrine\Tests\Models\CMS\CmsUser u',
1473
            QueryException::class
1474
        );
1475
    }
1476
1477
    /**
1478
     * @group DDC-1389
1479
     */
1480
    public function testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad() : void
1481
    {
1482
        $this->assertSqlGeneration(
1483
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1484
            '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"',
1485
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1486
        );
1487
    }
1488
1489
    /**
1490
     * @group DDC-1389
1491
     */
1492
    public function testInheritanceTypeJoinInRootClassWithEnabledForcePartialLoad() : void
1493
    {
1494
        $this->assertSqlGeneration(
1495
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1496
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0',
1497
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1498
        );
1499
    }
1500
1501
    /**
1502
     * @group DDC-1389
1503
     */
1504
    public function testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad() : void
1505
    {
1506
        $this->assertSqlGeneration(
1507
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1508
            '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"',
1509
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1510
        );
1511
    }
1512
1513
    /**
1514
     * @group DDC-1389
1515
     */
1516
    public function testInheritanceTypeJoinInChildClassWithEnabledForcePartialLoad() : void
1517
    {
1518
        $this->assertSqlGeneration(
1519
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1520
            '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"',
1521
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1522
        );
1523
    }
1524
1525
    /**
1526
     * @group DDC-1389
1527
     */
1528
    public function testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad() : void
1529
    {
1530
        $this->assertSqlGeneration(
1531
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1532
            '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"',
1533
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1534
        );
1535
    }
1536
1537
    /**
1538
     * @group DDC-1389
1539
     */
1540
    public function testInheritanceTypeJoinInLeafClassWithEnabledForcePartialLoad() : void
1541
    {
1542
        $this->assertSqlGeneration(
1543
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1544
            '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"',
1545
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1546
        );
1547
    }
1548
1549
    /**
1550
     * @group DDC-1389
1551
     */
1552
    public function testInheritanceTypeSingleTableInRootClassWithDisabledForcePartialLoad() : void
1553
    {
1554
        $this->assertSqlGeneration(
1555
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1556
            '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\')',
1557
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1558
        );
1559
    }
1560
1561
    /**
1562
     * @group DDC-1389
1563
     */
1564
    public function testInheritanceTypeSingleTableInRootClassWithEnabledForcePartialLoad() : void
1565
    {
1566
        $this->assertSqlGeneration(
1567
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1568
            '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\')',
1569
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1570
        );
1571
    }
1572
1573
    /**
1574
     * @group DDC-1389
1575
     */
1576
    public function testInheritanceTypeSingleTableInChildClassWithDisabledForcePartialLoad() : void
1577
    {
1578
        $this->assertSqlGeneration(
1579
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1580
            '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\')',
1581
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1582
        );
1583
    }
1584
1585
    /**
1586
     * @group DDC-1389
1587
     */
1588
    public function testInheritanceTypeSingleTableInChildClassWithEnabledForcePartialLoad() : void
1589
    {
1590
        $this->assertSqlGeneration(
1591
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1592
            '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\')',
1593
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1594
        );
1595
    }
1596
1597
    /**
1598
     * @group DDC-1389
1599
     */
1600
    public function testInheritanceTypeSingleTableInLeafClassWithDisabledForcePartialLoad() : void
1601
    {
1602
        $this->assertSqlGeneration(
1603
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1604
            '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\')',
1605
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1606
        );
1607
    }
1608
1609
    /**
1610
     * @group DDC-1389
1611
     */
1612
    public function testInheritanceTypeSingleTableInLeafClassWithEnabledForcePartialLoad() : void
1613
    {
1614
        $this->assertSqlGeneration(
1615
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1616
            '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\')',
1617
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1618
        );
1619
    }
1620
1621
    /**
1622
     * @group DDC-1161
1623
     */
1624
    public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias() : void
1625
    {
1626
        $this->assertSqlGeneration(
1627
            'SELECT p, pp FROM Doctrine\Tests\Models\Company\CompanyPerson p JOIN p.spouse pp',
1628
            '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"',
1629
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1630
        );
1631
    }
1632
1633
    /**
1634
     * @group DDC-1384
1635
     */
1636
    public function testAliasDoesNotExceedPlatformDefinedLength() : void
1637
    {
1638
        $this->assertSqlGeneration(
1639
            'SELECT m FROM ' . __NAMESPACE__ . '\\DDC1384Model m',
1640
            'SELECT t0."aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" AS c0 FROM "DDC1384Model" t0'
1641
        );
1642
    }
1643
1644
    /**
1645
     * @group DDC-331
1646
     * @group DDC-1384
1647
     */
1648
    public function testIssue331() : void
1649
    {
1650
        $this->assertSqlGeneration(
1651
            'SELECT e.name FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1652
            'SELECT t0."name" AS c0 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id"'
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/doctrine2/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