Project

General

Profile

Actions

Bug #88919

closed

QueryBuilder with DefaultRestrictionContainer effectivly transforms outer joins to inner joins because the restrictions are applied to all join tables unconditionally

Added by S P over 5 years ago. Updated about 3 years ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Database API (Doctrine DBAL)
Target version:
-
Start date:
2019-08-05
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
9
PHP Version:
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

In an outer join (left or right join) one of the sides can be null.

But when using the QueryBuilder with it's DefaultRestrictionContainer it adds all conditions to all tables. Which is fine for inner joins but breaks outer joins (by efectivley kicking out rows that are fetched by the outer join, leaving one with teh same result as the inner join).

Consider this example (scenario: content inline in content):

SELECT c1.*
FROM tt_content AS c1
LEFT JOIN tt_content AS c2 on c1.parent_field = c2.uid
WHERE (c2 IS NULL OR c2.hidden = 0);

This would fetch all content rows but leave out the children whose parent is hidden.

Another example would be a join on pages to find pages by some parent page property.

Now you want this query with correctly respected TYPO3 fields (enable fields, deleted) and use the QueryBuilder. The QueryBuilder will add the DefaultRestriction container. So far so good. It will add the Restrictions to all join tables however, no matter if they're inner or outer joined. So it adds

c1.hidden = 0 AND c2.hidden = 0

which implcitly removes all join rows where the outer side is NULL. Leaving you implicitly with the inner join result.

As soon as an explicit outer join is requested the DefaultRestrictionContainer should only be applied to the from-table, not to the join-tables - or it should also add a OR join_table.uid IS NULL to the RestrictionContainer in case of outer joins.

For single-table or inner-join queries nothing has to change.

I found this on TYPO3 9, but assume this is true for 8 and 10 as well.

In case this is intended (can't believe this) this should at least be documented prominently - found this only by manually debugging the generated SQL statement to this that my left join condition was "short-circuited" by the DefaultRestrictionContainer.


Related issues 5 (0 open5 closed)

Related to TYPO3 Core - Feature #87776: Limit Restriction to table/s in QueryBuilderClosedManuel Selbach2019-02-24

Actions
Related to TYPO3 Core - Bug #86385: QueryBuilder restrictions break leftJoinClosed2018-09-26

Actions
Related to TYPO3 Core - Bug #94141: Hidden records are taken into account in m:n relations but instantiated as empty objects Closed2021-05-14

Actions
Related to TYPO3 Core - Bug #94119: Ghost record for field with mm relation when relation record is disabledClosedMarkus Klein2021-05-12

Actions
Has duplicate TYPO3 Core - Bug #32539: Using a constraint or ordering on a property on the right side of a m:n relation causes records from the left side with no related elements (0 cardinality) to not showClosed2011-12-14

Actions
Actions

Also available in: Atom PDF