diff --git a/UPGRADE.md b/UPGRADE.md index 175bc06df5a..239a8615426 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,6 +8,11 @@ awareness about deprecated code. # Upgrade to 4.0 +## Removed defaults for MySQL table charset, collation and engine + +The library no longer provides the default values for MySQL table charset, collation and engine. +If omitted in the table definition, MySQL will derive the values from the database options. + ## Removed `ReservedWordsCommand::setKeywordListClass()` To add or replace a keyword list, use `ReservedWordsCommand::setKeywordList()`. diff --git a/src/Platforms/MySQLPlatform.php b/src/Platforms/MySQLPlatform.php index b983c6177a4..148861de4c9 100644 --- a/src/Platforms/MySQLPlatform.php +++ b/src/Platforms/MySQLPlatform.php @@ -28,6 +28,7 @@ use function is_string; use function sprintf; use function str_replace; +use function strcasecmp; use function strtoupper; use function trim; @@ -335,26 +336,32 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; } - $query = 'CREATE '; + $sql = ['CREATE']; if (! empty($options['temporary'])) { - $query .= 'TEMPORARY '; + $sql[] = 'TEMPORARY'; } - $query .= 'TABLE ' . $name . ' (' . $queryFields . ') '; - $query .= $this->buildTableOptions($options); - $query .= $this->buildPartitionOptions($options); + $sql[] = 'TABLE ' . $name . ' (' . $queryFields . ')'; - $sql = [$query]; - $engine = 'INNODB'; + $tableOptions = $this->buildTableOptions($options); - if (isset($options['engine'])) { - $engine = strtoupper(trim($options['engine'])); + if ($tableOptions !== '') { + $sql[] = $tableOptions; + } + + if (isset($options['partition_options'])) { + $sql[] = $options['partition_options']; } + $sql = [implode(' ', $sql)]; + // Propagate foreign key constraints only for InnoDB. - if (isset($options['foreignKeys']) && $engine === 'INNODB') { - foreach ((array) $options['foreignKeys'] as $definition) { + if ( + isset($options['foreignKeys']) + && (! isset($options['engine']) || strcasecmp($options['engine'], 'InnoDB') === 0) + ) { + foreach ($options['foreignKeys'] as $definition) { $sql[] = $this->getCreateForeignKeySQL($definition, $name); } } @@ -388,27 +395,18 @@ private function buildTableOptions(array $options): string $tableOptions = []; - // Charset - if (! isset($options['charset'])) { - $options['charset'] = 'utf8'; + if (isset($options['charset'])) { + $tableOptions[] = sprintf('DEFAULT CHARACTER SET %s', $options['charset']); } - $tableOptions[] = sprintf('DEFAULT CHARACTER SET %s', $options['charset']); - - // Collate - if (! isset($options['collate'])) { - $options['collate'] = $options['charset'] . '_unicode_ci'; + if (isset($options['collate'])) { + $tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collate']); } - $tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collate']); - - // Engine - if (! isset($options['engine'])) { - $options['engine'] = 'InnoDB'; + if (isset($options['engine'])) { + $tableOptions[] = sprintf('ENGINE = %s', $options['engine']); } - $tableOptions[] = sprintf('ENGINE = %s', $options['engine']); - // Auto increment if (isset($options['auto_increment'])) { $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']); @@ -427,18 +425,6 @@ private function buildTableOptions(array $options): string return implode(' ', $tableOptions); } - /** - * Build SQL for partition options. - * - * @param mixed[] $options - */ - private function buildPartitionOptions(array $options): string - { - return isset($options['partition_options']) - ? ' ' . $options['partition_options'] - : ''; - } - /** * {@inheritDoc} */ diff --git a/tests/Functional/Schema/MySQLSchemaManagerTest.php b/tests/Functional/Schema/MySQLSchemaManagerTest.php index bdb71c1fafe..5f0435983dc 100644 --- a/tests/Functional/Schema/MySQLSchemaManagerTest.php +++ b/tests/Functional/Schema/MySQLSchemaManagerTest.php @@ -204,7 +204,6 @@ public function testColumnCharset(): void { $table = new Table('test_column_charset'); $table->addColumn('id', 'integer'); - $table->addColumn('no_charset', 'text'); $table->addColumn('foo', 'text')->setPlatformOption('charset', 'ascii'); $table->addColumn('bar', 'text')->setPlatformOption('charset', 'latin1'); $this->schemaManager->dropAndCreateTable($table); @@ -212,7 +211,6 @@ public function testColumnCharset(): void $columns = $this->schemaManager->listTableColumns('test_column_charset'); self::assertFalse($columns['id']->hasPlatformOption('charset')); - self::assertEquals('utf8', $columns['no_charset']->getPlatformOption('charset')); self::assertEquals('ascii', $columns['foo']->getPlatformOption('charset')); self::assertEquals('latin1', $columns['bar']->getPlatformOption('charset')); } diff --git a/tests/Platforms/AbstractMySQLPlatformTestCase.php b/tests/Platforms/AbstractMySQLPlatformTestCase.php index 8e3ae57d8dc..1d69a9e6b4d 100644 --- a/tests/Platforms/AbstractMySQLPlatformTestCase.php +++ b/tests/Platforms/AbstractMySQLPlatformTestCase.php @@ -34,7 +34,7 @@ public function testGenerateMixedCaseTableCreate(): void $sql = $this->platform->getCreateTableSQL($table); self::assertEquals( - 'CREATE TABLE Foo (Bar INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + 'CREATE TABLE Foo (Bar INT NOT NULL)', array_shift($sql) ); } @@ -42,7 +42,7 @@ public function testGenerateMixedCaseTableCreate(): void public function getGenerateTableSql(): string { return 'CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL, ' - . 'PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB'; + . 'PRIMARY KEY(id))'; } /** @@ -52,8 +52,7 @@ public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ 'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL, ' - . 'UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA (foo, bar))' - . ' DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA (foo, bar))', ]; } @@ -206,7 +205,7 @@ public function getCreateTableColumnCommentsSQL(): array { return [ "CREATE TABLE test (id INT NOT NULL COMMENT 'This is a comment', " - . 'PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'PRIMARY KEY(id))', ]; } @@ -229,7 +228,7 @@ public function getCreateTableColumnTypeCommentsSQL(): array { return [ "CREATE TABLE test (id INT NOT NULL, data LONGTEXT NOT NULL COMMENT '(DC2Type:array)', " - . 'PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'PRIMARY KEY(id))', ]; } @@ -253,7 +252,7 @@ public function testChangeIndexWithForeignKeys(): void protected function getQuotedColumnInPrimaryKeySQL(): array { return ['CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, ' - . 'PRIMARY KEY(`create`)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'PRIMARY KEY(`create`))', ]; } @@ -264,8 +263,7 @@ protected function getQuotedColumnInIndexSQL(): array { return [ 'CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, ' - . 'INDEX IDX_22660D028FD6E0FB (`create`)) ' - . 'DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'INDEX IDX_22660D028FD6E0FB (`create`))', ]; } @@ -276,7 +274,7 @@ protected function getQuotedNameInIndexSQL(): array { return [ 'CREATE TABLE test (column1 VARCHAR(255) NOT NULL, ' - . 'INDEX `key` (column1)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'INDEX `key` (column1))', ]; } @@ -287,7 +285,7 @@ protected function getQuotedColumnInForeignKeySQL(): array { return [ 'CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, ' - . '`bar` VARCHAR(255) NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . '`bar` VARCHAR(255) NOT NULL)', 'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY (`create`, foo, `bar`)' . ' REFERENCES `foreign` (`create`, bar, `foo-bar`)', 'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY (`create`, foo, `bar`)' @@ -312,7 +310,7 @@ public function testCreateTableWithFulltextIndex(): void [ 'CREATE TABLE fulltext_table (text LONGTEXT NOT NULL, ' . 'FULLTEXT INDEX fulltext_text (text)) ' - . 'DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = MyISAM', + . 'ENGINE = MyISAM', ], $sql ); @@ -332,7 +330,7 @@ public function testCreateTableWithSpatialIndex(): void self::assertEquals( [ 'CREATE TABLE spatial_table (point LONGTEXT NOT NULL, SPATIAL INDEX spatial_text (point)) ' - . 'DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = MyISAM', + . 'ENGINE = MyISAM', ], $sql ); @@ -577,7 +575,7 @@ public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines(): [ 'CREATE TABLE foreign_table (id INT NOT NULL, fk_id INT NOT NULL, ' . 'INDEX IDX_5690FFE2A57719D0 (fk_id), PRIMARY KEY(id)) ' - . 'DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = MyISAM', + . 'ENGINE = MyISAM', ], $this->platform->getCreateTableSQL( $table, @@ -592,7 +590,7 @@ public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines(): [ 'CREATE TABLE foreign_table (id INT NOT NULL, fk_id INT NOT NULL, ' . 'INDEX IDX_5690FFE2A57719D0 (fk_id), PRIMARY KEY(id)) ' - . 'DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'ENGINE = InnoDB', 'ALTER TABLE foreign_table ADD CONSTRAINT FK_5690FFE2A57719D0 FOREIGN KEY (fk_id)' . ' REFERENCES foreign_table (id)', ], @@ -715,7 +713,7 @@ public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes(): vo . 'def_text_null LONGTEXT DEFAULT NULL, ' . 'def_blob LONGBLOB NOT NULL, ' . 'def_blob_null LONGBLOB DEFAULT NULL' - . ') DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . ')', ], $this->platform->getCreateTableSQL($table) ); @@ -970,8 +968,7 @@ public function testGetCreateTableSQLWithColumnCollation(): void self::assertSame( [ 'CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, ' - . 'column_collation VARCHAR(255) NOT NULL COLLATE `ascii_general_ci`) ' - . 'DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', + . 'column_collation VARCHAR(255) NOT NULL COLLATE `ascii_general_ci`)', ], $this->platform->getCreateTableSQL($table) ); diff --git a/tests/Schema/MySQLInheritCharsetTest.php b/tests/Schema/MySQLInheritCharsetTest.php index d0e684f6afe..9b4f6bb5c25 100644 --- a/tests/Schema/MySQLInheritCharsetTest.php +++ b/tests/Schema/MySQLInheritCharsetTest.php @@ -44,34 +44,18 @@ public function testTableOptions(): void { $platform = new MySQLPlatform(); - // default, no overrides + // no options $table = new Table('foobar', [new Column('aa', Type::getType('integer'))]); self::assertSame( - [ - 'CREATE TABLE foobar (aa INT NOT NULL)' - . ' DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', - ], + ['CREATE TABLE foobar (aa INT NOT NULL)'], $platform->getCreateTableSQL($table) ); - // explicit utf8 + // charset $table = new Table('foobar', [new Column('aa', Type::getType('integer'))]); $table->addOption('charset', 'utf8'); self::assertSame( - [ - 'CREATE TABLE foobar (aa INT NOT NULL)' - . ' DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', - ], - $platform->getCreateTableSQL($table) - ); - - // explicit utf8mb4 - $table = new Table('foobar', [new Column('aa', Type::getType('integer'))]); - $table->addOption('charset', 'utf8mb4'); - self::assertSame( - ['CREATE TABLE foobar (aa INT NOT NULL)' - . ' DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', - ], + ['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8'], $platform->getCreateTableSQL($table) ); }