diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php index f4d83ece134cf..e1b423d738a20 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php @@ -7,6 +7,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Ddl\Table; +use Magento\Framework\DB\Select; use Magento\Framework\Search\Adapter\Mysql\Aggregation\Builder as AggregationBuilder; use Magento\Framework\Search\AdapterInterface; use Magento\Framework\Search\RequestInterface; @@ -49,6 +50,16 @@ class Adapter implements AdapterInterface */ private $temporaryStorageFactory; + /** + * Query Select Parts to be skipped when prepare query for count + * + * @var array + */ + private $countSqlSkipParts = [ + \Magento\Framework\DB\Select::LIMIT_COUNT => true, + \Magento\Framework\DB\Select::LIMIT_OFFSET => true, + ]; + /** * @param Mapper $mapper * @param ResponseFactory $responseFactory @@ -86,7 +97,7 @@ public function query(RequestInterface $request) $response = [ 'documents' => $documents, 'aggregations' => $aggregations, - 'total' => count($documents) + 'total' => $this->getSize($query) ]; return $this->responseFactory->create($response); } @@ -115,4 +126,39 @@ private function getConnection() { return $this->resource->getConnection(); } + + /** + * Get rows size + * + * @param Select $query + * @return int + */ + private function getSize(Select $query): int + { + $sql = $this->getSelectCountSql($query); + $parentSelect = $this->getConnection()->select(); + $parentSelect->from(['core_select' => $sql]); + $parentSelect->reset(\Magento\Framework\DB\Select::COLUMNS); + $parentSelect->columns('COUNT(*)'); + $totalRecords = $this->getConnection()->fetchOne($parentSelect); + + return intval($totalRecords); + } + + /** + * Reset limit and offset + * + * @param Select $query + * @return Select + */ + private function getSelectCountSql(Select $query): Select + { + foreach ($this->countSqlSkipParts as $part => $toSkip) { + if ($toSkip) { + $query->reset($part); + } + } + + return $query; + } } diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php index a35e1fd8b6151..fbb56361bfe71 100644 --- a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php +++ b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php @@ -161,10 +161,16 @@ public function testQuery() $select = $this->getMockBuilder(\Magento\Framework\DB\Select::class) ->disableOriginalConstructor() ->getMock(); - $this->connectionAdapter->expects($this->once()) + + $this->connectionAdapter->expects($this->exactly(2)) ->method('select') ->willReturn($select); + $this->connectionAdapter->expects($this->once()) + ->method('fetchOne') + ->with($select) + ->willReturn($selectResult['total']); + $table = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class) ->disableOriginalConstructor() ->getMock();