Problem/Motivation

Discovered by @kevin.dutra in #2644088-20: DefaultTableMapping::getFieldTableName does not report table for fields with dedicated storage:

SqlContentEntityStorage contains a $tableMapping property which is populated on the first call to getTableMapping(). Subsequent calls use this locally cached version rather than recreating it. However, nothing forces this to be rebuilt after a field storage definition is inserted, so the table mapping has stale data for the remainder of the request.

Proposed resolution

Figure out a way to clear the SqlContentEntityStorage::$tableMapping static property when a new field storage definition is added.

Remaining tasks

Write a patch.

User interface changes

Nope.

API changes

I hope none.

Data model changes

Nope.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amateescu created an issue. See original summary.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

amateescu’s picture

I was poking around in this area lately and it seems that simply clearing the statically cached $tableMapping at the end of \Drupal\Core\Entity\Sql\SqlContentEntityStorage::onFieldStorageDefinitionCreate() will fix the test from #2644088-20: DefaultTableMapping::getFieldTableName does not report table for fields with dedicated storage, but it does not allow us to remove the @todo from \Drupal\Core\Entity\Sql\SqlContentEntityStorage::countFieldData().

The last submitted patch, 4: 2705205-test-only.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 4: 2705205-full.patch, failed testing.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

amateescu’s picture

Looking at this issue again after working on various places related to the table mapping, I think the current code for \Drupal\Core\Entity\Sql\SqlContentEntityStorage::countFieldData() in HEAD is actually correct and doesn't need the @todo anymore. Updated the comment to make it clear why we need to use a fresh table mapping instead of the cached one.

tstoeckler’s picture

Yes, this makes sense to me, as well. Not sure if we want to handle field storage update and delete here, as well, otherwise this is RTBC.

The last submitted patch, 10: 2705205-10-test-only.patch, failed testing. View results

amateescu’s picture

Since CRUD operations on field storage definitions usually go hand-in-hand, I think it's good to be consistent and save our future selves some unwanted headaches :)

The last submitted patch, 10: 2705205-10.patch, failed testing. View results

tstoeckler’s picture

OK, perfect! Looks good to me and I agree fully with #13. Just not sure whether we need dedicated test coverage for the update and delete cases, so not yet setting to RTBC to let someone else chime in, maybe.

Status: Needs review » Needs work

The last submitted patch, 13: 2705205-12.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Needs review
FileSize
3.86 KB
3.99 KB

The difference between the code path taken in #4 and #10/#13 is that \Drupal\Core\Entity\Sql\SqlContentEntityStorage::onFieldStorageDefinitionCreate() is operating on a cloned storage object (see \Drupal\Core\Field\FieldStorageDefinitionListener::onFieldStorageDefinitionCreate()), so setting the table mapping to NULL on the cloned storage object has no effect on the storage object cached in \Drupal\Core\Entity\EntityTypeManager::$handlers.

The only other option that I see is to reset the entity type manager cache directly in FieldStorageDefinitionListener, just like we do for the field manager cache.

Status: Needs review » Needs work

The last submitted patch, 17: 2705205-17.patch, failed testing. View results

amateescu’s picture

Version: 8.6.x-dev » 8.8.x-dev
Status: Needs work » Needs review
FileSize
2.52 KB

This problem was fixed in #2554235: Make the content entity storage and entity query use the last installed definitions instead of the ones living in code, but it would be nice to commit the extra test coverage from this issue.

This patch is basically the test-only one from #4.

plach’s picture

Version: 8.8.x-dev » 8.7.x-dev
plach’s picture

Status: Needs review » Reviewed & tested by the community

Looks good!

plach’s picture

Title: SqlContentEntityStorage::$tableMapping is not updated in the same request when a new field storage definition is added » Improve test coverage around updating table mapping after a new field storage definition is added
Category: Bug report » Task
alexpott’s picture

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 7c9ecd6c71 to 8.8.x and ead2914b5c to 8.7.x. Thanks!

As a documentation and test only patch this is eligible for backport to 8.7.x during the beta.

  • alexpott committed 7c9ecd6 on 8.8.x
    Issue #2705205 by amateescu, plach, tstoeckler: Improve test coverage...

  • alexpott committed ead2914 on 8.7.x
    Issue #2705205 by amateescu, plach, tstoeckler: Improve test coverage...

Status: Fixed » Closed (fixed)

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