diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 4739832..7a58904 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -245,6 +245,7 @@ Yii Framework 2 Change Log - Bug #2862: Using `DbCache` while enabling schema caching may cause infinite loops (qiangxue) - Bug #3052: Fixed the issue that cache dependency data is not reused when `reusable` is set true (qiangxue) - Bug #3691: Fixed the issue that `CookieCollection::has` always returns false for cookies from browser (sonicgd) +- Bug #4212: MSSQL query builder should not generate the `ORDER BY` clause when it is not needed (qiangxue) - Bug: Fixed `Call to a member function registerAssetFiles() on a non-object` in case of wrong `sourcePath` for an asset bundle (samdark) - Bug: Fixed incorrect event name for `yii\jui\Spinner` (samdark) - Bug: Json::encode() did not handle objects that implement JsonSerializable interface correctly (cebe) diff --git a/framework/db/mssql/QueryBuilder.php b/framework/db/mssql/QueryBuilder.php index bbf1249..6852c60 100644 --- a/framework/db/mssql/QueryBuilder.php +++ b/framework/db/mssql/QueryBuilder.php @@ -39,15 +39,6 @@ class QueryBuilder extends \yii\db\QueryBuilder Schema::TYPE_MONEY => 'decimal(19,4)', ]; -// public function update($table, $columns, $condition, &$params) -// { -// return ''; -// } - -// public function delete($table, $condition, &$params) -// { -// return ''; -// } /** * @param integer $limit @@ -71,11 +62,6 @@ class QueryBuilder extends \yii\db\QueryBuilder } } -// public function resetSequence($table, $value = null) -// { -// return ''; -// } - /** * Builds a SQL statement for renaming a DB table. * @param string $table the table to be renamed. The name will be properly quoted by the method. @@ -143,25 +129,19 @@ class QueryBuilder extends \yii\db\QueryBuilder /** * @inheritdoc */ - public function buildOrderBy($columns) - { - if (empty($columns)) { - // hack so LIMIT will work if no ORDER BY is specified - return 'ORDER BY (SELECT NULL)'; - } else { - return parent::buildOrderBy($columns); - } - } - - /** - * @inheritdoc - */ public function build($query, $params = []) { $query->prepareBuild($this); $params = empty($params) ? $query->params : array_merge($params, $query->params); + if (empty($query->orderBy) && ($this->hasLimit($query->limit) || $this->hasOffset($query->offset)) && $this->isOldMssql()) { + // hack so LIMIT will work because ROW_NUMBER requires an ORDER BY clause + $orderBy = 'ORDER BY (SELECT NULL)'; + } else { + $orderBy = $this->buildOrderBy($query->orderBy); + } + $clauses = [ $this->buildSelect($query->select, $params, $query->distinct, $query->selectOption), $this->buildFrom($query->from, $params), @@ -169,7 +149,7 @@ class QueryBuilder extends \yii\db\QueryBuilder $this->buildWhere($query->where, $params), $this->buildGroupBy($query->groupBy), $this->buildHaving($query->having, $params), - $this->buildOrderBy($query->orderBy), + $orderBy, $this->isOldMssql() ? '' : $this->buildLimit($query->limit, $query->offset), ]; @@ -189,7 +169,7 @@ class QueryBuilder extends \yii\db\QueryBuilder * Applies limit and offset to SQL query * * @param string $sql SQL query - * @param \yii\db\ActiveQuery $query the [[Query]] object from which the SQL statement generated + * @param \yii\db\Query $query the [[Query]] object from which the SQL statement generated * @return string resulting SQL */ private function applyLimitAndOffset($sql, $query)