Skip to content

Commit

Permalink
Merge pull request #3668 from staudenmeir/mysql-collation
Browse files Browse the repository at this point in the history
Quote collation on MySQL
  • Loading branch information
morozov authored Sep 2, 2019
2 parents d9b377c + 733b64b commit c98c548
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 20 deletions.
10 changes: 9 additions & 1 deletion lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ private function buildTableOptions(array $options)
$options['collate'] = $options['charset'] . '_unicode_ci';
}

$tableOptions[] = sprintf('COLLATE %s', $options['collate']);
$tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collate']);

// Engine
if (! isset($options['engine'])) {
Expand Down Expand Up @@ -965,6 +965,14 @@ public function getColumnCharsetDeclarationSQL($charset)
return 'CHARACTER SET ' . $charset;
}

/**
* {@inheritDoc}
*/
public function getColumnCollationDeclarationSQL($collation)
{
return 'COLLATE ' . $this->quoteSingleIdentifier($collation);
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\BlobType;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\Tests\Types\MySqlPointType;
Expand Down Expand Up @@ -275,6 +276,7 @@ public function testColumnCollation() : void
$table->addColumn('text', 'text');
$table->addColumn('foo', 'text')->setPlatformOption('collation', 'latin1_swedish_ci');
$table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci');
$table->addColumn('baz', 'text')->setPlatformOption('collation', 'binary');
$this->schemaManager->dropAndCreateTable($table);

$columns = $this->schemaManager->listTableColumns('test_collation');
Expand All @@ -283,6 +285,7 @@ public function testColumnCollation() : void
self::assertEquals('latin1_swedish_ci', $columns['text']->getPlatformOption('collation'));
self::assertEquals('latin1_swedish_ci', $columns['foo']->getPlatformOption('collation'));
self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation'));
self::assertInstanceOf(BlobType::class, $columns['baz']->getType());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ public function testGenerateMixedCaseTableCreate() : void
$table->addColumn('Bar', 'integer');

$sql = $this->platform->getCreateTableSQL($table);
self::assertEquals('CREATE TABLE Foo (Bar INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB', array_shift($sql));
self::assertEquals('CREATE TABLE Foo (Bar INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB', 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';
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';
}

/**
* @return string[]
*/
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'];
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'];
}

/**
Expand Down Expand Up @@ -209,7 +209,7 @@ public function testGetDateTimeTypeDeclarationSql() : void
*/
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"];
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"];
}

/**
Expand All @@ -225,7 +225,7 @@ public function getAlterTableColumnCommentsSQL() : array
*/
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"];
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"];
}

/**
Expand All @@ -250,23 +250,23 @@ 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'];
return ['CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, PRIMARY KEY(`create`)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB'];
}

/**
* @return string[]
*/
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'];
return ['CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, INDEX IDX_22660D028FD6E0FB (`create`)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB'];
}

/**
* @return string[]
*/
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'];
return ['CREATE TABLE test (column1 VARCHAR(255) NOT NULL, INDEX `key` (column1)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB'];
}

/**
Expand All @@ -275,7 +275,7 @@ protected function getQuotedNameInIndexSQL() : array
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',
'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',
'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`) REFERENCES foo (`create`, bar, `foo-bar`)',
'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY (`create`, foo, `bar`) REFERENCES `foo-bar` (`create`, bar, `foo-bar`)',
Expand All @@ -293,7 +293,7 @@ public function testCreateTableWithFulltextIndex() : void
$index->addFlag('fulltext');

$sql = $this->platform->getCreateTableSQL($table);
self::assertEquals(['CREATE TABLE fulltext_table (text LONGTEXT NOT NULL, FULLTEXT INDEX fulltext_text (text)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = MyISAM'], $sql);
self::assertEquals(['CREATE TABLE fulltext_table (text LONGTEXT NOT NULL, FULLTEXT INDEX fulltext_text (text)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = MyISAM'], $sql);
}

public function testCreateTableWithSpatialIndex() : void
Expand All @@ -307,7 +307,7 @@ public function testCreateTableWithSpatialIndex() : void
$index->addFlag('spatial');

$sql = $this->platform->getCreateTableSQL($table);
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'], $sql);
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'], $sql);
}

public function testClobTypeDeclarationSQL() : void
Expand Down Expand Up @@ -571,7 +571,7 @@ public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines()
$table->addOption('engine', 'MyISAM');

self::assertSame(
['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'],
['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'],
$this->platform->getCreateTableSQL(
$table,
AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS
Expand All @@ -583,7 +583,7 @@ public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines()

self::assertSame(
[
'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',
'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',
'ALTER TABLE foreign_table ADD CONSTRAINT FK_5690FFE2A57719D0 FOREIGN KEY (fk_id) REFERENCES foreign_table (id)',
],
$this->platform->getCreateTableSQL(
Expand Down Expand Up @@ -708,7 +708,7 @@ public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes() : v
$table->addColumn('def_blob_null', 'blob', ['notnull' => false, 'default' => 'def']);

self::assertSame(
['CREATE TABLE text_blob_default_value (def_text LONGTEXT NOT NULL, 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'],
['CREATE TABLE text_blob_default_value (def_text LONGTEXT NOT NULL, 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 @@ -979,7 +979,7 @@ public function testSupportsColumnCollation() : void
public function testColumnCollationDeclarationSQL() : void
{
self::assertSame(
'COLLATE ascii_general_ci',
'COLLATE `ascii_general_ci`',
$this->platform->getColumnCollationDeclarationSQL('ascii_general_ci')
);
}
Expand All @@ -991,7 +991,7 @@ public function testGetCreateTableSQLWithColumnCollation() : void
$table->addColumn('column_collation', 'string')->setPlatformOption('collation', 'ascii_general_ci');

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'],
['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'],
$this->platform->getCreateTableSQL($table),
'Column "no_collation" will use the default collation from the table/database and "column_collation" overwrites the collation on this column'
);
Expand Down
6 changes: 3 additions & 3 deletions tests/Doctrine/Tests/DBAL/Schema/MySqlInheritCharsetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,23 @@ public function testTableOptions() : void
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
self::assertSame(
$platform->getCreateTableSQL($table),
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB']
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB']
);

// explicit utf8
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
$table->addOption('charset', 'utf8');
self::assertSame(
$platform->getCreateTableSQL($table),
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB']
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB']
);

// explicit utf8mb4
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
$table->addOption('charset', 'utf8mb4');
self::assertSame(
$platform->getCreateTableSQL($table),
['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 utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB']
);
}

Expand Down

0 comments on commit c98c548

Please sign in to comment.