From 3ed515fbb316e81e3ffe09a8ec20e4da568a0df6 Mon Sep 17 00:00:00 2001
From: Sebastian Hofer <sebastian.hofer@marit.ag>
Date: Tue, 28 Nov 2017 22:31:34 +0100
Subject: [PATCH] [BUGFIX] get count consistent with execute for self written
 statements

Fix wrong result for self written sql statements executing count
on the query result.

To get this consistent, check for statement also in
getObjectCountByQuery and run getObjectDataByQuery
for self written statements. After that count the
rows.

Wrapping the statement in a subselect will
may be break doLanguageAndWorkspaceOverlay
in getObjectDataByQuery.

This is just to be consistent. Normally it does not
make sense to call the count method on a self written
statement.

Releases: master, 8.7
Resolves: #82910
Change-Id: I8bddb1b20d062d9f46939c16885f1eb73df1e5f4
Reviewed-on: https://review.typo3.org/54844
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Joerg Boesche <typo3@joergboesche.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
---
 .../Generic/Storage/Typo3DbBackend.php        | 56 +++++++++++--------
 1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php b/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
index cc2166d6172a..75bd84ac0a9a 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
@@ -456,32 +456,40 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
             throw new BadConstraintException('Could not execute count on queries with a constraint of type TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Qom\\Statement', 1256661045);
         }
 
-        $queryParser = $this->objectManager->get(Typo3DbQueryParser::class);
-        $queryBuilder = $queryParser
-            ->convertQueryToDoctrineQueryBuilder($query)
-            ->resetQueryPart('orderBy');
-
-        if ($queryParser->isDistinctQuerySuggested()) {
-            $source = $queryBuilder->getQueryPart('from')[0];
-            // Tablename is already quoted for the DBMS, we need to treat table and field names separately
-            $tableName = $source['alias'] ?: $source['table'];
-            $fieldName = $queryBuilder->quoteIdentifier('uid');
-            $queryBuilder->resetQueryPart('groupBy')
-             ->selectLiteral(sprintf('COUNT(DISTINCT %s.%s)', $tableName, $fieldName));
+        $statement = $query->getStatement();
+        if ($statement instanceof Qom\Statement
+            && !$statement->getStatement() instanceof QueryBuilder
+        ) {
+            $rows = $this->getObjectDataByQuery($query);
+            $count = count($rows);
         } else {
-            $queryBuilder->count('*');
-        }
+            $queryParser  = $this->objectManager->get(Typo3DbQueryParser::class);
+            $queryBuilder = $queryParser
+                ->convertQueryToDoctrineQueryBuilder($query)
+                ->resetQueryPart('orderBy');
+
+            if ($queryParser->isDistinctQuerySuggested()) {
+                $source = $queryBuilder->getQueryPart('from')[0];
+                // Tablename is already quoted for the DBMS, we need to treat table and field names separately
+                $tableName = $source['alias'] ?: $source['table'];
+                $fieldName = $queryBuilder->quoteIdentifier('uid');
+                $queryBuilder->resetQueryPart('groupBy')
+                             ->selectLiteral(sprintf('COUNT(DISTINCT %s.%s)', $tableName, $fieldName));
+            } else {
+                $queryBuilder->count('*');
+            }
 
-        try {
-            $count = $queryBuilder->execute()->fetchColumn(0);
-        } catch (DBALException $e) {
-            throw new SqlErrorException($e->getPrevious()->getMessage(), 1472074379);
-        }
-        if ($query->getOffset()) {
-            $count -= $query->getOffset();
-        }
-        if ($query->getLimit()) {
-            $count = min($count, $query->getLimit());
+            try {
+                $count = $queryBuilder->execute()->fetchColumn(0);
+            } catch (DBALException $e) {
+                throw new SqlErrorException($e->getPrevious()->getMessage(), 1472074379);
+            }
+            if ($query->getOffset()) {
+                $count -= $query->getOffset();
+            }
+            if ($query->getLimit()) {
+                $count = min($count, $query->getLimit());
+            }
         }
         return (int)max(0, $count);
     }
-- 
GitLab