Failed Conditions
Pull Request — develop (#3586)
by Sergei
02:50
created

getQuotedAlterTableChangeColumnLengthSQL()   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
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Platforms;
6
7
use Doctrine\DBAL\Exception\ColumnLengthRequired;
8
use Doctrine\DBAL\Platforms\AbstractPlatform;
9
use Doctrine\DBAL\Platforms\DB2Platform;
10
use Doctrine\DBAL\Schema\Column;
11
use Doctrine\DBAL\Schema\ColumnDiff;
12
use Doctrine\DBAL\Schema\Index;
13
use Doctrine\DBAL\Schema\Table;
14
use Doctrine\DBAL\Schema\TableDiff;
15
use Doctrine\DBAL\Types\Type;
16
use Doctrine\DBAL\Types\Types;
17
18
class DB2PlatformTest extends AbstractPlatformTestCase
0 ignored issues
show
Bug introduced by
The type Doctrine\Tests\DBAL\Plat...bstractPlatformTestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
{
20
    /** @var DB2Platform */
21
    protected $platform;
22
23
    public function createPlatform() : AbstractPlatform
24
    {
25
        return new DB2Platform();
26
    }
27
28
    /**
29
     * {@inheritDoc}
30
     */
31
    public function getGenerateAlterTableSql() : array
32
    {
33
        return [
34
            'ALTER TABLE mytable ALTER COLUMN baz SET DATA TYPE VARCHAR(255)',
35
            'ALTER TABLE mytable ALTER COLUMN baz SET NOT NULL',
36
            "ALTER TABLE mytable ALTER COLUMN baz SET DEFAULT 'def'",
37
            'ALTER TABLE mytable ALTER COLUMN bloo SET DATA TYPE SMALLINT',
38
            'ALTER TABLE mytable ALTER COLUMN bloo SET NOT NULL',
39
            "ALTER TABLE mytable ALTER COLUMN bloo SET DEFAULT '0'",
40
            'ALTER TABLE mytable ' .
41
            'ADD COLUMN quota INTEGER DEFAULT NULL ' .
42
            'DROP COLUMN foo',
43
            "CALL SYSPROC.ADMIN_CMD ('REORG TABLE mytable')",
44
            'RENAME TABLE mytable TO 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 INTEGER GENERATED BY DEFAULT AS 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 [
85
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)',
86
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar")',
87
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar")',
88
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar")',
89
        ];
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    protected function getQuotedColumnInIndexSQL() : array
96
    {
97
        return [
98
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
99
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
100
        ];
101
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106
    protected function getQuotedNameInIndexSQL() : array
107
    {
108
        return [
109
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
110
            'CREATE INDEX "key" ON test (column1)',
111
        ];
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117
    protected function getQuotedColumnInPrimaryKeySQL() : array
118
    {
119
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY("create"))'];
120
    }
121
122
    protected function getBitAndComparisonExpressionSql(string $value1, string $value2) : string
123
    {
124
        return 'BITAND(' . $value1 . ', ' . $value2 . ')';
125
    }
126
127
    protected function getBitOrComparisonExpressionSql(string $value1, string $value2) : string
128
    {
129
        return 'BITOR(' . $value1 . ', ' . $value2 . ')';
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     */
135
    public function getCreateTableColumnCommentsSQL() : array
136
    {
137
        return [
138
            'CREATE TABLE test (id INTEGER NOT NULL, PRIMARY KEY(id))',
139
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
140
        ];
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146
    public function getAlterTableColumnCommentsSQL() : array
147
    {
148
        return [
149
            'ALTER TABLE mytable ' .
150
            'ADD COLUMN quota INTEGER NOT NULL WITH DEFAULT',
151
            "CALL SYSPROC.ADMIN_CMD ('REORG TABLE mytable')",
152
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
153
            "COMMENT ON COLUMN mytable.foo IS ''",
154
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
155
        ];
156
    }
157
158
    /**
159
     * {@inheritDoc}
160
     */
161
    public function getCreateTableColumnTypeCommentsSQL() : array
162
    {
163
        return [
164
            'CREATE TABLE test (id INTEGER NOT NULL, "data" CLOB(1M) NOT NULL, PRIMARY KEY(id))',
165
            'COMMENT ON COLUMN test."data" IS \'(DC2Type:array)\'',
166
        ];
167
    }
168
169
    public function testHasCorrectPlatformName() : void
170
    {
171
        self::assertEquals('db2', $this->platform->getName());
172
    }
173
174
    public function testGeneratesCreateTableSQLWithCommonIndexes() : void
175
    {
176
        $table = new Table('test');
177
        $table->addColumn('id', 'integer');
178
        $table->addColumn('name', 'string', ['length' => 50]);
179
        $table->setPrimaryKey(['id']);
180
        $table->addIndex(['name']);
181
        $table->addIndex(['id', 'name'], 'composite_idx');
182
183
        self::assertEquals(
184
            [
185
                'CREATE TABLE test (id INTEGER NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id))',
186
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
187
                'CREATE INDEX composite_idx ON test (id, name)',
188
            ],
189
            $this->platform->getCreateTableSQL($table)
190
        );
191
    }
192
193
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints() : void
194
    {
195
        $table = new Table('test');
196
        $table->addColumn('id', 'integer');
197
        $table->addColumn('fk_1', 'integer');
198
        $table->addColumn('fk_2', 'integer');
199
        $table->setPrimaryKey(['id']);
200
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
201
        $table->addForeignKeyConstraint(
202
            'foreign_table2',
203
            ['fk_1', 'fk_2'],
204
            ['pk_1', 'pk_2'],
205
            [],
206
            'named_fk'
207
        );
208
209
        self::assertEquals(
210
            [
211
                'CREATE TABLE test (id INTEGER NOT NULL, fk_1 INTEGER NOT NULL, fk_2 INTEGER NOT NULL)',
212
                'ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2)',
213
                'ALTER TABLE test ADD CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2)',
214
            ],
215
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
216
        );
217
    }
218
219
    public function testGeneratesCreateTableSQLWithCheckConstraints() : void
220
    {
221
        $table = new Table('test');
222
        $table->addColumn('id', 'integer');
223
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
224
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
225
        $table->setPrimaryKey(['id']);
226
227
        self::assertEquals(
228
            ['CREATE TABLE test (id INTEGER NOT NULL, check_max INTEGER NOT NULL, check_min INTEGER NOT NULL, PRIMARY KEY(id), CHECK (check_max <= 10), CHECK (check_min >= 10))'],
229
            $this->platform->getCreateTableSQL($table)
230
        );
231
    }
232
233
    public function testGeneratesColumnTypesDeclarationSQL() : void
234
    {
235
        $fullColumnDef = [
236
            'length' => 10,
237
            'fixed' => true,
238
            'unsigned' => true,
239
            'autoincrement' => true,
240
        ];
241
242
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL([]));
243
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL(['unsigned' => true]));
244
        self::assertEquals('SMALLINT GENERATED BY DEFAULT AS IDENTITY', $this->platform->getSmallIntTypeDeclarationSQL($fullColumnDef));
245
        self::assertEquals('INTEGER', $this->platform->getIntegerTypeDeclarationSQL([]));
246
        self::assertEquals('INTEGER', $this->platform->getIntegerTypeDeclarationSQL(['unsigned' => true]));
247
        self::assertEquals('INTEGER GENERATED BY DEFAULT AS IDENTITY', $this->platform->getIntegerTypeDeclarationSQL($fullColumnDef));
248
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL([]));
249
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL(['unsigned' => true]));
250
        self::assertEquals('BIGINT GENERATED BY DEFAULT AS IDENTITY', $this->platform->getBigIntTypeDeclarationSQL($fullColumnDef));
251
        self::assertEquals('BLOB(1M)', $this->platform->getBlobTypeDeclarationSQL($fullColumnDef));
252
        self::assertEquals('SMALLINT', $this->platform->getBooleanTypeDeclarationSQL($fullColumnDef));
253
        self::assertEquals('CLOB(1M)', $this->platform->getClobTypeDeclarationSQL($fullColumnDef));
254
        self::assertEquals('DATE', $this->platform->getDateTypeDeclarationSQL($fullColumnDef));
255
        self::assertEquals('TIMESTAMP(0) WITH DEFAULT', $this->platform->getDateTimeTypeDeclarationSQL(['version' => true]));
256
        self::assertEquals('TIMESTAMP(0)', $this->platform->getDateTimeTypeDeclarationSQL($fullColumnDef));
257
        self::assertEquals('TIME', $this->platform->getTimeTypeDeclarationSQL($fullColumnDef));
258
    }
259
260
    public function testInitializesDoctrineTypeMappings() : void
261
    {
262
        $this->platform->initializeDoctrineTypeMappings();
263
264
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('smallint'));
265
        self::assertSame('smallint', $this->platform->getDoctrineTypeMapping('smallint'));
266
267
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('bigint'));
268
        self::assertSame('bigint', $this->platform->getDoctrineTypeMapping('bigint'));
269
270
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
271
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
272
273
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('time'));
274
        self::assertSame('time', $this->platform->getDoctrineTypeMapping('time'));
275
276
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('date'));
277
        self::assertSame('date', $this->platform->getDoctrineTypeMapping('date'));
278
279
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varchar'));
280
        self::assertSame('string', $this->platform->getDoctrineTypeMapping('varchar'));
281
282
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('character'));
283
        self::assertSame('string', $this->platform->getDoctrineTypeMapping('character'));
284
285
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('clob'));
286
        self::assertSame('text', $this->platform->getDoctrineTypeMapping('clob'));
287
288
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('blob'));
289
        self::assertSame('blob', $this->platform->getDoctrineTypeMapping('blob'));
290
291
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('decimal'));
292
        self::assertSame('decimal', $this->platform->getDoctrineTypeMapping('decimal'));
293
294
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('double'));
295
        self::assertSame('float', $this->platform->getDoctrineTypeMapping('double'));
296
297
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('real'));
298
        self::assertSame('float', $this->platform->getDoctrineTypeMapping('real'));
299
300
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp'));
301
        self::assertSame('datetime', $this->platform->getDoctrineTypeMapping('timestamp'));
302
    }
303
304
    /**
305
     * {@inheritDoc}
306
     */
307
    public function getIsCommentedDoctrineType() : array
308
    {
309
        $data = parent::getIsCommentedDoctrineType();
310
311
        $data[Types::BOOLEAN] = [Type::getType(Types::BOOLEAN), true];
312
313
        return $data;
314
    }
315
316
    public function testGeneratesDDLSnippets() : void
317
    {
318
        self::assertEquals('CREATE DATABASE foobar', $this->platform->getCreateDatabaseSQL('foobar'));
319
        self::assertEquals('DROP DATABASE foobar', $this->platform->getDropDatabaseSQL('foobar'));
320
        self::assertEquals('DECLARE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
321
        self::assertEquals('TRUNCATE foobar IMMEDIATE', $this->platform->getTruncateTableSQL('foobar'));
322
323
        $viewSql = 'SELECT * FROM footable';
324
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
325
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
326
    }
327
328
    public function testGeneratesCreateUnnamedPrimaryKeySQL() : void
329
    {
330
        self::assertEquals(
331
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
332
            $this->platform->getCreatePrimaryKeySQL(
333
                new Index('any_pk_name', ['a', 'b'], true, true),
334
                'foo'
335
            )
336
        );
337
    }
338
339
    public function testGeneratesSQLSnippets() : void
340
    {
341
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
342
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
343
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
344
        self::assertEquals("'1987/05/02' + 4 DAY", $this->platform->getDateAddDaysExpression("'1987/05/02'", '4'));
345
        self::assertEquals("'1987/05/02' + 12 HOUR", $this->platform->getDateAddHourExpression("'1987/05/02'", '12'));
346
        self::assertEquals("'1987/05/02' + 2 MINUTE", $this->platform->getDateAddMinutesExpression("'1987/05/02'", '2'));
347
        self::assertEquals("'1987/05/02' + 102 MONTH", $this->platform->getDateAddMonthExpression("'1987/05/02'", '102'));
348
        self::assertEquals("'1987/05/02' + (5 * 3) MONTH", $this->platform->getDateAddQuartersExpression("'1987/05/02'", '5'));
349
        self::assertEquals("'1987/05/02' + 1 SECOND", $this->platform->getDateAddSecondsExpression("'1987/05/02'", '1'));
350
        self::assertEquals("'1987/05/02' + (3 * 7) DAY", $this->platform->getDateAddWeeksExpression("'1987/05/02'", '3'));
351
        self::assertEquals("'1987/05/02' + 10 YEAR", $this->platform->getDateAddYearsExpression("'1987/05/02'", '10'));
352
        self::assertEquals("DAYS('1987/05/02') - DAYS('1987/04/01')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
353
        self::assertEquals("'1987/05/02' - 4 DAY", $this->platform->getDateSubDaysExpression("'1987/05/02'", '4'));
354
        self::assertEquals("'1987/05/02' - 12 HOUR", $this->platform->getDateSubHourExpression("'1987/05/02'", '12'));
355
        self::assertEquals("'1987/05/02' - 2 MINUTE", $this->platform->getDateSubMinutesExpression("'1987/05/02'", '2'));
356
        self::assertEquals("'1987/05/02' - 102 MONTH", $this->platform->getDateSubMonthExpression("'1987/05/02'", '102'));
357
        self::assertEquals("'1987/05/02' - (5 * 3) MONTH", $this->platform->getDateSubQuartersExpression("'1987/05/02'", '5'));
358
        self::assertEquals("'1987/05/02' - 1 SECOND", $this->platform->getDateSubSecondsExpression("'1987/05/02'", '1'));
359
        self::assertEquals("'1987/05/02' - (3 * 7) DAY", $this->platform->getDateSubWeeksExpression("'1987/05/02'", '3'));
360
        self::assertEquals("'1987/05/02' - 10 YEAR", $this->platform->getDateSubYearsExpression("'1987/05/02'", '10'));
361
        self::assertEquals(' WITH RR USE AND KEEP UPDATE LOCKS', $this->platform->getForUpdateSQL());
362
        self::assertEquals('LOCATE(substring_column, string_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
363
        self::assertEquals('LOCATE(substring_column, string_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', '1'));
364
        self::assertEquals('SUBSTR(column, 5)', $this->platform->getSubstringExpression('column', '5'));
365
        self::assertEquals('SUBSTR(column, 5, 2)', $this->platform->getSubstringExpression('column', '5', '2'));
366
    }
367
368
    public function testModifiesLimitQuery() : void
369
    {
370
        self::assertEquals(
371
            'SELECT * FROM user',
372
            $this->platform->modifyLimitQuery('SELECT * FROM user', null, 0)
373
        );
374
375
        self::assertEquals(
376
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10',
377
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
378
        );
379
380
        self::assertEquals(
381
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10',
382
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
383
        );
384
385
        self::assertEquals(
386
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM >= 6 AND db22.DC_ROWNUM <= 15',
387
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
388
        );
389
        self::assertEquals(
390
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM >= 6 AND db22.DC_ROWNUM <= 5',
391
            $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
392
        );
393
    }
394
395
    public function testPrefersIdentityColumns() : void
396
    {
397
        self::assertTrue($this->platform->prefersIdentityColumns());
398
    }
399
400
    public function testSupportsIdentityColumns() : void
401
    {
402
        self::assertTrue($this->platform->supportsIdentityColumns());
403
    }
404
405
    public function testDoesNotSupportSavePoints() : void
406
    {
407
        self::assertFalse($this->platform->supportsSavepoints());
408
    }
409
410
    public function testDoesNotSupportReleasePoints() : void
411
    {
412
        self::assertFalse($this->platform->supportsReleaseSavepoints());
413
    }
414
415
    public function testDoesNotSupportCreateDropDatabase() : void
416
    {
417
        self::assertFalse($this->platform->supportsCreateDropDatabase());
418
    }
419
420
    public function testReturnsSQLResultCasing() : void
421
    {
422
        self::assertSame('COL', $this->platform->getSQLResultCasing('cOl'));
423
    }
424
425
    public function testGetVariableLengthStringTypeDeclarationSQLNoLength() : void
426
    {
427
        $this->expectException(ColumnLengthRequired::class);
428
429
        parent::testGetVariableLengthStringTypeDeclarationSQLNoLength();
430
    }
431
432
    public function getExpectedFixedLengthBinaryTypeDeclarationSQLNoLength() : string
433
    {
434
        return 'CHAR FOR BIT DATA';
435
    }
436
437
    public function getExpectedFixedLengthBinaryTypeDeclarationSQLWithLength() : string
438
    {
439
        return 'CHAR(16) FOR BIT DATA';
440
    }
441
442
    public function getExpectedVariableLengthBinaryTypeDeclarationSQLNoLength() : string
443
    {
444
        return 'CHAR(16) FOR BIT DATA';
445
    }
446
447
    public function testGetVariableLengthBinaryTypeDeclarationSQLNoLength() : void
448
    {
449
        $this->expectException(ColumnLengthRequired::class);
450
451
        parent::testGetVariableLengthBinaryTypeDeclarationSQLNoLength();
452
    }
453
454
    public function getExpectedVariableLengthBinaryTypeDeclarationSQLWithLength() : string
455
    {
456
        return 'VARCHAR(16) FOR BIT DATA';
457
    }
458
459
    /**
460
     * {@inheritDoc}
461
     *
462
     * @group DBAL-234
463
     */
464
    protected function getAlterTableRenameIndexSQL() : array
465
    {
466
        return ['RENAME INDEX idx_foo TO idx_bar'];
467
    }
468
469
    /**
470
     * {@inheritDoc}
471
     *
472
     * @group DBAL-234
473
     */
474
    protected function getQuotedAlterTableRenameIndexSQL() : array
475
    {
476
        return [
477
            'RENAME INDEX "create" TO "select"',
478
            'RENAME INDEX "foo" TO "bar"',
479
        ];
480
    }
481
482
    /**
483
     * {@inheritdoc}
484
     */
485
    protected function getQuotedAlterTableRenameColumnSQL() : array
486
    {
487
        return ['ALTER TABLE mytable ' .
488
            'RENAME COLUMN unquoted1 TO unquoted ' .
489
            'RENAME COLUMN unquoted2 TO "where" ' .
490
            'RENAME COLUMN unquoted3 TO "foo" ' .
491
            'RENAME COLUMN "create" TO reserved_keyword ' .
492
            'RENAME COLUMN "table" TO "from" ' .
493
            'RENAME COLUMN "select" TO "bar" ' .
494
            'RENAME COLUMN quoted1 TO quoted ' .
495
            'RENAME COLUMN quoted2 TO "and" ' .
496
            'RENAME COLUMN quoted3 TO "baz"',
497
        ];
498
    }
499
500
    /**
501
     * {@inheritdoc}
502
     */
503
    protected function getQuotedAlterTableChangeColumnLengthSQL() : array
504
    {
505
        $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...
506
    }
507
508
    /**
509
     * {@inheritDoc}
510
     *
511
     * @group DBAL-807
512
     */
513
    protected function getAlterTableRenameIndexInSchemaSQL() : array
514
    {
515
        return ['RENAME INDEX myschema.idx_foo TO idx_bar'];
516
    }
517
518
    /**
519
     * {@inheritDoc}
520
     *
521
     * @group DBAL-807
522
     */
523
    protected function getQuotedAlterTableRenameIndexInSchemaSQL() : array
524
    {
525
        return [
526
            'RENAME INDEX "schema"."create" TO "select"',
527
            'RENAME INDEX "schema"."foo" TO "bar"',
528
        ];
529
    }
530
531
    /**
532
     * @group DBAL-423
533
     */
534
    public function testReturnsGuidTypeDeclarationSQL() : void
535
    {
536
        self::assertSame('CHAR(36)', $this->platform->getGuidTypeDeclarationSQL([]));
537
    }
538
539
    /**
540
     * {@inheritdoc}
541
     */
542
    public function getAlterTableRenameColumnSQL() : array
543
    {
544
        return ['ALTER TABLE foo RENAME COLUMN bar TO baz'];
545
    }
546
547
    /**
548
     * {@inheritdoc}
549
     */
550
    protected function getQuotesTableIdentifiersInAlterTableSQL() : array
551
    {
552
        return [
553
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
554
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
555
            'ALTER TABLE "foo" ' .
556
            'ADD COLUMN bloo INTEGER NOT NULL WITH DEFAULT ' .
557
            'DROP COLUMN baz ' .
558
            'ALTER COLUMN bar DROP NOT NULL ' .
559
            'RENAME COLUMN id TO war',
560
            'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE "foo"\')',
561
            'RENAME TABLE "foo" TO "table"',
562
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
563
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
564
        ];
565
    }
566
567
    /**
568
     * {@inheritdoc}
569
     */
570
    protected function getCommentOnColumnSQL() : array
571
    {
572
        return [
573
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
574
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
575
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
576
        ];
577
    }
578
579
    /**
580
     * @group DBAL-944
581
     * @dataProvider getGeneratesAlterColumnSQL
582
     */
583
    public function testGeneratesAlterColumnSQL(string $changedProperty, Column $column, ?string $expectedSQLClause = null) : void
584
    {
585
        $tableDiff                        = new TableDiff('foo');
586
        $tableDiff->fromTable             = new Table('foo');
587
        $tableDiff->changedColumns['bar'] = new ColumnDiff('bar', $column, [$changedProperty]);
588
589
        $expectedSQL = [];
590
591
        if ($expectedSQLClause !== null) {
592
            $expectedSQL[] = 'ALTER TABLE foo ALTER COLUMN bar ' . $expectedSQLClause;
593
        }
594
595
        $expectedSQL[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE foo')";
596
597
        self::assertSame($expectedSQL, $this->platform->getAlterTableSQL($tableDiff));
598
    }
599
600
    /**
601
     * @return mixed[][]
602
     */
603
    public static function getGeneratesAlterColumnSQL() : iterable
604
    {
605
        return [
606
            [
607
                'columnDefinition',
608
                new Column('bar', Type::getType('decimal'), ['columnDefinition' => 'MONEY NOT NULL']),
609
                'MONEY NOT NULL',
610
            ],
611
            [
612
                'type',
613
                new Column('bar', Type::getType('integer')),
614
                'SET DATA TYPE INTEGER',
615
            ],
616
            [
617
                'length',
618
                new Column('bar', Type::getType('string'), ['length' => 100]),
619
                'SET DATA TYPE VARCHAR(100)',
620
            ],
621
            [
622
                'precision',
623
                new Column('bar', Type::getType('decimal'), ['precision' => 10, 'scale' => 2]),
624
                'SET DATA TYPE NUMERIC(10, 2)',
625
            ],
626
            [
627
                'scale',
628
                new Column('bar', Type::getType('decimal'), ['precision' => 5, 'scale' => 4]),
629
                'SET DATA TYPE NUMERIC(5, 4)',
630
            ],
631
            [
632
                'fixed',
633
                new Column('bar', Type::getType('string'), ['length' => 20, 'fixed' => true]),
634
                'SET DATA TYPE CHAR(20)',
635
            ],
636
            [
637
                'notnull',
638
                new Column('bar', Type::getType('string'), ['notnull' => true]),
639
                'SET NOT NULL',
640
            ],
641
            [
642
                'notnull',
643
                new Column('bar', Type::getType('string'), ['notnull' => false]),
644
                'DROP NOT NULL',
645
            ],
646
            [
647
                'default',
648
                new Column('bar', Type::getType('string'), ['default' => 'foo']),
649
                "SET DEFAULT 'foo'",
650
            ],
651
            [
652
                'default',
653
                new Column('bar', Type::getType('integer'), ['autoincrement' => true, 'default' => 666]),
654
                null,
655
            ],
656
            [
657
                'default',
658
                new Column('bar', Type::getType('string')),
659
                'DROP DEFAULT',
660
            ],
661
        ];
662
    }
663
664
    /**
665
     * {@inheritdoc}
666
     */
667
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() : string
668
    {
669
        return 'CONSTRAINT "select" UNIQUE (foo)';
670
    }
671
672
    /**
673
     * {@inheritdoc}
674
     */
675
    protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string
676
    {
677
        return ''; // not supported by this platform
678
    }
679
680
    /**
681
     * {@inheritdoc}
682
     */
683
    protected function getQuotesReservedKeywordInTruncateTableSQL() : string
684
    {
685
        return 'TRUNCATE "select" IMMEDIATE';
686
    }
687
688
    /**
689
     * {@inheritdoc}
690
     */
691
    protected function supportsInlineIndexDeclaration() : bool
692
    {
693
        return false;
694
    }
695
696
    /**
697
     * {@inheritdoc}
698
     */
699
    protected function supportsCommentOnStatement() : bool
700
    {
701
        return true;
702
    }
703
704
    /**
705
     * {@inheritdoc}
706
     */
707
    protected function getAlterStringToFixedStringSQL() : array
708
    {
709
        return [
710
            'ALTER TABLE mytable ALTER COLUMN name SET DATA TYPE CHAR(2)',
711
            'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE mytable\')',
712
        ];
713
    }
714
715
    /**
716
     * {@inheritdoc}
717
     */
718
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array
719
    {
720
        return ['RENAME INDEX idx_foo TO idx_foo_renamed'];
721
    }
722
723
    /**
724
     * @group DBAL-2436
725
     */
726
    public function testQuotesTableNameInListTableColumnsSQL() : void
727
    {
728
        self::assertStringContainsStringIgnoringCase(
729
            "'Foo''Bar\\'",
730
            $this->platform->getListTableColumnsSQL("Foo'Bar\\")
731
        );
732
    }
733
734
    /**
735
     * @group DBAL-2436
736
     */
737
    public function testQuotesTableNameInListTableIndexesSQL() : void
738
    {
739
        self::assertStringContainsStringIgnoringCase(
740
            "'Foo''Bar\\'",
741
            $this->platform->getListTableIndexesSQL("Foo'Bar\\")
742
        );
743
    }
744
745
    /**
746
     * @group DBAL-2436
747
     */
748
    public function testQuotesTableNameInListTableForeignKeysSQL() : void
749
    {
750
        self::assertStringContainsStringIgnoringCase(
751
            "'Foo''Bar\\'",
752
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\")
753
        );
754
    }
755
}
756