Bad sql join statement in NodeComplete d7 source plugin excludes valid revisions from migration.

Created on 13 March 2025, 26 days ago

Problem/Motivation

A bug in the SQL query from plugin Drupal\node\Plugin\migrate\source\d7\NodeComplete can exclude node revisions from migration.

The issue is with the entity_translation_revision left join statement.

SELECT n.nid, nr.vid, nt.language, etr.revision_id
FROM node_revision nr
INNER JOIN node n
  ON n.nid = nr.nid
LEFT JOIN node nt
  ON n.tnid = nt.nid
LEFT JOIN entity_translation_revision etr
  ON nr.nid = etr.entity_id
  AND nr.vid = etr.revision_id
WHERE (
  n.tnid = 0
  OR n.tnid = n.nid
)
AND n.type IN ("page", "article")
AND (
  etr.entity_type = "node"
  OR etr.entity_type IS NULL
)
AND n.language in ("en", "fr", "und")
ORDER BY nr.vid, etr.revision_id, etr.language;D

The part causing the problem is the left join to entity_translation_revision

LEFT JOIN entity_translation_revision etr
  ON nr.nid = etr.entity_id
  AND nr.vid = etr.revision_id
WHERE
[...]
AND (
  etr.entity_type = "node"
  OR etr.entity_type IS NULL
)

The match on etr.entity_type = "node" should not be in the where clause but in the join statement.

An error occurs when the entity_translation_revision table has entries for different entity_type than node with the same entity_id and revision_id as the node revision being processed.

For example, the entity_translation_revision table could have an entry for a bean type entity with entity_id = 1 and revision_id = 1. When a node entity_type with the same entity_id = 1 and revision_id =1 is processed, the join statement can join with the bean entity_type row instead of the node row and then the revision get rejected on the where condition etr.entity_type = "node" and the revision is not migrated.

Proposed resolution

This can be fixed by adding a match on entity_type = "node" in the left join statement and removing the where clause/

From:

$query->leftJoin('entity_translation_revision', 'etr', '[nr].[nid] = [etr].[entity_id] AND [nr].[vid] = [etr].[revision_id]');

To:

$query->leftJoin('entity_translation_revision', 'etr', '[nr].[nid] = [etr].[entity_id] AND [nr].[vid] = [etr].[revision_id] AND [etr].[entity_type] = :entity_type', [':entity_type' => 'node']);

I've included a patch file to illustrate the full change required.

πŸ› Bug report
Status

Active

Version

11.0 πŸ”₯

Component

migration system

Created by

πŸ‡¨πŸ‡¦Canada iwayman

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024