Problem/Motivation
In Views on D7 there's code in views_many_to_one_helper as follows:
while ($r_join->left_table != $base_table) {
$r_join = views_get_table_join($r_join->left_table, $base_table);
}
Problems can arise if $r_join is invalid for some reason, e.g. a table becomes invalid or the join definition is incorrect.
In D7 the solution was to just add a check that $r_join was valid.
In D9 this code was moved to ManyToOneHelper.
Steps to reproduce
Add a missing table to your Views data and try to add a relationship to that table
The new test coverage shows it best.
Proposed resolution
For D9 we want to make sure we are not just masking the problem, but if you end up in this situation, that means your Views data is corrupt. At that point we need to fail hard to make sure the problem gets fixed.
Throw an exception when severely broken Views data is encountered.
Remaining tasks
Review
User interface changes
None
API changes
None
Data model changes
We throw an exception when severely broken Views data is encountered instead of looping endlessly
Release notes snippet
No needed
| Comment | File | Size | Author |
|---|
Issue fork drupal-2928757
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
dawehnerThanks a ton for creating the issue!
Comment #3
lendudeThis is the equivalent of the D7 fix for D8. The failing test simulates a missing join.
Comment #6
dawehnerWhat about calling it "non_existing_left_table". Given that should we also test what happens on a non existing right_table?
Comment #7
lendude@dawehner yeah that makes sense. Changed the wording.
Adding a test for the right_table seems out of scope here, fancy enough to get some explicit testing for ManyToOneHelper as it is.
Comment #8
dawehnerThank you @Lendude, especially for pinging me!
Comment #9
alexpottHow does the infinite loop occur? The test-only patch errors on trying to get a property of a non-object. Are we just hiding an error with this change?
Comment #10
alexpottSetting back to "needs review" so someone can answer #9.
Comment #11
lendude@alexpott you are right on both counts, we were just hiding the error and the test scenario wasn't the correct one to trigger the infinite loop.
Added a test for the infinite loop and instead of just quietly passing the error by, we now throw an exception when this happens, after all there is something seriously wrong when you run into this. But maybe that's a bit of overkill?
To test if we are inside a loop I've taken a page from
\Drupal\views\Plugin\views\query\Sql::ensurePathwhich already protects against that.Comment #12
dawehnerThis is indeed much better!
Can we document somehow how to resolve this for people? Like a table pointing to itself?
Comment #13
lendude@dawehner yeah that makes sense, something like this?
Comment #21
ranjith_kumar_k_u commentedRe-rolled #13 for 9.4.
Comment #22
alexpottThese need to confirm to our documentation standards. So we need a comment explaining each one. Also I think $alias is a string and $join will be a \Drupal\views\Plugin\views\join\JoinPluginInterface
Comment #23
yogeshmpawarResolved CS issues
Comment #26
pooja saraah commentedAttached patch against #23
Comment #27
pooja saraah commentedAttached patch against #26
Comment #28
lendudeThis should fix some of the fails and get rid of the unrelated changes.
Comment #29
lendudeUpdated the IS a bit
Comment #31
larowlanThis doesn't apply cleanly to 10.1.x, so we'll likely need two patches.
There seems to be a fair bit of duplication between the three test methods, especially around the handler/relationship setup - perhaps we could refactor some of that into a helper method to make it easier to maintain, as we're already at the rule of three here.
But other than that, the code looks good to me.
Comment #34
lendudeMoved to MR and rerolled
Comment #35
smustgrave commentedHiding patches for clarity.
Started the issue summary update but not as familiar with the issue so left TBD in sections that I couldn't answer. Is the proposed solution correct? Steps to reproduce?
Comment #36
lendudeUpdated the IS
Comment #37
smustgrave commentedThanks. Not sure because this is testing an infinite loop but when I tried to run the test-only feature it got hung up but did see an "E" in the output to show the failure.
So clearly test coverage is there haha.
Looking at the code change seems to appropriately catch the issue and throws the new exception.
Marking it but do new exceptions need a CR?
Comment #38
alexpottI've added some comments to the MR.
Comment #39
lendudeAddressed feedback. Not sure if the minor scope creep for php-stan is better than updating the base line and fixing it later, but it seems pretty minor so went for the fix
Comment #40
smustgrave commentedFeedback around the return null appears to have been addressed.
Comment #41
quietone commentedI'm triaging RTBC issues. I read the IS and the comments and the MR. I didn't find any unanswered questions or other work to do.
However, I left one small suggestion for a comment in the MR. So setting back to NW for someone to check that suggestion.