Problem/Motivation
When using Entity Field Query to query a revisionable entity and calling:
$query->allRevisions()
If you set a condition on an entity reference where the target entity type DOES NOT support revisions then the you get a fatal error form \Drupal\Core\Entity\Query\Sql\Tables::ensureEntityTable because \Drupal\Core\Entity\Query\Sql\Tables::addField will attempt to use the revision tables of the target entity even though they do not exist.
The simplest way to demonstrate this is to write a Entity Query to find all the node revisions that have a term in field_tags where the name equals a value.
$query = $this->entityTypeManager()->getStorage('node')->getQuery('AND');
$query->condition('field_tags.entity.name', $search_str);
$query->allRevisions();
$ids = $query->execute();This code throws the error.
Here is github demo repo that provides a module that demonstrates this problem.
Proposed resolution
Instead of directly using the "allRevision" metadata from the query use an $use_revisions variable which will be update if \Drupal\Core\Entity\Query\Sql\Tables::addField
determines the field is using a "valid relationship" through an entity reference field.
Remaining tasks
Complete patch
Write Tests
User interface changes
None
API changes
None
Data model changes
None
| Comment | File | Size | Author |
|---|---|---|---|
| #42 | 2649268-nr-bot.txt | 144 bytes | needs-review-queue-bot |
| #32 | 2649268-32.patch | 2.99 KB | rpayanm |
| #28 | interdiff-2649268.txt | 2.28 KB | dawehner |
| #28 | 2649268-28.patch | 2.97 KB | dawehner |
| #24 | 2649268-24-test-only.patch | 3.26 KB | hchonov |
Comments
Comment #2
tedbowPatch attached
Comment #3
tedbowComment #4
tedbowFor background I found this bug when a Scheduled Updates update runner plugin that will be add to the Workbench Moderation module.
I need to find all node revisions(or other entities) that reference Schedule Updates(non-revisionable entity) where the "update timestamp" is less that now. This works if am not looking for revisions and also works with patch in #2 applied.
Comment #6
tedbowUn-assigning myself. Still think this is an issue and would be great to get a review.
Comment #10
duneblpatch #2 doesn't apply properly on 8.5
Here is how I got this error:
[file_field_paths module is enable]
1- edit user's image field property: admin/config/people/accounts/fields/user.user.user_picture
2-in the "File (Field) Path settings" check "Retroactive update"
3-save the form
4-I got the following error:
Comment #11
amateescu commented@tedbow, I'm not sure the variable name should be changed from
all_revisionstouse_revisioin, it seems to me that the only real change needed is the last hunk from the patch :)Also, as noted in #10, this patch needs a reroll and some test coverage.
Comment #13
wim leersComment #14
esod commentedRerolled the patch for Drupal 8.6.x. Unfortunately, it doesn't solve our problem.
We have a problem similar to this with one of our custom modules. The module added a boolean field to the node_field_data table. During cron the value of the field is checked and act on (or not) accordingly. In hindsight it was not a good idea to use node_field_data, but since the custom module does things on every node on the site, it seemed like a good idea at the time. Before Drupal 8.5.x and content moderation, it worked fine.
I'll probably fix the problem by creating a custom table for the boolean field and the node_id. The custom field is not revisionable, which is the cause of my error.
My error message:
Comment #15
hchonov@esod, could you please provide more details? How exactly do you add the field? Is it translatable? Is it revisionable? Does it have cardinality? I think that your problem deserves a separate issue.
Also it would be nice if you could address @amateescu's remarks from #11:
Comment #16
hchonovAs I am currently working on issues in this area I've decided to write a test for the issue here, but unfortunately my test isn't failing. So did the issue go away in the meanwhile? Do we still want to commit this test ensuring this won't break again?
Comment #18
esod commented@hchonov, Sure. We added the field with this code in the module file.
As you can see, the cardinality is set to 1. The field is a boolean whose only content can be NULL, 0, or 1 so we didn't think about translations, nor do I think we need to. The fact that this field is not revisionable is why my custom module is now broken. :-\
Comment #19
esod commentedPer #11 here's a version of the reroll without changing $all_revisions to $use_revisions. Although since we're talking about using revisions, isn't it a good idea to keep the variable name change? Fwiw.
Comment #20
tedbowSetting to "Needs Review" to test #19
Comment #21
hchonov@tedbow, could you please confirm if the bug you've reported is still present? I think that the test from #16 is testing exactly this, but it isn't failing.
Comment #23
tedbowI don't think the bug still exists.
I didn't ride a test at the time but I did make a test module: https://github.com/tedbow/d8_core_test
It doesn't through the error any more.
I wonder if this issue fixed it: #2700261: allRevisions() entity queries ignore non-revisionable fields
Comment #24
hchonov@esod, do you mind opening a new issue for your problem?
@tedbow, do you think that the attached test reflects the initial problem described here? If so, do you think it is useful to commit it or simply close the issue? I personally think the more tests we have in that the direction the better.
P.S. I think that the issue you've referenced - #2700261: allRevisions() entity queries ignore non-revisionable fields - has solved the problem indeed.
Comment #25
tedbow@hchonov I do think it would be good to have a test for this. Because it wasn't actually fixed on purpose so it could easily break again if something else changes and we don't have a test.
I haven't had time to look at the test in detail but in the comments of the test I don't think it says it explicitly testing this from my original summary:
I think the we should explicitly state so the test doesn't get change in the future or if users because revisionable the test won't cover it anymore.
so actually is there test entity type that is explicitly not revision-able that we would join with?
Comment #26
hchonovI can add this to the comments.
This is already happening in the test, as it is adding a condition on the name of a referenced user entity and the user entity type isn't revisionable. Beside it there is the entity_test entity type, which isn't revisionable as well.
Comment #27
esod commented@hchonov, would you please explain how entity_test is not revisionable? Does your patch make that clearer? Does your patch make it clearer that the user entity entity type isn't revisionable? I'm curious to know.
Btw, I fixed my module. I changed
->setCustomStorage(TRUE)to->setCustomStorage(FALSE)since I'm not using custom storage. I also added->setRevisionable(FALSE)to be sure. I'd like my field to be revisionable, but it's not necessary for our current needs.I didn't mean for my problem to be an issue for the community. I was just looking for answers and came across this issue. Thanks.
Comment #28
dawehnerTrying out this patch on my jsonapi usage didn't fully fixed the issue. It still tries to join to the wrong table.
Here is a patch which helped with that.
Comment #30
duneblNeeds reroll for 8.7-dev
Comment #31
ajitsUpdating to correct status based on #30.
Comment #32
rpayanmComment #33
ajits@rpayanm - Thank you for the reroll. It is advisable to remove the "Needs reroll" tag when the reroll is done.
Comment #38
jnicola commentedWhoops, wrong issue! Sorry!
Comment #42
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.