Problem/Motivation
When uninstalling a module that adds a custom base field definition to a entity that has been translated into more than one language, the process crashes and the module is unable to be uninstalled:
Drupal\Core\Database\IntegrityConstraintViolationException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3-21-1-0-es'; for key 'PRIMARY': INSERT INTO {field_deleted_revision_fd812c0eda} (bundle, entity_id, revision_id, langcode, my_field_value, deleted, delta) SELECT base_table.type AS bundle, entity_table.nid AS entity_id, entity_table.vid AS revision_id, entity_table.langcode AS langcode, entity_table.my_field AS my_field_value, :deleted AS deleted, :delta AS delta
FROM
{node_field_data} entity_table
INNER JOIN {node_field_data} base_table ON entity_table.nid = base_table.nid
WHERE entity_table.my_field IS NOT NULL FOR UPDATE;
Steps to reproduce
- Add a second language to the site.
- Install the Content Translation module.
- Enable content translation for Basic Page.
- Install a module that adds a base field to the node entity type. (Sample hook below, full sample module attached.)
- Create a basic page.
- Add a translation of the page in the second language.
- Edit the page, check the "My field" checkbox, and save the page.
- Uninstall the module that added the base field definition.
Expected result: Module is uninstalled, and the my_field column is dropped from the node_field_data table.
Actual result: Error message above.
Sample module:
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* Implements hook_entity_base_field_info().
*/
function mymodule_entity_base_field_info(EntityTypeInterface $entity_type) {
if ($entity_type->id() == 'node') {
$fields['my_field'] = BaseFieldDefinition::create('boolean')
->setLabel(t('My field'))
->setDisplayConfigurable('form', TRUE)
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'weight' => 100,
]);
return $fields;
}
}
Proposed resolution
The error appears to be caused by a query in which the node_field_data is JOINed on itself by id, but not langcode, causing duplicate rows. I don't fully understand the purpose of the JOIN, but my workaround is to add the langcode as a JOIN condition. (Patch attached.)