diff --git a/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php b/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php index 22947946e0d..4f30d47f7ab 100644 --- a/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php +++ b/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php @@ -240,7 +240,7 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface { // field name to avoid clashes when multiple fields of the same type are // added to an entity type. $entity_type_id = $this->entityType->id(); - $real_key = "{$entity_type_id}_field__{$field_name}__{$key}"; + $real_key = $this->getFieldSchemaIdentifierName($entity_type_id, $field_name, $key); foreach ($columns as $column) { // Allow for indexes and unique keys to specified as an array of column // name and length. @@ -257,6 +257,34 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface { return $data; } + /** + * Generates a safe schema identifier (name of an index, column name etc.). + * + * @param string $entity_type_id + * The ID of the entity type. + * @param string $field_name + * The name of the field. + * @param string $key + * The key of the field. + * + * @return string + * The field identifier name. + */ + protected function getFieldSchemaIdentifierName($entity_type_id, $field_name, $key) { + $real_key = "{$entity_type_id}_field__{$field_name}__{$key}"; + // Limit the string to 48 characters, keeping a 16 characters margin for db + // prefixes. + if (strlen($real_key) > 48) { + // Use a shorter separator, a truncated entity_type, and a hash of the + // field name. + // Truncate to the same length for the current and revision tables. + $entity_type = substr($entity_type_id, 0, 36); + $field_hash = substr(hash('sha256', $real_key), 0, 10); + $real_key = $entity_type . '__' . $field_hash; + } + return $real_key; + } + /** * Returns field foreign keys. * diff --git a/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php b/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php index 83b3509266a..f6f4959551f 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php @@ -234,6 +234,17 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase { ), ), )); + // Add a field with a really long index. + $this->setUpStorageDefinition('long_index_name', array( + 'columns' => array( + 'long_index_name' => array( + 'type' => 'int', + ), + ), + 'indexes' => array( + 'long_index_name_really_long_long_name' => array(array('long_index_name', 10)), + ), + )); $this->setUpSchemaHandler(); @@ -321,6 +332,10 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase { 'description' => 'The editor_revision field.', 'type' => 'int', ), + 'long_index_name' => array( + 'description' => 'The long_index_name field.', + 'type' => 'int', + ), 'default_langcode' => array( 'description' => 'Boolean indicating whether field values are in the default entity language.', 'type' => 'int', @@ -349,6 +364,10 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase { 'location__state', array('location__city', 10), ), + 'entity_test__b588603cb9' => array( + array('long_index_name', 10), + ), + ), 'foreign keys' => array( 'entity_test_field__editor__user_id' => array(