Problem/Motivation
The advertised behavior of the JoinPluginBase is to permit operators other than '=' in the relationship:
<excerpted from core/modules/views/src/Plugin/views/join/JoinPluginBase.php>
* Here are some examples of configuration for the join plugins.
*
* For this SQL:
* @code
* LEFT JOIN {two} ON one.field_a = two.field_b
* @endcode
* Use this configuration:
* @code
* $configuration = array(
* 'table' => 'two',
* 'field' => 'field_b',
* 'left_table' => 'one',
* 'left_field' => 'field_a',
* 'operator' => '=',
* );
However, the code ignores the operator directive - using '=' regardless of the configuration:
$condition = "$left_field = $table[alias].$this->field";
While this might seem to be a critical bug on it's face, this actually is consistent with the views relationship handler in drupal 7 (see related issue), so, I mark it as "Normal", but given that the use description in the plugin code advertises this behavior it seems that it should be remedied.
Steps to reproduce
Proposed resolution
Add the configured operator to the condition
Remaining tasks
Review
Commit
User interface changes
API changes
Data model changes
Release notes snippet
Comments
Comment #2
robertwb commentedComment #3
robertwb commentedLinking D7 backport of this issue with patch.
Comment #4
lendudeNot sure it I'd call this a bug, feels more like a feature (with a tiny bit of documentation already existing), but whatever.
No reason this shouldn't work as far as I can tell. This would need a fair amount of tests.
Comment #5
robertwb commentedHey @Lendude thanks for the speedy review - I am guessing that as far as not breaking existing behavior, the existing test coverage suffices, but in terms of verifying that it works as advertised, for sure. I have not written any D8 tests, and wonder if you can elaborate on where this test should live, i.e., as part of an existing file that tests the ViewsJoin class in "core/modules/views/tests/" or one of it's sub-folders? Like, should I expand "./core/modules/views/tests/modules/views_test_data/src/Plugin/views/join/JoinTest.php" or add a new file?
Also, any ideas on what test cases should be used would be welcome - I have my limited need-to-use-now test cases which are built on contrib modules so I will have to make these up from scratch as it were. Thanks again!
Comment #6
lendudeWe can but hope :) But it comes back green, so lets assume it doesn't break anything (and if it does, we just uncovered a hole in our test coverage).
Adding coverage to
\Drupal\Tests\views\Kernel\Plugin\JoinTestsounds like a perfect place to start. Either just add to testBasePlugin() or if you feel there is too much other test config in the way from previous assertions, add a new test method and start from there. Add tests for different operators and see what happens.Also we need to make really sure to run the tests on all supported databases (just queue some more tests after you upload a patch), because edge case stuff like this tends to break across different databases. I tried some other operators then = on Postgres and that seemed fine, but we have to be sure.
Comment #7
robertwb commentedThanks for the feedback @LenDude - I will proceed.
Comment #9
aerozeppelin commentedUpdates to patch as per#6.
Comment #10
lendudeTests are inline with existing coverage for these settings and look good.
Comment #11
alexpottShould we be worried about existing views with operators other than = now behaving very differently? I.e. do we need an upgrade path to change any operators to = so as to not have a behaviour change?
Comment #12
robertwb commentedI suppose that IS a worry. But, the only problem with forcing all to '=' upon update *should* only break installs that have previously applied this patch, however, there may be other sub-classes of the views_join class that do NOT suffer from this bug. If that were the case then forcing to '=' could be really problematic.
Comment #16
bwong commentedCould this be expanded to support the 'formula' operator that can be used in SQL conditions? This would be useful in referencing different tables to the left of the join. Right now I have to use 'formul' in a WHERE condition which is less efficient.
Comment #21
quietone commentedReroll
Comment #22
quietone commentedComment #23
lendudeRe #11 : As far as I can tell, this configuration would come from ViewsData and not Views config, so not sure how we could do an upgrade path for that. But might be missing something.
But it might be worth it to add a CR that if somebody had defined an 'operator', it will now actually get used.
Instead of falling back to a default here, wouldn't it be better to set this in the constructor where we are already setting some default values? That way we keep the default settings together.
So add it to this:
Comment #24
quietone commented#23. Updated the patch as requested.
Added a CR but needs instructions for what action to take, which I am not sure about.
Should a new example be added in JoinPluginBase?
Comment #25
lendudeThis doesn't need the ? because it is getting added with +=, which in effect already does the empty check. So less logic needed, which is good I think :)
Comment #26
lendudeCR looks great, added a short line about the possible steps you need to take to update your code.
Comment #27
quietone commented#25. Yes, of course. Should be fixed in this patch,
Glad you liked the CR.
Comment #28
larowlanYes this is my first thought too. We've had broken code for a long time, that might suddenly start working and cause an unintended consequence.
For that I think we should add a CR.
Comment #29
quietone commented@larowlan, do you mean the existing CR needs more information?
Comment #30
larowlanSorry, I missed that there was already a change notice
Comment #31
lendudeWe don't even need the ??, it can just be
'operator' => '=',right?
Comment #32
quietone commented@Lendude, sorry to keep taking your time.
Comment #33
lendudeThanks for taking the time to keep coming back to this :)
Nothing to add from me anymore, looks ready.
Comment #34
alexpottCommitted and pushed 1760fab770 to 10.0.x and 2ce5ee3db5 to 9.4.x. Thanks!
Given the CR only merged back to 9.4.x