diff --git a/src/Database/QueryCompiler.php b/src/Database/QueryCompiler.php index 96c974dcf4a..67e528fb415 100644 --- a/src/Database/QueryCompiler.php +++ b/src/Database/QueryCompiler.php @@ -135,6 +135,9 @@ protected function _buildSelectPart($parts, $query, $generator) { $driver = $query->connection()->driver(); $select = 'SELECT %s%s%s'; + if ($query->clause('union')) { + $select = '(SELECT %s%s%s'; + } $distinct = $query->clause('distinct'); $modifiers = $query->clause('modifier') ?: null; @@ -253,10 +256,10 @@ protected function _buildUnionPart($parts, $query, $generator) $parts = array_map(function ($p) use ($generator) { $p['query'] = $p['query']->sql($generator); $p['query'] = $p['query'][0] === '(' ? trim($p['query'], '()') : $p['query']; - $prefix = $p['all'] ? 'ALL' : ''; - return sprintf('%s (%s)', $prefix, $p['query']); + $prefix = $p['all'] ? 'ALL ' : ''; + return sprintf('%s(%s)', $prefix, $p['query']); }, $parts); - return sprintf("\nUNION %s", implode("\nUNION ", $parts)); + return sprintf(")\nUNION %s", implode("\nUNION ", $parts)); } /** diff --git a/src/Database/SqliteCompiler.php b/src/Database/SqliteCompiler.php index 43a94eeda5a..2fca318d2f6 100644 --- a/src/Database/SqliteCompiler.php +++ b/src/Database/SqliteCompiler.php @@ -24,6 +24,25 @@ */ class SqliteCompiler extends QueryCompiler { + /** + * Helper function used to build the string representation of a SELECT clause, + * it constructs the field list taking care of aliasing and + * converting expression objects to string. This function also constructs the + * DISTINCT clause for the query. + * + * @param array $parts list of fields to be transformed to string + * @param \Cake\Database\Query $query The query that is being compiled + * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions + * @return string + */ + protected function _buildSelectPart($parts, $query, $generator) + { + $clause = parent::_buildSelectPart($parts, $query, $generator); + if ($clause[0] === '(') { + return substr($clause, 1); + } + return $clause; + } /** * Builds the SQL string for all the UNION clauses in this query, when dealing