diff -u b/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php --- b/core/lib/Drupal/Core/Entity/EntityType.php +++ b/core/lib/Drupal/Core/Entity/EntityType.php @@ -161,7 +161,7 @@ protected $revision_table = NULL; /** - * An array of entity metadata fields. + * An array of entity revision metadata keys. * * @var array */ @@ -392,11 +392,10 @@ * {@inheritdoc} */ public function getRevisionMetadataKeys() { - // Add a backward compatibility in case the revision metadata keys are not - // defined in the entity annotation. - if (empty($this->revision_metadata_keys)) { - $class = $this->getClass(); - $base_fields = $class::baseFieldDefinitions($this); + // Provide backwards compatibility in case the revision metadata keys are + // not defined in the entity annotation. + if (!$this->revision_metadata_keys) { + $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($this->id()); if ((isset($base_fields['revision_uid']) && $revision_user = $base_fields['revision_uid']) || (isset($base_fields['revision_user']) && $revision_user = $base_fields['revision_user'])) { $this->revision_metadata_keys['revision_user'] = $revision_user; } @@ -423,7 +422,7 @@ */ public function hasRevisionMetadataKey($key) { $keys = $this->getRevisionMetadataKeys(); - return !empty($keys[$key]); + return isset($keys[$key]); } /** diff -u b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php --- b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -297,7 +297,7 @@ // If the entity is revisionable, gather the fields that need to be put // in the revision table. $revisionable = $this->entityType->isRevisionable(); - $revision_metadata_fields = $revisionable ? array_values($this->entityType->getRevisionMetadataKeys()) : NULL; + $revision_metadata_fields = $revisionable ? array_values($this->entityType->getRevisionMetadataKeys()) : []; $translatable = $this->entityType->isTranslatable(); if (!$revisionable && !$translatable) { diff -u b/core/modules/system/system.install b/core/modules/system/system.install --- b/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1751,8 +1751,7 @@ foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type_id => $entity_type) { if ($entity_type->isRevisionable() && $entity_type->isTranslatable()) { - $class = $entity_type->getClass(); - $base_fields = $class::baseFieldDefinitions($entity_type); + $base_fields = $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type_id); $fields_to_update = array_intersect_key($base_fields, $entity_type->getRevisionMetadataKeys()); if (!empty($fields_to_update)) { @@ -1772,13 +1771,22 @@ $entity_definition_update_manager->installFieldStorageDefinition($revision_metadata_field_name, $entity_type_id, $entity_type->getProvider(), $definition); // Collect the revision ids only once for an entity type. - $revisions = isset($revisions) ? $revisions : \Drupal::entityQuery($entity_type_id) + $revisions = isset($revisions) ? $revisions : array_keys(\Drupal::entityQuery($entity_type_id) ->allRevisions() - ->execute(); + ->execute()); + + if (!isset($sandbox['progress'])) { + // This must be the first run. Initialize the sandbox. + $sandbox['progress'] = 0; + $sandbox['current'] = 0; + $sandbox['max'] = count($revisions); + } // Apply the field value from the revision data table to the // revision table. - foreach ($revisions as $rev_id => $id) { + $current = $sandbox['current']; + for ($i = $current; $i < $current + 100 && $i < $sandbox['max']; $i++) { + $rev_id = $revisions[$i]; $field_value = $database->select($revision_data_table, 'rd') ->fields('rd', [$revision_metadata_field_name]) ->condition($revision_field, $rev_id) @@ -1788,10 +1796,18 @@ ->condition($revision_field, $rev_id) ->fields([$revision_metadata_field_name => $field_value]) ->execute(); + + $sandbox['current']++; + } + + $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); + + if ($sandbox['#finished'] >= 1) { + // Drop the field from the data tables. + $database_schema->dropField($data_table, $revision_metadata_field_name); + $database_schema->dropField($revision_data_table, $revision_metadata_field_name); + unset($sandbox['progress']); } - // Drop the field from the data tables. - $database_schema->dropField($data_table, $revision_metadata_field_name); - $database_schema->dropField($revision_data_table, $revision_metadata_field_name); } } $revisions = NULL;