Problem/Motivation
FieldableEntity::getFieldValues()
does not guarantee that the returned field values are sorted by their delta.
In certain situations, this meant that the values of a multi-value field are migrated with reversed order.
Steps to reproduce
I ran into this error when I tried to migrate from PostgreSQL source with multi-value image, file and paragraph fields (during tests).
@todo
Proposed resolution
Add $query->orderBy('t.delta', 'ASC');
to the query, OR .ksort($values);
before the return statement
Remaining tasks
Steps to reproduce + failing test.
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#20 | core-migration-field-delta-order-3164520-20.patch | 3.88 KB | james.williams |
#20 | core-migration-field-delta-order-3164520-test_only-20.patch | 1.74 KB | james.williams |
#17 | 3164520-17.patch | 2.13 KB | Matroskeen |
#17 | 3164520-test_only-17.patch | 959 bytes | Matroskeen |
Issue fork drupal-3164520
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3164520-fieldable-entity-get-field-values-sort changes, plain diff MR !604
Comments
Comment #2
huzookaComment #3
huzookaComment #4
huzookaAdded a kernel test. The weirdest thing is that only node #1's
field_term_entityreference
values are affected, but not e.g. its email field values, nor node #2'sfield_tags
values.The interdiff between #2 and this comment equals to the test-only patch.
Comment #5
mikelutzUndefined sort orders from PostGreSQL are a class of bugs near and dear to me. :-)
Technically we don't promise that those deltas are in any particular order, so technically calling code should be sorting them if needed, but I'm sure it probably doesn't.
Fortunately, we technically don't promise that those deltas are in any particular order, so can certainly sort them without breaking backwards compatibility.
I would prefer that we go with the sort in the database call, that feels more performant. I would also like to see the comment for the return value of getFieldValues() to be edited to say
The raw field values, keyed and sorted by delta.
Comment #7
raman.b CreditAttribution: raman.b at OpenSense Labs commentedAdding
orderBy
in the database query instead of usingksort()
. Also updating the doc as per #5 and a minor CS issueComment #8
raman.b CreditAttribution: raman.b at OpenSense Labs commentedComment #9
raman.b CreditAttribution: raman.b at OpenSense Labs commentedComment #10
quietone CreditAttribution: quietone as a volunteer commentedThis is a nice addition, I like it. And mikelutz has already shown there are no BC concerns.
This test file is doing a lot of assertions that are already done elsewhere. This is just a node migration and then testing the results. So, we can just add only those assertions that are related to the changes in FieldableEntity to \Drupal\Tests\node\Kernel\Migrate\d7\MigrateNodeCompleteTest::testNodeCompleteMigration. We avoid making a new kernel test and this patch will be smaller as well.
Comment #12
huzookaGo Drupal, go! 😁
Comment #14
MatroskeenI noticed the issue is stuck for several months, so wanted to push it a little bit 😝
@huzooka, can you review to make sure it's enough and I didn't remove too much?
The test passed locally, so I'm moving this to "Needs review".
Comment #16
quietone CreditAttribution: quietone as a volunteer commentedI ran MigrateNodeCompleteTest locally without the fix and as I suspected, the tests pass. This needs a failing test. Setting to NW for that. Maybe in the setUp() field rows could be reordered?
Comment #17
MatroskeenIt should fail with PostgreSQL, let's see.
Comment #18
huzookaSee https://www.drupal.org/project/drupal/issues/3164520#comment-13784133.
Emails aren't affected.
@quitone:
(From IS)
Comment #19
james.williams CreditAttribution: james.williams at ComputerMinds for Hydrotechnik UK Ltd commentedThis also affects migrations from Drupal 6. I don't know if it's OK to bring that into scope? The fix is almost identical; and I've added what I think is the equivalent test.
Comment #20
james.williams CreditAttribution: james.williams at ComputerMinds for Hydrotechnik UK Ltd commentedMy apologies, I used a nid instead of a vid in the D6 test! These should work.
Comment #23
quietone CreditAttribution: quietone as a volunteer commentedI reviewed that patch and it all looks good to me.
I looked at the d6 and d7 databases and can confirm that the order of the field values being tested in the D6 and D7 tests are correct.
Comments are updated in d6/Node and FieldableEntity. I can't think where else that needs to be documented.
There is a failing test, \d7\MigrateNodeCompleteTest
I have one question, why didn't d6\MigrateNodeCompleteTest fail?
Oh, and the IS should be updated to indicate which of the two proposed resolutions has been implemented.
Thx.
Comment #24
james.williams CreditAttribution: james.williams at ComputerMinds for Hydrotechnik UK Ltd commentedThe rows in the test fixtures are ordered the 'expected' way round (i.e. with deltas ascending), so the records can come back the right way around without the explicit ordering. I experienced this issue even with MySQL, because my source database (D6!) happened to have data that was ordered the other way around, so the same solution applies as for the unexpected order from PostgreSQL.
Do we need to set up a new test fixture database with rows the 'wrong' way around? Feels like unnecessary work to me.
Comment #25
quietone CreditAttribution: quietone as a volunteer commented@james.williams, thanks for that. I agree, there is no need to alter the test fixtures.
My question has been answered, the code is good and there are tests.
Comment #28
catchCommitted/pushed to 9.3.x and cherry-picked to 9.2.x, thanks!
Comment #29
huzookaThank you all!