Completed
Pull Request — master (#3831)
by Sergei
63:14
created

QueryBuilderTest::testSelectEmptyGroupBy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Query;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\ParameterType;
9
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
10
use Doctrine\DBAL\Query\QueryBuilder;
11
use Doctrine\DBAL\Query\QueryException;
12
use Doctrine\Tests\DbalTestCase;
13
14
/**
15
 * @group DBAL-12
16
 */
17
class QueryBuilderTest extends DbalTestCase
18
{
19
    /** @var Connection */
20
    protected $conn;
21
22
    protected function setUp() : void
23
    {
24
        $this->conn = $this->createMock(Connection::class);
25
26
        $expressionBuilder = new ExpressionBuilder($this->conn);
27
28
        $this->conn->expects($this->any())
29
                   ->method('getExpressionBuilder')
30
                   ->will($this->returnValue($expressionBuilder));
31
    }
32
33
    /**
34
     * @group DBAL-2291
35
     */
36
    public function testSimpleSelectWithoutFrom() : void
37
    {
38
        $qb = new QueryBuilder($this->conn);
39
40
        $qb->select('some_function()');
41
42
        self::assertEquals('SELECT some_function()', (string) $qb);
43
    }
44
45
    public function testSimpleSelect() : void
46
    {
47
        $qb = new QueryBuilder($this->conn);
48
49
        $qb->select('u.id')
50
           ->from('users', 'u');
51
52
        self::assertEquals('SELECT u.id FROM users u', (string) $qb);
53
    }
54
55
    public function testSimpleSelectWithDistinct() : void
56
    {
57
        $qb = new QueryBuilder($this->conn);
58
59
        $qb->select('u.id')
60
           ->distinct()
61
           ->from('users', 'u');
62
63
        self::assertEquals('SELECT DISTINCT u.id FROM users u', (string) $qb);
64
    }
65
66
    public function testSelectWithSimpleWhere() : void
67
    {
68
        $qb   = new QueryBuilder($this->conn);
69
        $expr = $qb->expr();
70
71
        $qb->select('u.id')
72
           ->from('users', 'u')
73
           ->where($expr->andX($expr->eq('u.nickname', '?')));
74
75
        self::assertEquals('SELECT u.id FROM users u WHERE u.nickname = ?', (string) $qb);
76
    }
77
78
    public function testSelectWithLeftJoin() : void
79
    {
80
        $qb   = new QueryBuilder($this->conn);
81
        $expr = $qb->expr();
82
83
        $qb->select('u.*', 'p.*')
84
           ->from('users', 'u')
85
           ->leftJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
86
87
        self::assertEquals('SELECT u.*, p.* FROM users u LEFT JOIN phones p ON p.user_id = u.id', (string) $qb);
88
    }
89
90
    public function testSelectWithJoin() : void
91
    {
92
        $qb   = new QueryBuilder($this->conn);
93
        $expr = $qb->expr();
94
95
        $qb->select('u.*', 'p.*')
96
           ->from('users', 'u')
97
           ->Join('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
98
99
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
100
    }
101
102
    public function testSelectWithInnerJoin() : void
103
    {
104
        $qb   = new QueryBuilder($this->conn);
105
        $expr = $qb->expr();
106
107
        $qb->select('u.*', 'p.*')
108
           ->from('users', 'u')
109
           ->innerJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
110
111
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
112
    }
113
114
    public function testSelectWithRightJoin() : void
115
    {
116
        $qb   = new QueryBuilder($this->conn);
117
        $expr = $qb->expr();
118
119
        $qb->select('u.*', 'p.*')
120
           ->from('users', 'u')
121
           ->rightJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
122
123
        self::assertEquals('SELECT u.*, p.* FROM users u RIGHT JOIN phones p ON p.user_id = u.id', (string) $qb);
124
    }
125
126
    public function testSelectWithAndWhereConditions() : void
127
    {
128
        $qb = new QueryBuilder($this->conn);
129
130
        $qb->select('u.*', 'p.*')
131
           ->from('users', 'u')
132
           ->where('u.username = ?')
133
           ->andWhere('u.name = ?');
134
135
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) AND (u.name = ?)', (string) $qb);
136
    }
137
138
    public function testSelectWithOrWhereConditions() : void
139
    {
140
        $qb = new QueryBuilder($this->conn);
141
142
        $qb->select('u.*', 'p.*')
143
           ->from('users', 'u')
144
           ->where('u.username = ?')
145
           ->orWhere('u.name = ?');
146
147
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
148
    }
149
150
    public function testSelectWithOrOrWhereConditions() : void
151
    {
152
        $qb = new QueryBuilder($this->conn);
153
154
        $qb->select('u.*', 'p.*')
155
           ->from('users', 'u')
156
           ->orWhere('u.username = ?')
157
           ->orWhere('u.name = ?');
158
159
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
160
    }
161
162
    public function testSelectWithAndOrWhereConditions() : void
163
    {
164
        $qb = new QueryBuilder($this->conn);
165
166
        $qb->select('u.*', 'p.*')
167
           ->from('users', 'u')
168
           ->where('u.username = ?')
169
           ->andWhere('u.username = ?')
170
           ->orWhere('u.name = ?')
171
           ->andWhere('u.name = ?');
172
173
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (((u.username = ?) AND (u.username = ?)) OR (u.name = ?)) AND (u.name = ?)', (string) $qb);
174
    }
175
176
    public function testSelectGroupBy() : void
177
    {
178
        $qb = new QueryBuilder($this->conn);
179
180
        $qb->select('u.*', 'p.*')
181
           ->from('users', 'u')
182
           ->groupBy('u.id');
183
184
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id', (string) $qb);
185
    }
186
187
    public function testSelectAddGroupBy() : void
188
    {
189
        $qb = new QueryBuilder($this->conn);
190
191
        $qb->select('u.*', 'p.*')
192
           ->from('users', 'u')
193
           ->groupBy('u.id')
194
           ->addGroupBy('u.foo');
195
196
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo', (string) $qb);
197
    }
198
199
    public function testSelectAddGroupBys() : void
200
    {
201
        $qb = new QueryBuilder($this->conn);
202
203
        $qb->select('u.*', 'p.*')
204
           ->from('users', 'u')
205
           ->groupBy('u.id')
206
           ->addGroupBy('u.foo', 'u.bar');
207
208
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo, u.bar', (string) $qb);
209
    }
210
211
    public function testSelectHaving() : void
212
    {
213
        $qb = new QueryBuilder($this->conn);
214
215
        $qb->select('u.*', 'p.*')
216
           ->from('users', 'u')
217
           ->groupBy('u.id')
218
           ->having('u.name = ?');
219
220
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
221
    }
222
223
    public function testSelectAndHaving() : void
224
    {
225
        $qb = new QueryBuilder($this->conn);
226
227
        $qb->select('u.*', 'p.*')
228
           ->from('users', 'u')
229
           ->groupBy('u.id')
230
           ->andHaving('u.name = ?');
231
232
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
233
    }
234
235
    public function testSelectHavingAndHaving() : void
236
    {
237
        $qb = new QueryBuilder($this->conn);
238
239
        $qb->select('u.*', 'p.*')
240
           ->from('users', 'u')
241
           ->groupBy('u.id')
242
           ->having('u.name = ?')
243
           ->andHaving('u.username = ?');
244
245
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) AND (u.username = ?)', (string) $qb);
246
    }
247
248
    public function testSelectHavingOrHaving() : void
249
    {
250
        $qb = new QueryBuilder($this->conn);
251
252
        $qb->select('u.*', 'p.*')
253
           ->from('users', 'u')
254
           ->groupBy('u.id')
255
           ->having('u.name = ?')
256
           ->orHaving('u.username = ?');
257
258
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
259
    }
260
261
    public function testSelectOrHavingOrHaving() : void
262
    {
263
        $qb = new QueryBuilder($this->conn);
264
265
        $qb->select('u.*', 'p.*')
266
           ->from('users', 'u')
267
           ->groupBy('u.id')
268
           ->orHaving('u.name = ?')
269
           ->orHaving('u.username = ?');
270
271
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
272
    }
273
274
    public function testSelectHavingAndOrHaving() : void
275
    {
276
        $qb = new QueryBuilder($this->conn);
277
278
        $qb->select('u.*', 'p.*')
279
           ->from('users', 'u')
280
           ->groupBy('u.id')
281
           ->having('u.name = ?')
282
           ->orHaving('u.username = ?')
283
           ->andHaving('u.username = ?');
284
285
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING ((u.name = ?) OR (u.username = ?)) AND (u.username = ?)', (string) $qb);
286
    }
287
288
    public function testSelectOrderBy() : void
289
    {
290
        $qb = new QueryBuilder($this->conn);
291
292
        $qb->select('u.*', 'p.*')
293
           ->from('users', 'u')
294
           ->orderBy('u.name');
295
296
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC', (string) $qb);
297
    }
298
299
    public function testSelectAddOrderBy() : void
300
    {
301
        $qb = new QueryBuilder($this->conn);
302
303
        $qb->select('u.*', 'p.*')
304
           ->from('users', 'u')
305
           ->orderBy('u.name')
306
           ->addOrderBy('u.username', 'DESC');
307
308
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
309
    }
310
311
    public function testSelectAddAddOrderBy() : void
312
    {
313
        $qb = new QueryBuilder($this->conn);
314
315
        $qb->select('u.*', 'p.*')
316
           ->from('users', 'u')
317
           ->addOrderBy('u.name')
318
           ->addOrderBy('u.username', 'DESC');
319
320
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
321
    }
322
323
    public function testEmptySelect() : void
324
    {
325
        $qb  = new QueryBuilder($this->conn);
326
        $qb2 = $qb->select();
327
328
        self::assertSame($qb, $qb2);
329
        self::assertEquals(QueryBuilder::SELECT, $qb->getType());
330
    }
331
332
    public function testSelectAddSelect() : void
333
    {
334
        $qb = new QueryBuilder($this->conn);
335
336
        $qb->select('u.*')
337
           ->addSelect('p.*')
338
           ->from('users', 'u');
339
340
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
341
    }
342
343
    public function testSelectMultipleFrom() : void
344
    {
345
        $qb = new QueryBuilder($this->conn);
346
347
        $qb->select('u.*')
348
           ->addSelect('p.*')
349
           ->from('users', 'u')
350
           ->from('phonenumbers', 'p');
351
352
        self::assertEquals('SELECT u.*, p.* FROM users u, phonenumbers p', (string) $qb);
353
    }
354
355
    public function testUpdate() : void
356
    {
357
        $qb = new QueryBuilder($this->conn);
358
        $qb->update('users', 'u')
359
           ->set('u.foo', '?')
360
           ->set('u.bar', '?');
361
362
        self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
363
        self::assertEquals('UPDATE users u SET u.foo = ?, u.bar = ?', (string) $qb);
364
    }
365
366
    public function testUpdateWithoutAlias() : void
367
    {
368
        $qb = new QueryBuilder($this->conn);
369
        $qb->update('users')
370
           ->set('foo', '?')
371
           ->set('bar', '?');
372
373
        self::assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
374
    }
375
376
    public function testUpdateWithMatchingAlias() : void
377
    {
378
        $qb = new QueryBuilder($this->conn);
379
        $qb->update('users', 'users')
380
           ->set('foo', '?')
381
           ->set('bar', '?');
382
383
        self::assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
384
    }
385
386
    public function testUpdateWhere() : void
387
    {
388
        $qb = new QueryBuilder($this->conn);
389
        $qb->update('users', 'u')
390
           ->set('u.foo', '?')
391
           ->where('u.foo = ?');
392
393
        self::assertEquals('UPDATE users u SET u.foo = ? WHERE u.foo = ?', (string) $qb);
394
    }
395
396
    public function testEmptyUpdate() : void
397
    {
398
        $qb  = new QueryBuilder($this->conn);
399
        $qb2 = $qb->update();
400
401
        self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
402
        self::assertSame($qb2, $qb);
403
    }
404
405
    public function testDelete() : void
406
    {
407
        $qb = new QueryBuilder($this->conn);
408
        $qb->delete('users', 'u');
409
410
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
411
        self::assertEquals('DELETE FROM users u', (string) $qb);
412
    }
413
414
    public function testDeleteWithoutAlias() : void
415
    {
416
        $qb = new QueryBuilder($this->conn);
417
        $qb->delete('users');
418
419
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
420
        self::assertEquals('DELETE FROM users', (string) $qb);
421
    }
422
423
    public function testDeleteWithMatchingAlias() : void
424
    {
425
        $qb = new QueryBuilder($this->conn);
426
        $qb->delete('users', 'users');
427
428
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
429
        self::assertEquals('DELETE FROM users', (string) $qb);
430
    }
431
432
    public function testDeleteWhere() : void
433
    {
434
        $qb = new QueryBuilder($this->conn);
435
        $qb->delete('users', 'u')
436
           ->where('u.foo = ?');
437
438
        self::assertEquals('DELETE FROM users u WHERE u.foo = ?', (string) $qb);
439
    }
440
441
    public function testEmptyDelete() : void
442
    {
443
        $qb  = new QueryBuilder($this->conn);
444
        $qb2 = $qb->delete();
445
446
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
447
        self::assertSame($qb2, $qb);
448
    }
449
450
    public function testInsertValues() : void
451
    {
452
        $qb = new QueryBuilder($this->conn);
453
        $qb->insert('users')
454
            ->values(
455
                [
456
                    'foo' => '?',
457
                    'bar' => '?',
458
                ]
459
            );
460
461
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
462
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
463
    }
464
465
    public function testInsertReplaceValues() : void
466
    {
467
        $qb = new QueryBuilder($this->conn);
468
        $qb->insert('users')
469
            ->values(
470
                [
471
                    'foo' => '?',
472
                    'bar' => '?',
473
                ]
474
            )
475
            ->values(
476
                [
477
                    'bar' => '?',
478
                    'foo' => '?',
479
                ]
480
            );
481
482
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
483
        self::assertEquals('INSERT INTO users (bar, foo) VALUES(?, ?)', (string) $qb);
484
    }
485
486
    public function testInsertSetValue() : void
487
    {
488
        $qb = new QueryBuilder($this->conn);
489
        $qb->insert('users')
490
            ->setValue('foo', 'bar')
491
            ->setValue('bar', '?')
492
            ->setValue('foo', '?');
493
494
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
495
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
496
    }
497
498
    public function testInsertValuesSetValue() : void
499
    {
500
        $qb = new QueryBuilder($this->conn);
501
        $qb->insert('users')
502
            ->values(
503
                ['foo' => '?']
504
            )
505
            ->setValue('bar', '?');
506
507
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
508
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
509
    }
510
511
    public function testEmptyInsert() : void
512
    {
513
        $qb  = new QueryBuilder($this->conn);
514
        $qb2 = $qb->insert();
515
516
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
517
        self::assertSame($qb2, $qb);
518
    }
519
520
    public function testGetConnection() : void
521
    {
522
        $qb = new QueryBuilder($this->conn);
523
        self::assertSame($this->conn, $qb->getConnection());
524
    }
525
526
    public function testGetState() : void
527
    {
528
        $qb = new QueryBuilder($this->conn);
529
530
        self::assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
531
532
        $qb->select('u.*')->from('users', 'u');
533
534
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
535
536
        $sql1 = $qb->getSQL();
537
538
        self::assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
539
        self::assertEquals($sql1, $qb->getSQL());
540
    }
541
542
    public function testSetMaxResults() : void
543
    {
544
        $qb = new QueryBuilder($this->conn);
545
        $qb->setMaxResults(10);
546
547
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
548
        self::assertEquals(10, $qb->getMaxResults());
549
    }
550
551
    public function testSetFirstResult() : void
552
    {
553
        $qb = new QueryBuilder($this->conn);
554
        $qb->setFirstResult(10);
555
556
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
557
        self::assertEquals(10, $qb->getFirstResult());
558
    }
559
560
    public function testResetQueryPart() : void
561
    {
562
        $qb = new QueryBuilder($this->conn);
563
564
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?');
565
566
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
567
        $qb->resetQueryPart('where');
568
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
569
    }
570
571
    public function testResetQueryParts() : void
572
    {
573
        $qb = new QueryBuilder($this->conn);
574
575
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?')->orderBy('u.name');
576
577
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ? ORDER BY u.name ASC', (string) $qb);
578
        $qb->resetQueryParts(['where', 'orderBy']);
579
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
580
    }
581
582
    public function testCreateNamedParameter() : void
583
    {
584
        $qb = new QueryBuilder($this->conn);
585
586
        $qb->select('u.*')->from('users', 'u')->where(
587
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER))
588
        );
589
590
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :dcValue1', (string) $qb);
591
        self::assertEquals(10, $qb->getParameter('dcValue1'));
592
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('dcValue1'));
593
    }
594
595
    public function testCreateNamedParameterCustomPlaceholder() : void
596
    {
597
        $qb = new QueryBuilder($this->conn);
598
599
        $qb->select('u.*')->from('users', 'u')->where(
600
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER, ':test'))
601
        );
602
603
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :test', (string) $qb);
604
        self::assertEquals(10, $qb->getParameter('test'));
605
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('test'));
606
    }
607
608
    public function testCreatePositionalParameter() : void
609
    {
610
        $qb = new QueryBuilder($this->conn);
611
612
        $qb->select('u.*')->from('users', 'u')->where(
613
            $qb->expr()->eq('u.name', $qb->createPositionalParameter(10, ParameterType::INTEGER))
614
        );
615
616
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
617
        self::assertEquals(10, $qb->getParameter(1));
618
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType(1));
619
    }
620
621
    /**
622
     * @group DBAL-172
623
     */
624
    public function testReferenceJoinFromJoin() : void
625
    {
626
        $qb = new QueryBuilder($this->conn);
627
628
        $qb->select('COUNT(DISTINCT news.id)')
629
            ->from('cb_newspages', 'news')
630
            ->innerJoin('news', 'nodeversion', 'nv', 'nv.refId = news.id AND nv.refEntityname=\'News\'')
631
            ->innerJoin('invalid', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
632
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
633
            ->where('nt.lang = :lang AND n.deleted != 1');
634
635
        $this->expectException(QueryException::class);
636
        $this->expectExceptionMessage('The given alias "invalid" is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.');
637
        self::assertEquals('', $qb->getSQL());
638
    }
639
640
    /**
641
     * @group DBAL-172
642
     */
643
    public function testSelectFromMasterWithWhereOnJoinedTables() : void
644
    {
645
        $qb = new QueryBuilder($this->conn);
646
647
        $qb->select('COUNT(DISTINCT news.id)')
648
            ->from('newspages', 'news')
649
            ->innerJoin('news', 'nodeversion', 'nv', "nv.refId = news.id AND nv.refEntityname='Entity\\News'")
650
            ->innerJoin('nv', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
651
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
652
            ->where('nt.lang = ?')
653
            ->andWhere('n.deleted = 0');
654
655
        self::assertEquals("SELECT COUNT(DISTINCT news.id) FROM newspages news INNER JOIN nodeversion nv ON nv.refId = news.id AND nv.refEntityname='Entity\\News' INNER JOIN nodetranslation nt ON nv.nodetranslation = nt.id INNER JOIN node n ON nt.node = n.id WHERE (nt.lang = ?) AND (n.deleted = 0)", $qb->getSQL());
656
    }
657
658
    /**
659
     * @group DBAL-442
660
     */
661
    public function testSelectWithMultipleFromAndJoins() : void
662
    {
663
        $qb = new QueryBuilder($this->conn);
664
665
        $qb->select('DISTINCT u.id')
666
            ->from('users', 'u')
667
            ->from('articles', 'a')
668
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
669
            ->innerJoin('a', 'comments', 'c', 'c.article_id = a.id')
670
            ->where('u.id = a.user_id')
671
            ->andWhere('p.read = 1');
672
673
        self::assertEquals('SELECT DISTINCT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles a INNER JOIN comments c ON c.article_id = a.id WHERE (u.id = a.user_id) AND (p.read = 1)', $qb->getSQL());
674
    }
675
676
    /**
677
     * @group DBAL-774
678
     */
679
    public function testSelectWithJoinsWithMultipleOnConditionsParseOrder() : void
680
    {
681
        $qb = new QueryBuilder($this->conn);
682
683
        $qb->select('a.id')
684
            ->from('table_a', 'a')
685
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
686
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
687
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
688
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id');
689
690
        self::assertEquals(
691
            'SELECT a.id ' .
692
            'FROM table_a a ' .
693
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
694
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
695
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
696
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id',
697
            (string) $qb
698
        );
699
    }
700
701
    /**
702
     * @group DBAL-774
703
     */
704
    public function testSelectWithMultipleFromsAndJoinsWithMultipleOnConditionsParseOrder() : void
705
    {
706
        $qb = new QueryBuilder($this->conn);
707
708
        $qb->select('a.id')
709
            ->from('table_a', 'a')
710
            ->from('table_f', 'f')
711
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
712
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
713
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
714
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id')
715
            ->join('f', 'table_g', 'g', 'f.fk_g = g.id');
716
717
        self::assertEquals(
718
            'SELECT a.id ' .
719
            'FROM table_a a ' .
720
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
721
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
722
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
723
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id, ' .
724
            'table_f f ' .
725
            'INNER JOIN table_g g ON f.fk_g = g.id',
726
            (string) $qb
727
        );
728
    }
729
730
    public function testClone() : void
731
    {
732
        $qb = new QueryBuilder($this->conn);
733
734
        $qb->select('u.id')
735
            ->from('users', 'u')
736
            ->where('u.id = :test');
737
738
        $qb->setParameter(':test', (object) 1);
739
740
        $qb_clone = clone $qb;
741
742
        self::assertEquals((string) $qb, (string) $qb_clone);
743
744
        $qb->andWhere('u.id = 1');
745
746
        self::assertNotSame($qb->getQueryParts(), $qb_clone->getQueryParts());
747
        self::assertNotSame($qb->getParameters(), $qb_clone->getParameters());
748
    }
749
750
    public function testSimpleSelectWithoutTableAlias() : void
751
    {
752
        $qb = new QueryBuilder($this->conn);
753
754
        $qb->select('id')
755
            ->from('users');
756
757
        self::assertEquals('SELECT id FROM users', (string) $qb);
758
    }
759
760
    public function testSimpleSelectWithMatchingTableAlias() : void
761
    {
762
        $qb = new QueryBuilder($this->conn);
763
764
        $qb->select('id')
765
            ->from('users', 'users');
766
767
        self::assertEquals('SELECT id FROM users', (string) $qb);
768
    }
769
770
    public function testSelectWithSimpleWhereWithoutTableAlias() : void
771
    {
772
        $qb = new QueryBuilder($this->conn);
773
774
        $qb->select('id', 'name')
775
            ->from('users')
776
            ->where('awesome=9001');
777
778
        self::assertEquals('SELECT id, name FROM users WHERE awesome=9001', (string) $qb);
779
    }
780
781
    public function testComplexSelectWithoutTableAliases() : void
782
    {
783
        $qb = new QueryBuilder($this->conn);
784
785
        $qb->select('DISTINCT users.id')
786
            ->from('users')
787
            ->from('articles')
788
            ->innerJoin('users', 'permissions', 'p', 'p.user_id = users.id')
789
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id')
790
            ->where('users.id = articles.user_id')
791
            ->andWhere('p.read = 1');
792
793
        self::assertEquals('SELECT DISTINCT users.id FROM users INNER JOIN permissions p ON p.user_id = users.id, articles INNER JOIN comments c ON c.article_id = articles.id WHERE (users.id = articles.user_id) AND (p.read = 1)', $qb->getSQL());
794
    }
795
796
    public function testComplexSelectWithSomeTableAliases() : void
797
    {
798
        $qb = new QueryBuilder($this->conn);
799
800
        $qb->select('u.id')
801
            ->from('users', 'u')
802
            ->from('articles')
803
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
804
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id');
805
806
        self::assertEquals('SELECT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles INNER JOIN comments c ON c.article_id = articles.id', $qb->getSQL());
807
    }
808
809
    public function testSelectAllFromTableWithoutTableAlias() : void
810
    {
811
        $qb = new QueryBuilder($this->conn);
812
813
        $qb->select('users.*')
814
            ->from('users');
815
816
        self::assertEquals('SELECT users.* FROM users', (string) $qb);
817
    }
818
819
    public function testSelectAllWithoutTableAlias() : void
820
    {
821
        $qb = new QueryBuilder($this->conn);
822
823
        $qb->select('*')
824
            ->from('users');
825
826
        self::assertEquals('SELECT * FROM users', (string) $qb);
827
    }
828
829
    /**
830
     * @group DBAL-959
831
     */
832
    public function testGetParameterType() : void
833
    {
834
        $qb = new QueryBuilder($this->conn);
835
836
        $qb->select('*')->from('users');
837
838
        self::assertNull($qb->getParameterType('name'));
839
840
        $qb->where('name = :name');
841
        $qb->setParameter('name', 'foo');
842
843
        self::assertNull($qb->getParameterType('name'));
844
845
        $qb->setParameter('name', 'foo', ParameterType::STRING);
846
847
        self::assertSame(ParameterType::STRING, $qb->getParameterType('name'));
848
    }
849
850
    /**
851
     * @group DBAL-959
852
     */
853
    public function testGetParameterTypes() : void
854
    {
855
        $qb = new QueryBuilder($this->conn);
856
857
        $qb->select('*')->from('users');
858
859
        self::assertSame([], $qb->getParameterTypes());
860
861
        $qb->where('name = :name');
862
        $qb->setParameter('name', 'foo');
863
864
        self::assertSame([], $qb->getParameterTypes());
865
866
        $qb->setParameter('name', 'foo', ParameterType::STRING);
867
868
        $qb->where('is_active = :isActive');
869
        $qb->setParameter('isActive', true, ParameterType::BOOLEAN);
870
871
        self::assertSame([
872
            'name'     => ParameterType::STRING,
873
            'isActive' => ParameterType::BOOLEAN,
874
        ], $qb->getParameterTypes());
875
    }
876
877
    /**
878
     * @group DBAL-1137
879
     */
880
    public function testJoinWithNonUniqueAliasThrowsException() : void
881
    {
882
        $qb = new QueryBuilder($this->conn);
883
884
        $qb->select('a.id')
885
            ->from('table_a', 'a')
886
            ->join('a', 'table_b', 'a', 'a.fk_b = a.id');
887
888
        $this->expectException(QueryException::class);
889
        $this->expectExceptionMessage('The given alias "a" is not unique in FROM and JOIN clause table. The currently registered aliases are: a.');
890
891
        $qb->getSQL();
892
    }
893
}
894