Problem/Motivation
We are migrating a D6 website with lots of cck nodereferrer fields (not node references - these too, but they are not the issue). cck nodereferrer fields are not supported, but they should just be ignored on migration. Instead, migrating a content type with a nodereferrer field fails:
Migration failed with source plugin exception:
SQLSTATE[42S22]: Column not found: 1054 Unknown column ;field_codb_groups_for_co_; in ;where [error]
clause': SELECT 0 AS delta
FROM
{content_type_codb_conscientious_objector} t
WHERE (field_codb_groups_for_co_ IS NOT NULL ) AND (nid = :db_condition_placeholder_0) AND (vid = :db_condition_placeholder_1); Array
(
[:db_condition_placeholder_0] =778
[:db_condition_placeholder_1] =783
)I tracked it down to the function getCckData(array $field, Row $node) in core/modules/node/src/Plugin/migrate/source/d6/Node.php :
This function does not check whether the table columns array is empty, causing it to add the underscore to the column name (based on the field name), but then nothing. This column does not exist, obviously.
The problem is related to how nodereferrer saves the data in the content_node_field table: it stores an empty array in the column 'db_columns'.
As I understand it, the function first checks for a dedicated table based on the field name, and if that doesn't exist, it selects the table of the respective content type of the field instance.
It then tries to get the titles of the table columns of that table based on the content_node_field table (column db_columns). However, as for nodereferrer fields this contains an empty array, and the function does not check if we really have a value in there.
Steps to reproduce
Proposed resolution
Add a check in the source plugin
if (isset($query)) {
$columns = array_keys($field['db_columns']);
if ( $columns == array() ) {
return [];
}Remaining tasks
Patch
Review
Commit
User interface changes
N/A
API changes
N/A
Data model changes
N/A
Release notes snippet
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #27 | 2784783-27.patch | 2.2 KB | quietone |
| #27 | 2784783-27-fail.patch | 1.55 KB | quietone |
| #19 | interdiff-13-19.txt | 3.04 KB | jofitz |
| #19 | 2784783-19.patch | 2.2 KB | jofitz |
| #13 | interdiff-9-13.txt | 2.23 KB | RytoEX |
Comments
Comment #1
Anonymous (not verified) commentedAndreas Speck created an issue. See original summary.
Comment #4
mikeryanI'm not sure if this was an out-and-out bug in nodereferrer, or if this was a practice in other CCK fields... At any rate, bulletproofing wouldn't hurt:
Comment #5
dimr commentedI am going to work on it in Drupal Dev Days Seville
Comment #6
ebarrera commentedComment #7
ebarrera commentedComment #8
dimr commentedSorry, but finally I didn't work in this issue. I was working in translation of the User Guide to Spanish.
Comment #9
Charlotte17 commentedAdding comment#4
Comment #10
Charlotte17 commentedAdding comment#4
Comment #11
mikeryanLooks good, but we add a test for this - include a test-only patch which should fail, and a full patch which should succeed.
Comment #13
RytoEX commentedI took a crack at this to try to get it moving. The patch changed slightly after applying and generating due to #2833206: Convert Migrate's cckfield plugins to use the new field plugins, but the patch in #9 still applies okay to 8.4.x.
I added test source_data for nodereferrer for this, but let me know if it's in the wrong place. My local test run of NodeTest failed with "Undefined offset: 0", and the NodeTest passed after applying the full patch attached here. An interdiff against #9 is also attached.
Comment #15
RytoEX commentedI guess I attached the patches in #13 in the wrong order. Changing the status back to Needs Review since the test failure was expected. Also clearing the Needs tests tag.
Comment #16
maxocub commentedAssigning for review.
Comment #17
maxocub commentedThis looks good, I don't see anything wrong. The test only patch fails as expected. Thanks RytoEX!
Comment #18
catchThis needs an explanation of why we're just returning empty and not logging anything.
Without reading the issue summary I got confused by nodereferrer vs. nodereference. Could we use something more explanatory like 'missing_cck_module'?
Comment #19
jofitzComment #20
maxocub commentedI don't find this very clear. I don't think 'db_columns' is a field. Looking at the code I think this snippet is when there's no columns to fetch from a field table.
Also, there's no mention about why we are returning nothing and not logging something.
Comment #26
quietone commentedClosed #3196867: Pseudo-fields without "db columns", like noderelationships field_backref_* break node migration" as a duplicate. Adding credit for those who helped over there.
Updated IS.
Comment #27
quietone commentedUpdated the patch and made a fail patch.
Comment #30
quietone commentedClosed #3062062: Ignore nodereferrer field data in D6 Migration as a duplicate, adding credit.
Comment #31
anybodyGreat work @all and especially @quiteone!
As we've been using this fix for months now, I'll set this RTBC! :)
Comment #32
alexpottCommitted and pushed 81174ad778 to 9.3.x and 89d028223d to 9.2.x. Thanks!