diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index af8f46b153..2201fe3059 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -1453,23 +1453,7 @@ protected function deleteSharedTableSchema(FieldStorageDefinitionInterface $stor $schema = $this->getSharedTableFieldSchema($storage_definition, $table_name, $column_names); // Drop the primary key, indexes and unique keys first. - // The entity schema needs to be checked because the field schema is - // potentially incomplete. - // @todo Remove this in - // https://www.drupal.org/project/drupal/issues/2929120 - $entity_schema = $this->getEntitySchema($this->entityType); - if (array_intersect($column_names, $entity_schema[$table_name]['primary key'])) { - // Dropping a primary key must not leave a serial key, so we need to - // change any serial field to integer first. - foreach ($entity_schema[$table_name]['primary key'] as $column_name) { - if ($entity_schema[$table_name]['fields'][$column_name]['type'] === 'serial') { - $field_schema = $entity_schema[$table_name]['fields'][$column_name]; - $field_schema['type'] = 'int'; - $schema_handler->changeField($table_name, $column_name, $column_name, $field_schema); - } - } - $schema_handler->dropPrimaryKey($table_name); - } + $this->dropPrimaryKey($table_name, $column_names); if (!empty($schema['indexes'])) { foreach ($schema['indexes'] as $name => $specifier) { $schema_handler->dropIndex($table_name, $name); @@ -1655,7 +1639,10 @@ protected function updateSharedTableSchema(FieldStorageDefinitionInterface $stor } } - // Drop original indexes and unique keys. + // Drop the primary key, indexes and unique keys first. + $this->dropPrimaryKey($table_name, $column_names); + + // Drop original primary keys, indexes and unique keys. if (!empty($original_schema[$table_name]['indexes'])) { foreach ($original_schema[$table_name]['indexes'] as $name => $specifier) { $schema_handler->dropIndex($table_name, $name); @@ -1666,7 +1653,19 @@ protected function updateSharedTableSchema(FieldStorageDefinitionInterface $stor $schema_handler->dropUniqueKey($table_name, $name); } } - // Create new indexes and unique keys. + // Create new primary key, indexes and unique keys. + // The entity schema needs to be checked because the field schema is + // potentially incomplete. + // @todo Remove this in + // https://www.drupal.org/project/drupal/issues/2929120 + $entity_schema = $this->getEntitySchema($this->entityType); + foreach ($schema[$table_name]['fields'] as $name => $specifier) { + // Check if the field is part of the primary keys. + if (isset($entity_schema[$table_name]['primary key']) && array_intersect($column_names, $entity_schema[$table_name]['primary key'])) { + $schema_handler->addPrimaryKey($table_name, $entity_schema[$table_name]['primary key']); + break; + } + } if (!empty($schema[$table_name]['indexes'])) { foreach ($schema[$table_name]['indexes'] as $name => $specifier) { // Check if the index exists because it might already have been @@ -2316,4 +2315,35 @@ protected function addUniqueKey($table, $name, array $specifier) { $schema_handler->addUniqueKey($table, $name, $specifier); } + /** + * Removes the primary key of a table if the passed columns are part of it. + * + * @param string $table_name + * The name of the table whose primary key is to be deleted. + * @param string[] $column_names + * The list of columns to check whether they are part of the primary key. + * + * @internal + */ + private function dropPrimaryKey($table_name, $column_names) { + $schema_handler = $this->database->schema(); + // The entity schema needs to be checked because the field schema is + // potentially incomplete. + // @todo Remove this in + // https://www.drupal.org/project/drupal/issues/2929120 + $entity_schema = $this->getEntitySchema($this->entityType); + if (array_intersect($column_names, $entity_schema[$table_name]['primary key'])) { + // Dropping a primary key must not leave a serial key, so we need to + // change any serial field to integer first. + foreach ($entity_schema[$table_name]['primary key'] as $column_name) { + if ($entity_schema[$table_name]['fields'][$column_name]['type'] === 'serial') { + $field_schema = $entity_schema[$table_name]['fields'][$column_name]; + $field_schema['type'] = 'int'; + $schema_handler->changeField($table_name, $column_name, $column_name, $field_schema); + } + } + $schema_handler->dropPrimaryKey($table_name); + } + } + }