Passed
Push — master ( 914087...c6011d )
by Alexander
11:22
created

TestQueryBuilderTrait::testIssue15653()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 0
loc 16
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\TestSupport;
6
7
use Yiisoft\Db\Expression\Expression;
8
use Yiisoft\Db\QueryBuilder\QueryBuilder;
9
use Yiisoft\Db\Query\Query;
10
use Yiisoft\Db\Schema\Schema;
11
use Yiisoft\Db\Schema\SchemaBuilderTrait;
12
13
use function array_key_exists;
14
use function array_values;
15
use function is_array;
16
use function str_replace;
17
use function strncmp;
18
use function substr;
19
20
trait TestQueryBuilderTrait
21
{
22
    use SchemaBuilderTrait;
23
24
    /**
25
     * This is not used as a dataprovider for testGetColumnType to speed up the test when used as dataprovider every
26
     * single line will cause a reconnect with the database which is not needed here.
27
     */
28
    public function columnTypes(): array
29
    {
30
        $version = $this->getConnection()->getServerVersion();
0 ignored issues
show
Bug introduced by
It seems like getConnection() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

30
        $version = $this->/** @scrutinizer ignore-call */ getConnection()->getServerVersion();
Loading history...
31
32
        $items = [
33
            [
34
                Schema::TYPE_BIGINT,
35
                $this->bigInteger(),
36
                [
37
                    'mysql' => 'bigint(20)',
38
                    'pgsql' => 'bigint',
39
                    'sqlite' => 'bigint',
40
                    'oci' => 'NUMBER(20)',
41
                    'sqlsrv' => 'bigint',
42
                ],
43
            ],
44
            [
45
                Schema::TYPE_BIGINT . ' NOT NULL',
46
                $this->bigInteger()->notNull(),
47
                [
48
                    'mysql' => 'bigint(20) NOT NULL',
49
                    'pgsql' => 'bigint NOT NULL',
50
                    'sqlite' => 'bigint NOT NULL',
51
                    'oci' => 'NUMBER(20) NOT NULL',
52
                    'sqlsrv' => 'bigint NOT NULL',
53
                ],
54
            ],
55
            [
56
                Schema::TYPE_BIGINT . ' CHECK (value > 5)',
57
                $this->bigInteger()->check('value > 5'),
58
                [
59
                    'mysql' => 'bigint(20) CHECK (value > 5)',
60
                    'pgsql' => 'bigint CHECK (value > 5)',
61
                    'sqlite' => 'bigint CHECK (value > 5)',
62
                    'oci' => 'NUMBER(20) CHECK (value > 5)',
63
                    'sqlsrv' => 'bigint CHECK (value > 5)',
64
                ],
65
            ],
66
            [
67
                Schema::TYPE_BIGINT . '(8)',
68
                $this->bigInteger(8),
69
                [
70
                    'mysql' => 'bigint(8)',
71
                    'pgsql' => 'bigint',
72
                    'sqlite' => 'bigint',
73
                    'oci' => 'NUMBER(8)',
74
                    'sqlsrv' => 'bigint',
75
                ],
76
            ],
77
            [
78
                Schema::TYPE_BIGINT . '(8) CHECK (value > 5)',
79
                $this->bigInteger(8)->check('value > 5'),
80
                [
81
                    'mysql' => 'bigint(8) CHECK (value > 5)',
82
                    'pgsql' => 'bigint CHECK (value > 5)',
83
                    'sqlite' => 'bigint CHECK (value > 5)',
84
                    'oci' => 'NUMBER(8) CHECK (value > 5)',
85
                    'sqlsrv' => 'bigint CHECK (value > 5)',
86
                ],
87
            ],
88
            [
89
                Schema::TYPE_BIGPK,
90
                $this->bigPrimaryKey(),
91
                [
92
                    'mysql' => 'bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY',
93
                    'pgsql' => 'bigserial NOT NULL PRIMARY KEY',
94
                    'sqlite' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
95
                ],
96
            ],
97
            [
98
                Schema::TYPE_BINARY,
99
                $this->binary(),
100
                [
101
                    'mysql' => 'blob',
102
                    'pgsql' => 'bytea',
103
                    'sqlite' => 'blob',
104
                    'oci' => 'BLOB',
105
                    'sqlsrv' => 'varbinary(max)',
106
                ],
107
            ],
108
            [
109
                Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 1',
110
                $this->boolean()->notNull()->defaultValue(1),
111
                [
112
                    'mysql' => 'tinyint(1) NOT NULL DEFAULT 1',
113
                    'sqlite' => 'boolean NOT NULL DEFAULT 1',
114
                    'sqlsrv' => 'bit NOT NULL DEFAULT 1',
115
                ],
116
            ],
117
            [
118
                Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT TRUE',
119
                $this->boolean()->notNull()->defaultValue(true),
120
                [
121
                    'pgsql' => 'boolean NOT NULL DEFAULT TRUE',
122
                ],
123
            ],
124
            [
125
                Schema::TYPE_BOOLEAN,
126
                $this->boolean(),
127
                [
128
                    'mysql' => 'tinyint(1)',
129
                    'pgsql' => 'boolean',
130
                    'sqlite' => 'boolean',
131
                    'oci' => 'NUMBER(1)',
132
                    'sqlsrv' => 'bit',
133
                ],
134
            ],
135
            [
136
                Schema::TYPE_CHAR . ' CHECK (value LIKE \'test%\')',
137
                $this->char()->check('value LIKE \'test%\''),
138
                [
139
                    'pgsql' => 'char(1) CHECK (value LIKE \'test%\')',
140
                ],
141
            ],
142
            [
143
                Schema::TYPE_CHAR . ' CHECK (value LIKE "test%")',
144
                $this->char()->check('value LIKE "test%"'),
145
                [
146
                    'mysql' => 'char(1) CHECK (value LIKE "test%")',
147
                    'sqlite' => 'char(1) CHECK (value LIKE "test%")',
148
                ],
149
            ],
150
            [
151
                Schema::TYPE_CHAR . ' NOT NULL',
152
                $this->char()->notNull(),
153
                [
154
                    'mysql' => 'char(1) NOT NULL',
155
                    'pgsql' => 'char(1) NOT NULL',
156
                    'sqlite' => 'char(1) NOT NULL',
157
                    'oci' => 'CHAR(1) NOT NULL',
158
                ],
159
            ],
160
            [
161
                Schema::TYPE_CHAR . '(6) CHECK (value LIKE "test%")',
162
                $this->char(6)->check('value LIKE "test%"'),
163
                [
164
                    'mysql' => 'char(6) CHECK (value LIKE "test%")',
165
                    'sqlite' => 'char(6) CHECK (value LIKE "test%")',
166
                ],
167
            ],
168
            [
169
                Schema::TYPE_CHAR . '(6)',
170
                $this->char(6)->unsigned(),
171
                [
172
                    'pgsql' => 'char(6)',
173
                ],
174
            ],
175
            [
176
                Schema::TYPE_CHAR . '(6)',
177
                $this->char(6),
178
                [
179
                    'mysql' => 'char(6)',
180
                    'pgsql' => 'char(6)',
181
                    'sqlite' => 'char(6)',
182
                    'oci' => 'CHAR(6)',
183
                ],
184
            ],
185
            [
186
                Schema::TYPE_CHAR,
187
                $this->char(),
188
                [
189
                    'mysql' => 'char(1)',
190
                    'pgsql' => 'char(1)',
191
                    'sqlite' => 'char(1)',
192
                    'oci' => 'CHAR(1)',
193
                ],
194
            ],
195
            [
196
                Schema::TYPE_DATE . ' NOT NULL',
197
                $this->date()->notNull(),
198
                [
199
                    'pgsql' => 'date NOT NULL',
200
                    'sqlite' => 'date NOT NULL',
201
                    'oci' => 'DATE NOT NULL',
202
                    'sqlsrv' => 'date NOT NULL',
203
                ],
204
            ],
205
            [
206
                Schema::TYPE_DATE,
207
                $this->date(),
208
                [
209
                    'mysql' => 'date',
210
                    'pgsql' => 'date',
211
                    'sqlite' => 'date',
212
                    'oci' => 'DATE',
213
                    'sqlsrv' => 'date',
214
                ],
215
            ],
216
            [
217
                Schema::TYPE_DATETIME . ' NOT NULL',
218
                $this->dateTime()->notNull(),
219
                [
220
                    'mysql' => version_compare($version, '5.6.4', '>=') ? 'datetime(0) NOT NULL' : 'datetime NOT NULL',
221
                    'pgsql' => 'timestamp(0) NOT NULL',
222
                    'sqlite' => 'datetime NOT NULL',
223
                    'oci' => 'TIMESTAMP NOT NULL',
224
                    'sqlsrv' => 'datetime NOT NULL',
225
                ],
226
            ],
227
            [
228
                Schema::TYPE_DATETIME,
229
                $this->dateTime(),
230
                [
231
                    'mysql' => version_compare($version, '5.6.4', '>=') ? 'datetime(0)' : 'datetime',
232
                    'pgsql' => 'timestamp(0)',
233
                    'sqlite' => 'datetime',
234
                    'oci' => 'TIMESTAMP',
235
                    'sqlsrv' => 'datetime',
236
                ],
237
            ],
238
            [
239
                Schema::TYPE_DECIMAL . ' CHECK (value > 5.6)',
240
                $this->decimal()->check('value > 5.6'),
241
                [
242
                    'mysql' => 'decimal(10,0) CHECK (value > 5.6)',
243
                    'pgsql' => 'numeric(10,0) CHECK (value > 5.6)',
244
                    'sqlite' => 'decimal(10,0) CHECK (value > 5.6)',
245
                    'oci' => 'NUMBER CHECK (value > 5.6)',
246
                    'sqlsrv' => 'decimal(18,0) CHECK (value > 5.6)',
247
                ],
248
            ],
249
            [
250
                Schema::TYPE_DECIMAL . ' NOT NULL',
251
                $this->decimal()->notNull(),
252
                [
253
                    'mysql' => 'decimal(10,0) NOT NULL',
254
                    'pgsql' => 'numeric(10,0) NOT NULL',
255
                    'sqlite' => 'decimal(10,0) NOT NULL',
256
                    'oci' => 'NUMBER NOT NULL',
257
                    'sqlsrv' => 'decimal(18,0) NOT NULL',
258
                ],
259
            ],
260
            [
261
                Schema::TYPE_DECIMAL . '(12,4) CHECK (value > 5.6)',
262
                $this->decimal(12, 4)->check('value > 5.6'),
263
                [
264
                    'mysql' => 'decimal(12,4) CHECK (value > 5.6)',
265
                    'pgsql' => 'numeric(12,4) CHECK (value > 5.6)',
266
                    'sqlite' => 'decimal(12,4) CHECK (value > 5.6)',
267
                    'oci' => 'NUMBER CHECK (value > 5.6)',
268
                    'sqlsrv' => 'decimal(12,4) CHECK (value > 5.6)',
269
                ],
270
            ],
271
            [
272
                Schema::TYPE_DECIMAL . '(12,4)',
273
                $this->decimal(12, 4),
274
                [
275
                    'mysql' => 'decimal(12,4)',
276
                    'pgsql' => 'numeric(12,4)',
277
                    'sqlite' => 'decimal(12,4)',
278
                    'oci' => 'NUMBER',
279
                    'sqlsrv' => 'decimal(12,4)',
280
                ],
281
            ],
282
            [
283
                Schema::TYPE_DECIMAL,
284
                $this->decimal(),
285
                [
286
                    'mysql' => 'decimal(10,0)',
287
                    'pgsql' => 'numeric(10,0)',
288
                    'sqlite' => 'decimal(10,0)',
289
                    'oci' => 'NUMBER',
290
                    'sqlsrv' => 'decimal(18,0)',
291
                ],
292
            ],
293
            [
294
                Schema::TYPE_DOUBLE . ' CHECK (value > 5.6)',
295
                $this->double()->check('value > 5.6'),
296
                [
297
                    'mysql' => 'double CHECK (value > 5.6)',
298
                    'pgsql' => 'double precision CHECK (value > 5.6)',
299
                    'sqlite' => 'double CHECK (value > 5.6)',
300
                    'oci' => 'NUMBER CHECK (value > 5.6)',
301
                    'sqlsrv' => 'float CHECK (value > 5.6)',
302
                ],
303
            ],
304
            [
305
                Schema::TYPE_DOUBLE . ' NOT NULL',
306
                $this->double()->notNull(),
307
                [
308
                    'mysql' => 'double NOT NULL',
309
                    'pgsql' => 'double precision NOT NULL',
310
                    'sqlite' => 'double NOT NULL',
311
                    'oci' => 'NUMBER NOT NULL',
312
                    'sqlsrv' => 'float NOT NULL',
313
                ],
314
            ],
315
            [
316
                Schema::TYPE_DOUBLE . '(16) CHECK (value > 5.6)',
317
                $this->double(16)->check('value > 5.6'),
318
                [
319
                    'mysql' => 'double CHECK (value > 5.6)',
320
                    'pgsql' => 'double precision CHECK (value > 5.6)',
321
                    'sqlite' => 'double CHECK (value > 5.6)',
322
                    'oci' => 'NUMBER CHECK (value > 5.6)',
323
                    'sqlsrv' => 'float CHECK (value > 5.6)',
324
                ],
325
            ],
326
            [
327
                Schema::TYPE_DOUBLE . '(16)',
328
                $this->double(16),
329
                [
330
                    'mysql' => 'double',
331
                    'sqlite' => 'double',
332
                    'oci' => 'NUMBER',
333
                    'sqlsrv' => 'float',
334
                ],
335
            ],
336
            [
337
                Schema::TYPE_DOUBLE,
338
                $this->double(),
339
                [
340
                    'mysql' => 'double',
341
                    'pgsql' => 'double precision',
342
                    'sqlite' => 'double',
343
                    'oci' => 'NUMBER',
344
                    'sqlsrv' => 'float',
345
                ],
346
            ],
347
            [
348
                Schema::TYPE_FLOAT . ' CHECK (value > 5.6)',
349
                $this->float()->check('value > 5.6'),
350
                [
351
                    'mysql' => 'float CHECK (value > 5.6)',
352
                    'pgsql' => 'double precision CHECK (value > 5.6)',
353
                    'sqlite' => 'float CHECK (value > 5.6)',
354
                    'oci' => 'NUMBER CHECK (value > 5.6)',
355
                    'sqlsrv' => 'float CHECK (value > 5.6)',
356
                ],
357
            ],
358
            [
359
                Schema::TYPE_FLOAT . ' NOT NULL',
360
                $this->float()->notNull(),
361
                [
362
                    'mysql' => 'float NOT NULL',
363
                    'pgsql' => 'double precision NOT NULL',
364
                    'sqlite' => 'float NOT NULL',
365
                    'oci' => 'NUMBER NOT NULL',
366
                    'sqlsrv' => 'float NOT NULL',
367
                ],
368
            ],
369
            [
370
                Schema::TYPE_FLOAT . '(16) CHECK (value > 5.6)',
371
                $this->float(16)->check('value > 5.6'),
372
                [
373
                    'mysql' => 'float CHECK (value > 5.6)',
374
                    'pgsql' => 'double precision CHECK (value > 5.6)',
375
                    'sqlite' => 'float CHECK (value > 5.6)',
376
                    'oci' => 'NUMBER CHECK (value > 5.6)',
377
                    'sqlsrv' => 'float CHECK (value > 5.6)',
378
                ],
379
            ],
380
            [
381
                Schema::TYPE_FLOAT . '(16)',
382
                $this->float(16),
383
                [
384
                    'mysql' => 'float',
385
                    'sqlite' => 'float',
386
                    'oci' => 'NUMBER',
387
                    'sqlsrv' => 'float',
388
                ],
389
            ],
390
            [
391
                Schema::TYPE_FLOAT,
392
                $this->float(),
393
                [
394
                    'mysql' => 'float',
395
                    'pgsql' => 'double precision',
396
                    'sqlite' => 'float',
397
                    'oci' => 'NUMBER',
398
                    'sqlsrv' => 'float',
399
                ],
400
            ],
401
            [
402
                Schema::TYPE_INTEGER . ' CHECK (value > 5)',
403
                $this->integer()->check('value > 5'),
404
                [
405
                    'mysql' => 'int(11) CHECK (value > 5)',
406
                    'pgsql' => 'integer CHECK (value > 5)',
407
                    'sqlite' => 'integer CHECK (value > 5)',
408
                    'oci' => 'NUMBER(10) CHECK (value > 5)',
409
                    'sqlsrv' => 'int CHECK (value > 5)',
410
                ],
411
            ],
412
            [
413
                Schema::TYPE_INTEGER . ' NOT NULL',
414
                $this->integer()->notNull(),
415
                [
416
                    'mysql' => 'int(11) NOT NULL',
417
                    'pgsql' => 'integer NOT NULL',
418
                    'sqlite' => 'integer NOT NULL',
419
                    'oci' => 'NUMBER(10) NOT NULL',
420
                    'sqlsrv' => 'int NOT NULL',
421
                ],
422
            ],
423
            [
424
                Schema::TYPE_INTEGER . '(8) CHECK (value > 5)',
425
                $this->integer(8)->check('value > 5'),
426
                [
427
                    'mysql' => 'int(8) CHECK (value > 5)',
428
                    'pgsql' => 'integer CHECK (value > 5)',
429
                    'sqlite' => 'integer CHECK (value > 5)',
430
                    'oci' => 'NUMBER(8) CHECK (value > 5)',
431
                    'sqlsrv' => 'int CHECK (value > 5)',
432
                ],
433
            ],
434
            [
435
                Schema::TYPE_INTEGER . '(8)',
436
                $this->integer(8)->unsigned(),
437
                [
438
                    'pgsql' => 'integer',
439
                ],
440
            ],
441
            [
442
                Schema::TYPE_INTEGER . '(8)',
443
                $this->integer(8),
444
                [
445
                    'mysql' => 'int(8)',
446
                    'pgsql' => 'integer',
447
                    'sqlite' => 'integer',
448
                    'oci' => 'NUMBER(8)',
449
                    'sqlsrv' => 'int',
450
                ],
451
            ],
452
            [
453
                Schema::TYPE_INTEGER,
454
                $this->integer(),
455
                [
456
                    'mysql' => 'int(11)',
457
                    'pgsql' => 'integer',
458
                    'sqlite' => 'integer',
459
                    'oci' => 'NUMBER(10)',
460
                    'sqlsrv' => 'int',
461
                ],
462
            ],
463
            [
464
                Schema::TYPE_MONEY . ' CHECK (value > 0.0)',
465
                $this->money()->check('value > 0.0'),
466
                [
467
                    'mysql' => 'decimal(19,4) CHECK (value > 0.0)',
468
                    'pgsql' => 'numeric(19,4) CHECK (value > 0.0)',
469
                    'sqlite' => 'decimal(19,4) CHECK (value > 0.0)',
470
                    'oci' => 'NUMBER(19,4) CHECK (value > 0.0)',
471
                    'sqlsrv' => 'decimal(19,4) CHECK (value > 0.0)',
472
                ],
473
            ],
474
            [
475
                Schema::TYPE_MONEY . ' NOT NULL',
476
                $this->money()->notNull(),
477
                [
478
                    'mysql' => 'decimal(19,4) NOT NULL',
479
                    'pgsql' => 'numeric(19,4) NOT NULL',
480
                    'sqlite' => 'decimal(19,4) NOT NULL',
481
                    'oci' => 'NUMBER(19,4) NOT NULL',
482
                    'sqlsrv' => 'decimal(19,4) NOT NULL',
483
                ],
484
            ],
485
            [
486
                Schema::TYPE_MONEY . '(16,2) CHECK (value > 0.0)',
487
                $this->money(16, 2)->check('value > 0.0'),
488
                [
489
                    'mysql' => 'decimal(16,2) CHECK (value > 0.0)',
490
                    'pgsql' => 'numeric(16,2) CHECK (value > 0.0)',
491
                    'sqlite' => 'decimal(16,2) CHECK (value > 0.0)',
492
                    'oci' => 'NUMBER(16,2) CHECK (value > 0.0)',
493
                    'sqlsrv' => 'decimal(16,2) CHECK (value > 0.0)',
494
                ],
495
            ],
496
            [
497
                Schema::TYPE_MONEY . '(16,2)',
498
                $this->money(16, 2),
499
                [
500
                    'mysql' => 'decimal(16,2)',
501
                    'pgsql' => 'numeric(16,2)',
502
                    'sqlite' => 'decimal(16,2)',
503
                    'oci' => 'NUMBER(16,2)',
504
                    'sqlsrv' => 'decimal(16,2)',
505
                ],
506
            ],
507
            [
508
                Schema::TYPE_MONEY,
509
                $this->money(),
510
                [
511
                    'mysql' => 'decimal(19,4)',
512
                    'pgsql' => 'numeric(19,4)',
513
                    'sqlite' => 'decimal(19,4)',
514
                    'oci' => 'NUMBER(19,4)',
515
                    'sqlsrv' => 'decimal(19,4)',
516
                ],
517
            ],
518
            [
519
                Schema::TYPE_PK . ' AFTER `col_before`',
520
                $this->primaryKey()->after('col_before'),
521
                [
522
                    'mysql' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY AFTER `col_before`',
523
                ],
524
            ],
525
            [
526
                Schema::TYPE_PK . ' FIRST',
527
                $this->primaryKey()->first(),
528
                [
529
                    'mysql' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST',
530
                ],
531
            ],
532
            [
533
                Schema::TYPE_PK . ' FIRST',
534
                $this->primaryKey()->first()->after('col_before'),
535
                [
536
                    'mysql' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST',
537
                ],
538
                [
539
                    'sqlite' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
540
                ],
541
            ],
542
            [
543
                Schema::TYPE_PK . '(8) AFTER `col_before`',
544
                $this->primaryKey(8)->after('col_before'),
545
                [
546
                    'mysql' => 'int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY AFTER `col_before`',
547
                ],
548
            ],
549
            [
550
                Schema::TYPE_PK . '(8) FIRST',
551
                $this->primaryKey(8)->first(),
552
                [
553
                    'mysql' => 'int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST',
554
                ],
555
            ],
556
            [
557
                Schema::TYPE_PK . '(8) FIRST',
558
                $this->primaryKey(8)->first()->after('col_before'),
559
                [
560
                    'mysql' => 'int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST',
561
                ],
562
            ],
563
            [
564
                Schema::TYPE_PK . " COMMENT 'test' AFTER `col_before`",
565
                $this->primaryKey()->comment('test')->after('col_before'),
566
                [
567
                    'mysql' => "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'test' AFTER `col_before`",
568
                ],
569
            ],
570
            [
571
                Schema::TYPE_PK . " COMMENT 'testing \'quote\'' AFTER `col_before`",
572
                $this->primaryKey()->comment('testing \'quote\'')->after('col_before'),
573
                [
574
                    'mysql' => "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'testing \'quote\''"
575
                        . ' AFTER `col_before`',
576
                ],
577
            ],
578
            [
579
                Schema::TYPE_PK . ' CHECK (value > 5)',
580
                $this->primaryKey()->check('value > 5'),
581
                [
582
                    'mysql' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY CHECK (value > 5)',
583
                    'pgsql' => 'serial NOT NULL PRIMARY KEY CHECK (value > 5)',
584
                    'sqlite' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL CHECK (value > 5)',
585
                    'oci' => 'NUMBER(10) NOT NULL PRIMARY KEY CHECK (value > 5)',
586
                    'sqlsrv' => 'int IDENTITY PRIMARY KEY CHECK (value > 5)',
587
                ],
588
            ],
589
            [
590
                Schema::TYPE_PK . '(8) CHECK (value > 5)',
591
                $this->primaryKey(8)->check('value > 5'),
592
                [
593
                    'mysql' => 'int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY CHECK (value > 5)',
594
                    'oci' => 'NUMBER(8) NOT NULL PRIMARY KEY CHECK (value > 5)',
595
                ],
596
            ],
597
            [
598
                Schema::TYPE_PK . '(8)',
599
                $this->primaryKey(8),
600
                [
601
                    'mysql' => 'int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY',
602
                    'oci' => 'NUMBER(8) NOT NULL PRIMARY KEY',
603
                ],
604
            ],
605
            [
606
                Schema::TYPE_PK,
607
                $this->primaryKey(),
608
                [
609
                    'mysql' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY',
610
                    'pgsql' => 'serial NOT NULL PRIMARY KEY',
611
                    'sqlite' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
612
                    'oci' => 'NUMBER(10) NOT NULL PRIMARY KEY',
613
                    'sqlsrv' => 'int IDENTITY PRIMARY KEY',
614
                ],
615
            ],
616
            [
617
                Schema::TYPE_TINYINT . '(2)',
618
                $this->tinyInteger(2),
619
                [
620
                    'mysql' => 'tinyint(2)',
621
                    'pgsql' => 'smallint',
622
                    'sqlite' => 'tinyint',
623
                    'oci' => 'NUMBER(2)',
624
                    'sqlsrv' => 'tinyint',
625
                ],
626
            ],
627
            [
628
                Schema::TYPE_TINYINT . ' UNSIGNED',
629
                $this->tinyInteger()->unsigned(),
630
                [
631
                    'mysql' => 'tinyint(3) UNSIGNED',
632
                    'sqlite' => 'tinyint UNSIGNED',
633
                ],
634
            ],
635
            [
636
                Schema::TYPE_TINYINT,
637
                $this->tinyInteger(),
638
                [
639
                    'mysql' => 'tinyint(3)',
640
                    'pgsql' => 'smallint',
641
                    'sqlite' => 'tinyint',
642
                    'oci' => 'NUMBER(3)',
643
                    'sqlsrv' => 'tinyint',
644
                ],
645
            ],
646
            [
647
                Schema::TYPE_SMALLINT . '(8)',
648
                $this->smallInteger(8),
649
                [
650
                    'mysql' => 'smallint(8)',
651
                    'pgsql' => 'smallint',
652
                    'sqlite' => 'smallint',
653
                    'oci' => 'NUMBER(8)',
654
                    'sqlsrv' => 'smallint',
655
                ],
656
            ],
657
            [
658
                Schema::TYPE_SMALLINT,
659
                $this->smallInteger(),
660
                [
661
                    'mysql' => 'smallint(6)',
662
                    'pgsql' => 'smallint',
663
                    'sqlite' => 'smallint',
664
                    'oci' => 'NUMBER(5)',
665
                    'sqlsrv' => 'smallint',
666
                ],
667
            ],
668
            [
669
                Schema::TYPE_STRING . " CHECK (value LIKE 'test%')",
670
                $this->string()->check("value LIKE 'test%'"),
671
                [
672
                    'mysql' => "varchar(255) CHECK (value LIKE 'test%')",
673
                    'sqlite' => "varchar(255) CHECK (value LIKE 'test%')",
674
                    'sqlsrv' => "nvarchar(255) CHECK (value LIKE 'test%')",
675
                ],
676
            ],
677
            [
678
                Schema::TYPE_STRING . ' CHECK (value LIKE \'test%\')',
679
                $this->string()->check('value LIKE \'test%\''),
680
                [
681
                    'pgsql' => 'varchar(255) CHECK (value LIKE \'test%\')',
682
                    'oci' => 'VARCHAR2(255) CHECK (value LIKE \'test%\')',
683
                ],
684
            ],
685
            [
686
                Schema::TYPE_STRING . ' NOT NULL',
687
                $this->string()->notNull(),
688
                [
689
                    'mysql' => 'varchar(255) NOT NULL',
690
                    'pgsql' => 'varchar(255) NOT NULL',
691
                    'sqlite' => 'varchar(255) NOT NULL',
692
                    'oci' => 'VARCHAR2(255) NOT NULL',
693
                    'sqlsrv' => 'nvarchar(255) NOT NULL',
694
                ],
695
            ],
696
            [
697
                Schema::TYPE_STRING . "(32) CHECK (value LIKE 'test%')",
698
                $this->string(32)->check("value LIKE 'test%'"),
699
                [
700
                    'mysql' => "varchar(32) CHECK (value LIKE 'test%')",
701
                    'sqlite' => "varchar(32) CHECK (value LIKE 'test%')",
702
                    'sqlsrv' => "nvarchar(32) CHECK (value LIKE 'test%')",
703
                ],
704
            ],
705
            [
706
                Schema::TYPE_STRING . '(32) CHECK (value LIKE \'test%\')',
707
                $this->string(32)->check('value LIKE \'test%\''),
708
                [
709
                    'pgsql' => 'varchar(32) CHECK (value LIKE \'test%\')',
710
                    'oci' => 'VARCHAR2(32) CHECK (value LIKE \'test%\')',
711
                ],
712
            ],
713
            [
714
                Schema::TYPE_STRING . '(32)',
715
                $this->string(32),
716
                [
717
                    'mysql' => 'varchar(32)',
718
                    'pgsql' => 'varchar(32)',
719
                    'sqlite' => 'varchar(32)',
720
                    'oci' => 'VARCHAR2(32)',
721
                    'sqlsrv' => 'nvarchar(32)',
722
                ],
723
            ],
724
            [
725
                Schema::TYPE_STRING,
726
                $this->string(),
727
                [
728
                    'mysql' => 'varchar(255)',
729
                    'pgsql' => 'varchar(255)',
730
                    'sqlite' => 'varchar(255)',
731
                    'oci' => 'VARCHAR2(255)',
732
                    'sqlsrv' => 'nvarchar(255)',
733
                ],
734
            ],
735
            [
736
                Schema::TYPE_TEXT . " CHECK (value LIKE 'test%')",
737
                $this->text()->check("value LIKE 'test%'"),
738
                [
739
                    'mysql' => "text CHECK (value LIKE 'test%')",
740
                    'sqlite' => "text CHECK (value LIKE 'test%')",
741
                    'sqlsrv' => "nvarchar(max) CHECK (value LIKE 'test%')",
742
                ],
743
            ],
744
            [
745
                Schema::TYPE_TEXT . ' CHECK (value LIKE \'test%\')',
746
                $this->text()->check('value LIKE \'test%\''),
747
                [
748
                    'pgsql' => 'text CHECK (value LIKE \'test%\')',
749
                    'oci' => 'CLOB CHECK (value LIKE \'test%\')',
750
                ],
751
            ],
752
            [
753
                Schema::TYPE_TEXT . ' NOT NULL',
754
                $this->text()->notNull(),
755
                [
756
                    'mysql' => 'text NOT NULL',
757
                    'pgsql' => 'text NOT NULL',
758
                    'sqlite' => 'text NOT NULL',
759
                    'oci' => 'CLOB NOT NULL',
760
                    'sqlsrv' => 'nvarchar(max) NOT NULL',
761
                ],
762
            ],
763
            [
764
                Schema::TYPE_TEXT . " CHECK (value LIKE 'test%')",
765
                $this->text()->check("value LIKE 'test%'"),
766
                [
767
                    'mysql' => "text CHECK (value LIKE 'test%')",
768
                    'sqlite' => "text CHECK (value LIKE 'test%')",
769
                    'sqlsrv' => "nvarchar(max) CHECK (value LIKE 'test%')",
770
                ],
771
                Schema::TYPE_TEXT . " CHECK (value LIKE 'test%')",
772
            ],
773
            [
774
                Schema::TYPE_TEXT . ' CHECK (value LIKE \'test%\')',
775
                $this->text()->check('value LIKE \'test%\''),
776
                [
777
                    'pgsql' => 'text CHECK (value LIKE \'test%\')',
778
                    'oci' => 'CLOB CHECK (value LIKE \'test%\')',
779
                ],
780
                Schema::TYPE_TEXT . ' CHECK (value LIKE \'test%\')',
781
            ],
782
            [
783
                Schema::TYPE_TEXT . ' NOT NULL',
784
                $this->text()->notNull(),
785
                [
786
                    'mysql' => 'text NOT NULL',
787
                    'pgsql' => 'text NOT NULL',
788
                    'sqlite' => 'text NOT NULL',
789
                    'oci' => 'CLOB NOT NULL',
790
                    'sqlsrv' => 'nvarchar(max) NOT NULL',
791
                ],
792
                Schema::TYPE_TEXT . ' NOT NULL',
793
            ],
794
            [
795
                Schema::TYPE_TEXT,
796
                $this->text(),
797
                [
798
                    'mysql' => 'text',
799
                    'pgsql' => 'text',
800
                    'sqlite' => 'text',
801
                    'oci' => 'CLOB',
802
                    'sqlsrv' => 'nvarchar(max)',
803
                ],
804
                Schema::TYPE_TEXT,
805
            ],
806
            [
807
                Schema::TYPE_TEXT,
808
                $this->text(),
809
                [
810
                    'mysql' => 'text',
811
                    'pgsql' => 'text',
812
                    'sqlite' => 'text',
813
                    'oci' => 'CLOB',
814
                    'sqlsrv' => 'nvarchar(max)',
815
                ],
816
            ],
817
            [
818
                Schema::TYPE_TIME . ' NOT NULL',
819
                $this->time()->notNull(),
820
                [
821
                    'mysql' => version_compare($version, '5.6.4', '>=') ? 'time(0) NOT NULL' : 'time NOT NULL',
822
                    'pgsql' => 'time(0) NOT NULL',
823
                    'sqlite' => 'time NOT NULL',
824
                    'oci' => 'TIMESTAMP NOT NULL',
825
                    'sqlsrv' => 'time NOT NULL',
826
                ],
827
            ],
828
            [
829
                Schema::TYPE_TIME,
830
                $this->time(),
831
                [
832
                    'mysql' => version_compare($version, '5.6.4', '>=') ? 'time(0)' : 'time',
833
                    'pgsql' => 'time(0)',
834
                    'sqlite' => 'time',
835
                    'oci' => 'TIMESTAMP',
836
                    'sqlsrv' => 'time',
837
                ],
838
            ],
839
            [
840
                Schema::TYPE_TIMESTAMP . ' NOT NULL',
841
                $this->timestamp()->notNull(),
842
                [
843
                    'mysql' => version_compare($version, '5.6.4', '>=') ? 'timestamp(0) NOT NULL'
844
                        : 'timestamp NOT NULL',
845
                    'pgsql' => 'timestamp(0) NOT NULL',
846
                    'sqlite' => 'timestamp NOT NULL',
847
                    'oci' => 'TIMESTAMP NOT NULL',
848
                    'sqlsrv' => 'datetime NOT NULL',
849
                ],
850
            ],
851
            [
852
                Schema::TYPE_TIMESTAMP . ' NULL DEFAULT NULL',
853
                $this->timestamp()->defaultValue(null),
854
                [
855
                    'mysql' => version_compare($version, '5.6.4', '>=') ? 'timestamp(0) NULL DEFAULT NULL'
856
                        : 'timestamp NULL DEFAULT NULL',
857
                    'pgsql' => 'timestamp(0) NULL DEFAULT NULL',
858
                    'sqlite' => 'timestamp NULL DEFAULT NULL',
859
                    'sqlsrv' => 'datetime NULL DEFAULT NULL',
860
                ],
861
            ],
862
            [
863
                Schema::TYPE_TIMESTAMP . '(4)',
864
                $this->timestamp(4),
865
                [
866
                    'pgsql' => 'timestamp(4)',
867
                ],
868
            ],
869
            [
870
                Schema::TYPE_TIMESTAMP,
871
                $this->timestamp(),
872
                [
873
                    /**
874
                     * MySQL has its own TIMESTAMP test realization.
875
                     *
876
                     * {@see QueryBuilderTest::columnTypes()}
877
                     */
878
                    'pgsql' => 'timestamp(0)',
879
                    'sqlite' => 'timestamp',
880
                    'oci' => 'TIMESTAMP',
881
                    'sqlsrv' => 'datetime',
882
                ],
883
            ],
884
            [
885
                Schema::TYPE_UPK,
886
                $this->primaryKey()->unsigned(),
887
                [
888
                    'mysql' => 'int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
889
                    'pgsql' => 'serial NOT NULL PRIMARY KEY',
890
                    'sqlite' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
891
                ],
892
            ],
893
            [
894
                Schema::TYPE_UBIGPK,
895
                $this->bigPrimaryKey()->unsigned(),
896
                [
897
                    'mysql' => 'bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
898
                    'pgsql' => 'bigserial NOT NULL PRIMARY KEY',
899
                    'sqlite' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
900
                ],
901
            ],
902
            [
903
                Schema::TYPE_INTEGER . " COMMENT 'test comment'",
904
                $this->integer()->comment('test comment'),
905
                [
906
                    'mysql' => "int(11) COMMENT 'test comment'",
907
                    'sqlsrv' => 'int',
908
                ],
909
                [
910
                    'sqlsrv' => 'integer',
911
                ],
912
            ],
913
            [
914
                Schema::TYPE_PK . " COMMENT 'test comment'",
915
                $this->primaryKey()->comment('test comment'),
916
                [
917
                    'mysql' => "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'test comment'",
918
                    'sqlsrv' => 'int IDENTITY PRIMARY KEY',
919
                ],
920
                [
921
                    'sqlsrv' => 'pk',
922
                ],
923
            ],
924
            [
925
                Schema::TYPE_PK . ' FIRST',
926
                $this->primaryKey()->first(),
927
                [
928
                    'mysql' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST',
929
                    'sqlsrv' => 'int IDENTITY PRIMARY KEY',
930
                ],
931
                [
932
                    'oci' => 'NUMBER(10) NOT NULL PRIMARY KEY FIRST',
933
                    'sqlsrv' => 'pk',
934
                ],
935
            ],
936
            [
937
                Schema::TYPE_INTEGER . ' FIRST',
938
                $this->integer()->first(),
939
                [
940
                    'mysql' => 'int(11) FIRST',
941
                    'sqlsrv' => 'int',
942
                ],
943
                [
944
                    'oci' => 'NUMBER(10) FIRST',
945
                    'pgsql' => 'integer',
946
                    'sqlsrv' => 'integer',
947
                ],
948
            ],
949
            [
950
                Schema::TYPE_STRING . ' FIRST',
951
                $this->string()->first(),
952
                [
953
                    'mysql' => 'varchar(255) FIRST',
954
                    'sqlsrv' => 'nvarchar(255)',
955
                ],
956
                [
957
                    'oci' => 'VARCHAR2(255) FIRST',
958
                    'sqlsrv' => 'string',
959
                ],
960
            ],
961
            [
962
                Schema::TYPE_INTEGER . ' NOT NULL FIRST',
963
                $this->integer()->append('NOT NULL')->first(),
964
                [
965
                    'mysql' => 'int(11) NOT NULL FIRST',
966
                    'sqlsrv' => 'int NOT NULL',
967
                ],
968
                [
969
                    'oci' => 'NUMBER(10) NOT NULL FIRST',
970
                    'sqlsrv' => 'integer NOT NULL',
971
                ],
972
            ],
973
            [
974
                Schema::TYPE_STRING . ' NOT NULL FIRST',
975
                $this->string()->append('NOT NULL')->first(),
976
                [
977
                    'mysql' => 'varchar(255) NOT NULL FIRST',
978
                    'sqlsrv' => 'nvarchar(255) NOT NULL',
979
                ],
980
                [
981
                    'oci' => 'VARCHAR2(255) NOT NULL FIRST',
982
                    'sqlsrv' => 'string NOT NULL',
983
                ],
984
            ],
985
            [
986
                Schema::TYPE_JSON,
987
                $this->json(),
988
                [
989
                    'pgsql' => 'jsonb',
990
                ],
991
            ],
992
        ];
993
994
        $driverName = $this->getConnection()->getDriverName();
995
        foreach ($items as $i => $item) {
996
            if (array_key_exists($driverName, $item[2])) {
997
                $item[2] = $item[2][$driverName];
998
                $items[$i] = $item;
999
            } else {
1000
                unset($items[$i]);
1001
            }
1002
        }
1003
1004
        return array_values($items);
1005
    }
1006
1007
    public function testGetColumnType(): void
1008
    {
1009
        $db = $this->getConnection();
1010
        $qb = $db->getQueryBuilder();
1011
1012
        foreach ($this->columnTypes() as $item) {
1013
            [$column, $builder, $expected] = $item;
1014
1015
            $driverName = $db->getDriverName();
1016
            if (isset($item[3][$driverName])) {
1017
                $expectedColumnSchemaBuilder = $item[3][$driverName];
1018
            } elseif (isset($item[3]) && !is_array($item[3])) {
1019
                $expectedColumnSchemaBuilder = $item[3];
1020
            } else {
1021
                $expectedColumnSchemaBuilder = $column;
1022
            }
1023
1024
            $this->assertEquals($expectedColumnSchemaBuilder, $builder->__toString());
0 ignored issues
show
Bug introduced by
It seems like assertEquals() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1024
            $this->/** @scrutinizer ignore-call */ 
1025
                   assertEquals($expectedColumnSchemaBuilder, $builder->__toString());
Loading history...
1025
            $this->assertEquals($expected, $qb->getColumnType($column));
1026
            $this->assertEquals($expected, $qb->getColumnType($builder));
1027
        }
1028
    }
1029
1030
    public function testCreateTableColumnTypes(): void
1031
    {
1032
        $db = $this->getConnection();
1033
        $qb = $db->getQueryBuilder();
1034
1035
        if ($db->getTableSchema('column_type_table', true) !== null) {
1036
            $db->createCommand($qb->dropTable('column_type_table'))->execute();
1037
        }
1038
1039
        $columns = [];
1040
        $i = 0;
1041
1042
        foreach ($this->columnTypes() as [$column, $builder, $expected]) {
1043
            if (
1044
                !(
1045
                    strncmp($column, Schema::TYPE_PK, 2) === 0 ||
1046
                    strncmp($column, Schema::TYPE_UPK, 3) === 0 ||
1047
                    strncmp($column, Schema::TYPE_BIGPK, 5) === 0 ||
1048
                    strncmp($column, Schema::TYPE_UBIGPK, 6) === 0 ||
1049
                    strncmp(substr($column, -5), 'FIRST', 5) === 0
1050
                )
1051
            ) {
1052
                $columns['col' . ++$i] = str_replace('CHECK (value', 'CHECK ([[col' . $i . ']]', $column);
1053
            }
1054
        }
1055
1056
        $db->createCommand($qb->createTable('column_type_table', $columns))->execute();
1057
        $this->assertNotEmpty($db->getTableSchema('column_type_table', true));
0 ignored issues
show
Bug introduced by
It seems like assertNotEmpty() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1057
        $this->/** @scrutinizer ignore-call */ 
1058
               assertNotEmpty($db->getTableSchema('column_type_table', true));
Loading history...
1058
    }
1059
1060
    public function testBuildWhereExistsWithParameters(): void
1061
    {
1062
        $db = $this->getConnection();
1063
1064
        $expectedQuerySql = $this->replaceQuotes(
0 ignored issues
show
Bug introduced by
It seems like replaceQuotes() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1064
        /** @scrutinizer ignore-call */ 
1065
        $expectedQuerySql = $this->replaceQuotes(
Loading history...
1065
            'SELECT [[id]] FROM [[TotalExample]] [[t]] WHERE (EXISTS (SELECT [[1]] FROM [[Website]] [[w]]'
1066
            . ' WHERE (w.id = t.website_id) AND (w.merchant_id = :merchant_id))) AND (t.some_column = :some_value)'
1067
        );
1068
1069
        $expectedQueryParams = [':some_value' => 'asd', ':merchant_id' => 6];
1070
1071
        $subQuery = new Query($db);
1072
1073
        $subQuery->select('1')
1074
            ->from('Website w')
1075
            ->where('w.id = t.website_id')
1076
            ->andWhere('w.merchant_id = :merchant_id', [':merchant_id' => 6]);
1077
1078
        $query = new Query($db);
1079
1080
        $query->select('id')
1081
            ->from('TotalExample t')
1082
            ->where(['exists', $subQuery])
1083
            ->andWhere('t.some_column = :some_value', [':some_value' => 'asd']);
1084
1085
        [$actualQuerySql, $queryParams] = $db->getQueryBuilder()->build($query);
1086
1087
        $this->assertEquals($expectedQuerySql, $actualQuerySql);
1088
        $this->assertEquals($expectedQueryParams, $queryParams);
1089
    }
1090
1091
    public function testBuildWhereExistsWithArrayParameters(): void
1092
    {
1093
        $db = $this->getConnection();
1094
1095
        $expectedQuerySql = $this->replaceQuotes(
1096
            'SELECT [[id]] FROM [[TotalExample]] [[t]] WHERE (EXISTS (SELECT [[1]] FROM [[Website]] [[w]]'
1097
            . ' WHERE (w.id = t.website_id) AND (([[w]].[[merchant_id]]=:qp0) AND ([[w]].[[user_id]]=:qp1))))'
1098
            . ' AND ([[t]].[[some_column]]=:qp2)'
1099
        );
1100
1101
        $expectedQueryParams = [':qp0' => 6, ':qp1' => 210, ':qp2' => 'asd'];
1102
1103
        $subQuery = new Query($db);
1104
1105
        $subQuery->select('1')
1106
            ->from('Website w')
1107
            ->where('w.id = t.website_id')
1108
            ->andWhere(['w.merchant_id' => 6, 'w.user_id' => '210']);
1109
1110
        $query = new Query($db);
1111
1112
        $query->select('id')
1113
            ->from('TotalExample t')
1114
            ->where(['exists', $subQuery])
1115
            ->andWhere(['t.some_column' => 'asd']);
1116
1117
        [$actualQuerySql, $queryParams] = $db->getQueryBuilder()->build($query);
1118
1119
        $this->assertEquals($expectedQuerySql, $actualQuerySql);
1120
        $this->assertEquals($expectedQueryParams, $queryParams);
1121
    }
1122
1123
    /**
1124
     * This test contains three select queries connected with UNION and UNION ALL constructions.
1125
     * It could be useful to use "phpunit --group=db --filter testBuildUnion" command for run it.
1126
     */
1127
    public function testBuildUnion(): void
1128
    {
1129
        $db = $this->getConnection();
1130
1131
        $expectedQuerySql = $this->replaceQuotes(
1132
            '(SELECT [[id]] FROM [[TotalExample]] [[t1]] WHERE (w > 0) AND (x < 2)) UNION ( SELECT [[id]]'
1133
            . ' FROM [[TotalTotalExample]] [[t2]] WHERE w > 5 ) UNION ALL ( SELECT [[id]] FROM [[TotalTotalExample]]'
1134
            . ' [[t3]] WHERE w = 3 )'
1135
        );
1136
1137
        $query = new Query($db);
1138
        $secondQuery = new Query($db);
1139
1140
        $secondQuery->select('id')
1141
              ->from('TotalTotalExample t2')
1142
              ->where('w > 5');
1143
1144
        $thirdQuery = new Query($db);
1145
1146
        $thirdQuery->select('id')
1147
              ->from('TotalTotalExample t3')
1148
              ->where('w = 3');
1149
1150
        $query->select('id')
1151
              ->from('TotalExample t1')
1152
              ->where(['and', 'w > 0', 'x < 2'])
1153
              ->union($secondQuery)
1154
              ->union($thirdQuery, true);
1155
1156
        [$actualQuerySql, $queryParams] = $db->getQueryBuilder()->build($query);
1157
1158
        $this->assertEquals($expectedQuerySql, $actualQuerySql);
1159
        $this->assertEquals([], $queryParams);
1160
    }
1161
1162
    public function testBuildWithQuery(): void
1163
    {
1164
        $db = $this->getConnection();
1165
1166
        $expectedQuerySql = $this->replaceQuotes(
1167
            'WITH a1 AS (SELECT [[id]] FROM [[t1]] WHERE expr = 1), a2 AS ((SELECT [[id]] FROM [[t2]]'
1168
            . ' INNER JOIN [[a1]] ON t2.id = a1.id WHERE expr = 2) UNION ( SELECT [[id]] FROM [[t3]] WHERE expr = 3 ))'
1169
            . ' SELECT * FROM [[a2]]'
1170
        );
1171
1172
        $with1Query = (new Query($db))
1173
            ->select('id')
1174
            ->from('t1')
1175
            ->where('expr = 1');
1176
1177
        $with2Query = (new Query($db))
1178
            ->select('id')
1179
            ->from('t2')
1180
            ->innerJoin('a1', 't2.id = a1.id')
1181
            ->where('expr = 2');
1182
1183
        $with3Query = (new Query($db))
1184
            ->select('id')
1185
            ->from('t3')
1186
            ->where('expr = 3');
1187
1188
        $query = (new Query($db))
1189
            ->withQuery($with1Query, 'a1')
1190
            ->withQuery($with2Query->union($with3Query), 'a2')
1191
            ->from('a2');
1192
1193
        [$actualQuerySql, $queryParams] = $db->getQueryBuilder()->build($query);
1194
1195
        $this->assertEquals($expectedQuerySql, $actualQuerySql);
1196
        $this->assertEquals([], $queryParams);
1197
    }
1198
1199
    public function testBuildWithQueryRecursive(): void
1200
    {
1201
        $db = $this->getConnection();
1202
1203
        $expectedQuerySql = $this->replaceQuotes(
1204
            'WITH RECURSIVE a1 AS (SELECT [[id]] FROM [[t1]] WHERE expr = 1) SELECT * FROM [[a1]]'
1205
        );
1206
1207
        $with1Query = (new Query($db))
1208
            ->select('id')
1209
            ->from('t1')
1210
            ->where('expr = 1');
1211
1212
        $query = (new Query($db))
1213
            ->withQuery($with1Query, 'a1', true)
1214
            ->from('a1');
1215
1216
        [$actualQuerySql, $queryParams] = $db->getQueryBuilder()->build($query);
1217
1218
        $this->assertEquals($expectedQuerySql, $actualQuerySql);
1219
        $this->assertEquals([], $queryParams);
1220
    }
1221
1222
    public function testSelectSubquery(): void
1223
    {
1224
        $db = $this->getConnection();
1225
1226
        $subquery = (new Query($db))
1227
            ->select('COUNT(*)')
1228
            ->from('operations')
1229
            ->where('account_id = accounts.id');
1230
1231
        $query = (new Query($db))
1232
            ->select('*')
1233
            ->from('accounts')
1234
            ->addSelect(['operations_count' => $subquery]);
1235
1236
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1237
1238
        $expected = $this->replaceQuotes(
1239
            'SELECT *, (SELECT COUNT(*) FROM [[operations]] WHERE account_id = accounts.id) AS [[operations_count]]'
1240
            . ' FROM [[accounts]]'
1241
        );
1242
1243
        $this->assertEquals($expected, $sql);
1244
        $this->assertEmpty($params);
0 ignored issues
show
Bug introduced by
It seems like assertEmpty() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1244
        $this->/** @scrutinizer ignore-call */ 
1245
               assertEmpty($params);
Loading history...
1245
    }
1246
1247
    public function testComplexSelect(): void
1248
    {
1249
        $db = $this->getConnection();
1250
1251
        $expressionString = $this->replaceQuotes(
1252
            "case t.Status_Id when 1 then 'Acknowledge' when 2 then 'No Action' else 'Unknown Action'"
1253
            . ' END as [[Next Action]]'
1254
        );
1255
        $this->assertIsString($expressionString);
0 ignored issues
show
Bug introduced by
It seems like assertIsString() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1255
        $this->/** @scrutinizer ignore-call */ 
1256
               assertIsString($expressionString);
Loading history...
1256
1257
        $query = (new Query($db))
1258
            ->select([
1259
                'ID' => 't.id',
1260
                'gsm.username as GSM',
1261
                'part.Part',
1262
                'Part Cost' => 't.Part_Cost',
1263
                'st_x(location::geometry) as lon',
1264
                new Expression($expressionString),
1265
            ])
1266
            ->from('tablename');
1267
1268
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1269
1270
        $expected = $this->replaceQuotes(
1271
            'SELECT [[t]].[[id]] AS [[ID]], [[gsm]].[[username]] AS [[GSM]], [[part]].[[Part]], [[t]].[[Part_Cost]]'
1272
            . ' AS [[Part Cost]], st_x(location::geometry) AS [[lon]], case t.Status_Id when 1 then \'Acknowledge\''
1273
            . ' when 2 then \'No Action\' else \'Unknown Action\' END as [[Next Action]] FROM [[tablename]]'
1274
        );
1275
1276
        $this->assertEquals($expected, $sql);
1277
        $this->assertEmpty($params);
1278
    }
1279
1280
    public function testSelectExpression(): void
1281
    {
1282
        $db = $this->getConnection();
1283
1284
        $query = (new Query($db))
1285
            ->select(new Expression('1 AS ab'))
1286
            ->from('tablename');
1287
1288
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1289
1290
        $expected = $this->replaceQuotes('SELECT 1 AS ab FROM [[tablename]]');
1291
1292
        $this->assertEquals($expected, $sql);
1293
        $this->assertEmpty($params);
1294
1295
        $query = (new Query($db))
1296
            ->select(new Expression('1 AS ab'))
1297
            ->addSelect(new Expression('2 AS cd'))
1298
            ->addSelect(['ef' => new Expression('3')])
1299
            ->from('tablename');
1300
1301
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1302
1303
        $expected = $this->replaceQuotes('SELECT 1 AS ab, 2 AS cd, 3 AS [[ef]] FROM [[tablename]]');
1304
1305
        $this->assertEquals($expected, $sql);
1306
        $this->assertEmpty($params);
1307
1308
        $query = (new Query($db))
1309
            ->select(new Expression('SUBSTR(name, 0, :len)', [':len' => 4]))
1310
            ->from('tablename');
1311
1312
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1313
1314
        $expected = $this->replaceQuotes('SELECT SUBSTR(name, 0, :len) FROM [[tablename]]');
1315
1316
        $this->assertEquals($expected, $sql);
1317
        $this->assertEquals([':len' => 4], $params);
1318
    }
1319
1320
    /**
1321
     * {@see https://github.com/yiisoft/yii2/issues/10869}
1322
     */
1323
    public function testFromIndexHint(): void
1324
    {
1325
        $db = $this->getConnection();
1326
1327
        $query = (new Query($db))->from([new Expression('{{%user}} USE INDEX (primary)')]);
1328
1329
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1330
1331
        $expected = $this->replaceQuotes('SELECT * FROM {{%user}} USE INDEX (primary)');
1332
1333
        $this->assertEquals($expected, $sql);
1334
        $this->assertEmpty($params);
1335
1336
        $query = (new Query($db))
1337
            ->from([new Expression('{{user}} {{t}} FORCE INDEX (primary) IGNORE INDEX FOR ORDER BY (i1)')])
1338
            ->leftJoin(['p' => 'profile'], 'user.id = profile.user_id USE INDEX (i2)');
1339
1340
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1341
1342
        $expected = $this->replaceQuotes(
1343
            'SELECT * FROM {{user}} {{t}} FORCE INDEX (primary) IGNORE INDEX FOR ORDER BY (i1)'
1344
            . ' LEFT JOIN [[profile]] [[p]] ON user.id = profile.user_id USE INDEX (i2)'
1345
        );
1346
1347
        $this->assertEquals($expected, $sql);
1348
        $this->assertEmpty($params);
1349
    }
1350
1351
    public function testFromSubquery(): void
1352
    {
1353
        $db = $this->getConnection();
1354
1355
        /* query subquery */
1356
        $subquery = (new Query($db))->from('user')->where('account_id = accounts.id');
1357
1358
        $query = (new Query($db))->from(['activeusers' => $subquery]);
1359
1360
        /* SELECT * FROM (SELECT * FROM [[user]] WHERE [[active]] = 1) [[activeusers]]; */
1361
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1362
1363
        $expected = $this->replaceQuotes(
1364
            'SELECT * FROM (SELECT * FROM [[user]] WHERE account_id = accounts.id) [[activeusers]]'
1365
        );
1366
1367
        $this->assertEquals($expected, $sql);
1368
        $this->assertEmpty($params);
1369
1370
        /* query subquery with params */
1371
        $subquery = (new Query($db))->from('user')->where('account_id = :id', ['id' => 1]);
1372
1373
        $query = (new Query($db))->from(['activeusers' => $subquery])->where('abc = :abc', ['abc' => 'abc']);
1374
1375
        /* SELECT * FROM (SELECT * FROM [[user]] WHERE [[active]] = 1) [[activeusers]]; */
1376
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1377
1378
        $expected = $this->replaceQuotes(
1379
            'SELECT * FROM (SELECT * FROM [[user]] WHERE account_id = :id) [[activeusers]] WHERE abc = :abc'
1380
        );
1381
1382
        $this->assertEquals($expected, $sql);
1383
        $this->assertEquals(['id' => 1, 'abc' => 'abc'], $params);
1384
1385
        /* simple subquery */
1386
        $subquery = '(SELECT * FROM user WHERE account_id = accounts.id)';
1387
1388
        $query = (new Query($db))->from(['activeusers' => $subquery]);
1389
1390
        /* SELECT * FROM (SELECT * FROM [[user]] WHERE [[active]] = 1) [[activeusers]]; */
1391
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1392
1393
        $expected = $this->replaceQuotes(
1394
            'SELECT * FROM (SELECT * FROM user WHERE account_id = accounts.id) [[activeusers]]'
1395
        );
1396
1397
        $this->assertEquals($expected, $sql);
1398
        $this->assertEmpty($params);
1399
    }
1400
1401
    public function testOrderBy(): void
1402
    {
1403
        $db = $this->getConnection();
1404
1405
        /* simple string */
1406
        $query = (new Query($db))
1407
            ->select('*')
1408
            ->from('operations')
1409
            ->orderBy('name ASC, date DESC');
1410
1411
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1412
1413
        $expected = $this->replaceQuotes('SELECT * FROM [[operations]] ORDER BY [[name]], [[date]] DESC');
1414
1415
        $this->assertEquals($expected, $sql);
1416
        $this->assertEmpty($params);
1417
1418
        /* array syntax */
1419
        $query = (new Query($db))
1420
            ->select('*')
1421
            ->from('operations')
1422
            ->orderBy(['name' => SORT_ASC, 'date' => SORT_DESC]);
1423
1424
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1425
1426
        $expected = $this->replaceQuotes('SELECT * FROM [[operations]] ORDER BY [[name]], [[date]] DESC');
1427
1428
        $this->assertEquals($expected, $sql);
1429
        $this->assertEmpty($params);
1430
1431
        /* expression */
1432
        $query = (new Query($db))
1433
            ->select('*')
1434
            ->from('operations')
1435
            ->where('account_id = accounts.id')
1436
            ->orderBy(new Expression('SUBSTR(name, 3, 4) DESC, x ASC'));
1437
1438
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1439
1440
        $expected = $this->replaceQuotes(
1441
            'SELECT * FROM [[operations]] WHERE account_id = accounts.id ORDER BY SUBSTR(name, 3, 4) DESC, x ASC'
1442
        );
1443
1444
        $this->assertEquals($expected, $sql);
1445
        $this->assertEmpty($params);
1446
1447
        /* expression with params */
1448
        $query = (new Query($db))
1449
            ->select('*')
1450
            ->from('operations')
1451
            ->orderBy(new Expression('SUBSTR(name, 3, :to) DESC, x ASC', [':to' => 4]));
1452
1453
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1454
1455
        $expected = $this->replaceQuotes('SELECT * FROM [[operations]] ORDER BY SUBSTR(name, 3, :to) DESC, x ASC');
1456
1457
        $this->assertEquals($expected, $sql);
1458
        $this->assertEquals([':to' => 4], $params);
1459
    }
1460
1461
    public function testGroupBy(): void
1462
    {
1463
        $db = $this->getConnection();
1464
1465
        /* simple string */
1466
        $query = (new Query($db))
1467
            ->select('*')
1468
            ->from('operations')
1469
            ->groupBy('name, date');
1470
1471
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1472
1473
        $expected = $this->replaceQuotes('SELECT * FROM [[operations]] GROUP BY [[name]], [[date]]');
1474
1475
        $this->assertEquals($expected, $sql);
1476
        $this->assertEmpty($params);
1477
1478
        /* array syntax */
1479
        $query = (new Query($db))
1480
            ->select('*')
1481
            ->from('operations')
1482
            ->groupBy(['name', 'date']);
1483
1484
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1485
1486
        $expected = $this->replaceQuotes('SELECT * FROM [[operations]] GROUP BY [[name]], [[date]]');
1487
1488
        $this->assertEquals($expected, $sql);
1489
        $this->assertEmpty($params);
1490
1491
        /* expression */
1492
        $query = (new Query($db))
1493
            ->select('*')
1494
            ->from('operations')
1495
            ->where('account_id = accounts.id')
1496
            ->groupBy(new Expression('SUBSTR(name, 0, 1), x'));
1497
1498
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1499
1500
        $expected = $this->replaceQuotes(
1501
            'SELECT * FROM [[operations]] WHERE account_id = accounts.id GROUP BY SUBSTR(name, 0, 1), x'
1502
        );
1503
1504
        $this->assertEquals($expected, $sql);
1505
        $this->assertEmpty($params);
1506
1507
        /* expression with params */
1508
        $query = (new Query($db))
1509
            ->select('*')
1510
            ->from('operations')
1511
            ->groupBy(new Expression('SUBSTR(name, 0, :to), x', [':to' => 4]));
1512
1513
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1514
1515
        $expected = $this->replaceQuotes('SELECT * FROM [[operations]] GROUP BY SUBSTR(name, 0, :to), x');
1516
1517
        $this->assertEquals($expected, $sql);
1518
        $this->assertEquals([':to' => 4], $params);
1519
    }
1520
1521
    /**
1522
     * Dummy test to speed up QB's tests which rely on DB schema.
1523
     */
1524
    public function testInitFixtures(): void
1525
    {
1526
        $db = $this->getConnection();
1527
        $this->assertInstanceOf(QueryBuilder::class, $db->getQueryBuilder());
0 ignored issues
show
Bug introduced by
It seems like assertInstanceOf() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1527
        $this->/** @scrutinizer ignore-call */ 
1528
               assertInstanceOf(QueryBuilder::class, $db->getQueryBuilder());
Loading history...
1528
    }
1529
1530
    /**
1531
     * {@see https://github.com/yiisoft/yii2/issues/15653}
1532
     */
1533
    public function testIssue15653(): void
1534
    {
1535
        $db = $this->getConnection();
1536
1537
        $query = (new Query($db))
1538
            ->from('admin_user')
1539
            ->where(['is_deleted' => false]);
1540
1541
        $query
1542
            ->where([])
1543
            ->andWhere(['in', 'id', ['1', '0']]);
1544
1545
        [$sql, $params] = $db->getQueryBuilder()->build($query);
1546
1547
        $this->assertSame($this->replaceQuotes('SELECT * FROM [[admin_user]] WHERE [[id]] IN (:qp0, :qp1)'), $sql);
0 ignored issues
show
Bug introduced by
It seems like assertSame() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1547
        $this->/** @scrutinizer ignore-call */ 
1548
               assertSame($this->replaceQuotes('SELECT * FROM [[admin_user]] WHERE [[id]] IN (:qp0, :qp1)'), $sql);
Loading history...
1548
        $this->assertSame([':qp0' => '1', ':qp1' => '0'], $params);
1549
    }
1550
1551
    public function buildFromDataProviderTrait(): array
1552
    {
1553
        return [
1554
            ['test t1', '[[test]] [[t1]]'],
1555
            ['test as t1', '[[test]] [[t1]]'],
1556
            ['test AS t1', '[[test]] [[t1]]'],
1557
            ['test', '[[test]]'],
1558
        ];
1559
    }
1560
}
1561