QueryBuilderTest.php 27.2 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\Tests\DBAL\Query;

Sergei Morozov's avatar
Sergei Morozov committed
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\ParameterType;
jeroendedauw's avatar
jeroendedauw committed
7 8
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\QueryBuilder;
Sergei Morozov's avatar
Sergei Morozov committed
9
use Doctrine\DBAL\Query\QueryException;
Sergei Morozov's avatar
Sergei Morozov committed
10
use Doctrine\Tests\DbalTestCase;
11

12 13 14
/**
 * @group DBAL-12
 */
Sergei Morozov's avatar
Sergei Morozov committed
15
class QueryBuilderTest extends DbalTestCase
16
{
Sergei Morozov's avatar
Sergei Morozov committed
17
    /** @var Connection */
18
    protected $conn;
19

20
    protected function setUp() : void
21
    {
Sergei Morozov's avatar
Sergei Morozov committed
22
        $this->conn = $this->createMock(Connection::class);
23

24
        $expressionBuilder = new ExpressionBuilder($this->conn);
25

26 27 28 29
        $this->conn->expects($this->any())
                   ->method('getExpressionBuilder')
                   ->will($this->returnValue($expressionBuilder));
    }
30

31 32 33 34 35 36 37 38 39
    /**
     * @group DBAL-2291
     */
    public function testSimpleSelectWithoutFrom()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('some_function()');

40
        self::assertEquals('SELECT some_function()', (string) $qb);
41 42
    }

43 44 45
    public function testSimpleSelect()
    {
        $qb = new QueryBuilder($this->conn);
46

47 48
        $qb->select('u.id')
           ->from('users', 'u');
49

50
        self::assertEquals('SELECT u.id FROM users u', (string) $qb);
51
    }
52

53 54 55
    public function testSelectWithSimpleWhere()
    {
        $qb   = new QueryBuilder($this->conn);
56 57
        $expr = $qb->expr();

58 59 60
        $qb->select('u.id')
           ->from('users', 'u')
           ->where($expr->andX($expr->eq('u.nickname', '?')));
61

Sergei Morozov's avatar
Sergei Morozov committed
62
        self::assertEquals('SELECT u.id FROM users u WHERE u.nickname = ?', (string) $qb);
63
    }
64

65
    public function testSelectWithLeftJoin()
66 67
    {
        $qb   = new QueryBuilder($this->conn);
68 69
        $expr = $qb->expr();

70 71 72
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->leftJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
73

74
        self::assertEquals('SELECT u.*, p.* FROM users u LEFT JOIN phones p ON p.user_id = u.id', (string) $qb);
75
    }
76

77 78 79
    public function testSelectWithJoin()
    {
        $qb   = new QueryBuilder($this->conn);
80 81
        $expr = $qb->expr();

82 83 84
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->Join('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
85

86
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
87
    }
88

89 90 91
    public function testSelectWithInnerJoin()
    {
        $qb   = new QueryBuilder($this->conn);
92 93
        $expr = $qb->expr();

94 95 96
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->innerJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
97

98
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
99
    }
100

101 102 103 104
    public function testSelectWithRightJoin()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
105

106 107 108
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->rightJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
109

110
        self::assertEquals('SELECT u.*, p.* FROM users u RIGHT JOIN phones p ON p.user_id = u.id', (string) $qb);
111
    }
112

113 114 115 116
    public function testSelectWithAndWhereConditions()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
117

118 119 120 121
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->where('u.username = ?')
           ->andWhere('u.name = ?');
122

123
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) AND (u.name = ?)', (string) $qb);
124
    }
125

126 127 128 129
    public function testSelectWithOrWhereConditions()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
130

131 132 133 134
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->where('u.username = ?')
           ->orWhere('u.name = ?');
135

136
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
137
    }
138

139 140 141 142
    public function testSelectWithOrOrWhereConditions()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
143

144 145 146 147
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->orWhere('u.username = ?')
           ->orWhere('u.name = ?');
148

149
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
150
    }
151

152 153 154 155
    public function testSelectWithAndOrWhereConditions()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
156

157 158 159 160 161 162
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->where('u.username = ?')
           ->andWhere('u.username = ?')
           ->orWhere('u.name = ?')
           ->andWhere('u.name = ?');
163

164
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (((u.username = ?) AND (u.username = ?)) OR (u.name = ?)) AND (u.name = ?)', (string) $qb);
165
    }
166

167 168 169 170
    public function testSelectGroupBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
171

172 173 174
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id');
175

176
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id', (string) $qb);
177
    }
178

179 180 181 182
    public function testSelectEmptyGroupBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
183

184
        $qb->select('u.*', 'p.*')
Sergei Morozov's avatar
Sergei Morozov committed
185
           ->groupBy([])
186
           ->from('users', 'u');
187

188
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
189
    }
190

191 192 193 194
    public function testSelectEmptyAddGroupBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
195

196
        $qb->select('u.*', 'p.*')
Sergei Morozov's avatar
Sergei Morozov committed
197
           ->addGroupBy([])
198
           ->from('users', 'u');
199

200
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
201
    }
202

203 204 205 206
    public function testSelectAddGroupBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
207

208 209 210 211
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->addGroupBy('u.foo');
212

213
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo', (string) $qb);
214
    }
215

216 217 218 219
    public function testSelectAddGroupBys()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
220

221 222 223 224
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->addGroupBy('u.foo', 'u.bar');
225

226
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo, u.bar', (string) $qb);
227
    }
228

229 230 231 232
    public function testSelectHaving()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
233

234 235 236 237
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->having('u.name = ?');
238

239
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
240
    }
241

242 243 244 245
    public function testSelectAndHaving()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
246

247 248 249 250
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->andHaving('u.name = ?');
251

252
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
253
    }
254

255 256 257 258
    public function testSelectHavingAndHaving()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
259

260 261 262 263 264
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->having('u.name = ?')
           ->andHaving('u.username = ?');
265

266
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) AND (u.username = ?)', (string) $qb);
267
    }
268

269 270 271 272
    public function testSelectHavingOrHaving()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
273

274 275 276 277 278
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->having('u.name = ?')
           ->orHaving('u.username = ?');
279

280
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
281
    }
282

283 284 285 286
    public function testSelectOrHavingOrHaving()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
287

288 289 290 291 292
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->orHaving('u.name = ?')
           ->orHaving('u.username = ?');
293

294
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
295
    }
296

297 298 299 300
    public function testSelectHavingAndOrHaving()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
301

302 303 304 305 306 307
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->groupBy('u.id')
           ->having('u.name = ?')
           ->orHaving('u.username = ?')
           ->andHaving('u.username = ?');
308

309
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING ((u.name = ?) OR (u.username = ?)) AND (u.username = ?)', (string) $qb);
310
    }
311

312 313 314 315
    public function testSelectOrderBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
316

317 318 319
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->orderBy('u.name');
320

321
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC', (string) $qb);
322
    }
323

324 325 326 327
    public function testSelectAddOrderBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
328

329 330 331 332
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->orderBy('u.name')
           ->addOrderBy('u.username', 'DESC');
333

334
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
335
    }
336

337 338 339 340
    public function testSelectAddAddOrderBy()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
341

342 343 344 345
        $qb->select('u.*', 'p.*')
           ->from('users', 'u')
           ->addOrderBy('u.name')
           ->addOrderBy('u.username', 'DESC');
346

347
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
348
    }
349

350 351
    public function testEmptySelect()
    {
Sergei Morozov's avatar
Sergei Morozov committed
352
        $qb  = new QueryBuilder($this->conn);
353
        $qb2 = $qb->select();
354

355 356
        self::assertSame($qb, $qb2);
        self::assertEquals(QueryBuilder::SELECT, $qb->getType());
357
    }
358

359 360 361 362
    public function testSelectAddSelect()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
363

364 365 366
        $qb->select('u.*')
           ->addSelect('p.*')
           ->from('users', 'u');
367

368
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
369
    }
370

371 372
    public function testEmptyAddSelect()
    {
Sergei Morozov's avatar
Sergei Morozov committed
373
        $qb  = new QueryBuilder($this->conn);
374
        $qb2 = $qb->addSelect();
375

376 377
        self::assertSame($qb, $qb2);
        self::assertEquals(QueryBuilder::SELECT, $qb->getType());
378
    }
379

380 381 382 383
    public function testSelectMultipleFrom()
    {
        $qb   = new QueryBuilder($this->conn);
        $expr = $qb->expr();
384

385 386 387 388
        $qb->select('u.*')
           ->addSelect('p.*')
           ->from('users', 'u')
           ->from('phonenumbers', 'p');
389

390
        self::assertEquals('SELECT u.*, p.* FROM users u, phonenumbers p', (string) $qb);
391
    }
392

393 394
    public function testUpdate()
    {
Sergei Morozov's avatar
Sergei Morozov committed
395
        $qb = new QueryBuilder($this->conn);
396 397 398
        $qb->update('users', 'u')
           ->set('u.foo', '?')
           ->set('u.bar', '?');
399

400 401
        self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
        self::assertEquals('UPDATE users u SET u.foo = ?, u.bar = ?', (string) $qb);
402
    }
403

404 405
    public function testUpdateWithoutAlias()
    {
Sergei Morozov's avatar
Sergei Morozov committed
406
        $qb = new QueryBuilder($this->conn);
407 408 409
        $qb->update('users')
           ->set('foo', '?')
           ->set('bar', '?');
410

411
        self::assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
412
    }
413

414 415
    public function testUpdateWhere()
    {
Sergei Morozov's avatar
Sergei Morozov committed
416
        $qb = new QueryBuilder($this->conn);
417 418 419
        $qb->update('users', 'u')
           ->set('u.foo', '?')
           ->where('u.foo = ?');
420

421
        self::assertEquals('UPDATE users u SET u.foo = ? WHERE u.foo = ?', (string) $qb);
422
    }
423

424 425
    public function testEmptyUpdate()
    {
Sergei Morozov's avatar
Sergei Morozov committed
426
        $qb  = new QueryBuilder($this->conn);
427
        $qb2 = $qb->update();
428

429 430
        self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
        self::assertSame($qb2, $qb);
431
    }
432

433 434
    public function testDelete()
    {
Sergei Morozov's avatar
Sergei Morozov committed
435
        $qb = new QueryBuilder($this->conn);
436
        $qb->delete('users', 'u');
437

438 439
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
        self::assertEquals('DELETE FROM users u', (string) $qb);
440
    }
441

442 443
    public function testDeleteWithoutAlias()
    {
Sergei Morozov's avatar
Sergei Morozov committed
444
        $qb = new QueryBuilder($this->conn);
445
        $qb->delete('users');
446

447 448
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
        self::assertEquals('DELETE FROM users', (string) $qb);
449
    }
450

451 452
    public function testDeleteWhere()
    {
Sergei Morozov's avatar
Sergei Morozov committed
453
        $qb = new QueryBuilder($this->conn);
454 455
        $qb->delete('users', 'u')
           ->where('u.foo = ?');
456

457
        self::assertEquals('DELETE FROM users u WHERE u.foo = ?', (string) $qb);
458
    }
459

460 461
    public function testEmptyDelete()
    {
Sergei Morozov's avatar
Sergei Morozov committed
462
        $qb  = new QueryBuilder($this->conn);
463
        $qb2 = $qb->delete();
464

465 466
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
        self::assertSame($qb2, $qb);
Steve Müller's avatar
Steve Müller committed
467 468 469 470 471 472 473
    }

    public function testInsertValues()
    {
        $qb = new QueryBuilder($this->conn);
        $qb->insert('users')
            ->values(
Sergei Morozov's avatar
Sergei Morozov committed
474
                [
Steve Müller's avatar
Steve Müller committed
475
                    'foo' => '?',
Sergei Morozov's avatar
Sergei Morozov committed
476 477
                    'bar' => '?',
                ]
Steve Müller's avatar
Steve Müller committed
478 479
            );

480 481
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
Steve Müller's avatar
Steve Müller committed
482 483 484 485 486 487 488
    }

    public function testInsertReplaceValues()
    {
        $qb = new QueryBuilder($this->conn);
        $qb->insert('users')
            ->values(
Sergei Morozov's avatar
Sergei Morozov committed
489
                [
Steve Müller's avatar
Steve Müller committed
490
                    'foo' => '?',
Sergei Morozov's avatar
Sergei Morozov committed
491 492
                    'bar' => '?',
                ]
Steve Müller's avatar
Steve Müller committed
493 494
            )
            ->values(
Sergei Morozov's avatar
Sergei Morozov committed
495
                [
Steve Müller's avatar
Steve Müller committed
496
                    'bar' => '?',
Sergei Morozov's avatar
Sergei Morozov committed
497 498
                    'foo' => '?',
                ]
Steve Müller's avatar
Steve Müller committed
499 500
            );

501 502
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
        self::assertEquals('INSERT INTO users (bar, foo) VALUES(?, ?)', (string) $qb);
Steve Müller's avatar
Steve Müller committed
503 504 505 506 507 508 509 510 511 512
    }

    public function testInsertSetValue()
    {
        $qb = new QueryBuilder($this->conn);
        $qb->insert('users')
            ->setValue('foo', 'bar')
            ->setValue('bar', '?')
            ->setValue('foo', '?');

513 514
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
Steve Müller's avatar
Steve Müller committed
515 516 517 518 519 520 521
    }

    public function testInsertValuesSetValue()
    {
        $qb = new QueryBuilder($this->conn);
        $qb->insert('users')
            ->values(
Sergei Morozov's avatar
Sergei Morozov committed
522
                ['foo' => '?']
Steve Müller's avatar
Steve Müller committed
523 524 525
            )
            ->setValue('bar', '?');

526 527
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
Steve Müller's avatar
Steve Müller committed
528 529 530 531
    }

    public function testEmptyInsert()
    {
Sergei Morozov's avatar
Sergei Morozov committed
532
        $qb  = new QueryBuilder($this->conn);
Steve Müller's avatar
Steve Müller committed
533 534
        $qb2 = $qb->insert();

535 536
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
        self::assertSame($qb2, $qb);
537
    }
538

539 540
    public function testGetConnection()
    {
Sergei Morozov's avatar
Sergei Morozov committed
541
        $qb = new QueryBuilder($this->conn);
542
        self::assertSame($this->conn, $qb->getConnection());
543
    }
544

545 546
    public function testGetState()
    {
Sergei Morozov's avatar
Sergei Morozov committed
547
        $qb = new QueryBuilder($this->conn);
548

549
        self::assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
550

551
        $qb->select('u.*')->from('users', 'u');
552

553
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
554

555
        $sql1 = $qb->getSQL();
556

557 558
        self::assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
        self::assertEquals($sql1, $qb->getSQL());
559
    }
560

561 562
    public function testSetMaxResults()
    {
Sergei Morozov's avatar
Sergei Morozov committed
563
        $qb = new QueryBuilder($this->conn);
564
        $qb->setMaxResults(10);
565

566
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
567
        self::assertEquals(10, $qb->getMaxResults());
568
    }
569

570 571
    public function testSetFirstResult()
    {
Sergei Morozov's avatar
Sergei Morozov committed
572
        $qb = new QueryBuilder($this->conn);
573
        $qb->setFirstResult(10);
574

575
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
576
        self::assertEquals(10, $qb->getFirstResult());
577
    }
578

579 580
    public function testResetQueryPart()
    {
Sergei Morozov's avatar
Sergei Morozov committed
581
        $qb = new QueryBuilder($this->conn);
582

583
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?');
584

585
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
586
        $qb->resetQueryPart('where');
587
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
588
    }
589

590 591
    public function testResetQueryParts()
    {
Sergei Morozov's avatar
Sergei Morozov committed
592
        $qb = new QueryBuilder($this->conn);
593

594
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?')->orderBy('u.name');
595

596
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ? ORDER BY u.name ASC', (string) $qb);
Sergei Morozov's avatar
Sergei Morozov committed
597
        $qb->resetQueryParts(['where', 'orderBy']);
598
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
599
    }
600

601 602
    public function testCreateNamedParameter()
    {
Sergei Morozov's avatar
Sergei Morozov committed
603
        $qb = new QueryBuilder($this->conn);
604

605
        $qb->select('u.*')->from('users', 'u')->where(
606
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER))
607
        );
608

609
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :dcValue1', (string) $qb);
610
        self::assertEquals(10, $qb->getParameter('dcValue1'));
611
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('dcValue1'));
612
    }
613

614 615
    public function testCreateNamedParameterCustomPlaceholder()
    {
Sergei Morozov's avatar
Sergei Morozov committed
616
        $qb = new QueryBuilder($this->conn);
617

618
        $qb->select('u.*')->from('users', 'u')->where(
619
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER, ':test'))
620
        );
621

622
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :test', (string) $qb);
623
        self::assertEquals(10, $qb->getParameter('test'));
624
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('test'));
625
    }
626

627 628
    public function testCreatePositionalParameter()
    {
Sergei Morozov's avatar
Sergei Morozov committed
629
        $qb = new QueryBuilder($this->conn);
630

631
        $qb->select('u.*')->from('users', 'u')->where(
632
            $qb->expr()->eq('u.name', $qb->createPositionalParameter(10, ParameterType::INTEGER))
633
        );
634

635
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
636
        self::assertEquals(10, $qb->getParameter(1));
637
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType(1));
638
    }
639 640 641 642 643 644 645 646

    /**
     * @group DBAL-172
     */
    public function testReferenceJoinFromJoin()
    {
        $qb = new QueryBuilder($this->conn);

Wim Vandersmissen's avatar
Wim Vandersmissen committed
647 648 649 650 651 652 653
        $qb->select('COUNT(DISTINCT news.id)')
            ->from('cb_newspages', 'news')
            ->innerJoin('news', 'nodeversion', 'nv', 'nv.refId = news.id AND nv.refEntityname=\'News\'')
            ->innerJoin('invalid', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
            ->where('nt.lang = :lang AND n.deleted != 1');

Sergei Morozov's avatar
Sergei Morozov committed
654
        $this->expectException(QueryException::class);
655
        $this->expectExceptionMessage("The given alias 'invalid' is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.");
656
        self::assertEquals('', $qb->getSQL());
657
    }
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673

    /**
     * @group DBAL-172
     */
    public function testSelectFromMasterWithWhereOnJoinedTables()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('COUNT(DISTINCT news.id)')
            ->from('newspages', 'news')
            ->innerJoin('news', 'nodeversion', 'nv', "nv.refId = news.id AND nv.refEntityname='Entity\\News'")
            ->innerJoin('nv', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
            ->where('nt.lang = ?')
            ->andWhere('n.deleted = 0');

674
        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());
675
    }
Deni's avatar
Deni committed
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691

    /**
     * @group DBAL-442
     */
    public function testSelectWithMultipleFromAndJoins()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('DISTINCT u.id')
            ->from('users', 'u')
            ->from('articles', 'a')
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
            ->innerJoin('a', 'comments', 'c', 'c.article_id = a.id')
            ->where('u.id = a.user_id')
            ->andWhere('p.read = 1');

692
        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());
Deni's avatar
Deni committed
693
    }
Paul's avatar
Paul committed
694

Jeroen Thora's avatar
Jeroen Thora committed
695 696 697
    /**
     * @group DBAL-774
     */
698 699 700 701 702 703 704 705 706 707 708
    public function testSelectWithJoinsWithMultipleOnConditionsParseOrder()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('a.id')
            ->from('table_a', 'a')
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id');

709
        self::assertEquals(
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
            'SELECT a.id ' .
            'FROM table_a a ' .
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id',
            (string) $qb
        );
    }

    /**
     * @group DBAL-774
     */
    public function testSelectWithMultipleFromsAndJoinsWithMultipleOnConditionsParseOrder()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('a.id')
            ->from('table_a', 'a')
            ->from('table_f', 'f')
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id')
            ->join('f', 'table_g', 'g', 'f.fk_g = g.id');

736
        self::assertEquals(
737 738 739 740 741 742 743 744 745 746
            'SELECT a.id ' .
            'FROM table_a a ' .
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id, ' .
            'table_f f ' .
            'INNER JOIN table_g g ON f.fk_g = g.id',
            (string) $qb
        );
747 748
    }

Paul's avatar
Paul committed
749 750 751 752 753 754 755 756 757 758 759 760
    public function testClone()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('u.id')
            ->from('users', 'u')
            ->where('u.id = :test');

        $qb->setParameter(':test', (object) 1);

        $qb_clone = clone $qb;

761
        self::assertEquals((string) $qb, (string) $qb_clone);
Paul's avatar
Paul committed
762 763 764

        $qb->andWhere('u.id = 1');

Gabriel Caruso's avatar
Gabriel Caruso committed
765 766
        self::assertNotSame($qb->getQueryParts(), $qb_clone->getQueryParts());
        self::assertNotSame($qb->getParameters(), $qb_clone->getParameters());
Paul's avatar
Paul committed
767
    }
768 769 770 771 772 773 774 775

    public function testSimpleSelectWithoutTableAlias()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('id')
            ->from('users');

776
        self::assertEquals('SELECT id FROM users', (string) $qb);
777 778 779 780 781 782 783 784 785 786
    }

    public function testSelectWithSimpleWhereWithoutTableAlias()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('id', 'name')
            ->from('users')
            ->where('awesome=9001');

Sergei Morozov's avatar
Sergei Morozov committed
787
        self::assertEquals('SELECT id, name FROM users WHERE awesome=9001', (string) $qb);
788 789 790 791 792 793 794 795 796 797 798 799 800 801
    }

    public function testComplexSelectWithoutTableAliases()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('DISTINCT users.id')
            ->from('users')
            ->from('articles')
            ->innerJoin('users', 'permissions', 'p', 'p.user_id = users.id')
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id')
            ->where('users.id = articles.user_id')
            ->andWhere('p.read = 1');

802
        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());
803 804 805 806 807 808 809 810 811 812 813 814
    }

    public function testComplexSelectWithSomeTableAliases()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('u.id')
            ->from('users', 'u')
            ->from('articles')
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id');

815
        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());
816
    }
817 818 819 820 821 822 823 824

    public function testSelectAllFromTableWithoutTableAlias()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('users.*')
            ->from('users');

Sergei Morozov's avatar
Sergei Morozov committed
825
        self::assertEquals('SELECT users.* FROM users', (string) $qb);
826 827 828 829 830 831 832 833 834
    }

    public function testSelectAllWithoutTableAlias()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('*')
            ->from('users');

Sergei Morozov's avatar
Sergei Morozov committed
835
        self::assertEquals('SELECT * FROM users', (string) $qb);
836
    }
837 838 839 840 841 842 843 844 845 846

    /**
     * @group DBAL-959
     */
    public function testGetParameterType()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('*')->from('users');

847
        self::assertNull($qb->getParameterType('name'));
848 849 850 851

        $qb->where('name = :name');
        $qb->setParameter('name', 'foo');

852
        self::assertNull($qb->getParameterType('name'));
853

854
        $qb->setParameter('name', 'foo', ParameterType::STRING);
855

856
        self::assertSame(ParameterType::STRING, $qb->getParameterType('name'));
857 858 859 860 861 862 863 864 865 866 867
    }

    /**
     * @group DBAL-959
     */
    public function testGetParameterTypes()
    {
        $qb = new QueryBuilder($this->conn);

        $qb->select('*')->from('users');

Sergei Morozov's avatar
Sergei Morozov committed
868
        self::assertSame([], $qb->getParameterTypes());
869 870 871 872

        $qb->where('name = :name');
        $qb->setParameter('name', 'foo');

Sergei Morozov's avatar
Sergei Morozov committed
873
        self::assertSame([], $qb->getParameterTypes());
874

875
        $qb->setParameter('name', 'foo', ParameterType::STRING);
876 877

        $qb->where('is_active = :isActive');
878
        $qb->setParameter('isActive', true, ParameterType::BOOLEAN);
879

Sergei Morozov's avatar
Sergei Morozov committed
880 881 882 883
        self::assertSame([
            'name'     => ParameterType::STRING,
            'isActive' => ParameterType::BOOLEAN,
        ], $qb->getParameterTypes());
884
    }
jarekj's avatar
jarekj committed
885 886

    /**
Steve Müller's avatar
Steve Müller committed
887
     * @group DBAL-1137
jarekj's avatar
jarekj committed
888
     */
889
    public function testJoinWithNonUniqueAliasThrowsException()
jarekj's avatar
jarekj committed
890 891 892
    {
        $qb = new QueryBuilder($this->conn);

Steve Müller's avatar
Steve Müller committed
893
        $qb->select('a.id')
jarekj's avatar
jarekj committed
894
            ->from('table_a', 'a')
Steve Müller's avatar
Steve Müller committed
895
            ->join('a', 'table_b', 'a', 'a.fk_b = a.id');
jarekj's avatar
jarekj committed
896

Sergei Morozov's avatar
Sergei Morozov committed
897
        $this->expectException(QueryException::class);
898
        $this->expectExceptionMessage("The given alias 'a' is not unique in FROM and JOIN clause table. The currently registered aliases are: a.");
Steve Müller's avatar
Steve Müller committed
899 900

        $qb->getSQL();
jarekj's avatar
jarekj committed
901
    }
Paul's avatar
Paul committed
902
}