Project

General

Profile

Actions

Bug #84779

closed

QueryInterface->execute() should do a rewind() before returning to avoid mismatch between content and count

Added by Stefan P about 6 years ago. Updated about 4 years ago.

Status:
Rejected
Priority:
Should have
Category:
Extbase
Target version:
-
Start date:
2018-04-18
Due date:
% Done:

0%

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

Description

It is possible to create situations in which the QueryResult content of a repository mismatches the QueryResult->count(). This seems to happen in statement() mode (writing raw SQL) and can also occur in language overlays (when not all or even none of the objects are translated). In these situations it is possible that, after the initial (raw or L=0) query is done, some objects are removed from the result (L>0 does not exist or enable fields are applied to the result from the raw statement), but the internal count is not updated then.

This is especially problematic for empty QueryResults that are presented as non-empty. In consequence <f:if condition="{queryResult}"> can return true for empty results or $queryResult->count() can mismatch. Doing f:debug (or a regular Extbase var_dump) on such a QueryResult shows the object as non-empty, but as soon as one tries to open the list of items it's empty.

Using the QueryResult only in a foreach loop does not have this problem, as the rewind is done implicitly then, though the \Iterable interface, but all non-\Iterable actions acting on the count() can behave weird.

In our projects we adopted to always doing ->rewind() before returning from the Repository find method. But ideally this should happen already in the execute() method automatically as the very last action before returning to ensure consitency between content and counter.

This happens in TYPO 7 and 8.

Actions #1

Updated by Stefan P about 6 years ago

  • Subject changed from QueryResult->execute() should do a rewind() before returning to QueryResult->execute() should do a rewind() before returning to avoid mismatch between content and count
Actions #2

Updated by Stefan P about 6 years ago

  • Subject changed from QueryResult->execute() should do a rewind() before returning to avoid mismatch between content and count to QueryInterface->execute() should do a rewind() before returning to avoid mismatch between content and count
Actions #3

Updated by Alexander Schnitzler about 4 years ago

  • Assignee set to Stefan Froemken
Actions #4

Updated by Stefan Froemken about 4 years ago

Hello Stefan,

sorry, I can understand this problem and I know this problem a long time. If your statement contains a JOIN, your aggregate root may appear multiple times, but with different related records. In that case extbase fetches the first aggregate root record and stores the mapped DomainModel in Session Object of Extbase. Processing the next record, which contains the same record as before, will not access the db again. Instead it will get DomainModel from Session Object. So you never have the possibility to create multiple aggregate roots with same UID and different related records each.
We can not call rewind() automatically by extbase as this will start mapping DomainModels directly. We have DBs queries with over 150.000 records. This will fill RAM drastically and counting the objects may feel like years.

Solving this issue performant incl. repairing all side-effects (Session-object) would nearly break everything.

You know how many records you have and how many you want to select. So IMO it would be better to close this ticket and call ->rewind() yourself.

Stefan

Actions #5

Updated by Alexander Schnitzler about 4 years ago

  • Status changed from New to Rejected
Actions

Also available in: Atom PDF