From 665fafb297a1daac06e87ad688763dd5a15054c6 Mon Sep 17 00:00:00 2001 From: Jakub Vrana Date: Fri, 9 Mar 2018 18:06:19 +0100 Subject: [PATCH] Simplify running slow queries --- adminer/drivers/mysql.inc.php | 10 ++++++++++ adminer/drivers/pgsql.inc.php | 5 +++++ adminer/drivers/simpledb.inc.php | 6 ++++++ adminer/include/driver.inc.php | 8 ++++++++ adminer/include/functions.inc.php | 12 +++++------- changes.txt | 1 + 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 71e1a825..f995cc52 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -298,6 +298,16 @@ if (!defined("DRIVER")) { return queries($prefix . implode(",\n", $values) . $suffix); } + function slowQuery($query, $timeout) { + if (min_version('5.7.8', '10.1.2')) { + if (preg_match('~MariaDB~', $this->_conn->server_info)) { + return "SET STATEMENT max_statement_time=$timeout FOR $query"; + } elseif (preg_match('~^(SELECT\b)(.+)~is', $query, $match)) { + return "$match[1] /*+ MAX_EXECUTION_TIME(" . ($timeout * 1000) . ") */ $match[2]"; + } + } + } + function convertSearch($idf, $val, $field) { return (preg_match('~char|text|enum|set~', $field["type"]) && !preg_match("~^utf8~", $field["collation"]) && preg_match('~[\x80-\xFF]~', $val['val']) ? "CONVERT($idf USING " . charset($this->_conn) . ")" diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php index 52aac65f..39a1a6b6 100644 --- a/adminer/drivers/pgsql.inc.php +++ b/adminer/drivers/pgsql.inc.php @@ -193,6 +193,11 @@ if (isset($_GET["pgsql"])) { return true; } + function slowQuery($query, $timeout) { + // BEGIN, COMMIT - automatically wrapped into a transaction by pg_query but not by PDO + return "BEGIN; SET LOCAL statement_timeout = " . (1000 * $timeout) . "; $query; COMMIT"; + } + function convertSearch($idf, $val, $field) { return (preg_match('~char|text' . (!preg_match('~LIKE~', $val["op"]) ? '|date|time(stamp)?' . (is_numeric($val["val"]) ? '|' . number_type() : '') : '') diff --git a/adminer/drivers/simpledb.inc.php b/adminer/drivers/simpledb.inc.php index 63ca4869..040309c5 100644 --- a/adminer/drivers/simpledb.inc.php +++ b/adminer/drivers/simpledb.inc.php @@ -19,6 +19,7 @@ if (isset($_GET["simpledb"])) { $params['NextToken'] = $this->next; } $result = sdb_request_all('Select', 'Item', $params, $this->timeout); //! respect $unbuffered + $this->timeout = 0; if ($result === false) { return $result; } @@ -236,6 +237,11 @@ if (isset($_GET["simpledb"])) { function rollback() { return false; } + + function slowQuery($query, $timeout) { + $this->_conn->timeout = $timeout; + return $query; + } } diff --git a/adminer/include/driver.inc.php b/adminer/include/driver.inc.php index 5ca8f951..893d1667 100644 --- a/adminer/include/driver.inc.php +++ b/adminer/include/driver.inc.php @@ -113,6 +113,14 @@ return queries("ROLLBACK"); } + /** Return query with a timeout + * @param string + * @param int seconds + * @return string or null if the driver doesn't support query timeouts + */ + function slowQuery($query, $timeout) { + } + /** Convert column to be searchable * @param string escaped column name * @param array array("op" => , "val" => ) diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php index 4742414e..4a7bd6a4 100644 --- a/adminer/include/functions.inc.php +++ b/adminer/include/functions.inc.php @@ -393,19 +393,16 @@ function get_vals($query, $column = 0) { /** Get keys from first column and values from second * @param string * @param Min_DB -* @param float * @param bool * @return array */ -function get_key_vals($query, $connection2 = null, $timeout = 0, $set_keys = true) { +function get_key_vals($query, $connection2 = null, $set_keys = true) { global $connection; if (!is_object($connection2)) { $connection2 = $connection; } $return = array(); - $connection2->timeout = $timeout; $result = $connection2->query($query); - $connection2->timeout = 0; if (is_object($result)) { while ($row = $result->fetch_row()) { if ($set_keys) { @@ -1306,10 +1303,11 @@ function count_rows($table, $where, $is_group, $group) { * @return array of strings */ function slow_query($query) { - global $adminer, $token; + global $adminer, $token, $driver; $db = $adminer->database(); $timeout = $adminer->queryTimeout(); - if (support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) { + $slow_query = $driver->slowQuery($query, $timeout); + if (!$slow_query && support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) { $kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL ?> > @@ -1324,7 +1322,7 @@ var timeout = setTimeout(function () { } ob_flush(); flush(); - $return = @get_key_vals($query, $connection2, $timeout, false); // @ - may be killed + $return = @get_key_vals(($slow_query ? $slow_query : $query), $connection2, false); // @ - may be killed if ($connection2) { echo script("clearTimeout(timeout);"); ob_flush(); diff --git a/changes.txt b/changes.txt index 33844fdd..43222c1b 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,6 @@ Adminer 4.6.3-dev: Stop session before connecting +Simplify running slow queries Fix displaying info about non-alphabetical objects (bug #599) PDO: Support binary fields download MySQL: Use CONVERT() only when searching for non-ASCII (bug #603)