From cddb036cf95e9ee0955d5154de25a76196dfd407 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Wed, 11 Nov 2015 21:05:57 +0300 Subject: [PATCH] Fixes #9790: Fixed `yii\db\sqlite\QueryBuilder` to generate proper SQL for UNION --- framework/CHANGELOG.md | 1 + framework/db/sqlite/QueryBuilder.php | 52 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 4e5ebbaaec..6536c63459 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -24,6 +24,7 @@ Yii Framework 2 Change Log - Bug #9707: Fixed Memcache duration which exceeds 30 days (vernik91) - Bug #9714: Fixed `yii\rbac\PhpManager::updateItem()` unable to save users assignments (rezident1307) - Bug #9754: Fixed `yii\web\Request` error when path info is empty (dynasource) +- Bug #9790: Fixed `yii\db\sqlite\QueryBuilder` to generate proper SQL for UNION (romeOz, samdark) - Bug #9791: Fixed endless loop on file creation for non-existing device letters on windows (lukos, cebe) - Bug #9874: Fixed outputting exception stacktrace in non-debug mode when `Response::FORMAT_RAW` is used (nainoon) - Bug #9883: Passing a single `yii\db\Expression` to `Query::select()` or `::addSelect()` was not handled correctly in all cases (cebe) diff --git a/framework/db/sqlite/QueryBuilder.php b/framework/db/sqlite/QueryBuilder.php index ab4c034da4..763ebdee3f 100644 --- a/framework/db/sqlite/QueryBuilder.php +++ b/framework/db/sqlite/QueryBuilder.php @@ -356,4 +356,56 @@ class QueryBuilder extends \yii\db\QueryBuilder return '(' . implode($operator === 'IN' ? ' OR ' : ' AND ', $vss) . ')'; } + + /** + * @inheritdoc + */ + public function build($query, $params = []) + { + $query = $query->prepare($this); + + $params = empty($params) ? $query->params : array_merge($params, $query->params); + + $clauses = [ + $this->buildSelect($query->select, $params, $query->distinct, $query->selectOption), + $this->buildFrom($query->from, $params), + $this->buildJoin($query->join, $params), + $this->buildWhere($query->where, $params), + $this->buildGroupBy($query->groupBy), + $this->buildHaving($query->having, $params), + ]; + + $sql = implode($this->separator, array_filter($clauses)); + $sql = $this->buildOrderByAndLimit($sql, $query->orderBy, $query->limit, $query->offset); + + $union = $this->buildUnion($query->union, $params); + if ($union !== '') { + $sql = "$sql{$this->separator}$union"; + } + + return [$sql, $params]; + } + + /** + * @inheritdoc + */ + public function buildUnion($unions, &$params) + { + if (empty($unions)) { + return ''; + } + + $result = ''; + + foreach ($unions as $i => $union) { + $query = $union['query']; + if ($query instanceof Query) { + list($unions[$i]['query'], $params) = $this->build($query, $params); + } + + $result .= ' UNION ' . ($union['all'] ? 'ALL ' : '') . ' ' . $unions[$i]['query']; + } + + return trim($result); + } }