diff options
author | heikki@hundin.mysql.fi <> | 2002-12-22 01:54:29 +0200 |
---|---|---|
committer | heikki@hundin.mysql.fi <> | 2002-12-22 01:54:29 +0200 |
commit | 843e1d8e9c6bff2b25a2ac8c367f9d7fcbc528cc (patch) | |
tree | 120402316f5b15cb879b72bdb1c4cf59c8d932cb /innobase/dict | |
parent | f03bbd3fe28455885603890a21eebfe2792f2704 (diff) | |
download | mariadb-git-843e1d8e9c6bff2b25a2ac8c367f9d7fcbc528cc.tar.gz |
Many files:
Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE
sql_select.cc:
Remove superfluous prints to .err log when a locking SELECT fails to a deadlock or a lock wait timeout
Diffstat (limited to 'innobase/dict')
-rw-r--r-- | innobase/dict/dict0dict.c | 136 |
1 files changed, 109 insertions, 27 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 563ca2521a4..c70e848c5c8 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1145,23 +1145,25 @@ dict_index_add_to_cache( } /* Check that the same column does not appear twice in the index. - InnoDB assumes this in its algorithms, e.g., update of an index - entry */ + InnoDB assumes this in its algorithms, e.g., update of an index + entry */ for (i = 0; i < dict_index_get_n_fields(index); i++) { - for (j = 0; j < i; j++) { - if (dict_index_get_nth_field(index, j)->col - == dict_index_get_nth_field(index, i)->col) { + for (j = 0; j < i; j++) { + if (dict_index_get_nth_field(index, j)->col + == dict_index_get_nth_field(index, i)->col) { - fprintf(stderr, -"InnoDB: Error: column %s appears twice in index %s of table %s\n" + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error: column %s appears twice in index %s of table %s\n" "InnoDB: This is not allowed in InnoDB.\n" "InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n", - dict_index_get_nth_field(index, i)->col->name, - index->name, table->name); - } - } + dict_index_get_nth_field(index, i)->col->name, + index->name, table->name); + } + } } /* Build the cache internal representation of the index, @@ -2233,6 +2235,9 @@ dict_create_foreign_constraints( ulint error; ulint i; ulint j; + ibool is_on_delete; + ulint n_on_deletes; + ulint n_on_updates; dict_col_t* columns[500]; char* column_names[500]; ulint column_name_lens[500]; @@ -2392,6 +2397,12 @@ col_loop2: return(DB_CANNOT_ADD_CONSTRAINT); } + n_on_deletes = 0; + n_on_updates = 0; + +scan_on_conditions: + /* Loop here as long as we can find ON ... conditions */ + ptr = dict_accept(ptr, "ON", &success); if (!success) { @@ -2402,23 +2413,58 @@ col_loop2: ptr = dict_accept(ptr, "DELETE", &success); if (!success) { - dict_foreign_free(foreign); + ptr = dict_accept(ptr, "UPDATE", &success); + + if (!success) { + + dict_foreign_free(foreign); - return(DB_CANNOT_ADD_CONSTRAINT); + return(DB_CANNOT_ADD_CONSTRAINT); + } + + is_on_delete = FALSE; + n_on_updates++; + } else { + is_on_delete = TRUE; + n_on_deletes++; } ptr = dict_accept(ptr, "RESTRICT", &success); if (success) { - goto try_find_index; + goto scan_on_conditions; } ptr = dict_accept(ptr, "CASCADE", &success); if (success) { - foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE; + if (is_on_delete) { + foreign->type |= DICT_FOREIGN_ON_DELETE_CASCADE; + } else { + foreign->type |= DICT_FOREIGN_ON_UPDATE_CASCADE; + } - goto try_find_index; + goto scan_on_conditions; + } + + ptr = dict_accept(ptr, "NO", &success); + + if (success) { + ptr = dict_accept(ptr, "ACTION", &success); + + if (!success) { + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); + } + + if (is_on_delete) { + foreign->type |= DICT_FOREIGN_ON_DELETE_NO_ACTION; + } else { + foreign->type |= DICT_FOREIGN_ON_UPDATE_NO_ACTION; + } + + goto scan_on_conditions; } ptr = dict_accept(ptr, "SET", &success); @@ -2451,20 +2497,23 @@ col_loop2: } } - foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL; + if (is_on_delete) { + foreign->type |= DICT_FOREIGN_ON_DELETE_SET_NULL; + } else { + foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL; + } -try_find_index: - /* We check that there are no superfluous words like 'ON UPDATE ...' - which we do not support yet. */ - - ptr = dict_accept(ptr, (char *) "ON", &success); + goto scan_on_conditions; - if (success) { +try_find_index: + if (n_on_deletes > 1 || n_on_updates > 1) { + /* It is an error to define more than 1 action */ + dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); } - + /* Try to find an index which contains the columns as the first fields and in the right order, and the types are the same as in foreign->foreign_index */ @@ -3286,7 +3335,8 @@ dict_print_info_on_foreign_keys_in_create_format( /*=============================================*/ char* buf, /* in: auxiliary buffer */ char* str, /* in/out: pointer to a string */ - ulint len, /* in: space in str available for info */ + ulint len, /* in: str has to be a buffer at least + len + 5000 bytes */ dict_table_t* table) /* in: table */ { @@ -3356,14 +3406,30 @@ dict_print_info_on_foreign_keys_in_create_format( buf2 += sprintf(buf2, ")"); - if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { + if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) { buf2 += sprintf(buf2, " ON DELETE CASCADE"); } - if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { + if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) { buf2 += sprintf(buf2, " ON DELETE SET NULL"); } + if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + buf2 += sprintf(buf2, " ON DELETE NO ACTION"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { + buf2 += sprintf(buf2, " ON UPDATE CASCADE"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { + buf2 += sprintf(buf2, " ON UPDATE SET NULL"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + buf2 += sprintf(buf2, " ON UPDATE NO ACTION"); + } + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } no_space: @@ -3455,6 +3521,22 @@ dict_print_info_on_foreign_keys( buf2 += sprintf(buf2, " ON DELETE SET NULL"); } + if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + buf2 += sprintf(buf2, " ON DELETE NO ACTION"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { + buf2 += sprintf(buf2, " ON UPDATE CASCADE"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { + buf2 += sprintf(buf2, " ON UPDATE SET NULL"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + buf2 += sprintf(buf2, " ON UPDATE NO ACTION"); + } + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } no_space: |