Completed
Pull Request — develop (#3348)
by Sergei
65:02
created

testCannotGenerateTransactionCommandWithInvalidIsolationLevel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Platforms;
6
7
use Doctrine\DBAL\DBALException;
8
use Doctrine\DBAL\LockMode;
9
use Doctrine\DBAL\Platforms\AbstractPlatform;
10
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
11
use Doctrine\DBAL\Platforms\TrimMode;
12
use Doctrine\DBAL\Schema\Column;
13
use Doctrine\DBAL\Schema\ColumnDiff;
14
use Doctrine\DBAL\Schema\Comparator;
15
use Doctrine\DBAL\Schema\Constraint;
16
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
17
use Doctrine\DBAL\Schema\Index;
18
use Doctrine\DBAL\Schema\Sequence;
19
use Doctrine\DBAL\Schema\Table;
20
use Doctrine\DBAL\Schema\TableDiff;
21
use Doctrine\DBAL\Schema\UniqueConstraint;
22
use Doctrine\DBAL\TransactionIsolationLevel;
23
use Doctrine\DBAL\Types\Type;
24
use InvalidArgumentException;
25
use function mt_rand;
26
use function strlen;
27
use function substr;
28
29
class SQLAnywherePlatformTest extends AbstractPlatformTestCase
30
{
31
    /** @var SQLAnywherePlatform */
32
    protected $platform;
33
34
    public function createPlatform() : AbstractPlatform
35
    {
36
        return new SQLAnywherePlatform();
37
    }
38
39
    /**
40
     * {@inheritDoc}
41
     */
42
    public function getGenerateAlterTableSql() : array
43
    {
44
        return [
45
            "ALTER TABLE mytable ADD quota INT DEFAULT NULL, DROP foo, ALTER baz VARCHAR(1) DEFAULT 'def' NOT NULL, ALTER bloo BIT DEFAULT '0' NOT NULL",
46
            'ALTER TABLE mytable RENAME userlist',
47
        ];
48
    }
49
50
    public function getGenerateForeignKeySql() : string
51
    {
52
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
53
    }
54
55
    public function getGenerateIndexSql() : string
56
    {
57
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
58
    }
59
60
    public function getGenerateTableSql() : string
61
    {
62
        return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id))';
63
    }
64
65
    /**
66
     * {@inheritDoc}
67
     */
68
    public function getGenerateTableWithMultiColumnUniqueIndexSql() : array
69
    {
70
        return [
71
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
72
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
73
        ];
74
    }
75
76
    public function getGenerateUniqueIndexSql() : string
77
    {
78
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     */
84
    protected function getQuotedColumnInForeignKeySQL() : array
85
    {
86
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL, CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar"), CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar"), CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar"))'];
87
    }
88
89
    /**
90
     * {@inheritDoc}
91
     */
92
    protected function getQuotedColumnInIndexSQL() : array
93
    {
94
        return [
95
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
96
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
97
        ];
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103
    protected function getQuotedNameInIndexSQL() : array
104
    {
105
        return [
106
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
107
            'CREATE INDEX "key" ON test (column1)',
108
        ];
109
    }
110
111
    /**
112
     * {@inheritDoc}
113
     */
114
    protected function getQuotedColumnInPrimaryKeySQL() : array
115
    {
116
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY ("create"))'];
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122
    public function getCreateTableColumnCommentsSQL() : array
123
    {
124
        return [
125
            'CREATE TABLE test (id INT NOT NULL, PRIMARY KEY (id))',
126
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
127
        ];
128
    }
129
130
    /**
131
     * {@inheritDoc}
132
     */
133
    public function getAlterTableColumnCommentsSQL() : array
134
    {
135
        return [
136
            'ALTER TABLE mytable ADD quota INT NOT NULL',
137
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
138
            'COMMENT ON COLUMN mytable.foo IS NULL',
139
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
140
        ];
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146
    public function getCreateTableColumnTypeCommentsSQL() : array
147
    {
148
        return [
149
            'CREATE TABLE test (id INT NOT NULL, data TEXT NOT NULL, PRIMARY KEY (id))',
150
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'",
151
        ];
152
    }
153
154
    public function testHasCorrectPlatformName() : void
155
    {
156
        self::assertEquals('sqlanywhere', $this->platform->getName());
157
    }
158
159
    public function testGeneratesCreateTableSQLWithCommonIndexes() : void
160
    {
161
        $table = new Table('test');
162
        $table->addColumn('id', 'integer');
163
        $table->addColumn('name', 'string', ['length' => 50]);
164
        $table->setPrimaryKey(['id']);
165
        $table->addIndex(['name']);
166
        $table->addIndex(['id', 'name'], 'composite_idx');
167
168
        self::assertEquals(
169
            [
170
                'CREATE TABLE test (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id))',
171
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
172
                'CREATE INDEX composite_idx ON test (id, name)',
173
            ],
174
            $this->platform->getCreateTableSQL($table)
175
        );
176
    }
177
178
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints() : void
179
    {
180
        $table = new Table('test');
181
        $table->addColumn('id', 'integer');
182
        $table->addColumn('fk_1', 'integer');
183
        $table->addColumn('fk_2', 'integer');
184
        $table->setPrimaryKey(['id']);
185
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
186
        $table->addForeignKeyConstraint(
187
            'foreign_table2',
188
            ['fk_1', 'fk_2'],
189
            ['pk_1', 'pk_2'],
190
            [],
191
            'named_fk'
192
        );
193
194
        self::assertEquals(
195
            ['CREATE TABLE test (id INT NOT NULL, fk_1 INT NOT NULL, fk_2 INT NOT NULL, ' .
196
                'CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2), ' .
197
                'CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2))',
198
            ],
199
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
200
        );
201
    }
202
203
    public function testGeneratesCreateTableSQLWithCheckConstraints() : void
204
    {
205
        $table = new Table('test');
206
        $table->addColumn('id', 'integer');
207
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
208
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
209
        $table->setPrimaryKey(['id']);
210
211
        self::assertEquals(
212
            ['CREATE TABLE test (id INT NOT NULL, check_max INT NOT NULL, check_min INT NOT NULL, PRIMARY KEY (id), CHECK (check_max <= 10), CHECK (check_min >= 10))'],
213
            $this->platform->getCreateTableSQL($table)
214
        );
215
    }
216
217
    public function testGeneratesTableAlterationWithRemovedColumnCommentSql() : void
218
    {
219
        $table = new Table('mytable');
220
        $table->addColumn('foo', 'string', ['comment' => 'foo comment']);
221
222
        $tableDiff                        = new TableDiff('mytable');
223
        $tableDiff->fromTable             = $table;
224
        $tableDiff->changedColumns['foo'] = new ColumnDiff(
225
            'foo',
226
            new Column('foo', Type::getType('string')),
227
            ['comment']
228
        );
229
230
        self::assertEquals(
231
            ['COMMENT ON COLUMN mytable.foo IS NULL'],
232
            $this->platform->getAlterTableSQL($tableDiff)
233
        );
234
    }
235
236
    /**
237
     * @dataProvider getLockHints
238
     */
239
    public function testAppendsLockHint(?int $lockMode, string $lockHint) : void
240
    {
241
        $fromClause     = 'FROM users';
242
        $expectedResult = $fromClause . $lockHint;
243
244
        self::assertSame($expectedResult, $this->platform->appendLockHint($fromClause, $lockMode));
245
    }
246
247
    /**
248
     * @return mixed[][]
249
     */
250
    public static function getLockHints() : iterable
251
    {
252
        return [
253
            [null, ''],
254
            [LockMode::NONE, ' WITH (NOLOCK)'],
255
            [LockMode::OPTIMISTIC, ''],
256
            [LockMode::PESSIMISTIC_READ, ' WITH (UPDLOCK)'],
257
            [LockMode::PESSIMISTIC_WRITE, ' WITH (XLOCK)'],
258
        ];
259
    }
260
261
    public function testHasCorrectMaxIdentifierLength() : void
262
    {
263
        self::assertEquals(128, $this->platform->getMaxIdentifierLength());
264
    }
265
266
    public function testFixesSchemaElementNames() : void
267
    {
268
        $maxIdentifierLength = $this->platform->getMaxIdentifierLength();
269
        $characters          = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
270
        $schemaElementName   = '';
271
272
        for ($i = 0; $i < $maxIdentifierLength + 100; $i++) {
273
            $schemaElementName .= $characters[mt_rand(0, strlen($characters) - 1)];
274
        }
275
276
        $fixedSchemaElementName = substr($schemaElementName, 0, $maxIdentifierLength);
277
278
        self::assertEquals(
279
            $fixedSchemaElementName,
280
            $this->platform->fixSchemaElementName($schemaElementName)
281
        );
282
        self::assertEquals(
283
            $fixedSchemaElementName,
284
            $this->platform->fixSchemaElementName($fixedSchemaElementName)
285
        );
286
    }
287
288
    public function testGeneratesColumnTypesDeclarationSQL() : void
289
    {
290
        $fullColumnDef = [
291
            'length' => 10,
292
            'fixed' => true,
293
            'unsigned' => true,
294
            'autoincrement' => true,
295
        ];
296
297
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL([]));
298
        self::assertEquals('UNSIGNED SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL(['unsigned' => true]));
299
        self::assertEquals('UNSIGNED SMALLINT IDENTITY', $this->platform->getSmallIntTypeDeclarationSQL($fullColumnDef));
300
        self::assertEquals('INT', $this->platform->getIntegerTypeDeclarationSQL([]));
301
        self::assertEquals('UNSIGNED INT', $this->platform->getIntegerTypeDeclarationSQL(['unsigned' => true]));
302
        self::assertEquals('UNSIGNED INT IDENTITY', $this->platform->getIntegerTypeDeclarationSQL($fullColumnDef));
303
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL([]));
304
        self::assertEquals('UNSIGNED BIGINT', $this->platform->getBigIntTypeDeclarationSQL(['unsigned' => true]));
305
        self::assertEquals('UNSIGNED BIGINT IDENTITY', $this->platform->getBigIntTypeDeclarationSQL($fullColumnDef));
306
        self::assertEquals('LONG BINARY', $this->platform->getBlobTypeDeclarationSQL($fullColumnDef));
307
        self::assertEquals('BIT', $this->platform->getBooleanTypeDeclarationSQL($fullColumnDef));
308
        self::assertEquals('TEXT', $this->platform->getClobTypeDeclarationSQL($fullColumnDef));
309
        self::assertEquals('DATE', $this->platform->getDateTypeDeclarationSQL($fullColumnDef));
310
        self::assertEquals('DATETIME', $this->platform->getDateTimeTypeDeclarationSQL($fullColumnDef));
311
        self::assertEquals('TIME', $this->platform->getTimeTypeDeclarationSQL($fullColumnDef));
312
        self::assertEquals('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL($fullColumnDef));
313
314
        self::assertEquals(1, $this->platform->getVarcharDefaultLength());
315
        self::assertEquals(32767, $this->platform->getVarcharMaxLength());
316
    }
317
318
    public function testHasNativeGuidType() : void
319
    {
320
        self::assertTrue($this->platform->hasNativeGuidType());
321
    }
322
323
    public function testGeneratesDDLSnippets() : void
324
    {
325
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('foobar'));
326
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('"foobar"'));
327
        self::assertEquals("CREATE DATABASE 'create'", $this->platform->getCreateDatabaseSQL('create'));
328
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('foobar'));
329
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('"foobar"'));
330
        self::assertEquals("DROP DATABASE 'create'", $this->platform->getDropDatabaseSQL('create'));
331
        self::assertEquals('CREATE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
332
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('foobar'));
333
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('"foobar"'));
334
        self::assertEquals("START DATABASE 'create' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('create'));
335
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('foobar'));
336
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('"foobar"'));
337
        self::assertEquals('STOP DATABASE "create" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('create'));
338
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'));
339
340
        $viewSql = 'SELECT * FROM footable';
341
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
342
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
343
    }
344
345
    public function testGeneratesPrimaryKeyDeclarationSQL() : void
346
    {
347
        self::assertEquals(
348
            'CONSTRAINT pk PRIMARY KEY CLUSTERED (a, b)',
349
            $this->platform->getPrimaryKeyDeclarationSQL(
350
                new Index(null, ['a', 'b'], true, true, ['clustered']),
351
                'pk'
352
            )
353
        );
354
        self::assertEquals(
355
            'PRIMARY KEY (a, b)',
356
            $this->platform->getPrimaryKeyDeclarationSQL(
357
                new Index(null, ['a', 'b'], true, true)
358
            )
359
        );
360
    }
361
362
    public function testCannotGeneratePrimaryKeyDeclarationSQLWithEmptyColumns() : void
363
    {
364
        $this->expectException(InvalidArgumentException::class);
365
366
        $this->platform->getPrimaryKeyDeclarationSQL(new Index('pk', [], true, true));
367
    }
368
369
    public function testGeneratesCreateUnnamedPrimaryKeySQL() : void
370
    {
371
        self::assertEquals(
372
            'ALTER TABLE foo ADD PRIMARY KEY CLUSTERED (a, b)',
373
            $this->platform->getCreatePrimaryKeySQL(
374
                new Index('pk', ['a', 'b'], true, true, ['clustered']),
375
                'foo'
376
            )
377
        );
378
        self::assertEquals(
379
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
380
            $this->platform->getCreatePrimaryKeySQL(
381
                new Index('any_pk_name', ['a', 'b'], true, true),
382
                new Table('foo')
383
            )
384
        );
385
    }
386
387
    public function testGeneratesUniqueConstraintDeclarationSQL() : void
388
    {
389
        self::assertEquals(
390
            'CONSTRAINT unique_constraint UNIQUE CLUSTERED (a, b)',
391
            $this->platform->getUniqueConstraintDeclarationSQL(
392
                'unique_constraint',
393
                new UniqueConstraint(null, ['a', 'b'], ['clustered'])
394
            )
395
        );
396
        self::assertEquals(
397
            'CONSTRAINT UNIQUE (a, b)',
398
            $this->platform->getUniqueConstraintDeclarationSQL(null, new UniqueConstraint(null, ['a', 'b']))
399
        );
400
    }
401
402
    public function testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns() : void
403
    {
404
        $this->expectException(InvalidArgumentException::class);
405
406
        $this->platform->getUniqueConstraintDeclarationSQL('constr', new UniqueConstraint('constr', []));
407
    }
408
409
    public function testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL() : void
410
    {
411
        self::assertEquals(
412
            'CONSTRAINT fk ' .
413
                'NOT NULL FOREIGN KEY (a, b) ' .
414
                'REFERENCES foreign_table (c, d) ' .
415
                'MATCH UNIQUE SIMPLE ON UPDATE CASCADE ON DELETE SET NULL CHECK ON COMMIT CLUSTERED FOR OLAP WORKLOAD',
416
            $this->platform->getForeignKeyDeclarationSQL(
417
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'], 'fk', [
418
                    'notnull' => true,
419
                    'match' => SQLAnywherePlatform::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE,
420
                    'onUpdate' => 'CASCADE',
421
                    'onDelete' => 'SET NULL',
422
                    'check_on_commit' => true,
423
                    'clustered' => true,
424
                    'for_olap_workload' => true,
425
                ])
426
            )
427
        );
428
        self::assertEquals(
429
            'FOREIGN KEY (a, b) REFERENCES foreign_table (c, d)',
430
            $this->platform->getForeignKeyDeclarationSQL(
431
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'])
432
            )
433
        );
434
    }
435
436
    public function testGeneratesForeignKeyMatchClausesSQL() : void
437
    {
438
        self::assertEquals('SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(1));
439
        self::assertEquals('FULL', $this->platform->getForeignKeyMatchClauseSQL(2));
440
        self::assertEquals('UNIQUE SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(129));
441
        self::assertEquals('UNIQUE FULL', $this->platform->getForeignKeyMatchClauseSQL(130));
442
    }
443
444
    public function testCannotGenerateInvalidForeignKeyMatchClauseSQL() : void
445
    {
446
        $this->expectException(InvalidArgumentException::class);
447
448
        $this->platform->getForeignKeyMatchCLauseSQL(3);
449
    }
450
451
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyLocalColumns() : void
452
    {
453
        $this->expectException(InvalidArgumentException::class);
454
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint([], 'foreign_tbl', ['c', 'd']));
455
    }
456
457
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignColumns() : void
458
    {
459
        $this->expectException(InvalidArgumentException::class);
460
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], 'foreign_tbl', []));
461
    }
462
463
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignTableName() : void
464
    {
465
        $this->expectException(InvalidArgumentException::class);
466
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], '', ['c', 'd']));
467
    }
468
469
    public function testCannotGenerateCommonIndexWithCreateConstraintSQL() : void
470
    {
471
        $this->expectException(InvalidArgumentException::class);
472
473
        $this->platform->getCreateConstraintSQL(new Index('fooindex', []), new Table('footable'));
474
    }
475
476
    public function testCannotGenerateCustomConstraintWithCreateConstraintSQL() : void
477
    {
478
        $this->expectException(InvalidArgumentException::class);
479
480
        $this->platform->getCreateConstraintSQL($this->createMock(Constraint::class), 'footable');
481
    }
482
483
    public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() : void
484
    {
485
        self::assertEquals(
486
            'CREATE UNIQUE INDEX fooindex ON footable (a, b) WITH NULLS DISTINCT',
487
            $this->platform->getCreateIndexSQL(
488
                new Index(
489
                    'fooindex',
490
                    ['a', 'b'],
491
                    true,
492
                    false,
493
                    ['with_nulls_distinct']
494
                ),
495
                'footable'
496
            )
497
        );
498
499
        // WITH NULLS DISTINCT clause not available on primary indexes.
500
        self::assertEquals(
501
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
502
            $this->platform->getCreateIndexSQL(
503
                new Index(
504
                    'fooindex',
505
                    ['a', 'b'],
506
                    false,
507
                    true,
508
                    ['with_nulls_distinct']
509
                ),
510
                'footable'
511
            )
512
        );
513
514
        // WITH NULLS DISTINCT clause not available on non-unique indexes.
515
        self::assertEquals(
516
            'CREATE INDEX fooindex ON footable (a, b)',
517
            $this->platform->getCreateIndexSQL(
518
                new Index(
519
                    'fooindex',
520
                    ['a', 'b'],
521
                    false,
522
                    false,
523
                    ['with_nulls_distinct']
524
                ),
525
                'footable'
526
            )
527
        );
528
529
        self::assertEquals(
530
            'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
531
            $this->platform->getCreateIndexSQL(
532
                new Index(
533
                    'fooindex',
534
                    ['a', 'b'],
535
                    true,
536
                    false,
537
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
538
                ),
539
                'footable'
540
            )
541
        );
542
        self::assertEquals(
543
            'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
544
            $this->platform->getCreateIndexSQL(
545
                new Index(
546
                    'fooindex',
547
                    ['a', 'b'],
548
                    false,
549
                    false,
550
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
551
                ),
552
                'footable'
553
            )
554
        );
555
556
        // WITH NULLS NOT DISTINCT clause not available on primary indexes.
557
        self::assertEquals(
558
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
559
            $this->platform->getCreateIndexSQL(
560
                new Index(
561
                    'fooindex',
562
                    ['a', 'b'],
563
                    false,
564
                    true,
565
                    ['with_nulls_not_distinct']
566
                ),
567
                'footable'
568
            )
569
        );
570
571
        // WITH NULLS NOT DISTINCT clause not available on non-unique indexes.
572
        self::assertEquals(
573
            'CREATE INDEX fooindex ON footable (a, b)',
574
            $this->platform->getCreateIndexSQL(
575
                new Index(
576
                    'fooindex',
577
                    ['a', 'b'],
578
                    false,
579
                    false,
580
                    ['with_nulls_not_distinct']
581
                ),
582
                'footable'
583
            )
584
        );
585
    }
586
587
    public function testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions() : void
588
    {
589
        $this->expectException('UnexpectedValueException');
590
591
        $this->platform->getCreateIndexSQL(
592
            new Index(
593
                'fooindex',
594
                ['a', 'b'],
595
                false,
596
                false,
597
                ['with_nulls_distinct', 'with_nulls_not_distinct']
598
            ),
599
            'footable'
600
        );
601
    }
602
603
    public function testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() : void
604
    {
605
        $this->expectException(DBALException::class);
606
607
        $this->platform->getIndexDeclarationSQL('index', new Index('index', []));
608
    }
609
610
    public function testGeneratesDropIndexSQL() : void
611
    {
612
        $index = new Index('fooindex', []);
613
614
        self::assertEquals('DROP INDEX fooindex', $this->platform->getDropIndexSQL($index));
615
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL($index, 'footable'));
616
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL(
617
            $index,
618
            new Table('footable')
619
        ));
620
    }
621
622
    public function testCannotGenerateDropIndexSQLWithInvalidIndexParameter() : void
623
    {
624
        $this->expectException(InvalidArgumentException::class);
625
626
        $this->platform->getDropIndexSQL(['index'], 'table');
627
    }
628
629
    public function testCannotGenerateDropIndexSQLWithInvalidTableParameter() : void
630
    {
631
        $this->expectException(InvalidArgumentException::class);
632
633
        $this->platform->getDropIndexSQL('index', ['table']);
634
    }
635
636
    public function testGeneratesSQLSnippets() : void
637
    {
638
        self::assertEquals('STRING(column1, "string1", column2, "string2")', $this->platform->getConcatExpression(
639
            'column1',
640
            '"string1"',
641
            'column2',
642
            '"string2"'
643
        ));
644
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
645
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
646
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
647
        self::assertEquals("DATEADD(DAY, 4, '1987/05/02')", $this->platform->getDateAddDaysExpression("'1987/05/02'", '4'));
648
        self::assertEquals("DATEADD(HOUR, 12, '1987/05/02')", $this->platform->getDateAddHourExpression("'1987/05/02'", '12'));
649
        self::assertEquals("DATEADD(MINUTE, 2, '1987/05/02')", $this->platform->getDateAddMinutesExpression("'1987/05/02'", '2'));
650
        self::assertEquals("DATEADD(MONTH, 102, '1987/05/02')", $this->platform->getDateAddMonthExpression("'1987/05/02'", '102'));
651
        self::assertEquals("DATEADD(QUARTER, 5, '1987/05/02')", $this->platform->getDateAddQuartersExpression("'1987/05/02'", '5'));
652
        self::assertEquals("DATEADD(SECOND, 1, '1987/05/02')", $this->platform->getDateAddSecondsExpression("'1987/05/02'", '1'));
653
        self::assertEquals("DATEADD(WEEK, 3, '1987/05/02')", $this->platform->getDateAddWeeksExpression("'1987/05/02'", '3'));
654
        self::assertEquals("DATEADD(YEAR, 10, '1987/05/02')", $this->platform->getDateAddYearsExpression("'1987/05/02'", '10'));
655
        self::assertEquals("DATEDIFF(day, '1987/04/01', '1987/05/02')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
656
        self::assertEquals("DATEADD(DAY, -1 * 4, '1987/05/02')", $this->platform->getDateSubDaysExpression("'1987/05/02'", '4'));
657
        self::assertEquals("DATEADD(HOUR, -1 * 12, '1987/05/02')", $this->platform->getDateSubHourExpression("'1987/05/02'", '12'));
658
        self::assertEquals("DATEADD(MINUTE, -1 * 2, '1987/05/02')", $this->platform->getDateSubMinutesExpression("'1987/05/02'", '2'));
659
        self::assertEquals("DATEADD(MONTH, -1 * 102, '1987/05/02')", $this->platform->getDateSubMonthExpression("'1987/05/02'", '102'));
660
        self::assertEquals("DATEADD(QUARTER, -1 * 5, '1987/05/02')", $this->platform->getDateSubQuartersExpression("'1987/05/02'", '5'));
661
        self::assertEquals("DATEADD(SECOND, -1 * 1, '1987/05/02')", $this->platform->getDateSubSecondsExpression("'1987/05/02'", '1'));
662
        self::assertEquals("DATEADD(WEEK, -1 * 3, '1987/05/02')", $this->platform->getDateSubWeeksExpression("'1987/05/02'", '3'));
663
        self::assertEquals("DATEADD(YEAR, -1 * 10, '1987/05/02')", $this->platform->getDateSubYearsExpression("'1987/05/02'", '10'));
664
        self::assertEquals('Y-m-d H:i:s.u', $this->platform->getDateTimeFormatString());
665
        self::assertEquals('H:i:s.u', $this->platform->getTimeFormatString());
666
        self::assertEquals('', $this->platform->getForUpdateSQL());
667
        self::assertEquals('LOCATE(string_column, substring_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
668
        self::assertEquals('LOCATE(string_column, substring_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', '1'));
669
        self::assertEquals("HASH(column, 'MD5')", $this->platform->getMd5Expression('column'));
670
        self::assertEquals('SUBSTRING(column, 5)', $this->platform->getSubstringExpression('column', '5'));
671
        self::assertEquals('SUBSTRING(column, 5, 2)', $this->platform->getSubstringExpression('column', '5', '2'));
672
        self::assertEquals('GLOBAL TEMPORARY', $this->platform->getTemporaryTableSQL());
673
        self::assertEquals(
674
            'LTRIM(column)',
675
            $this->platform->getTrimExpression('column', TrimMode::LEADING)
676
        );
677
        self::assertEquals(
678
            'RTRIM(column)',
679
            $this->platform->getTrimExpression('column', TrimMode::TRAILING)
680
        );
681
        self::assertEquals(
682
            'TRIM(column)',
683
            $this->platform->getTrimExpression('column')
684
        );
685
        self::assertEquals(
686
            'TRIM(column)',
687
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED)
688
        );
689
        self::assertEquals(
690
            "SUBSTR(column, PATINDEX('%[^' + c + ']%', column))",
691
            $this->platform->getTrimExpression('column', TrimMode::LEADING, 'c')
692
        );
693
        self::assertEquals(
694
            "REVERSE(SUBSTR(REVERSE(column), PATINDEX('%[^' + c + ']%', REVERSE(column))))",
695
            $this->platform->getTrimExpression('column', TrimMode::TRAILING, 'c')
696
        );
697
        self::assertEquals(
698
            "REVERSE(SUBSTR(REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))), PATINDEX('%[^' + c + ']%', " .
699
            "REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))))))",
700
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED, 'c')
701
        );
702
    }
703
704
    public function testHasCorrectDateTimeTzFormatString() : void
705
    {
706
        self::assertEquals('Y-m-d H:i:s.uP', $this->platform->getDateTimeTzFormatString());
707
    }
708
709
    public function testGeneratesDateTimeTzColumnTypeDeclarationSQL() : void
710
    {
711
        self::assertEquals(
712
            'TIMESTAMP WITH TIME ZONE',
713
            $this->platform->getDateTimeTzTypeDeclarationSQL([
714
                'length' => 10,
715
                'fixed' => true,
716
                'unsigned' => true,
717
                'autoincrement' => true,
718
            ])
719
        );
720
    }
721
722
    public function testInitializesDateTimeTzTypeMapping() : void
723
    {
724
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
725
        self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
726
    }
727
728
    public function testHasCorrectDefaultTransactionIsolationLevel() : void
729
    {
730
        self::assertEquals(
731
            TransactionIsolationLevel::READ_UNCOMMITTED,
732
            $this->platform->getDefaultTransactionIsolationLevel()
733
        );
734
    }
735
736
    public function testGeneratesTransactionsCommands() : void
737
    {
738
        self::assertEquals(
739
            'SET TEMPORARY OPTION isolation_level = 0',
740
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
741
        );
742
        self::assertEquals(
743
            'SET TEMPORARY OPTION isolation_level = 1',
744
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
745
        );
746
        self::assertEquals(
747
            'SET TEMPORARY OPTION isolation_level = 2',
748
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
749
        );
750
        self::assertEquals(
751
            'SET TEMPORARY OPTION isolation_level = 3',
752
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
753
        );
754
    }
755
756
    public function testModifiesLimitQuery() : void
757
    {
758
        self::assertEquals(
759
            'SELECT TOP 10 * FROM user',
760
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
761
        );
762
    }
763
764
    public function testModifiesLimitQueryWithEmptyOffset() : void
765
    {
766
        self::assertEquals(
767
            'SELECT TOP 10 * FROM user',
768
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
769
        );
770
    }
771
772
    public function testModifiesLimitQueryWithOffset() : void
773
    {
774
        self::assertEquals(
775
            'SELECT TOP 10 START AT 6 * FROM user',
776
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
777
        );
778
        self::assertEquals(
779
            'SELECT TOP 0 START AT 6 * FROM user',
780
            $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
781
        );
782
    }
783
784
    public function testModifiesLimitQueryWithSubSelect() : void
785
    {
786
        self::assertEquals(
787
            'SELECT TOP 10 * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl',
788
            $this->platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl', 10)
789
        );
790
    }
791
792
    public function testModifiesLimitQueryWithoutLimit() : void
793
    {
794
        self::assertEquals(
795
            'SELECT TOP ALL START AT 11 n FROM Foo',
796
            $this->platform->modifyLimitQuery('SELECT n FROM Foo', null, 10)
797
        );
798
    }
799
800
    public function testPrefersIdentityColumns() : void
801
    {
802
        self::assertTrue($this->platform->prefersIdentityColumns());
803
    }
804
805
    public function testDoesNotPreferSequences() : void
806
    {
807
        self::assertFalse($this->platform->prefersSequences());
808
    }
809
810
    public function testSupportsIdentityColumns() : void
811
    {
812
        self::assertTrue($this->platform->supportsIdentityColumns());
813
    }
814
815
    public function testSupportsPrimaryConstraints() : void
816
    {
817
        self::assertTrue($this->platform->supportsPrimaryConstraints());
818
    }
819
820
    public function testSupportsForeignKeyConstraints() : void
821
    {
822
        self::assertTrue($this->platform->supportsForeignKeyConstraints());
823
    }
824
825
    public function testSupportsForeignKeyOnUpdate() : void
826
    {
827
        self::assertTrue($this->platform->supportsForeignKeyOnUpdate());
828
    }
829
830
    public function testSupportsAlterTable() : void
831
    {
832
        self::assertTrue($this->platform->supportsAlterTable());
833
    }
834
835
    public function testSupportsTransactions() : void
836
    {
837
        self::assertTrue($this->platform->supportsTransactions());
838
    }
839
840
    public function testSupportsSchemas() : void
841
    {
842
        self::assertFalse($this->platform->supportsSchemas());
843
    }
844
845
    public function testSupportsIndexes() : void
846
    {
847
        self::assertTrue($this->platform->supportsIndexes());
848
    }
849
850
    public function testSupportsCommentOnStatement() : void
851
    {
852
        self::assertTrue($this->platform->supportsCommentOnStatement());
853
    }
854
855
    public function testSupportsSavePoints() : void
856
    {
857
        self::assertTrue($this->platform->supportsSavepoints());
858
    }
859
860
    public function testSupportsReleasePoints() : void
861
    {
862
        self::assertTrue($this->platform->supportsReleaseSavepoints());
863
    }
864
865
    public function testSupportsCreateDropDatabase() : void
866
    {
867
        self::assertTrue($this->platform->supportsCreateDropDatabase());
868
    }
869
870
    public function testSupportsGettingAffectedRows() : void
871
    {
872
        self::assertTrue($this->platform->supportsGettingAffectedRows());
873
    }
874
875
    public function testDoesNotSupportSequences() : void
876
    {
877
        self::markTestSkipped('This version of the platform now supports sequences.');
878
    }
879
880
    public function testSupportsSequences() : void
881
    {
882
        self::assertTrue($this->platform->supportsSequences());
883
    }
884
885
    public function testGeneratesSequenceSqlCommands() : void
886
    {
887
        $sequence = new Sequence('myseq', 20, 1);
888
        self::assertEquals(
889
            'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
890
            $this->platform->getCreateSequenceSQL($sequence)
891
        );
892
        self::assertEquals(
893
            'ALTER SEQUENCE myseq INCREMENT BY 20',
894
            $this->platform->getAlterSequenceSQL($sequence)
895
        );
896
        self::assertEquals(
897
            'DROP SEQUENCE myseq',
898
            $this->platform->getDropSequenceSQL('myseq')
899
        );
900
        self::assertEquals(
901
            'DROP SEQUENCE myseq',
902
            $this->platform->getDropSequenceSQL($sequence)
903
        );
904
        self::assertEquals(
905
            'SELECT myseq.NEXTVAL',
906
            $this->platform->getSequenceNextValSQL('myseq')
907
        );
908
        self::assertEquals(
909
            'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE',
910
            $this->platform->getListSequencesSQL(null)
911
        );
912
    }
913
914
    public function testDoesNotSupportInlineColumnComments() : void
915
    {
916
        self::assertFalse($this->platform->supportsInlineColumnComments());
917
    }
918
919
    public function testCannotEmulateSchemas() : void
920
    {
921
        self::assertFalse($this->platform->canEmulateSchemas());
922
    }
923
924
    public function testInitializesDoctrineTypeMappings() : void
925
    {
926
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
927
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
928
929
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('binary'));
930
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('binary'));
931
932
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varbinary'));
933
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('varbinary'));
934
    }
935
936
    protected function getBinaryDefaultLength() : int
937
    {
938
        return 1;
939
    }
940
941
    protected function getBinaryMaxLength() : int
942
    {
943
        return 32767;
944
    }
945
946
    public function testReturnsBinaryTypeDeclarationSQL() : void
947
    {
948
        self::assertSame('VARBINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([]));
949
        self::assertSame('VARBINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
950
        self::assertSame('VARBINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32767]));
951
952
        self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
953
        self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([
954
            'fixed' => true,
955
            'length' => 0,
956
        ]));
957
        self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL([
958
            'fixed' => true,
959
            'length' => 32767,
960
        ]));
961
    }
962
963
    /**
964
     * {@inheritDoc}
965
     *
966
     * @group DBAL-234
967
     */
968
    protected function getAlterTableRenameIndexSQL() : array
969
    {
970
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_bar'];
971
    }
972
973
    /**
974
     * {@inheritDoc}
975
     *
976
     * @group DBAL-234
977
     */
978
    protected function getQuotedAlterTableRenameIndexSQL() : array
979
    {
980
        return [
981
            'ALTER INDEX "create" ON "table" RENAME TO "select"',
982
            'ALTER INDEX "foo" ON "table" RENAME TO "bar"',
983
        ];
984
    }
985
986
    /**
987
     * {@inheritdoc}
988
     */
989
    protected function getQuotedAlterTableRenameColumnSQL() : array
990
    {
991
        return [
992
            'ALTER TABLE mytable RENAME unquoted1 TO unquoted',
993
            'ALTER TABLE mytable RENAME unquoted2 TO "where"',
994
            'ALTER TABLE mytable RENAME unquoted3 TO "foo"',
995
            'ALTER TABLE mytable RENAME "create" TO reserved_keyword',
996
            'ALTER TABLE mytable RENAME "table" TO "from"',
997
            'ALTER TABLE mytable RENAME "select" TO "bar"',
998
            'ALTER TABLE mytable RENAME quoted1 TO quoted',
999
            'ALTER TABLE mytable RENAME quoted2 TO "and"',
1000
            'ALTER TABLE mytable RENAME quoted3 TO "baz"',
1001
        ];
1002
    }
1003
1004
    /**
1005
     * {@inheritdoc}
1006
     */
1007
    protected function getQuotedAlterTableChangeColumnLengthSQL() : array
1008
    {
1009
        $this->markTestIncomplete('Not implemented yet');
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
1010
    }
1011
1012
    /**
1013
     * {@inheritDoc}
1014
     *
1015
     * @group DBAL-807
1016
     */
1017
    protected function getAlterTableRenameIndexInSchemaSQL() : array
1018
    {
1019
        return ['ALTER INDEX idx_foo ON myschema.mytable RENAME TO idx_bar'];
1020
    }
1021
1022
    /**
1023
     * {@inheritDoc}
1024
     *
1025
     * @group DBAL-807
1026
     */
1027
    protected function getQuotedAlterTableRenameIndexInSchemaSQL() : array
1028
    {
1029
        return [
1030
            'ALTER INDEX "create" ON "schema"."table" RENAME TO "select"',
1031
            'ALTER INDEX "foo" ON "schema"."table" RENAME TO "bar"',
1032
        ];
1033
    }
1034
1035
    /**
1036
     * @group DBAL-423
1037
     */
1038
    public function testReturnsGuidTypeDeclarationSQL() : void
1039
    {
1040
        self::assertSame('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL([]));
1041
    }
1042
1043
    /**
1044
     * {@inheritdoc}
1045
     */
1046
    public function getAlterTableRenameColumnSQL() : array
1047
    {
1048
        return ['ALTER TABLE foo RENAME bar TO baz'];
1049
    }
1050
1051
    /**
1052
     * {@inheritdoc}
1053
     */
1054
    protected function getQuotesTableIdentifiersInAlterTableSQL() : array
1055
    {
1056
        return [
1057
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
1058
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
1059
            'ALTER TABLE "foo" RENAME id TO war',
1060
            'ALTER TABLE "foo" ADD bloo INT NOT NULL, DROP baz, ALTER bar INT DEFAULT NULL',
1061
            'ALTER TABLE "foo" RENAME "table"',
1062
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
1063
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
1064
        ];
1065
    }
1066
1067
    /**
1068
     * {@inheritdoc}
1069
     */
1070
    protected function getCommentOnColumnSQL() : array
1071
    {
1072
        return [
1073
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
1074
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
1075
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
1076
        ];
1077
    }
1078
1079
    /**
1080
     * @group DBAL-1004
1081
     */
1082
    public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers() : void
1083
    {
1084
        $table1 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'))]);
1085
        $table2 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'), ['comment' => 'baz'])]);
1086
1087
        $comparator = new Comparator();
1088
1089
        $tableDiff = $comparator->diffTable($table1, $table2);
1090
1091
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1092
        self::assertSame(
1093
            ['COMMENT ON COLUMN "foo"."bar" IS \'baz\''],
1094
            $this->platform->getAlterTableSQL($tableDiff)
0 ignored issues
show
Bug introduced by
It seems like $tableDiff can also be of type false; however, parameter $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

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

1094
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $tableDiff)
Loading history...
1095
        );
1096
    }
1097
1098
    /**
1099
     * {@inheritdoc}
1100
     */
1101
    public static function getReturnsForeignKeyReferentialActionSQL() : iterable
1102
    {
1103
        return [
1104
            ['CASCADE', 'CASCADE'],
1105
            ['SET NULL', 'SET NULL'],
1106
            ['NO ACTION', 'RESTRICT'],
1107
            ['RESTRICT', 'RESTRICT'],
1108
            ['SET DEFAULT', 'SET DEFAULT'],
1109
            ['CaScAdE', 'CASCADE'],
1110
        ];
1111
    }
1112
1113
    /**
1114
     * {@inheritdoc}
1115
     */
1116
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() : string
1117
    {
1118
        return 'CONSTRAINT "select" UNIQUE (foo)';
1119
    }
1120
1121
    /**
1122
     * {@inheritdoc}
1123
     */
1124
    protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string
1125
    {
1126
        return ''; // not supported by this platform
1127
    }
1128
1129
    /**
1130
     * {@inheritdoc}
1131
     */
1132
    protected function getQuotesReservedKeywordInTruncateTableSQL() : string
1133
    {
1134
        return 'TRUNCATE TABLE "select"';
1135
    }
1136
1137
    /**
1138
     * {@inheritdoc}
1139
     */
1140
    protected function supportsInlineIndexDeclaration() : bool
1141
    {
1142
        return false;
1143
    }
1144
1145
    /**
1146
     * {@inheritdoc}
1147
     */
1148
    protected function getAlterStringToFixedStringSQL() : array
1149
    {
1150
        return ['ALTER TABLE mytable ALTER name CHAR(2) NOT NULL'];
1151
    }
1152
1153
    /**
1154
     * {@inheritdoc}
1155
     */
1156
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array
1157
    {
1158
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_foo_renamed'];
1159
    }
1160
1161
    /**
1162
     * @group DBAL-2436
1163
     */
1164
    public function testQuotesSchemaNameInListTableColumnsSQL() : void
1165
    {
1166
        self::assertStringContainsStringIgnoringCase(
1167
            "'Foo''Bar\\'",
1168
            $this->platform->getListTableColumnsSQL("Foo'Bar\\.baz_table")
1169
        );
1170
    }
1171
1172
    /**
1173
     * @group DBAL-2436
1174
     */
1175
    public function testQuotesTableNameInListTableConstraintsSQL() : void
1176
    {
1177
        self::assertStringContainsStringIgnoringCase("'Foo''Bar\\'", $this->platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true);
0 ignored issues
show
Unused Code introduced by
The call to PHPUnit\Framework\Assert...insStringIgnoringCase() has too many arguments starting with true. ( Ignorable by Annotation )

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

1177
        self::/** @scrutinizer ignore-call */ 
1178
              assertStringContainsStringIgnoringCase("'Foo''Bar\\'", $this->platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1178
    }
1179
1180
    /**
1181
     * @group DBAL-2436
1182
     */
1183
    public function testQuotesSchemaNameInListTableConstraintsSQL() : void
1184
    {
1185
        self::assertStringContainsStringIgnoringCase(
1186
            "'Foo''Bar\\'",
1187
            $this->platform->getListTableConstraintsSQL("Foo'Bar\\.baz_table")
1188
        );
1189
    }
1190
1191
    /**
1192
     * @group DBAL-2436
1193
     */
1194
    public function testQuotesTableNameInListTableForeignKeysSQL() : void
1195
    {
1196
        self::assertStringContainsStringIgnoringCase(
1197
            "'Foo''Bar\\'",
1198
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\")
1199
        );
1200
    }
1201
1202
    /**
1203
     * @group DBAL-2436
1204
     */
1205
    public function testQuotesSchemaNameInListTableForeignKeysSQL() : void
1206
    {
1207
        self::assertStringContainsStringIgnoringCase(
1208
            "'Foo''Bar\\'",
1209
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table")
1210
        );
1211
    }
1212
1213
    /**
1214
     * @group DBAL-2436
1215
     */
1216
    public function testQuotesTableNameInListTableIndexesSQL() : void
1217
    {
1218
        self::assertStringContainsStringIgnoringCase(
1219
            "'Foo''Bar\\'",
1220
            $this->platform->getListTableIndexesSQL("Foo'Bar\\")
1221
        );
1222
    }
1223
1224
    /**
1225
     * @group DBAL-2436
1226
     */
1227
    public function testQuotesSchemaNameInListTableIndexesSQL() : void
1228
    {
1229
        self::assertStringContainsStringIgnoringCase(
1230
            "'Foo''Bar\\'",
1231
            $this->platform->getListTableIndexesSQL("Foo'Bar\\.baz_table")
1232
        );
1233
    }
1234
}
1235