Failed Conditions
Pull Request — master (#6143)
by Luís
10:34
created

assertInvalidSqlGeneration()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
c 0
b 0
f 0
rs 9.0856
cc 3
eloc 12
nc 4
nop 4
1
<?php
2
3
namespace Doctrine\Tests\ORM\Query;
4
5
use Doctrine\DBAL\LockMode;
6
use Doctrine\DBAL\Platforms\MySqlPlatform;
7
use Doctrine\DBAL\Platforms\OraclePlatform;
8
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
9
use Doctrine\DBAL\Platforms\SqlitePlatform;
10
use Doctrine\DBAL\Platforms\SQLServerPlatform;
11
use Doctrine\DBAL\Types\Type as DBALType;
12
use Doctrine\ORM\Query as ORMQuery;
13
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
14
use Doctrine\ORM\Query\Lexer;
15
use Doctrine\ORM\Query\Parser;
16
use Doctrine\ORM\Query\QueryException;
17
use Doctrine\ORM\Query\SqlWalker;
18
use Doctrine\Tests\DbalTypes\NegativeToPositiveType;
19
use Doctrine\Tests\Models\CMS\CmsGroup;
20
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
21
use Doctrine\Tests\Models\Company\CompanyEmployee;
22
use Doctrine\Tests\Models\Company\CompanyPerson;
23
use Doctrine\Tests\OrmTestCase;
24
25
class SelectSqlGenerationTest extends OrmTestCase
26
{
27
    private $_em;
28
29
    protected function setUp()
30
    {
31
        $this->_em = $this->_getTestEntityManager();
32
    }
33
34
    /**
35
     * Assert a valid SQL generation.
36
     *
37
     * @param string $dqlToBeTested
38
     * @param string $sqlToBeConfirmed
39
     * @param array $queryHints
40
     * @param array $queryParams
41
     */
42
    public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = [], array $queryParams = [])
43
    {
44
        try {
45
            $query = $this->_em->createQuery($dqlToBeTested);
46
47
            foreach ($queryParams AS $name => $value) {
48
                $query->setParameter($name, $value);
49
            }
50
51
            $query->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
52
                  ->useQueryCache(false);
53
54
            foreach ($queryHints AS $name => $value) {
55
                $query->setHint($name, $value);
56
            }
57
58
            $sqlGenerated = $query->getSQL();
59
60
            parent::assertEquals(
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (assertEquals() instead of assertSqlGeneration()). Are you sure this is correct? If so, you might want to change this to $this->assertEquals().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
61
                $sqlToBeConfirmed,
62
                $sqlGenerated,
63
                sprintf('"%s" is not equal of "%s"', $sqlGenerated, $sqlToBeConfirmed)
64
            );
65
66
            $query->free();
67
        } catch (\Exception $e) {
68
            $this->fail($e->getMessage() ."\n".$e->getTraceAsString());
69
        }
70
    }
71
72
    /**
73
     * Asser an invalid SQL generation.
74
     *
75
     * @param string $dqlToBeTested
76
     * @param string $expectedException
77
     * @param array $queryHints
78
     * @param array $queryParams
79
     */
80
    public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = [], array $queryParams = [])
81
    {
82
        $this->expectException($expectedException);
83
84
        $query = $this->_em->createQuery($dqlToBeTested);
85
86
        foreach ($queryParams AS $name => $value) {
87
            $query->setParameter($name, $value);
88
        }
89
90
        $query->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
91
              ->useQueryCache(false);
92
93
        foreach ($queryHints AS $name => $value) {
94
            $query->setHint($name, $value);
95
        }
96
97
        $sql = $query->getSql();
98
        $query->free();
99
100
        // If we reached here, test failed
101
        $this->fail($sql);
0 ignored issues
show
Documentation introduced by
$sql is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
102
    }
103
104
    /**
105
     * @group DDC-3697
106
     */
107
    public function testJoinWithRangeVariablePutsConditionIntoSqlWhereClause()
108
    {
109
        $this->assertSqlGeneration(
110
            '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',
111
            'SELECT c0_.id AS id_0 FROM company_persons c0_ INNER JOIN company_persons c1_ WHERE c0_.spouse_id = c1_.id AND c1_.id = 42',
112
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
113
        );
114
    }
115
116
    /**
117
     * @group DDC-3697
118
     */
119
    public function testJoinWithRangeVariableAndInheritancePutsConditionIntoSqlWhereClause()
120
    {
121
        /*
122
         * Basically like the previous test, but this time load data for the inherited objects as well.
123
         * The important thing is that the ON clauses in LEFT JOINs only contain the conditions necessary to join the appropriate inheritance table
124
         * whereas the filtering condition must remain in the SQL WHERE clause.
125
         */
126
        $this->assertSqlGeneration(
127
            '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',
128
            'SELECT c0_.id AS id_0 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id INNER JOIN company_persons c3_ LEFT JOIN company_managers c4_ ON c3_.id = c4_.id LEFT JOIN company_employees c5_ ON c3_.id = c5_.id WHERE c0_.spouse_id = c3_.id AND c3_.id = 42',
129
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
130
        );
131
    }
132
133
    public function testSupportsSelectForAllFields()
134
    {
135
        $this->assertSqlGeneration(
136
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
137
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_'
138
        );
139
    }
140
141
    public function testSupportsSelectForOneField()
142
    {
143
        $this->assertSqlGeneration(
144
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u',
145
            'SELECT c0_.id AS id_0 FROM cms_users c0_'
146
        );
147
    }
148
149
    public function testSupportsSelectForOneNestedField()
150
    {
151
        $this->assertSqlGeneration(
152
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
153
            'SELECT c0_.id AS id_0 FROM cms_articles c1_ INNER JOIN cms_users c0_ ON c1_.user_id = c0_.id'
154
        );
155
    }
156
157
    public function testSupportsSelectForAllNestedField()
158
    {
159
        $this->assertSqlGeneration(
160
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
161
            'SELECT c0_.id AS id_0, c0_.topic AS topic_1, c0_.text AS text_2, c0_.version AS version_3 FROM cms_articles c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id ORDER BY c1_.name ASC'
162
        );
163
    }
164
165
    public function testNotExistsExpression()
166
    {
167
        $this->assertSqlGeneration(
168
            '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)',
169
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE NOT EXISTS (SELECT c1_.phonenumber FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234)'
170
        );
171
    }
172
173
    public function testSupportsSelectForMultipleColumnsOfASingleComponent()
174
    {
175
        $this->assertSqlGeneration(
176
            'SELECT u.username, u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
177
            'SELECT c0_.username AS username_0, c0_.name AS name_1 FROM cms_users c0_'
178
        );
179
    }
180
181
    public function testSupportsSelectUsingMultipleFromComponents()
182
    {
183
        $this->assertSqlGeneration(
184
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user',
185
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c1_.phonenumber AS phonenumber_4 FROM cms_users c0_, cms_phonenumbers c1_ WHERE c0_.id = c1_.user_id'
186
        );
187
    }
188
189
    public function testSupportsJoinOnMultipleComponents()
190
    {
191
        $this->assertSqlGeneration(
192
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user',
193
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c1_.phonenumber AS phonenumber_4 FROM cms_users c0_ INNER JOIN cms_phonenumbers c1_ ON (c0_.id = c1_.user_id)'
194
        );
195
    }
196
197
    public function testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType()
198
    {
199
        $this->assertSqlGeneration(
200
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
201
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id INNER JOIN company_managers c2_ INNER JOIN company_employees c4_ ON c2_.id = c4_.id INNER JOIN company_persons c3_ ON c2_.id = c3_.id AND (c0_.id = c3_.id)'
202
        );
203
204
        $this->assertSqlGeneration(
205
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
206
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ INNER JOIN company_employees c4_ ON c2_.id = c4_.id INNER JOIN company_persons c3_ ON c2_.id = c3_.id ON (c0_.id = c3_.id)'
207
        );
208
    }
209
210
    public function testSupportsSelectWithCollectionAssociationJoin()
211
    {
212
        $this->assertSqlGeneration(
213
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p',
214
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c1_.phonenumber AS phonenumber_4 FROM cms_users c0_ INNER JOIN cms_phonenumbers c1_ ON c0_.id = c1_.user_id'
215
        );
216
    }
217
218
    public function testSupportsSelectWithSingleValuedAssociationJoin()
219
    {
220
        $this->assertSqlGeneration(
221
            'SELECT u, a FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a',
222
            'SELECT f0_.id AS id_0, f0_.username AS username_1, f1_.id AS id_2 FROM forum_users f0_ INNER JOIN forum_avatars f1_ ON f0_.avatar_id = f1_.id'
223
        );
224
    }
225
226
    public function testSelectCorrelatedSubqueryComplexMathematicalExpression()
227
    {
228
        $this->assertSqlGeneration(
229
            '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',
230
            'SELECT (SELECT (count(c0_.phonenumber) + 5) * 10 AS sclr_1 FROM cms_phonenumbers c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id WHERE c1_.id = c2_.id) AS sclr_0 FROM cms_users c2_'
231
        );
232
    }
233
234
    public function testSelectComplexMathematicalExpression()
235
    {
236
        $this->assertSqlGeneration(
237
            'SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = ?1',
238
            'SELECT (count(c0_.phonenumber) + 5) * 10 AS sclr_0 FROM cms_phonenumbers c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id WHERE c1_.id = ?'
239
        );
240
    }
241
242
    /* NOT (YET?) SUPPORTED.
243
       Can be supported if SimpleSelectExpression supports SingleValuedPathExpression instead of StateFieldPathExpression.
244
245
    public function testSingleAssociationPathExpressionInSubselect()
246
    {
247
        $this->assertSqlGeneration(
248
            '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',
249
            'SELECT (SELECT c0_.user_id FROM cms_phonenumbers c0_ WHERE c0_.user_id = c1_.id) AS sclr_0 FROM cms_users c1_ WHERE c1_.id = ?'
250
        );
251
    }*/
252
253
    /**
254
     * @group DDC-1077
255
     */
256
    public function testConstantValueInSelect()
257
    {
258
        $this->assertSqlGeneration(
259
            "SELECT u.name, 'foo' AS bar FROM Doctrine\Tests\Models\CMS\CmsUser u",
260
            "SELECT c0_.name AS name_0, 'foo' AS sclr_1 FROM cms_users c0_"
261
        );
262
    }
263
264
    public function testSupportsOrderByWithAscAsDefault()
265
    {
266
        $this->assertSqlGeneration(
267
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id',
268
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ ORDER BY f0_.id ASC'
269
        );
270
    }
271
272
    public function testSupportsOrderByAsc()
273
    {
274
        $this->assertSqlGeneration(
275
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id asc',
276
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ ORDER BY f0_.id ASC'
277
        );
278
    }
279
    public function testSupportsOrderByDesc()
280
    {
281
        $this->assertSqlGeneration(
282
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id desc',
283
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ ORDER BY f0_.id DESC'
284
        );
285
    }
286
287
    public function testSupportsSelectDistinct()
288
    {
289
        $this->assertSqlGeneration(
290
            'SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
291
            'SELECT DISTINCT c0_.name AS name_0 FROM cms_users c0_'
292
        );
293
    }
294
295
    public function testSupportsAggregateFunctionInSelectedFields()
296
    {
297
        $this->assertSqlGeneration(
298
            'SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
299
            'SELECT COUNT(c0_.id) AS sclr_0 FROM cms_users c0_ GROUP BY c0_.id'
300
        );
301
    }
302
303
    public function testSupportsAggregateFunctionWithSimpleArithmetic()
304
    {
305
        $this->assertSqlGeneration(
306
            'SELECT MAX(u.id + 4) * 2 FROM Doctrine\Tests\Models\CMS\CmsUser u',
307
            'SELECT MAX(c0_.id + 4) * 2 AS sclr_0 FROM cms_users c0_'
308
        );
309
    }
310
311
    /**
312
     * @group DDC-3276
313
     */
314
    public function testSupportsAggregateCountFunctionWithSimpleArithmetic()
315
    {
316
        $connMock = $this->_em->getConnection();
317
        $orgPlatform = $connMock->getDatabasePlatform();
318
319
        $connMock->setDatabasePlatform(new MySqlPlatform());
320
321
        $this->assertSqlGeneration(
322
            'SELECT COUNT(CONCAT(u.id, u.name)) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
323
            'SELECT COUNT(CONCAT(c0_.id, c0_.name)) AS sclr_0 FROM cms_users c0_ GROUP BY c0_.id'
324
        );
325
326
        $connMock->setDatabasePlatform($orgPlatform);
327
    }
328
329
    public function testSupportsWhereClauseWithPositionalParameter()
330
    {
331
        $this->assertSqlGeneration(
332
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.id = ?1',
333
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE f0_.id = ?'
334
        );
335
    }
336
337
    public function testSupportsWhereClauseWithNamedParameter()
338
    {
339
        $this->assertSqlGeneration(
340
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name',
341
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE f0_.username = ?'
342
        );
343
    }
344
345
    public function testSupportsWhereAndClauseWithNamedParameters()
346
    {
347
        $this->assertSqlGeneration(
348
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name and u.username = :name2',
349
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE f0_.username = ? AND f0_.username = ?'
350
        );
351
    }
352
353
    public function testSupportsCombinedWhereClauseWithNamedParameter()
354
    {
355
        $this->assertSqlGeneration(
356
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where (u.username = :name OR u.username = :name2) AND u.id = :id',
357
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE (f0_.username = ? OR f0_.username = ?) AND f0_.id = ?'
358
        );
359
    }
360
361
    public function testSupportsAggregateFunctionInASelectDistinct()
362
    {
363
        $this->assertSqlGeneration(
364
            'SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u',
365
            'SELECT COUNT(DISTINCT c0_.name) AS sclr_0 FROM cms_users c0_'
366
        );
367
    }
368
369
    // Ticket #668
370
    public function testSupportsASqlKeywordInAStringLiteralParam()
371
    {
372
        $this->assertSqlGeneration(
373
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE '%foo OR bar%'",
374
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE c0_.name LIKE '%foo OR bar%'"
375
        );
376
    }
377
378
    public function testSupportsArithmeticExpressionsInWherePart()
379
    {
380
        $this->assertSqlGeneration(
381
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000',
382
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE ((c0_.id + 5000) * c0_.id + 3) < 10000000'
383
        );
384
    }
385
386
    public function testSupportsMultipleEntitiesInFromClause()
387
    {
388
        $this->assertSqlGeneration(
389
            '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',
390
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c1_.id AS id_4, c1_.topic AS topic_5, c1_.text AS text_6, c1_.version AS version_7 FROM cms_users c0_, cms_articles c1_ INNER JOIN cms_users c2_ ON c1_.user_id = c2_.id WHERE c0_.id = c2_.id'
391
        );
392
    }
393
394
    public function testSupportsMultipleEntitiesInFromClauseUsingPathExpression()
395
    {
396
        $this->assertSqlGeneration(
397
            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.id = a.user',
398
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c1_.id AS id_4, c1_.topic AS topic_5, c1_.text AS text_6, c1_.version AS version_7 FROM cms_users c0_, cms_articles c1_ WHERE c0_.id = c1_.user_id'
399
        );
400
    }
401
402
    public function testSupportsPlainJoinWithoutClause()
403
    {
404
        $this->assertSqlGeneration(
405
            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a',
406
            'SELECT c0_.id AS id_0, c1_.id AS id_1 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id'
407
        );
408
        $this->assertSqlGeneration(
409
            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a',
410
            'SELECT c0_.id AS id_0, c1_.id AS id_1 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id'
411
        );
412
    }
413
414
    /**
415
     * @group DDC-135
416
     */
417
    public function testSupportsJoinAndWithClauseRestriction()
418
    {
419
        $this->assertSqlGeneration(
420
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE '%foo%'",
421
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE '%foo%')"
422
        );
423
        $this->assertSqlGeneration(
424
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a WITH a.topic LIKE '%foo%'",
425
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE '%foo%')"
426
        );
427
    }
428
429
    /**
430
     * @group DDC-135
431
     * @group DDC-177
432
     */
433
    public function testJoinOnClause_NotYetSupported_ThrowsException()
434
    {
435
        $this->expectException(QueryException::class);
436
437
        $sql = $this->_em->createQuery(
0 ignored issues
show
Unused Code introduced by
$sql is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
438
            "SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a ON a.topic LIKE '%foo%'"
439
        )->getSql();
440
    }
441
442
    public function testSupportsMultipleJoins()
443
    {
444
        $this->assertSqlGeneration(
445
            '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',
446
            'SELECT c0_.id AS id_0, c1_.id AS id_1, c2_.phonenumber AS phonenumber_2, c3_.id AS id_3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id INNER JOIN cms_phonenumbers c2_ ON c0_.id = c2_.user_id INNER JOIN cms_comments c3_ ON c1_.id = c3_.article_id'
447
        );
448
    }
449
450
    public function testSupportsTrimFunction()
451
    {
452
        $this->assertSqlGeneration(
453
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING ' ' FROM u.name) = 'someone'",
454
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE TRIM(TRAILING ' ' FROM c0_.name) = 'someone'"
455
        );
456
    }
457
458
    /**
459
     * @group DDC-2668
460
     */
461
    public function testSupportsTrimLeadingZeroString()
462
    {
463
        $this->assertSqlGeneration(
464
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING '0' FROM u.name) != ''",
465
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE TRIM(TRAILING '0' FROM c0_.name) <> ''"
466
        );
467
    }
468
469
    // Ticket 894
470
    public function testSupportsBetweenClauseWithPositionalParameters()
471
    {
472
        $this->assertSqlGeneration(
473
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2",
474
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE c0_.id BETWEEN ? AND ?"
475
        );
476
    }
477
478
    /**
479
     * @group DDC-1802
480
     */
481
    public function testSupportsNotBetweenForSizeFunction()
482
    {
483
        $this->assertSqlGeneration(
484
            "SELECT m.name FROM Doctrine\Tests\Models\StockExchange\Market m WHERE SIZE(m.stocks) NOT BETWEEN ?1 AND ?2",
485
            "SELECT e0_.name AS name_0 FROM exchange_markets e0_ WHERE (SELECT COUNT(*) FROM exchange_stocks e1_ WHERE e1_.market_id = e0_.id) NOT BETWEEN ? AND ?"
486
        );
487
    }
488
489
    public function testSupportsFunctionalExpressionsInWherePart()
490
    {
491
        $this->assertSqlGeneration(
492
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'",
493
            // String quoting in the SQL usually depends on the database platform.
494
            // This test works with a mock connection which uses ' for string quoting.
495
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE TRIM(c0_.name) = 'someone'"
496
        );
497
    }
498
499
    public function testSupportsInstanceOfExpressionsInWherePart()
500
    {
501
        $this->assertSqlGeneration(
502
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee",
503
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')"
504
        );
505
    }
506
507
    public function testSupportsInstanceOfExpressionInWherePartWithMultipleValues()
508
    {
509
        // This also uses FQCNs starting with or without a backslash in the INSTANCE OF parameter
510
        $this->assertSqlGeneration(
511
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF (Doctrine\Tests\Models\Company\CompanyEmployee, \Doctrine\Tests\Models\Company\CompanyManager)",
512
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('employee', 'manager')"
513
        );
514
    }
515
516
    /**
517
     * @group DDC-1194
518
     */
519
    public function testSupportsInstanceOfExpressionsInWherePartPrefixedSlash()
520
    {
521
        $this->assertSqlGeneration(
522
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\Company\CompanyEmployee",
523
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')"
524
        );
525
    }
526
527
    /**
528
     * @group DDC-1194
529
     */
530
    public function testSupportsInstanceOfExpressionsInWherePartWithUnrelatedClass()
531
    {
532
        $this->assertInvalidSqlGeneration(
533
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\CMS\CmsUser",
534
            QueryException::class
535
        );
536
    }
537
538
    public function testSupportsInstanceOfExpressionsInWherePartInDeeperLevel()
539
    {
540
        $this->assertSqlGeneration(
541
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
542
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id WHERE c0_.discr IN ('manager')"
543
        );
544
    }
545
546
    public function testSupportsInstanceOfExpressionsInWherePartInDeepestLevel()
547
    {
548
        $this->assertSqlGeneration(
549
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyManager u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
550
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c2_.title AS title_5, c0_.discr AS discr_6 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id WHERE c0_.discr IN ('manager')"
551
        );
552
    }
553
554
    public function testSupportsInstanceOfExpressionsUsingInputParameterInWherePart()
555
    {
556
        $this->assertSqlGeneration(
557
            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1",
558
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_ WHERE c0_.discr IN (?)",
559
            [], [1 => $this->_em->getClassMetadata(CompanyEmployee::class)]
560
        );
561
    }
562
563
    // Ticket #973
564
    public function testSupportsSingleValuedInExpressionWithoutSpacesInWherePart()
565
    {
566
        $this->assertSqlGeneration(
567
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IN(46)",
568
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE c0_.email_id IN (46)"
569
        );
570
    }
571
572
    public function testSupportsMultipleValuedInExpressionInWherePart()
573
    {
574
        $this->assertSqlGeneration(
575
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)',
576
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.id IN (1, 2)'
577
        );
578
    }
579
580
    public function testSupportsNotInExpressionInWherePart()
581
    {
582
        $this->assertSqlGeneration(
583
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :id NOT IN (1)',
584
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE ? NOT IN (1)'
585
        );
586
    }
587
588
    /**
589
     * @group DDC-1802
590
     */
591
    public function testSupportsNotInExpressionForModFunction()
592
    {
593
        $this->assertSqlGeneration(
594
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE MOD(u.id, 5) NOT IN(1,3,4)",
595
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE MOD(c0_.id, 5) NOT IN (1, 3, 4)"
596
        );
597
    }
598
599
    public function testInExpressionWithSingleValuedAssociationPathExpressionInWherePart()
600
    {
601
        $this->assertSqlGeneration(
602
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)',
603
            'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE f0_.avatar_id IN (?, ?)'
604
        );
605
    }
606
607
    public function testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide()
608
    {
609
        // We do not support SingleValuedAssociationPathExpression on inverse side
610
        $this->assertInvalidSqlGeneration(
611
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IN (?1, ?2)",
612
            QueryException::class
613
        );
614
    }
615
616
    public function testSupportsConcatFunctionForMysqlAndPostgresql()
617
    {
618
        $connMock = $this->_em->getConnection();
619
        $orgPlatform = $connMock->getDatabasePlatform();
620
621
        $connMock->setDatabasePlatform(new MySqlPlatform());
622
        $this->assertSqlGeneration(
623
            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
624
            "SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE CONCAT(c0_.name, 's') = ?"
625
        );
626
        $this->assertSqlGeneration(
627
            "SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
628
            "SELECT CONCAT(c0_.id, c0_.name) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?"
629
        );
630
631
        $connMock->setDatabasePlatform(new PostgreSqlPlatform());
632
        $this->assertSqlGeneration(
633
            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
634
            "SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE c0_.name || 's' = ?"
635
        );
636
        $this->assertSqlGeneration(
637
            "SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
638
            "SELECT c0_.id || c0_.name AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?"
639
        );
640
641
        $connMock->setDatabasePlatform($orgPlatform);
642
    }
643
644
    public function testSupportsExistsExpressionInWherePartWithCorrelatedSubquery()
645
    {
646
        $this->assertSqlGeneration(
647
            '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)',
648
            'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT c1_.phonenumber FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = c0_.id)'
649
        );
650
    }
651
652
    /**
653
     * @group DDC-593
654
     */
655
    public function testSubqueriesInComparisonExpression()
656
    {
657
        $this->assertSqlGeneration(
658
            '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))',
659
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (c0_.id >= (SELECT c1_.id FROM cms_users c1_ WHERE c1_.name = ?)) AND (c0_.id <= (SELECT c2_.id FROM cms_users c2_ WHERE c2_.name = ?))'
660
        );
661
    }
662
663 View Code Duplication
    public function testSupportsMemberOfExpressionOneToMany()
664
    {
665
        // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...)
666
        $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
667
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
668
669
        $phone = new CmsPhonenumber();
670
        $phone->phonenumber = 101;
671
        $q->setParameter('param', $phone);
672
673
        $this->assertEquals(
674
            'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_phonenumbers c1_ WHERE c0_.id = c1_.user_id AND c1_.phonenumber = ?)',
675
            $q->getSql()
676
        );
677
    }
678
679 View Code Duplication
    public function testSupportsMemberOfExpressionManyToMany()
680
    {
681
        // "Get all users who are members of $group."
682
        $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
683
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
684
685
        $group = new CmsGroup();
686
        $group->id = 101;
687
        $q->setParameter('param', $group);
688
689
        $this->assertEquals(
690
            'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (?))',
691
            $q->getSql()
692
        );
693
    }
694
695
    public function testSupportsMemberOfExpressionManyToManyParameterArray()
696
    {
697
        $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
698
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
699
700
        $group = new CmsGroup();
701
        $group->id = 101;
702
        $group2 = new CmsGroup();
703
        $group2->id = 105;
704
        $q->setParameter('param', [$group, $group2]);
705
706
        $this->assertEquals(
707
            'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (?))',
708
            $q->getSql()
709
        );
710
    }
711
712
    public function testSupportsMemberOfExpressionSelfReferencing()
713
    {
714
        // "Get all persons who have $person as a friend."
715
        // Tough one: Many-many self-referencing ("friends") with class table inheritance
716
        $q = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
717
        $person = new CompanyPerson();
718
        $this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, ['id' => 101]);
719
        $q->setParameter('param', $person);
720
        $this->assertEquals(
721
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.title AS title_2, c2_.salary AS salary_3, c2_.department AS department_4, c2_.startDate AS startDate_5, c0_.discr AS discr_6, c0_.spouse_id AS spouse_id_7, c1_.car_id AS car_id_8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id IN (?))',
722
            $q->getSql()
723
        );
724
    }
725
726
    public function testSupportsMemberOfWithSingleValuedAssociation()
727
    {
728
        // Impossible example, but it illustrates the purpose
729
        $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.email MEMBER OF u.groups');
730
731
        $this->assertEquals(
732
            'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (c0_.email_id))',
733
            $q->getSql()
734
        );
735
    }
736
737
    public function testSupportsMemberOfWithIdentificationVariable()
738
    {
739
        // Impossible example, but it illustrates the purpose
740
        $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u MEMBER OF u.groups');
741
742
        $this->assertEquals(
743
            'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (c0_.id))',
744
            $q->getSql()
745
        );
746
    }
747
748
    public function testSupportsCurrentDateFunction()
749
    {
750
        $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()');
751
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
752
        $this->assertEquals('SELECT d0_.id AS id_0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_DATE', $q->getSql());
753
    }
754
755
    public function testSupportsCurrentTimeFunction()
756
    {
757
        $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()');
758
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
759
        $this->assertEquals('SELECT d0_.id AS id_0 FROM date_time_model d0_ WHERE d0_.col_time > CURRENT_TIME', $q->getSql());
760
    }
761
762
    public function testSupportsCurrentTimestampFunction()
763
    {
764
        $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()');
765
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
766
        $this->assertEquals('SELECT d0_.id AS id_0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_TIMESTAMP', $q->getSql());
767
    }
768
769
    public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
770
    {
771
        $this->assertSqlGeneration(
772
            // DQL
773
            // The result of this query consists of all employees whose spouses are also employees.
774
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
775
                WHERE EXISTS (
776
                    SELECT spouseEmp
777
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
778
                    WHERE spouseEmp = emp.spouse)',
779
            // SQL
780
            'SELECT DISTINCT c0_.id AS id_0, c0_.name AS name_1 FROM cms_employees c0_'
781
                . ' WHERE EXISTS ('
782
                    . 'SELECT c1_.id FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
783
                    . ')'
784
        );
785
    }
786
787
    public function testExistsExpressionWithSimpleSelectReturningScalar()
788
    {
789
        $this->assertSqlGeneration(
790
            // DQL
791
            // The result of this query consists of all employees whose spouses are also employees.
792
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
793
                WHERE EXISTS (
794
                    SELECT 1
795
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
796
                    WHERE spouseEmp = emp.spouse)',
797
            // SQL
798
            'SELECT DISTINCT c0_.id AS id_0, c0_.name AS name_1 FROM cms_employees c0_'
799
                . ' WHERE EXISTS ('
800
                    . 'SELECT 1 AS sclr_2 FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
801
                    . ')'
802
        );
803
    }
804
805
    public function testLimitFromQueryClass()
806
    {
807
        $q = $this->_em
808
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
809
            ->setMaxResults(10);
810
811
        $this->assertEquals('SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c0_.email_id AS email_id_4 FROM cms_users c0_ LIMIT 10', $q->getSql());
812
    }
813
814
    public function testLimitAndOffsetFromQueryClass()
815
    {
816
        $q = $this->_em
817
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
818
            ->setMaxResults(10)
819
            ->setFirstResult(0);
820
821
        $this->assertEquals('SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c0_.email_id AS email_id_4 FROM cms_users c0_ LIMIT 10 OFFSET 0', $q->getSql());
822
    }
823
824
    public function testSizeFunction()
825
    {
826
        $this->assertSqlGeneration(
827
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1",
828
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) > 1"
829
        );
830
    }
831
832
    public function testSizeFunctionSupportsManyToMany()
833
    {
834
        $this->assertSqlGeneration(
835
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1",
836
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_users_groups c1_ WHERE c1_.user_id = c0_.id) > 1"
837
        );
838
    }
839
840
    public function testEmptyCollectionComparisonExpression()
841
    {
842
        $this->assertSqlGeneration(
843
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY",
844
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) = 0"
845
        );
846
        $this->assertSqlGeneration(
847
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS NOT EMPTY",
848
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) > 0"
849
        );
850
    }
851
852
    public function testNestedExpressions()
853
    {
854
        $this->assertSqlGeneration(
855
            "select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)",
856
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.id > 10 AND c0_.id < 42 AND ((c0_.id * 2) > 5)"
857
        );
858
    }
859
860
    public function testNestedExpressions2()
861
    {
862
        $this->assertSqlGeneration(
863
            "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",
864
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (c0_.id > 10) AND (c0_.id < 42 AND ((c0_.id * 2) > 5)) OR c0_.id <> 42"
865
        );
866
    }
867
868
    public function testNestedExpressions3()
869
    {
870
        $this->assertSqlGeneration(
871
            "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))",
872
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (c0_.id > 10) AND (c0_.id BETWEEN 1 AND 10 OR c0_.id IN (1, 2, 3, 4, 5))"
873
        );
874
    }
875
876
    public function testOrderByCollectionAssociationSize()
877
    {
878
        $this->assertSqlGeneration(
879
            "select u, size(u.articles) as numArticles from Doctrine\Tests\Models\CMS\CmsUser u order by numArticles",
880
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, (SELECT COUNT(*) FROM cms_articles c1_ WHERE c1_.user_id = c0_.id) AS sclr_4 FROM cms_users c0_ ORDER BY sclr_4 ASC"
881
        );
882
    }
883
884
    public function testOrderBySupportsSingleValuedPathExpressionOwningSide()
885
    {
886
        $this->assertSqlGeneration(
887
            "select a from Doctrine\Tests\Models\CMS\CmsArticle a order by a.user",
888
            "SELECT c0_.id AS id_0, c0_.topic AS topic_1, c0_.text AS text_2, c0_.version AS version_3 FROM cms_articles c0_ ORDER BY c0_.user_id ASC"
889
        );
890
    }
891
892
    /**
893
     * @expectedException \Doctrine\ORM\Query\QueryException
894
     */
895
    public function testOrderBySupportsSingleValuedPathExpressionInverseSide()
896
    {
897
        $q = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u order by u.address");
898
        $q->getSQL();
899
    }
900
901 View Code Duplication
    public function testBooleanLiteralInWhereOnSqlite()
902
    {
903
        $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
904
        $this->_em->getConnection()->setDatabasePlatform(new SqlitePlatform());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
905
906
        $this->assertSqlGeneration(
907
            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true",
908
            "SELECT b0_.id AS id_0, b0_.booleanField AS booleanField_1 FROM boolean_model b0_ WHERE b0_.booleanField = 1"
909
        );
910
911
        $this->assertSqlGeneration(
912
            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false",
913
            "SELECT b0_.id AS id_0, b0_.booleanField AS booleanField_1 FROM boolean_model b0_ WHERE b0_.booleanField = 0"
914
        );
915
916
        $this->_em->getConnection()->setDatabasePlatform($oldPlat);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
917
    }
918
919 View Code Duplication
    public function testBooleanLiteralInWhereOnPostgres()
920
    {
921
        $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
922
        $this->_em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
923
924
        $this->assertSqlGeneration(
925
            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true",
926
            "SELECT b0_.id AS id_0, b0_.booleanField AS booleanfield_1 FROM boolean_model b0_ WHERE b0_.booleanField = true"
927
        );
928
929
        $this->assertSqlGeneration(
930
            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false",
931
            "SELECT b0_.id AS id_0, b0_.booleanField AS booleanfield_1 FROM boolean_model b0_ WHERE b0_.booleanField = false"
932
        );
933
934
        $this->_em->getConnection()->setDatabasePlatform($oldPlat);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
935
    }
936
937
    public function testSingleValuedAssociationFieldInWhere()
938
    {
939
        $this->assertSqlGeneration(
940
            "SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1",
941
            "SELECT c0_.phonenumber AS phonenumber_0 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?"
942
        );
943
    }
944
945
    public function testSingleValuedAssociationNullCheckOnOwningSide()
946
    {
947
        $this->assertSqlGeneration(
948
            "SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user IS NULL",
949
            "SELECT c0_.id AS id_0, c0_.country AS country_1, c0_.zip AS zip_2, c0_.city AS city_3 FROM cms_addresses c0_ WHERE c0_.user_id IS NULL"
950
        );
951
    }
952
953
    // Null check on inverse side has to happen through explicit JOIN.
954
    // "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IS NULL"
955
    // where the CmsUser is the inverse side is not supported.
956
    public function testSingleValuedAssociationNullCheckOnInverseSide()
957
    {
958
        $this->assertSqlGeneration(
959
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.address a WHERE a.id IS NULL",
960
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON c0_.id = c1_.user_id WHERE c1_.id IS NULL"
961
        );
962
    }
963
964
    /**
965
     * @group DDC-339
966
     * @group DDC-1572
967
     */
968
    public function testStringFunctionLikeExpression()
969
    {
970
        $this->assertSqlGeneration(
971
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE '%foo OR bar%'",
972
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE '%foo OR bar%'"
973
        );
974
        $this->assertSqlGeneration(
975
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str",
976
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE ?"
977
        );
978
        $this->assertSqlGeneration(
979
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), '_moo') LIKE :str",
980
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE UPPER(c0_.name) || '_moo' LIKE ?"
981
        );
982
983
        // DDC-1572
984
        $this->assertSqlGeneration(
985
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(u.name) LIKE UPPER(:str)",
986
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE UPPER(c0_.name) LIKE UPPER(?)"
987
        );
988
        $this->assertSqlGeneration(
989
            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) LIKE UPPER(LOWER(:str))",
990
            "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE UPPER(LOWER(c0_.name)) LIKE UPPER(LOWER(?))"
991
        );
992
        $this->assertSqlGeneration(
993
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE u.name",
994
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE c0_.name)"
995
        );
996
    }
997
998
    /**
999
     * @group DDC-1802
1000
     */
1001
    public function testStringFunctionNotLikeExpression()
1002
    {
1003
        $this->assertSqlGeneration(
1004
                "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) NOT LIKE '%foo OR bar%'",
1005
                "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE LOWER(c0_.name) NOT LIKE '%foo OR bar%'"
1006
        );
1007
1008
        $this->assertSqlGeneration(
1009
                "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) NOT LIKE UPPER(LOWER(:str))",
1010
                "SELECT c0_.name AS name_0 FROM cms_users c0_ WHERE UPPER(LOWER(c0_.name)) NOT LIKE UPPER(LOWER(?))"
1011
        );
1012
        $this->assertSqlGeneration(
1013
                "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic NOT LIKE u.name",
1014
                "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic NOT LIKE c0_.name)"
1015
        );
1016
    }
1017
1018
    /**
1019
     * @group DDC-338
1020
     */
1021
    public function testOrderedCollectionFetchJoined()
1022
    {
1023
        $this->assertSqlGeneration(
1024
            "SELECT r, l FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.legs l",
1025
            "SELECT r0_.id AS id_0, r1_.id AS id_1, r1_.departureDate AS departureDate_2, r1_.arrivalDate AS arrivalDate_3 FROM RoutingRoute r0_ INNER JOIN RoutingRouteLegs r2_ ON r0_.id = r2_.route_id INNER JOIN RoutingLeg r1_ ON r1_.id = r2_.leg_id ".
1026
            "ORDER BY r1_.departureDate ASC"
1027
        );
1028
    }
1029
1030
    public function testSubselectInSelect()
1031
    {
1032
        $this->assertSqlGeneration(
1033
            "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'",
1034
            "SELECT c0_.name AS name_0, (SELECT COUNT(c1_.phonenumber) AS sclr_2 FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234) AS sclr_1 FROM cms_users c0_ WHERE c0_.name = 'jon'"
1035
        );
1036
    }
1037
1038
    /**
1039
     * @group locking
1040
     * @group DDC-178
1041
     */
1042
    public function testPessimisticWriteLockQueryHint()
1043
    {
1044
        if ($this->_em->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) {
1045
            $this->markTestSkipped('SqLite does not support Row locking at all.');
1046
        }
1047
1048
        $this->assertSqlGeneration(
1049
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
1050
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 ".
1051
            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR UPDATE",
1052
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_WRITE]
1053
        );
1054
    }
1055
1056
    /**
1057
     * @group locking
1058
     * @group DDC-178
1059
     */
1060 View Code Duplication
    public function testPessimisticReadLockQueryHintPostgreSql()
1061
    {
1062
        $this->_em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1063
1064
        $this->assertSqlGeneration(
1065
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
1066
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 ".
1067
            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR SHARE",
1068
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1069
        );
1070
    }
1071
1072
    /**
1073
     * @group DDC-1693
1074
     * @group locking
1075
     */
1076
    public function testLockModeNoneQueryHint()
1077
    {
1078
        $this->assertSqlGeneration(
1079
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
1080
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 ".
1081
            "FROM cms_users c0_ WHERE c0_.username = 'gblanco'",
1082
            [ORMQuery::HINT_LOCK_MODE => LockMode::NONE]
1083
        );
1084
    }
1085
1086
    /**
1087
     * @group DDC-430
1088
     */
1089
    public function testSupportSelectWithMoreThan10InputParameters()
1090
    {
1091
        $this->assertSqlGeneration(
1092
            "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",
1093
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ?"
1094
        );
1095
    }
1096
1097
    /**
1098
     * @group locking
1099
     * @group DDC-178
1100
     */
1101 View Code Duplication
    public function testPessimisticReadLockQueryHintMySql()
1102
    {
1103
        $this->_em->getConnection()->setDatabasePlatform(new MySqlPlatform());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1104
1105
        $this->assertSqlGeneration(
1106
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
1107
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 ".
1108
            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' LOCK IN SHARE MODE",
1109
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1110
        );
1111
    }
1112
1113
    /**
1114
     * @group locking
1115
     * @group DDC-178
1116
     */
1117 View Code Duplication
    public function testPessimisticReadLockQueryHintOracle()
1118
    {
1119
        $this->_em->getConnection()->setDatabasePlatform(new OraclePlatform());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Doctrine\DBAL\Connection as the method setDatabasePlatform() does only exist in the following sub-classes of Doctrine\DBAL\Connection: Doctrine\Tests\Mocks\ConnectionMock. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1120
1121
        $this->assertSqlGeneration(
1122
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
1123
            "SELECT c0_.id AS ID_0, c0_.status AS STATUS_1, c0_.username AS USERNAME_2, c0_.name AS NAME_3 ".
1124
            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR UPDATE",
1125
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1126
        );
1127
    }
1128
1129
    /**
1130
     * @group DDC-431
1131
     */
1132
    public function testSupportToCustomDQLFunctions()
1133
    {
1134
        $config = $this->_em->getConfiguration();
1135
        $config->addCustomNumericFunction('MYABS', MyAbsFunction::class);
1136
1137
        $this->assertSqlGeneration(
1138
            'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
1139
            'SELECT ABS(c0_.phonenumber) AS sclr_0 FROM cms_phonenumbers c0_'
1140
        );
1141
1142
        $config->setCustomNumericFunctions([]);
1143
    }
1144
1145
    /**
1146
     * @group DDC-826
1147
     */
1148
    public function testMappedSuperclassAssociationJoin()
1149
    {
1150
        $this->assertSqlGeneration(
1151
            'SELECT f FROM Doctrine\Tests\Models\DirectoryTree\File f JOIN f.parentDirectory d WHERE f.id = ?1',
1152
            'SELECT f0_.id AS id_0, f0_.extension AS extension_1, f0_.name AS name_2 FROM "file" f0_ INNER JOIN Directory d1_ ON f0_.parentDirectory_id = d1_.id WHERE f0_.id = ?'
1153
        );
1154
    }
1155
1156
    /**
1157
     * @group DDC-1053
1158
     */
1159
    public function testGroupBy()
1160
    {
1161
        $this->assertSqlGeneration(
1162
            'SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id',
1163
            'SELECT c0_.id AS id_0, count(c1_.id) AS sclr_1 FROM cms_groups c0_ INNER JOIN cms_users_groups c2_ ON c0_.id = c2_.group_id INNER JOIN cms_users c1_ ON c1_.id = c2_.user_id GROUP BY c0_.id'
1164
        );
1165
    }
1166
1167
    /**
1168
     * @group DDC-1053
1169
     */
1170
    public function testGroupByIdentificationVariable()
1171
    {
1172
        $this->assertSqlGeneration(
1173
            'SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g',
1174
            'SELECT c0_.id AS id_0, c0_.name AS name_1, count(c1_.id) AS sclr_2 FROM cms_groups c0_ INNER JOIN cms_users_groups c2_ ON c0_.id = c2_.group_id INNER JOIN cms_users c1_ ON c1_.id = c2_.user_id GROUP BY c0_.id, c0_.name'
1175
        );
1176
    }
1177
1178
    public function testCaseContainingNullIf()
1179
    {
1180
        $this->assertSqlGeneration(
1181
            "SELECT NULLIF(g.id, g.name) AS NullIfEqual FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1182
            'SELECT NULLIF(c0_.id, c0_.name) AS sclr_0 FROM cms_groups c0_'
1183
        );
1184
    }
1185
1186
    public function testCaseContainingCoalesce()
1187
    {
1188
        $this->assertSqlGeneration(
1189
            "SELECT COALESCE(NULLIF(u.name, ''), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u",
1190
            "SELECT COALESCE(NULLIF(c0_.name, ''), c0_.username) AS sclr_0 FROM cms_users c0_"
1191
        );
1192
    }
1193
1194
    /**
1195
     * Test that the right discriminator data is inserted in a subquery.
1196
     */
1197
    public function testSubSelectDiscriminator()
1198
    {
1199
        $this->assertSqlGeneration(
1200
            "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",
1201
            "SELECT c0_.name AS name_0, (SELECT COUNT(c1_.id) AS sclr_2 FROM company_contracts c1_ WHERE c1_.discr IN ('fix')) AS sclr_1 FROM cms_users c0_"
1202
        );
1203
    }
1204
1205
    public function testIdVariableResultVariableReuse()
1206
    {
1207
        $exceptionThrown = false;
1208
        try {
1209
            $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)");
1210
1211
            $query->getSql();
1212
            $query->free();
1213
        } catch (\Exception $e) {
1214
            $exceptionThrown = true;
1215
        }
1216
1217
        $this->assertTrue($exceptionThrown);
1218
1219
    }
1220
1221
    public function testSubSelectAliasesFromOuterQuery()
1222
    {
1223
        $this->assertSqlGeneration(
1224
            "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",
1225
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id) AS sclr_4 FROM cms_users c0_"
1226
        );
1227
    }
1228
1229
    public function testSubSelectAliasesFromOuterQueryWithSubquery()
1230
    {
1231
        $this->assertSqlGeneration(
1232
            "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",
1233
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id AND c1_.name IN (SELECT c2_.name FROM cms_users c2_)) AS sclr_4 FROM cms_users c0_"
1234
        );
1235
    }
1236
1237
    public function testSubSelectAliasesFromOuterQueryReuseInWhereClause()
1238
    {
1239
        $this->assertSqlGeneration(
1240
            "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",
1241
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id) AS sclr_4 FROM cms_users c0_ WHERE sclr_4 = ?"
1242
        );
1243
    }
1244
1245
    /**
1246
     * @group DDC-1298
1247
     */
1248
    public function testSelectForeignKeyPKWithoutFields()
1249
    {
1250
        $this->assertSqlGeneration(
1251
            "SELECT t, s, l FROM Doctrine\Tests\Models\DDC117\DDC117Link l INNER JOIN l.target t INNER JOIN l.source s",
1252
            "SELECT d0_.article_id AS article_id_0, d0_.title AS title_1, d1_.article_id AS article_id_2, d1_.title AS title_3, d2_.source_id AS source_id_4, d2_.target_id AS target_id_5 FROM DDC117Link d2_ INNER JOIN DDC117Article d0_ ON d2_.target_id = d0_.article_id INNER JOIN DDC117Article d1_ ON d2_.source_id = d1_.article_id"
1253
        );
1254
    }
1255
1256
    public function testGeneralCaseWithSingleWhenClause()
1257
    {
1258
        $this->assertSqlGeneration(
1259
            "SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1260
            "SELECT c0_.id AS id_0, CASE WHEN ((c0_.id / 2) > 18) THEN 1 ELSE 0 END AS sclr_1 FROM cms_groups c0_"
1261
        );
1262
    }
1263
1264
    public function testGeneralCaseWithMultipleWhenClause()
1265
    {
1266
        $this->assertSqlGeneration(
1267
            "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",
1268
            "SELECT c0_.id AS id_0, CASE WHEN (c0_.id / 2 < 10) THEN 2 WHEN ((c0_.id / 2) > 20) THEN 1 ELSE 0 END AS sclr_1 FROM cms_groups c0_"
1269
        );
1270
    }
1271
1272
    public function testSimpleCaseWithSingleWhenClause()
1273
    {
1274
        $this->assertSqlGeneration(
1275
            "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = CASE g.name WHEN 'admin' THEN 1 ELSE 2 END",
1276
            "SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_groups c0_ WHERE c0_.id = CASE c0_.name WHEN 'admin' THEN 1 ELSE 2 END"
1277
        );
1278
    }
1279
1280
    public function testSimpleCaseWithMultipleWhenClause()
1281
    {
1282
        $this->assertSqlGeneration(
1283
            "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)",
1284
            "SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_groups c0_ WHERE c0_.id = (CASE c0_.name WHEN 'admin' THEN 1 WHEN 'moderator' THEN 2 ELSE 3 END)"
1285
        );
1286
    }
1287
1288
    public function testGeneralCaseWithSingleWhenClauseInSubselect()
1289
    {
1290
        $this->assertSqlGeneration(
1291
            "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)",
1292
            "SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE WHEN ((c1_.id / 2) > 18) THEN 2 ELSE 1 END AS sclr_2 FROM cms_groups c1_)"
1293
        );
1294
    }
1295
1296
    public function testGeneralCaseWithMultipleWhenClauseInSubselect()
1297
    {
1298
        $this->assertSqlGeneration(
1299
            "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)",
1300
            "SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE WHEN (c0_.id / 2 < 10) THEN 3 WHEN ((c0_.id / 2) > 20) THEN 2 ELSE 1 END AS sclr_2 FROM cms_groups c1_)"
1301
        );
1302
    }
1303
1304
    public function testSimpleCaseWithSingleWhenClauseInSubselect()
1305
    {
1306
        $this->assertSqlGeneration(
1307
            "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)",
1308
            "SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE c1_.name WHEN 'admin' THEN 1 ELSE 2 END AS sclr_2 FROM cms_groups c1_)"
1309
        );
1310
    }
1311
1312
    public function testSimpleCaseWithMultipleWhenClauseInSubselect()
1313
    {
1314
        $this->assertSqlGeneration(
1315
            "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)",
1316
            "SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE c1_.name WHEN 'admin' THEN 1 WHEN 'moderator' THEN 2 ELSE 3 END AS sclr_2 FROM cms_groups c1_)"
1317
        );
1318
    }
1319
1320
    /**
1321
     * @group DDC-1696
1322
     */
1323
    public function testSimpleCaseWithStringPrimary()
1324
    {
1325
        $this->assertSqlGeneration(
1326
            "SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 'Foo' ELSE 'Bar' END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1327
            "SELECT c0_.id AS id_0, CASE WHEN ((c0_.id / 2) > 18) THEN 'Foo' ELSE 'Bar' END AS sclr_1 FROM cms_groups c0_"
1328
        );
1329
    }
1330
1331
    /**
1332
     * @group DDC-2205
1333
     */
1334 View Code Duplication
    public function testCaseNegativeValuesInThenExpression()
1335
    {
1336
        $this->assertSqlGeneration(
1337
            "SELECT CASE g.name WHEN 'admin' THEN - 1 ELSE - 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1338
            "SELECT CASE c0_.name WHEN 'admin' THEN -1 ELSE -2 END AS sclr_0 FROM cms_groups c0_"
1339
        );
1340
1341
        $this->assertSqlGeneration(
1342
            "SELECT CASE g.name WHEN 'admin' THEN  - 2 WHEN 'guest' THEN - 1 ELSE 0 END FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1343
            "SELECT CASE c0_.name WHEN 'admin' THEN -2 WHEN 'guest' THEN -1 ELSE 0 END AS sclr_0 FROM cms_groups c0_"
1344
        );
1345
1346
        $this->assertSqlGeneration(
1347
            "SELECT CASE g.name WHEN 'admin' THEN (- 1) ELSE (- 2) END FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1348
            "SELECT CASE c0_.name WHEN 'admin' THEN (-1) ELSE (-2) END AS sclr_0 FROM cms_groups c0_"
1349
        );
1350
1351
        $this->assertSqlGeneration(
1352
            "SELECT CASE g.name WHEN 'admin' THEN ( - :value) ELSE ( + :value) END FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1353
            "SELECT CASE c0_.name WHEN 'admin' THEN (-?) ELSE (+?) END AS sclr_0 FROM cms_groups c0_"
1354
        );
1355
1356
        $this->assertSqlGeneration(
1357
            "SELECT CASE g.name WHEN 'admin' THEN ( - g.id) ELSE ( + g.id) END FROM Doctrine\Tests\Models\CMS\CmsGroup g",
1358
            "SELECT CASE c0_.name WHEN 'admin' THEN (-c0_.id) ELSE (+c0_.id) END AS sclr_0 FROM cms_groups c0_"
1359
        );
1360
    }
1361
1362
    public function testIdentityFunctionWithCompositePrimaryKey()
1363
    {
1364
        $this->assertSqlGeneration(
1365
            "SELECT IDENTITY(p.poi, 'long') AS long FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
1366
            "SELECT n0_.poi_long AS sclr_0 FROM navigation_photos n0_"
1367
        );
1368
1369
        $this->assertSqlGeneration(
1370
            "SELECT IDENTITY(p.poi, 'lat') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
1371
            "SELECT n0_.poi_lat AS sclr_0 FROM navigation_photos n0_"
1372
        );
1373
1374
        $this->assertSqlGeneration(
1375
            "SELECT IDENTITY(p.poi, 'long') AS long, IDENTITY(p.poi, 'lat') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
1376
            "SELECT n0_.poi_long AS sclr_0, n0_.poi_lat AS sclr_1 FROM navigation_photos n0_"
1377
        );
1378
1379
        $this->assertInvalidSqlGeneration(
1380
            "SELECT IDENTITY(p.poi, 'invalid') AS invalid FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
1381
            QueryException::class
1382
        );
1383
    }
1384
1385
    /**
1386
     * @group DDC-2519
1387
     */
1388
    public function testPartialWithAssociationIdentifier()
1389
    {
1390
        $this->assertSqlGeneration(
1391
            "SELECT PARTIAL l.{_source, _target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l",
1392
            'SELECT l0_.iUserIdSource AS iUserIdSource_0, l0_.iUserIdTarget AS iUserIdTarget_1 FROM legacy_users_reference l0_'
1393
        );
1394
1395
        $this->assertSqlGeneration(
1396
            "SELECT PARTIAL l.{_description, _source, _target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l",
1397
            'SELECT l0_.description AS description_0, l0_.iUserIdSource AS iUserIdSource_1, l0_.iUserIdTarget AS iUserIdTarget_2 FROM legacy_users_reference l0_'
1398
        );
1399
    }
1400
1401
    /**
1402
     * @group DDC-1339
1403
     */
1404
    public function testIdentityFunctionInSelectClause()
1405
    {
1406
        $this->assertSqlGeneration(
1407
            "SELECT IDENTITY(u.email) as email_id FROM Doctrine\Tests\Models\CMS\CmsUser u",
1408
            "SELECT c0_.email_id AS sclr_0 FROM cms_users c0_"
1409
        );
1410
    }
1411
1412
    public function testIdentityFunctionInJoinedSubclass()
1413
    {
1414
        //relation is in the subclass (CompanyManager) we are querying
1415
        $this->assertSqlGeneration(
1416
            'SELECT m, IDENTITY(m.car) as car_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1417
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c2_.title AS title_5, c2_.car_id AS sclr_6, c0_.discr AS discr_7 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id'
1418
        );
1419
1420
        //relation is in the base class (CompanyPerson).
1421
        $this->assertSqlGeneration(
1422
            'SELECT m, IDENTITY(m.spouse) as spouse_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1423
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c2_.title AS title_5, c0_.spouse_id AS sclr_6, c0_.discr AS discr_7 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id'
1424
        );
1425
    }
1426
1427
    /**
1428
     * @group DDC-1339
1429
     */
1430
    public function testIdentityFunctionDoesNotAcceptStateField()
1431
    {
1432
        $this->assertInvalidSqlGeneration(
1433
            "SELECT IDENTITY(u.name) as name FROM Doctrine\Tests\Models\CMS\CmsUser u",
1434
            QueryException::class
1435
        );
1436
    }
1437
1438
    /**
1439
     * @group DDC-1389
1440
     */
1441
    public function testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad()
1442
    {
1443
        $this->assertSqlGeneration(
1444
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1445
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.title AS title_2, c2_.salary AS salary_3, c2_.department AS department_4, c2_.startDate AS startDate_5, c0_.discr AS discr_6, c0_.spouse_id AS spouse_id_7, c1_.car_id AS car_id_8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id',
1446
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1447
        );
1448
    }
1449
1450
    /**
1451
     * @group DDC-1389
1452
     */
1453
    public function testInheritanceTypeJoinInRootClassWithEnabledForcePartialLoad()
1454
    {
1455
        $this->assertSqlGeneration(
1456
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1457
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c0_.discr AS discr_2 FROM company_persons c0_',
1458
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1459
        );
1460
    }
1461
1462
    /**
1463
     * @group DDC-1389
1464
     */
1465
    public function testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad()
1466
    {
1467
        $this->assertSqlGeneration(
1468
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1469
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c2_.title AS title_5, c0_.discr AS discr_6, c0_.spouse_id AS spouse_id_7, c2_.car_id AS car_id_8 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ ON c1_.id = c2_.id',
1470
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1471
        );
1472
    }
1473
1474
    /**
1475
     * @group DDC-1389
1476
     */
1477
    public function testInheritanceTypeJoinInChildClassWithEnabledForcePartialLoad()
1478
    {
1479
        $this->assertSqlGeneration(
1480
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1481
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id',
1482
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1483
        );
1484
    }
1485
1486
    /**
1487
     * @group DDC-1389
1488
     */
1489
    public function testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad()
1490
    {
1491
        $this->assertSqlGeneration(
1492
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1493
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c2_.title AS title_5, c0_.discr AS discr_6, c0_.spouse_id AS spouse_id_7, c2_.car_id AS car_id_8 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id',
1494
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1495
        );
1496
    }
1497
1498
    /**
1499
     * @group DDC-1389
1500
     */
1501
    public function testInheritanceTypeJoinInLeafClassWithEnabledForcePartialLoad()
1502
    {
1503
        $this->assertSqlGeneration(
1504
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1505
            'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c2_.title AS title_5, c0_.discr AS discr_6 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id',
1506
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1507
        );
1508
    }
1509
1510
    /**
1511
     * @group DDC-1389
1512
     */
1513
    public function testInheritanceTypeSingleTableInRootClassWithDisabledForcePartialLoad()
1514
    {
1515
        $this->assertSqlGeneration(
1516
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1517
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6, c0_.salesPerson_id AS salesPerson_id_7 FROM company_contracts c0_ WHERE c0_.discr IN ('fix', 'flexible', 'flexultra')",
1518
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1519
        );
1520
    }
1521
1522
    /**
1523
     * @group DDC-1389
1524
     */
1525
    public function testInheritanceTypeSingleTableInRootClassWithEnabledForcePartialLoad()
1526
    {
1527
        $this->assertSqlGeneration(
1528
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1529
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_contracts c0_ WHERE c0_.discr IN ('fix', 'flexible', 'flexultra')",
1530
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1531
        );
1532
    }
1533
1534
    /**
1535
     * @group DDC-1389
1536
     */
1537
    public function testInheritanceTypeSingleTableInChildClassWithDisabledForcePartialLoad()
1538
    {
1539
        $this->assertSqlGeneration(
1540
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1541
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.hoursWorked AS hoursWorked_2, c0_.pricePerHour AS pricePerHour_3, c0_.maxPrice AS maxPrice_4, c0_.discr AS discr_5, c0_.salesPerson_id AS salesPerson_id_6 FROM company_contracts c0_ WHERE c0_.discr IN ('flexible', 'flexultra')",
1542
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1543
        );
1544
    }
1545
1546
    /**
1547
     * @group DDC-1389
1548
     */
1549
    public function testInheritanceTypeSingleTableInChildClassWithEnabledForcePartialLoad()
1550
    {
1551
        $this->assertSqlGeneration(
1552
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1553
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.hoursWorked AS hoursWorked_2, c0_.pricePerHour AS pricePerHour_3, c0_.maxPrice AS maxPrice_4, c0_.discr AS discr_5 FROM company_contracts c0_ WHERE c0_.discr IN ('flexible', 'flexultra')",
1554
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1555
        );
1556
    }
1557
1558
    /**
1559
     * @group DDC-1389
1560
     */
1561
    public function testInheritanceTypeSingleTableInLeafClassWithDisabledForcePartialLoad()
1562
    {
1563
        $this->assertSqlGeneration(
1564
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1565
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.hoursWorked AS hoursWorked_2, c0_.pricePerHour AS pricePerHour_3, c0_.maxPrice AS maxPrice_4, c0_.discr AS discr_5, c0_.salesPerson_id AS salesPerson_id_6 FROM company_contracts c0_ WHERE c0_.discr IN ('flexultra')",
1566
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1567
        );
1568
    }
1569
1570
    /**
1571
     * @group DDC-1389
1572
     */
1573
    public function testInheritanceTypeSingleTableInLeafClassWithEnabledForcePartialLoad()
1574
    {
1575
        $this->assertSqlGeneration(
1576
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1577
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.hoursWorked AS hoursWorked_2, c0_.pricePerHour AS pricePerHour_3, c0_.maxPrice AS maxPrice_4, c0_.discr AS discr_5 FROM company_contracts c0_ WHERE c0_.discr IN ('flexultra')",
1578
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1579
        );
1580
    }
1581
1582
    /**
1583
     * @group DDC-1161
1584
     */
1585
    public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias()
1586
    {
1587
        $this->assertSqlGeneration(
1588
            'SELECT p, pp FROM Doctrine\Tests\Models\Company\CompanyPerson p JOIN p.spouse pp',
1589
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.title AS title_2, c2_.salary AS salary_3, c2_.department AS department_4, c2_.startDate AS startDate_5, c3_.id AS id_6, c3_.name AS name_7, c4_.title AS title_8, c5_.salary AS salary_9, c5_.department AS department_10, c5_.startDate AS startDate_11, c0_.discr AS discr_12, c0_.spouse_id AS spouse_id_13, c1_.car_id AS car_id_14, c3_.discr AS discr_15, c3_.spouse_id AS spouse_id_16, c4_.car_id AS car_id_17 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id INNER JOIN company_persons c3_ ON c0_.spouse_id = c3_.id LEFT JOIN company_managers c4_ ON c3_.id = c4_.id LEFT JOIN company_employees c5_ ON c3_.id = c5_.id",
1590
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1591
        );
1592
    }
1593
1594
    /**
1595
     * @group DDC-1384
1596
     */
1597
    public function testAliasDoesNotExceedPlatformDefinedLength()
1598
    {
1599
        $this->assertSqlGeneration(
1600
            'SELECT m FROM ' . __NAMESPACE__ .  '\\DDC1384Model m',
1601
            "SELECT d0_.aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo AS ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo_0 FROM DDC1384Model d0_"
1602
        );
1603
    }
1604
1605
    /**
1606
     * @group DDC-331
1607
     * @group DDC-1384
1608
     */
1609
    public function testIssue331()
1610
    {
1611
        $this->assertSqlGeneration(
1612
            'SELECT e.name FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1613
            'SELECT c0_.name AS name_0 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id'
1614
        );
1615
    }
1616
    /**
1617
     * @group DDC-1435
1618
     */
1619
    public function testForeignKeyAsPrimaryKeySubselect()
1620
    {
1621
        $this->assertSqlGeneration(
1622
            "SELECT s FROM Doctrine\Tests\Models\DDC117\DDC117Article s WHERE EXISTS (SELECT r FROM Doctrine\Tests\Models\DDC117\DDC117Reference r WHERE r.source = s)",
1623
            "SELECT d0_.article_id AS article_id_0, d0_.title AS title_1 FROM DDC117Article d0_ WHERE EXISTS (SELECT d1_.source_id, d1_.target_id FROM DDC117Reference d1_ WHERE d1_.source_id = d0_.article_id)"
1624
        );
1625
    }
1626
1627
    /**
1628
     * @group DDC-1474
1629
     */
1630
    public function testSelectWithArithmeticExpressionBeforeField()
1631
    {
1632
        $this->assertSqlGeneration(
1633
            'SELECT - e.value AS value, e.id FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
1634
            'SELECT -d0_.value AS sclr_0, d0_.id AS id_1 FROM DDC1474Entity d0_'
1635
        );
1636
1637
        $this->assertSqlGeneration(
1638
            'SELECT e.id, + e.value AS value FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
1639
            'SELECT d0_.id AS id_0, +d0_.value AS sclr_1 FROM DDC1474Entity d0_'
1640
        );
1641
    }
1642
1643
     /**
1644
     * @group DDC-1430
1645
     */
1646
    public function testGroupByAllFieldsWhenObjectHasForeignKeys()
1647
    {
1648
        $this->assertSqlGeneration(
1649
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u',
1650
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ GROUP BY c0_.id, c0_.status, c0_.username, c0_.name, c0_.email_id'
1651
        );
1652
1653
        $this->assertSqlGeneration(
1654
            'SELECT e FROM Doctrine\Tests\Models\CMS\CmsEmployee e GROUP BY e',
1655
            'SELECT c0_.id AS id_0, c0_.name AS name_1 FROM cms_employees c0_ GROUP BY c0_.id, c0_.name, c0_.spouse_id'
1656
        );
1657
    }
1658
1659
    /**
1660
     * @group DDC-1236
1661
     */
1662
    public function testGroupBySupportsResultVariable()
1663
    {
1664
        $this->assertSqlGeneration(
1665
            'SELECT u, u.status AS st FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY st',
1666
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c0_.status AS status_4 FROM cms_users c0_ GROUP BY c0_.status'
1667
        );
1668
    }
1669
1670
    /**
1671
     * @group DDC-1236
1672
     */
1673
    public function testGroupBySupportsIdentificationVariable()
1674
    {
1675
        $this->assertSqlGeneration(
1676
            'SELECT u AS user FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY user',
1677
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ GROUP BY id_0, status_1, username_2, name_3'
1678
        );
1679
    }
1680
1681
    /**
1682
     * @group DDC-1213
1683
     */
1684 View Code Duplication
    public function testSupportsBitComparison()
1685
    {
1686
        $this->assertSqlGeneration(
1687
            'SELECT BIT_OR(4,2), BIT_AND(4,2), u FROM Doctrine\Tests\Models\CMS\CmsUser u',
1688
            'SELECT (4 | 2) AS sclr_0, (4 & 2) AS sclr_1, c0_.id AS id_2, c0_.status AS status_3, c0_.username AS username_4, c0_.name AS name_5 FROM cms_users c0_'
1689
        );
1690
        $this->assertSqlGeneration(
1691
            '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',
1692
            'SELECT (c0_.id | 2) AS sclr_0, (c0_.id & 2) AS sclr_1 FROM cms_users c0_ WHERE (c0_.id | 2) > 0'
1693
        );
1694
        $this->assertSqlGeneration(
1695
            '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',
1696
            'SELECT (c0_.id | 2) AS sclr_0, (c0_.id & 2) AS sclr_1 FROM cms_users c0_ WHERE (c0_.id & 4) > 0'
1697
        );
1698
        $this->assertSqlGeneration(
1699
            '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',
1700
            'SELECT (c0_.id | 2) AS sclr_0, (c0_.id & 2) AS sclr_1 FROM cms_users c0_ WHERE (c0_.id | 2) > 0 OR (c0_.id & 4) > 0'
1701
        );
1702
    }
1703
1704
    /**
1705
     * @group DDC-1539
1706
     */
1707
    public function testParenthesesOnTheLeftHandOfComparison()
1708
    {
1709
        $this->assertSqlGeneration(
1710
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where ( (u.id + u.id) * u.id ) > 100',
1711
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE ((c0_.id + c0_.id) * c0_.id) > 100'
1712
        );
1713
        $this->assertSqlGeneration(
1714
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where (u.id + u.id) * u.id > 100',
1715
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE (c0_.id + c0_.id) * c0_.id > 100'
1716
        );
1717
        $this->assertSqlGeneration(
1718
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where 100 < (u.id + u.id) * u.id ',
1719
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE 100 < (c0_.id + c0_.id) * c0_.id'
1720
        );
1721
    }
1722
1723
    public function testSupportsParenthesisExpressionInSubSelect() {
1724
        $this->assertSqlGeneration(
1725
            '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',
1726
            'SELECT c0_.id AS id_0, (SELECT (1000 * SUM(c1_.id) / SUM(c1_.id)) FROM cms_users c1_ WHERE c1_.id = c0_.id) AS sclr_1 FROM cms_users c0_'
1727
        );
1728
    }
1729
1730
    /**
1731
     * @group DDC-1557
1732
     */
1733
    public function testSupportsSubSqlFunction()
1734
    {
1735
        $this->assertSqlGeneration(
1736
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1737
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.name IN (SELECT TRIM(c1_.name) AS sclr_4 FROM cms_users c1_)'
1738
        );
1739
        $this->assertSqlGeneration(
1740
            '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%\')',
1741
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.name IN (SELECT TRIM(c1_.name) AS sclr_4 FROM cms_users c1_ WHERE LOWER(c1_.name) LIKE \'%fabio%\')'
1742
        );
1743
        $this->assertSqlGeneration(
1744
            '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 )',
1745
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.email_id IN (SELECT TRIM(c1_.email_id) AS sclr_4 FROM cms_users c1_)'
1746
        );
1747
        $this->assertSqlGeneration(
1748
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT IDENTITY(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1749
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.email_id IN (SELECT c1_.email_id AS sclr_4 FROM cms_users c1_)'
1750
        );
1751
        $this->assertSqlGeneration(
1752
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) = ( SELECT SUM(u2.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1753
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE COUNT(c0_.id) = (SELECT SUM(c1_.id) AS sclr_4 FROM cms_users c1_)'
1754
        );
1755
        $this->assertSqlGeneration(
1756
            '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 )',
1757
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE COUNT(c0_.id) <= (SELECT SUM(c1_.id) + COUNT(c1_.email_id) AS sclr_4 FROM cms_users c1_)'
1758
        );
1759
    }
1760
1761
    /**
1762
     * @group DDC-1574
1763
     */
1764
    public function testSupportsNewOperator()
1765
    {
1766
        $this->assertSqlGeneration(
1767
            "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",
1768
            "SELECT c0_.name AS sclr_0, c1_.email AS sclr_1, c2_.city AS sclr_2 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id"
1769
        );
1770
1771
        $this->assertSqlGeneration(
1772
            "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",
1773
            "SELECT c0_.name AS sclr_0, c1_.email AS sclr_1, c2_.id + c0_.id AS sclr_2 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id"
1774
        );
1775
1776
        $this->assertSqlGeneration(
1777
            "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",
1778
            "SELECT c0_.name AS sclr_0, c1_.email AS sclr_1, c2_.city AS sclr_2, COUNT(c3_.phonenumber) AS sclr_3 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id INNER JOIN cms_phonenumbers c3_ ON c0_.id = c3_.user_id"
1779
        );
1780
1781
        $this->assertSqlGeneration(
1782
            "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",
1783
            "SELECT c0_.name AS sclr_0, c1_.email AS sclr_1, c2_.city AS sclr_2, COUNT(c3_.phonenumber) + c0_.id AS sclr_3 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id INNER JOIN cms_phonenumbers c3_ ON c0_.id = c3_.user_id"
1784
        );
1785
1786
        $this->assertSqlGeneration(
1787
            "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",
1788
            "SELECT c0_.id AS sclr_0, c0_.country AS sclr_1, c0_.city AS sclr_2, c1_.name AS sclr_3, c2_.email AS sclr_4 FROM cms_users c1_ INNER JOIN cms_emails c2_ ON c1_.email_id = c2_.id INNER JOIN cms_addresses c0_ ON c1_.id = c0_.user_id ORDER BY c1_.name ASC"
1789
        );
1790
1791
        $this->assertSqlGeneration(
1792
            "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",
1793
            "SELECT c0_.id AS sclr_0, (SELECT 1 AS sclr_2 FROM cms_users c1_) AS sclr_1, c0_.country AS sclr_3, c0_.city AS sclr_4, c2_.name AS sclr_5, c3_.email AS sclr_6 FROM cms_users c2_ INNER JOIN cms_emails c3_ ON c2_.email_id = c3_.id INNER JOIN cms_addresses c0_ ON c2_.id = c0_.user_id ORDER BY c2_.name ASC"
1794
        );
1795
    }
1796
1797
    /**
1798
     * @group DDC-2234
1799
     */
1800
    public function testWhereFunctionIsNullComparisonExpression()
1801
    {
1802
        $this->assertSqlGeneration(
1803
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IS NULL",
1804
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.email_id IS NULL"
1805
        );
1806
1807
        $this->assertSqlGeneration(
1808
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NULLIF(u.name, 'FabioBatSilva') IS NULL AND IDENTITY(u.email) IS NOT NULL",
1809
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE NULLIF(c0_.name, 'FabioBatSilva') IS NULL AND c0_.email_id IS NOT NULL"
1810
        );
1811
1812
        $this->assertSqlGeneration(
1813
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IS NOT NULL",
1814
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE c0_.email_id IS NOT NULL"
1815
        );
1816
1817
        $this->assertSqlGeneration(
1818
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NULLIF(u.name, 'FabioBatSilva') IS NOT NULL",
1819
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE NULLIF(c0_.name, 'FabioBatSilva') IS NOT NULL"
1820
        );
1821
1822
        $this->assertSqlGeneration(
1823
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(u.name, u.id) IS NOT NULL",
1824
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE COALESCE(c0_.name, c0_.id) IS NOT NULL"
1825
        );
1826
1827
        $this->assertSqlGeneration(
1828
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(u.id, IDENTITY(u.email)) IS NOT NULL",
1829
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE COALESCE(c0_.id, c0_.email_id) IS NOT NULL"
1830
        );
1831
1832
        $this->assertSqlGeneration(
1833
            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(IDENTITY(u.email), NULLIF(u.name, 'FabioBatSilva')) IS NOT NULL",
1834
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ WHERE COALESCE(c0_.email_id, NULLIF(c0_.name, 'FabioBatSilva')) IS NOT NULL"
1835
        );
1836
    }
1837
1838 View Code Duplication
    public function testCustomTypeValueSql()
1839
    {
1840
        if (DBALType::hasType('negative_to_positive')) {
1841
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1842
        } else {
1843
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1844
        }
1845
1846
        $this->assertSqlGeneration(
1847
            'SELECT p.customInteger FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
1848
            'SELECT -(c0_.customInteger) AS customInteger_0 FROM customtype_parents c0_ WHERE c0_.id = 1'
1849
        );
1850
    }
1851
1852 View Code Duplication
    public function testCustomTypeValueSqlIgnoresIdentifierColumn()
1853
    {
1854
        if (DBALType::hasType('negative_to_positive')) {
1855
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1856
        } else {
1857
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1858
        }
1859
1860
        $this->assertSqlGeneration(
1861
            'SELECT p.id FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
1862
            'SELECT c0_.id AS id_0 FROM customtype_parents c0_ WHERE c0_.id = 1'
1863
        );
1864
    }
1865
1866 View Code Duplication
    public function testCustomTypeValueSqlForAllFields()
1867
    {
1868
        if (DBALType::hasType('negative_to_positive')) {
1869
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1870
        } else {
1871
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1872
        }
1873
1874
        $this->assertSqlGeneration(
1875
            'SELECT p FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
1876
            'SELECT c0_.id AS id_0, -(c0_.customInteger) AS customInteger_1 FROM customtype_parents c0_'
1877
        );
1878
    }
1879
1880 View Code Duplication
    public function testCustomTypeValueSqlForPartialObject()
1881
    {
1882
        if (DBALType::hasType('negative_to_positive')) {
1883
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1884
        } else {
1885
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1886
        }
1887
1888
        $this->assertSqlGeneration(
1889
            'SELECT partial p.{id, customInteger} FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
1890
            'SELECT c0_.id AS id_0, -(c0_.customInteger) AS customInteger_1 FROM customtype_parents c0_'
1891
        );
1892
    }
1893
1894
    /**
1895
     * @group DDC-1529
1896
     */
1897
    public function testMultipleFromAndInheritanceCondition()
1898
    {
1899
        $this->assertSqlGeneration(
1900
            'SELECT fix, flex FROM Doctrine\Tests\Models\Company\CompanyFixContract fix, Doctrine\Tests\Models\Company\CompanyFlexContract flex',
1901
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c1_.id AS id_3, c1_.completed AS completed_4, c1_.hoursWorked AS hoursWorked_5, c1_.pricePerHour AS pricePerHour_6, c1_.maxPrice AS maxPrice_7, c0_.discr AS discr_8, c1_.discr AS discr_9 FROM company_contracts c0_, company_contracts c1_ WHERE (c0_.discr IN ('fix') AND c1_.discr IN ('flexible', 'flexultra'))"
1902
        );
1903
    }
1904
1905
    /**
1906
     * @group DDC-775
1907
     */
1908
    public function testOrderByClauseSupportsSimpleArithmeticExpression()
1909
    {
1910
        $this->assertSqlGeneration(
1911
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.id + 1 ',
1912
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ ORDER BY c0_.id + 1 ASC'
1913
        );
1914
        $this->assertSqlGeneration(
1915
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY ( ( (u.id + 1) * (u.id - 1) ) / 2)',
1916
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ ORDER BY (((c0_.id + 1) * (c0_.id - 1)) / 2) ASC'
1917
        );
1918
        $this->assertSqlGeneration(
1919
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY ((u.id + 5000) * u.id + 3) ',
1920
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ ORDER BY ((c0_.id + 5000) * c0_.id + 3) ASC'
1921
        );
1922
    }
1923
1924
    public function testOrderByClauseSupportsFunction()
1925
    {
1926
        $this->assertSqlGeneration(
1927
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY CONCAT(u.username, u.name) ',
1928
            'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3 FROM cms_users c0_ ORDER BY c0_.username || c0_.name ASC'
1929
        );
1930
    }
1931
1932
    /**
1933
     * @group DDC-1719
1934
     */
1935
    public function testStripNonAlphanumericCharactersFromAlias()
1936
    {
1937
        $this->assertSqlGeneration(
1938
            'SELECT e FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e',
1939
            'SELECT n0_."simple-entity-id" AS simpleentityid_0, n0_."simple-entity-value" AS simpleentityvalue_1 FROM "not-a-simple-entity" n0_'
1940
        );
1941
1942
        $this->assertSqlGeneration(
1943
            'SELECT e.value FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e ORDER BY e.value',
1944
            'SELECT n0_."simple-entity-value" AS simpleentityvalue_0 FROM "not-a-simple-entity" n0_ ORDER BY n0_."simple-entity-value" ASC'
1945
        );
1946
1947
        $this->assertSqlGeneration(
1948
            'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e ORDER BY e.value',
1949
            'SELECT TRIM(n0_."simple-entity-value") AS sclr_0 FROM "not-a-simple-entity" n0_ ORDER BY n0_."simple-entity-value" ASC'
1950
        );
1951
    }
1952
1953
    /**
1954
     * @group DDC-2435
1955
     */
1956
    public function testColumnNameWithNumbersAndNonAlphanumericCharacters()
1957
    {
1958
        $this->assertSqlGeneration(
1959
            'SELECT e FROM Doctrine\Tests\Models\Quote\NumericEntity e',
1960
            'SELECT t0_."1:1" AS 11_0, t0_."2:2" AS 22_1 FROM table t0_'
1961
        );
1962
1963
        $this->assertSqlGeneration(
1964
            'SELECT e.value FROM Doctrine\Tests\Models\Quote\NumericEntity e',
1965
            'SELECT t0_."2:2" AS 22_0 FROM table t0_'
1966
        );
1967
1968
        $this->assertSqlGeneration(
1969
            'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Quote\NumericEntity e',
1970
            'SELECT TRIM(t0_."2:2") AS sclr_0 FROM table t0_'
1971
        );
1972
    }
1973
1974
    /**
1975
     * @group DDC-1845
1976
     */
1977
    public function testQuotedTableDeclaration()
1978
    {
1979
        $this->assertSqlGeneration(
1980
            'SELECT u FROM Doctrine\Tests\Models\Quote\User u',
1981
            'SELECT q0_."user-id" AS userid_0, q0_."user-name" AS username_1 FROM "quote-user" q0_'
1982
        );
1983
    }
1984
1985
   /**
1986
    * @group DDC-1845
1987
    */
1988
    public function testQuotedWalkJoinVariableDeclaration()
1989
    {
1990
        $this->assertSqlGeneration(
1991
            'SELECT u, a FROM Doctrine\Tests\Models\Quote\User u JOIN u.address a',
1992
            'SELECT q0_."user-id" AS userid_0, q0_."user-name" AS username_1, q1_."address-id" AS addressid_2, q1_."address-zip" AS addresszip_3, q1_.type AS type_4 FROM "quote-user" q0_ INNER JOIN "quote-address" q1_ ON q0_."address-id" = q1_."address-id" AND q1_.type IN (\'simple\', \'full\')'
1993
        );
1994
1995
        $this->assertSqlGeneration(
1996
            'SELECT u, p FROM Doctrine\Tests\Models\Quote\User u JOIN u.phones p',
1997
            'SELECT q0_."user-id" AS userid_0, q0_."user-name" AS username_1, q1_."phone-number" AS phonenumber_2 FROM "quote-user" q0_ INNER JOIN "quote-phone" q1_ ON q0_."user-id" = q1_."user-id"'
1998
        );
1999
2000
        $this->assertSqlGeneration(
2001
            'SELECT u, g FROM Doctrine\Tests\Models\Quote\User u JOIN u.groups g',
2002
            'SELECT q0_."user-id" AS userid_0, q0_."user-name" AS username_1, q1_."group-id" AS groupid_2, q1_."group-name" AS groupname_3 FROM "quote-user" q0_ INNER JOIN "quote-users-groups" q2_ ON q0_."user-id" = q2_."user-id" INNER JOIN "quote-group" q1_ ON q1_."group-id" = q2_."group-id"'
2003
        );
2004
2005
        $this->assertSqlGeneration(
2006
            'SELECT a, u FROM Doctrine\Tests\Models\Quote\Address a JOIN a.user u',
2007
            'SELECT q0_."address-id" AS addressid_0, q0_."address-zip" AS addresszip_1, q1_."user-id" AS userid_2, q1_."user-name" AS username_3, q0_.type AS type_4 FROM "quote-address" q0_ INNER JOIN "quote-user" q1_ ON q0_."user-id" = q1_."user-id" WHERE q0_.type IN (\'simple\', \'full\')'
2008
        );
2009
2010
        $this->assertSqlGeneration(
2011
            'SELECT g, u FROM Doctrine\Tests\Models\Quote\Group g JOIN g.users u',
2012
            'SELECT q0_."group-id" AS groupid_0, q0_."group-name" AS groupname_1, q1_."user-id" AS userid_2, q1_."user-name" AS username_3 FROM "quote-group" q0_ INNER JOIN "quote-users-groups" q2_ ON q0_."group-id" = q2_."group-id" INNER JOIN "quote-user" q1_ ON q1_."user-id" = q2_."user-id"'
2013
        );
2014
2015
        $this->assertSqlGeneration(
2016
            'SELECT g, p FROM Doctrine\Tests\Models\Quote\Group g JOIN g.parent p',
2017
            'SELECT q0_."group-id" AS groupid_0, q0_."group-name" AS groupname_1, q1_."group-id" AS groupid_2, q1_."group-name" AS groupname_3 FROM "quote-group" q0_ INNER JOIN "quote-group" q1_ ON q0_."parent-id" = q1_."group-id"'
2018
        );
2019
    }
2020
2021
   /**
2022
    * @group DDC-2208
2023
    */
2024
    public function testCaseThenParameterArithmeticExpression()
2025
    {
2026
        $this->assertSqlGeneration(
2027
            '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',
2028
            'SELECT SUM(CASE WHEN c0_.salary <= ? THEN c0_.salary - ? WHEN c0_.salary >= ? THEN ? - c0_.salary ELSE 0 END) AS sclr_0 FROM company_employees c0_ INNER JOIN company_persons c1_ ON c0_.id = c1_.id'
2029
        );
2030
2031
        $this->assertSqlGeneration(
2032
            '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',
2033
            'SELECT SUM(CASE WHEN c0_.salary <= ? THEN c0_.salary - ? WHEN c0_.salary >= ? THEN ? - c0_.salary ELSE c0_.salary + 0 END) AS sclr_0 FROM company_employees c0_ INNER JOIN company_persons c1_ ON c0_.id = c1_.id'
2034
        );
2035
2036
        $this->assertSqlGeneration(
2037
            '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',
2038
            'SELECT SUM(CASE WHEN c0_.salary <= ? THEN (c0_.salary - ?) WHEN c0_.salary >= ? THEN (? - c0_.salary) ELSE (c0_.salary + ?) END) AS sclr_0 FROM company_employees c0_ INNER JOIN company_persons c1_ ON c0_.id = c1_.id'
2039
        );
2040
    }
2041
2042
    /**
2043
    * @group DDC-2268
2044
    */
2045
    public function testCaseThenFunction()
2046
    {
2047
        $this->assertSqlGeneration(
2048
            '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',
2049
            'SELECT CASE WHEN LENGTH(c0_.name) <> 0 THEN c0_.id || c0_.name ELSE c0_.id END AS sclr_0 FROM cms_users c0_'
2050
        );
2051
2052
        $this->assertSqlGeneration(
2053
            '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',
2054
            'SELECT CASE WHEN LENGTH(c0_.name) <> LENGTH(TRIM(c0_.name)) THEN TRIM(c0_.name) ELSE c0_.name END AS sclr_0 FROM cms_users c0_'
2055
        );
2056
2057
        $this->assertSqlGeneration(
2058
            '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',
2059
            'SELECT CASE WHEN LENGTH(c0_.name) > ? THEN SUBSTRING(c0_.name FROM 0 FOR ?) ELSE TRIM(c0_.name) END AS sclr_0 FROM cms_users c0_'
2060
        );
2061
    }
2062
2063
    /**
2064
     * @group DDC-2268
2065
     */
2066
    public function testSupportsMoreThanTwoParametersInConcatFunction()
2067
    {
2068
    	$connMock    = $this->_em->getConnection();
2069
    	$orgPlatform = $connMock->getDatabasePlatform();
2070
2071
    	$connMock->setDatabasePlatform(new MySqlPlatform());
2072
    	$this->assertSqlGeneration(
2073
            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
2074
            "SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE CONCAT(c0_.name, c0_.status, 's') = ?"
2075
    	);
2076
    	$this->assertSqlGeneration(
2077
            "SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
2078
            "SELECT CONCAT(c0_.id, c0_.name, c0_.status) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?"
2079
    	);
2080
2081
    	$connMock->setDatabasePlatform(new PostgreSqlPlatform());
2082
    	$this->assertSqlGeneration(
2083
            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
2084
            "SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE c0_.name || c0_.status || 's' = ?"
2085
    	);
2086
    	$this->assertSqlGeneration(
2087
            "SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
2088
            "SELECT c0_.id || c0_.name || c0_.status AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?"
2089
    	);
2090
2091
    	$connMock->setDatabasePlatform(new SQLServerPlatform());
2092
    	$this->assertSqlGeneration(
2093
            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
2094
            "SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE (c0_.name + c0_.status + 's') = ?"
2095
    	);
2096
    	$this->assertSqlGeneration(
2097
            "SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
2098
            "SELECT (c0_.id + c0_.name + c0_.status) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?"
2099
    	);
2100
2101
    	$connMock->setDatabasePlatform($orgPlatform);
2102
    }
2103
2104
     /**
2105
     * @group DDC-2188
2106
     */
2107
    public function testArithmeticPriority()
2108
    {
2109
        $this->assertSqlGeneration(
2110
            'SELECT 100/(2*2) FROM Doctrine\Tests\Models\CMS\CmsUser u',
2111
            'SELECT 100 / (2 * 2) AS sclr_0 FROM cms_users c0_'
2112
        );
2113
2114
        $this->assertSqlGeneration(
2115
            'SELECT (u.id / (u.id * 2)) FROM Doctrine\Tests\Models\CMS\CmsUser u',
2116
            'SELECT (c0_.id / (c0_.id * 2)) AS sclr_0 FROM cms_users c0_'
2117
        );
2118
2119
        $this->assertSqlGeneration(
2120
            'SELECT 100/(2*2) + (u.id / (u.id * 2)) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id / (u.id * 2)) > 0',
2121
            'SELECT 100 / (2 * 2) + (c0_.id / (c0_.id * 2)) AS sclr_0 FROM cms_users c0_ WHERE (c0_.id / (c0_.id * 2)) > 0'
2122
        );
2123
    }
2124
2125
    /**
2126
    * @group DDC-2475
2127
    */
2128
    public function testOrderByClauseShouldReplaceOrderByRelationMapping()
2129
    {
2130
        $this->assertSqlGeneration(
2131
            'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b',
2132
            'SELECT r0_.id AS id_0, r1_.id AS id_1, r1_.passengerName AS passengerName_2 FROM RoutingRoute r0_ INNER JOIN RoutingRouteBooking r1_ ON r0_.id = r1_.route_id ORDER BY r1_.passengerName ASC'
2133
        );
2134
2135
        $this->assertSqlGeneration(
2136
            'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b ORDER BY b.passengerName DESC',
2137
            'SELECT r0_.id AS id_0, r1_.id AS id_1, r1_.passengerName AS passengerName_2 FROM RoutingRoute r0_ INNER JOIN RoutingRouteBooking r1_ ON r0_.id = r1_.route_id ORDER BY r1_.passengerName DESC'
2138
        );
2139
    }
2140
2141
    /**
2142
     * @group DDC-1858
2143
     */
2144
    public function testHavingSupportIsNullExpression()
2145
    {
2146
        $this->assertSqlGeneration(
2147
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING u.username IS NULL',
2148
            'SELECT c0_.name AS name_0 FROM cms_users c0_ HAVING c0_.username IS NULL'
2149
        );
2150
2151
        $this->assertSqlGeneration(
2152
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING MAX(u.name) IS NULL',
2153
            'SELECT c0_.name AS name_0 FROM cms_users c0_ HAVING MAX(c0_.name) IS NULL'
2154
        );
2155
    }
2156
2157
    /**
2158
     * @group DDC-2506
2159
     */
2160
    public function testClassTableInheritanceJoinWithConditionAppliesToBaseTable()
2161
    {
2162
        $this->assertSqlGeneration(
2163
            'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1',
2164
            'SELECT c0_.id AS id_0 FROM company_organizations c1_ INNER JOIN (company_events c0_ LEFT JOIN company_auctions c2_ ON c0_.id = c2_.id LEFT JOIN company_raffles c3_ ON c0_.id = c3_.id) ON c1_.id = c0_.org_id AND (c0_.id = ?)',
2165
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
2166
        );
2167
    }
2168
2169
    /**
2170
     * @group DDC-2235
2171
     */
2172
    public function testSingleTableInheritanceLeftJoinWithCondition()
2173
    {
2174
        // Regression test for the bug
2175
        $this->assertSqlGeneration(
2176
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id',
2177
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_employees c1_ INNER JOIN company_persons c2_ ON c1_.id = c2_.id LEFT JOIN company_contracts c0_ ON (c0_.salesPerson_id = c2_.id) AND c0_.discr IN ('fix', 'flexible', 'flexultra')"
2178
        );
2179
    }
2180
2181
    /**
2182
     * @group DDC-2235
2183
     */
2184
    public function testSingleTableInheritanceLeftJoinWithConditionAndWhere()
2185
    {
2186
        // Ensure other WHERE predicates are passed through to the main WHERE clause
2187
        $this->assertSqlGeneration(
2188
            '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',
2189
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_employees c1_ INNER JOIN company_persons c2_ ON c1_.id = c2_.id LEFT JOIN company_contracts c0_ ON (c0_.salesPerson_id = c2_.id) AND c0_.discr IN ('fix', 'flexible', 'flexultra') WHERE c1_.salary > 1000"
2190
        );
2191
    }
2192
2193
    /**
2194
     * @group DDC-2235
2195
     */
2196
    public function testSingleTableInheritanceInnerJoinWithCondition()
2197
    {
2198
        // Test inner joins too
2199
        $this->assertSqlGeneration(
2200
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e INNER JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id',
2201
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_employees c1_ INNER JOIN company_persons c2_ ON c1_.id = c2_.id INNER JOIN company_contracts c0_ ON (c0_.salesPerson_id = c2_.id) AND c0_.discr IN ('fix', 'flexible', 'flexultra')"
2202
        );
2203
    }
2204
2205
    /**
2206
     * @group DDC-2235
2207
     */
2208
    public function testSingleTableInheritanceLeftJoinNonAssociationWithConditionAndWhere()
2209
    {
2210
        // Test that the discriminator IN() predicate is still added into
2211
        // the where clause when not joining onto that table
2212
        $this->assertSqlGeneration(
2213
            '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',
2214
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_contracts c0_ LEFT JOIN company_employees c1_ INNER JOIN company_persons c2_ ON c1_.id = c2_.id ON (c2_.id = c0_.salesPerson_id) WHERE (c0_.completed = 1) AND c0_.discr IN ('fix', 'flexible', 'flexultra')"
2215
        );
2216
    }
2217
2218
    /**
2219
     * @group DDC-2235
2220
     */
2221
    public function testSingleTableInheritanceJoinCreatesOnCondition()
2222
    {
2223
        // Test that the discriminator IN() predicate is still added
2224
        // into the where clause when not joining onto a single table inheritance entity
2225
        // via a join association
2226
        $this->assertSqlGeneration(
2227
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson s WHERE c.completed = true',
2228
            "SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_contracts c0_ INNER JOIN company_employees c1_ ON c0_.salesPerson_id = c1_.id LEFT JOIN company_persons c2_ ON c1_.id = c2_.id WHERE (c0_.completed = 1) AND c0_.discr IN ('fix', 'flexible', 'flexultra')"
2229
        );
2230
    }
2231
2232
    /**
2233
     * @group DDC-2235
2234
     */
2235
    public function testSingleTableInheritanceCreatesOnConditionAndWhere()
2236
    {
2237
        // Test that when joining onto an entity using single table inheritance via
2238
        // a join association that the discriminator IN() predicate is placed
2239
        // into the ON clause of the join
2240
        $this->assertSqlGeneration(
2241
            'SELECT e, COUNT(c) FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN e.contracts c WHERE e.department = :department',
2242
            "SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, COUNT(c2_.id) AS sclr_5, c0_.discr AS discr_6 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id INNER JOIN company_contract_employees c3_ ON c1_.id = c3_.employee_id INNER JOIN company_contracts c2_ ON c2_.id = c3_.contract_id AND c2_.discr IN ('fix', 'flexible', 'flexultra') WHERE c1_.department = ?",
2243
            [],
2244
            ['department' => 'foobar']
2245
        );
2246
    }
2247
2248
    /**
2249
     * @group DDC-1858
2250
     */
2251
    public function testHavingSupportResultVariableInExpression()
2252
    {
2253
        $this->assertSqlGeneration(
2254
            'SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo IN (?1)',
2255
            'SELECT c0_.name AS name_0 FROM cms_users c0_ HAVING name_0 IN (?)'
2256
        );
2257
    }
2258
2259
    /**
2260
     * @group DDC-1858
2261
     */
2262
    public function testHavingSupportResultVariableLikeExpression()
2263
    {
2264
        $this->assertSqlGeneration(
2265
            "SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo LIKE '3'",
2266
            "SELECT c0_.name AS name_0 FROM cms_users c0_ HAVING name_0 LIKE '3'"
2267
        );
2268
    }
2269
2270
    /**
2271
     * @group DDC-3085
2272
     */
2273
    public function testHavingSupportResultVariableNullComparisonExpression()
2274
    {
2275
        $this->assertSqlGeneration(
2276
            "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",
2277
            "SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, SUM(c1_.id) AS sclr_4 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON (c1_.user_id = c0_.id) GROUP BY c0_.id, c0_.status, c0_.username, c0_.name, c0_.email_id HAVING sclr_4 IS NOT NULL AND sclr_4 >= 5"
2278
        );
2279
    }
2280
2281
    /**
2282
     * @group DDC-1858
2283
     */
2284
    public function testHavingSupportResultVariableInAggregateFunction()
2285
    {
2286
        $this->assertSqlGeneration(
2287
            'SELECT COUNT(u.name) AS countName FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING countName IS NULL',
2288
            'SELECT COUNT(c0_.name) AS sclr_0 FROM cms_users c0_ HAVING sclr_0 IS NULL'
2289
        );
2290
    }
2291
2292
    /**
2293
     * GitHub issue #4764: https://github.com/doctrine/doctrine2/issues/4764
2294
     * @group DDC-3907
2295
     * @dataProvider mathematicOperatorsProvider
2296
     */
2297
    public function testHavingRegressionUsingVariableWithMathOperatorsExpression($operator)
2298
    {
2299
        $this->assertSqlGeneration(
2300
            'SELECT COUNT(u.name) AS countName FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING 1 ' . $operator . ' countName > 0',
2301
            'SELECT COUNT(c0_.name) AS sclr_0 FROM cms_users c0_ HAVING 1 ' . $operator . ' sclr_0 > 0'
2302
        );
2303
    }
2304
2305
    /**
2306
     * @return array
2307
     */
2308
    public function mathematicOperatorsProvider()
2309
    {
2310
        return [['+'], ['-'], ['*'], ['/']];
2311
    }
2312
}
2313
2314 View Code Duplication
class MyAbsFunction extends FunctionNode
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2315
{
2316
    public $simpleArithmeticExpression;
2317
2318
    /**
2319
     * @override
2320
     */
2321
    public function getSql(SqlWalker $sqlWalker)
2322
    {
2323
        return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')';
0 ignored issues
show
Bug introduced by
It seems like $this->simpleArithmeticExpression can be null; however, walkSimpleArithmeticExpression() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2324
    }
2325
2326
    /**
2327
     * @override
2328
     */
2329
    public function parse(Parser $parser)
2330
    {
2331
        $lexer = $parser->getLexer();
0 ignored issues
show
Unused Code introduced by
$lexer is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2332
2333
        $parser->match(Lexer::T_IDENTIFIER);
2334
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
2335
2336
        $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
2337
2338
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
2339
    }
2340
}
2341
/**
2342
 * @Entity
2343
 */
2344
class DDC1384Model
2345
{
2346
    /**
2347
     * @Id
2348
     * @Column(type="integer")
2349
     * @GeneratedValue
2350
     */
2351
    protected $aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo;
2352
}
2353
2354
2355
/**
2356
 * @Entity
2357
 */
2358
class DDC1474Entity
2359
{
2360
2361
    /**
2362
     * @Id
2363
     * @Column(type="integer")
2364
     * @GeneratedValue()
2365
     */
2366
    protected $id;
2367
2368
    /**
2369
     * @column(type="float")
2370
     */
2371
    private $value;
2372
2373
    /**
2374
     * @param string $float
2375
     */
2376
    public function __construct($float)
2377
    {
2378
        $this->value = $float;
2379
    }
2380
2381
    /**
2382
     * @return int
2383
     */
2384
    public function getId()
2385
    {
2386
        return $this->id;
2387
    }
2388
2389
    /**
2390
     * @return float
2391
     */
2392
    public function getValue()
2393
    {
2394
        return $this->value;
2395
    }
2396
2397
    /**
2398
     * @param float $value
2399
     */
2400
    public function setValue($value)
2401
    {
2402
        $this->value = $value;
2403
    }
2404
2405
}
2406