-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #20239: fix yii\data\ActiveDataProvider
to avoid unexpected pagination results with UNION queries
#20311
base: master
Are you sure you want to change the base?
Changes from 1 commit
360bd90
0e6358d
e9a919c
96ff732
dcf8674
442761d
2bedcf4
30bc262
efb8b5e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -11,6 +11,7 @@ | |||
use yii\base\Model; | ||||
use yii\db\ActiveQueryInterface; | ||||
use yii\db\Connection; | ||||
use yii\db\Query; | ||||
use yii\db\QueryInterface; | ||||
use yii\di\Instance; | ||||
|
||||
|
@@ -93,14 +94,40 @@ public function init() | |||
} | ||||
|
||||
/** | ||||
* {@inheritdoc} | ||||
* Creates a wrapper of [[query]] that allows adding limit and order. | ||||
* @return QueryInterface | ||||
* @throws InvalidConfigException | ||||
*/ | ||||
protected function prepareModels() | ||||
protected function createQueryWrapper(): QueryInterface | ||||
{ | ||||
if (!$this->query instanceof QueryInterface) { | ||||
throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.'); | ||||
} | ||||
$query = clone $this->query; | ||||
$wrapper = clone $this->query; | ||||
if ($wrapper instanceof Query && !empty($wrapper->union)) { | ||||
$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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There might be more properties that needs to be reset. For example Or we cold use yii2/framework/db/ActiveQuery.php Line 355 in b0b7832
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a |
||||
} | ||||
return $wrapper; | ||||
} | ||||
|
||||
/** | ||||
* {@inheritdoc} | ||||
*/ | ||||
protected function prepareModels() | ||||
{ | ||||
$query = $this->createQueryWrapper(); | ||||
if (($pagination = $this->getPagination()) !== false) { | ||||
$pagination->totalCount = $this->getTotalCount(); | ||||
if ($pagination->totalCount === 0) { | ||||
|
@@ -161,11 +188,7 @@ protected function prepareKeys($models) | |||
*/ | ||||
protected function prepareTotalCount() | ||||
{ | ||||
if (!$this->query instanceof QueryInterface) { | ||||
throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.'); | ||||
} | ||||
$query = clone $this->query; | ||||
return (int) $query->limit(-1)->offset(-1)->orderBy([])->count('*', $this->db); | ||||
return (int) $this->createQueryWrapper()->limit(-1)->offset(-1)->orderBy([])->count('*', $this->db); | ||||
} | ||||
|
||||
/** | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we return
$this->query
if the condition isn't met right away?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather
return $wrapper;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?