diff --git a/ChangeLog b/ChangeLog index 2aa0e0ba5e..8bd16eac61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ phpMyAdmin - ChangeLog 4.6.0.0 (not yet released) + issue #11456 Disabled storage engines + issue #11479 Allow setting routine wise privileges +- issue Hide Insert tab for non-updatable views ++ issue #11490 UI for defining partitioning in create table window 4.5.1.0 (not yet released) - issue Invalid argument supplied for foreach() @@ -15,6 +17,9 @@ phpMyAdmin - ChangeLog - issue #11495 'PMA_Microhistory' is undefined - issue #11496 Incorrect definition for getTablesWhenOpen() - issue #11500 Error when creating new user on MariaDB 10.0.21 +- issue #11505 Notice on htmlspecialchars() +- issue Notice in Structure page of views +- issue #11510 AUTO_INCREMENT always exported when IF NOT EXISTS is on 4.5.0.2 (2015-09-25) - issue #11497 Incorrect indexes when exporting diff --git a/doc/faq.rst b/doc/faq.rst index f99a3114e2..baae226c75 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -2039,7 +2039,7 @@ on its own. By selecting this option, phpMyAdmin will adjust the privilege table so that users have the same privileges on the new items. For example: A user 'bob'@'localhost' has a 'SELECT' privilege on a -column named 'id'. Now, if this column is renamed to 'id_new'; MySQL, +column named 'id'. Now, if this column is renamed to 'id_new', MySQL, on its own, would **not** adjust the column privileges to the new column name. phpMyAdmin can make this adjustment for you automatically. diff --git a/js/functions.js b/js/functions.js index 44a6ceb71e..8ae4a6547c 100644 --- a/js/functions.js +++ b/js/functions.js @@ -2742,6 +2742,9 @@ AJAX.registerTeardown('functions.js', function () { $(document).off('submit', "form.create_table_form.ajax"); $(document).off('click', "form.create_table_form.ajax input[name=submit_num_fields]"); $(document).off('keyup', "form.create_table_form.ajax input"); + $(document).off('change', "form.create_table_form.ajax input[name=partition_count]," + + "form.create_table_form.ajax input[name=subpartition_count]," + + "form.create_table_form.ajax select[name=partition_by]"); }); /** @@ -2855,24 +2858,21 @@ AJAX.registerOnload('functions.js', function () { }); // end create table form (save) /** - * Attach event handler for create table form (add fields) + * Submits the intermediate changes in the table creation form + * to refresh the UI accordingly */ - $(document).on('click', "form.create_table_form.ajax input[name=submit_num_fields]", function (event) { - event.preventDefault(); + function submitChangesInCreateTableForm (actionParam) { + /** * @var the_form object referring to the create table form */ - var $form = $(this).closest('form'); - - if (!checkFormElementInRange(this.form, 'added_fields', PMA_messages.strLeastColumnError, 1)) { - return; - } + var $form = $('form.create_table_form.ajax'); var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest); PMA_prepareForAjaxRequest($form); //User wants to add more fields to the table - $.post($form.attr('action'), $form.serialize() + "&submit_num_fields=1", function (data) { + $.post($form.attr('action'), $form.serialize() + "&" + actionParam, function (data) { if (typeof data !== 'undefined' && data.success) { var $pageContent = $("#page_content"); $pageContent.html(data.message); @@ -2884,6 +2884,19 @@ AJAX.registerOnload('functions.js', function () { PMA_ajaxShowMessage(data.error); } }); //end $.post() + } + + /** + * Attach event handler for create table form (add fields) + */ + $(document).on('click', "form.create_table_form.ajax input[name=submit_num_fields]", function (event) { + event.preventDefault(); + + if (!checkFormElementInRange(this.form, 'added_fields', PMA_messages.strLeastColumnError, 1)) { + return; + } + + submitChangesInCreateTableForm('submit_num_fields=1'); }); // end create table form (add fields) $(document).on('keydown', "form.create_table_form.ajax input[name=added_fields]", function (event) { @@ -2896,6 +2909,16 @@ AJAX.registerOnload('functions.js', function () { .click(); } }); + + /** + * Attach event handler to manage changes in number of partitions and subpartitions + */ + $(document).on('change', "form.create_table_form.ajax input[name=partition_count]," + + "form.create_table_form.ajax input[name=subpartition_count]," + + "form.create_table_form.ajax select[name=partition_by]", function (event) { + submitChangesInCreateTableForm('submit_partition_change=1'); + }); + $("input[value=AUTO_INCREMENT]").change(function(){ if (this.checked) { var col = /\d/.exec($(this).attr('name')); diff --git a/libraries/Menu.php b/libraries/Menu.php index 8edf799236..b208d242c0 100644 --- a/libraries/Menu.php +++ b/libraries/Menu.php @@ -299,6 +299,11 @@ class Menu $db_is_system_schema = $GLOBALS['dbi']->isSystemSchema($this->_db); $tbl_is_view = $GLOBALS['dbi']->getTable($this->_db, $this->_table) ->isView(); + $updatable_view = false; + if ($tbl_is_view) { + $updatable_view = $GLOBALS['dbi']->getTable($this->_db, $this->_table) + ->isUpdatableView(); + } $is_superuser = $GLOBALS['dbi']->isSuperuser(); $isCreateOrGrantUser = $GLOBALS['dbi']->isUserType('grant') || $GLOBALS['dbi']->isUserType('create'); @@ -330,7 +335,7 @@ class Menu array('tbl_select.php', 'tbl_zoom_select.php', 'tbl_find_replace.php') ); - if (! $db_is_system_schema) { + if (! $db_is_system_schema && (! $tbl_is_view || $updatable_view)) { $tabs['insert']['icon'] = 'b_insrow.png'; $tabs['insert']['link'] = 'tbl_change.php'; $tabs['insert']['text'] = __('Insert'); diff --git a/libraries/StorageEngine.php b/libraries/StorageEngine.php index c6b33841d6..f4702cf77a 100644 --- a/libraries/StorageEngine.php +++ b/libraries/StorageEngine.php @@ -135,18 +135,24 @@ class StorageEngine * @param string $selected The selected engine * @param boolean $offerUnavailableEngines Should unavailable storage * engines be offered? + * @param boolean $addEmpty Whether to provide empty option * * @static * @return string html selectbox */ static public function getHtmlSelect( $name = 'engine', $id = null, - $selected = null, $offerUnavailableEngines = false + $selected = null, $offerUnavailableEngines = false, + $addEmpty = false ) { $selected = /*overload*/mb_strtolower($selected); $output = ''; + // As seen in the reporting server (#15042) we sometimes receive + // an array here. No clue about its origin nor content, so let's avoid + // a notice on htmlspecialchars(). + if (! is_array($value)) { + $htmlOutput .= ''; + } break; case 'number_text': $htmlOutput .= ' 1 + ) { + $sql_query .= " PARTITION BY " . $_REQUEST['partition_by'] + . " (" . $_REQUEST['partition_expr'] . ")" + . " PARTITIONS " . $_REQUEST['partition_count']; + } + + if (! empty($_REQUEST['subpartition_by']) + && ! empty($_REQUEST['subpartition_expr']) + && ! empty($_REQUEST['subpartition_count']) + && $_REQUEST['subpartition_count'] > 1 + ) { + $sql_query .= " SUBPARTITION BY " . $_REQUEST['subpartition_by'] + . " (" . $_REQUEST['subpartition_expr'] . ")" + . " SUBPARTITIONS " . $_REQUEST['subpartition_count']; + } + + if (! empty($_REQUEST['partitions'])) { + $i = 0; + $partitions = array(); + foreach ($_REQUEST['partitions'] as $partition) { + $partitions[] = PMA_getPartitionDefinition('p' . $i, $partition); + $i++; + } + $sql_query .= " (" . implode(", ", $partitions) . ")"; + } + + return $sql_query; +} + +/** + * Returns the definition of a partition/subpartition + * + * @param string $name name of the partition/subpartition + * @param array $partition array of partition/subpartition detiails + * @param boolean $isSubPartition whether a subpartition + * + * @return string partition/subpartition definition + */ +function PMA_getPartitionDefinition($name, $partition, $isSubPartition = false) +{ + $sql_query = " " . ($isSubPartition ? "SUB" : "") . "PARTITION " . $name; + + if (! empty($partition['value_type'])) { + $sql_query .= " VALUES " . $partition['value_type']; + + if ($partition['value_type'] != 'LESS THAN MAXVALUE') { + $sql_query .= " (" . $partition['value'] . ")"; + } + } + + if (! empty($partition['engine'])) { + $sql_query .= " ENGINE = " . $partition['engine']; + } + if (! empty($partition['comment'])) { + $sql_query .= " COMMENT = '" . $partition['comment'] . "'"; + } + if (! empty($partition['data_directory'])) { + $sql_query .= " DATA DIRECTORY = '" . $partition['data_directory'] . "'"; + } + if (! empty($partition['index_directory'])) { + $sql_query .= " INDEX_DIRECTORY = '" . $partition['index_directory'] . "'"; + } + if (! empty($partition['max_rows'])) { + $sql_query .= " MAX_ROWS = " . $partition['max_rows']; + } + if (! empty($partition['min_rows'])) { + $sql_query .= " MIN_ROWS = " . $partition['min_rows']; + } + if (! empty($partition['tablespace'])) { + $sql_query .= " TABLESPACE = " . $partition['tablespace']; + } + if (! empty($partition['node_group'])) { + $sql_query .= " NODEGROUP = " . $partition['node_group']; + } + + if (! empty($partition['subpartitions'])) { + $j = 0; + $subpartitions = array(); + foreach ($partition['subpartitions'] as $subpartition) { + $subpartitions[] = PMA_getPartitionDefinition($name . 's' . $j, $subpartition, true); + $j++; + } + $sql_query .= " (" . implode(", ", $subpartitions) . ")"; + } + + return $sql_query; +} + /** * Function to get table creation sql query * @@ -331,11 +431,7 @@ function PMA_getTableCreationQuery($db, $table) $sql_query .= ' COMMENT = \'' . PMA\libraries\Util::sqlAddSlashes($_REQUEST['comment']) . '\''; } - if (!empty($_REQUEST['partition_definition'])) { - $sql_query .= ' ' . PMA\libraries\Util::sqlAddSlashes( - $_REQUEST['partition_definition'] - ); - } + $sql_query .= PMA_getPartitionsDefinition(); $sql_query .= ';'; return $sql_query; @@ -348,13 +444,15 @@ function PMA_getTableCreationQuery($db, $table) */ function PMA_getNumberOfFieldsFromRequest() { - if (isset($_REQUEST['submit_num_fields'])) { + if (isset($_REQUEST['submit_num_fields'])) { // adding new fields $num_fields = $_REQUEST['orig_num_fields'] + $_REQUEST['added_fields']; + } elseif (isset($_REQUEST['orig_num_fields'])) { // retaining existing fields + $num_fields = $_REQUEST['orig_num_fields']; } elseif (isset($_REQUEST['num_fields']) && intval($_REQUEST['num_fields']) > 0 - ) { + ) { // new table with specified number of fields $num_fields = (int) $_REQUEST['num_fields']; - } else { + } else { // new table with unspecified number of fields $num_fields = 4; } diff --git a/libraries/plugins/export/ExportSql.php b/libraries/plugins/export/ExportSql.php index 86bd1a32b3..9372713485 100644 --- a/libraries/plugins/export/ExportSql.php +++ b/libraries/plugins/export/ExportSql.php @@ -1766,7 +1766,8 @@ class ExportSql extends ExportPlugin // Removing the `AUTO_INCREMENT` attribute from the `CREATE TABLE` // too. if (!empty($statement->entityOptions) - && empty($GLOBALS['sql_if_not_exists']) + && (empty($GLOBALS['sql_if_not_exists']) + || empty($GLOBALS['sql_auto_increment'])) ) { $statement->entityOptions->remove('AUTO_INCREMENT'); } diff --git a/libraries/server_privileges.lib.php b/libraries/server_privileges.lib.php index 64cc599eca..28b00cce40 100644 --- a/libraries/server_privileges.lib.php +++ b/libraries/server_privileges.lib.php @@ -732,7 +732,7 @@ function PMA_getHtmlForRequires($row) $html_output .= ' $action, 'form_params' => $form_params, 'content_cells' => $content_cells, + 'partitionDetails' => isset($partitionDetails) ? $partitionDetails : array() ) ); diff --git a/po/af.po b/po/af.po index 876f051f79..2ed2b515fd 100644 --- a/po/af.po +++ b/po/af.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: phpMyAdmin 4.6.0-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" -"POT-Creation-Date: 2015-09-06 07:31-0400\n" +"POT-Creation-Date: 2015-09-28 18:02-0400\n" "PO-Revision-Date: 2014-03-28 11:05+0200\n" "Last-Translator: Michal Čihař \n" "Language-Team: Afrikaans