Merge pull request #11395 from madhuracj/partition

Improve partition support
This commit is contained in:
Marc Delisle 2015-08-15 07:00:53 -04:00
commit 5c7d5bfcb0
6 changed files with 526 additions and 4 deletions

View File

@ -85,6 +85,7 @@ AJAX.registerTeardown('tbl_structure.js', function () {
$(document).off('click', "#printView");
$(document).off('submit', ".append_fields_form.ajax");
$('body').off('click', '#fieldsForm.ajax button[name="submit_mult"], #fieldsForm.ajax input[name="submit_mult"]');
$(document).off('click', 'a[name^=partition_action].ajax');
});
AJAX.registerOnload('tbl_structure.js', function () {
@ -432,6 +433,35 @@ AJAX.registerOnload('tbl_structure.js', function () {
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
/**
* Handles clicks on Action links in partition table
*/
$(document).on('click', 'a[name^=partition_action].ajax', function (e) {
e.preventDefault();
var $link = $(this);
function submitPartitionAction(url) {
var submitData = '&ajax_request=true&ajax_page_request=true';
PMA_ajaxShowMessage();
AJAX.source = $link;
$.post(url, submitData, AJAX.responseHandler);
}
if ($link.is('#partition_action_DROP')) {
var question = PMA_messages.strDropPartitionWarning;
$link.PMA_confirm(question, $link.attr('href'), function (url) {
submitPartitionAction(url);
});
} else if ($link.is('#partition_action_TRUNCATE')) {
var question = PMA_messages.strTruncatePartitionWarning;
$link.PMA_confirm(question, $link.attr('href'), function (url) {
submitPartitionAction(url);
});
} else {
submitPartitionAction($link.attr('href'));
}
});
});
/** Handler for "More" dropdown in structure table rows */

View File

@ -9,13 +9,336 @@ if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Represents a sub partition of a table
*
* @package PhpMyAdmin
*/
class PMA_SubPartition
{
/**
* @var string the database
*/
protected $db;
/**
* @var string the table
*/
protected $table;
/**
* @var string partition name
*/
protected $name;
/**
* @var integer ordinal
*/
protected $ordinal;
/**
* @var string partition method
*/
protected $method;
/**
* @var string partition expression
*/
protected $expression;
/**
* @var integer no of table rows in the partition
*/
protected $rows;
/**
* @var integer data length
*/
protected $dataLength;
/**
* @var integer index length
*/
protected $indexLength;
/**
* Constructs a partition
*
* @param array $row fetched row from information_schema.PARTITIONS
*/
public function __construct($row)
{
$this->db = $row['TABLE_SCHEMA'];
$this->table = $row['TABLE_NAME'];
$this->loadData($row);
}
/**
* Loads data from the fetched row from information_schema.PARTITIONS
*
* @param array $row fetched row
*
* @return void
*/
protected function loadData($row)
{
$this->name = $row['SUBPARTITION_NAME'];
$this->ordinal = $row['SUBPARTITION_ORDINAL_POSITION'];
$this->method = $row['SUBPARTITION_METHOD'];
$this->expression = $row['SUBPARTITION_EXPRESSION'];
$this->loadCommonData($row);
}
/**
* Loads some data that is common to both partitions and sub partitions
*
* @param array $row fetched row
*
* @return void
*/
protected function loadCommonData($row)
{
$this->rows = $row['TABLE_ROWS'];
$this->dataLength = $row['DATA_LENGTH'];
$this->indexLength = $row['INDEX_LENGTH'];
}
/**
* Return the partition name
*
* @return string partition name
*/
public function getName()
{
return $this->name;
}
/**
* Return the ordinal of the partition
*
* @return number the ordinal
*/
public function getOrdinal()
{
return $this->ordinal;
}
/**
* Returns the partition method
*
* @return string partition method
*/
public function getMethod()
{
return $this->method;
}
/**
* Returns the partition expression
*
* @return string partition expression
*/
public function getExpression()
{
return $this->expression;
}
/**
* Returns the number of data rows
*
* @return integer number of rows
*/
public function getRows()
{
return $this->rows;
}
/**
* Returns the data length
*
* @return integer data length
*/
public function getDataLength()
{
return $this->dataLength;
}
/**
* Returns the index length
*
* @return integer index length
*/
public function getIndexLength()
{
return $this->indexLength;
}
}
/**
* base Partition Class
*
* @package PhpMyAdmin
*/
class PMA_Partition
class PMA_Partition extends PMA_SubPartition
{
/**
* @var string partition description
*/
protected $description;
/**
* @var PMA_SubPartition[] sub partitions
*/
protected $subPartitions = array();
/**
* Loads data from the fetched row from information_schema.PARTITIONS
*
* @param array $row fetched row
*
* @return void
*/
protected function loadData($row)
{
$this->name = $row['PARTITION_NAME'];
$this->ordinal = $row['PARTITION_ORDINAL_POSITION'];
$this->method = $row['PARTITION_METHOD'];
$this->expression = $row['PARTITION_EXPRESSION'];
$this->description = $row['PARTITION_DESCRIPTION'];
// no sub partitions, load all data to this object
if (empty($row['SUBPARTITION_NAME'])) {
$this->loadCommonData($row);
}
}
/**
* Returns the partiotion description
*
* @return string partition description
*/
public function getDescription()
{
return $this->description;
}
/**
* Add a sub partition
*
* @param PMA_SubPartition $partition
*
* @return void
*/
public function addSubPartition(PMA_SubPartition $partition)
{
$this->subPartitions[] = $partition;
}
/**
* Whether there are sub partitions
*
* @return boolean
*/
public function hasSubPartitions()
{
return ! empty($this->subPartitions);
}
/**
* Returns the number of data rows
*
* @return integer number of rows
*/
public function getRows()
{
if (empty($this->subPartitions)) {
return $this->rows;
} else {
$rows = 0;
foreach ($this->subPartitions as $subPartition) {
$rows += $subPartition->rows;
}
return $rows;
}
}
/**
* Returns the total data length
*
* @return integer data length
*/
public function getDataLength()
{
if (empty($this->subPartitions)) {
return $this->dataLength;
} else {
$dataLength = 0;
foreach ($this->subPartitions as $subPartition) {
$dataLength += $subPartition->dataLength;
}
return $dataLength;
}
}
/**
* Returns the tatal index length
*
* @return integer index length
*/
public function getIndexLength()
{
if (empty($this->subPartitions)) {
return $this->indexLength;
} else {
$indexLength = 0;
foreach ($this->subPartitions as $subPartition) {
$indexLength += $subPartition->indexLength;
}
return $indexLength;
}
}
/**
* Returns the list of sub partitions
*
* @return PMA_SubPartition[]
*/
public function getSubPartitions()
{
return $this->subPartitions;
}
/**
* Returns array of partitions for a specific db/table
*
* @param string $db database name
* @param string $table table name
*
* @access public
* @return PMA_Partition[]
*/
static public function getParititions($db, $table)
{
if (PMA_Partition::havePartitioning()) {
$result = $GLOBALS['dbi']->fetchResult(
"SELECT * FROM `information_schema`.`PARTITIONS`"
. " WHERE `TABLE_SCHEMA` = '" . PMA_Util::sqlAddSlashes($db)
. "' AND `TABLE_NAME` = '" . PMA_Util::sqlAddSlashes($table) . "'"
);
if ($result) {
$partitionMap = array();
foreach ($result as $row) {
if (isset($partitionMap[$row['PARTITION_NAME']])) {
$partition = $partitionMap[$row['PARTITION_NAME']];
} else {
$partition = new PMA_Partition($row);
$partitionMap[$row['PARTITION_NAME']] = $partition;
}
if (! empty($row['SUBPARTITION_NAME'])) {
$parentPartition = $partition;
$partition = new PMA_SubPartition($row);
$parentPartition->addSubPartition($partition);
}
}
return array_values($partitionMap);
}
return array();
} else {
return array();
}
}
/**
* returns array of partition names for a specific db/table
*
@ -96,4 +419,4 @@ class PMA_Partition
}
return $have_partitioning;
}
}
}

View File

@ -11,6 +11,7 @@ namespace PMA\Controllers;
use PMA\Template;
use PMA_Index;
use PMA_Partition;
use PMA_Table;
use PMA_Message;
use PMA_PageSettings;
@ -21,6 +22,7 @@ use SqlParser;
require_once 'libraries/common.inc.php';
require_once 'libraries/tbl_info.inc.php';
require_once 'libraries/Index.class.php';
require_once 'libraries/Partition.class.php';
require_once 'libraries/mysql_charsets.inc.php';
require_once 'libraries/config/page_settings.class.php';
require_once 'libraries/transformations.lib.php';
@ -274,7 +276,9 @@ class TableStructureController extends TableController
/**
* Adding indexes
*/
if (isset($_REQUEST['add_key'])) {
if (isset($_REQUEST['add_key'])
|| isset($_REQUEST['partition_maintenance'])
) {
//todo: set some variables for sql.php include, to be eliminated
//after refactoring sql.php
$db = $this->db;

View File

@ -1234,7 +1234,9 @@ function PMA_deleteTransformationInfo($db, $table, $analyzed_sql_results)
include_once 'libraries/transformations.lib.php';
$statement = $analyzed_sql_results['statement'];
if ($statement instanceof SqlParser\Statements\AlterStatement) {
if ($statement->altered[0]->options->has('DROP')) {
if (!empty($statement->altered[0])
&& $statement->altered[0]->options->has('DROP')
) {
if (!empty($statement->altered[0]->field->column)) {
PMA_clearTransformations(
$db,

View File

@ -0,0 +1,120 @@
<div id="partitions">
<fieldset>
<legend><?php echo __('Partitions')
. PMA_Util::showMySQLDocu('partitioning'); ?>
</legend>
<p>
<?php echo __('Partitioned by:');?>
<code><?php echo $partitionMethod . '(' . $partitionExpression . ' )'; ?></code>
</p>
<?php if ($hasSubPartitions): ?>
<p>
<?php echo __('Sub partitioned by:'); ?>
<code><?php echo $subPartitionMethod . '(' . $subPartitionExpression . ' )'; ?></code>
<p>
<?php endif; ?>
<table>
<thead>
<tr>
<th colspan="2">#</th>
<th><?php echo __('Name'); ?></th>
<?php if ($hasDescription): ?>
<th><?php echo __('Expression'); ?></th>
<?php endif; ?>
<th><?php echo __('Rows'); ?></th>
<th><?php echo __('Data length'); ?></th>
<th><?php echo __('Index length'); ?></th>
<th colspan="7"><?php echo __('Action'); ?></th>
</tr>
</thead>
<tbody>
<?php $odd = true; ?>
<?php foreach ($partitions as $partition): ?>
<tr class="noclick <?php echo $odd ? 'odd' : 'even'; echo $hasSubPartitions ? ' marked' : '';?>">
<?php if ($hasSubPartitions): ?>
<td><?php echo $partition->getOrdinal(); ?></td>
<td></td>
<?php else: ?>
<td colspan="2"><?php echo $partition->getOrdinal(); ?></td>
<?php endif; ?>
<th><?php echo htmlspecialchars($partition->getName()); ?></th>
<?php if ($hasDescription): ?>
<td>
<code>
<?php
echo htmlspecialchars($partition->getExpression())
. ($partition->getMethod() == 'LIST' ? ' IN (' : ' < ')
. htmlspecialchars($partition->getDescription())
. ($partition->getMethod() == 'LIST' ? ')' : '');
?>
</code>
</td>
<?php endif; ?>
<td class="value"><?php echo $partition->getRows(); ?></td>
<td class="value"><?php
list($value, $unit) = PMA_Util::formatByteDown(
$partition->getDataLength(), 3, 1
);
?>
<span><?php echo $value; ?></span>
<span class="unit"><?php echo $unit; ?></span>
</td>
<td class="value"><?php
list($value, $unit) = PMA_Util::formatByteDown(
$partition->getIndexLength(), 3, 1
);
?>
<span><?php echo $value; ?></span>
<span class="unit"><?php echo $unit; ?></span>
</td>
<?php foreach ($actionIcons as $action => $icon): ?>
<td>
<a href="tbl_structure.php<?php echo $url_query; ?>&amp;partition_maintenance=1&amp;sql_query=<?php echo urlencode(
"ALTER TABLE " . PMA_Util::backquote($table) . $action . " PARTITION " . $partition->getName()
) ?>"
id="partition_action_<?php echo $action; ?>"
name="partition_action_<?php echo $action; ?>"
class="ajax"
>
<?php echo $icon; ?>
</a>
</td>
<?php endforeach; ?>
<?php if ($hasSubPartitions): ?>
<?php foreach ($partition->getSubPartitions() as $subParition): ?>
<tr class="noclick <?php echo $odd ? 'odd' : 'even' ?>">
<td></td>
<td><?php echo $subParition->getOrdinal(); ?></td>
<td><?php echo htmlspecialchars($subParition->getName()); ?></td>
<?php if ($hasDescription): ?>
<td></td>
<?php endif; ?>
<td class="value"><?php echo $subParition->getRows(); ?></td>
<td class="value"><?php
list($value, $unit) = PMA_Util::formatByteDown(
$subParition->getDataLength(), 3, 1
);
?>
<span><?php echo $value; ?></span>
<span class="unit"><?php echo $unit; ?></span>
</td>
<td class="value"><?php
list($value, $unit) = PMA_Util::formatByteDown(
$subParition->getIndexLength(), 3, 1
);
?>
<span><?php echo $value; ?></span>
<span class="unit"><?php echo $unit; ?></span>
</td>
<td colspan="7"></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tr>
<?php $odd = ! $odd; ?>
<?php endforeach; ?>
</tbody>
</table>
</fieldset>
</div>

View File

@ -154,11 +154,54 @@
array('columns_list' => $columns_list)
); ?>
<?php endif; ?>
<!--Displays indexes-->
<?php if (! $tbl_is_view
&& ! $db_is_system_schema && 'ARCHIVE' != $tbl_storage_engine): ?>
<?php echo PMA_getHtmlForDisplayIndexes(); ?>
<?php endif; ?>
<!--Display partition details-->
<?php
$partition_names = PMA_Partition::getPartitionNames($db, $table);
// detect partitioning
if (! is_null($partition_names[0])) {
$partitions = PMA_Partition::getParititions($db, $table);
$firstPartition = $partitions[0];
$subParitions = $firstPartition->getSubPartitions();
$hasSubPartitions = $firstPartition->hasSubPartitions();
if ($hasSubPartitions) {
$firstSubPartition = $subParitions[0];
}
$actionIcons = array(
'ANALYZE' => PMA_Util::getIcon('b_search.png', __('Analyze')),
'CHECK' => PMA_Util::getIcon('eye.png', __('Check')),
'OPTIMIZE' => PMA_Util::getIcon('normalize.png', __('Optimize')),
'REBUILD' => PMA_Util::getIcon('s_tbl.png', __('Rebuild')),
'REPAIR' => PMA_Util::getIcon('b_tblops.png', __('Repair')),
'TRUNCATE' => PMA_Util::getIcon('b_empty.png', __('Truncate')),
'DROP' => PMA_Util::getIcon('b_drop.png', __('Drop'))
);
echo PMA\Template::get('table/structure/display_partitions')->render(
array(
'table' => $table,
'url_query' => $url_query,
'partitions' => $partitions,
'partitionMethod' => $firstPartition->getMethod(),
'partitionExpression' => $firstPartition->getExpression(),
'hasDescription' => ! empty($firstPartition->getDescription()),
'hasSubPartitions' => $hasSubPartitions,
'subPartitionMethod' => $hasSubPartitions ? $firstSubPartition->getMethod() : null,
'subPartitionExpression' => $hasSubPartitions ? $firstSubPartition->getExpression() : null,
'actionIcons' => $actionIcons,
)
);
}
?>
<!--Displays Space usage and row statistics-->
<?php if ($GLOBALS['cfg']['ShowStats']): ?>
<?php echo $tablestats; ?>