Problem/Motivation
In relation_handler_relationship::query(), for the left
table, the relationship handler always adds a join instead of reusing an existing join. The result set is overstated / incorrect as it contains a cross product of unrelated rows from the database.
I am somewhat hesitant to file this issue. If this is truly a bug, then it very much surprises me that noone else has encountered this and reported it. If not, is there something that should be done differently in the setup described below?
Setup
Entities: two node bundles, A and B, connected by directional relation C.
Fields: each entity has various fields.
View relationships using relation: node -> node, node -> relation.
View fields: at least one from each entity.
Data: one instance of bundle A with N relations to N different instances of bundle B.
Expected
Result set should have N rows.
Actual
Result set has N x N rows.
Proposed resolution
In relation_handler_relationship::query(), for the left
table, use the ensure_table() method instead of add_table() method.
Remaining tasks
Review and test.
User interface changes
None.
API changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | 2417385-004-relation-ensure_table.patch | 1.43 KB | boombatower |
| #1 | 2417385-1-reuse-existing-join.patch | 1.03 KB | solotandem |
Comments
Comment #1
solotandem commentedAttached patch implements proposed resolution.
Comment #2
solotandem commentedIf verified, then this change also needs to be made to 8.x branch.
Comment #3
mikran commentedThis should be added as a test.
Comment #4
boombatower commentedAfter utilizing solotandem's patch we have discovered there is a bit more to the story in that views has a bug in ensure_table() that can be hit for certain relationships. So while add_table() is indeed the incorrect choice, certain combinations can cause issue in either setup.
With the related fix to views (#2617032: ensure_table() does not allow two distinct joins against base table and another, while also adding duplicate relations with different join types) the problem is completely resolved.
If one of us has time perhaps we will add a test, but we would happily accept contributions from others. This was a lot of work to debug. ;)
A test should constitute two joins from base table to the other endpoint entity and one which joins to the relation to which the base table entity is attached. With add_table() that will cause a cross-product. With ensure_table() (unpatched views) it should work as long as the two relationships share the same required state. I am sure someone can permutate the possibilities in a test without too much trouble. The issue is explained in detail in the linked views issue.