Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove defaults for MySQL table charset, collation and engine #4644

Merged
merged 1 commit into from
Jun 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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()`.
Expand Down
62 changes: 24 additions & 38 deletions src/Platforms/MySQLPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use function is_string;
use function sprintf;
use function str_replace;
use function strcasecmp;
use function strtoupper;
use function trim;

Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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']);
Expand All @@ -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}
*/
Expand Down
2 changes: 0 additions & 2 deletions tests/Functional/Schema/MySQLSchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,13 @@ 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);

$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'));
}
Expand Down
33 changes: 15 additions & 18 deletions tests/Platforms/AbstractMySQLPlatformTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ 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)
);
}

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))';
}

/**
Expand All @@ -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))',
];
}

Expand Down Expand Up @@ -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))',
];
}

Expand All @@ -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))',
];
}

Expand All @@ -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`))',
];
}

Expand All @@ -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`))',
];
}

Expand All @@ -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))',
];
}

Expand All @@ -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`)'
Expand All @@ -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
);
Expand All @@ -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
);
Expand Down Expand Up @@ -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,
Expand All @@ -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)',
],
Expand Down Expand Up @@ -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)
);
Expand Down Expand Up @@ -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)
);
Expand Down
24 changes: 4 additions & 20 deletions tests/Schema/MySQLInheritCharsetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}
Expand Down