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

Quote collation on MySQL #3668

Merged
merged 1 commit into from
Sep 2, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
staudenmeir marked this conversation as resolved.
Show resolved Hide resolved
}

/**
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