diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index 189c954..d5576ae 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -549,6 +549,24 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res $this->processRevisionDataTable($entity_type, $schema[$tables['revision_data_table']]); } + // Add an index for the 'published' entity key. + if (is_subclass_of($entity_type->getClass(), EntityPublishedInterface::class)) { + $published_key = $entity_type->getKey('published'); + if (!$storage_definitions[$published_key]->hasCustomStorage()) { + $published_field_table = $table_mapping->getFieldTableName($published_key); + $id_key = $entity_type->getKey('id'); + if ($bundle_key = $entity_type->getKey('bundle')) { + $index = "{$published_key}_{$bundle_key}"; + $columns = [$published_key, $bundle_key, $id_key]; + } + else { + $index = $published_key; + $columns = [$published_key, $id_key]; + } + $schema[$published_field_table]['indexes'][$this->getEntityIndexName($entity_type, $index)] = $columns; + } + } + $this->schema[$entity_type_id] = $schema; // Restore the actual definition. @@ -1624,27 +1642,6 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st $schema['indexes'] = $this->getFieldIndexes($field_name, $field_schema, $column_mapping); } - // Add an index for the 'published' entity key. - $published_key = $this->entityType->getKey('published'); - if ( - // The entity type supports 'published' key. - is_subclass_of($this->entityType->getClass(), EntityPublishedInterface::class) - // and this field is the 'published' field. - && $field_name === $published_key - // and this is not the revisions data table. - && $table_name !== $this->storage->getRevisionDataTable() - // and the field doesn't have a custom storage. - && !$this->fieldStorageDefinitions[$published_key]->hasCustomStorage() - ) { - $id_key = $this->entityType->getKey('id'); - if ($bundle_key = $this->entityType->getKey('bundle')) { - $schema['indexes'][$this->getEntityIndexName($this->entityType, $published_key . '_' . $bundle_key)] = [$published_key, $bundle_key, $id_key]; - } - else { - $schema['indexes'][$this->getEntityIndexName($this->entityType, $published_key)] = [$published_key, $id_key]; - } - } - if (!empty($field_schema['unique keys'])) { $schema['unique keys'] = $this->getFieldUniqueKeys($field_name, $field_schema, $column_mapping); } diff --git a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaPublishedTest.php b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaPublishedTest.php new file mode 100644 index 0000000..5719449 --- /dev/null +++ b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaPublishedTest.php @@ -0,0 +1,39 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + ]; + } + + /** + * Tests entity and field schema database updates and execution order. + */ + public function testIndex() { + /** @var \Drupal\Core\Database\Schema $schema */ + $schema = $this->container->get('database')->schema(); + + // Check that the {comment_field_data} table status index does not exists. + $this->assertFalse($schema->indexExists('comment_field_data', 'comment__status_comment_type')); + + $this->runUpdates(); + + // Check that the {comment_field_data} table status index exists. + $this->assertTrue($schema->indexExists('comment_field_data', 'comment__status_comment_type')); + } + +} diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 6dc2663..1d50f90 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -13,6 +13,9 @@ use Drupal\Core\Url; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; +use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityPublishedInterface; +use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; use Drupal\Core\Site\Settings; use Drupal\Core\StreamWrapper\PrivateStream; use Drupal\Core\StreamWrapper\PublicStream; @@ -1794,3 +1797,41 @@ function system_update_8203() { ->set('logging', 1) ->save(TRUE); } + +/** + * @addtogroup updates-8.3.x + * @{ + */ + +function system_update_8300() { + $entity_type_manager = \Drupal::entityTypeManager(); + $entity_update_manager = \Drupal::entityDefinitionUpdateManager(); + + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ + foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) { + $class = $entity_type->getClass(); + /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */ + $storage = $entity_type_manager->getStorage($entity_type_id); + + // Deal only with content entities that are declaring a 'published' entity + // key and are using the canonical storage. + if (!is_subclass_of($class, ContentEntityInterface::class) || !is_subclass_of($class, EntityPublishedInterface::class) || !is_subclass_of($storage, SqlEntityStorageInterface::class)) { + continue; + } + + $published_key = $entity_type->getKey('published'); + $field_definition = $entity_update_manager->getFieldStorageDefinition($published_key, $entity_type_id); + + // Skip if the 'published' field uses a custom storage. + if ($field_definition->hasCustomStorage()) { + continue; + } + + // Regenerate entity type indexes, this should add the missed indexes. + $entity_update_manager->updateEntityType($entity_type); + } +} + +/** + * @} End of "addtogroup updates-8.3.x". + */