Problem/Motivation
While working on #2503185: Specify a more specific cache context in FilterPluginBase, I found that the boolean filter does't work when is used the reverse condition 'Is not equal'. See the attached test-only patch.
The current behavior of using the reverse condition "Is not equal" has the opposite of the intended effect. For instance, adding an exposed node status filter using the "Is not equal" operator and value of "Yes" will display all published nodes and setting the value to "No" will display all unpublished nodes. This is demonstrated in the following screenshot.
Proposed resolution
1. Add a test to demonstrate the behavior.
2. Add logic to fix the equal/not equal operator behavior.
Remaining tasks
- Write test (done)
- Write patch (done)
- Manually test (done)
- Triage
This screenshot with the patch applied uses "No" instead of "Yes" as the value, but demonstrates that the operator "Is not equal" has been fixed.
User interface changes
None.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #40 | 2595169-39-BooleanOperator-is-not-equal-bug.patch | 1.04 KB | sam152 |
| #34 | 2595169-34-BooleanOperator-is-not-equal.patch | 7.05 KB | mikeker |
| #34 | 2595169-32-34.interdiff.txt | 642 bytes | mikeker |
| #32 | 2595169-32-BooleanOperator-is-not-equal.patch | 7.06 KB | mikeker |
| #32 | 2595169-25-32.interdiff.txt | 1.98 KB | mikeker |


Comments
Comment #3
claudiu.cristeaThe bug has been proved in #2. Here's the patch.
Comment #4
claudiu.cristeaSeems to be Major because a core Views handler doesn't work.
Comment #5
claudiu.cristeaFixed some docs and the case when "accept null" is
TRUEand the operator is!=.Comment #6
claudiu.cristeaforgot the patch :)
Comment #7
brandenlhamilton commentedI'll try and see if I can manually test this issue.
Comment #8
brandenlhamilton commentedI've manually tested this patch and it does appear to effect the advertise change.
Steps taken.
drush generate-content 20 --types=page,articleManually unpublished 10 nodes.
Manually edited the "Content" view.
Visual results attached.
Comment #9
dawehnerWell, RC eligible means for example documentation/test only changes, this is not the case here. Let's add 'rc target triage' instead.
Do you mind describing in the issue summary what 'doesn't work mean'? Is it not filtered at all, or do we see no items?
Comment #10
mradcliffeYes, I think this could be fixed in a patch release instead of 8.0.0, but could also make it into 8.0.0 because it has value and no cost.
Comment #11
dawehnerSure, but its the point of the rc target thing to focus on what is really important.
Comment #12
dawehnerThis fixes a bug, so we should IMHO allow that.
Comment #14
stefan.r commentedeither... or
Comment #15
mikeker commentedFixes #14.
Comment #16
catchThe double negative here really confuses me - could use a comment at least?
Also what's the likelihood that someone extends BooleanOperator?
Comment #17
dawehnerIs there more to boolean than boolean?
Comment #18
mradcliffeIt's possible that there is a field with extra data and the developer wants the query logic to be modified by some extra data. Probably something crazy like that.
Comment #19
mikeker commentedFrom #16:
Very high... We do it in core! :)
See
core/modules/user/src/Plugin/views/filter/Current.phpAgreed. In rereading the code, I don't think it's necessary. I've also cleaned up the
adminSummaryandqueryOpBooleanfunction signature.Comment #20
mikeker commentedComment #21
catchThat looks much better.
Given thus does get extended, do we need to be concerned about the change to the signature of queryOpBoolean? Given the extra argument has a default value, calling it's going to be fine, so it's only if it was overridden that it could be a problem.
Can think of ways to make the change without the theoretical bc break, but in this case it might just be OK to do it.
Comment #22
mikeker commented@catch, got it -- now I understand the concern about BooleanOperator being inherited. Didn't think of this as a BC break, but you're right that it would be...
In core, there's just the one filter plugin that inherits BooleanOperator. But who knows what's in contrib? DrupalContrib.org doesn't show any usages, but it's got pretty limited coverage.
So, is there wiggle room in the allowed changes for D8? If not, I can add a BC layer and mark it for removal in D9.
Comment #23
berdirflag seems to have a class that extends from that, for example. That's the only one outside of core that I have in my project.
Comment #24
mikeker commentedBased on that, we need a BC layer. I'll work on one shortly.
Comment #25
mikeker commentedQuick shot at a BC layer before I have to run out the door...
Edit: I should say I haven't tested this with Flag yet.
Comment #26
catch@mikeker we can make the original change fine in a minor release because protected methods are documented as @internal. We expect extenders of non-base classes to keep up, and in practice few or none would actually be affected.
However we're also trying not to change even @internal things in patch releases. So one option here would be to fix this without the helper, then have an 8.1.x follow up to add it. Or your patch with the new helper documented as @internal and with a leading underscore, which we then revert to the original patch in 8.1.x. This isn't a problem we've had before in the same way.
Comment #27
catchOK discussed with @xjm.
This is one of several issues where:
- the patch is fine for a minor version
- due to semver and our own approach to not breaking @internal things in patch releases, it's not fine for a patch release, but there ought to be simple enough way to do it in a patch-safe way
- requiring the patch-safe patch first, means we end up CNW-ing a patch that's fine for 8.1.x, then we have a patch to both branches, then another follow-up to get us back to where the original patch would have in 8.1.x which is double or triple the work.
- on top of that, the actual disruption/breakage from breaking semver here is very likely to be zero, but I think there's benefits to being strict on this, since as we rack up hundreds/thousands of commits to patch releases, we'll eventually hit a 'winner' the looser we are.
Trying this:
- moving this issue to 8.1.x
- RTBC for the patch in #19
- once that's committed, we can move it back to 8.0.x and 'to be ported' for the patch-safe fix.
Worst case, it never gets backported, everyone gets the fix in April when 8.1.0 is out anyway, which is better than the issue getting completely stuck on semver discussions.
Comment #29
catchOK, committed/pushed to 8.1.x, thanks!
Moving to 8.0.x for backport. Since #25 is a start on that, moving to CNW based on #26's review.
For me that's the easiest way to do this in a patch-safe way.
Comment #30
mradcliffeIf the 8.1.x commit broke BC, then does this need a change record?
Comment #31
mikeker commented@mradcliffe, I suppose it does. Draft CR is here: https://www.drupal.org/node/2635864. Feel free to publish if you feel it covers this issue. Thanks.
Comment #32
mikeker commented@catch, Thank you for thinking through the complicated contortions needed to get this into D8 as soon as possible. Much appreciated!
I believe this is what you're asking for...
Comment #33
claudiu.cristeaSeems a wrong indent? But can be fixed on commit.
Comment #34
mikeker commentedYeah, must've fat-fingered the tab key at some point... Fixed.
Comment #35
claudiu.cristeaCool. Anyway I can not RTBC it because i provided the original patch. Maybe somebody from the Views team?
Comment #36
claudiu.cristeaWell, in fact the original patch was RTBCed by @catch. What I'm reviewing and RTBC here is only the port to 8.0.x. And that wasn't provided by me. Good to go :)
Comment #37
catchCommitted/pushed the backport to 8.0.x, thanks!
Comment #40
sam152 commentedI could be mistaking the purpose of the 'accept_null' field in the views_data_definition, but I believe this has introduced a regression whereby "Is not equal to" used in conjunction with accept_null breaks.
SQL before the patch:
> AND( (some_bool <> '0') AND (some_bool IS NOT NULL ) )
SQL after the patch:
> AND( (some_bool <> '0') OR (some_bool IS NULL ) )
I don't know enough about the data definitions to say which result is correct and the accept_null is barely used in core, so it's going to be annoying to come up with concrete test cases.
Comment #41
wturrell commentedI appear to still have this issue - or another that shows the same symptoms - in 8.7.6?
Specifically, setting 'is not equal to' doesn't change the operator from = to !=
#3073518: 'Is not equal to' operator ignored on exposed, grouped filter