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.
When you have a field with dedicated storage (e.g. a base field with cardinality > 1), DefaultTableMapping::getFieldTableName() will not return the dedicated table that the field actually resides in.
Comment | File | Size | Author |
---|---|---|---|
#42 | 2644088-42.test.patch | 5.42 KB | plach |
#41 | interdiff.txt | 2.48 KB | amateescu |
#41 | 2644088-40.patch | 11.19 KB | amateescu |
Comments
Comment #2
dawehnerThat sounds indeed like a bug which should be solved.
Comment #3
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThis blocks #2477899: Multiple valued Base fields won't work in Views and at least two contrib modules have to work around the problem (Dynamic Entity Reference and Entityqueue), so I'm bumping to major.
Here's the relevant portion of the patch from #2477899: Multiple valued Base fields won't work in Views and a unit test for it.
Comment #6
dawehnerLooking into the failures for now.
Comment #7
dawehnerHere is a fix for that.
Regarding the actual patch, this looked perfect for me. First I thought you renamed variables for the sake of it, but this was actually required as
$definitions
is reused later again.Comment #8
kevin.dutra CreditAttribution: kevin.dutra at Workday, Inc. commentedLooks good to my eyes. RTBC+1
Comment #9
borisson_This looks like a great solution. I remember from working on #2477899: Multiple valued Base fields won't work in Views that the
$definitions
rename was needed.Comment #10
jibranI think @plach_ should eyeball this other then that +1 for RTBC.
Comment #11
alexpottI think this looks good too. I've pinged @plach about this issue in IRC.
As far as I can see the patch looks good - it comes with a test that fails if the fix is not applied and the changes make sense. Also I think this is an obvious bug fix that belongs in 8.0.x.
Comment #12
plachSorry, I don't understand this change: why are we excluding configurable fields?
Comment #13
alexpottChanging status given #11
Comment #14
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented@plach, I'm not sure either, it came from #2477899-11: Multiple valued Base fields won't work in Views - see the last paragraph of that comment.
If we remove that change from the patch and nothing breaks.. we're missing some more test coverage?
Comment #16
kevin.dutra CreditAttribution: kevin.dutra at Workday, Inc. commented@plach, excellent question. It's been too long at this point and I can't remember what reasoning I may have had (if any...I may have just been too focused on base fields).
EDIT: Heck, it may have just been to work around that wall of errors that just popped up. ;) Can't remember if I tried to go down that rabbit hole.
Comment #17
plachI think we do: the previous patch was green and IIRC configurable fields are supposed to be returned.
Comment #19
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedWell.. in HEAD they are not :) If you try this snippet:
you'll get a nice exception:
And with the patch, the correct table name is returned (i.e. node__body). Let's see if this small changes fixes all the failures from #14, and I'll work on adding an integration test for the default table mapping because phpunit tests can only take us so far...
Comment #20
kevin.dutra CreditAttribution: kevin.dutra at Workday, Inc. commentedThis patch adds a small integration test case which (I think) exposes another issue. I expect this to fail.
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.
To illustrate further, if the test were to use this code segment, where you use the current definitions to forcibly bypass the locally cached version, it would pass:
But I'm not sure that adjusting the test like that is really the right way to go.
The easy fix would be to simply remove the property and force it to be rebuilt every time. I'm not sure how bad the performance impact would be if that was done. It implements
onFieldStorageDefinitionCreate()
, but that appears to run prior to the save of the field storage, so that doesn't really help. As far as I can tell, there isn't any sort of post-save equivalent mechanism.Comment #22
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedAfter lots of digging around I finally have a firm answer for #12/#17:
SqlContentEntityStorage::getTableMapping()
is *not* supposed to return configurable fields, because of this line inside that method:and
\Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions()
only returns base field storage definitions: http://cgit.drupalcode.org/drupal/tree/core/lib/Drupal/Core/Entity/Entit...So I went back to the patch from #7 and added a small integration test class for DefaultTableMapping. Interdiff is to #7.
Comment #24
dawehnerPlease use the new base class:
\Drupal\KernelTests\Core\Entity\EntityKernelTestBase
Comment #25
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedWe need #2683391: Backport EntityKernelTestBase to 8.0.x if we want to do that.
Comment #26
dawehnerWell, do we really need this patch for 8.0.x still?
Comment #27
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedWhy not, 8.1.0 is still a month away :)
Comment #28
dawehnerWell, you could use one base class for the tests for one version and the old one for 8.0.x
Comment #29
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedYes, but it would be nicer to have a single patch for all three branches. Otherwise I wouldn't have bothered with #2683391: Backport EntityKernelTestBase to 8.0.x :)
Comment #30
kevin.dutra CreditAttribution: kevin.dutra at Workday, Inc. commentedThe backport for the EntityKernelTestBase went in, so this is unblocked. :)
Comment #31
kevin.dutra CreditAttribution: kevin.dutra at Workday, Inc. commentedAnd while I won't transition it to RTBC myself, based on the explanation in #22, I'll say RTBC +1.
Comment #32
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedUpdated the patch to use EntityKernelTestBase.
Comment #33
dawehnerThank you @amateescu!
Comment #34
jibranThank you @amateescu for working on this patch. Assigning it to @plach to review it one final time.
Comment #36
alexpottUnrelated random test fail see #2609874: Boolean field "On label" and "Off label" are not translatable
Comment #37
catchJust a note I'm leaving this RTBC at the moment in case plach is able to re-review before commit.
Comment #38
andypostLooks great and blocks entityqueue usage
Comment #39
xjmMarking for @plach's subsystem maintainer review but leaving at RTBC as @catch said.
Discussed with @Cottser, @effulgentsia, @alexpott and we agreed to look at this as an RC target given its impact and the fact that it is risky for a patch release.
Comment #40
plachI'm sorry, but I'm not convinced by this argument:
SqlContentEntityStorage::getTableMapping()
*is* supposed to return configurable fields, in factEntityFieldManager::getFieldStorageDefinitions()
returns thebody
storage definition of the related configurable field. Besides of this, if we agree thatuser__roles
should be part of the table mapping (and we do :), I don't see a reason on earth whynode__body
shouldn't be.The first sentence sounds a bit weird, but maybe it's just me.
Comment #41
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented@plach, you're right, I only looked at the code of
EntityFieldManager::getFieldStorageDefinitions()
and it seemed to return only base fields, but after some manual testing I can confirm that it does return configurable fields as well.So I added back the interdiffs from #14 and #19 to the latest patch and opened #2705205: Improve test coverage around updating table mapping after a new field storage definition is added for the problem discovered in #20.
Comment #42
plachThanks! And here's a test-only patch
Comment #43
tstoecklerPatch looks good to me. I agree it shouldn't land in a patch release.
Comment #44
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedWe also had one in #22 :P
Comment #45
plachThe patch looks great to me now, and tests fail/succeed as expected.
Comment #47
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented:)
Comment #50
effulgentsia CreditAttribution: effulgentsia at Acquia commentedPushed to 8.2.x and 8.1.x. I'm very happy that we waited for #40.1 to be addressed before committing this.
This patch doesn't add
getDedicatedRevisionTableName()
, which I think is okay, because the function returns the first matching table, and I don't think you can be in a situation where you wouldn't match the data table and match the revision table only. That said, is that logic also true for getRevisionTable(), in which case, should we remove that too? Or else, add a comment explaining why we have one but not the other? Either way, non-release-blocking follow-up material.Comment #51
plachThe current logic should be fine because we can have fields living only in the revision table, e.g.
revision_log
, while, as you were pointing out, we can't have a field living in a dedicated revision table while not living in the dedicated data table. A comment explaining this would definitely be helpful :)