In handlers/views_handler_filter_boolean_operator_string.inc, the query() method is setting up a where clause string, and then calling:
$this->query->add_where($this->options['group'], $where);
This calls (in plugins/views_plugin_query_default.inc) the add_where() method on the query class, which adds it to the query conditions... but I think it should be calling add_where_expression() instead, because add_where() doesn't seem to handle a full where clause correctly, and the query is coming out IS NULL every time, even though the handler is setting the where clause to <> ''
Does that make any sense? What I'm trying to say is that the where clause from this filter is coming out (fieldname IS NULL) or (fieldname IS NOT NULL) even though the $where that the function calculates is either (fieldname = '') or (fieldname <> ''). The reason is that calling add_where() doesn't work for a where expression. You need to call add_where_expression() instead.
This patch fixes it. You might want to see if there are other places in Views where the same thing is happening too?
I encountered this in trying to set up a hook_views_data() by the way, so I don't have a way to test it directly in the UI... I'm not sure that filter is being used in Views anywhere directly?
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | vdc-2006560-23.patch | 8.66 KB | alexpott |
| handlerfilterbooleanstring.patch | 578 bytes | jhodgdon |
Comments
Comment #2
jhodgdonhandlerfilterbooleanstring.patch queued for re-testing.
Comment #3
jhodgdonI'm wondering if I dare to just mark this RTBC? It's a fairly obvious fix affecting one line of code, and the patch definitely works for me, and we'll need it on api.drupal.org the next time we update the API module, so that we can make a listing page of all items marked with @deprecated documentation tags. And your Views tests pass.
Yes, I dare to do it! You can always mark it back to "needs review" or "needs work" if you disagree. :)
Comment #4
jhodgdonIs it possible that this could get committed sometime soon?
I would like to deploy some new code from the API module to api.drupal.org sometime soon, and it depends on the fix to this issue. I can grab the dev version of Views, but dealing with a patch in the bzr repo there is kind of annoying... Please? :)
Comment #5
dawehnerCommitted but not pushed yet, but it will happen the next time I really come online.
Comment #6
jhodgdonIt does look to me as though the Drupal 8 code is probably making the same mistake.
The code is in
core/modules/views/lib/Drupal/views/Plugin/views/filter/BooleanOperatorString.php
and just like the D7 code, it's calling
$this->query->addWhere([group], $where).
on line 40.
However, I'm not sure what this addWhere() method is. It doesn't appear to be part of Views' QueryPluginBase class, which is what HandlerBase::$query is documented to be.
Oh I see. It's on the Sql class.
Yeah, it looks like it should be calling Sql::addWhereExpression() and not Sql::addWhere.
Comment #7
jhodgdonHere's a completely untested patch to fix this. I think it's correct but unlike in D7 I do not have code in place to test it.
Comment #8
jhodgdonSo... Shouldn't the QueryInterface class in D8 views have this addWhere method and others on it that SQL has, so that a Handler like Boolean String whatever it's called can call this method reliably? And shouldn't the $query member variable on the Handler base class be documented to be QueryInterface rather than QueryPluginBase? And yes these questions are both off-topic for this issue... but it's sloppy to say the least...
Comment #9
jhodgdonI checked the other filters in the same directory and I am pretty sure their calls to addWhere() are fine. None of them is attempting to pass in a string WHERE clause except this one. I didn't go back to Views 7.x contrib to check there.
I also looked at the arguments directory in D8 core Views and didn't see anything obvious there either.
So this one filter is probably the only place this problem occurs? hopefully.
Comment #10
jhodgdonWell, the test bot didn't complain. I'm not going to RTBC my own patch here because I didn't test it in D8, but the equivalent patch is definitely working in D7.
Comment #11
dawehnerWe haven't really made progress with defining a proper interface for queries, but the general problem is that query plugins are independent from things like the database, so something like addWhere might need a different interface if you are dealing with apache solr for example.
I would RTBC it, if there would be a test, but actually, do you know of any example where this handler could be actually useful in core, because then maybe already the HandlerAll test would be triggered and test what we need.
Comment #12
jhodgdonWell, let's see. I used it in the D7 API module... What I had is a database field with this hook_schema() definition:
This database field stores the description that people put after the @deprecated tag in API documentation.
And what I wanted to do is be able to use that to filter API documentation based on whether that database field was empty or not. So I put the following into hook_views_data():
And then I was able to use this as a filter in a view, to set up a page displaying all deprecated functions (which is coming soon to api.drupal.org, like maybe today or this week, now that the views 7 patch has been committed):
So this handler basically allows you to set up a filter for a text-containing database field that acts as a Boolean. I'm not sure if it would be useful in Core for anything or not... I cannot think of anything off-hand?
Comment #13
dawehnerJust wrote a test, but they don't work yet.
Comment #15
dawehnerThis was easy to fix.
The change in the base test class is indented, because it was useful here.
Comment #17
dawehnerThere we go.
Comment #18
jhodgdonThe documentation on the test class needs some work:
a) I think we need @inheritdoc on the getInfo() function?
b)
The word Boolean is a proper noun and should be capitalized.
c)
@return statements need a line of descriptive documentation as well.
d) There may be an extra blank line at the end of the test file.
e) It would also probably be good to attach just the test addition part of the patch so we can verify that it fails without the code fix (to verify that it is testing the actual bug reported here).
Comment #19
dawehnerI can't find a parent function also called getInfo(), so @inheritdoc would be kind of pointless
Comment #20
jhodgdonOK on (a). Stupid getInfo().
Anyway, the docs now look good, and I gave both the code patch and the tests a close review. They make sense to me. The patch is what was needed in Drupal 7 Views to fix this bug, and the tests certainly look like they are testing this exact functionality.
So assuming that the test bot returns red for the FAIL patch and green for the PASS patch, I believe this is good to go, and I'm marking it RTBC. I suppose that when the FAIL patch fails, the bot will change the status, but we can change it back then.
Comment #21
jhodgdonfixing inadvertent tag re-add
Comment #22
alexpottviews_get_view has been deprecated see #2032031: [Change notice] Deprecate use of views_get_view function in favour of Views::getView() method. We need to use \Drupal\views\Views::getView()
Comment #23
dawehnerGood catch!
Comment #25
alexpottRe-uploading patch because the test fail is interesting... I know I can press retest but it makes retrieving the borked test super hard. See #2057247: On really quick testbots LocaleUpdateCronTest can fail
No commit credit should be given!
Comment #26
alexpottComment #27
dawehnerI will try to look at the messages in the future in order to detect maybe other random failures.
Comment #28
jhodgdonBack to RTBC, since the two changes in the latest patch appear to have fixed all the views_get_view() calls.
Comment #29
alexpottCommitted c5b9bb0 and pushed to 8.x. Thanks!
Comment #31
ZenDoodles commentedPatch does not appear to have made it into 7.x-3.7. Original patch will probably work, but tests should prolly be backported too.
Comment #32
rudiedirkx commentedWhy handle it so differently from parent class
views_handler_filter_boolean_operator? I reused that logic, which usesadd_where()anddb_or():Makes more sense IMO.
Comment #33
jhodgdonThere was a patch for 7.x in the very early stages of this issue, which is here:
https://drupal.org/files/handlerfilterbooleanstring.patch
On comment #5, @dawehner said he committed it, but it may never have gotten pushed. Could we just get it committed and pushed?
Comment #34
micahw156Looks like this was committed for 7.x and is now included in 7.x-3.8 release.
http://cgit.drupalcode.org/views/commit/?id=356aee7686b96f6c15e262a2d5e4...
Comment #35
micahw156Whoops. Reopening -- didn't quite read the part about needing tests in #31.