1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-09 16:17:48 +02:00

Fix counting rows with grouping outside MySQL

This commit is contained in:
Jakub Vrana
2013-07-03 18:40:55 -07:00
parent 4a6b289c8e
commit 063ddcced5
2 changed files with 32 additions and 18 deletions

View File

@@ -981,6 +981,22 @@ function is_shortable($field) {
return ereg('char|text|lob|geometry|point|linestring|polygon', $field["type"]); return ereg('char|text|lob|geometry|point|linestring|polygon', $field["type"]);
} }
/** Get query to compute number of found rows
* @param string
* @param array
* @param bool
* @param array
* @return string
*/
function count_rows($table, $where, $is_group, $group) {
global $jush;
$query = " FROM " . table($table) . ($where ? " WHERE " . implode(" AND ", $where) : "");
return ($is_group && ($jush == "sql" || count($group) == 1)
? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query"
: "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query$group_by) x" : $query)
);
}
/** Run query which can be killed by AJAX call after timing out /** Run query which can be killed by AJAX call after timing out
* @param string * @param string
* @return array of strings * @return array of strings

View File

@@ -237,18 +237,14 @@ if (!$columns) {
$page = $_GET["page"]; $page = $_GET["page"];
if ($page == "last") { if ($page == "last") {
$query = " FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : ""); $found_rows = $connection->result(count_rows($TABLE, $where, $is_group, $group));
$found_rows = $connection->result($is_group && ($jush == "sql" || count($group) == 1)
? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query"
: "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query$group_by) x" : $query)
);
$page = floor(max(0, $found_rows - 1) / $limit); $page = floor(max(0, $found_rows - 1) / $limit);
} }
$query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page); $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
if (!$query) { if (!$query) {
$query = "SELECT" . limit( $query = "SELECT" . limit(
(+$limit && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from, ($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from,
($where ? "\nWHERE " . implode(" AND ", $where) : "") . $group_by, ($where ? "\nWHERE " . implode(" AND ", $where) : "") . $group_by,
($limit != "" ? +$limit : null), ($limit != "" ? +$limit : null),
($page ? $limit * $page : 0), ($page ? $limit * $page : 0),
@@ -273,12 +269,10 @@ if (!$columns) {
} }
$rows[] = $row; $rows[] = $row;
} }
// use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest) // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
if ($_GET["page"] != "last") { if ($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql") {
$found_rows = (+$limit && $group && $is_group $found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode
? ($jush == "sql" ? $connection->result(" SELECT FOUND_ROWS()") : $connection->result("SELECT COUNT(*) FROM ($query) x")) // space to allow mysql.trace_mode
: count($rows)
);
} }
if (!$rows) { if (!$rows) {
@@ -448,15 +442,19 @@ if (!$columns) {
if (($rows || $page) && !is_ajax()) { if (($rows || $page) && !is_ajax()) {
$exact_count = true; $exact_count = true;
if ($_GET["page"] != "last" && +$limit && !$is_group && ($found_rows >= $limit || $page)) { if ($_GET["page"] != "last") {
$found_rows = found_rows($table_status, $where); if (!+$limit) {
$found_rows = count($rows);
} elseif ($jush != "sql" || !$is_group) {
$found_rows = ($is_group ? false : found_rows($table_status, $where));
if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) { if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
// slow with big tables // slow with big tables
$found_rows = reset(slow_query("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : ""))); $found_rows = reset(slow_query(count_rows($TABLE, $where, $is_group, $group)));
} else { } else {
$exact_count = false; $exact_count = false;
} }
} }
}
if (+$limit && ($found_rows === false || $found_rows > $limit || $page)) { if (+$limit && ($found_rows === false || $found_rows > $limit || $page)) {
echo "<p class='pages'>"; echo "<p class='pages'>";