Completed
Push — 2.6 ( 3cfcd6...36e6a7 )
by Luís
25s queued 18s
created

testStringPrimaryAcceptsAggregateExpression()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Doctrine\Tests\ORM\Query;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Doctrine\ORM\Query,
7
    Doctrine\ORM\Query\QueryException;
8
use Doctrine\Tests\Mocks\MockTreeWalker;
9
use Doctrine\Tests\OrmTestCase;
10
11
class LanguageRecognitionTest extends OrmTestCase
12
{
13
    /**
14
     * @var EntityManagerInterface
15
     */
16
    private $_em;
17
18
    protected function setUp()
19
    {
20
        $this->_em = $this->_getTestEntityManager();
21
    }
22
23
    public function assertValidDQL($dql, $debug = false)
24
    {
25
        try {
26
            $parserResult = $this->parseDql($dql);
0 ignored issues
show
Unused Code introduced by
The assignment to $parserResult is dead and can be removed.
Loading history...
27
            $this->addToAssertionCount(1);
28
        } catch (QueryException $e) {
29
            if ($debug) {
30
                echo $e->getTraceAsString() . PHP_EOL;
31
            }
32
33
            $this->fail($e->getMessage());
34
        }
35
    }
36
37
    public function assertInvalidDQL($dql, $debug = false)
38
    {
39
        try {
40
            $parserResult = $this->parseDql($dql);
0 ignored issues
show
Unused Code introduced by
The assignment to $parserResult is dead and can be removed.
Loading history...
41
42
            $this->fail('No syntax errors were detected, when syntax errors were expected');
43
        } catch (QueryException $e) {
44
            if ($debug) {
45
                echo $e->getMessage() . PHP_EOL;
46
                echo $e->getTraceAsString() . PHP_EOL;
47
            }
48
            $this->addToAssertionCount(1);
49
        }
50
    }
51
52
    public function parseDql($dql, $hints = [])
53
    {
54
        $query = $this->_em->createQuery($dql);
55
        $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
56
        $query->setDQL($dql);
57
58
        foreach ($hints as $key => $value) {
59
        	$query->setHint($key, $value);
60
        }
61
62
        $parser = new Query\Parser($query);
63
64
        // We do NOT test SQL output here. That only unnecessarily slows down the tests!
65
        $parser->setCustomOutputTreeWalker(MockTreeWalker::class);
66
67
        return $parser->parse();
68
    }
69
70
    public function testEmptyQueryString()
71
    {
72
        $this->assertInvalidDQL('');
73
    }
74
75
    public function testPlainFromClauseWithAlias()
76
    {
77
        $this->assertValidDQL('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u');
78
    }
79
80
    public function testSelectSingleComponentWithAsterisk()
81
    {
82
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u');
83
    }
84
85
    /**
86
     * @dataProvider invalidDQL
87
     */
88
    public function testRejectsInvalidDQL($dql)
89
    {
90
        $this->expectException(QueryException::class);
91
92
        $this->_em->getConfiguration()->setEntityNamespaces(
93
            [
94
            'Unknown' => 'Unknown',
95
            'CMS' => 'Doctrine\Tests\Models\CMS'
96
            ]
97
        );
98
99
        $this->parseDql($dql);
100
    }
101
102
    public function invalidDQL()
103
    {
104
        return [
105
106
            ['SELECT \'foo\' AS foo\bar FROM Doctrine\Tests\Models\CMS\CmsUser u'],
107
            /* Checks for invalid IdentificationVariables and AliasIdentificationVariables */
108
            ['SELECT \foo FROM Doctrine\Tests\Models\CMS\CmsUser \foo'],
109
            ['SELECT foo\ FROM Doctrine\Tests\Models\CMS\CmsUser foo\\'],
110
            ['SELECT foo\bar FROM Doctrine\Tests\Models\CMS\CmsUser foo\bar'],
111
            ['SELECT foo:bar FROM Doctrine\Tests\Models\CMS\CmsUser foo:bar'],
112
            ['SELECT foo: FROM Doctrine\Tests\Models\CMS\CmsUser foo:'],
113
114
            /* Checks for invalid AbstractSchemaName */
115
            ['SELECT u FROM UnknownClass u'],  // unknown
116
            ['SELECT u FROM Unknown\Class u'], // unknown with namespace
117
            ['SELECT u FROM \Unknown\Class u'], // unknown, leading backslash
118
            ['SELECT u FROM Unknown\\\\Class u'], // unknown, syntactically bogus (duplicate \\)
119
            ['SELECT u FROM Unknown\Class\ u'], // unknown, syntactically bogus (trailing \)
120
            ['SELECT u FROM Unknown:Class u'], // unknown, with namespace alias
121
            ['SELECT u FROM Unknown::Class u'], // unknown, with PAAMAYIM_NEKUDOTAYIM
122
            ['SELECT u FROM Unknown:Class:Name u'], // unknown, with invalid namespace alias
123
            ['SELECT u FROM UnknownClass: u'], // unknown, with invalid namespace alias
124
            ['SELECT u FROM Unknown:Class: u'], // unknown, with invalid namespace alias
125
            ['SELECT u FROM Doctrine\Tests\Models\CMS\\\\CmsUser u'], // syntactically bogus (duplicate \\)array('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser\ u'), // syntactically bogus (trailing \)
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
126
            ['SELECT u FROM CMS::User u'],
127
            ['SELECT u FROM CMS:User: u'],
128
            ['SELECT u FROM CMS:User:Foo u'],
129
130
            /* Checks for invalid AliasResultVariable */
131
            ['SELECT \'foo\' AS \foo FROM Doctrine\Tests\Models\CMS\CmsUser u'],
132
            ['SELECT \'foo\' AS \foo\bar FROM Doctrine\Tests\Models\CMS\CmsUser u'],
133
            ['SELECT \'foo\' AS foo\ FROM Doctrine\Tests\Models\CMS\CmsUser u'],
134
            ['SELECT \'foo\' AS foo\\\\bar FROM Doctrine\Tests\Models\CMS\CmsUser u'],
135
            ['SELECT \'foo\' AS foo: FROM Doctrine\Tests\Models\CMS\CmsUser u'],
136
            ['SELECT \'foo\' AS foo:bar FROM Doctrine\Tests\Models\CMS\CmsUser u'],
137
        ];
138
    }
139
140
    public function testSelectSingleComponentWithMultipleColumns()
141
    {
142
        $this->assertValidDQL('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u');
143
    }
144
145
    public function testSelectMultipleComponentsUsingMultipleFrom()
146
    {
147
        $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user');
148
    }
149
150
    public function testSelectMultipleComponentsWithAsterisk()
151
    {
152
        $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
153
    }
154
155
    public function testSelectDistinctIsSupported()
156
    {
157
        $this->assertValidDQL('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u');
158
    }
159
160
    public function testAggregateFunctionInSelect()
161
    {
162
        $this->assertValidDQL('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
163
    }
164
165
    public function testMultipleParenthesisInSelect()
166
    {
167
        $this->assertValidDQL('SELECT (((u.id))) as v FROM Doctrine\Tests\Models\CMS\CmsUser u');
168
    }
169
170
    public function testDuplicatedAliasInAggregateFunction()
171
    {
172
        $this->assertInvalidDQL('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u');
173
    }
174
175
    public function testAggregateFunctionWithDistinctInSelect()
176
    {
177
        $this->assertValidDQL('SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u');
178
    }
179
180
    public function testFunctionalExpressionsSupportedInWherePart()
181
    {
182
        $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'");
183
    }
184
185
    public function testArithmeticExpressionsSupportedInWherePart()
186
    {
187
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000');
188
    }
189
190
    public function testInExpressionSupportedInWherePart()
191
    {
192
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)');
193
    }
194
195
    public function testInExpressionWithoutSpacesSupportedInWherePart()
196
    {
197
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1,2,3)');
198
    }
199
200
    public function testNotInExpressionSupportedInWherePart()
201
    {
202
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)');
203
    }
204
205
    public function testInExpressionWithSingleValuedAssociationPathExpression()
206
    {
207
        $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)");
208
    }
209
210
    public function testInvalidInExpressionWithCollectionValuedAssociationPathExpression()
211
    {
212
        $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IN (?1, ?2)");
213
    }
214
215
    public function testInstanceOfExpressionSupportedInWherePart()
216
    {
217
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
218
    }
219
220
    public function testInstanceOfExpressionWithInputParamSupportedInWherePart()
221
    {
222
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1');
223
    }
224
225
    public function testNotInstanceOfExpressionSupportedInWherePart()
226
    {
227
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u NOT INSTANCE OF ?1');
228
    }
229
230
    public function testExistsExpressionSupportedInWherePart()
231
    {
232
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
233
    }
234
235
    public function testNotExistsExpressionSupportedInWherePart()
236
    {
237
        $this->assertValidDQL('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)');
238
    }
239
240
    public function testAggregateFunctionInHavingClause()
241
    {
242
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING COUNT(p.phonenumber) > 2');
243
        $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING MAX(u.name) = 'romanb'");
244
    }
245
246
    public function testLeftJoin()
247
    {
248
        $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p');
249
    }
250
251
    public function testJoin()
252
    {
253
        $this->assertValidDQL('SELECT u,p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
254
    }
255
256
    public function testInnerJoin()
257
    {
258
        $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p');
259
    }
260
261
    public function testMultipleLeftJoin()
262
    {
263
        $this->assertValidDQL('SELECT u, a, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a LEFT JOIN u.phonenumbers p');
264
    }
265
266
    public function testMultipleInnerJoin()
267
    {
268
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INNER JOIN u.phonenumbers p');
269
    }
270
271
    public function testMixingOfJoins()
272
    {
273
        $this->assertValidDQL('SELECT u.name, a.topic, p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a LEFT JOIN u.phonenumbers p');
274
    }
275
276
    public function testJoinClassPathUsingWITH()
277
    {
278
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN Doctrine\Tests\Models\CMS\CmsArticle a WITH a.user = u.id');
279
    }
280
281
    /**
282
     * @group DDC-3701
283
     */
284
    public function testJoinClassPathUsingWHERE()
285
    {
286
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.user = u.id');
287
    }
288
289
    /**
290
     * @group DDC-3701
291
     */
292
    public function testDDC3701WHEREIsNotWITH()
293
    {
294
        $this->assertInvalidDQL('SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN Doctrine\Tests\Models\Company\CompanyEmployee e WHERE e.id = c.salesPerson WHERE c.completed = true');
295
    }
296
297
    public function testOrderBySingleColumn()
298
    {
299
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name');
300
    }
301
302
    public function testOrderBySingleColumnAscending()
303
    {
304
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name ASC');
305
    }
306
307
    public function testOrderBySingleColumnDescending()
308
    {
309
        $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name DESC');
310
    }
311
312
    public function testOrderByMultipleColumns()
313
    {
314
        $this->assertValidDQL('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username DESC, u.name DESC');
315
    }
316
317
    public function testSubselectInInExpression()
318
    {
319
        $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = 'zYne')");
320
    }
321
322
    public function testSubselectInSelectPart()
323
    {
324
        $this->assertValidDQL("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'");
325
    }
326
327
    public function testArithmeticExpressionInSelectPart()
328
    {
329
        $this->assertValidDQL("SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u");
330
    }
331
332
    public function testArithmeticExpressionInSubselectPart()
333
    {
334
        $this->assertValidDQL("SELECT (SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
335
    }
336
337
    public function testArithmeticExpressionWithParenthesisInSubselectPart()
338
    {
339
        $this->assertValidDQL("SELECT (SELECT (SUM(u.id) / COUNT(u.id)) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
340
    }
341
342
    /**
343
     * @group DDC-1079
344
     */
345
    public function testSelectLiteralInSubselect()
346
    {
347
        $this->assertValidDQL('SELECT (SELECT 1 FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u');
348
        $this->assertValidDQL('SELECT (SELECT 0 FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u');
349
    }
350
351
    /**
352
     * @group DDC-1077
353
     */
354
    public function testConstantValueInSelect()
355
    {
356
        $this->assertValidDQL("SELECT u.name, 'foo' AS bar FROM Doctrine\Tests\Models\CMS\CmsUser u", true);
357
    }
358
359
    public function testDuplicateAliasInSubselectPart()
360
    {
361
        $this->assertInvalidDQL("SELECT (SELECT SUM(u.id) / COUNT(u.id) AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u2) foo FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
362
    }
363
364
    public function testPositionalInputParameter()
365
    {
366
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1');
367
    }
368
369
    public function testNamedInputParameter()
370
    {
371
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id');
372
    }
373
374
    public function testJoinConditionOverrideNotSupported()
375
    {
376
        $this->assertInvalidDQL("SELECT u.name, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p ON p.phonenumber = '123 123'");
377
    }
378
379
    public function testIndexByClauseWithOneComponent()
380
    {
381
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id');
382
    }
383
384
    public function testIndexBySupportsJoins()
385
    {
386
        $this->assertValidDQL('SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a INDEX BY a.id'); // INDEX BY is now referring to articles
387
    }
388
389
    public function testIndexBySupportsJoins2()
390
    {
391
        $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p INDEX BY p.phonenumber');
392
    }
393
394
    public function testBetweenExpressionSupported()
395
    {
396
        $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name BETWEEN 'jepso' AND 'zYne'");
397
    }
398
399
    public function testNotBetweenExpressionSupported()
400
    {
401
        $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT BETWEEN 'jepso' AND 'zYne'");
402
    }
403
404
    public function testLikeExpression()
405
    {
406
        $this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z%'");
407
    }
408
409
    public function testNotLikeExpression()
410
    {
411
        $this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT LIKE 'z%'");
412
    }
413
414
    public function testLikeExpressionWithCustomEscapeCharacter()
415
    {
416
        $this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'");
417
    }
418
419
    public function testFieldComparisonWithoutAlias()
420
    {
421
        $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE id = 1");
422
    }
423
424
    public function testDuplicatedAliasDeclaration()
425
    {
426
        $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles u WHERE u.id = 1");
427
    }
428
429
    public function testImplicitJoinInWhereOnSingleValuedAssociationPathExpression()
430
    {
431
        // This should be allowed because avatar is a single-value association.
432
        // SQL: SELECT ... FROM forum_user fu INNER JOIN forum_avatar fa ON fu.avatar_id = fa.id WHERE fa.id = ?
433
        $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a WHERE a.id = ?1");
434
    }
435
436
    public function testImplicitJoinInWhereOnCollectionValuedPathExpression()
437
    {
438
        // This should be forbidden, because articles is a collection
439
        $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a WHERE a.title = ?");
440
    }
441
442
    public function testInvalidSyntaxIsRejected()
443
    {
444
        $this->assertInvalidDQL("FOOBAR CmsUser");
445
        $this->assertInvalidDQL("DELETE FROM Doctrine\Tests\Models\CMS\CmsUser.articles");
446
        $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles.comments");
447
448
        // Currently UNDEFINED OFFSET error
449
        $this->assertInvalidDQL("SELECT c FROM CmsUser.articles.comments c");
450
    }
451
452
    public function testUpdateWorksWithOneField()
453
    {
454
        $this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone'");
455
    }
456
457
    public function testUpdateWorksWithMultipleFields()
458
    {
459
        $this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone', u.username = 'some'");
460
    }
461
462
    public function testUpdateSupportsConditions()
463
    {
464
        $this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone' WHERE u.id = 5");
465
    }
466
467
    public function testDeleteAll()
468
    {
469
        $this->assertValidDQL('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u');
470
    }
471
472
    public function testDeleteWithCondition()
473
    {
474
        $this->assertValidDQL('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = 3');
475
    }
476
477
    /**
478
     * The main use case for this generalized style of join is when a join condition
479
     * does not involve a foreign key relationship that is mapped to an entity relationship.
480
     */
481
    public function testImplicitJoinWithCartesianProductAndConditionInWhere()
482
    {
483
        $this->assertValidDQL("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.name = a.topic");
484
    }
485
486
    public function testAllExpressionWithCorrelatedSubquery()
487
    {
488
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
489
    }
490
491
    public function testCustomJoinsAndWithKeywordSupported()
492
    {
493
        $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p WITH p.phonenumber = 123 WHERE u.id = 1');
494
    }
495
496
    public function testAnyExpressionWithCorrelatedSubquery()
497
    {
498
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ANY (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
499
    }
500
501
    public function testSomeExpressionWithCorrelatedSubquery()
502
    {
503
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
504
    }
505
506
    public function testArithmeticExpressionWithoutParenthesisInWhereClause()
507
    {
508
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) + 1 > 10');
509
    }
510
511
    public function testMemberOfExpression()
512
    {
513
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
514
        //$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE 'Joe' MEMBER OF u.nicknames");
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
515
    }
516
517
    public function testSizeFunction()
518
    {
519
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1');
520
    }
521
522
    public function testEmptyCollectionComparisonExpression()
523
    {
524
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY');
525
    }
526
527
    public function testSingleValuedAssociationFieldInWhere()
528
    {
529
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
530
        $this->assertValidDQL('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1');
531
    }
532
533
    public function testBooleanLiteralInWhere()
534
    {
535
        $this->assertValidDQL('SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true');
536
    }
537
538
    public function testSubqueryInSelectExpression()
539
    {
540
        $this->assertValidDQL('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u');
541
    }
542
543
    public function testUsageOfQComponentOutsideSubquery()
544
    {
545
        $this->assertInvalidDQL('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u WHERE p.user = ?1');
546
    }
547
548
    public function testUnknownAbstractSchemaName()
549
    {
550
        $this->assertInvalidDQL('SELECT u FROM UnknownClassName u');
551
    }
552
553
    public function testCorrectPartialObjectLoad()
554
    {
555
        $this->assertValidDQL('SELECT PARTIAL u.{id,name} FROM Doctrine\Tests\Models\CMS\CmsUser u');
556
    }
557
558
    public function testIncorrectPartialObjectLoadBecauseOfMissingIdentifier()
559
    {
560
        $this->assertInvalidDQL('SELECT PARTIAL u.{name} FROM Doctrine\Tests\Models\CMS\CmsUser u');
561
    }
562
563
    public function testScalarExpressionInSelect()
564
    {
565
        $this->assertValidDQL('SELECT u, 42 + u.id AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
566
    }
567
568
    public function testInputParameterInSelect()
569
    {
570
        $this->assertValidDQL('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
571
    }
572
573
    /**
574
     * @group DDC-1091
575
     */
576
    public function testCustomFunctionsReturningStringInStringPrimary()
577
    {
578
        $this->_em->getConfiguration()->addCustomStringFunction('CC', Query\AST\Functions\ConcatFunction::class);
579
580
        $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CC('%', u.name) LIKE '%foo%'", true);
581
    }
582
583
    /**
584
     * @group DDC-505
585
     */
586
    public function testDQLKeywordInJoinIsAllowed()
587
    {
588
        $this->assertValidDQL('SELECT u FROM ' . __NAMESPACE__ . '\DQLKeywordsModelUser u JOIN u.group g');
589
    }
590
591
    /**
592
     * @group DDC-505
593
     */
594
    public function testDQLKeywordInConditionIsAllowed()
595
    {
596
        $this->assertValidDQL('SELECT g FROM ' . __NAMESPACE__ . '\DQLKeywordsModelGroup g WHERE g.from=0');
597
    }
598
599
    /* The exception is currently thrown in the SQLWalker, not earlier.
600
    public function testInverseSideSingleValuedAssociationPathNotAllowed()
601
    {
602
        $this->assertInvalidDQL('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
603
    }
604
    */
605
606
    /**
607
     * @group DDC-617
608
     */
609
    public function testSelectOnlyNonRootEntityAlias()
610
    {
611
        $this->assertInvalidDQL('SELECT g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g');
612
    }
613
614
    /**
615
     * @group DDC-1108
616
     */
617
    public function testInputParameterSingleChar()
618
    {
619
        $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :q');
620
    }
621
622
    /**
623
     * @group DDC-1053
624
     */
625
    public function testGroupBy()
626
    {
627
        $this->assertValidDQL('SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id');
628
    }
629
630
    /**
631
     * @group DDC-1053
632
     */
633
    public function testGroupByIdentificationVariable()
634
    {
635
        $this->assertValidDQL('SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g');
636
    }
637
638
    /**
639
     * @group DDC-1053
640
     */
641
    public function testGroupByUnknownIdentificationVariable()
642
    {
643
        $this->assertInvalidDQL('SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY m');
644
    }
645
646
    /**
647
     * @group DDC-117
648
     */
649
    public function testSizeOfForeignKeyOneToManyPrimaryKeyEntity()
650
    {
651
        $this->assertValidDQL("SELECT a, t FROM Doctrine\Tests\Models\DDC117\DDC117Article a JOIN a.translations t WHERE SIZE(a.translations) > 0");
652
    }
653
654
    /**
655
     * @group DDC-117
656
     */
657
    public function testSizeOfForeignKeyManyToManyPrimaryKeyEntity()
658
    {
659
        $this->assertValidDQL("SELECT e, t FROM Doctrine\Tests\Models\DDC117\DDC117Editor e JOIN e.reviewingTranslations t WHERE SIZE(e.reviewingTranslations) > 0");
660
    }
661
662
    public function testCaseSupportContainingNullIfExpression()
663
    {
664
        $this->assertValidDQL("SELECT u.id, NULLIF(u.name, u.name) AS shouldBeNull FROM Doctrine\Tests\Models\CMS\CmsUser u");
665
    }
666
667
    public function testCaseSupportContainingCoalesceExpression()
668
    {
669
        $this->assertValidDQL("select COALESCE(NULLIF(u.name, ''), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u");
670
    }
671
672
    /**
673
     * @group DDC-1858
674
     */
675
    public function testHavingSupportIsNullExpression()
676
    {
677
        $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING u.username IS NULL");
678
    }
679
680
    /**
681
     * @group DDC-3085
682
     */
683
    public function testHavingSupportResultVariableInNullComparisonExpression()
684
    {
685
        $this->assertValidDQL("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");
686
    }
687
688
    /**
689
     * @group DDC-1858
690
     */
691
    public function testHavingSupportLikeExpression()
692
    {
693
        $this->assertValidDQL("SELECT _u.id, count(_articles) as uuuu FROM Doctrine\Tests\Models\CMS\CmsUser _u LEFT JOIN _u.articles _articles GROUP BY _u HAVING uuuu LIKE '3'");
694
    }
695
696
    /**
697
     * @group DDC-3018
698
     */
699
    public function testNewLiteralExpression()
700
    {
701
        $this->assertValidDQL("SELECT new " . __NAMESPACE__ . "\\DummyStruct(u.id, 'foo', 1, true) FROM Doctrine\Tests\Models\CMS\CmsUser u");
702
    }
703
704
    /**
705
     * @group DDC-3075
706
     */
707
    public function testNewLiteralWithSubselectExpression()
708
    {
709
        $this->assertValidDQL("SELECT new " . __NAMESPACE__ . "\\DummyStruct(u.id, 'foo', (SELECT 1 FROM Doctrine\Tests\Models\CMS\CmsUser su), true) FROM Doctrine\Tests\Models\CMS\CmsUser u");
710
    }
711
712
    public function testStringPrimaryAcceptsAggregateExpression() : void
713
    {
714
        $this->assertValidDQL(
715
            'SELECT CONCAT(a.topic, MAX(a.version)) last FROM Doctrine\Tests\Models\CMS\CmsArticle a GROUP BY a'
716
        );
717
    }
718
}
719
720
/** @Entity */
721
class DQLKeywordsModelUser
722
{
723
    /** @Id @Column(type="integer") @GeneratedValue */
724
    private $id;
0 ignored issues
show
introduced by
The private property $id is not used, and could be removed.
Loading history...
725
    /** @OneToOne(targetEntity="DQLKeywordsModelGroup") */
726
    private $group;
0 ignored issues
show
introduced by
The private property $group is not used, and could be removed.
Loading history...
727
}
728
729
/** @Entity */
730
class DQLKeywordsModelGroup
731
{
732
    /** @Id @Column(type="integer") @GeneratedValue */
733
    private $id;
734
    /** @Column */
735
    private $from;
0 ignored issues
show
introduced by
The private property $from is not used, and could be removed.
Loading history...
736
}
737
738
class DummyStruct
739
{
740
    public function __construct($id, $arg1, $arg2, $arg3)
0 ignored issues
show
Unused Code introduced by
The parameter $arg3 is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

740
    public function __construct($id, $arg1, $arg2, /** @scrutinizer ignore-unused */ $arg3)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $id is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

740
    public function __construct(/** @scrutinizer ignore-unused */ $id, $arg1, $arg2, $arg3)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $arg2 is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

740
    public function __construct($id, $arg1, /** @scrutinizer ignore-unused */ $arg2, $arg3)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $arg1 is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

740
    public function __construct($id, /** @scrutinizer ignore-unused */ $arg1, $arg2, $arg3)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
741
    {
742
    }
743
}
744