diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index cc89fa9..4968087 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -445,6 +445,9 @@ field.storage_settings.string: case_sensitive: type: boolean label: 'Case sensitive' + is_ascii: + type: boolean + label: 'Contains US ASCII characters only' field.field_settings.string: type: mapping diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index b1144e4..27460e4 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -441,7 +441,7 @@ public function schemaDefinition() { 'fields' => array( 'cid' => array( 'description' => 'Primary Key: Unique cache ID.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -482,7 +482,7 @@ public function schemaDefinition() { ), 'checksum' => array( 'description' => 'The tag invalidation checksum when this entry was saved.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, ), diff --git a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php index cc882ee..14b34ec 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php +++ b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php @@ -175,7 +175,7 @@ public function schemaDefinition() { 'fields' => array( 'tag' => array( 'description' => 'Namespace-prefixed tag string.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', diff --git a/core/lib/Drupal/Core/Config/DatabaseStorage.php b/core/lib/Drupal/Core/Config/DatabaseStorage.php index 6c33273..646a1d5 100644 --- a/core/lib/Drupal/Core/Config/DatabaseStorage.php +++ b/core/lib/Drupal/Core/Config/DatabaseStorage.php @@ -192,14 +192,14 @@ protected static function schemaDefinition() { 'fields' => array( 'collection' => array( 'description' => 'Primary Key: Config object collection.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', ), 'name' => array( 'description' => 'Primary Key: Config object name.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php index d0aba49..5cb6248 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php @@ -144,6 +144,9 @@ protected function createFieldSql($name, $spec) { if (!empty($spec['binary'])) { $sql .= ' BINARY'; } + if (isset($spec['type']) && $spec['type'] == 'varchar_ascii') { + $sql .= ' CHARACTER SET ascii COLLATE ascii_general_ci'; + } } elseif (isset($spec['precision']) && isset($spec['scale'])) { $sql .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')'; @@ -218,6 +221,8 @@ public function getFieldTypeMap() { // database types back into schema types. // $map does not use drupal_static as its value never changes. static $map = array( + 'varchar_ascii:normal' => 'VARCHAR', + 'varchar:normal' => 'VARCHAR', 'char:normal' => 'CHAR', diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php index 506baa8..5b70b1b 100644 --- a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php @@ -363,6 +363,7 @@ function getFieldTypeMap() { // database types back into schema types. // $map does not use drupal_static as its value never changes. static $map = array( + 'varchar_ascii:normal' => 'varchar', 'varchar:normal' => 'varchar', 'char:normal' => 'character', diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php index 6673d1f..897de79 100644 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php @@ -207,6 +207,8 @@ public function getFieldTypeMap() { // database types back into schema types. // $map does not use drupal_static as its value never changes. static $map = array( + 'varchar_ascii:normal' => 'VARCHAR', + 'varchar:normal' => 'VARCHAR', 'char:normal' => 'CHAR', diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index 6fb4ddf..b066969 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -1568,7 +1568,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor } else { $id_schema = array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'description' => 'The entity id this data is attached to', @@ -1601,7 +1601,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor 'description' => $description_current, 'fields' => array( 'bundle' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', @@ -1617,7 +1617,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor 'entity_id' => $id_schema, 'revision_id' => $revision_id_schema, 'langcode' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 32, 'not null' => TRUE, 'default' => '', diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php index ca54aa8..21d7090 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -133,7 +133,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) $columns = array( 'target_id' => array( 'description' => 'The ID of the target entity.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', // If the target entities act as bundles for another entity type, // their IDs should not exceed the maximum length for bundles. 'length' => $target_type_info->getBundleOf() ? EntityTypeInterface::BUNDLE_MAX_LENGTH : 255, diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php index 9ab60a4..b7ce7fb 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php @@ -44,6 +44,7 @@ class LanguageItem extends FieldItemBase { public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties['value'] = DataDefinition::create('string') ->setLabel(t('Language code')) + ->setSetting('is_ascii', TRUE) ->setRequired(TRUE); $properties['language'] = DataReferenceDefinition::create('language') @@ -75,6 +76,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) 'value' => array( 'type' => 'varchar', 'length' => 12, + 'is_ascii' => TRUE, ), ), ); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php index 8817c87..2329c86 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php @@ -32,6 +32,7 @@ class StringItem extends StringItemBase { public static function defaultStorageSettings() { return array( 'max_length' => 255, + 'is_ascii' => FALSE, ) + parent::defaultStorageSettings(); } @@ -42,7 +43,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) return array( 'columns' => array( 'value' => array( - 'type' => 'varchar', + 'type' => $field_definition->getSetting('is_ascii') === TRUE ? 'varchar_ascii' : 'varchar', 'length' => (int) $field_definition->getSetting('max_length'), 'binary' => $field_definition->getSetting('case_sensitive'), ), diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php index 84d1ec5..1bdd10e 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php @@ -30,6 +30,7 @@ class UuidItem extends StringItem { public static function defaultStorageSettings() { return array( 'max_length' => 128, + 'is_ascii' => TRUE, ) + parent::defaultStorageSettings(); } diff --git a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php index 2ce68f7..659d6be 100644 --- a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php +++ b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php @@ -1193,7 +1193,7 @@ protected static function schemaDefinition() { 'fields' => array( 'menu_name' => array( 'description' => "The menu name. All links with the same menu name (such as 'tools') are part of the same menu.", - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 32, 'not null' => TRUE, 'default' => '', @@ -1206,20 +1206,20 @@ protected static function schemaDefinition() { ), 'id' => array( 'description' => 'Unique machine name: the plugin ID.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, ), 'parent' => array( 'description' => 'The plugin ID for the parent of this link.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', ), 'route_name' => array( 'description' => 'The machine name of a defined Symfony Route this menu item represents.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, ), 'route_param_key' => array( @@ -1281,7 +1281,7 @@ protected static function schemaDefinition() { ), 'provider' => array( 'description' => 'The name of the module that generated this link.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, 'not null' => TRUE, 'default' => 'system', diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php index 6f3d2e2..a5ed081 100644 --- a/core/modules/aggregator/src/Entity/Feed.php +++ b/core/modules/aggregator/src/Entity/Feed.php @@ -226,6 +226,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['hash'] = BaseFieldDefinition::create('string') ->setLabel(t('Hash')) + ->setSetting('is_ascii', TRUE) ->setDescription(t('Calculated hash of the feed data, used for validating cache.')); $fields['etag'] = BaseFieldDefinition::create('string') diff --git a/core/modules/aggregator/src/FeedInterface.php b/core/modules/aggregator/src/FeedInterface.php index 29c6782..e678c90 100644 --- a/core/modules/aggregator/src/FeedInterface.php +++ b/core/modules/aggregator/src/FeedInterface.php @@ -170,7 +170,8 @@ public function getHash(); * Sets the calculated hash of the feed data, used for validating cache. * * @param string $hash - * A string containing the calculated hash of the feed. + * A string containing the calculated hash of the feed. Must contain + * US ASCII characters only. * * @return \Drupal\aggregator\FeedInterface * The class instance that this method is called on. diff --git a/core/modules/ban/ban.install b/core/modules/ban/ban.install index 7a5494f..b2ea1fe 100644 --- a/core/modules/ban/ban.install +++ b/core/modules/ban/ban.install @@ -20,7 +20,7 @@ function ban_schema() { ), 'ip' => array( 'description' => 'IP address', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 40, 'not null' => TRUE, 'default' => '', diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 64aa6bd..66ab638 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -46,17 +46,18 @@ function comment_schema() { 'description' => 'The entity_id of the entity for which the statistics are compiled.', ), 'entity_type' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'not null' => TRUE, 'default' => 'node', 'length' => EntityTypeInterface::ID_MAX_LENGTH, 'description' => 'The entity_type of the entity to which this comment is a reply.', ), 'field_name' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'not null' => TRUE, 'default' => '', 'length' => FieldStorageConfig::NAME_MAX_LENGTH, + 'is_ascii' => TRUE, 'description' => 'The field_name of the field that was used to add this comment.', ), 'cid' => array( diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index 798a69f..f83f54b 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -303,6 +303,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['entity_type'] = BaseFieldDefinition::create('string') ->setLabel(t('Entity type')) ->setDescription(t('The entity type to which this comment is attached.')) + ->setSetting('is_ascii', TRUE) ->setSetting('max_length', EntityTypeInterface::ID_MAX_LENGTH); $fields['comment_type'] = BaseFieldDefinition::create('entity_reference') @@ -313,6 +314,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['field_name'] = BaseFieldDefinition::create('string') ->setLabel(t('Comment field name')) ->setDescription(t('The field name through which this comment was added.')) + ->setSetting('is_ascii', TRUE) ->setSetting('max_length', FieldStorageConfig::NAME_MAX_LENGTH); return $fields; diff --git a/core/modules/dblog/dblog.install b/core/modules/dblog/dblog.install index b7454c1..1119c47 100644 --- a/core/modules/dblog/dblog.install +++ b/core/modules/dblog/dblog.install @@ -25,7 +25,7 @@ function dblog_schema() { 'description' => 'The {users}.uid of the user who triggered the event.', ), 'type' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'default' => '', @@ -69,7 +69,7 @@ function dblog_schema() { 'description' => 'URL of referring page.', ), 'hostname' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', diff --git a/core/modules/file/file.install b/core/modules/file/file.install index 6e188c6..fd3503c 100644 --- a/core/modules/file/file.install +++ b/core/modules/file/file.install @@ -20,21 +20,21 @@ function file_schema() { ), 'module' => array( 'description' => 'The name of the module that is using the file.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, 'not null' => TRUE, 'default' => '', ), 'type' => array( 'description' => 'The name of the object type in which the file is used.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'default' => '', ), 'id' => array( 'description' => 'The primary key of the object using the file.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'default' => 0, diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php index 42de0ae..ff38ab3 100644 --- a/core/modules/file/src/Entity/File.php +++ b/core/modules/file/src/Entity/File.php @@ -254,6 +254,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['filemime'] = BaseFieldDefinition::create('string') ->setLabel(t('File MIME type')) + ->setSetting('is_ascii', TRUE) ->setDescription(t("The file's MIME type.")); $fields['filesize'] = BaseFieldDefinition::create('integer') diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index 81aadf5..0258767 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -67,14 +67,14 @@ function locale_schema() { 'description' => 'The original string in English.', ), 'context' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'The context this string applies to.', ), 'version' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 20, 'not null' => TRUE, 'default' => 'none', @@ -103,7 +103,7 @@ function locale_schema() { 'description' => 'Translation string value in this language.', ), 'language' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 12, 'not null' => TRUE, 'default' => '', @@ -142,7 +142,7 @@ function locale_schema() { 'description' => 'Unique identifier of this string.', ), 'type' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 50, 'not null' => TRUE, 'default' => '', @@ -156,7 +156,7 @@ function locale_schema() { 'description' => 'Type dependent location information (file name, path, etc).', ), 'version' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 20, 'not null' => TRUE, 'default' => 'none', @@ -180,14 +180,14 @@ function locale_schema() { 'description' => 'File import status information for interface translation files.', 'fields' => array( 'project' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => '255', 'not null' => TRUE, 'default' => '', 'description' => 'A unique short name to identify the project the file belongs to.', ), 'langcode' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => '12', 'not null' => TRUE, 'default' => '', diff --git a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php index 5570a2a..d6610a0 100644 --- a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php +++ b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php @@ -250,6 +250,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Bundle')) ->setDescription(t('The content menu link bundle.')) ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH) + ->setSetting('is_ascii', TRUE) ->setReadOnly(TRUE); $fields['title'] = BaseFieldDefinition::create('string') @@ -291,7 +292,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['menu_name'] = BaseFieldDefinition::create('string') ->setLabel(t('Menu name')) ->setDescription(t('The menu name. All links with the same menu name (such as "tools") are part of the same menu.')) - ->setDefaultValue('tools'); + ->setDefaultValue('tools') + ->setSetting('is_ascii', TRUE); $fields['link'] = BaseFieldDefinition::create('link') ->setLabel(t('Link')) diff --git a/core/modules/node/node.install b/core/modules/node/node.install index fa0d245..a7cb55e 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -54,7 +54,7 @@ function node_schema() { ), 'langcode' => array( 'description' => 'The {language}.langcode of this node.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 12, 'not null' => TRUE, 'default' => '', @@ -75,7 +75,7 @@ function node_schema() { ), 'realm' => array( 'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', diff --git a/core/modules/search/search.install b/core/modules/search/search.install index a298f2f..f920aa5 100644 --- a/core/modules/search/search.install +++ b/core/modules/search/search.install @@ -20,14 +20,14 @@ function search_schema() { 'description' => 'Search item ID, e.g. node ID for nodes.', ), 'langcode' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => '12', 'not null' => TRUE, 'description' => 'The {languages}.langcode of the item variant.', 'default' => '', ), 'type' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'description' => 'Type of item, e.g. node.', @@ -67,14 +67,14 @@ function search_schema() { 'description' => 'The {search_dataset}.sid of the searchable item to which the word belongs.', ), 'langcode' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => '12', 'not null' => TRUE, 'description' => 'The {languages}.langcode of the item variant.', 'default' => '', ), 'type' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'description' => 'The {search_dataset}.type of the searchable item to which the word belongs.', diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install index c1a6883..2a90306 100644 --- a/core/modules/shortcut/shortcut.install +++ b/core/modules/shortcut/shortcut.install @@ -20,7 +20,7 @@ function shortcut_schema() { 'description' => 'The {users}.uid for this set.', ), 'set_name' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 32, 'not null' => TRUE, 'default' => '', diff --git a/core/modules/simpletest/simpletest.install b/core/modules/simpletest/simpletest.install index 47c0ee2..b4792ea 100644 --- a/core/modules/simpletest/simpletest.install +++ b/core/modules/simpletest/simpletest.install @@ -108,7 +108,7 @@ function simpletest_schema() { 'description' => 'Test ID, messages belonging to the same ID are reported together', ), 'test_class' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -127,14 +127,14 @@ function simpletest_schema() { 'description' => 'The message itself.', ), 'message_group' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'The message group this message belongs to. For example: warning, browser, user.', ), 'function' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', diff --git a/core/modules/system/database.api.php b/core/modules/system/database.api.php index a01ff59..f3d7fe2 100644 --- a/core/modules/system/database.api.php +++ b/core/modules/system/database.api.php @@ -256,6 +256,8 @@ * 'float', 'numeric', or 'serial'. Most types just map to the according * database engine specific datatypes. Use 'serial' for auto incrementing * fields. This will expand to 'INT auto_increment' on MySQL. + * A special 'varchar_ascii' type is also available for limiting machine + * name field to US ASCII characters. * - 'mysql_type', 'pgsql_type', 'sqlite_type', etc.: If you need to * use a record type not included in the officially supported list * of types above, you can specify a type for each database diff --git a/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php index a59b9d9..188cfbf 100644 --- a/core/modules/system/src/Tests/Database/SchemaTest.php +++ b/core/modules/system/src/Tests/Database/SchemaTest.php @@ -49,6 +49,11 @@ function testSchema() { 'default' => "'\"funky default'\"", 'description' => 'Schema column description for string.', ), + 'test_field_string_ascii' => array( + 'type' => 'varchar_ascii', + 'length' => 255, + 'description' => 'Schema column description for ASCII string.', + ), ), ); db_create_table('test_table', $table_specification); @@ -62,6 +67,17 @@ function testSchema() { // Assert that the column comment has been set. $this->checkSchemaComment($table_specification['fields']['test_field']['description'], 'test_table', 'test_field'); + // Make sure that varchar fields have the correct collation. + $columns = db_query('SHOW FULL COLUMNS FROM {test_table}'); + foreach ($columns as $column) { + if ($column->Field == 'test_field_string') { + $this->assertTrue($column->Collation == 'utf8_general_ci'); + } + if ($column->Field == 'test_field_string_ascii') { + $this->assertTrue($column->Collation == 'ascii_general_ci'); + } + } + // An insert without a value for the column 'test_table' should fail. $this->assertFalse($this->tryInsert(), 'Insert without a default failed.'); diff --git a/core/modules/system/system.install b/core/modules/system/system.install index f1e6612..b9d221f 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -685,7 +685,7 @@ function system_schema() { ), 'token' => array( 'description' => "A string token generated against the current user's session id and the batch id, used to ensure that only the user who submitted the batch can effectively access it.", - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, ), @@ -717,14 +717,14 @@ function system_schema() { ), 'event' => array( 'description' => 'Name of event (e.g. contact).', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'default' => '', ), 'identifier' => array( 'description' => 'Identifier of the visitor, such as an IP address or hostname.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', @@ -754,14 +754,13 @@ function system_schema() { 'fields' => array( 'collection' => array( 'description' => 'A named collection of key and value pairs.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', ), 'name' => array( 'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.', - 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', @@ -781,7 +780,7 @@ function system_schema() { 'fields' => array( 'collection' => array( 'description' => 'A named collection of key and value pairs.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', @@ -789,7 +788,7 @@ function system_schema() { 'name' => array( // KEY is an SQL reserved word, so use 'name' as the key's field name. 'description' => 'The key of the key/value pair.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', @@ -824,7 +823,7 @@ function system_schema() { 'description' => 'Primary Key: Unique item ID.', ), 'name' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -862,7 +861,7 @@ function system_schema() { 'fields' => array( 'name' => array( 'description' => 'Primary Key: Machine name of this route', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', @@ -911,14 +910,14 @@ function system_schema() { 'fields' => array( 'name' => array( 'description' => 'Primary Key: Unique name.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '' ), 'value' => array( 'description' => 'A value for the semaphore.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '' @@ -961,13 +960,13 @@ function system_schema() { ), 'sid' => array( 'description' => "A session ID (hashed). The value is generated by Drupal's session handlers.", - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, ), 'hostname' => array( 'description' => 'The IP address that last used this session ID (sid).', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', @@ -1025,7 +1024,7 @@ function system_schema() { ), 'langcode' => array( 'description' => "The language code this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.", - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 12, 'not null' => TRUE, 'default' => '', diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php index c55953c..9a24194 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php @@ -34,7 +34,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) 'size' => 'big', ), 'format' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, ), ), diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php index 48d4dac..413ad47 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php @@ -68,7 +68,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) 'size' => 'big', ), 'format' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 255, ), ), diff --git a/core/modules/user/user.install b/core/modules/user/user.install index 7b3c3d3..dd55b49 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -21,14 +21,14 @@ function user_schema() { ), 'module' => array( 'description' => 'The name of the module declaring the variable.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, 'not null' => TRUE, 'default' => '', ), 'name' => array( 'description' => 'The identifier of the data.', - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php index 08f73cb..e67b8e6 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php @@ -802,7 +802,7 @@ public function testDedicatedTableSchema() { 'description' => "Data storage for $entity_type_id field $field_name.", 'fields' => array( 'bundle' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => true, 'default' => '', @@ -828,7 +828,7 @@ public function testDedicatedTableSchema() { 'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id', ), 'langcode' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 32, 'not null' => true, 'default' => '', @@ -947,7 +947,7 @@ public function testDedicatedTableSchemaForEntityWithStringIdentifier() { 'description' => "Data storage for $entity_type_id field $field_name.", 'fields' => array( 'bundle' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => true, 'default' => '', @@ -961,19 +961,19 @@ public function testDedicatedTableSchemaForEntityWithStringIdentifier() { 'description' => 'A boolean indicating whether this data item has been deleted', ), 'entity_id' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => true, 'description' => 'The entity id this data is attached to', ), 'revision_id' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 128, 'not null' => true, 'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id', ), 'langcode' => array( - 'type' => 'varchar', + 'type' => 'varchar_ascii', 'length' => 32, 'not null' => true, 'default' => '',