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