Failed Conditions
Pull Request — develop (#3348)
by Sergei
62:13
created

SQLAnywherePlatformTest::testSupportsIndexes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Platforms;
4
5
use Doctrine\DBAL\DBALException;
6
use Doctrine\DBAL\LockMode;
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
9
use Doctrine\DBAL\Platforms\TrimMode;
10
use Doctrine\DBAL\Schema\Column;
11
use Doctrine\DBAL\Schema\ColumnDiff;
12
use Doctrine\DBAL\Schema\Comparator;
13
use Doctrine\DBAL\Schema\Constraint;
14
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
15
use Doctrine\DBAL\Schema\Index;
16
use Doctrine\DBAL\Schema\Sequence;
17
use Doctrine\DBAL\Schema\Table;
18
use Doctrine\DBAL\Schema\TableDiff;
19
use Doctrine\DBAL\Schema\UniqueConstraint;
20
use Doctrine\DBAL\TransactionIsolationLevel;
21
use Doctrine\DBAL\Types\Type;
22
use InvalidArgumentException;
23
use function mt_rand;
24
use function strlen;
25
use function substr;
26
27
class SQLAnywherePlatformTest extends AbstractPlatformTestCase
28
{
29
    /** @var SQLAnywherePlatform */
30
    protected $platform;
31
32
    public function createPlatform() : AbstractPlatform
33
    {
34
        return new SQLAnywherePlatform();
35
    }
36
37
    /**
38
     * {@inheritDoc}
39
     */
40
    public function getGenerateAlterTableSql() : array
41
    {
42
        return [
43
            "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",
44
            'ALTER TABLE mytable RENAME userlist',
45
        ];
46
    }
47
48
    public function getGenerateForeignKeySql() : string
49
    {
50
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
51
    }
52
53
    public function getGenerateIndexSql() : string
54
    {
55
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
56
    }
57
58
    public function getGenerateTableSql() : string
59
    {
60
        return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id))';
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    public function getGenerateTableWithMultiColumnUniqueIndexSql() : array
67
    {
68
        return [
69
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
70
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
71
        ];
72
    }
73
74
    public function getGenerateUniqueIndexSql() : string
75
    {
76
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82
    protected function getQuotedColumnInForeignKeySQL() : array
83
    {
84
        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"))'];
85
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90
    protected function getQuotedColumnInIndexSQL() : array
91
    {
92
        return [
93
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
94
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
95
        ];
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     */
101
    protected function getQuotedNameInIndexSQL() : array
102
    {
103
        return [
104
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
105
            'CREATE INDEX "key" ON test (column1)',
106
        ];
107
    }
108
109
    /**
110
     * {@inheritDoc}
111
     */
112
    protected function getQuotedColumnInPrimaryKeySQL() : array
113
    {
114
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY ("create"))'];
115
    }
116
117
    /**
118
     * {@inheritDoc}
119
     */
120
    public function getCreateTableColumnCommentsSQL() : array
121
    {
122
        return [
123
            'CREATE TABLE test (id INT NOT NULL, PRIMARY KEY (id))',
124
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
125
        ];
126
    }
127
128
    /**
129
     * {@inheritDoc}
130
     */
131
    public function getAlterTableColumnCommentsSQL() : array
132
    {
133
        return [
134
            'ALTER TABLE mytable ADD quota INT NOT NULL',
135
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
136
            "COMMENT ON COLUMN mytable.foo IS ''",
137
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
138
        ];
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144
    public function getCreateTableColumnTypeCommentsSQL() : array
145
    {
146
        return [
147
            'CREATE TABLE test (id INT NOT NULL, data TEXT NOT NULL, PRIMARY KEY (id))',
148
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'",
149
        ];
150
    }
151
152
    public function testHasCorrectPlatformName() : void
153
    {
154
        self::assertEquals('sqlanywhere', $this->platform->getName());
155
    }
156
157
    public function testGeneratesCreateTableSQLWithCommonIndexes() : void
158
    {
159
        $table = new Table('test');
160
        $table->addColumn('id', 'integer');
161
        $table->addColumn('name', 'string', ['length' => 50]);
162
        $table->setPrimaryKey(['id']);
163
        $table->addIndex(['name']);
164
        $table->addIndex(['id', 'name'], 'composite_idx');
165
166
        self::assertEquals(
167
            [
168
                'CREATE TABLE test (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id))',
169
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
170
                'CREATE INDEX composite_idx ON test (id, name)',
171
            ],
172
            $this->platform->getCreateTableSQL($table)
173
        );
174
    }
175
176
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints() : void
177
    {
178
        $table = new Table('test');
179
        $table->addColumn('id', 'integer');
180
        $table->addColumn('fk_1', 'integer');
181
        $table->addColumn('fk_2', 'integer');
182
        $table->setPrimaryKey(['id']);
183
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
184
        $table->addForeignKeyConstraint(
185
            'foreign_table2',
186
            ['fk_1', 'fk_2'],
187
            ['pk_1', 'pk_2'],
188
            [],
189
            'named_fk'
190
        );
191
192
        self::assertEquals(
193
            ['CREATE TABLE test (id INT NOT NULL, fk_1 INT NOT NULL, fk_2 INT NOT NULL, ' .
194
                'CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2), ' .
195
                'CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2))',
196
            ],
197
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
198
        );
199
    }
200
201
    public function testGeneratesCreateTableSQLWithCheckConstraints() : void
202
    {
203
        $table = new Table('test');
204
        $table->addColumn('id', 'integer');
205
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
206
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
207
        $table->setPrimaryKey(['id']);
208
209
        self::assertEquals(
210
            ['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))'],
211
            $this->platform->getCreateTableSQL($table)
212
        );
213
    }
214
215
    public function testGeneratesTableAlterationWithRemovedColumnCommentSql() : void
216
    {
217
        $table = new Table('mytable');
218
        $table->addColumn('foo', 'string', ['comment' => 'foo comment']);
219
220
        $tableDiff                        = new TableDiff('mytable');
221
        $tableDiff->fromTable             = $table;
222
        $tableDiff->changedColumns['foo'] = new ColumnDiff(
223
            'foo',
224
            new Column('foo', Type::getType('string')),
225
            ['comment']
226
        );
227
228
        self::assertEquals(
229
            ["COMMENT ON COLUMN mytable.foo IS ''"],
230
            $this->platform->getAlterTableSQL($tableDiff)
231
        );
232
    }
233
234
    /**
235
     * @dataProvider getLockHints
236
     */
237
    public function testAppendsLockHint(?int $lockMode, string $lockHint) : void
238
    {
239
        $fromClause     = 'FROM users';
240
        $expectedResult = $fromClause . $lockHint;
241
242
        self::assertSame($expectedResult, $this->platform->appendLockHint($fromClause, $lockMode));
243
    }
244
245
    /**
246
     * @return mixed[][]
247
     */
248
    public static function getLockHints() : iterable
249
    {
250
        return [
251
            [null, ''],
252
            [LockMode::NONE, ' WITH (NOLOCK)'],
253
            [LockMode::OPTIMISTIC, ''],
254
            [LockMode::PESSIMISTIC_READ, ' WITH (UPDLOCK)'],
255
            [LockMode::PESSIMISTIC_WRITE, ' WITH (XLOCK)'],
256
        ];
257
    }
258
259
    public function testHasCorrectMaxIdentifierLength() : void
260
    {
261
        self::assertEquals(128, $this->platform->getMaxIdentifierLength());
262
    }
263
264
    public function testFixesSchemaElementNames() : void
265
    {
266
        $maxIdentifierLength = $this->platform->getMaxIdentifierLength();
267
        $characters          = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
268
        $schemaElementName   = '';
269
270
        for ($i = 0; $i < $maxIdentifierLength + 100; $i++) {
271
            $schemaElementName .= $characters[mt_rand(0, strlen($characters) - 1)];
272
        }
273
274
        $fixedSchemaElementName = substr($schemaElementName, 0, $maxIdentifierLength);
275
276
        self::assertEquals(
277
            $fixedSchemaElementName,
278
            $this->platform->fixSchemaElementName($schemaElementName)
279
        );
280
        self::assertEquals(
281
            $fixedSchemaElementName,
282
            $this->platform->fixSchemaElementName($fixedSchemaElementName)
283
        );
284
    }
285
286
    public function testGeneratesColumnTypesDeclarationSQL() : void
287
    {
288
        $fullColumnDef = [
289
            'length' => 10,
290
            'fixed' => true,
291
            'unsigned' => true,
292
            'autoincrement' => true,
293
        ];
294
295
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL([]));
296
        self::assertEquals('UNSIGNED SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL(['unsigned' => true]));
297
        self::assertEquals('UNSIGNED SMALLINT IDENTITY', $this->platform->getSmallIntTypeDeclarationSQL($fullColumnDef));
298
        self::assertEquals('INT', $this->platform->getIntegerTypeDeclarationSQL([]));
299
        self::assertEquals('UNSIGNED INT', $this->platform->getIntegerTypeDeclarationSQL(['unsigned' => true]));
300
        self::assertEquals('UNSIGNED INT IDENTITY', $this->platform->getIntegerTypeDeclarationSQL($fullColumnDef));
301
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL([]));
302
        self::assertEquals('UNSIGNED BIGINT', $this->platform->getBigIntTypeDeclarationSQL(['unsigned' => true]));
303
        self::assertEquals('UNSIGNED BIGINT IDENTITY', $this->platform->getBigIntTypeDeclarationSQL($fullColumnDef));
304
        self::assertEquals('LONG BINARY', $this->platform->getBlobTypeDeclarationSQL($fullColumnDef));
305
        self::assertEquals('BIT', $this->platform->getBooleanTypeDeclarationSQL($fullColumnDef));
306
        self::assertEquals('TEXT', $this->platform->getClobTypeDeclarationSQL($fullColumnDef));
307
        self::assertEquals('DATE', $this->platform->getDateTypeDeclarationSQL($fullColumnDef));
308
        self::assertEquals('DATETIME', $this->platform->getDateTimeTypeDeclarationSQL($fullColumnDef));
309
        self::assertEquals('TIME', $this->platform->getTimeTypeDeclarationSQL($fullColumnDef));
310
        self::assertEquals('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL($fullColumnDef));
311
312
        self::assertEquals(1, $this->platform->getVarcharDefaultLength());
313
        self::assertEquals(32767, $this->platform->getVarcharMaxLength());
314
    }
315
316
    public function testHasNativeGuidType() : void
317
    {
318
        self::assertTrue($this->platform->hasNativeGuidType());
319
    }
320
321
    public function testGeneratesDDLSnippets() : void
322
    {
323
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('foobar'));
324
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('"foobar"'));
325
        self::assertEquals("CREATE DATABASE 'create'", $this->platform->getCreateDatabaseSQL('create'));
326
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('foobar'));
327
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('"foobar"'));
328
        self::assertEquals("DROP DATABASE 'create'", $this->platform->getDropDatabaseSQL('create'));
329
        self::assertEquals('CREATE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
330
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('foobar'));
331
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('"foobar"'));
332
        self::assertEquals("START DATABASE 'create' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('create'));
333
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('foobar'));
334
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('"foobar"'));
335
        self::assertEquals('STOP DATABASE "create" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('create'));
336
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'));
337
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'), true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $message of PHPUnit\Framework\Assert::assertEquals(). ( Ignorable by Annotation )

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

337
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'), /** @scrutinizer ignore-type */ true);
Loading history...
338
339
        $viewSql = 'SELECT * FROM footable';
340
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
341
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
342
    }
343
344
    public function testGeneratesPrimaryKeyDeclarationSQL() : void
345
    {
346
        self::assertEquals(
347
            'CONSTRAINT pk PRIMARY KEY CLUSTERED (a, b)',
348
            $this->platform->getPrimaryKeyDeclarationSQL(
349
                new Index(null, ['a', 'b'], true, true, ['clustered']),
350
                'pk'
351
            )
352
        );
353
        self::assertEquals(
354
            'PRIMARY KEY (a, b)',
355
            $this->platform->getPrimaryKeyDeclarationSQL(
356
                new Index(null, ['a', 'b'], true, true)
357
            )
358
        );
359
    }
360
361
    public function testCannotGeneratePrimaryKeyDeclarationSQLWithEmptyColumns() : void
362
    {
363
        $this->expectException(InvalidArgumentException::class);
364
365
        $this->platform->getPrimaryKeyDeclarationSQL(new Index('pk', [], true, true));
366
    }
367
368
    public function testGeneratesCreateUnnamedPrimaryKeySQL() : void
369
    {
370
        self::assertEquals(
371
            'ALTER TABLE foo ADD PRIMARY KEY CLUSTERED (a, b)',
372
            $this->platform->getCreatePrimaryKeySQL(
373
                new Index('pk', ['a', 'b'], true, true, ['clustered']),
374
                'foo'
375
            )
376
        );
377
        self::assertEquals(
378
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
379
            $this->platform->getCreatePrimaryKeySQL(
380
                new Index('any_pk_name', ['a', 'b'], true, true),
381
                new Table('foo')
382
            )
383
        );
384
    }
385
386
    public function testGeneratesUniqueConstraintDeclarationSQL() : void
387
    {
388
        self::assertEquals(
389
            'CONSTRAINT unique_constraint UNIQUE CLUSTERED (a, b)',
390
            $this->platform->getUniqueConstraintDeclarationSQL(
391
                'unique_constraint',
392
                new UniqueConstraint(null, ['a', 'b'], ['clustered'])
393
            )
394
        );
395
        self::assertEquals(
396
            'CONSTRAINT UNIQUE (a, b)',
397
            $this->platform->getUniqueConstraintDeclarationSQL(null, new UniqueConstraint(null, ['a', 'b']))
398
        );
399
    }
400
401
    public function testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns() : void
402
    {
403
        $this->expectException(InvalidArgumentException::class);
404
405
        $this->platform->getUniqueConstraintDeclarationSQL('constr', new UniqueConstraint('constr', []));
406
    }
407
408
    public function testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL() : void
409
    {
410
        self::assertEquals(
411
            'CONSTRAINT fk ' .
412
                'NOT NULL FOREIGN KEY (a, b) ' .
413
                'REFERENCES foreign_table (c, d) ' .
414
                'MATCH UNIQUE SIMPLE ON UPDATE CASCADE ON DELETE SET NULL CHECK ON COMMIT CLUSTERED FOR OLAP WORKLOAD',
415
            $this->platform->getForeignKeyDeclarationSQL(
416
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'], 'fk', [
417
                    'notnull' => true,
418
                    'match' => SQLAnywherePlatform::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE,
419
                    'onUpdate' => 'CASCADE',
420
                    'onDelete' => 'SET NULL',
421
                    'check_on_commit' => true,
422
                    'clustered' => true,
423
                    'for_olap_workload' => true,
424
                ])
425
            )
426
        );
427
        self::assertEquals(
428
            'FOREIGN KEY (a, b) REFERENCES foreign_table (c, d)',
429
            $this->platform->getForeignKeyDeclarationSQL(
430
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'])
431
            )
432
        );
433
    }
434
435
    public function testGeneratesForeignKeyMatchClausesSQL() : void
436
    {
437
        self::assertEquals('SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(1));
438
        self::assertEquals('FULL', $this->platform->getForeignKeyMatchClauseSQL(2));
439
        self::assertEquals('UNIQUE SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(129));
440
        self::assertEquals('UNIQUE FULL', $this->platform->getForeignKeyMatchClauseSQL(130));
441
    }
442
443
    public function testCannotGenerateInvalidForeignKeyMatchClauseSQL() : void
444
    {
445
        $this->expectException(InvalidArgumentException::class);
446
447
        $this->platform->getForeignKeyMatchCLauseSQL(3);
448
    }
449
450
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyLocalColumns() : void
451
    {
452
        $this->expectException(InvalidArgumentException::class);
453
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint([], 'foreign_tbl', ['c', 'd']));
454
    }
455
456
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignColumns() : void
457
    {
458
        $this->expectException(InvalidArgumentException::class);
459
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], 'foreign_tbl', []));
460
    }
461
462
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignTableName() : void
463
    {
464
        $this->expectException(InvalidArgumentException::class);
465
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], '', ['c', 'd']));
466
    }
467
468
    public function testCannotGenerateCommonIndexWithCreateConstraintSQL() : void
469
    {
470
        $this->expectException(InvalidArgumentException::class);
471
472
        $this->platform->getCreateConstraintSQL(new Index('fooindex', []), new Table('footable'));
473
    }
474
475
    public function testCannotGenerateCustomConstraintWithCreateConstraintSQL() : void
476
    {
477
        $this->expectException(InvalidArgumentException::class);
478
479
        $this->platform->getCreateConstraintSQL($this->createMock(Constraint::class), 'footable');
480
    }
481
482
    public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() : void
483
    {
484
        self::assertEquals(
485
            'CREATE UNIQUE INDEX fooindex ON footable (a, b) WITH NULLS DISTINCT',
486
            $this->platform->getCreateIndexSQL(
487
                new Index(
488
                    'fooindex',
489
                    ['a', 'b'],
490
                    true,
491
                    false,
492
                    ['with_nulls_distinct']
493
                ),
494
                'footable'
495
            )
496
        );
497
498
        // WITH NULLS DISTINCT clause not available on primary indexes.
499
        self::assertEquals(
500
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
501
            $this->platform->getCreateIndexSQL(
502
                new Index(
503
                    'fooindex',
504
                    ['a', 'b'],
505
                    false,
506
                    true,
507
                    ['with_nulls_distinct']
508
                ),
509
                'footable'
510
            )
511
        );
512
513
        // WITH NULLS DISTINCT clause not available on non-unique indexes.
514
        self::assertEquals(
515
            'CREATE INDEX fooindex ON footable (a, b)',
516
            $this->platform->getCreateIndexSQL(
517
                new Index(
518
                    'fooindex',
519
                    ['a', 'b'],
520
                    false,
521
                    false,
522
                    ['with_nulls_distinct']
523
                ),
524
                'footable'
525
            )
526
        );
527
528
        self::assertEquals(
529
            'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
530
            $this->platform->getCreateIndexSQL(
531
                new Index(
532
                    'fooindex',
533
                    ['a', 'b'],
534
                    true,
535
                    false,
536
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
537
                ),
538
                'footable'
539
            )
540
        );
541
        self::assertEquals(
542
            'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
543
            $this->platform->getCreateIndexSQL(
544
                new Index(
545
                    'fooindex',
546
                    ['a', 'b'],
547
                    false,
548
                    false,
549
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
550
                ),
551
                'footable'
552
            )
553
        );
554
555
        // WITH NULLS NOT DISTINCT clause not available on primary indexes.
556
        self::assertEquals(
557
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
558
            $this->platform->getCreateIndexSQL(
559
                new Index(
560
                    'fooindex',
561
                    ['a', 'b'],
562
                    false,
563
                    true,
564
                    ['with_nulls_not_distinct']
565
                ),
566
                'footable'
567
            )
568
        );
569
570
        // WITH NULLS NOT DISTINCT clause not available on non-unique indexes.
571
        self::assertEquals(
572
            'CREATE INDEX fooindex ON footable (a, b)',
573
            $this->platform->getCreateIndexSQL(
574
                new Index(
575
                    'fooindex',
576
                    ['a', 'b'],
577
                    false,
578
                    false,
579
                    ['with_nulls_not_distinct']
580
                ),
581
                'footable'
582
            )
583
        );
584
    }
585
586
    public function testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions() : void
587
    {
588
        $this->expectException('UnexpectedValueException');
589
590
        $this->platform->getCreateIndexSQL(
591
            new Index(
592
                'fooindex',
593
                ['a', 'b'],
594
                false,
595
                false,
596
                ['with_nulls_distinct', 'with_nulls_not_distinct']
597
            ),
598
            'footable'
599
        );
600
    }
601
602
    public function testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() : void
603
    {
604
        $this->expectException(DBALException::class);
605
606
        $this->platform->getIndexDeclarationSQL('index', new Index('index', []));
607
    }
608
609
    public function testGeneratesDropIndexSQL() : void
610
    {
611
        $index = new Index('fooindex', []);
612
613
        self::assertEquals('DROP INDEX fooindex', $this->platform->getDropIndexSQL($index));
614
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL($index, 'footable'));
615
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL(
616
            $index,
617
            new Table('footable')
618
        ));
619
    }
620
621
    public function testCannotGenerateDropIndexSQLWithInvalidIndexParameter() : void
622
    {
623
        $this->expectException(InvalidArgumentException::class);
624
625
        $this->platform->getDropIndexSQL(['index'], 'table');
626
    }
627
628
    public function testCannotGenerateDropIndexSQLWithInvalidTableParameter() : void
629
    {
630
        $this->expectException(InvalidArgumentException::class);
631
632
        $this->platform->getDropIndexSQL('index', ['table']);
633
    }
634
635
    public function testGeneratesSQLSnippets() : void
636
    {
637
        self::assertEquals('STRING(column1, "string1", column2, "string2")', $this->platform->getConcatExpression(
638
            'column1',
639
            '"string1"',
640
            'column2',
641
            '"string2"'
642
        ));
643
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
644
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
645
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
646
        self::assertEquals("DATEADD(DAY, 4, '1987/05/02')", $this->platform->getDateAddDaysExpression("'1987/05/02'", 4));
647
        self::assertEquals("DATEADD(HOUR, 12, '1987/05/02')", $this->platform->getDateAddHourExpression("'1987/05/02'", 12));
648
        self::assertEquals("DATEADD(MINUTE, 2, '1987/05/02')", $this->platform->getDateAddMinutesExpression("'1987/05/02'", 2));
649
        self::assertEquals("DATEADD(MONTH, 102, '1987/05/02')", $this->platform->getDateAddMonthExpression("'1987/05/02'", 102));
650
        self::assertEquals("DATEADD(QUARTER, 5, '1987/05/02')", $this->platform->getDateAddQuartersExpression("'1987/05/02'", 5));
651
        self::assertEquals("DATEADD(SECOND, 1, '1987/05/02')", $this->platform->getDateAddSecondsExpression("'1987/05/02'", 1));
652
        self::assertEquals("DATEADD(WEEK, 3, '1987/05/02')", $this->platform->getDateAddWeeksExpression("'1987/05/02'", 3));
653
        self::assertEquals("DATEADD(YEAR, 10, '1987/05/02')", $this->platform->getDateAddYearsExpression("'1987/05/02'", 10));
654
        self::assertEquals("DATEDIFF(day, '1987/04/01', '1987/05/02')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
655
        self::assertEquals("DATEADD(DAY, -1 * 4, '1987/05/02')", $this->platform->getDateSubDaysExpression("'1987/05/02'", 4));
656
        self::assertEquals("DATEADD(HOUR, -1 * 12, '1987/05/02')", $this->platform->getDateSubHourExpression("'1987/05/02'", 12));
657
        self::assertEquals("DATEADD(MINUTE, -1 * 2, '1987/05/02')", $this->platform->getDateSubMinutesExpression("'1987/05/02'", 2));
658
        self::assertEquals("DATEADD(MONTH, -1 * 102, '1987/05/02')", $this->platform->getDateSubMonthExpression("'1987/05/02'", 102));
659
        self::assertEquals("DATEADD(QUARTER, -1 * 5, '1987/05/02')", $this->platform->getDateSubQuartersExpression("'1987/05/02'", 5));
660
        self::assertEquals("DATEADD(SECOND, -1 * 1, '1987/05/02')", $this->platform->getDateSubSecondsExpression("'1987/05/02'", 1));
661
        self::assertEquals("DATEADD(WEEK, -1 * 3, '1987/05/02')", $this->platform->getDateSubWeeksExpression("'1987/05/02'", 3));
662
        self::assertEquals("DATEADD(YEAR, -1 * 10, '1987/05/02')", $this->platform->getDateSubYearsExpression("'1987/05/02'", 10));
663
        self::assertEquals('Y-m-d H:i:s.u', $this->platform->getDateTimeFormatString());
664
        self::assertEquals('H:i:s.u', $this->platform->getTimeFormatString());
665
        self::assertEquals('', $this->platform->getForUpdateSQL());
666
        self::assertEquals('LOCATE(string_column, substring_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
667
        self::assertEquals('LOCATE(string_column, substring_column, 2)', $this->platform->getLocateExpression('string_column', 'substring_column', 2));
668
        self::assertEquals("HASH(column, 'MD5')", $this->platform->getMd5Expression('column'));
669
        self::assertEquals('SUBSTRING(column, 5)', $this->platform->getSubstringExpression('column', 5));
670
        self::assertEquals('SUBSTRING(column, 5, 2)', $this->platform->getSubstringExpression('column', 5, 2));
671
        self::assertEquals('GLOBAL TEMPORARY', $this->platform->getTemporaryTableSQL());
672
        self::assertEquals(
673
            'LTRIM(column)',
674
            $this->platform->getTrimExpression('column', TrimMode::LEADING)
675
        );
676
        self::assertEquals(
677
            'RTRIM(column)',
678
            $this->platform->getTrimExpression('column', TrimMode::TRAILING)
679
        );
680
        self::assertEquals(
681
            'TRIM(column)',
682
            $this->platform->getTrimExpression('column')
683
        );
684
        self::assertEquals(
685
            'TRIM(column)',
686
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED)
687
        );
688
        self::assertEquals(
689
            "SUBSTR(column, PATINDEX('%[^' + c + ']%', column))",
690
            $this->platform->getTrimExpression('column', TrimMode::LEADING, 'c')
691
        );
692
        self::assertEquals(
693
            "REVERSE(SUBSTR(REVERSE(column), PATINDEX('%[^' + c + ']%', REVERSE(column))))",
694
            $this->platform->getTrimExpression('column', TrimMode::TRAILING, 'c')
695
        );
696
        self::assertEquals(
697
            "REVERSE(SUBSTR(REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))), PATINDEX('%[^' + c + ']%', " .
698
            "REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))))))",
699
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED, 'c')
700
        );
701
    }
702
703
    public function testHasCorrectDateTimeTzFormatString() : void
704
    {
705
        self::assertEquals('Y-m-d H:i:s.uP', $this->platform->getDateTimeTzFormatString());
706
    }
707
708
    public function testGeneratesDateTimeTzColumnTypeDeclarationSQL() : void
709
    {
710
        self::assertEquals(
711
            'TIMESTAMP WITH TIME ZONE',
712
            $this->platform->getDateTimeTzTypeDeclarationSQL([
713
                'length' => 10,
714
                'fixed' => true,
715
                'unsigned' => true,
716
                'autoincrement' => true,
717
            ])
718
        );
719
    }
720
721
    public function testInitializesDateTimeTzTypeMapping() : void
722
    {
723
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
724
        self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
725
    }
726
727
    public function testHasCorrectDefaultTransactionIsolationLevel() : void
728
    {
729
        self::assertEquals(
730
            TransactionIsolationLevel::READ_UNCOMMITTED,
731
            $this->platform->getDefaultTransactionIsolationLevel()
732
        );
733
    }
734
735
    public function testGeneratesTransactionsCommands() : void
736
    {
737
        self::assertEquals(
738
            'SET TEMPORARY OPTION isolation_level = 0',
739
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
740
        );
741
        self::assertEquals(
742
            'SET TEMPORARY OPTION isolation_level = 1',
743
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
744
        );
745
        self::assertEquals(
746
            'SET TEMPORARY OPTION isolation_level = 2',
747
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
748
        );
749
        self::assertEquals(
750
            'SET TEMPORARY OPTION isolation_level = 3',
751
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
752
        );
753
    }
754
755
    public function testModifiesLimitQuery() : void
756
    {
757
        self::assertEquals(
758
            'SELECT TOP 10 * FROM user',
759
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
760
        );
761
    }
762
763
    public function testModifiesLimitQueryWithEmptyOffset() : void
764
    {
765
        self::assertEquals(
766
            'SELECT TOP 10 * FROM user',
767
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
768
        );
769
    }
770
771
    public function testModifiesLimitQueryWithOffset() : void
772
    {
773
        self::assertEquals(
774
            'SELECT TOP 10 START AT 6 * FROM user',
775
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
776
        );
777
        self::assertEquals(
778
            'SELECT TOP ALL START AT 6 * FROM user',
779
            $this->platform->modifyLimitQuery('SELECT * FROM user', null, 5)
780
        );
781
    }
782
783
    public function testModifiesLimitQueryWithSubSelect() : void
784
    {
785
        self::assertEquals(
786
            'SELECT TOP 10 * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl',
787
            $this->platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl', 10)
788
        );
789
    }
790
791
    public function testPrefersIdentityColumns() : void
792
    {
793
        self::assertTrue($this->platform->prefersIdentityColumns());
794
    }
795
796
    public function testDoesNotPreferSequences() : void
797
    {
798
        self::assertFalse($this->platform->prefersSequences());
799
    }
800
801
    public function testSupportsIdentityColumns() : void
802
    {
803
        self::assertTrue($this->platform->supportsIdentityColumns());
804
    }
805
806
    public function testSupportsPrimaryConstraints() : void
807
    {
808
        self::assertTrue($this->platform->supportsPrimaryConstraints());
809
    }
810
811
    public function testSupportsForeignKeyConstraints() : void
812
    {
813
        self::assertTrue($this->platform->supportsForeignKeyConstraints());
814
    }
815
816
    public function testSupportsForeignKeyOnUpdate() : void
817
    {
818
        self::assertTrue($this->platform->supportsForeignKeyOnUpdate());
819
    }
820
821
    public function testSupportsAlterTable() : void
822
    {
823
        self::assertTrue($this->platform->supportsAlterTable());
824
    }
825
826
    public function testSupportsTransactions() : void
827
    {
828
        self::assertTrue($this->platform->supportsTransactions());
829
    }
830
831
    public function testSupportsSchemas() : void
832
    {
833
        self::assertFalse($this->platform->supportsSchemas());
834
    }
835
836
    public function testSupportsIndexes() : void
837
    {
838
        self::assertTrue($this->platform->supportsIndexes());
839
    }
840
841
    public function testSupportsCommentOnStatement() : void
842
    {
843
        self::assertTrue($this->platform->supportsCommentOnStatement());
844
    }
845
846
    public function testSupportsSavePoints() : void
847
    {
848
        self::assertTrue($this->platform->supportsSavepoints());
849
    }
850
851
    public function testSupportsReleasePoints() : void
852
    {
853
        self::assertTrue($this->platform->supportsReleaseSavepoints());
854
    }
855
856
    public function testSupportsCreateDropDatabase() : void
857
    {
858
        self::assertTrue($this->platform->supportsCreateDropDatabase());
859
    }
860
861
    public function testSupportsGettingAffectedRows() : void
862
    {
863
        self::assertTrue($this->platform->supportsGettingAffectedRows());
864
    }
865
866
    public function testDoesNotSupportSequences() : void
867
    {
868
        self::markTestSkipped('This version of the platform now supports sequences.');
869
    }
870
871
    public function testSupportsSequences() : void
872
    {
873
        self::assertTrue($this->platform->supportsSequences());
874
    }
875
876
    public function testGeneratesSequenceSqlCommands() : void
877
    {
878
        $sequence = new Sequence('myseq', 20, 1);
879
        self::assertEquals(
880
            'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
881
            $this->platform->getCreateSequenceSQL($sequence)
882
        );
883
        self::assertEquals(
884
            'ALTER SEQUENCE myseq INCREMENT BY 20',
885
            $this->platform->getAlterSequenceSQL($sequence)
886
        );
887
        self::assertEquals(
888
            'DROP SEQUENCE myseq',
889
            $this->platform->getDropSequenceSQL('myseq')
890
        );
891
        self::assertEquals(
892
            'DROP SEQUENCE myseq',
893
            $this->platform->getDropSequenceSQL($sequence)
894
        );
895
        self::assertEquals(
896
            'SELECT myseq.NEXTVAL',
897
            $this->platform->getSequenceNextValSQL('myseq')
898
        );
899
        self::assertEquals(
900
            'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE',
901
            $this->platform->getListSequencesSQL(null)
902
        );
903
    }
904
905
    public function testDoesNotSupportInlineColumnComments() : void
906
    {
907
        self::assertFalse($this->platform->supportsInlineColumnComments());
908
    }
909
910
    public function testCannotEmulateSchemas() : void
911
    {
912
        self::assertFalse($this->platform->canEmulateSchemas());
913
    }
914
915
    public function testInitializesDoctrineTypeMappings() : void
916
    {
917
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
918
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
919
920
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('binary'));
921
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('binary'));
922
923
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varbinary'));
924
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('varbinary'));
925
    }
926
927
    protected function getBinaryDefaultLength() : int
928
    {
929
        return 1;
930
    }
931
932
    protected function getBinaryMaxLength() : int
933
    {
934
        return 32767;
935
    }
936
937
    public function testReturnsBinaryTypeDeclarationSQL() : void
938
    {
939
        self::assertSame('VARBINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([]));
940
        self::assertSame('VARBINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
941
        self::assertSame('VARBINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32767]));
942
943
        self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
944
        self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([
945
            'fixed' => true,
946
            'length' => 0,
947
        ]));
948
        self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL([
949
            'fixed' => true,
950
            'length' => 32767,
951
        ]));
952
    }
953
954
    /**
955
     * {@inheritDoc}
956
     *
957
     * @group DBAL-234
958
     */
959
    protected function getAlterTableRenameIndexSQL() : array
960
    {
961
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_bar'];
962
    }
963
964
    /**
965
     * {@inheritDoc}
966
     *
967
     * @group DBAL-234
968
     */
969
    protected function getQuotedAlterTableRenameIndexSQL() : array
970
    {
971
        return [
972
            'ALTER INDEX "create" ON "table" RENAME TO "select"',
973
            'ALTER INDEX "foo" ON "table" RENAME TO "bar"',
974
        ];
975
    }
976
977
    /**
978
     * {@inheritdoc}
979
     */
980
    protected function getQuotedAlterTableRenameColumnSQL() : array
981
    {
982
        return [
983
            'ALTER TABLE mytable RENAME unquoted1 TO unquoted',
984
            'ALTER TABLE mytable RENAME unquoted2 TO "where"',
985
            'ALTER TABLE mytable RENAME unquoted3 TO "foo"',
986
            'ALTER TABLE mytable RENAME "create" TO reserved_keyword',
987
            'ALTER TABLE mytable RENAME "table" TO "from"',
988
            'ALTER TABLE mytable RENAME "select" TO "bar"',
989
            'ALTER TABLE mytable RENAME quoted1 TO quoted',
990
            'ALTER TABLE mytable RENAME quoted2 TO "and"',
991
            'ALTER TABLE mytable RENAME quoted3 TO "baz"',
992
        ];
993
    }
994
995
    /**
996
     * {@inheritdoc}
997
     */
998
    protected function getQuotedAlterTableChangeColumnLengthSQL() : array
999
    {
1000
        $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...
1001
    }
1002
1003
    /**
1004
     * {@inheritDoc}
1005
     *
1006
     * @group DBAL-807
1007
     */
1008
    protected function getAlterTableRenameIndexInSchemaSQL() : array
1009
    {
1010
        return ['ALTER INDEX idx_foo ON myschema.mytable RENAME TO idx_bar'];
1011
    }
1012
1013
    /**
1014
     * {@inheritDoc}
1015
     *
1016
     * @group DBAL-807
1017
     */
1018
    protected function getQuotedAlterTableRenameIndexInSchemaSQL() : array
1019
    {
1020
        return [
1021
            'ALTER INDEX "create" ON "schema"."table" RENAME TO "select"',
1022
            'ALTER INDEX "foo" ON "schema"."table" RENAME TO "bar"',
1023
        ];
1024
    }
1025
1026
    /**
1027
     * @group DBAL-423
1028
     */
1029
    public function testReturnsGuidTypeDeclarationSQL() : void
1030
    {
1031
        self::assertSame('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL([]));
1032
    }
1033
1034
    /**
1035
     * {@inheritdoc}
1036
     */
1037
    public function getAlterTableRenameColumnSQL() : array
1038
    {
1039
        return ['ALTER TABLE foo RENAME bar TO baz'];
1040
    }
1041
1042
    /**
1043
     * {@inheritdoc}
1044
     */
1045
    protected function getQuotesTableIdentifiersInAlterTableSQL() : array
1046
    {
1047
        return [
1048
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
1049
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
1050
            'ALTER TABLE "foo" RENAME id TO war',
1051
            'ALTER TABLE "foo" ADD bloo INT NOT NULL, DROP baz, ALTER bar INT DEFAULT NULL',
1052
            'ALTER TABLE "foo" RENAME "table"',
1053
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
1054
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
1055
        ];
1056
    }
1057
1058
    /**
1059
     * {@inheritdoc}
1060
     */
1061
    protected function getCommentOnColumnSQL() : array
1062
    {
1063
        return [
1064
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
1065
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
1066
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
1067
        ];
1068
    }
1069
1070
    /**
1071
     * @group DBAL-1004
1072
     */
1073
    public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers() : void
1074
    {
1075
        $table1 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'))]);
1076
        $table2 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'), ['comment' => 'baz'])]);
1077
1078
        $comparator = new Comparator();
1079
1080
        $tableDiff = $comparator->diffTable($table1, $table2);
1081
1082
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1083
        self::assertSame(
1084
            ['COMMENT ON COLUMN "foo"."bar" IS \'baz\''],
1085
            $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

1085
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $tableDiff)
Loading history...
1086
        );
1087
    }
1088
1089
    /**
1090
     * {@inheritdoc}
1091
     */
1092
    public static function getReturnsForeignKeyReferentialActionSQL() : iterable
1093
    {
1094
        return [
1095
            ['CASCADE', 'CASCADE'],
1096
            ['SET NULL', 'SET NULL'],
1097
            ['NO ACTION', 'RESTRICT'],
1098
            ['RESTRICT', 'RESTRICT'],
1099
            ['SET DEFAULT', 'SET DEFAULT'],
1100
            ['CaScAdE', 'CASCADE'],
1101
        ];
1102
    }
1103
1104
    /**
1105
     * {@inheritdoc}
1106
     */
1107
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() : string
1108
    {
1109
        return 'CONSTRAINT "select" UNIQUE (foo)';
1110
    }
1111
1112
    /**
1113
     * {@inheritdoc}
1114
     */
1115
    protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string
1116
    {
1117
        return ''; // not supported by this platform
1118
    }
1119
1120
    /**
1121
     * {@inheritdoc}
1122
     */
1123
    protected function getQuotesReservedKeywordInTruncateTableSQL() : string
1124
    {
1125
        return 'TRUNCATE TABLE "select"';
1126
    }
1127
1128
    /**
1129
     * {@inheritdoc}
1130
     */
1131
    protected function supportsInlineIndexDeclaration() : bool
1132
    {
1133
        return false;
1134
    }
1135
1136
    /**
1137
     * {@inheritdoc}
1138
     */
1139
    protected function getAlterStringToFixedStringSQL() : array
1140
    {
1141
        return ['ALTER TABLE mytable ALTER name CHAR(2) NOT NULL'];
1142
    }
1143
1144
    /**
1145
     * {@inheritdoc}
1146
     */
1147
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array
1148
    {
1149
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_foo_renamed'];
1150
    }
1151
1152
    /**
1153
     * @group DBAL-2436
1154
     */
1155
    public function testQuotesSchemaNameInListTableColumnsSQL() : void
1156
    {
1157
        self::assertContains(
1158
            "'Foo''Bar\\'",
1159
            $this->platform->getListTableColumnsSQL("Foo'Bar\\.baz_table"),
1160
            '',
1161
            true
1162
        );
1163
    }
1164
1165
    /**
1166
     * @group DBAL-2436
1167
     */
1168
    public function testQuotesTableNameInListTableConstraintsSQL() : void
1169
    {
1170
        self::assertContains("'Foo''Bar\\'", $this->platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true);
1171
    }
1172
1173
    /**
1174
     * @group DBAL-2436
1175
     */
1176
    public function testQuotesSchemaNameInListTableConstraintsSQL() : void
1177
    {
1178
        self::assertContains(
1179
            "'Foo''Bar\\'",
1180
            $this->platform->getListTableConstraintsSQL("Foo'Bar\\.baz_table"),
1181
            '',
1182
            true
1183
        );
1184
    }
1185
1186
    /**
1187
     * @group DBAL-2436
1188
     */
1189
    public function testQuotesTableNameInListTableForeignKeysSQL() : void
1190
    {
1191
        self::assertContains("'Foo''Bar\\'", $this->platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true);
1192
    }
1193
1194
    /**
1195
     * @group DBAL-2436
1196
     */
1197
    public function testQuotesSchemaNameInListTableForeignKeysSQL() : void
1198
    {
1199
        self::assertContains(
1200
            "'Foo''Bar\\'",
1201
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table"),
1202
            '',
1203
            true
1204
        );
1205
    }
1206
1207
    /**
1208
     * @group DBAL-2436
1209
     */
1210
    public function testQuotesTableNameInListTableIndexesSQL() : void
1211
    {
1212
        self::assertContains("'Foo''Bar\\'", $this->platform->getListTableIndexesSQL("Foo'Bar\\"), '', true);
1213
    }
1214
1215
    /**
1216
     * @group DBAL-2436
1217
     */
1218
    public function testQuotesSchemaNameInListTableIndexesSQL() : void
1219
    {
1220
        self::assertContains(
1221
            "'Foo''Bar\\'",
1222
            $this->platform->getListTableIndexesSQL("Foo'Bar\\.baz_table"),
1223
            '',
1224
            true
1225
        );
1226
    }
1227
}
1228