Paginator with output walker returns count 0 when the query has previously been executed #12183
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When the
Paginator
creates the dedicated count query, it starts with a clone of the query underlying the pagination.If that query has previously been executed, it contains a result set mapping (RSM) in the
AbstractQuery::$_resultSetMapping
property. That RSM may have been provided by the user, or, more probably, will have been created by the DQL parser when the query was first analyzed.Either way, the RSM does not match or accurately reflect the actual count query. The count query modifies at least the select clause through either an output or a tree walker. That change needs to be reflected in the RSM for hydration to work correctly.
In the output walker case, the code in
Paginator::getCountQuery
even creates and sets a new RSM explicitly. In the tree walker case, the RSM was not taken care of.My current suggestion is not to clone the query in preparation for counting the items, but instead create a copy of the query to start with. This will leave the RSM as
null
in the new query.I was wondering whether there might be any good reasons to keep the existing RSM since it might have been provided by the user. But, since we modify the query and completely replace the select clause with the scalar expression for counting the rows, I don't see how any pre-existing RSM could apply to the new query.
Nevertheless, reviewers might want to take a step back and consider other options we might have to fix this:
Query::__clone
marks a query as dirty when it is cloned. Should a dirty query drop its RSM to make sure it is re-created upon the nextparse()
?$_resultSetMapping
property and keep/use them unconditionally, but treat parser-derived RSMs differently and forget about them as soon as the query gets dirty?