diff --git a/adminer/create.inc.php b/adminer/create.inc.php index 4eddfba4..d50d75d8 100644 --- a/adminer/create.inc.php +++ b/adminer/create.inc.php @@ -78,38 +78,24 @@ if ($_POST && !process_fields($row["fields"]) && !$error) { } } - $partitioning = ""; + $partitioning = array(); if (in_array($row["partition_by"], $partition_by)) { - $params = array(); foreach ($row as $key => $val) { if (preg_match('~^partition~', $key)) { - $params[$key] = $val; + $partitioning[$key] = $val; } } - foreach ($params["partition_names"] as $key => $name) { + foreach ($partitioning["partition_names"] as $key => $name) { if ($name == "") { - unset($params["partition_names"][$key]); - unset($params["partition_values"][$key]); + unset($partitioning["partition_names"][$key]); + unset($partitioning["partition_values"][$key]); } } - if ($params != $partitions_info) { - $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 " . (+$params["partitions"]); - } + if ($partitioning == $partitions_info) { + $partitioning = array(); } } elseif (preg_match("~partitioned~", $table_status["Create_options"])) { - $partitioning .= "\nREMOVE PARTITIONING"; + $partitioning = null; } $message = lang('Table has been altered.'); diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 4309de3d..f0247de7 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -691,9 +691,10 @@ if (!defined('Adminer\DRIVER')) { * @param list, string}> $fields of [$orig, $process_field, $after] * @param string[] $foreign * @param numeric-string $auto_increment + * @param ?Partitions $partitioning null means remove partitioning * @return Result|bool */ - function alter_table(string $table, string $name, array $fields, array $foreign, ?string $comment, string $engine, string $collation, string $auto_increment, string $partitioning) { + function alter_table(string $table, string $name, array $fields, array $foreign, ?string $comment, string $engine, string $collation, string $auto_increment, ?array $partitioning) { $alter = array(); foreach ($fields as $field) { if ($field[1]) { @@ -714,8 +715,28 @@ if (!defined('Adminer\DRIVER')) { . ($collation ? " COLLATE " . q($collation) : "") . ($auto_increment != "" ? " AUTO_INCREMENT=$auto_increment" : "") ; + + if ($partitioning) { + $partitions = array(); + if ($partitioning["partition_by"] == 'RANGE' || $partitioning["partition_by"] == 'LIST') { + foreach ($partitioning["partition_names"] as $key => $val) { + $value = $partitioning["partition_values"][$key]; + $partitions[] = "\n PARTITION " . idf_escape($val) . " VALUES " . ($partitioning["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection + } + } + // $partitioning["partition"] can be expression, not only column + $status .= "\nPARTITION BY $partitioning[partition_by]($partitioning[partition])"; + if ($partitions) { + $status .= " (" . implode(",", $partitions) . "\n)"; + } elseif ($partitioning["partitions"]) { + $status .= " PARTITIONS " . (+$partitioning["partitions"]); + } + } elseif ($partitioning === null) { + $status .= "\nREMOVE PARTITIONING"; + } + if ($table == "") { - return queries("CREATE TABLE " . table($name) . " (\n" . implode(",\n", $alter) . "\n)$status$partitioning"); + return queries("CREATE TABLE " . table($name) . " (\n" . implode(",\n", $alter) . "\n)$status"); } if ($table != $name) { $alter[] = "RENAME TO " . table($name); @@ -723,7 +744,7 @@ if (!defined('Adminer\DRIVER')) { if ($status) { $alter[] = ltrim($status); } - return ($alter || $partitioning ? queries("ALTER TABLE " . table($table) . "\n" . implode(",\n", $alter) . $partitioning) : true); + return ($alter ? queries("ALTER TABLE " . table($table) . "\n" . implode(",\n", $alter)) : true); } /** Run commands to alter indexes diff --git a/adminer/include/driver.inc.php b/adminer/include/driver.inc.php index f3a59819..5437d479 100644 --- a/adminer/include/driver.inc.php +++ b/adminer/include/driver.inc.php @@ -233,7 +233,7 @@ abstract class SqlDriver { } /** Get partitions info - * @return array{partition_by?:string, partition?:string, partitions?:string, partition_names?:list, partition_values?:list} + * @return Partitions */ function partitionsInfo(string $table): array { return array(); diff --git a/phpstan.neon b/phpstan.neon index 05b6004e..121201ae 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -69,4 +69,5 @@ parameters: ForeignKey: "array{db?:string, ns?:string, table:string, source:list, target:list, on_delete:string, on_update?:string, definition?:string, deferrable?:string}" Trigger: "array{Trigger?:string, Timing?:string, Event?:string, Of?:string, Type?:string, Statement?:string}" Routine: "array{name?:string, fields:list, comment:string, returns?:FieldType, definition:string, language?:string}" + Partitions: "array{partition_by?:string, partition?:string, partitions?:numeric-string, partition_names?:list, partition_values?:list}" BackwardKey: "array{name:string, keys:string[][]}"