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

CommentFileSizeAuthor
#20 core-migration-field-delta-order-3164520-20.patch3.88 KBjames.williams
#20 core-migration-field-delta-order-3164520-test_only-20.patch1.74 KBjames.williams
#20 interdiff-3164520-19-20.txt673 bytesjames.williams
#19 core-migration-field-delta-order-3164520-19.patch3.88 KBjames.williams
#19 core-migration-field-delta-order-3164520-test_only-19.patch1.74 KBjames.williams
#19 interdiff-3164520-17-19.txt1.75 KBjames.williams
#17 3164520-17.patch2.13 KBMatroskeen
#17 3164520-test_only-17.patch959 bytesMatroskeen
#2 core-fieldableentity_addfieldvalues_delta_order-3164520-2--fix-only.patch516 byteshuzooka
#4 core-fieldableentity_addfieldvalues_delta_order-3164520-4--test-only.patch9.23 KBhuzooka
#4 core-fieldableentity_addfieldvalues_delta_order-3164520-4--complete.patch9.77 KBhuzooka
#7 3164520-7.patch10.42 KBraman.b
#7 interdiff_4-7.txt1.73 KBraman.b
#9 3164520-8.patch10.45 KBraman.b
#9 interdiff_7-8.txt546 bytesraman.b

Issue fork drupal-3164520

Command icon 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:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

huzooka created an issue. See original summary.

huzooka’s picture

huzooka’s picture

Assigned: Unassigned » huzooka
mikelutz’s picture

Status: Needs review » Needs work
Issue tags: -Needs subsystem maintainer review

Undefined 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.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

raman.b’s picture

Adding orderBy in the database query instead of using ksort(). Also updating the doc as per #5 and a minor CS issue

raman.b’s picture

Status: Needs work » Needs review
raman.b’s picture

/var/www/html/core/modules/migrate_drupal/tests/src/Kernel/d7/MultiValueFieldMigrationsTest.php:211:47 - Unknown word (Opaka)
/var/www/html/core/modules/migrate_drupal/tests/src/Kernel/d7/MultiValueFieldMigrationsTest.php:275:47 - Unknown word (Opaka)

CSpell: failed
quietone’s picture

Status: Needs review » Needs work

This is a nice addition, I like it. And mikelutz has already shown there are no BC concerns.

  1. +++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/MultiValueFieldMigrationsTest.php
    @@ -0,0 +1,285 @@
    +class MultiValueFieldMigrationsTest extends MigrateDrupal7TestBase {
    

    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.

Matroskeen made their first commit to this issue’s fork.

huzooka’s picture

Go Drupal, go! 😁

Matroskeen’s picture

Status: Needs work » Needs review

I 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".

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Status: Needs review » Needs work

I 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?

Matroskeen’s picture

It should fail with PostgreSQL, let's see.

huzooka’s picture

See https://www.drupal.org/project/drupal/issues/3164520#comment-13784133.

Emails aren't affected.

@quitone:
(From IS)

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).

james.williams’s picture

This 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.

The last submitted patch, 19: core-migration-field-delta-order-3164520-19.patch, failed testing. View results

quietone’s picture

Status: Needs review » Needs work

I 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.

james.williams’s picture

Issue summary: View changes

I have one question, why didn't d6\MigrateNodeCompleteTest fail?

The 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.

quietone’s picture

Status: Needs work » Reviewed & tested by the community

@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.

  • catch committed 1c17abd on 9.3.x
    Issue #3164520 by james.williams, Matroskeen, huzooka, raman.b, quietone...

  • catch committed 37c6f13 on 9.2.x
    Issue #3164520 by james.williams, Matroskeen, huzooka, raman.b, quietone...
catch’s picture

Version: 9.3.x-dev » 9.2.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 9.3.x and cherry-picked to 9.2.x, thanks!

huzooka’s picture

Thank you all!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.