1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-06 22:56:46 +02:00

Move partitioning functions

This commit is contained in:
Jakub Vrana
2025-04-14 13:51:43 +02:00
parent 8783f4d3ac
commit cde6b9008c
4 changed files with 59 additions and 55 deletions

View File

@@ -2,10 +2,8 @@
namespace Adminer; namespace Adminer;
$TABLE = $_GET["create"]; $TABLE = $_GET["create"];
$partition_by = array(); $partition_by = driver()->partitionBy;
foreach (array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST') as $key) { $partitions_info = driver()->partitionsInfo($TABLE);
$partition_by[$key] = $key;
}
$referencable_primary = referencable_primary($TABLE); $referencable_primary = referencable_primary($TABLE);
$foreign_keys = array(); $foreign_keys = array();
@@ -81,39 +79,37 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
} }
$partitioning = ""; $partitioning = "";
if (support("partitioning")) { if (in_array($row["partition_by"], $partition_by)) {
if (isset($partition_by[$row["partition_by"]])) { $params = array();
$params = array(); foreach ($row as $key => $val) {
foreach ($row as $key => $val) { if (preg_match('~^partition~', $key)) {
if (preg_match('~^partition~', $key)) { $params[$key] = $val;
$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.'); $message = lang('Table has been altered.');
@@ -159,8 +155,8 @@ if (!$_POST) {
$row["fields"][] = $field; $row["fields"][] = $field;
} }
if (support("partitioning")) { if ($partition_by) {
$row += get_partitions_info($TABLE); $row += $partitions_info;
$row["partition_names"][] = ""; $row["partition_names"][] = "";
$row["partition_values"][] = ""; $row["partition_values"][] = "";
} }
@@ -221,10 +217,10 @@ if (support("columns")) {
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $TABLE)); ?> <input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $TABLE)); ?>
<?php } ?> <?php } ?>
<?php <?php
if (support("partitioning")) { if ($partition_by && (JUSH == 'sql' || $TABLE == "")) {
$partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]); $partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]);
print_fieldset("partition", lang('Partition by'), $row["partition_by"]); print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
echo "<p>" . 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 "<p>" . 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 "(<input name='partition' value='" . h($row["partition"]) . "'>)\n"; echo "(<input name='partition' value='" . h($row["partition"]) . "'>)\n";
echo lang('Partitions') . ": <input type='number' name='partitions' class='size" . ($partition_table || !$row["partition_by"] ? " hidden" : "") . "' value='" . h($row["partitions"]) . "'>\n"; echo lang('Partitions') . ": <input type='number' name='partitions' class='size" . ($partition_table || !$row["partition_by"] ? " hidden" : "") . "' value='" . h($row["partitions"]) . "'>\n";
echo "<table id='partition-table'" . ($partition_table ? "" : " class='hidden'") . ">\n"; echo "<table id='partition-table'" . ($partition_table ? "" : " class='hidden'") . ">\n";

View File

@@ -258,6 +258,9 @@ if (!defined('Adminer\DRIVER')) {
$this->types[lang('Numbers')]["vector"] = 16383; $this->types[lang('Numbers')]["vector"] = 16383;
$this->insertFunctions['vector'] = 'string_to_vector'; $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)) { if (min_version(5.7, 10.2, $connection)) {
$this->generated = array("STORED", "VIRTUAL"); $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 { function hasCStyleEscapes(): bool {
static $c_style; static $c_style;
if ($c_style === null) { if ($c_style === null) {
@@ -1012,10 +1026,10 @@ if (!defined('Adminer\DRIVER')) {
} }
/** Check whether a feature is supported /** 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 { 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 /** Kill a process

View File

@@ -26,6 +26,7 @@ abstract class SqlDriver {
/** @var list<string> */ public $functions = array(); // functions used in select /** @var list<string> */ public $functions = array(); // functions used in select
/** @var list<string> */ public $grouping = array(); // grouping functions used in select /** @var list<string> */ 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 string */ public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; // used in foreign_keys()
/** @var list<string> */ public $partitionBy = array(); // supported partitioning types
/** @var string */ public $inout = "IN|OUT|INOUT"; // used in routines /** @var string */ public $inout = "IN|OUT|INOUT"; // used in routines
/** @var string */ public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; // regular expression for parsing enum lengths /** @var string */ public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; // regular expression for parsing enum lengths
/** @var list<string> */ public $generated = array(); // allowed types of generated columns /** @var list<string> */ public $generated = array(); // allowed types of generated columns
@@ -231,6 +232,13 @@ abstract class SqlDriver {
return array(); return array();
} }
/** Get partitions info
* @return array{partition_by?:string, partition?:string, partitions?:string, partition_names?:list<string>, partition_values?:list<string>}
*/
function partitionsInfo(string $table): array {
return array();
}
/** Check if C-style escapes are supported */ /** Check if C-style escapes are supported */
function hasCStyleEscapes(): bool { function hasCStyleEscapes(): bool {
return false; return false;

View File

@@ -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<string>, partition_values:list<string>}
*/
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 */ /** Filter length value including enums */
function process_length(?string $length): string { function process_length(?string $length): string {
$enum_length = driver()->enumLength; $enum_length = driver()->enumLength;