Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Follow-up to #2282119: Make the Entity Field API handle field purging. Base fields can be stored in different entity tables based on a custom data_table
set in the entity definition or if the base field is translatable or not. Currently when copying base fields from shared table storage to dedicated table storage for purging, the wrong tables are used in some scenarios.
Proposed resolution
Add additional test coverage for different combinations of entity and field definitions and fix these.
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#47 | Drupal_core___Drupal_org.png | 81.92 KB | plach |
#43 | interdiff-43.txt | 1.02 KB | amateescu |
#43 | 2923567-43.patch | 15.96 KB | amateescu |
#40 | 2923567-40.patch | 17.16 KB | Sam152 |
#40 | 2923567-interdiff.txt | 3.36 KB | Sam152 |
Comments
Comment #2
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedSeeing if this passes the existing tests.
Comment #3
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThat makes perfect sense, want to add a test for it?
Comment #4
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedThanks for reviewing. I'll have a look at the test for this now.
Comment #5
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedHaving looked a bit more into it, how come
$base_table = $is_translatable ? $this->storage->getDataTable() : $this->storage->getBaseTable();
is not returning 'user_field_data' in your case? The user entity is translatable and correctly defines a data table in its annotation.Comment #6
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedAlso, the issue summary says "based on if the entity is revisionable or not" but the patch is about being translatable or not..
Comment #7
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedGood catch, updating.
Comment #8
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedAdding a test for this too.
Comment #9
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedComment #12
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedFixing the views test.
Comment #13
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedRemoving unused use.
Comment #15
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedI missed the comment in #5,
$is_translatable
was coming up FALSE because I believe the field was not translatable.Comment #16
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedThe code snippet in the issue summary is actually incorrect. Must have pulled that from somewhere else. Updating.
Comment #17
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThat's weird, because if the field was not translatable, why is it stored in the data table? In any case, we need to also check the hunk below the one changed by this patch where we do the same
if
for the field revision table. And probably add some dedicated test coverage for that as well.Comment #18
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedI'm not sure how the field is assigned to the tables, however the test case fails in the same fashion as I encountered. The
entity_test_mul
table is used however I believe the base field ends up inentity_test_mul_property_data
.Some good additional coverage might be additional entity revisions in
testBaseFieldDeleteWithExistingData
or would you suggest a new test method?Comment #19
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedI think adding a few revisions in
testBaseFieldDeleteWithExistingData
is fine :)Comment #20
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedAdding the revisions instantly exposed a bug in #13, so great catch to check this. To fix this part I think it makes sense to add the equivalent method to
getFieldTableName
for revisions.I think it also allows us to add coverage for another scenario which I also think has issues, a non-revisionable base field on a revisionable entity type. That's based on the following part of the patch:
In this case I don't think the field appears in either
getRevisionDataTable
orgetRevisionTable
because it's not revisionable, but the condition is based on the entity type.I haven't had much luck debugging these and it's getting a bit late but I think it makes sense to include these test cases in the scope of this issue and rejigging the title and IS. Feel free to adjust for brevity, the title got a bit wordy.
Comment #21
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedHelps to upload the patch files...
Comment #23
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedI was able to get the test cases I introduced to pass with this approach.
Comment #24
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedAnd a test only patch for #23.
Comment #26
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedComment #27
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedReroll and a few tweaks.
Comment #28
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThis is getting better and better :) I found just a few more issues:
This still doesn't look quite right. What happens when the entity type is revisionable but not translatable? It shouldn't have a data table in that case..
How come the revision id is 1 for the first assertion? Didn't we just created and saved a new revision above?
We should mention in the assertion message that this is about the dedicated revision table.
And I'm not sure the message is quite right, we're asserting that the table does not exist anymore. The assertion above has the same problem and should probably be changed as well.
Comment #29
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commented1. Is there a test entity type that meets this criteria we can use?
2. We create an additional entity in #2923572: Account for NULL base field values in shared table storage when copying to dedicated table storage for field purging., so the revision IDs in these test cases are 3 and 2.
3. Good point.
Comment #30
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented1. Yep, entity_test_rev ;)
2. Maybe it deserves a comment then because it definitely tripped me at first.
Comment #31
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commented1. Both new test cases indeed failed!
2. Hard coding both revision IDs seems clearer to me.
3. Fixed.
I experimented with a few ways of representing the list tables. I'm not sure my matrix implementation makes it any more understandable :D
Comment #33
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedI think the code that we have in the patch is just fine, being more explicit is better here :)
Comment #35
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedRerolling.
Comment #36
plachThis looks great, I have only one doubt (and the inevitable nitpick):
Why are we creating a dedicated deleted field revision table even if the field is non-revisionable?
Missing default description :)
Comment #37
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedHad a look into this. I can confirm for the
Revisionable entity type, non revisionable base field
test case, a deleted revision and data and revision table exist, with a single row for both. Not sure if that is intentional or was just easier to implement by design. Maybe @amateescu can help out here.Comment #38
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedSorry, I'm afk for a few days so I won't be able to look at the code, but it may very well be a mistake from the initial patch that we could correct here :)
Comment #39
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedDug into this a little bit deeper. In
SqlContentEntityStorageSchema::getDedicatedTableSchema
, the code which checks if a revision table is created for someFieldStorageDefinitionInterface
is:So, I think the answer is that currently if a field requires dedicated table storage and is not revisionable but the entity type it is attached to is, field revision tables are created. This could be so that in
::updateDedicatedTableSchema
, table layouts don't have to be changed if a field is changed from revisionable to non-revisionable and back again?Perhaps we could detect in
getDedicatedTableSchema
if the schema was being created for a previously shared table field which had been deleted, and was thus unlikely to change from non-revisionable to revisionable. In that sense we'd have less tables but also more complexity, at which point I'd ask, is it worth it? Perhaps worth further discussion in a follow up?Comment #40
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedHere is an attempt at this. Do we purge field data for all revisions of a field or only the default?
I had a read through
SqlContentEntityStorage::readFieldItemsToPurge
, but am a little out of my depth.Not confident this is the right approach to take or even why this works.
Comment #41
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented@Sam152, thanks for digging into this!
I think #39 is the proper answer for #36.1 (dedicated revision tables are created even for non-revisionable fields if the entity type itself is revisionable), and changing that is not in the scope of this issue.
So we just need a small update to the patch in #35 for #36.2 :)
Comment #42
plachAgreed, I just wanted to make sure it wasn't a bug in the test code, #36 makes sense to me as well, and given that at the time I was working on #2497737: Entity type revisionability is not taken into account when switching field revisionability, it's probably the right answer:
Let's just fix the nitpick and get this in :)
Comment #43
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThis simple change fixes the nitpick, so back to RTBC! Interdiff is to #35.
Comment #44
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedThanks @plach and @amateescu! Looks good to me.
Comment #46
plachCommitted bdba294 and pushed to 8.5.x. Thanks!
Comment #47
plachOops :)
Comment #48
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedCongrats on the first commit @plach! 🎉
Comment #49
mondrakeThis caused #2930197: EntityDefinitionUpdateTest fails with contrib db driver (again)
Comment #50
plachOuch :(