From 53aad3bb62884d97ed37d46c966f01afca9d9ac3 Mon Sep 17 00:00:00 2001 From: Peter Knut Date: Sun, 22 Sep 2024 00:33:55 +0200 Subject: [PATCH] Do not include unchanged PARTITION BY definition into ALTER TABLE query --- adminer/create.inc.php | 53 ++++++++++++++++++++----------- adminer/include/functions.inc.php | 16 ++++++++++ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/adminer/create.inc.php b/adminer/create.inc.php index 03acfe42..905ff390 100644 --- a/adminer/create.inc.php +++ b/adminer/create.inc.php @@ -82,20 +82,39 @@ if ($_POST && !process_fields($row["fields"]) && !$error) { } $partitioning = ""; - if ($partition_by[$row["partition_by"]]) { - $partitions = array(); - if ($row["partition_by"] == 'RANGE' || $row["partition_by"] == 'LIST') { - foreach (array_filter($row["partition_names"]) as $key => $val) { - $value = $row["partition_values"][$key]; - $partitions[] = "\n PARTITION " . idf_escape($val) . " VALUES " . ($row["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection + if (support("partitioning")) { + if (isset($partition_by[$row["partition_by"]])) { + $params = array_filter($row, function ($key) { + return preg_match('~^partition~', $key); + }, ARRAY_FILTER_USE_KEY); + + foreach ($params["partition_names"] as $key => $name) { + if ($name === "") { + unset($params["partition_names"][$key]); + unset($params["partition_values"][$key]); + } } + + if ($params != get_partitions_info($TABLE)) { + $partitions = array(); + if ($params["partition_by"] == 'RANGE' || $params["partition_by"] == 'LIST') { + foreach ($params["partition_names"] as $key => $name) { + $value = $params["partition_values"][$key]; + $partitions[] = "\n PARTITION " . idf_escape($name) . " VALUES " . ($params["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection + } + } + + // $params["partition"] can be expression, not only column + $partitioning .= "\nPARTITION BY {$params["partition_by"]}({$params["partition"]})"; + if ($partitions) { + $partitioning .= " (" . implode(",", $partitions) . "\n)"; + } elseif ($params["partitions"]) { + $partitioning .= " PARTITIONS " . (int)$params["partitions"]; + } + } + } elseif (preg_match("~partitioned~", $table_status["Create_options"])) { + $partitioning .= "\nREMOVE PARTITIONING"; } - $partitioning .= "\nPARTITION BY $row[partition_by]($row[partition])" . ($partitions // $row["partition"] can be expression, not only column - ? " (" . implode(",", $partitions) . "\n)" - : ($row["partitions"] ? " PARTITIONS " . (+$row["partitions"]) : "") - ); - } elseif (support("partitioning") && preg_match("~partitioned~", $table_status["Create_options"])) { - $partitioning .= "\nREMOVE PARTITIONING"; } $message = lang('Table has been altered.'); @@ -141,13 +160,9 @@ if (!$_POST) { } if (support("partitioning")) { - $from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE); - $result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1"); - list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row(); - $partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION"); - $partitions[""] = ""; - $row["partition_names"] = array_keys($partitions); - $row["partition_values"] = array_values($partitions); + $row += get_partitions_info($TABLE); + $row["partition_names"][] = ""; + $row["partition_values"][] = ""; } } } diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php index 44b0a50a..d3384937 100644 --- a/adminer/include/functions.inc.php +++ b/adminer/include/functions.inc.php @@ -1108,6 +1108,22 @@ function search_tables() { echo ($sep ? "

" . lang('No tables.') : "") . "\n"; } +/** +* @param string $table +* @return array +*/ +function get_partitions_info($table) { + global $connection; + $from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($table); + $result = $connection->query("SELECT PARTITION_METHOD, PARTITION_EXPRESSION, PARTITION_ORDINAL_POSITION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1"); + $info = array(); + list($info["partition_by"], $info["partition"], $info["partitions"]) = $result->fetch_row(); + $partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION"); + $info["partition_names"] = array_keys($partitions); + $info["partition_values"] = array_values($partitions); + return $info; +} + /** Send headers for export * @param string * @param bool