Commit 7b2e60e1 authored by marko's avatar marko

Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns for which

there is a foreign key constraint ON ... SET NULL.  (Bug #25927)

dict_foreign_find_index(): Add paramettter check_null.

dict_foreign_add_to_cache(): Do not allow ON DELETE SET NULL
or ON UPDATE SET NULL if any of the referencing columns are declared NOT NULL.
parent a364d4bc
...@@ -1970,9 +1970,12 @@ dict_foreign_find_index( ...@@ -1970,9 +1970,12 @@ dict_foreign_find_index(
ulint n_cols, /* in: number of columns */ ulint n_cols, /* in: number of columns */
dict_index_t* types_idx, /* in: NULL or an index to whose types the dict_index_t* types_idx, /* in: NULL or an index to whose types the
column types must match */ column types must match */
ibool check_charsets) ibool check_charsets,
/* in: whether to check charsets. /* in: whether to check charsets.
only has an effect if types_idx != NULL */ only has an effect if types_idx != NULL */
ulint check_null)
/* in: nonzero if none of the columns must
be declared NOT NULL */
{ {
dict_index_t* index; dict_index_t* index;
dict_field_t* field; dict_field_t* field;
...@@ -2002,6 +2005,12 @@ dict_foreign_find_index( ...@@ -2002,6 +2005,12 @@ dict_foreign_find_index(
break; break;
} }
if (check_null
&& (field->col->prtype & DATA_NOT_NULL)) {
return(NULL);
}
if (types_idx && !cmp_cols_are_equal( if (types_idx && !cmp_cols_are_equal(
dict_index_get_nth_col(index, i), dict_index_get_nth_col(index, i),
dict_index_get_nth_col(types_idx, dict_index_get_nth_col(types_idx,
...@@ -2118,7 +2127,7 @@ dict_foreign_add_to_cache( ...@@ -2118,7 +2127,7 @@ dict_foreign_add_to_cache(
ref_table, ref_table,
(const char**) for_in_cache->referenced_col_names, (const char**) for_in_cache->referenced_col_names,
for_in_cache->n_fields, for_in_cache->foreign_index, for_in_cache->n_fields, for_in_cache->foreign_index,
check_charsets); check_charsets, FALSE);
if (index == NULL) { if (index == NULL) {
dict_foreign_error_report( dict_foreign_error_report(
...@@ -2150,7 +2159,10 @@ dict_foreign_add_to_cache( ...@@ -2150,7 +2159,10 @@ dict_foreign_add_to_cache(
for_table, for_table,
(const char**) for_in_cache->foreign_col_names, (const char**) for_in_cache->foreign_col_names,
for_in_cache->n_fields, for_in_cache->n_fields,
for_in_cache->referenced_index, check_charsets); for_in_cache->referenced_index, check_charsets,
for_in_cache->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
if (index == NULL) { if (index == NULL) {
dict_foreign_error_report( dict_foreign_error_report(
...@@ -2160,7 +2172,9 @@ dict_foreign_add_to_cache( ...@@ -2160,7 +2172,9 @@ dict_foreign_add_to_cache(
"the columns as the first columns," "the columns as the first columns,"
" or the data types in the\n" " or the data types in the\n"
"table do not match" "table do not match"
" the ones in the referenced table."); " the ones in the referenced table\n"
"or one of the ON ... SET NULL columns"
" is declared NOT NULL.");
if (for_in_cache == foreign) { if (for_in_cache == foreign) {
if (added_to_referenced_list) { if (added_to_referenced_list) {
...@@ -2966,7 +2980,8 @@ dict_create_foreign_constraints_low( ...@@ -2966,7 +2980,8 @@ dict_create_foreign_constraints_low(
/* Try to find an index which contains the columns /* Try to find an index which contains the columns
as the first fields and in the right order */ as the first fields and in the right order */
index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); index = dict_foreign_find_index(table, column_names, i,
NULL, TRUE, FALSE);
if (!index) { if (!index) {
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
...@@ -3237,7 +3252,8 @@ dict_create_foreign_constraints_low( ...@@ -3237,7 +3252,8 @@ dict_create_foreign_constraints_low(
if (referenced_table) { if (referenced_table) {
index = dict_foreign_find_index(referenced_table, index = dict_foreign_find_index(referenced_table,
column_names, i, column_names, i,
foreign->foreign_index, TRUE); foreign->foreign_index,
TRUE, FALSE);
if (!index) { if (!index) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment