Skip to content

Commit 9d0f611

Browse files
committed
Fix row count with SQL_NO_CACHE
Signed-off-by: Maximilian Krög <maxi_kroeg@web.de>
1 parent 5a96d52 commit 9d0f611

3 files changed

Lines changed: 29 additions & 1 deletion

File tree

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"symfony/polyfill-ctype": "^1.17.0",
7979
"symfony/polyfill-mbstring": "^1.17.0",
8080
"symfony/polyfill-php80": "^1.16",
81+
"symfony/polyfill-php84": "^1.33",
8182
"twig/twig": "^3.3.5",
8283
"webmozart/assert": "^1.10",
8384
"williamdes/mariadb-mysql-kbs": "^1.2"

libraries/classes/Sql.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
use PhpMyAdmin\Utils\ForeignKey;
2222

2323
use function __;
24+
use function array_find_key;
2425
use function array_key_exists;
2526
use function array_keys;
2627
use function array_map;
28+
use function assert;
2729
use function bin2hex;
2830
use function ceil;
2931
use function count;
@@ -34,11 +36,13 @@
3436
use function is_array;
3537
use function is_bool;
3638
use function is_object;
39+
use function is_string;
3740
use function session_start;
3841
use function session_write_close;
3942
use function sprintf;
4043
use function str_contains;
4144
use function str_replace;
45+
use function strtoupper;
4246
use function ucwords;
4347

4448
/**
@@ -745,15 +749,30 @@ private function countQueryResults(
745749
/** @var SelectStatement $statement */
746750
$statement = $analyzedSqlResults['statement'];
747751

752+
assert($statement->options !== null);
753+
/** @var int|null $noCacheIndex */
754+
$noCacheIndex = array_find_key(
755+
$statement->options->options,
756+
/** @param mixed $value */
757+
static function ($value): bool {
758+
return is_string($value) && strtoupper($value) === 'SQL_NO_CACHE';
759+
}
760+
);
748761
$changeOrder = $analyzedSqlResults['order'] !== false;
749762
$changeLimit = $analyzedSqlResults['limit'] !== false;
750763
$changeExpression = $analyzedSqlResults['is_group'] === false
751764
&& $analyzedSqlResults['distinct'] === false
752765
&& $analyzedSqlResults['union'] === false
753766
&& count($statement->expr) === 1;
754767

755-
if ($changeOrder || $changeLimit || $changeExpression) {
768+
if ($changeOrder || $changeLimit || $changeExpression || $noCacheIndex !== null) {
756769
$statement = clone $statement;
770+
// Remove SQL_NO_CACHE from subquery because it is not valid sql
771+
if ($noCacheIndex !== null) {
772+
assert($statement->options !== null);
773+
$statement->options = clone $statement->options;
774+
unset($statement->options->options[$noCacheIndex]);
775+
}
757776
}
758777

759778
// Remove ORDER BY to decrease unnecessary sorting time

test/classes/SqlTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,14 @@ public static function dataProviderCountQueryResults(): array
538538
false,
539539
'SELECT COUNT(*) FROM (SELECT * FROM t1 UNION SELECT * FROM t2 ) as cnt',
540540
],
541+
[
542+
'SELECT SQL_NO_CACHE * FROM t1 WHERE id <> 0',
543+
['max_rows' => -1, 'pos' => 0],
544+
25,
545+
100,
546+
false,
547+
'SELECT COUNT(*) FROM (SELECT 1 FROM t1 WHERE id <> 0 ) as cnt',
548+
],
541549
];
542550
}
543551

0 commit comments

Comments
 (0)