diff --git a/ChangeLog b/ChangeLog
index cf2ec854c6..e8f00a4d45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,7 @@ phpMyAdmin - ChangeLog
+ rfe #1145 Preview SQL instead of executing it
+ rfe #759 Use aliases in SQL export for tables and columns
- bug #4450 Query is duplicated on Ctrl+Enter
++ rfe #755 Export with table/column name changes
4.2.4.0 (not yet released)
- bug #4449 Mediawiki export does not produce table header row; also fix related PHP warnings
diff --git a/export.php b/export.php
index 215d494032..b1c80789bc 100644
--- a/export.php
+++ b/export.php
@@ -126,6 +126,7 @@ if (!defined('TESTSUITE')) {
'sql_hex_for_binary',
'sql_utc_time',
'sql_drop_database',
+ 'sql_views_as_tables',
'csv_separator',
'csv_enclosed',
'csv_escaped',
@@ -147,7 +148,8 @@ if (!defined('TESTSUITE')) {
'latex_data_caption',
'latex_data_continued_caption',
'latex_data_label',
- 'latex_null'
+ 'latex_null',
+ 'aliases'
);
foreach ($post_params as $one_post_param) {
@@ -241,6 +243,18 @@ if (!defined('TESTSUITE')) {
PMA_fatalError(__('Bad parameters!'));
}
+ // Merge SQL Query aliases with Export aliases from
+ // export page, Export page aliases are given more
+ // preference over SQL Query aliases.
+ if (!empty($_REQUEST['aliases'])) {
+ $aliases = PMA_mergeAliases(
+ PMA_SQP_getAliasesFromQuery($sql_query, $db),
+ $_REQUEST['aliases']
+ );
+ } else {
+ $aliases = PMA_SQP_getAliasesFromQuery($sql_query, $db);
+ }
+
/**
* Increase time limit for script execution and initializes some variables
*/
@@ -370,12 +384,14 @@ if (!defined('TESTSUITE')) {
}
PMA_exportServer(
$db_select, $whatStrucOrData, $export_plugin, $crlf, $err_url,
- $export_type, $do_relation, $do_comments, $do_mime, $do_dates
+ $export_type, $do_relation, $do_comments, $do_mime, $do_dates,
+ $aliases
);
} elseif ($export_type == 'database') {
PMA_exportDatabase(
$db, $tables, $whatStrucOrData, $export_plugin, $crlf, $err_url,
- $export_type, $do_relation, $do_comments, $do_mime, $do_dates
+ $export_type, $do_relation, $do_comments, $do_mime, $do_dates,
+ $aliases
);
} else {
// We export just one table
@@ -392,8 +408,7 @@ if (!defined('TESTSUITE')) {
PMA_exportTable(
$db, $table, $whatStrucOrData, $export_plugin, $crlf, $err_url,
$export_type, $do_relation, $do_comments, $do_mime, $do_dates,
- $allrows, $limit_to, $limit_from, $sql_query,
- PMA_SQP_getAliasesFromQuery($sql_query, $db)
+ $allrows, $limit_to, $limit_from, $sql_query, $aliases
);
}
if (! $export_plugin->exportFooter()) {
diff --git a/js/export.js b/js/export.js
index 2f80e1518b..012d618069 100644
--- a/js/export.js
+++ b/js/export.js
@@ -42,6 +42,9 @@ AJAX.registerTeardown('export.js', function () {
$("#plugins").unbind('change');
$("input[type='radio'][name='quick_or_custom']").unbind('change');
$("input[type='radio'][name='allrows']").unbind('change');
+ $('#btn_alias_config').off('click');
+ $('#db_alias_select').off('change');
+ $('.table_alias_select').off('change');
});
AJAX.registerOnload('export.js', function () {
@@ -246,6 +249,73 @@ function check_time_out(time_limit)
}, time_limit * 1000);
}
+
+/**
+ * Handler for Database/table alias select
+ *
+ * @param object event the event object
+ *
+ * @return void
+ */
+function aliasSelectHandler(event) {
+ var sel = event.data.sel;
+ var type = event.data.type;
+ var inputId = $(this).val();
+ var $label = $(this).next('label');
+ $('input#' + $label.attr('for')).addClass('hide');
+ $('input#' + inputId).removeClass('hide');
+ $label.attr('for', inputId);
+ //alert('#' + $label.attr('for'));
+ $('#alias_modal ' + sel + '[id$=' + type + ']:visible').addClass('hide');
+ $('#alias_modal ' + sel + '#' + inputId + type).removeClass('hide');
+ $("#alias_modal").dialog("option", "position", "center");
+}
+
+/**
+ * Handler for Alias dialog box
+ *
+ * @param object event the event object
+ *
+ * @return void
+ */
+ function createAliasModal(event) {
+ event.preventDefault();
+ $('#alias_modal').dialog({
+ width: Math.min($(window).width() - 100, 700),
+ modal: true,
+ dialogClass: "alias-dialog",
+ buttons: {
+ 'Reset All': function() {
+ $(this).find('input[type="text"]').val('');
+ },
+ 'Reset': function() {
+ $(this).find('input[type="text"]:visible').val('');
+ },
+ 'Save & Close': function() {
+ $(this).dialog("close");
+ $('#alias_modal').parent().appendTo($('form[name="dump"]'));
+ }
+ },
+ create: function() {
+ $(this).css('maxHeight', $(window).height() - 150);
+ $('.alias-dialog .ui-dialog-titlebar-close').remove();
+ },
+ close: function() {
+ var isEmpty = true;
+ $(this).find('input[type="text"]').each(function() {
+ // trim input fields on close
+ $(this).val($(this).val().trim());
+ // check if non empty field present
+ if ($(this).val()) {
+ isEmpty = false;
+ }
+ });
+ $('input#btn_alias_config').attr('checked', !isEmpty);
+ },
+ position: 'center'
+ });
+ }
+
AJAX.registerOnload('export.js', function () {
$("input[type='radio'][name='quick_or_custom']").change(toggle_quick_or_custom);
@@ -278,4 +348,21 @@ AJAX.registerOnload('export.js', function () {
disable_dump_some_rows_sub_options();
}
});
+
+ // Open Alias Modal Dialog on click
+ $('#btn_alias_config').on('click', createAliasModal);
+
+ // Database alias select on change event
+ $('#db_alias_select').on(
+ 'change',
+ {sel: 'span', type: '_tables'},
+ aliasSelectHandler
+ );
+
+ // Table alias select on change event
+ $('.table_alias_select').on(
+ 'change',
+ {sel: 'table', type: '_cols'},
+ aliasSelectHandler
+ );
});
diff --git a/libraries/display_export.lib.php b/libraries/display_export.lib.php
index 01dee658ae..9b48b886df 100644
--- a/libraries/display_export.lib.php
+++ b/libraries/display_export.lib.php
@@ -634,6 +634,10 @@ function PMA_getHtmlForExportOptionsOutput($export_type)
$html = '
';
$html .= '
' . __('Output:') . '
';
$html .= '
';
+ $html .= '- ';
+ $html .= '
';
$html .= '- ';
$html .= 'getColumnsFull(
+ null, null, null, $GLOBALS['userlink']
+ );
+ foreach ($dbs_not_allowed as $db) {
+ unset($databases[$db]);
+ }
+ // Database export does not have table set.
+ } elseif (empty($table)) {
+ $tables = $GLOBALS['dbi']->getColumnsFull(
+ $db, null, null, $GLOBALS['userlink']
+ );
+ $databases = array($db => $tables);
+ // Table export
+ } else {
+ $columns = $GLOBALS['dbi']->getColumnsFull(
+ $db, $table, null, $GLOBALS['userlink']
+ );
+ $databases = array(
+ $db => array(
+ $table => $columns
+ )
+ );
+ }
+
+ $html = '';
+ return $html;
+}
?>
diff --git a/libraries/export.lib.php b/libraries/export.lib.php
index 41d2315977..cd7b0d7f2d 100644
--- a/libraries/export.lib.php
+++ b/libraries/export.lib.php
@@ -457,12 +457,14 @@ function PMA_getHtmlForDisplayedExportHeader($export_type, $db, $table)
* @param string $do_comments whether to add comments
* @param string $do_mime whether to add MIME info
* @param string $do_dates whether to add dates
+ * @param array $aliases Alias information for db/table/column
*
* @return void
*/
function PMA_exportServer(
$db_select, $whatStrucOrData, $export_plugin, $crlf, $err_url,
- $export_type, $do_relation, $do_comments, $do_mime, $do_dates
+ $export_type, $do_relation, $do_comments, $do_mime, $do_dates,
+ $aliases
) {
if (! empty($db_select)) {
$tmp_select = implode($db_select, '|');
@@ -477,7 +479,7 @@ function PMA_exportServer(
PMA_exportDatabase(
$current_db, $tables, $whatStrucOrData, $export_plugin, $crlf,
$err_url, $export_type, $do_relation, $do_comments, $do_mime,
- $do_dates
+ $do_dates, $aliases
);
}
} // end foreach database
@@ -497,17 +499,21 @@ function PMA_exportServer(
* @param string $do_comments whether to add comments
* @param string $do_mime whether to add MIME info
* @param string $do_dates whether to add dates
+ * @param array $aliases Alias information for db/table/column
*
* @return void
*/
function PMA_exportDatabase(
$db, $tables, $whatStrucOrData, $export_plugin, $crlf, $err_url,
- $export_type, $do_relation, $do_comments, $do_mime, $do_dates
+ $export_type, $do_relation, $do_comments, $do_mime, $do_dates,
+ $aliases
) {
- if (! $export_plugin->exportDBHeader($db)) {
+ $db_alias = !empty($aliases[$db]['alias'])
+ ? $aliases[$db]['alias'] : '';
+ if (! $export_plugin->exportDBHeader($db, $db_alias)) {
return;
}
- if (! $export_plugin->exportDBCreate($db)) {
+ if (! $export_plugin->exportDBCreate($db, $db_alias)) {
return;
}
@@ -515,7 +521,7 @@ function PMA_exportDatabase(
&& strpos($GLOBALS['sql_structure_or_data'], 'structure') !== false
&& isset($GLOBALS['sql_procedure_function'])
) {
- $export_plugin->exportRoutines($db);
+ $export_plugin->exportRoutines($db, $aliases);
}
$views = array();
@@ -537,9 +543,9 @@ function PMA_exportDatabase(
if (isset($GLOBALS['sql_create_view'])) {
if (! $export_plugin->exportStructure(
- $db, $table, $crlf, $err_url,
- 'stand_in', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates
+ $db, $table, $crlf, $err_url, 'stand_in',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
break 1;
}
@@ -566,9 +572,9 @@ function PMA_exportDatabase(
}
if (! $export_plugin->exportStructure(
- $db, $table, $crlf, $err_url,
- 'create_table', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates
+ $db, $table, $crlf, $err_url, 'create_table',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
break 1;
}
@@ -584,7 +590,7 @@ function PMA_exportDatabase(
$local_query = 'SELECT * FROM ' . PMA_Util::backquote($db)
. '.' . PMA_Util::backquote($table);
if (! $export_plugin->exportData(
- $db, $table, $crlf, $err_url, $local_query
+ $db, $table, $crlf, $err_url, $local_query, $aliases
)) {
break 1;
}
@@ -595,9 +601,9 @@ function PMA_exportDatabase(
|| $whatStrucOrData == 'structure_and_data')
) {
if (! $export_plugin->exportStructure(
- $db, $table, $crlf, $err_url,
- 'triggers', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates
+ $db, $table, $crlf, $err_url, 'triggers',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
break 1;
}
@@ -612,9 +618,9 @@ function PMA_exportDatabase(
|| $whatStrucOrData == 'structure_and_data'
) {
if (! $export_plugin->exportStructure(
- $db, $view, $crlf, $err_url,
- 'create_view', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates
+ $db, $view, $crlf, $err_url, 'create_view',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
break 1;
}
@@ -623,7 +629,7 @@ function PMA_exportDatabase(
}
- if (! $export_plugin->exportDBFooter($db)) {
+ if (! $export_plugin->exportDBFooter($db, $db_alias)) {
return;
}
}
@@ -655,7 +661,9 @@ function PMA_exportTable(
$export_type, $do_relation, $do_comments, $do_mime, $do_dates,
$allrows, $limit_to, $limit_from, $sql_query, $aliases
) {
- if (! $export_plugin->exportDBHeader($db)) {
+ $db_alias = !empty($aliases[$db]['alias'])
+ ? $aliases[$db]['alias'] : '';
+ if (! $export_plugin->exportDBHeader($db, $db_alias)) {
return;
}
if (isset($allrows)
@@ -679,9 +687,9 @@ function PMA_exportTable(
if (isset($GLOBALS['sql_create_view'])) {
if (! $export_plugin->exportStructure(
- $db, $table, $crlf, $err_url,
- 'create_view', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates
+ $db, $table, $crlf, $err_url, 'create_view',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
return;
}
@@ -690,9 +698,9 @@ function PMA_exportTable(
} else if (isset($GLOBALS['sql_create_table'])) {
if (! $export_plugin->exportStructure(
- $db, $table, $crlf, $err_url,
- 'create_table', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates, $aliases
+ $db, $table, $crlf, $err_url, 'create_table',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
return;
}
@@ -731,14 +739,14 @@ function PMA_exportTable(
|| $whatStrucOrData == 'structure_and_data')
) {
if (! $export_plugin->exportStructure(
- $db, $table, $crlf, $err_url,
- 'triggers', $export_type,
- $do_relation, $do_comments, $do_mime, $do_dates, $aliases
+ $db, $table, $crlf, $err_url, 'triggers',
+ $export_type, $do_relation, $do_comments,
+ $do_mime, $do_dates, $aliases
)) {
return;
}
}
- if (! $export_plugin->exportDBFooter($db)) {
+ if (! $export_plugin->exportDBFooter($db, $db_alias)) {
return;
}
}
@@ -764,4 +772,58 @@ function PMA_showExportPage($export_type)
}
exit();
}
+
+/**
+ * Merge two alias arrays, if array1 and array2 have
+ * conflicting alias then array2 value is used if it
+ * is non empty otherwise array1 value.
+ *
+ * @param array $aliases1 first array of aliases
+ * @param array $aliases2 second array of aliases
+ *
+ * @return array resultant merged aliases info
+ */
+function PMA_mergeAliases($aliases1, $aliases2)
+{
+ // First do a recursive array merge
+ // on aliases arrays.
+ $aliases = array_merge_recursive($aliases1, $aliases2);
+ // Now, resolve conflicts in aliases, if any
+ foreach ($aliases as $db_name => $db) {
+ // If alias key is an array then
+ // it is a merge conflict.
+ if (isset($db['alias']) && is_array($db['alias'])) {
+ $val1 = $db['alias'][0];
+ $val2 = $db['alias'][1];
+ // Use aliases2 alias if non empty
+ $aliases[$db_name]['alias']
+ = empty($val2) ? $val1 : $val2;
+ }
+ if (!isset($db['tables'])) {
+ continue;
+ }
+ foreach ($db['tables'] as $tbl_name => $tbl) {
+ if (isset($tbl['alias']) && is_array($tbl['alias'])) {
+ $val1 = $tbl['alias'][0];
+ $val2 = $tbl['alias'][1];
+ // Use aliases2 alias if non empty
+ $aliases[$db_name]['tables'][$tbl_name]['alias']
+ = empty($val2) ? $val1 : $val2;
+ }
+ if (!isset($tbl['columns'])) {
+ continue;
+ }
+ foreach ($tbl['columns'] as $col => $col_as) {
+ if (isset($col_as) && is_array($col_as)) {
+ $val1 = $col_as[0];
+ $val2 = $col_as[1];
+ // Use aliases2 alias if non empty
+ $aliases[$db_name]['tables'][$tbl_name]['columns'][$col]
+ = empty($val2) ? $val1 : $val2;
+ }
+ };
+ };
+ }
+ return $aliases;
+}
?>
diff --git a/libraries/plugins/export/ExportSql.class.php b/libraries/plugins/export/ExportSql.class.php
index 42a0ac0995..36b0125efd 100644
--- a/libraries/plugins/export/ExportSql.class.php
+++ b/libraries/plugins/export/ExportSql.class.php
@@ -475,14 +475,18 @@ class ExportSql extends ExportPlugin
/**
* Exports routines (procedures and functions)
*
- * @param string $db Database
+ * @param string $db Database
+ * @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
- public function exportRoutines($db)
+ public function exportRoutines($db, $aliases = array())
{
global $crlf;
+ $db_alias = $db;
+ $this->initAlias($aliases, $db_alias);
+
$text = '';
$delimiter = '$$';
@@ -500,17 +504,31 @@ class ExportSql extends ExportPlugin
$this->_exportComment()
. $this->_exportComment(__('Procedures'))
. $this->_exportComment();
-
+ $used_alias = false;
+ $proc_query = '';
foreach ($procedure_names as $procedure_name) {
if (! empty($GLOBALS['sql_drop_table'])) {
- $text .= 'DROP PROCEDURE IF EXISTS '
+ $proc_query .= 'DROP PROCEDURE IF EXISTS '
. PMA_Util::backquote($procedure_name)
. $delimiter . $crlf;
}
- $text .= $GLOBALS['dbi']
- ->getDefinition($db, 'PROCEDURE', $procedure_name)
- . $delimiter . $crlf . $crlf;
+ $create_query = $GLOBALS['dbi']
+ ->getDefinition($db, 'PROCEDURE', $procedure_name);
+ $create_query = $this->replaceWithAliases(
+ $create_query, $aliases, $db, '', $flag
+ );
+ // One warning per database
+ if ($flag) {
+ $used_alias = true;
+ }
+ $proc_query .= $create_query . $delimiter . $crlf . $crlf;
}
+ if ($used_alias) {
+ $text .= $this->_exportComment(__('It appears your database uses procedures;'))
+ . $this->_exportComment(__('alias export may not work reliably in all cases.'))
+ . $this->_exportComment();
+ }
+ $text .= $proc_query;
}
if ($function_names) {
@@ -518,17 +536,31 @@ class ExportSql extends ExportPlugin
$this->_exportComment()
. $this->_exportComment(__('Functions'))
. $this->_exportComment();
-
+ $used_alias = false;
+ $function_query = '';
foreach ($function_names as $function_name) {
if (! empty($GLOBALS['sql_drop_table'])) {
- $text .= 'DROP FUNCTION IF EXISTS '
+ $function_query .= 'DROP FUNCTION IF EXISTS '
. PMA_Util::backquote($function_name)
. $delimiter . $crlf;
}
- $text .= $GLOBALS['dbi']
- ->getDefinition($db, 'FUNCTION', $function_name)
- . $delimiter . $crlf . $crlf;
+ $create_query = $GLOBALS['dbi']
+ ->getDefinition($db, 'FUNCTION', $function_name);
+ $create_query = $this->replaceWithAliases(
+ $create_query, $aliases, $db, '', $flag
+ );
+ // One warning per database
+ if ($flag) {
+ $used_alias = true;
+ }
+ $function_query .= $create_query . $delimiter . $crlf . $crlf;
}
+ if ($used_alias) {
+ $text .= $this->_exportComment(__('It appears your database uses functions;'))
+ . $this->_exportComment(__('alias export may not work reliably in all cases.'))
+ . $this->_exportComment();
+ }
+ $text .= $function_query;
}
if ($procedure_names || $function_names) {
@@ -760,7 +792,7 @@ class ExportSql extends ExportPlugin
$create_query = 'CREATE DATABASE IF NOT EXISTS '
. (isset($GLOBALS['sql_backquotes'])
? PMA_Util::backquoteCompat($db_alias, $compat) : $db_alias);
- $collation = PMA_getDbCollation($db_alias);
+ $collation = PMA_getDbCollation($db);
if (PMA_DRIZZLE) {
$create_query .= ' COLLATE ' . $collation;
} else {
@@ -903,18 +935,22 @@ class ExportSql extends ExportPlugin
/**
* Returns a stand-in CREATE definition to resolve view dependencies
*
- * @param string $db the database name
- * @param string $view the view name
- * @param string $crlf the end of line sequence
+ * @param string $db the database name
+ * @param string $view the view name
+ * @param string $crlf the end of line sequence
+ * @param array $aliases Aliases of db/table/columns
*
* @return string resulting definition
*/
- public function getTableDefStandIn($db, $view, $crlf)
+ public function getTableDefStandIn($db, $view, $crlf, $aliases = array())
{
+ $db_alias = $db;
+ $view_alias = $view;
+ $this->initAlias($aliases, $db_alias, $view_alias);
$create_query = '';
if (! empty($GLOBALS['sql_drop_table'])) {
$create_query .= 'DROP VIEW IF EXISTS '
- . PMA_Util::backquote($view)
+ . PMA_Util::backquote($view_alias)
. ';' . $crlf;
}
@@ -925,14 +961,18 @@ class ExportSql extends ExportPlugin
) {
$create_query .= 'IF NOT EXISTS ';
}
- $create_query .= PMA_Util::backquote($view) . ' (' . $crlf;
+ $create_query .= PMA_Util::backquote($view_alias) . ' (' . $crlf;
$tmp = array();
$columns = $GLOBALS['dbi']->getColumnsFull($db, $view);
foreach ($columns as $column_name => $definition) {
- $tmp[] = PMA_Util::backquote($column_name) . ' ' .
+ $col_alias = $column_name;
+ if (!empty($aliases[$db]['tables'][$view]['columns'][$col_alias])) {
+ $col_alias = $aliases[$db]['tables'][$view]['columns'][$col_alias];
+ }
+ $tmp[] = PMA_Util::backquote($col_alias) . ' ' .
$definition['Type'] . $crlf;
}
- $create_query .= implode(',', $tmp) . ');';
+ $create_query .= implode(',', $tmp) . ');' . $crlf;
return($create_query);
}
@@ -944,6 +984,7 @@ class ExportSql extends ExportPlugin
* @param string $crlf the end of line sequence
* @param bool $add_semicolon whether to add semicolon and end-of-line at
* the end
+ * @param array $aliases Aliases of db/table/columns
*
* @return string resulting schema
*/
@@ -951,24 +992,32 @@ class ExportSql extends ExportPlugin
$db,
$view,
$crlf,
- $add_semicolon = true
+ $add_semicolon = true,
+ $aliases = array()
) {
+ $db_alias = $db;
+ $view_alias = $view;
+ $this->initAlias($aliases, $db_alias, $view_alias);
$create_query = "CREATE TABLE";
if (isset($GLOBALS['sql_if_not_exists'])) {
$create_query .= " IF NOT EXISTS ";
}
- $create_query .= PMA_Util::backquote($view) . "(" . $crlf;
+ $create_query .= PMA_Util::backquote($view_alias) . "(" . $crlf;
$columns = $GLOBALS['dbi']->getColumns($db, $view, null, true);
$firstCol = true;
foreach ($columns as $column) {
+ $col_alias = $column['Field'];
+ if (!empty($aliases[$db]['tables'][$view]['columns'][$col_alias])) {
+ $col_alias = $aliases[$db]['tables'][$view]['columns'][$col_alias];
+ }
$extracted_columnspec = PMA_Util::extractColumnSpec($column['Type']);
if (! $firstCol) {
$create_query .= "," . $crlf;
}
- $create_query .= " " . PMA_Util::backquote($column['Field']);
+ $create_query .= " " . PMA_Util::backquote($col_alias);
$create_query .= " " . $column['Type'];
if ($extracted_columnspec['can_contain_collation']
&& ! empty($column['Collation'])
@@ -1173,6 +1222,7 @@ class ExportSql extends ExportPlugin
return $this->_exportComment(__('in use') . '(' . $tmp_error . ')');
}
+ $warning = '';
if ($result != false && ($row = $GLOBALS['dbi']->fetchRow($result))) {
$create_query = $row[1];
unset($row);
@@ -1202,8 +1252,19 @@ class ExportSql extends ExportPlugin
}
// substitute aliases in create query
$create_query = $this->replaceWithAliases(
- $create_query, $aliases, $db, $table
+ $create_query, $aliases, $db, $table, $flag
);
+ // One warning per view
+ if ($flag && $view) {
+ $warning = $this->_exportComment()
+ . $this->_exportComment(
+ __('It appears your database uses views;')
+ )
+ . $this->_exportComment(
+ __('alias export may not work reliably in all cases.')
+ )
+ . $this->_exportComment();
+ }
// Should we use IF NOT EXISTS?
if (isset($GLOBALS['sql_if_not_exists'])) {
$create_query = preg_replace(
@@ -1505,7 +1566,7 @@ class ExportSql extends ExportPlugin
$schema_create .= ($compat != 'MSSQL') ? $auto_increment : '';
$GLOBALS['dbi']->freeResult($result);
- return $schema_create . ($add_semicolon ? ';' . $crlf : '');
+ return $warning . $schema_create . ($add_semicolon ? ';' . $crlf : '');
} // end of the 'getTableDef()' function
/**
@@ -1698,16 +1759,33 @@ class ExportSql extends ExportPlugin
__('Triggers') . ' ' . $formatted_table_name
)
. $this->_exportComment();
+ $used_alias = false;
+ $trigger_query = '';
foreach ($triggers as $trigger) {
if (! empty($GLOBALS['sql_drop_table'])) {
- $dump .= $trigger['drop'] . ';' . $crlf;
+ $trigger_query .= $trigger['drop'] . ';' . $crlf;
}
- $dump .= 'DELIMITER ' . $delimiter . $crlf;
- $dump .= $this->replaceWithAliases(
- $trigger['create'], $aliases, $db, $table
+
+ $trigger_query .= 'DELIMITER ' . $delimiter . $crlf;
+ $trigger_query .= $this->replaceWithAliases(
+ $trigger['create'], $aliases, $db, $table, $flag
);
- $dump .= 'DELIMITER ;' . $crlf;
+ if ($flag) {
+ $used_alias = true;
+ }
+ $trigger_query .= 'DELIMITER ;' . $crlf;
}
+ // One warning per table.
+ if ($used_alias) {
+ $dump .= $this->_exportComment(
+ __('It appears your table uses triggers;')
+ )
+ . $this->_exportComment(
+ __('alias export may not work reliably in all cases.')
+ )
+ . $this->_exportComment();
+ }
+ $dump .= $trigger_query;
}
break;
case 'create_view':
@@ -1722,10 +1800,11 @@ class ExportSql extends ExportPlugin
// delete the stand-in table previously created (if any)
if ($export_type != 'table') {
$dump .= 'DROP TABLE IF EXISTS '
- . PMA_Util::backquote($table) . ';' . $crlf;
+ . PMA_Util::backquote($table_alias) . ';' . $crlf;
}
$dump .= $this->getTableDef(
- $db, $table, $crlf, $error_url, $dates, true, true
+ $db, $table, $crlf, $error_url, $dates,
+ true, true, true, $aliases
);
} else {
$dump .=
@@ -1739,10 +1818,10 @@ class ExportSql extends ExportPlugin
// delete the stand-in table previously created (if any)
if ($export_type != 'table') {
$dump .= 'DROP TABLE IF EXISTS '
- . PMA_Util::backquote($table) . ';' . $crlf;
+ . PMA_Util::backquote($table_alias) . ';' . $crlf;
}
$dump .= $this->_getTableDefForView(
- $db, $table, $crlf, true
+ $db, $table, $crlf, true, $aliases
);
}
break;
@@ -1753,7 +1832,7 @@ class ExportSql extends ExportPlugin
)
. $this->_exportComment();
// export a stand-in definition to resolve view dependencies
- $dump .= $this->getTableDefStandIn($db, $table, $crlf);
+ $dump .= $this->getTableDefStandIn($db, $table, $crlf, $aliases);
} // end switch
// this one is built by getTableDef() to use in table copy/move
@@ -1837,8 +1916,12 @@ class ExportSql extends ExportPlugin
$field_set = array();
for ($j = 0; $j < $fields_cnt; $j++) {
+ $col_as = $fields_meta[$j]->name;
+ if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
+ $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
+ }
$field_set[$j] = PMA_Util::backquoteCompat(
- $fields_meta[$j]->name,
+ $col_as,
$compat,
$sql_backquotes
);
@@ -2235,11 +2318,14 @@ class ExportSql extends ExportPlugin
* @param array $aliases Alias information for db/table/column
* @param string $db the database name
* @param string $table the tablename
+ * @param string &$flag the flag denoting whether any replacement was done
*
* @return string query replaced with aliases
*/
- public function replaceWithAliases($sql_query, $aliases, $db, $table)
- {
+ public function replaceWithAliases(
+ $sql_query, $aliases, $db, $table = '', &$flag = null
+ ) {
+ $flag = false;
// Return original sql query if no aliases are provided.
if (!is_array($aliases) || empty($aliases) || empty($sql_query)) {
return $sql_query;
@@ -2249,7 +2335,10 @@ class ExportSql extends ExportPlugin
);
$supported_query_ons = array(
'TABLE' => true,
- 'TRIGGER' => true
+ 'VIEW' => true,
+ 'TRIGGER' => true,
+ 'FUNCTION' => true,
+ 'PROCEDURE' => true
);
$identifier_types = array(
'alpha_identifier',
@@ -2276,8 +2365,15 @@ class ExportSql extends ExportPlugin
for ($i = 0; $i < $size && !$query_end; $i++) {
$type = $tokens[$i]['type'];
$data = $tokens[$i]['data'];
+ $data_next = isset($tokens[$i+1]['data'])
+ ? $tokens[$i+1]['data'] : '';
+ $data_prev = ($i > 0) ? $tokens[$i-1]['data'] : '';
$d_unq = PMA_Util::unQuote($data);
+ $d_unq_next = PMA_Util::unQuote($data_next);
+ $d_unq_prev = PMA_Util::unQuote($data_prev);
$d_upper = strtoupper($d_unq);
+ $d_upper_next = strtoupper($d_unq_next);
+ $d_upper_prev = strtoupper($d_unq_prev);
$pos = $tokens[$i]['pos'] + $offset;
if ($type === 'alpha_reservedWord') {
if ($query_type === ''
@@ -2295,13 +2391,14 @@ class ExportSql extends ExportPlugin
// replace create table name
if (!$in_create_table_fields
&& in_array($type, $identifier_types)
- && isset($aliases[$db]['tables'][$table]['alias'])
+ && !empty($aliases[$db]['tables'][$table]['alias'])
) {
$sql_query = $this->substituteAlias(
$sql_query, $data,
$aliases[$db]['tables'][$table]['alias'],
$pos, $offset
);
+ $flag = true;
} elseif ($type === 'punct_bracket_open_round') {
// CREATE TABLE fields started
if (!$in_create_table_fields) {
@@ -2330,15 +2427,24 @@ class ExportSql extends ExportPlugin
) {
$table = $d_unq;
$ref_table_seen = true;
+ if (!empty($aliases[$db]['tables'][$table]['alias'])) {
+ $sql_query = $this->substituteAlias(
+ $sql_query, $data,
+ $aliases[$db]['tables'][$table]['alias'],
+ $pos, $offset
+ );
+ $flag = true;
+ }
// Replace column names
} elseif (in_array($type, $identifier_types)
- && isset($aliases[$db]['tables'][$table]['columns'][$d_unq])
+ && !empty($aliases[$db]['tables'][$table]['columns'][$d_unq])
) {
$sql_query = $this->substituteAlias(
$sql_query, $data,
$aliases[$db]['tables'][$table]['columns'][$d_unq],
$pos, $offset
);
+ $flag = true;
}
// CREATE TRIGGER - Alias replacement
} elseif ($query_type === 'CREATE' && $query_on === 'TRIGGER') {
@@ -2349,7 +2455,7 @@ class ExportSql extends ExportPlugin
$on_seen = true;
} elseif ($on_seen && in_array($type, $identifier_types)) {
if (!$ref_table_seen
- && isset($aliases[$db]['tables'][$d_unq]['alias'])
+ && !empty($aliases[$db]['tables'][$d_unq]['alias'])
) {
$ref_table_seen = true;
$sql_query = $this->substituteAlias(
@@ -2357,25 +2463,49 @@ class ExportSql extends ExportPlugin
$aliases[$db]['tables'][$d_unq]['alias'],
$pos, $offset
);
+ $flag = true;
} else {
- // search for identifiers
+ // search for identifier alias
$alias = $this->getAlias($aliases, $d_unq);
if (!empty($alias)) {
$sql_query = $this->substituteAlias(
$sql_query, $data, $alias, $pos, $offset
);
+ $flag = true;
}
}
}
+ // CREATE PROCEDURE|FUNCTION|VIEW - Alias replacement
+ } elseif ($query_type === 'CREATE'
+ && ($query_on === 'FUNCTION'
+ || $query_on === 'PROCEDURE'
+ || $query_on === 'VIEW')
+ ) {
+ // LANGUAGE SQL | (READS|MODIFIES) SQL DATA
+ // characteristics are skipped
+ if ($type === 'alpha_identifier'
+ && (($d_upper === 'LANGUAGE' && $d_upper_next === 'SQL')
+ || ($d_upper === 'DATA' && $d_upper_prev === 'SQL'))
+ ) {
+ continue;
+ // No need to process further in case of VIEW
+ // when 'WITH' keyword has been detected
+ } elseif ($query_on === 'VIEW'
+ && $type === 'alpha_reservedWord' && $d_upper === 'WITH'
+ ) {
+ $query_end = true;
+ } elseif (in_array($type, $identifier_types)) {
+ // search for identifier alias
+ $alias = $this->getAlias($aliases, $d_unq);
+ if (!empty($alias)) {
+ $sql_query = $this->substituteAlias(
+ $sql_query, $data, $alias, $pos, $offset
+ );
+ $flag = true;
+ };
+ }
}
}
- if ($query_type === 'CREATE' && $query_on === 'TRIGGER') {
- $warning = $this->_exportComment()
- . $this->_exportComment(__('It appears your table uses triggers;'))
- . $this->_exportComment(__('alias export may not work reliably in all cases.'))
- . $this->_exportComment();
- PMA_exportOutputHandler($warning);
- }
return $sql_query;
}
@@ -2418,10 +2548,10 @@ class ExportSql extends ExportPlugin
*/
public function initAlias($aliases, &$db, &$table = null)
{
- if (isset($aliases[$db]['tables'][$table]['alias'])) {
+ if (!empty($aliases[$db]['tables'][$table]['alias'])) {
$table = $aliases[$db]['tables'][$table]['alias'];
}
- if (isset($aliases[$db]['alias'])) {
+ if (!empty($aliases[$db]['alias'])) {
$db = $aliases[$db]['alias'];
}
}
@@ -2431,27 +2561,35 @@ class ExportSql extends ExportPlugin
*
* @param array $aliases Alias information for db/table/column
* @param string $id the identifier to be searched
+ * @param string $type db/tbl/col or any combination of them
+ * representing what to be searched
*
* @return string alias of the identifier if found or ''
*/
- public function getAlias($aliases, $id)
+ public function getAlias($aliases, $id, $type = 'dbtblcol')
{
// search each database
foreach ($aliases as $db_key => $db) {
// check if id is database and has alias
- if ($db_key === $id && !empty($db['alias'])) {
+ if (stristr($type, 'db') !== false
+ && $db_key === $id && !empty($db['alias'])
+ ) {
return $db['alias'];
}
// search each of its tables
foreach ($db['tables'] as $table_key => $table) {
// check if id is table and has alias
- if ($table_key === $id && !empty($table['alias'])) {
+ if (stristr($type, 'tbl') !== false
+ && $table_key === $id && !empty($table['alias'])
+ ) {
return $table['alias'];
}
// search each of its columns
foreach ($table['columns'] as $col_key => $col) {
// check if id is column
- if ($col_key === $id) {
+ if (stristr($type, 'col') !== false
+ && $col_key === $id && !empty($col)
+ ) {
return $col;
}
}
diff --git a/libraries/sqlparser.data.php b/libraries/sqlparser.data.php
index c70849ebe3..c1379864d6 100644
--- a/libraries/sqlparser.data.php
+++ b/libraries/sqlparser.data.php
@@ -494,6 +494,7 @@ $PMA_SQPdata_reserved_word = array (
'INDEXES',
'INFILE',
'INNER',
+ 'INOUT',
'INSERT',
'INSERT_ID',
'INSERT_METHOD',
@@ -541,6 +542,7 @@ $PMA_SQPdata_reserved_word = array (
'MINUTE_SECOND',
'MIN_ROWS',
'MODE',
+ 'MODIFIES',
'MODIFY',
'MONTH',
'MRG_MYISAM',
@@ -559,6 +561,7 @@ $PMA_SQPdata_reserved_word = array (
'OPTIONALLY',
'OR',
'ORDER',
+ 'OUT',
'OUTER',
'OUTFILE',
'PACK_KEYS',
@@ -581,6 +584,7 @@ $PMA_SQPdata_reserved_word = array (
'RAID_TYPE',
'RANGE', // 5.1
'READ',
+ 'READS',
'READ_ONLY', // 5.1
'READ_WRITE', // 5.1
'REFERENCES',
diff --git a/test/libraries/PMA_display_export_test.php b/test/libraries/PMA_display_export_test.php
index 845efe211e..ed1eb0c9d1 100644
--- a/test/libraries/PMA_display_export_test.php
+++ b/test/libraries/PMA_display_export_test.php
@@ -143,6 +143,23 @@ class PMA_DisplayExport_Test extends PHPUnit_Framework_TestCase
$single_table = "single_table";
PMA_Table::$cache[$db][$table]['ENGINE'] = "MERGE";
+ $columns_info = array(
+ 'test_column1' => array(
+ 'COLUMN_NAME' => 'test_column1'
+ ),
+ 'test_column2' => array(
+ 'COLUMN_NAME' => 'test_column2'
+ )
+ );
+ $dbi = $this->getMockBuilder('PMA_DatabaseInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dbi->expects($this->any())->method('getColumnsFull')
+ ->will($this->returnValue($columns_info));
+
+ $GLOBALS['dbi'] = $dbi;
+
/* Scan for plugins */
$export_list = PMA_getPlugins(
"export",
@@ -217,7 +234,34 @@ class PMA_DisplayExport_Test extends PHPUnit_Framework_TestCase
$html
);
- //validate 5: PMA_getHtmlForExportOptionsOutput
+ //validate 5: PMA_getHtmlForAliasModalDialog
+ $this->assertContains(
+ '
',
+ $html
+ );
+ $this->assertContains(
+ 'Select database',
+ $html
+ );
+ $this->assertContains(
+ 'Select table',
+ $html
+ );
+ $this->assertContains(
+ 'New database name',
+ $html
+ );
+ $this->assertContains(
+ 'New table name',
+ $html
+ );
+ $this->assertContains(
+ 'test_column',
+ $html
+ );
+
+ //validate 6: PMA_getHtmlForExportOptionsOutput
$this->assertContains(
'
',
$html
@@ -227,7 +271,7 @@ class PMA_DisplayExport_Test extends PHPUnit_Framework_TestCase
$html
);
- //validate 6: PMA_getHtmlForExportOptionsFormat
+ //validate 7: PMA_getHtmlForExportOptionsFormat
$this->assertContains(
'