diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php index a94c0d30a9b862e0cce98db86c26cb10f4160d04..e092a982a28dea671b0556003ba3cd04b5f533bf 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php @@ -64,7 +64,7 @@ public static function open(array &$connection_options = array()) { // Character set is added to dsn to ensure PDO uses the proper character // set when escaping. This has security implications. See // https://www.drupal.org/node/1201452 for further discussion. - $dsn .= ';charset=utf8mb4'; + $dsn .= ';charset=utf8'; if (!empty($connection_options['database'])) { $dsn .= ';dbname=' . $connection_options['database']; } @@ -92,13 +92,13 @@ public static function open(array &$connection_options = array()) { $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']); // Force MySQL to use the UTF-8 character set. Also set the collation, if a - // certain one has been set; otherwise, MySQL defaults to - // 'utf8mb4_general_ci' for utf8mb4. + // certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci' + // for UTF-8. if (!empty($connection_options['collation'])) { - $pdo->exec('SET NAMES utf8mb4 COLLATE ' . $connection_options['collation']); + $pdo->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']); } else { - $pdo->exec('SET NAMES utf8mb4'); + $pdo->exec('SET NAMES utf8'); } // Set MySQL init_commands if not already defined. Default Drupal's MySQL diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php index 6326bcf3831665dbc4f35599d3a1440dfb580eba..8237c79112c81f925a0820754cef2d3a73bd12ee 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php @@ -87,7 +87,7 @@ protected function createTableSql($name, $table) { // Provide defaults if needed. $table += array( 'mysql_engine' => 'InnoDB', - 'mysql_character_set' => 'utf8mb4', + 'mysql_character_set' => 'utf8', ); $sql = "CREATE TABLE {" . $name . "} (\n"; @@ -108,8 +108,8 @@ protected function createTableSql($name, $table) { $sql .= 'ENGINE = ' . $table['mysql_engine'] . ' DEFAULT CHARACTER SET ' . $table['mysql_character_set']; // By default, MySQL uses the default collation for new tables, which is - // 'utf8mb4_general_ci' for utf8mb4. If an alternate collation has been - // set, it needs to be explicitly specified. + // 'utf8_general_ci' for utf8. If an alternate collation has been set, it + // needs to be explicitly specified. // @see DatabaseConnection_mysql if (!empty($info['collation'])) { $sql .= ' COLLATE ' . $info['collation']; diff --git a/core/modules/aggregator/src/FeedStorageSchema.php b/core/modules/aggregator/src/FeedStorageSchema.php index 4d51bdb1e7e29912b0702fadecc59f428d06ba68..d251ed5f1ea019e04ba915c79f20107978a6d041 100644 --- a/core/modules/aggregator/src/FeedStorageSchema.php +++ b/core/modules/aggregator/src/FeedStorageSchema.php @@ -33,7 +33,7 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st break; case 'title': - $this->addSharedTableFieldIndex($storage_definition, $schema, TRUE); + $this->addSharedTableFieldUniqueKey($storage_definition, $schema); break; } } diff --git a/core/modules/block_content/src/BlockContentStorageSchema.php b/core/modules/block_content/src/BlockContentStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..c1674aef125d616d078ff028d3e93eb9987103b5 --- /dev/null +++ b/core/modules/block_content/src/BlockContentStorageSchema.php @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Contains \Drupal\block_content\BlockContentStorageSchema. + */ + +namespace Drupal\block_content; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema; +use Drupal\Core\Field\FieldStorageDefinitionInterface; + +/** + * Defines the block content schema handler. + */ +class BlockContentStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + $schema['block_content_field_data']['unique keys'] += array( + 'block_content__info' => array('info', 'langcode'), + ); + + return $schema; + } + + /** + * {@inheritdoc} + */ + protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $storage_definition, $table_name, array $column_mapping) { + $schema = parent::getSharedTableFieldSchema($storage_definition, $table_name, $column_mapping); + $field_name = $storage_definition->getName(); + + if ($table_name == 'block_content_field_data') { + switch ($field_name) { + case 'info': + // Improves the performance of the block_content__info index defined + // in getEntitySchema(). + $schema['fields'][$field_name]['not null'] = TRUE; + break; + } + } + + return $schema; + } + +} diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php index cf5e21af546ffaf733d30d95220e4bc7315a3db5..82e16f52da1e58310ce814cf53da1b2fddca4e91 100644 --- a/core/modules/block_content/src/Entity/BlockContent.php +++ b/core/modules/block_content/src/Entity/BlockContent.php @@ -23,6 +23,7 @@ * bundle_label = @Translation("Custom block type"), * handlers = { * "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage", + * "storage_schema" = "Drupal\block_content\BlockContentStorageSchema", * "access" = "Drupal\block_content\BlockContentAccessControlHandler", * "list_builder" = "Drupal\block_content\BlockContentListBuilder", * "view_builder" = "Drupal\block_content\BlockContentViewBuilder", diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php index 511c5d594036692a03f3bb488c5a5689acfd2a95..8a5bd427011c6e8103ad163299f4632dbb1a585a 100644 --- a/core/modules/file/src/Entity/File.php +++ b/core/modules/file/src/Entity/File.php @@ -252,8 +252,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('URI')) ->setDescription(t('The URI to access the file (either local or remote).')) ->setSetting('max_length', 255) - ->setSetting('case_sensitive', TRUE) - ->addConstraint('FileUriUnique'); + ->setSetting('case_sensitive', TRUE); $fields['filemime'] = BaseFieldDefinition::create('string') ->setLabel(t('File MIME type')) diff --git a/core/modules/file/src/FileStorageSchema.php b/core/modules/file/src/FileStorageSchema.php index e0856f4311f41fab1c39f070b9a983f970eb82d6..f253020bc5c66596c05c2e1e770693daf46e0e31 100644 --- a/core/modules/file/src/FileStorageSchema.php +++ b/core/modules/file/src/FileStorageSchema.php @@ -30,7 +30,7 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st break; case 'uri': - $this->addSharedTableFieldIndex($storage_definition, $schema, TRUE); + $this->addSharedTableFieldUniqueKey($storage_definition, $schema, TRUE); break; } } diff --git a/core/modules/file/src/Plugin/Validation/Constraint/FileUriUnique.php b/core/modules/file/src/Plugin/Validation/Constraint/FileUriUnique.php deleted file mode 100644 index 1d795056df6a3727ee973af67c11c8bc54ce2ae6..0000000000000000000000000000000000000000 --- a/core/modules/file/src/Plugin/Validation/Constraint/FileUriUnique.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\file\Plugin\Validation\Constraint\FileUriUnique. - */ - -namespace Drupal\file\Plugin\Validation\Constraint; - -use Symfony\Component\Validator\Constraint; - -/** - * Supports validating file URIs. - * - * @Plugin( - * id = "FileUriUnique", - * label = @Translation("File URI", context = "Validation") - * ) - */ -class FileUriUnique extends Constraint { - - public $message = 'The file %value already exists. Enter a unique file URI.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() { - return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator'; - } - -} diff --git a/core/modules/file/src/Tests/SaveTest.php b/core/modules/file/src/Tests/SaveTest.php index 7b4bb180c31b4985c56c012ef7d646639ac57ac4..666b08de91bb22c128a2dd26c078b0844c5b785b 100644 --- a/core/modules/file/src/Tests/SaveTest.php +++ b/core/modules/file/src/Tests/SaveTest.php @@ -8,9 +8,6 @@ namespace Drupal\file\Tests; use Drupal\file\Entity\File; -use Drupal\Core\Entity\EntityStorageException; -use Drupal\Core\Entity\EntityStorageInterface; -use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; /** * File saving tests. @@ -60,27 +57,16 @@ function testFileSave() { // Try to insert a second file with the same name apart from case insensitivity // to ensure the 'uri' index allows for filenames with different cases. - $uppercase_values = array( + $uppercase_file = File::create(array( 'uid' => 1, 'filename' => 'DRUPLICON.txt', 'uri' => 'public://DRUPLICON.txt', 'filemime' => 'text/plain', 'status' => FILE_STATUS_PERMANENT, - ); - $uppercase_file = File::create($uppercase_values); + )); file_put_contents($uppercase_file->getFileUri(), 'hello world'); - $violations = $uppercase_file->validate(); - $this->assertEqual(count($violations), 0, 'No violations when adding an URI with an existing filename in upper case.'); $uppercase_file->save(); - // Ensure the database URI uniqueness constraint is triggered. - $uppercase_file_duplicate = File::create($uppercase_values); - file_put_contents($uppercase_file_duplicate->getFileUri(), 'hello world'); - $violations = $uppercase_file_duplicate->validate(); - $this->assertEqual(count($violations), 1); - $this->assertEqual($violations[0]->getMessage(), t('The file %value already exists. Enter a unique file URI.', [ - '%value' => $uppercase_file_duplicate->getFileUri(), - ])); // Ensure that file URI entity queries are case sensitive. $fids = \Drupal::entityQuery('file') ->condition('uri', $uppercase_file->getFileUri()) diff --git a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php index f1507a3b87e547f534553252c027ed464f2ae022..42488c7d534ff6ae84b67fa662f29c24f03c6111 100644 --- a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php +++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php @@ -261,12 +261,6 @@ protected function ensureTables() { foreach ($this->migration->getSourcePlugin()->getIds() as $id_definition) { $mapkey = 'sourceid' . $count++; $source_id_schema[$mapkey] = $this->getFieldSchema($id_definition); - - // With InnoDB, utf8mb4-based primary keys can't be over 191 characters. - // Use ASCII-based primary keys instead. - if (isset($source_id_schema[$mapkey]['type']) && $source_id_schema[$mapkey]['type'] == 'varchar') { - $source_id_schema[$mapkey]['type'] = 'varchar_ascii'; - } $pks[] = $mapkey; } diff --git a/core/modules/migrate_drupal/src/Tests/Table/d6/System.php b/core/modules/migrate_drupal/src/Tests/Table/d6/System.php index 5bf482f9f78a6957631ddac38f53bfae00f94220..23bcbd66847c7f78254e4c749958a87434f9bb47 100644 --- a/core/modules/migrate_drupal/src/Tests/Table/d6/System.php +++ b/core/modules/migrate_drupal/src/Tests/Table/d6/System.php @@ -26,7 +26,7 @@ public function load() { ), 'fields' => array( 'filename' => array( - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'not null' => TRUE, 'length' => '255', 'default' => '', @@ -916,4 +916,4 @@ public function load() { } } -#e15f00f5d9b1c571ee015c40f8fc7b00 +#8867fc0eccc6c8439bff0a269ec597ae diff --git a/core/modules/node/src/Tests/NodeViewTest.php b/core/modules/node/src/Tests/NodeViewTest.php index c60d44a0a950a5a2c2370a08c769e7a25cf20065..2281dd8b816cd7ee6a6da57df9fd42db8d3e1706 100644 --- a/core/modules/node/src/Tests/NodeViewTest.php +++ b/core/modules/node/src/Tests/NodeViewTest.php @@ -33,16 +33,4 @@ public function testHtmlHeadLinks() { $this->assertEqual($result[0]['href'], $node->url()); } - /** - * Tests that we store and retrieve multi-byte UTF-8 characters correctly. - */ - public function testMultiByteUtf8() { - $title = 'ðŸ'; - $this->assertTrue(mb_strlen($title, 'utf-8') < strlen($title), 'Title has multi-byte characters.'); - $node = $this->drupalCreateNode(array('title' => $title)); - $this->drupalGet($node->urlInfo()); - $result = $this->xpath('//span[contains(@class, "field-name-title")]'); - $this->assertEqual((string) $result[0], $title, 'The passed title was returned.'); - } - } diff --git a/core/modules/system/src/Tests/Database/RegressionTest.php b/core/modules/system/src/Tests/Database/RegressionTest.php index 6f87d2a6444b1efdd241957254c5e6414f04b53d..81f962d0da1e29c635bc1661a37c704f7c434cf0 100644 --- a/core/modules/system/src/Tests/Database/RegressionTest.php +++ b/core/modules/system/src/Tests/Database/RegressionTest.php @@ -26,16 +26,16 @@ class RegressionTest extends DatabaseTestBase { */ function testRegression_310447() { // That's a 255 character UTF-8 string. - $job = str_repeat("é", 255); + $name = str_repeat("é", 255); db_insert('test') ->fields(array( - 'name' => $this->randomMachineName(), + 'name' => $name, 'age' => 20, - 'job' => $job, + 'job' => 'Dancer', ))->execute(); - $from_database = db_query('SELECT job FROM {test} WHERE job = :job', array(':job' => $job))->fetchField(); - $this->assertIdentical($job, $from_database, 'The database handles UTF-8 characters cleanly.'); + $from_database = db_query('SELECT name FROM {test} WHERE name = :name', array(':name' => $name))->fetchField(); + $this->assertIdentical($name, $from_database, 'The database handles UTF-8 characters cleanly.'); } /** diff --git a/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php index df1b0b6530c1cb10b8abdbd896e090bd69967c38..9a234edd5b2d40950998e2c7989e8f60a6257950 100644 --- a/core/modules/system/src/Tests/Database/SchemaTest.php +++ b/core/modules/system/src/Tests/Database/SchemaTest.php @@ -72,7 +72,7 @@ function testSchema() { $columns = db_query('SHOW FULL COLUMNS FROM {test_table}'); foreach ($columns as $column) { if ($column->Field == 'test_field_string') { - $string_check = ($column->Collation == 'utf8mb4_general_ci'); + $string_check = ($column->Collation == 'utf8_general_ci'); } if ($column->Field == 'test_field_string_ascii') { $string_ascii_check = ($column->Collation == 'ascii_general_ci'); diff --git a/core/modules/system/tests/modules/database_test/database_test.install b/core/modules/system/tests/modules/database_test/database_test.install index cfd72d5fe3578ce267c11f1a7e3071ee98c25cfa..7c74c1c4be64492d86a3d2c46d11ccc0ba3ba6ee 100644 --- a/core/modules/system/tests/modules/database_test/database_test.install +++ b/core/modules/system/tests/modules/database_test/database_test.install @@ -24,7 +24,7 @@ function database_test_schema() { ), 'name' => array( 'description' => "A person's name", - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -75,7 +75,7 @@ function database_test_schema() { ), 'job' => array( 'description' => "The person's job", - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -106,7 +106,7 @@ function database_test_schema() { ), 'job' => array( 'description' => "The person's job", - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -197,7 +197,7 @@ function database_test_schema() { ), 'name' => array( 'description' => "A person's name.", - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => FALSE, 'default' => '', @@ -228,7 +228,7 @@ function database_test_schema() { ), 'name' => array( 'description' => "A person's name.", - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => FALSE, 'default' => '', diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php index d6b6c59ea129e29ec06acf09036de0bcac5caad3..7e057d4b4aeb9b1d9512457e1a2208dabdea9ef3 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php @@ -45,10 +45,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['id'] = BaseFieldDefinition::create('string') ->setLabel(t('ID')) ->setDescription(t('The ID of the test entity.')) - ->setReadOnly(TRUE) - // In order to work around the InnoDB 191 character limit on utf8mb4 - // primary keys, we set the character set for the field to ASCII. - ->setSetting('is_ascii', TRUE); + ->setReadOnly(TRUE); return $fields; } diff --git a/core/modules/user/src/UserStorageSchema.php b/core/modules/user/src/UserStorageSchema.php index 6247b10db1579e550cc6808601fa8adb1557476c..447469d34e948f018a89c159b047968ad502b16b 100644 --- a/core/modules/user/src/UserStorageSchema.php +++ b/core/modules/user/src/UserStorageSchema.php @@ -52,9 +52,6 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st // Improves the performance of the user__name index defined // in getEntitySchema(). $schema['fields'][$field_name]['not null'] = TRUE; - // Make sure the field is no longer than 191 characters so we can - // add a unique constraint in MySQL. - $schema['fields'][$field_name]['length'] = USERNAME_MAX_LENGTH; break; case 'mail': diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 7a3e84329c7cbb04303e188d4415e0d72024da77..1e6de88c236d431932431bddebd077db1c105350 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -26,8 +26,6 @@ /** * Maximum length of username text field. - * - * Keep this under 191 characters so we can use a unique constraint in MySQL. */ const USERNAME_MAX_LENGTH = 60; diff --git a/core/modules/views/src/Tests/ViewTestData.php b/core/modules/views/src/Tests/ViewTestData.php index 34fcd444dde1b903a09b919559ac6219005f14af..4b5340ea960324424b495b5adf75767f296efed7 100644 --- a/core/modules/views/src/Tests/ViewTestData.php +++ b/core/modules/views/src/Tests/ViewTestData.php @@ -75,7 +75,7 @@ public static function schemaDefinition() { ), 'name' => array( 'description' => "A person's name", - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', diff --git a/core/scripts/dump-database-d6.sh b/core/scripts/dump-database-d6.sh index d0a89d7b1ce8b33d314740d92366f679300f3cf5..ace93d9d34f60ecb27b39ced9c320f9724b2f2cd 100644 --- a/core/scripts/dump-database-d6.sh +++ b/core/scripts/dump-database-d6.sh @@ -53,11 +53,6 @@ $schema = drupal_get_schema(); ksort($schema); -// Override the field type of the filename primary key to bypass the -// InnoDB 191 character limitation. -if (isset($schema['system']['primary key']) && $schema['system']['primary key'] == 'filename' && isset($schema['system']['fields']['filename']['type']) && $schema['system']['fields']['filename']['type'] == 'varchar') { - $schema['system']['fields']['filename']['type'] = 'varchar_ascii'; -} // Export all the tables in the schema. foreach ($schema as $table => $data) { // Remove descriptions to save time and code. diff --git a/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php b/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php index 05762353d33f35c28877dc96fdb3d89555e8df1d..54cd70de76634f5a44b57d8a9753f5327571be86 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php +++ b/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php @@ -172,7 +172,7 @@ public function routingTableDefinition() { 'fields' => array( 'name' => array( 'description' => 'Primary Key: Machine name of this route', - 'type' => 'varchar_ascii', + 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index d894b11729f25771e7654afdf8f23bb8ea9732d5..ef839391355bc17c66110c51ce98134da82ad6c8 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -75,7 +75,7 @@ * 'host' => 'localhost', * 'port' => 3306, * 'prefix' => 'myprefix_', - * 'collation' => 'utf8mb4_general_ci', + * 'collation' => 'utf8_general_ci', * ); * @endcode * @@ -127,7 +127,7 @@ * 'password' => 'password', * 'host' => 'localhost', * 'prefix' => 'main_', - * 'collation' => 'utf8mb4_general_ci', + * 'collation' => 'utf8_general_ci', * ); * @endcode *