Problem/Motivation
When creating a node view with both translatable and non translatable fields, the view filter on language adds a join condition on the langcode of all fields (even those that have not been translated). This causes no results to be found in the languages that are other than the default language the non translated field were saved in.
For the same reason sorting does not work on untranslated fields. Things are sorted as expected in on language, but not in another.
Proposed resolution
Before applying the join to langcode on the fields, check whether the field is translatable.
Remaining tasks
Add the watchdog error mentioned in #193.
Open a followup issue to Improve the query. See #157-#158
User interface changes
None.
API changes
None, I guess.
Original report by @vitalie
Comments
Comment #1
plachComment #2
upchuk commentedSteps to reproduce:
testIf you are in the default site language (EN), you should see the node you created with the title and test field value. But if you switch languages in the URL, the view won't find anything because of the join I mentioned in the issue summary. What it should do is show the title in FR with the test field value that is for all languages.
Comment #3
dawehner/
Comment #4
dawehner... its pretty major, honestly
Comment #5
plachMajor, at least. Testing this right now.
Comment #6
plach@Upchuck:
Ok, the issue is pretty clear. The main problem I see to fix it is that a view may be listing more than one bundle, hence the same field might be translatable in some cases and not translatable in others.
My proposal is to adapt the current code to do the following:
langcodecondition;LEFT JOIN node__field_test node__field_test ON node_field_data.nid = node__field_test.entity_id AND node__field_test.deleted = '0' AND ( node__field_test.langcode = node_field_data.langcode OR node__field_test.bundle IN ('article') )Comment #7
upchuk commentedHey @plach.
Thanks for the input. Working on a patch.
Comment #8
jhodgdonAre we talking about a views filter here, or the formatter? I'm confused about what is going wrong where.
Comment #9
upchuk commentedThis is it the level of the join caused by adding a views filter on the respective field (the questionably translated field) :)
Comment #10
jhodgdonReread the issue summary. It is a good issue summary. Sorry for getting confused. ;)
Comment #11
dawehner@Upchuk asked me to write a test, here is not even a proper start yet.
Comment #12
upchuk commentedLet's see what the bot says about it though.
Comment #14
upchuk commentedAlright, so here we have a start for a patch that we can work on.
I think I found a bug though related to the join build that happens inside
JoinPluginBase::buildJoin():The problem happens when inside the
extrakey we add a join condition with avalueas an array. In that case,$arguments += $local_arguments;correctly hydrates the $arguments array with the relevant argument => value. However, if you read down, there is a check if the 'field' key is contained. In this block, the absence of a 'left_field' (which due to the presence of the 'value' key I think is logical) the placeholder gets added again to the arguments array ('$placeholder' remaining set from the previous block). And down the line this causes an error in theConnection::expandArguments()because it misses brackets at the end of the placeholder AND that you have too many placeholders.huu, I hope this is clear :) I'm not sure if this is 100% a bug, hence I didn't open an issue. But if it is, we need to fix it before we can fix the current issue. In the patch, I manually remove the array value argument from the main $arguments array to fix this:
Comment #15
dawehnerThe reason why i'm a bit hesitate here is, that the implementation of the child class looks really similar to the parent class.
I'm wondering whether we could change the parent class in a way, so subclassing is easy.
Comment #16
upchuk commentedYeah, it's almost the same. But I think it's outside the scope of this issue no? And do you agree about the bug I found or that is how it should work? :)
Comment #17
dawehnerI think it would be a bad idea to get a patch in, which makes core more complex to maintain.
Comment #18
upchuk commentedSo here's a patch responsible for two things:
1 Refactor a bit the
buildJoin()method of theJoinPluginBaseclass so that it can be more easily extended2 Fix a bug I encountered and discussed with @dawehner on ICR related to a mismatch in the number of placeholders and condition values (In the next comment I will zoom into the small fix for this)
Regarding the refactoring, I'm not so sure. It's done through some logic delegation to other methods but a combination of returning data and updating it through reference. The
$argumentsarray is being built has to always be passed by reference. If you have any better alternative, please!! :)Comment #19
upchuk commentedThis is the bug fix I mentioned in the previous comment. It prevents the placeholder for the array of values to be added again (since it's already added earlier via the local arguments)
Comment #21
upchuk commentedLet's try this again.
Comment #22
dawehnerI really like the split you made:
a) build a single extra condition
b) build the join string out of the multiple extra conditions.
we could improve the parameter name in a follow up from $left to $left_table for example. ... I'm curious, can we add a typehint for the select query? On top of that, $left is not really optional if there is a parameter after it, which isn't.
Comment #23
upchuk commentedHey @dawehner, thanks for the review.
Sorry for no interdiff...
I guess we can move on with the actual fix for this issue no?
Comment #24
dawehner+1
Comment #25
gábor hojtsy@Upchuk: still working on this one?
Comment #26
upchuk commentedHey Gabor,
Yes, I am. A lot of the work is already done and can be found in the previous patch. I just need to re-apply the work on top of these changes we did in the last comments.
I've just been a bit swamped these days.
D
Comment #27
upchuk commentedSo here we go. The interdiff reflects changes from #23.
Comment #28
plachOverall looks good to me, however I'm not sure checking for field translatability in the views data handler is correct. I realize it makes things more performant, but I'm wondering whether we can ensure data is rebuilt every time field translatability changes.
@dawehner:
Would it be possible/make sense to do this at runtime? Or, does the current approach look correct to you? Also, you were mentioning test coverage might not be complete, right?
Quick code review:
Comments are not wrapping at column 80 correctly.
Comment #29
upchuk commentedHey @plach,
Daim, you are right. If you change field translatability without cache clear the changes won't be picked up. Where could we then handle this? In the join plugin? That seems to be called all the time.
Comment #30
plachAs we discussed, we should add a subscriber for
ConfigEvents::SAVEandConfigEvents::IMPORTto detect translatability changes for thefield.fieldandcore.base_field_overrideconfig objects, and invalidate views data cache via theviews_datacache tag.Comment #31
dawehnerI really like the extracting into the submethods!
Here is the promised test ... one has a odd result.
Comment #32
upchuk commentedThe interdiff is from #27 and the patch contains also the test in #31. In #31 it should fail and hopefully here it would pass.
I'm guessing that was forgotten there :)
Comment #33
upchuk commented@plach,
I forgot to mention in the previous comment. I had started implementing the listener but then i realized that whenever the language settings are saved at
admin/config/regional/content-language, the views data gets cleared already using a hook (views_field_config_update()). So there is no more need to add the listener. Also works when you import a field config.Comment #34
plachTranslatability may be changed also by programmatically saving a config field definition/override, we need to account for that, I think.
Comment #35
upchuk commentedWell, I suppose that programatically saving field configs would trigger the hook.
Comment #38
plachYes, but that works only with configurable fields, we need to do the same for the
base_field_overrideconfig entity.Comment #39
yesct commentedI talked to @Upchuk in IRC. They will not be able to get to this today, so unassigning.
Looks like the next thing is to look at the tests.... ? Anyway, someone can jump on this if they like. And @Upchuk can rejoin when available. :)
Comment #40
upchuk commentedA couple of things are left to do here I think:
Maybe also a reroll might be necessary since there's been so much progress during the sprint :)
I might check in tomorrow for 1.
Comment #41
upchuk commentedLooking into this a bit.
Comment #42
upchuk commentedI think the patch in #32 was broken a bit...didn't apply. This one should work.
Comment #43
skyredwangUpdate the status, since there is a new patch in #42
Comment #44
upchuk commentedSo here we go.
The interdiff contains the work needed to address what @plach mentioned in #38 and that is basically the only change from #42.
Comment #45
plachGreat work, we are almost there!
I know similar code is already existing in HEAD but I'm wondering whether we should escape variables to avoid SQL injections or whether we are sure those are safe.
hm
Mmmh, why? :)
This code should use the entity manager to retrieve and process all field definitions, not just configurable fields. We can use the table mapping (see
SqlContentEntityStorage::getTableMapping()) to determine which ones are stored in dedicated tables.Comments do not wrap at column 80.
This hook is invoked when instantiating a new entity object, I think we need
hook_entity_insert()instead.Given how much often these would be called, perhaps we should go back to the entity type specific form and implement it also for base field overrides.
Comment #46
upchuk commentedHey @plach,
Thanks for the feedback. I will defer to @dawehner for 1,2 and 3 (though 2 is just a typo). And maybe he can also consult on the rest :)
As for the rest:
4. A yes. Just realize I am only loading field configs and not base_field_overrides as well. Though I will bug you for a minute on IRC for some details.
5. Hm...thought I checked all the comments. Will take another look :)
6. I think you are right...though the previous version was using
createas well. Maybe @dawehner can also chime in.7. I used the more generic variants to avoid too much repetition there. But if it becomes unperformant, we can move to the entity type specific versions. But does it become unperformant?
Cheers!
Comment #47
plachWell, the repetition is one API method invocation, so I will turn the question. Is it repetition or just correct API usage? ;)
Comment #48
upchuk commentedWell, it's not an incorrect usage of the API :) The repetition I was talking about was the call to clear the Views data cache that currently is present in 3 functions and would have to now go into 3 more. I am really not sure of what the policy is here. I had talked to @dawehner about this and he said he prefers the more generic solution.
For me it's ok one way or the other.
D
Comment #49
plachFine for me, personally I'd prefer to call the same API method (cache invalidation) 6 times but doing it only when needed. That's the correct API usage (and not repetition) I was referring to :)
Btw, if we keep the current approach, we should have a separate function called from the three hook implementations to avoid repeating the if logic.
Comment #50
plach@upchuck:
What's the current status? Who is supposed to address my review?
Comment #51
upchuk commentedHey @plach,
Both me and dawehner. But I was away for more than a week so I couldn't do anything..Will pick up your feedback soon. Testing side is fully dawehner though.
Cheers!
Comment #52
plachupchuck++ :)
Comment #53
dawehnerupchuck asked me to reroll the patch. Alright, let's give it a try. This does not address comment #45 yet.
Comment #55
jibranThis is an api addition so we have to update IS. As it is an API addition we also need a change notice as well.
Extra space not needed.
Can we add a comment to explain this?
@param type missing.
Extra space not needed.
Can we please extend these comments to 80 char limit?
Can we please expand this how the join would actually look like?
Comment #56
upchuk commented@plach,
I addressed some of the easier stuff in #45. Regarding the "repetition" point, I left it like this for now and extracted the logic to a function. But do let me know if you insist on making it into separate hook implementations and I'll do it :)
Regarding point 4, Upon a further look, I'm not sure I understand why the base field override fields need to be loaded and processed. The `views_field_default_views_data()` function only seems to get passed field_config entity storage objects and no base_field_override ones. Maybe you can take a look?
@jibran,
Will address your issues as well shortly, didn't have a lot of time now.
Comment #57
upchuk commentedComment #59
plachYep, sorry, I think it would be better to go with
views_entity_field_config_[insert|update|delete]andviews_entity_base_field_override_[insert|update|delete]: it will highly reduce the amount of times those hooks are invoked. The separate function to encapsulate the logic looks fine, though.Because also base multiple fields are stored in dedicated tables. We should not assume an implementation, we should rely on the API to tell us which field definitions we have to deal with. However it seems all the views data code is acting only on configurable fields, so let's ignore this for now :(
PHP doc is not standard compliant
"join" should go in the previous line.
Comment #60
upchuk commentedHey @plach
Quickly addressed your two points in #59:
1. Done! However, removed the separate function because now the logic is really only one liner so no more need.
2. Fixed
Regarding the field_config vs base_field_override issue: indeed, only field_config are taken into account by views here. So leaving as it is for now.
Still remains #55 to address.
@dawehner, think you can see what's going wrong with the tests?
Comment #62
plachComment #63
deepakaryan1988Comment #64
deepakaryan1988Re-rolling the patch which is in #60
Comment #66
upchuk commentedThanks for the reroll.
What happened to this class?
Comment #67
gábor hojtsyWhile I think this should ideally be fixed, removing from sprint due to lack of activity in over a month.
Comment #68
deepakaryan1988@Upchuk I will take look on this upcoming Friday.
We are having internal code sprint. :)
Sorry for the delay.
Comment #69
sharique commentedFixing syntax error from #64.
Comment #70
sharique commentedAdding missing class FieldOrLanguageJoin.
Comment #75
upchuk commentedRerolling from #60 because other rerolls seem to be missing data. Hopefully this is ok..
Comment #77
googletorp commentedComment #78
lokapujyaThis code doesn't do anything. Plus, I think it's causing test failures.
For reference, getFieldLangcode is gone:
https://www.drupal.org/node/1867518#comment-9713165
Comment #80
lokapujyaThat only fixed two of them.That exposed another issue; the code I removed originally did something (back in the last green patch), and needs to be properly merged with changes in HEAD.Comment #81
dawehnerAs written on IRC, can't we do something like
$entity = $this->getEntityFieldRenderer()->getTranslation()Comment #82
upchuk commented@dawehner, I ran your test locally but it fails (no exception but assertion fails)...not sure what is going on...
Let's try to see if any other test fail without including your test here.
The patch contains the latest from #78 minus the test and test view.
Comment #83
upchuk commentedDamn git..here is the patch :)
Comment #84
lokapujyaUpchuk, did you try #81? If so, can you post it?
Comment #85
upchuk commented@lokapujya, no, sorry. We dropped that attempt as discussed on IRC.
Comment #86
lokapujyaSomething like this?
Comment #87
upchuk commented@dawehner, can you confirm #86?
Comment #90
upchuk commentedHere is a reroll off #86.
Comment #93
upchuk commentedSorry, I uploaded the wrong patch. Hope this will apply :)
Comment #96
dawehnerRerolled, now working on the failure
Comment #97
dawehnerThere we go.
Comment #100
dawehnerAlright, so the tasks are resolved
A little bit more explanation would be helpful I think. I think everyone should assume at any point that we are doing the right thing :P
Comment #101
plachLooks great!
Performed some minor coding standard clean-up. I'm not sure this needs a change record.
Comment #102
dawehnerYeah I don't believe either that this is a change record. Its almost like documenting that we have a new field formatter now.
Comment #105
lokapujyathe order of the results changed, and shows 1 fail, but it's still green?
Comment #106
dawehnerWell, let's add a sort criteria to ensure the behaviour and not cause any maybe even random failures on the testbot.
Comment #107
alexpottI thought this patch might fix the failures I'm seeing when you do this... it does not.
Comment #109
dawehnerYeah that totally doesn't make sense. locale is not about content translation, which is what this issue is about.
Comment #110
upchuk commentedHere we go. Added a sort on language to the view to match the expected array. Hopefully this will fix it :) Did locally..
Comment #111
upchuk commentedComment #113
dawehnerThank you @Upchuk
Comment #115
upchuk commentedComment #116
effulgentsia commentedDiscussed with @alexpott and Views incorrectly returning no results for a fairly common scenario like this one is a serious enough bug to justify fixing during RC.
Comment #117
alexpottWhy is this close necessary? I can't see why. If it is it needs documenting.
This needs more documentation as to what it is doing.
Comment #118
yobottehg commentedThis patch does not longer apply since 8.0.2. But the bug is there in 8.0.2
Comment #119
lokapujyaNeeds reroll according to #118.
Comment #120
AkshayKalose commentedRerolled
Comment #121
gvsoComment #123
lokapujyaComment #124
lokapujyarerolled. diffed the #120 patch and the files are identical.
Comment #127
lokapujyaPHP Fatal error: Cannot use Drupal\Core\Entity\EntityInterface as EntityInterface because the name is already in use in ./core/modules/views/views.module on line 21
Comment #128
lokapujyaComment #129
sharique commentedComment #130
holist commentedNeeds reroll after 8.0.3, I will also look into the comments by @alexpott in #117.
Comment #131
holist commentedI rerolled the patch, removed the dubious clone @alexpott mentioned (works fine for me, I didn't see the reason either), and improved the comments a bit but probably it needs more.
The patch seems to mostly do it's job, but I noticed one weirdness that definitely is a blocker: I have an integer field that is used in several bundles. I use the field for ordering rows in view. With the patch, the join plugin builds a join clause that OR's this field's bundle matching a different bundle than the one all the nodes in the current view belong to.
To make it more plain: I am ordering rows of nodes of bundle
courseonfield_priority, but the join clause saysnode__field_priority.bundle = 'management_personnel'.field_priorityis used on bothcourseandmanagement_personnel.The view's SQL before the patch:
and after patching:
And a small screen shot to illustrate the
node__field_prioritytable:Changing to "Needs work" for testbot, but really needs work.
Comment #132
holist commentedActually changing the status now. (And unassigning, can't put more time into this for now.)
Comment #133
lokapujyaInterdiff for 131, also showing the code affected by reroll.
Comment #134
lokapujyaI don't even have translation turned on. I added a field to two different bundles. I can reproduce the problem in #131. However, that makes no sense because that means that on one bundle the field is translatable and on the other it is not translatable. The "field OR language" join (introduced in this issue) only gets used when the field is translatable on certain bundles.
In summary, there is a bug ( I think) in Core, in that translatable is different for the 2 bundles. Also, there is an issue with this patch which we are trying to identify.
Comment #135
holist commentedOk now I think I understand what is happening. Our site did actually have the field translatable on one bundle and not on the other, I missed this earlier. If I disable translatability on one bundle, the OR clause changes to
(node__field_priority.langcode = node_field_data.langcode OR node__field_priority.bundle IN ( 'management_personnel', 'course' )). And vice versa, if both instances are translatable, no OR's with .bundle.So works as designed, but does it work as expected? Could we somehow check which bundles we are dealing with here and add only those? If I understand correctly, checking the translatability happens at
views_field_default_views_data(), but there it seems we don't have any knowledge of which bundles are being listed in the view. So to me, it seems the answer is no?So if I got this right, I think this behaviour should be added to the documentation that it causes no further confusion. I can do the patch for that. Considering what @alexpott wrote in #117, we have good progress here but someone still needs to check the test coverage per his request (asking humbly someone who knows what is going on there).
Comment #136
lokapujyaWill probably need a test to cover the joins described in #131-#135.
Comment #137
holist commentedNew patch with improved documentation.
Comment #139
holist commentedOops, wrong file, let's try again.
Comment #140
holist commentedTriggering testbot.
Comment #141
xjmThe core committers and Views maintainers (alexpott, xjm, effulgentsia, tim.plunkett, and dawehner) agreed that this is a major issue. It's not critical because there is no loss of data, but it is a severe bug that will cause incomplete (and therefore essentially broken) view results on many multilingual sites.
Comment #142
xjmComment #143
xanoMoving to 8.1.x since that's in beta now, and we must fix it there before we fix it in 8.0.x, or this would be a regression.
Comment #144
lokapujyaTried looking at this again. If I create two content types.
1. Create a new integer field on the first one,
2. Reuse the field on the second content type.
3. Export the configuration of both fields
The first has:
translatable: true
The second has:
translatable: false
So, this new join (in this patch) will be used on a view of the only the first content type. See comment #6.
Opened: https://www.drupal.org/node/2689339 Edit: Since closed this issue. The second content type need to be configured to be translatable.
Comment #145
dawehner@lokapujya So do you think this issue needs work?
Comment #146
lokapujyaFor the issue in #131.
and because the new (more complex) join (introduced in this patch) gets used when it's not needed. If the view is only showing one content type then it doesn't need the complex join.
Comment #147
lokapujyaClosed the issue that I opened in #144. That in itself is not an issue. The 2nd content type just needed to be configured to be translatable. But that doesn't change the fact that this new join still has a problem.
Comment #148
xjm@Xano Filing an issue against 8.0.x does not mean it will not be fixed in 8.1.x; just that it is patch-safe as well. OTOH looking at the patch here I agree this is best targeted for a minor version. Therefore, I'm actually moving this to 8.2.x for now.
This was marked as an RC target for 8.0.0. It's possible that it might also be an RC target for 8.1.0 as well based on the impact, but we can evaluate that using the RC target triage process if the issue is actually ready during RC.
Thanks everyone for your continued work here!
Comment #149
holist commentedOk, looked over this issue again. The issue in #131 is about bundle id being checked for if that bundle isn't translatable, because bundles not being looked at in the query are not filtered out. Strictly speaking, it is not good because the query gets more complexity, but without seeing an obvious way to filter the irrelevant bundles out, I lean towards to "it works" approach here. (Considering without the patch, it really does not work.)
Theoretically there could be some performance hit, but I suspect it won't be significant? Maybe profiling if it is a concern?
The latest patch contains a note that this is happening.
Tests though, they should be checked, anyone?
Comment #150
vasi commentedI agree that the extra query complexity is ok. It would be much more complex if each field join had to look through all the other query conditions, to figure out which bundles were allowed.
Comment #151
zolt_toth commentedThe patch in #139 has solved our problem but it cannot be applied for the codebase of 8.1.1. Could someone maintain it?
Comment #153
lokapujyaNeeds reroll for 8.2
Comment #154
ndewhurstI was also able to reproduce this issue and will look at re-rolling #139...
Comment #155
ashishdalviHi ndewhurst, lokapujya,
I am able to apply patch on 8.2.x. No Reroll required.
Comment #156
lokapujyaBack to needs review, since there are currently no actionable items to work on.
Comment #157
lokapujyaIs this condition any different than not having the condition at all?
Comment #158
holist commentedOn #157, @lokapujya, does the latter part of that OR clause result in any field of the given bundle(s) match? Then you're right, the condition is not very effective. Maybe it should rather check for LANGUAGE_NONE?
Comment #159
grubshka_v2 commented#139 fixed my issue (wrong sort order on untranslated number field)
Thanks !
Comment #160
yobottehg commentedDoes not apply any longer on 8.1.4. Needs a reroll and rebase.
Comment #161
yobottehg commentedi'll try to reroll
Comment #162
yobottehg commentedi hope i did everything right
Comment #165
yobottehg commentednew version without the mass replace error
Comment #167
yobottehg commentedone more try
Comment #168
yobottehg commentedForgot one Test
Comment #172
peacog commentedI've done a re-roll of the patch from #139 for 8.2.x, since #139 is the last one that passed. I've included a diff rather than an interdiff because a bug in my version of patchutils won't let me create an interdiff of patches that add new files.
Let's see if this one passes.
Comment #174
peacog commentedComment #176
mkernel commentedThe Patch from #172 worked for us - I just had to fix a minor typo. See attached diff.
Comment #177
lauriii@mkernel: Thank you for the patch. Next time please upload patch which includes all the changes so test bot can test it. Please also read this documentation which explains how to create a patch for Drupal.
I selfishly created the patch myself this time since I believe there is quite a few people using patch from this issue on their sites.
Comment #178
yobottehg commentedI think you don't want this in the patch
Comment #179
xanoComment #180
pminfAfter appling this patch I get a syntax error, when I filter on a not translatable field (in my case zip code field_service_zip_code):
Comment #181
xano@pminf: Please help us reproduce your problem by writing down detailed step-by-step instructions and/or by attaching a failing view configuration file to this issue.
Comment #182
pminf@Xano:
This morning I wanted to reproduce it to write a step-by-setp guide but I did not get the error again. I do not know why this happend yesterday but I will keep an eye on it.Sorry, I had an error while appling the patch. So I updated drupal core to 8.1.7 and applied the patch again with no problem. It's working fine!
Comment #183
swentel commentedThis had a fatal on one our installations where $config was simply empty .. not sure whether we should account for it or not.
- edit - Ok, so after skipping an empty $config, then clearing cache, and then commenting out the check whether it's empty or not, all is fine again. The thing is, it was impossible to even run update.php or cc with drush before, so quite annoying and almost impossible to recover from this one.
- edit 2 - Actually, after a full cache clear, we're back to fatals:
PHP Fatal error: Call to a member function isTranslatable() on a non-object in /home/project/core/modules/views/views.views.inc on line 368Comment #184
holist commentedAdded simple !empty() check to address @swentel's issue in #183.
Comment #186
lokapujyaWhich config is empty?
Comment #187
berdirVariable names here could IMHO be better. $config usually refers to simple config, this is a config entity.
Just use $fields and $field. and also $translatable_fields and so on.
The comment is also wrong, there are no field instances in Drupal 8, just field storages and fields.
@swentel: That said, if getBundles() returns something that doesn't exist as a field config, then something is really off. Apparently the field map on that site is out of sync, a field got deleted without updating that, maybe through a low-level config delete. You will have to clean that up manually.
This is not something that should happen. I guess we could use an entity query like this to load them in a way that it only loads those that actually exist:
$ids = \Drupal::entityQuery('field_config')
->condition('entity_type', $field_storage->getTargetEntityTypeId())
->condition('field_name', $field_storage->getName())
->execute();
but that would actually be slower here.
Comment #188
lokapujyaUpdating Remaining Tasks so some older things don't get forgotten.
Comment #189
holist commented@Berdir, if that shouldn't happen, should we then let the fatal error happen here?
Comment #190
berdirThat's always the question. I'm fine with keeping that for now, but while it shouldn't happen, it apparently did. Fatal errors are are bad, silently ignoring something like this too. We could throw an exception, but a non-developer won't be able to solve this himself, so really not sure.
Leave that part as it is for now.
Comment #191
holist commentedThanks @Berdir. If no one else does the variable name change, I'll take that on later today.
I also looked a bit into the discussion with @lokapujya in #157 and #158, doing that part differently would involve changing the whole logic of how the issue has been solved so far. As the current solution works and does not present any apparent problems, I'd rather just go with the current solution and leave open the possibility to improve the query in a follow-up.
Comment #192
swentel commented@Berdir So yeah, for some reason there was a storage field that had no field(s) anymore .. I can't really figure out what happened here since I didn't work on the project internally myself so it's a dark guess. You'd think that $field_storage->getBundles() would return false there, but it doesn't, so as you said, field map was out of sync for some reason and never corrected itself ? (haven't inspected that yet, will do so later)
That said, I'd vote keeping the check in the code, even though it means we have a problem somewhere else, but in this case it's very hard to recover from. The only way is to set a breakpoint and find out which field storage is causing the trouble.
(Ironically I had a somewhat similar problem the same day with a content entity where a term was deleted, but a field was still referencing to it and when trying to display it, it failed horribly)
Comment #193
berdirYeah, the new fieldmap approch has no capability to correct itself. If a change is not reported, then it has no way of finding that out. It's no longer just cached, it's persistently stored.
Agreed, failing with a fatal during cache rebuild is bad, so lets add a check, possibly with a watchdog error that reports the field name and bundle? I think a missing module works in a similar way and it's not easy to clean up either.
Comment #194
swentel commentedYeah, that was my first thought as well, just wondering whether we have a better place to report this, somewhere more up in the code closer to the field config entities ? Haven't looked closely, but I'm fine here too as a start and maybe a follow up to investigate it more in depth.
Comment #196
NobodyLikesGreg commentedWe used #184 in two cases. Once when working with a translated taxonomy field, there it worked. Then we needed it again for a date field and it doesn't work. Could that field still be an exception?
Comment #197
lokapujyaCan you elaborate on "it doesn't work"?
Issue Summary Changes: Added the watchdog error to "Remaining tasks". Changed "Improve the query" to "open a followup issue to improve the query."
Comment #198
willwh commentedThe last patch failed testing because of a duplicate key in `core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_config_translation_filter.yml`. I also provided an interdiff Let's hope the test bot likes it, it's passing locally :D
Comment #199
willwh commentedI see Berdir has requested some changes I didn't drop in here, and my patch was bunk too. (nid is not a valid entity_type ;) )
I'll post something up tonight as soon as I can get some time! :)
Comment #200
willwh commentedI'll come back to the rest later tonight :)
Comment #201
willwh commentedInterestingly, my patch in #198 has a false positive, insofar, given the actual config in the patch was not quite valid (entity_type: nid).
Anyway, here we go :)
Comment #202
holist commentedThanks @willwh for getting this forward.
Added logging for the empty config entity check.
Comment #203
willwh commentedAwesome, holist! :)
I've given this a test this morning. Let's hope we can get some more eyeballs on it with an RTBC! :)
Comment #204
dawehnerInteresting! I guess we don't validate views configurations somehow. Do you mind opening a dedicated issue to research that a bit?
F
Nitpick: can be dropped
Let's add type information to those parameters.
Is there a reason why
&$infois using a reference? I get&$argumentsbut maybe its just good to document, why we need that.Comment #205
willwh commentedOk, here we go!
I don't see $info being passed with a reference? Am I blind? :)
Comment #207
willwh commentedHmm, tests are passing locally, going to try this again?
Comment #208
dawehnerNope, but I am :)
I'm pretty sure this was just a random test failure, so let's see what happens. If its green, its RTBC. Great work
Comment #209
willwh commentedHooray :)
So, what did I do wrong, or is it not possible for me to re-queue a patch for testing?
Comment #210
holist commentedLooks green to me. Thanks @willwh for the final pushes.
Comment #211
holist commentedAnd should this go into 8.2.0 (beta) as well, being a bug fix?
Comment #212
alexpottThis should be here - it is part of the defgroup docs started at the beginning of the document.
Out of scope changes.
Seems out of scope too.
Comment #213
sic commentedHi guys,
do I have to apply both patches or is one (which one?) enough?
thanks
Comment #214
jibranI'd like to see some Kernel tests like
JoinTest::testBasePluginforFieldOrLanguageJoin.Comment #215
k4v commentedI tested this patch for a different problem:
Views cannot sort on fields that are untranslated for the same reason: The query always contains a join condition node__field_myfield.langcode = node_field_data.langcode.
The effect is that the view is correctly sorted in one language, but not in the other. The patch fixes this for me, thanks :).
A test would be also needed for the sorting problem, I think...
Comment #216
k4v commentedHere's a reroll with the changes from #212.
Comment #217
k4v commentedComment #218
k4v commentedComment #219
jibranComment #220
k4v commentedComment #221
k4v commentedComment #222
k4v commentedSo I worked a bit on the test, trying to add an untranslated weight field to the nodes. But I have no idea how to test the view for different languages...
Comment #223
pminfCould you please reroll the last patch for Drupal 8.2?
Comment #224
pminfSee attached my rerolled version of #217. Beware, it's my first patch.
Comment #225
yesct commentedneeds review to let the bot run on it. (we can then add a test for 8.2.x) [edit: huh. it knew it was 8.2.x? ok.]
Comment #227
martin_klimaI used a workaround until a patch ready for 8.2.x. Ispired by https://api.drupal.org/comment/62648#comment-62648.
Comment #228
lokapujyaMarting, did you try the patch? Do you think the patch will work for your problem? How does it differ from the code you posted?
Comment #230
k4v commentedComment #231
k4v commentedSo here is a version of the sort test. It's still not showing the right thing. When I test manually I can show that the nodes are in the right order in English, but in the wrong order in German.
In this version of the test, the result is in both cases english and the right order. Any idea how I can write the test so it shows the "right" wrong result?
Comment #232
k4v commentedComment #234
dawehnerDo you mind removing these orphan experimental code pieces :)
Did you maybe forgot something in the test, given its actually failing? Note: For this issue we should IMHO run the tests certainly on all available database engines.
Comment #235
tstoecklerJust something that at least makes the query in the test query for 'de', the test still fails with this.
Comment #236
tstoecklerOk with this I actually get the expected fail because of the incorrect ordering.
Comment #237
k4v commentedGreat! Here is a rerolled patch including the new test.
Comment #238
k4v commentedAnd here's the failing new test.
Comment #239
k4v commentedComment #241
tstoecklerNice! Passes/fails as expected
Comment #242
k4v commentedSo what would be the next steps to get this committed? Do we need more tests as requested in #214?
Comment #243
dawehnerI really like the new methods, as they describe what is done.
We could fix #214 by not extending from FieldTestBase but rather writing a kernel test. Therefor extend from
\Drupal\Tests\views\Kernel\ViewsKernelTestBaseMaybe check out some of the other classes extending that one. It should give you a good hint.Comment #244
SaytO commentedApply this solution: #227.
For now solve my problem, TY @martin_klima.
Comment #245
k4v commentedComment #246
peacog commentedThis needs a re-roll following on from the decision to use short array syntax in core #2776975: March 3, 2017: Convert core to array syntax coding standards for Drupal 8.3.x RC phase. Here's a patch.
I couldn't create an interdiff because it fails for some reason, so I've addad an ordinary diff instead.
Comment #247
peacog commentedI missed some arrays using long array() syntax in FieldApiDataSortTest.php. Here's an updated patch.
Comment #248
dawehnerHere is just some really quick feedback.
Is it just me that this seems to be an unrelated issue actually? I guess you used that to write the test coverage, right? What could be nice is to have explicit tests which deal which tests just that, without the language joining.
Comment #249
rodrigoaguileraMy team testing the latest patch on a drupal 8.3.0-rc2 installation and we are experiencing issues when importing configuration with "drush config-import"
I'm feeling this is an untested part of core.
Maybe this is related to the fact that the default language of the site is non-english and all our configuration is in that language.
I don't understand the reason why this fails now but I hope It can give you some information about the risk of this change.
Comment #250
rodrigoaguileraDigging more I found that it has to do with having config field translations in /config/sync/language/en/field.field.somentity.fieldname.yml
Making the static cache in the config factory to be corrupt(by only having the translated parts) and leading to the error I pasted.
So this is just triggering it with the following line from the patch
I'll investigate more but probably it won't belong here and it can be triggered by different means.
Comment #251
tstoecklerTalked to @rodrigoaguilera in Seville, and if I understood correctly #250 was caused by a separate issue and was able to be reproduced in HEAD. Would be nice for him or someone from his team to confirm, though.
Comment #252
rodrigoaguileraSorry for the late answer.
I think the issue that I found can't be blamed on this patch although this patch triggers it (there is other ways to trigger it).
I still have to gather some files to report the issue properly. I'll post it here but the work on this shouldn't be halted that's why I didn't change status.
At the moment we really need this patch so we deleted all English configuration since we don't really use it and we have English enabled just for the interface translations. This may be useful for someone as a workaround.
Comment #253
k4v commentedTo address #248 I created a followup: https://www.drupal.org/node/2866067. EntityField::getValue should return the right translation.
Comment #254
k4v commentedAs requested in #243 I replaced FieldApiDataSortTest with a KernelTest, now titled SortTranslationTest.
Comment #256
k4v commentedComment #258
tacituseu commented'Missing @group annotation in Drupal\Tests\views\Kernel\Handler\SortTranslationTest'Comment #259
berdirFixed that and some more comment clean-ups.
Comment #260
heldercor commentedWith latest patch from Berdir, in Drupal 8.3, I'm getting this error:
The lines in question:
The problem is that in
isset($substitutions[$value]),$valueis an array (see views_join_condition_2):The view has a filter for not empty (field_image).
This is without the patch:
Comment #261
tstoecklerComment #262
tstoecklerThis adds a kernel test for the new join plugin similar to
JoinTest::testBasePluginper #214. I actually copied some parts of that method over to the new test because the sole entry point for these join plugins is::buildJoin()but we are only overriding a specific sub-part of that, so I think it makes sense to make sure that we don't accidentally break the "normal" joining.So this completes the test coverage as far as I can see, so removing the "Needs tests" tag. Also @dawehner has approved on the general direction of this patch above as far as I can tell, so removing the "Needs subsystem maintainer review" tag as well.
Anyone care to RTBC? ;-)
Comment #263
dawehnerNice test coverage in #262!
The german in me would like to add some commas in the last sentence. Not sure which specific instance of the english language we follow, but one comma after "bundles" and another one after "untranslatable" makes this sentence, at least for me, more readable.
+1 again for the general refactoring here. This makes the code easier to understand.
I'm adding this point given some discussions in #2877593: Improve \Drupal\hal\LinkManager\RelationLinkManager::getRelations() documentation.
A review of the documentation of this method:
+1 for documenting test purposes!
Comment #264
k4v commentedwoot!
Comment #265
jibranNice work @tstoeckler. Sorry for being a buzz kill but we need some docs here. I also think we need a change notice for this as well.
We should add a configuration and SQL example to this doc block for better understanding just like
JoinPluginBase. TBH, I didn't understand the problem till I read the newly added KTB so I think docs are essential here. It can be something like this:SQL
'AND (node__field_tags3.bundle = :views_join_condition_5 OR node__field_tags3.langcode = .langcode)'Comment #266
tstoecklerComment #267
tstoecklerThis should fix the docs per #263 and #265. I hope this makes it more clear for everyone. I also took the liberty of a minor array re-ordering for consistency with the other conditions.
Re #265: Can you clarify why this needs a change notice? I'm not sure what that should contain, to be honest.
Comment #268
jibranThanks, for adding the docs. We are changing the default behavior here so I thought that's why we need a change notice here. I'll the committer decide that. Do we need an update/post-update hook to clear the cache for existing views?
Redundant blank space. It can be cleared out on the commit.
Comment #269
catchSorry this took so long to review, I found a couple of things.
On the update, we should add an empty post update if this is going to get committed to 8.3.x, but since 8.4.x will have other updates, one isn't needed for that.
Why &$extra in the foreach? I can't see the reference being used anywhere. If there's a reason for it, it could use a comment because it's not obvious.
Sine we unset $extras[$key] above sometimes, isn't it theoretically possible that count($extras) == 0 by the time we get here? If so should it not be
if (count($extras) > 1) {
}
else if ($extras) {
}
else {
// Not sure??
}
Also if it's theoretically possible, is that only due to a bug or is it a valid condition? If it's a valid condition looks like we're missing test coverage.
Why would $extras be empty when we've already checked is(array($this->extra)) above?
Is this a @todo/bug?
Extra blank line.
Comment #270
geertvd commented$extrascan't be empty in this situation, it will at least contain a['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]recordI rewrote that part a bit so it doesn't fatal if someone manages to get there without it anyway. I'm not sure if we should add test coverage for that case.
To answer the question
That field is untranslatable so it has a fallback to the original value which is "'field name 3: es'", not sure if that's correct so I left the comment in for now.
Comment #271
um commentedThanks for the patch.
#270 worked perfectly for me.
Comment #272
tstoecklerThis adds explicit test coverage per #269.2. Also extracted a helper function in the test to build the join information. This makes the interdiff a bit harder to read, but the resulting test looks a bit cleaner, IMO.
Also not sure why this is tagged "Needs change record", does anyone know?
Comment #273
tstoecklerThis time with an actual patch, not just a diffstat. Sorry.
Comment #275
pritishkumar commentedFixed the coding standard messages. Interdiff was not generated so couldn't upload.
It gave this error
The next patch would create the file /tmp/interdiff-1.arq4Hs,
which already exists!
Comment #276
lokapujya@pritish.kumar , Can you generate an interdiff between #270 and #275?
Comment #277
tstoecklerHere is the interdiff.
@pritish.kumar apparently you are using some tool to generate the interdiff which failed you in this instance. What I did was just apply the previous patch with
--indexthen reverse apply it and then apply the new patch. That doesn't always work, but most of the time it does, so hope that helps you for the next time ;-). Concretely, this is what I did in this instance:Hopefully someone can RTBC now ;-)
Comment #278
lokapujyaWhat was changed from #270 to #273?
Comment #279
tstoecklerOh, I totally missed, that I goofed up the interdiff in #272 as well, I thought that one was good. Here we go. Sorry about that.
Comment #280
jibranI thought this went in. RTBC again #269 is addressed.
Comment #282
catchCommitted 3469863 and pushed to 8.4.x. Thanks!
Comment #283
holist commentedWow good job everyone! Are we getting this in a patch release for 8.3.x too?
Comment #284
tacituseu commented#275 got committed and it ate defgroup ending @alexpott mentioned in #212.2.
Comment #285
jibranPlease create the followup issue.
Comment #287
cburschkaRe-rolled #275 + #284 on 8.3.7, for the benefit of anyone applying this patch with composer. (Encountered while upgrading from 8.2 to 8.3.)
Comment #288
cburschka[last reroll was incomplete]
Comment #289
ludo.r@cburschka,
Thank you very much for this 8.3.x patch! :)
For those that are trying this patch, don't forget to rebuild cache to see the effect.
Comment #290
qproIt seems to me that issue https://www.drupal.org/project/drupal/issues/3018025 is related to this issue, since it's trying to SUM the langcode field.
I'm right?