diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 563d1ffe..dea561fe 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -583,18 +583,24 @@ if (!defined("DRIVER")) { * @return array array($name => array("db" => , "ns" => , "table" => , "source" => array(), "target" => array(), "on_delete" => , "on_update" => )) */ function foreign_keys($table) { + global $connection, $on_actions; + static $pattern = '(?:`(?:[^`]|``)+`|(?:"(?:[^"]|"")+"))'; $return = array(); - foreach (get_rows("SELECT * FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table)) as $row) { - $columns = get_key_vals("SELECT COLUMN_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE CONSTRAINT_SCHEMA = DATABASE() AND CONSTRAINT_NAME = " . q($row["CONSTRAINT_NAME"]) . " ORDER BY ORDINAL_POSITION"); - $db = $row["UNIQUE_CONSTRAINT_SCHEMA"]; - $return[$row["CONSTRAINT_NAME"]] = array( - "db" => ($db == DB ? "" : $db), - "table" => $row["REFERENCED_TABLE_NAME"], - "source" => array_keys($columns), - "target" => array_values($columns), - "on_delete" => $row["DELETE_RULE"], - "on_update" => $row["UPDATE_RULE"], - ); + $create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1); + if ($create_table) { + preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($on_actions))?(?: ON UPDATE ($on_actions))?~", $create_table, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + preg_match_all("~$pattern~", $match[2], $source); + preg_match_all("~$pattern~", $match[5], $target); + $return[idf_unescape($match[1])] = array( + "db" => idf_unescape($match[4] != "" ? $match[3] : $match[4]), + "table" => idf_unescape($match[4] != "" ? $match[4] : $match[3]), + "source" => array_map('idf_unescape', $source[0]), + "target" => array_map('idf_unescape', $target[0]), + "on_delete" => ($match[6] ? $match[6] : "RESTRICT"), + "on_update" => ($match[7] ? $match[7] : "RESTRICT"), + ); + } } return $return; } diff --git a/changes.txt b/changes.txt index 124ac4f7..933d42fd 100644 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,5 @@ Adminer 4.7.3-dev: +MySQL: Speed up displaying tables in large databases (bug #700) MySQL: Skip editing generated columns SQLite: Quote strings stored in integer columns in export (bug #696) @@ -8,7 +9,7 @@ Stretch footer over the whole table width (bug #624) Allow overwriting tables when copying them Fix displaying SQL command after Save and continue edit Cache busting for adminer.css -MySQL: Fix displaying multi-columns foreign keys (bug #675) +MySQL: Fix displaying multi-columns foreign keys (bug #675, regression from 4.7.0) MySQL: Fix creating users and changing password in MySQL 8 (bug #663) MySQL: Pass SRID to GeomFromText PostgreSQL: Fix setting column comments on new table