diff --git a/adminer/create.inc.php b/adminer/create.inc.php
index cf28adf2..4eddfba4 100644
--- a/adminer/create.inc.php
+++ b/adminer/create.inc.php
@@ -2,10 +2,8 @@
namespace Adminer;
$TABLE = $_GET["create"];
-$partition_by = array();
-foreach (array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST') as $key) {
- $partition_by[$key] = $key;
-}
+$partition_by = driver()->partitionBy;
+$partitions_info = driver()->partitionsInfo($TABLE);
$referencable_primary = referencable_primary($TABLE);
$foreign_keys = array();
@@ -81,39 +79,37 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
}
$partitioning = "";
- if (support("partitioning")) {
- if (isset($partition_by[$row["partition_by"]])) {
- $params = array();
- foreach ($row as $key => $val) {
- if (preg_match('~^partition~', $key)) {
- $params[$key] = $val;
- }
+ if (in_array($row["partition_by"], $partition_by)) {
+ $params = array();
+ foreach ($row as $key => $val) {
+ if (preg_match('~^partition~', $key)) {
+ $params[$key] = $val;
}
- 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 " . (+$params["partitions"]);
- }
- }
- } elseif (preg_match("~partitioned~", $table_status["Create_options"])) {
- $partitioning .= "\nREMOVE PARTITIONING";
}
+ foreach ($params["partition_names"] as $key => $name) {
+ if ($name == "") {
+ unset($params["partition_names"][$key]);
+ unset($params["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"]);
+ }
+ }
+ } elseif (preg_match("~partitioned~", $table_status["Create_options"])) {
+ $partitioning .= "\nREMOVE PARTITIONING";
}
$message = lang('Table has been altered.');
@@ -159,8 +155,8 @@ if (!$_POST) {
$row["fields"][] = $field;
}
- if (support("partitioning")) {
- $row += get_partitions_info($TABLE);
+ if ($partition_by) {
+ $row += $partitions_info;
$row["partition_names"][] = "";
$row["partition_values"][] = "";
}
@@ -221,10 +217,10 @@ if (support("columns")) {
" . html_select("partition_by", array("" => "") + $partition_by, $row["partition_by"]) . on_help("event.target.value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;");
+ echo "
" . html_select("partition_by", array_merge(array(""), $partition_by), $row["partition_by"]) . on_help("event.target.value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;");
echo "()\n";
echo lang('Partitions') . ": \n";
echo "
\n";
diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php
index 33f5ef4b..4309de3d 100644
--- a/adminer/drivers/mysql.inc.php
+++ b/adminer/drivers/mysql.inc.php
@@ -258,6 +258,9 @@ if (!defined('Adminer\DRIVER')) {
$this->types[lang('Numbers')]["vector"] = 16383;
$this->insertFunctions['vector'] = 'string_to_vector';
}
+ if (min_version(5.1, '', $connection)) {
+ $this->partitionBy = array("HASH", "LINEAR HASH", "KEY", "LINEAR KEY", "RANGE", "LIST");
+ }
if (min_version(5.7, 10.2, $connection)) {
$this->generated = array("STORED", "VIRTUAL");
}
@@ -335,6 +338,17 @@ if (!defined('Adminer\DRIVER')) {
}
}
+ function partitionsInfo(string $table): array {
+ $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");
+ $return = array();
+ list($return["partition_by"], $return["partition"], $return["partitions"]) = $result->fetch_row();
+ $partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION");
+ $return["partition_names"] = array_keys($partitions);
+ $return["partition_values"] = array_values($partitions);
+ return $return;
+ }
+
function hasCStyleEscapes(): bool {
static $c_style;
if ($c_style === null) {
@@ -1012,10 +1026,10 @@ if (!defined('Adminer\DRIVER')) {
}
/** Check whether a feature is supported
- * @param literal-string $feature "check|comment|copy|database|descidx|drop_col|dump|event|indexes|kill|materializedview|partitioning|privileges|procedure|processlist|routine|scheme|sequence|status|table|trigger|type|variables|view|view_trigger"
+ * @param literal-string $feature "check|comment|copy|database|descidx|drop_col|dump|event|indexes|kill|materializedview|privileges|procedure|processlist|routine|scheme|sequence|status|table|trigger|type|variables|view|view_trigger"
*/
function support(string $feature): bool {
- return !preg_match("~scheme|sequence|type|view_trigger|materializedview" . (min_version(8) ? "" : "|descidx" . (min_version(5.1) ? "" : "|event|partitioning")) . (min_version('8.0.16', '10.2.1') ? "" : "|check") . "~", $feature);
+ return !preg_match("~scheme|sequence|type|view_trigger|materializedview" . (min_version(8) ? "" : "|descidx" . (min_version(5.1) ? "" : "|event")) . (min_version('8.0.16', '10.2.1') ? "" : "|check") . "~", $feature);
}
/** Kill a process
diff --git a/adminer/include/driver.inc.php b/adminer/include/driver.inc.php
index 8cd1b208..f3a59819 100644
--- a/adminer/include/driver.inc.php
+++ b/adminer/include/driver.inc.php
@@ -26,6 +26,7 @@ abstract class SqlDriver {
/** @var list */ public $functions = array(); // functions used in select
/** @var list */ public $grouping = array(); // grouping functions used in select
/** @var string */ public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; // used in foreign_keys()
+ /** @var list */ public $partitionBy = array(); // supported partitioning types
/** @var string */ public $inout = "IN|OUT|INOUT"; // used in routines
/** @var string */ public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; // regular expression for parsing enum lengths
/** @var list */ public $generated = array(); // allowed types of generated columns
@@ -231,6 +232,13 @@ abstract class SqlDriver {
return array();
}
+ /** Get partitions info
+ * @return array{partition_by?:string, partition?:string, partitions?:string, partition_names?:list, partition_values?:list}
+ */
+ function partitionsInfo(string $table): array {
+ return array();
+ }
+
/** Check if C-style escapes are supported */
function hasCStyleEscapes(): bool {
return false;
diff --git a/adminer/include/editing.inc.php b/adminer/include/editing.inc.php
index 4af1f272..a7d3382a 100644
--- a/adminer/include/editing.inc.php
+++ b/adminer/include/editing.inc.php
@@ -201,20 +201,6 @@ function edit_type(string $key, array $field, array $collations, array $foreign_
);
}
-/** Get partition info
-* @return array{partition_by:string, partition:string, partitions:string, partition_names:list, partition_values:list}
-*/
-function get_partitions_info(string $table): array {
- $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");
- $return = array();
- list($return["partition_by"], $return["partition"], $return["partitions"]) = $result->fetch_row();
- $partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION");
- $return["partition_names"] = array_keys($partitions);
- $return["partition_values"] = array_values($partitions);
- return $return;
-}
-
/** Filter length value including enums */
function process_length(?string $length): string {
$enum_length = driver()->enumLength;