From 50e758cdb2e514f32d403a8f723aeeefd6413f91 Mon Sep 17 00:00:00 2001
From: Bingo-Soft
Date: Sun, 13 Oct 2019 20:27:12 +0300
Subject: [PATCH] Add support for DISTINCT clause
---
composer.json | 2 +-
composer.lock | 189 +++++++++---------
docs/en/reference/query-builder.rst | 15 ++
.../DBAL/Cache/ResultCacheStatement.php | 10 +-
lib/Doctrine/DBAL/Query/QueryBuilder.php | 53 +++--
.../Tests/DBAL/Functional/ResultCacheTest.php | 16 ++
.../Tests/DBAL/Query/QueryBuilderTest.php | 11 +
7 files changed, 184 insertions(+), 112 deletions(-)
diff --git a/composer.json b/composer.json
index fb2402a45aa..4a426e4881a 100644
--- a/composer.json
+++ b/composer.json
@@ -41,7 +41,7 @@
"doctrine/coding-standard": "^6.0",
"jetbrains/phpstorm-stubs": "^2019.1",
"phpstan/phpstan": "^0.11.3",
- "phpunit/phpunit": "^8.3.3, <8.4.0",
+ "phpunit/phpunit": "^8.4.1",
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0"
},
"suggest": {
diff --git a/composer.lock b/composer.lock
index d34e6af55c7..aa0428c2019 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "7502364f1cb482daff6265017e5e9f4f",
+ "content-hash": "120172ae44052999ec9a50b1121414cc",
"packages": [
{
"name": "doctrine/cache",
@@ -475,16 +475,16 @@
},
{
"name": "myclabs/deep-copy",
- "version": "1.9.1",
+ "version": "1.9.3",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72"
+ "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72",
- "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea",
+ "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea",
"shasum": ""
},
"require": {
@@ -519,7 +519,7 @@
"object",
"object graph"
],
- "time": "2019-04-07T13:18:21+00:00"
+ "time": "2019-08-09T12:45:53+00:00"
},
{
"name": "nette/bootstrap",
@@ -1249,35 +1249,33 @@
},
{
"name": "phpdocumentor/reflection-common",
- "version": "1.0.1",
+ "version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
- "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a",
+ "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a",
"shasum": ""
},
"require": {
- "php": ">=5.5"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.6"
+ "phpunit/phpunit": "~6"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src"
- ]
+ "phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1299,30 +1297,30 @@
"reflection",
"static analysis"
],
- "time": "2017-09-11T18:02:19+00:00"
+ "time": "2018-08-07T13:53:10+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "4.3.1",
+ "version": "4.3.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c"
+ "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c",
- "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
+ "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
"shasum": ""
},
"require": {
"php": "^7.0",
- "phpdocumentor/reflection-common": "^1.0.0",
- "phpdocumentor/type-resolver": "^0.4.0",
+ "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
+ "phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
- "doctrine/instantiator": "~1.0.5",
+ "doctrine/instantiator": "^1.0.5",
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^6.4"
},
@@ -1350,41 +1348,40 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2019-04-30T17:48:53+00:00"
+ "time": "2019-09-12T14:27:41+00:00"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "0.4.0",
+ "version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
- "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
+ "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
"shasum": ""
},
"require": {
- "php": "^5.5 || ^7.0",
- "phpdocumentor/reflection-common": "^1.0"
+ "php": "^7.1",
+ "phpdocumentor/reflection-common": "^2.0"
},
"require-dev": {
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^5.2||^4.8.24"
+ "ext-tokenizer": "^7.1",
+ "mockery/mockery": "~1",
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src/"
- ]
+ "phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1397,26 +1394,27 @@
"email": "me@mikevanriel.com"
}
],
- "time": "2017-07-14T14:27:02+00:00"
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "time": "2019-08-22T18:11:29+00:00"
},
{
"name": "phpspec/prophecy",
- "version": "1.8.1",
+ "version": "1.9.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76"
+ "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
- "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203",
+ "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
"sebastian/comparator": "^1.1|^2.0|^3.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
@@ -1460,7 +1458,7 @@
"spy",
"stub"
],
- "time": "2019-06-13T12:50:23+00:00"
+ "time": "2019-10-03T11:07:50+00:00"
},
{
"name": "phpstan/phpdoc-parser",
@@ -1586,16 +1584,16 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "7.0.7",
+ "version": "7.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "7743bbcfff2a907e9ee4a25be13d0f8ec5e73800"
+ "reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7743bbcfff2a907e9ee4a25be13d0f8ec5e73800",
- "reference": "7743bbcfff2a907e9ee4a25be13d0f8ec5e73800",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa0d179a13284c7420fc281fc32750e6cc7c9e2f",
+ "reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f",
"shasum": ""
},
"require": {
@@ -1604,7 +1602,7 @@
"php": "^7.2",
"phpunit/php-file-iterator": "^2.0.2",
"phpunit/php-text-template": "^1.2.1",
- "phpunit/php-token-stream": "^3.1.0",
+ "phpunit/php-token-stream": "^3.1.1",
"sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^4.2.2",
"sebastian/version": "^2.0.1",
@@ -1634,8 +1632,8 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "role": "lead",
- "email": "sebastian@phpunit.de"
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
@@ -1645,7 +1643,7 @@
"testing",
"xunit"
],
- "time": "2019-07-25T05:31:54+00:00"
+ "time": "2019-09-17T06:24:36+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -1789,16 +1787,16 @@
},
{
"name": "phpunit/php-token-stream",
- "version": "3.1.0",
+ "version": "3.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a"
+ "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e899757bb3df5ff6e95089132f32cd59aac2220a",
- "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff",
+ "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff",
"shasum": ""
},
"require": {
@@ -1834,20 +1832,20 @@
"keywords": [
"tokenizer"
],
- "time": "2019-07-25T05:29:42+00:00"
+ "time": "2019-09-17T06:23:10+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "8.3.3",
+ "version": "8.4.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "c319d08ebd31e137034c84ad7339054709491485"
+ "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c319d08ebd31e137034c84ad7339054709491485",
- "reference": "c319d08ebd31e137034c84ad7339054709491485",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/366a4a0f2b971fd43b7c351d621e8dd7d7131869",
+ "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869",
"shasum": ""
},
"require": {
@@ -1870,7 +1868,7 @@
"sebastian/comparator": "^3.0.2",
"sebastian/diff": "^3.0.2",
"sebastian/environment": "^4.2.2",
- "sebastian/exporter": "^3.1.0",
+ "sebastian/exporter": "^3.1.1",
"sebastian/global-state": "^3.0.0",
"sebastian/object-enumerator": "^3.0.3",
"sebastian/resource-operations": "^2.0.1",
@@ -1891,7 +1889,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "8.3-dev"
+ "dev-master": "8.4-dev"
}
},
"autoload": {
@@ -1906,8 +1904,8 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "role": "lead",
- "email": "sebastian@phpunit.de"
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
@@ -1917,7 +1915,7 @@
"testing",
"xunit"
],
- "time": "2019-08-03T15:41:47+00:00"
+ "time": "2019-10-07T12:57:41+00:00"
},
{
"name": "psr/log",
@@ -2186,16 +2184,16 @@
},
{
"name": "sebastian/exporter",
- "version": "3.1.0",
+ "version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
+ "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
- "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
+ "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
"shasum": ""
},
"require": {
@@ -2222,6 +2220,10 @@
"BSD-3-Clause"
],
"authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
@@ -2230,17 +2232,13 @@
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
}
],
"description": "Provides the functionality to export PHP variables for visualization",
@@ -2249,7 +2247,7 @@
"export",
"exporter"
],
- "time": "2017-04-03T13:19:02+00:00"
+ "time": "2019-09-14T09:02:43+00:00"
},
{
"name": "sebastian/global-state",
@@ -2919,16 +2917,16 @@
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.11.0",
+ "version": "v1.12.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "82ebae02209c21113908c229e9883c419720738a"
+ "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
- "reference": "82ebae02209c21113908c229e9883c419720738a",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
+ "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
"shasum": ""
},
"require": {
@@ -2940,7 +2938,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.11-dev"
+ "dev-master": "1.12-dev"
}
},
"autoload": {
@@ -2956,13 +2954,13 @@
"MIT"
],
"authors": [
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- },
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
@@ -2973,7 +2971,7 @@
"polyfill",
"portable"
],
- "time": "2019-02-06T07:57:58+00:00"
+ "time": "2019-08-06T08:03:45+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -3076,16 +3074,16 @@
},
{
"name": "webmozart/assert",
- "version": "1.4.0",
+ "version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
- "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
+ "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
- "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
+ "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
"shasum": ""
},
"require": {
@@ -3093,8 +3091,7 @@
"symfony/polyfill-ctype": "^1.8"
},
"require-dev": {
- "phpunit/phpunit": "^4.6",
- "sebastian/version": "^1.0.1"
+ "phpunit/phpunit": "^4.8.36 || ^7.5.13"
},
"type": "library",
"extra": {
@@ -3123,7 +3120,7 @@
"check",
"validate"
],
- "time": "2018-12-25T11:19:39+00:00"
+ "time": "2019-08-24T08:43:50+00:00"
}
],
"aliases": [],
diff --git a/docs/en/reference/query-builder.rst b/docs/en/reference/query-builder.rst
index 427380679de..059a70bef5f 100644
--- a/docs/en/reference/query-builder.rst
+++ b/docs/en/reference/query-builder.rst
@@ -87,6 +87,21 @@ and ``delete($tableName)``:
You can convert a query builder to its SQL string representation
by calling ``$queryBuilder->getSQL()`` or casting the object to string.
+DISTINCT-Clause
+~~~~~~~~~~~~~~~
+
+The ``SELECT`` statement can be specified with a ``DISTINCT`` clause:
+
+.. code-block:: php
+
+ select('name')
+ ->distinct()
+ ->from('users')
+ ;
+
WHERE-Clause
~~~~~~~~~~~~
diff --git a/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php b/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
index 8fbae62de29..f04c8524974 100644
--- a/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
+++ b/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
@@ -167,7 +167,15 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
*/
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
{
- $this->data = $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs);
+ $data = $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs);
+
+ if ($fetchMode === FetchMode::COLUMN) {
+ foreach ($data as $key => $value) {
+ $data[$key] = [$value];
+ }
+ }
+
+ $this->data = $data;
$this->emptied = true;
return $this->data;
diff --git a/lib/Doctrine/DBAL/Query/QueryBuilder.php b/lib/Doctrine/DBAL/Query/QueryBuilder.php
index 50c08655ff3..587e26656ab 100644
--- a/lib/Doctrine/DBAL/Query/QueryBuilder.php
+++ b/lib/Doctrine/DBAL/Query/QueryBuilder.php
@@ -52,22 +52,28 @@ class QueryBuilder
*/
private $connection;
+ /*
+ * The default values of SQL parts collection
+ */
+ private const SQL_PARTS_DEFAULTS = [
+ 'select' => [],
+ 'distinct' => false,
+ 'from' => [],
+ 'join' => [],
+ 'set' => [],
+ 'where' => null,
+ 'groupBy' => [],
+ 'having' => null,
+ 'orderBy' => [],
+ 'values' => [],
+ ];
+
/**
* The array of SQL parts collected.
*
* @var mixed[]
*/
- private $sqlParts = [
- 'select' => [],
- 'from' => [],
- 'join' => [],
- 'set' => [],
- 'where' => null,
- 'groupBy' => [],
- 'having' => null,
- 'orderBy' => [],
- 'values' => [],
- ];
+ private $sqlParts = self::SQL_PARTS_DEFAULTS;
/**
* The complete SQL string for this query.
@@ -469,6 +475,25 @@ public function select($select = null)
return $this->add('select', $selects);
}
+ /**
+ * Adds DISTINCT to the query.
+ *
+ *
+ * $qb = $conn->createQueryBuilder()
+ * ->select('u.id')
+ * ->distinct()
+ * ->from('users', 'u')
+ *
+ *
+ * @return $this This QueryBuilder instance.
+ */
+ public function distinct() : self
+ {
+ $this->sqlParts['distinct'] = true;
+
+ return $this;
+ }
+
/**
* Adds an item that is to be returned in the query result.
*
@@ -1083,8 +1108,7 @@ public function resetQueryParts($queryPartNames = null)
*/
public function resetQueryPart($queryPartName)
{
- $this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName])
- ? [] : null;
+ $this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName];
$this->state = self::STATE_DIRTY;
@@ -1098,7 +1122,8 @@ public function resetQueryPart($queryPartName)
*/
private function getSQLForSelect()
{
- $query = 'SELECT ' . implode(', ', $this->sqlParts['select']);
+ $query = 'SELECT ' . ($this->sqlParts['distinct'] ? 'DISTINCT ' : '') .
+ implode(', ', $this->sqlParts['select']);
$query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '')
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
diff --git a/tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php b/tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
index 35ce061b5b9..8d0a17c9b43 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
@@ -177,6 +177,22 @@ public function testFetchAllAndFinishSavesCache() : void
self::assertCount(1, $layerCache->fetch('testcachekey'));
}
+ public function testFetchAllColumn() : void
+ {
+ $query = $this->connection->getDatabasePlatform()
+ ->getDummySelectSQL('1');
+
+ $qcp = new QueryCacheProfile(0, 0, new ArrayCache());
+
+ $stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);
+ $stmt->fetchAll(FetchMode::COLUMN);
+ $stmt->closeCursor();
+
+ $stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);
+
+ self::assertEquals([1], $stmt->fetchAll(FetchMode::COLUMN));
+ }
+
/**
* @param array> $expectedResult
*/
diff --git a/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php b/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
index 610abc319a9..a210ef2fe73 100644
--- a/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
+++ b/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
@@ -50,6 +50,17 @@ public function testSimpleSelect() : void
self::assertEquals('SELECT u.id FROM users u', (string) $qb);
}
+ public function testSimpleSelectWithDistinct() : void
+ {
+ $qb = new QueryBuilder($this->conn);
+
+ $qb->select('u.id')
+ ->distinct()
+ ->from('users', 'u');
+
+ self::assertEquals('SELECT DISTINCT u.id FROM users u', (string) $qb);
+ }
+
public function testSelectWithSimpleWhere() : void
{
$qb = new QueryBuilder($this->conn);