3 * Library for extracting information about the partitions
6 declare(strict_types
=1);
8 namespace PhpMyAdmin\Partitioning
;
10 use PhpMyAdmin\DatabaseInterface
;
12 use function array_values
;
14 class Partition
extends SubPartition
16 protected string|
null $description = null;
17 /** @var SubPartition[] */
18 protected array $subPartitions = [];
21 * Loads data from the fetched row from information_schema.PARTITIONS
23 * @param mixed[] $row fetched row
25 public function __construct(array $row)
27 $this->name
= $row['PARTITION_NAME'];
28 $this->ordinal
= $row['PARTITION_ORDINAL_POSITION'] !== null ?
(int) $row['PARTITION_ORDINAL_POSITION'] : null;
29 $this->method
= $row['PARTITION_METHOD'];
30 $this->expression
= $row['PARTITION_EXPRESSION'];
31 $this->description
= $row['PARTITION_DESCRIPTION'];
32 // no sub partitions, load all data to this object
33 if (! empty($row['SUBPARTITION_NAME'])) {
37 $this->loadCommonData($row);
41 * Returns the partition description
43 public function getDescription(): string|
null
45 return $this->description
;
51 public function addSubPartition(SubPartition
$subPartition): void
53 $this->subPartitions
[] = $subPartition;
57 * Whether there are sub partitions
59 public function hasSubPartitions(): bool
61 return $this->subPartitions
!== [];
65 * Returns the number of data rows
67 * @return int number of rows
69 public function getRows(): int
71 if ($this->subPartitions
=== []) {
76 foreach ($this->subPartitions
as $subPartition) {
77 $rows +
= $subPartition->rows
;
84 * Returns the total data length
86 * @return int data length
88 public function getDataLength(): int
90 if ($this->subPartitions
=== []) {
91 return $this->dataLength
;
95 foreach ($this->subPartitions
as $subPartition) {
96 $dataLength +
= $subPartition->dataLength
;
103 * Returns the total index length
105 * @return int index length
107 public function getIndexLength(): int
109 if ($this->subPartitions
=== []) {
110 return $this->indexLength
;
114 foreach ($this->subPartitions
as $subPartition) {
115 $indexLength +
= $subPartition->indexLength
;
122 * Returns the list of sub partitions
124 * @return SubPartition[]
126 public function getSubPartitions(): array
128 return $this->subPartitions
;
132 * Returns array of partitions for a specific db/table
134 * @param string $db database name
135 * @param string $table table name
137 * @return Partition[]
139 public static function getPartitions(string $db, string $table): array
141 if (self
::havePartitioning()) {
142 $dbi = DatabaseInterface
::getInstance();
143 $result = $dbi->fetchResult(
144 'SELECT * FROM `information_schema`.`PARTITIONS`'
145 . ' WHERE `TABLE_SCHEMA` = ' . $dbi->quoteString($db)
146 . ' AND `TABLE_NAME` = ' . $dbi->quoteString($table),
148 if ($result !== []) {
150 /** @var array $row */
151 foreach ($result as $row) {
152 if (isset($partitionMap[$row['PARTITION_NAME']])) {
153 $partition = $partitionMap[$row['PARTITION_NAME']];
155 $partition = new Partition($row);
156 $partitionMap[$row['PARTITION_NAME']] = $partition;
159 if (empty($row['SUBPARTITION_NAME'])) {
163 $partition->addSubPartition(new SubPartition($row));
166 return array_values($partitionMap);
176 * returns array of partition names for a specific db/table
178 * @param string $db database name
179 * @param string $table table name
181 * @return mixed[] of partition names
183 public static function getPartitionNames(string $db, string $table): array
185 if (self
::havePartitioning()) {
186 $dbi = DatabaseInterface
::getInstance();
188 return $dbi->fetchResult(
189 'SELECT DISTINCT `PARTITION_NAME` FROM `information_schema`.`PARTITIONS`'
190 . ' WHERE `TABLE_SCHEMA` = ' . $dbi->quoteString($db)
191 . ' AND `TABLE_NAME` = ' . $dbi->quoteString($table),
199 * returns the partition method used by the table.
201 * @param string $db database name
202 * @param string $table table name
204 * @return string|null partition method
206 public static function getPartitionMethod(string $db, string $table): string|
null
208 if (self
::havePartitioning()) {
209 $dbi = DatabaseInterface
::getInstance();
210 $partitionMethod = $dbi->fetchResult(
211 'SELECT `PARTITION_METHOD` FROM `information_schema`.`PARTITIONS`'
212 . ' WHERE `TABLE_SCHEMA` = ' . $dbi->quoteString($db)
213 . ' AND `TABLE_NAME` = ' . $dbi->quoteString($table)
216 if ($partitionMethod !== []) {
217 return $partitionMethod[0];
225 * checks if MySQL server supports partitioning
227 * @staticvar bool $have_partitioning
228 * @staticvar bool $already_checked
230 public static function havePartitioning(): bool
232 static $havePartitioning = false;
233 static $alreadyChecked = false;
235 if (! $alreadyChecked) {
236 $dbi = DatabaseInterface
::getInstance();
237 if ($dbi->getVersion() < 50600) {
238 if ($dbi->fetchValue('SELECT @@have_partitioning;')) {
239 $havePartitioning = true;
241 } elseif ($dbi->getVersion() >= 80000) {
242 $havePartitioning = true;
244 // see https://dev.mysql.com/doc/refman/5.6/en/partitioning.html
245 $plugins = $dbi->fetchResult('SHOW PLUGINS');
246 foreach ($plugins as $value) {
247 if ($value['Name'] === 'partition') {
248 $havePartitioning = true;
254 $alreadyChecked = true;
257 return $havePartitioning;