Fix #20239: fix yii\data\ActiveDataProvider to avoid unexpected pagination results with UNION queries#20311
Fix #20239: fix yii\data\ActiveDataProvider to avoid unexpected pagination results with UNION queries#20311Izumi-kun wants to merge 9 commits intoyiisoft:masterfrom
yii\data\ActiveDataProvider to avoid unexpected pagination results with UNION queries#20311Conversation
…ted pagination results with UNION queries
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #20311 +/- ##
============================================
+ Coverage 64.85% 64.86% +0.01%
- Complexity 11435 11437 +2
============================================
Files 431 431
Lines 37193 37203 +10
============================================
+ Hits 24120 24131 +11
+ Misses 13073 13072 -1 ☔ View full report in Codecov by Sentry. |
|
Let's exclude |
|
@rob006 would you please take a look? |
| } | ||
| $query = clone $this->query; | ||
| $wrapper = clone $this->query; | ||
| if ($wrapper instanceof Query && !empty($wrapper->union)) { |
There was a problem hiding this comment.
Can we return $this->query if the condition isn't met right away?
if (!$wrapper instanceof Query || empty($wrapper->union)) {
return $this->query;
}There was a problem hiding this comment.
I decided to keep the original logic (not reusing the original query):
yii2/framework/data/ActiveDataProvider.php
Lines 98 to 104 in b0b7832
yii2/framework/data/ActiveDataProvider.php
Lines 162 to 168 in b0b7832
Should I change it?
| $wrapper->where = []; | ||
| $wrapper->limit = null; | ||
| $wrapper->offset = null; | ||
| $wrapper->orderBy = []; | ||
| $wrapper->selectOption = null; | ||
| $wrapper->distinct = false; | ||
| $wrapper->groupBy = []; | ||
| $wrapper->join = []; | ||
| $wrapper->having = []; | ||
| $wrapper->union = []; | ||
| $wrapper->params = []; | ||
| $wrapper->withQueries = []; | ||
| $wrapper->select('*')->from(['q' => $this->query]); |
There was a problem hiding this comment.
There might be more properties that needs to be reset. For example ActiveQuery has on and joinWith (and sql?) properties, that may leak to wrapper. Developer may extend these classes and create own properties with the same problem. Query needs some kind of reset() method, that would be responsible for resting query state.
Or we cold use new Query(), similar to ActiveQuery::queryScalar():
yii2/framework/db/ActiveQuery.php
Line 355 in b0b7832
There was a problem hiding this comment.
Using a new Query() will break prepareModels() itself if query is an ActiveQuery and the expected return value of ActiveQuery::all() is array of objects rather then an array of arrays. I'll think about the solution a little more.
|
I don't really like the implementation, it looks like a workaround. The design of the query build doesn't allow for a more proper solution without breaking BC. Or am I missing something? |
|
Moved to next milestone for now. |
|
@Izumi-kun any idea about better solution? |
No any new solutions without BC. |
Related PR: #20246