#3861 Errors while editing foreign constraints
This commit is contained in:
parent
8254d3eaf6
commit
aebceda7ac
222
tbl_relation.php
222
tbl_relation.php
@ -143,13 +143,14 @@ if (isset($destination) && $cfgRelation['relwork']) {
|
||||
// u p d a t e s f o r f o r e i g n k e y s
|
||||
// (for now, one index name only; we keep the definitions if the
|
||||
// foreign db is not the same)
|
||||
// I use $sql_query to be able to display directly the query via
|
||||
// getMessage()
|
||||
|
||||
if (isset($_REQUEST['destination_foreign'])) {
|
||||
$display_query = '';
|
||||
$seen_error = false;
|
||||
$shown_error = false;
|
||||
foreach ($_REQUEST['destination_foreign'] as $master_field_md5 => $foreign_string) {
|
||||
$create = false;
|
||||
$drop = false;
|
||||
|
||||
// Map the fieldname's md5 back to it's real name
|
||||
$master_field = $multi_edit_columns_name[$master_field_md5];
|
||||
@ -157,85 +158,66 @@ if (isset($_REQUEST['destination_foreign'])) {
|
||||
if (! empty($foreign_string)) {
|
||||
list($foreign_db, $foreign_table, $foreign_field)
|
||||
= PMA_backquoteSplit($foreign_string);
|
||||
|
||||
if ( isset($existrel_foreign[$master_field])
|
||||
&& ( PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']) != $foreign_db
|
||||
if (! isset($existrel_foreign[$master_field])) {
|
||||
// no key defined for this field
|
||||
$create = true;
|
||||
} elseif (PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']) != $foreign_db
|
||||
|| PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']) != $foreign_table
|
||||
|| PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']) != $foreign_field
|
||||
|| $_REQUEST['constraint_name'][$master_field_md5] != $existrel_foreign[$master_field]['constraint']
|
||||
|| ($_REQUEST['on_delete'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_delete']) ? $existrel_foreign[$master_field]['on_delete'] : 'RESTRICT'))
|
||||
|| ($_REQUEST['on_update'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : 'RESTRICT')))
|
||||
|| ($_REQUEST['on_update'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : 'RESTRICT'))
|
||||
) {
|
||||
// another foreign key is already defined for this field
|
||||
// or
|
||||
// an option has been changed for ON DELETE or ON UPDATE
|
||||
// remove existing key
|
||||
$sql_query_drop = 'ALTER TABLE ' . PMA_Util::backquote($table)
|
||||
. ' DROP FOREIGN KEY '
|
||||
. PMA_Util::backquote(
|
||||
$existrel_foreign[$master_field]['constraint']
|
||||
);
|
||||
$sql_query_drop .= ';';
|
||||
$display_query .= $sql_query_drop . "\n";
|
||||
} // end if...
|
||||
|
||||
// The next few lines are repeated below, so they
|
||||
// could be put in an include file
|
||||
// Note: I tried to enclose the db and table name with
|
||||
// backquotes but MySQL 4.0.16 did not like the syntax
|
||||
// (for example: `base2`.`table1`)
|
||||
$sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD ';
|
||||
// if user entered a constraint name
|
||||
if (! empty($_REQUEST['constraint_name'][$master_field_md5])) {
|
||||
$sql_query .= ' CONSTRAINT ' . PMA_Util::backquote(
|
||||
$_REQUEST['constraint_name'][$master_field_md5]
|
||||
);
|
||||
}
|
||||
$sql_query .= ' FOREIGN KEY ('
|
||||
. PMA_Util::backquote($master_field) . ')'
|
||||
. ' REFERENCES ' . $foreign_db . '.' . $foreign_table
|
||||
. '(' . $foreign_field . ')';
|
||||
if (! empty($_REQUEST['on_delete'][$master_field_md5])) {
|
||||
$sql_query .= ' ON DELETE '
|
||||
. $options_array[$_REQUEST['on_delete'][$master_field_md5]];
|
||||
}
|
||||
if (! empty($_REQUEST['on_update'][$master_field_md5])) {
|
||||
$sql_query .= ' ON UPDATE '
|
||||
. $options_array[$_REQUEST['on_update'][$master_field_md5]];
|
||||
}
|
||||
$sql_query .= ';';
|
||||
$display_query .= $sql_query . "\n";
|
||||
|
||||
// or an option has been changed for ON DELETE or ON UPDATE
|
||||
$drop = true;
|
||||
$create = true;
|
||||
} // end if... else....
|
||||
} elseif (isset($existrel_foreign[$master_field])) {
|
||||
$sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table)
|
||||
. ' DROP FOREIGN KEY '
|
||||
. PMA_Util::backquote(
|
||||
$existrel_foreign[$master_field]['constraint']
|
||||
);
|
||||
$sql_query .= ';';
|
||||
$display_query .= $sql_query . "\n";
|
||||
$drop = true;
|
||||
} // end if... else....
|
||||
|
||||
if (! empty($sql_query)) {
|
||||
if (! empty($sql_query_drop)) {
|
||||
PMA_DBI_try_query($sql_query_drop);
|
||||
$tmp_error_drop = PMA_DBI_getError();
|
||||
$tmp_error_drop = false;
|
||||
if ($drop) {
|
||||
$drop_query = PMA_getSQLToDropForeignKey(
|
||||
$table, $existrel_foreign[$master_field]['constraint']
|
||||
);
|
||||
$display_query .= $drop_query . "\n";
|
||||
PMA_DBI_try_query($drop_query);
|
||||
$tmp_error_drop = PMA_DBI_getError();
|
||||
|
||||
if (! empty($tmp_error_drop)) {
|
||||
$seen_error = true;
|
||||
continue;
|
||||
}
|
||||
PMA_DBI_try_query($sql_query);
|
||||
$tmp_error = PMA_DBI_getError();
|
||||
if (! empty($tmp_error)) {
|
||||
}
|
||||
$tmp_error_create = false;
|
||||
if ($create) {
|
||||
$create_query = PMA_getSQLToCreateForeignKey(
|
||||
$table, $master_field, $foreign_db, $foreign_table, $foreign_field,
|
||||
$_REQUEST['constraint_name'][$master_field_md5],
|
||||
$options_array[$_REQUEST['on_delete'][$master_field_md5]],
|
||||
$options_array[$_REQUEST['on_update'][$master_field_md5]]
|
||||
);
|
||||
|
||||
$display_query .= $create_query . "\n";
|
||||
PMA_DBI_try_query($create_query);
|
||||
$tmp_error_create = PMA_DBI_getError();
|
||||
if (! empty($tmp_error_create)) {
|
||||
$seen_error = true;
|
||||
}
|
||||
|
||||
if (substr($tmp_error, 1, 4) == '1216'
|
||||
|| substr($tmp_error, 1, 4) == '1452'
|
||||
if (substr($tmp_error_create, 1, 4) == '1216'
|
||||
|| substr($tmp_error_create, 1, 4) == '1452'
|
||||
) {
|
||||
PMA_Util::mysqlDie($tmp_error, $sql_query, false, '', false);
|
||||
PMA_Util::mysqlDie(
|
||||
$tmp_error_create, $create_query, false, '', false
|
||||
);
|
||||
$html_output .= PMA_Util::showMySQLDocu(
|
||||
'manual_Table_types', 'InnoDB_foreign_key_constraints'
|
||||
) . "\n";
|
||||
}
|
||||
if (substr($tmp_error, 1, 4) == '1005') {
|
||||
if (substr($tmp_error_create, 1, 4) == '1005') {
|
||||
$message = PMA_Message::error(
|
||||
__('Error creating foreign key on %1$s (check data types)')
|
||||
);
|
||||
@ -244,46 +226,34 @@ if (isset($_REQUEST['destination_foreign'])) {
|
||||
$html_output .= PMA_Util::showMySQLDocu(
|
||||
'manual_Table_types', 'InnoDB_foreign_key_constraints'
|
||||
) . "\n";
|
||||
$shown_error = true;
|
||||
}
|
||||
if (! empty($tmp_error) && empty($tmp_error_drop)) {
|
||||
// constraint might be dropped without creation of a new one
|
||||
// this is an alteration and the old constraint has been dropped
|
||||
// without creation of a new one
|
||||
if ($drop && $create && empty($tmp_error_drop)
|
||||
&& ! empty($tmp_error_create)
|
||||
) {
|
||||
// a rollback may be better here
|
||||
$sql_query_recreate = 'ALTER TABLE ' . PMA_Util::backquote($table)
|
||||
. ' ADD '
|
||||
. ' CONSTRAINT ' . PMA_Util::backquote(
|
||||
$existrel_foreign[$master_field]['constraint']
|
||||
)
|
||||
. ' FOREIGN KEY (' . PMA_Util::backquote($master_field) . ')'
|
||||
. ' REFERENCES ' . PMA_Util::backquote(
|
||||
$existrel_foreign[$master_field]['foreign_db']
|
||||
)
|
||||
. '.' . PMA_Util::backquote(
|
||||
$existrel_foreign[$master_field]['foreign_table']
|
||||
)
|
||||
. '(' . PMA_Util::backquote(
|
||||
$existrel_foreign[$master_field]['foreign_field']
|
||||
)
|
||||
. ')';
|
||||
if (! empty($existrel_foreign[$master_field]['on_delete'])) {
|
||||
$sql_query_recreate .= ' ON DELETE '
|
||||
. $existrel_foreign[$master_field]['on_delete'];
|
||||
}
|
||||
if (! empty($existrel_foreign[$master_field]['on_update'])) {
|
||||
$sql_query_recreate .= ' ON UPDATE '
|
||||
. $existrel_foreign[$master_field]['on_update'];
|
||||
}
|
||||
$sql_query_recreate .= ';';
|
||||
$sql_query_recreate = '# Restoring the dropped constraint...' . "\n";
|
||||
$sql_query_recreate .= PMA_getSQLToCreateForeignKey(
|
||||
$table, $master_field,
|
||||
PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']),
|
||||
PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']),
|
||||
PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']),
|
||||
$existrel_foreign[$master_field]['constraint'],
|
||||
$options_array[$existrel_foreign[$master_field]['on_delete']],
|
||||
$options_array[$existrel_foreign[$master_field]['on_update']]
|
||||
);
|
||||
$display_query .= $sql_query_recreate . "\n";
|
||||
PMA_DBI_try_query($sql_query_recreate);
|
||||
unset($sql_query_recreate);
|
||||
}
|
||||
unset($tmp_error);
|
||||
unset($tmp_error_drop);
|
||||
$sql_query = '';
|
||||
}
|
||||
} // end foreach
|
||||
if (!empty($display_query)) {
|
||||
if ($seen_error) {
|
||||
$html_output .= PMA_Util::getMessage(__('Error'), null, 'error');
|
||||
if (! $shown_error) {
|
||||
$html_output .= PMA_Util::getMessage(__('Error'), null, 'error');
|
||||
}
|
||||
} else {
|
||||
$html_output .= PMA_Util::getMessage(
|
||||
__('Your SQL query has been executed successfully'),
|
||||
@ -406,17 +376,17 @@ if ($cfgRelation['relwork']
|
||||
$columns = PMA_DBI_get_columns($db, $table);
|
||||
|
||||
if (count($columns) > 0) {
|
||||
|
||||
|
||||
foreach ($columns as $row) {
|
||||
$save_row[] = $row;
|
||||
}
|
||||
|
||||
|
||||
$saved_row_cnt = count($save_row);
|
||||
$html_output .= '<fieldset>'
|
||||
. '<legend>' . __('Relations'). '</legend>'
|
||||
. '<table>'
|
||||
. '<tr><th>' . __('Column') . '</th>';
|
||||
|
||||
|
||||
if ($cfgRelation['relwork']) {
|
||||
$html_output .= '<th>' . __('Internal relation');
|
||||
if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
|
||||
@ -429,7 +399,7 @@ if (count($columns) > 0) {
|
||||
}
|
||||
$html_output .= '</th>';
|
||||
}
|
||||
|
||||
|
||||
if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
|
||||
// this does not have to be translated, it's part of the MySQL syntax
|
||||
$html_output .= '<th colspan="2">' . __('Foreign key constraint')
|
||||
@ -638,7 +608,7 @@ function PMA_generateDropdown(
|
||||
$html_output .= '>' . htmlspecialchars($one_label) . '</option>' . "\n";
|
||||
}
|
||||
$html_output .= '</select>' . "\n";
|
||||
|
||||
|
||||
return $html_output;
|
||||
}
|
||||
|
||||
@ -674,4 +644,56 @@ function PMA_backquoteSplit($text)
|
||||
}
|
||||
return($elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DROP query for a foreign key constraint
|
||||
*
|
||||
* @param string $table table of the foreign key
|
||||
* @param string $fk foreign key name
|
||||
*
|
||||
* @return string DROP query for the foreign key constraint
|
||||
*/
|
||||
function PMA_getSQLToDropForeignKey($table, $fk)
|
||||
{
|
||||
return 'ALTER TABLE ' . PMA_Util::backquote($table)
|
||||
. ' DROP FOREIGN KEY ' . PMA_Util::backquote($fk) . ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SQL query for foreign key constraint creation
|
||||
*
|
||||
* @param string $table table name
|
||||
* @param string $field field name
|
||||
* @param string $foreignDb back-quoted foreign database name
|
||||
* @param string $foreignTable back-quoted foreign table name
|
||||
* @param string $foreignField back-quoted foreign field name
|
||||
* @param string $name name of the constraint
|
||||
* @param string $onDelete on delete action
|
||||
* @param string $onUpdate on update action
|
||||
*
|
||||
* @return string SQL query for foreign key constraint creation
|
||||
*/
|
||||
function PMA_getSQLToCreateForeignKey($table, $field, $foreignDb, $foreignTable,
|
||||
$foreignField, $name = null, $onDelete = null, $onUpdate = null
|
||||
) {
|
||||
$sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD ';
|
||||
// if user entered a constraint name
|
||||
if (! empty($name)) {
|
||||
$sql_query .= ' CONSTRAINT ' . PMA_Util::backquote($name);
|
||||
}
|
||||
|
||||
$sql_query .= ' FOREIGN KEY (' . PMA_Util::backquote($field) . ')'
|
||||
. ' REFERENCES ' . $foreignDb . '.' . $foreignTable
|
||||
. '(' . $foreignField . ')';
|
||||
|
||||
if (! empty($onDelete)) {
|
||||
$sql_query .= ' ON DELETE ' . $onDelete;
|
||||
}
|
||||
if (! empty($onUpdate)) {
|
||||
$sql_query .= ' ON UPDATE ' . $onUpdate;
|
||||
}
|
||||
$sql_query .= ';';
|
||||
|
||||
return $sql_query;
|
||||
}
|
||||
?>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user