]> git.joonet.de Git - adminer.git/commitdiff
Fix counting rows with grouping outside MySQL
authorJakub Vrana <jakub@vrana.cz>
Thu, 4 Jul 2013 01:40:55 +0000 (18:40 -0700)
committerJakub Vrana <jakub@vrana.cz>
Thu, 4 Jul 2013 01:40:55 +0000 (18:40 -0700)
adminer/include/functions.inc.php
adminer/select.inc.php

index 54038828f6e8ea225d073d3857f13d361e8a3e16..41c231e8e5c71f39a389e0acd1fab7d241517d4b 100644 (file)
@@ -981,6 +981,22 @@ function is_shortable($field) {
        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
 * @param string
 * @return array of strings
index df3c3af0afe7b4e6d1fe3e8c74681566ffb2148c..621aab8674ec6e2c3dc2ac5ed1b0157ad8e58ecb 100644 (file)
@@ -237,18 +237,14 @@ if (!$columns) {
        
        $page = $_GET["page"];
        if ($page == "last") {
-               $query = " FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : "");
-               $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)
-               );
+               $found_rows = $connection->result(count_rows($TABLE, $where, $is_group, $group));
                $page = floor(max(0, $found_rows - 1) / $limit);
        }
 
        $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
        if (!$query) {
                $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,
                        ($limit != "" ? +$limit : null),
                        ($page ? $limit * $page : 0),
@@ -273,12 +269,10 @@ if (!$columns) {
                        }
                        $rows[] = $row;
                }
+               
                // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
-               if ($_GET["page"] != "last") {
-                       $found_rows = (+$limit && $group && $is_group
-                               ? ($jush == "sql" ? $connection->result(" SELECT FOUND_ROWS()") : $connection->result("SELECT COUNT(*) FROM ($query) x")) // space to allow mysql.trace_mode
-                               : count($rows)
-                       );
+               if ($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql") {
+                       $found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode
                }
                
                if (!$rows) {
@@ -448,13 +442,17 @@ if (!$columns) {
                
                if (($rows || $page) && !is_ajax()) {
                        $exact_count = true;
-                       if ($_GET["page"] != "last" && +$limit && !$is_group && ($found_rows >= $limit || $page)) {
-                               $found_rows = found_rows($table_status, $where);
-                               if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
-                                       // slow with big tables
-                                       $found_rows = reset(slow_query("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : "")));
-                               } else {
-                                       $exact_count = false;
+                       if ($_GET["page"] != "last") {
+                               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)) {
+                                               // slow with big tables
+                                               $found_rows = reset(slow_query(count_rows($TABLE, $where, $is_group, $group)));
+                                       } else {
+                                               $exact_count = false;
+                                       }
                                }
                        }