diff options
author | unknown <heikki@hundin.mysql.fi> | 2002-11-06 00:41:27 +0200 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2002-11-06 00:41:27 +0200 |
commit | 444d8207d9a277231733dc6cd58bf21b626bba31 (patch) | |
tree | fed8334ab45443418d527c3837593e1121ed1975 /innobase/dict | |
parent | 23f4865b163293006bbedbc2b69bc55ba1081baa (diff) | |
download | mariadb-git-444d8207d9a277231733dc6cd58bf21b626bba31.tar.gz |
Many files:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
sql/ha_innodb.cc:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/dict/dict0crea.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/dict/dict0dict.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/log0recv.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/row0mysql.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/srv0srv.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/trx0trx.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/log/log0recv.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/os/os0sync.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/os/os0thread.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0ins.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0mysql.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0purge.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0undo.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0upd.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/srv/srv0srv.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/srv/srv0start.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/trx/trx0roll.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/trx/trx0trx.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
Diffstat (limited to 'innobase/dict')
-rw-r--r-- | innobase/dict/dict0crea.c | 18 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 219 |
2 files changed, 199 insertions, 38 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 60beeacf435..b0f84e5663a 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -1041,7 +1041,7 @@ dict_create_or_check_foreign_constraint_tables(void) que_t* graph; ulint error; trx_t* trx; - char* str; + char* str; mutex_enter(&(dict_sys->mutex)); @@ -1060,20 +1060,24 @@ dict_create_or_check_foreign_constraint_tables(void) return(DB_SUCCESS); } + mutex_exit(&(dict_sys->mutex)); + trx = trx_allocate_for_mysql(); trx->op_info = (char *) "creating foreign key sys tables"; + row_mysql_lock_data_dictionary(trx); + if (table1) { fprintf(stderr, "InnoDB: dropping incompletely created SYS_FOREIGN table\n"); - row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx); } if (table2) { fprintf(stderr, "InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n"); - row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS",trx,TRUE); + row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx); } fprintf(stderr, @@ -1122,8 +1126,8 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: dropping incompletely created SYS_FOREIGN tables\n"); - row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS",trx,TRUE); + row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx); + row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx); error = DB_MUST_GET_MORE_FILE_SPACE; } @@ -1132,6 +1136,8 @@ dict_create_or_check_foreign_constraint_tables(void) trx->op_info = (char *) ""; + row_mysql_unlock_data_dictionary(trx); + trx_free_for_mysql(trx); if (error == DB_SUCCESS) { @@ -1139,8 +1145,6 @@ dict_create_or_check_foreign_constraint_tables(void) "InnoDB: Foreign key constraint system tables created\n"); } - mutex_exit(&(dict_sys->mutex)); - return(error); } diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 2ee2c9d18a9..18f27602cf0 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -30,13 +30,16 @@ Created 1/8/1996 Heikki Tuuri dict_sys_t* dict_sys = NULL; /* the dictionary system */ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve - this in X-mode, implicit or backround + this in X-mode; implicit or backround operations purge, rollback, foreign key checks reserve this in S-mode; we cannot trust that MySQL protects implicit or background operations - from dropping a table: this is our - mechanism */ + a table drop since MySQL does not + know of them; therefore we need this; + NOTE: a transaction which reserves + this must keep book on the mode in + trx->dict_operation_lock_mode */ #define DICT_HEAP_SIZE 100 /* initial memory heap size when creating a table or index object */ @@ -183,6 +186,58 @@ dict_foreign_free( dict_foreign_t* foreign); /* in, own: foreign key struct */ /************************************************************************ +Checks if the database name in two table names is the same. */ +static +ibool +dict_tables_have_same_db( +/*=====================*/ + /* out: TRUE if same db name */ + char* name1, /* in: table name in the form dbname '/' tablename */ + char* name2) /* in: table name in the form dbname '/' tablename */ +{ + ulint i; + + for (i = 0; i < 100000; i++) { + if (name1[i] == '/' && name2[i] == '/') { + + return(TRUE); + } + + if (name1[i] != name2[i]) { + + return(FALSE); + } + } + + ut_a(0); + + return(FALSE); +} + +/************************************************************************ +Return the end of table name where we have removed dbname and '/'. */ +static +char* +dict_remove_db_name( +/*================*/ + /* out: table name */ + char* name) /* in: table name in the form dbname '/' tablename */ +{ + ulint i; + + for (i = 0; i < 100000 ; i++) { + if (name[i] == '/') { + + return(name + i + 1); + } + } + + ut_a(0); + + return(NULL); +} + +/************************************************************************ Reserves the dictionary system mutex for MySQL. */ void @@ -1926,7 +1981,8 @@ dict_scan_col( old_ptr = ptr; - while (!isspace(*ptr) && *ptr != ',' && *ptr != ')' && *ptr != '`') { + while (!isspace(*ptr) && *ptr != ',' && *ptr != ')' && *ptr != '`' + && *ptr != '\0') { ptr++; } @@ -2000,7 +2056,7 @@ dict_scan_table_name( old_ptr = ptr; - while (!isspace(*ptr) && *ptr != '(' && *ptr != '`') { + while (!isspace(*ptr) && *ptr != '(' && *ptr != '`' && *ptr != '\0') { if (*ptr == '.') { dot_ptr = ptr; } @@ -2023,17 +2079,28 @@ dict_scan_table_name( } #ifdef __WIN__ ut_cpy_in_lower_case(second_table_name + i, old_ptr, - ptr - old_ptr); + ptr - old_ptr); #else - ut_memcpy(second_table_name + i, old_ptr, ptr - old_ptr); + if (srv_lower_case_table_names) { + ut_cpy_in_lower_case(second_table_name + i, old_ptr, + ptr - old_ptr); + } else { + ut_memcpy(second_table_name + i, old_ptr, + ptr - old_ptr); + } #endif second_table_name[i + (ptr - old_ptr)] = '\0'; } else { #ifdef __WIN__ ut_cpy_in_lower_case(second_table_name, old_ptr, - ptr - old_ptr); + ptr - old_ptr); #else - ut_memcpy(second_table_name, old_ptr, ptr - old_ptr); + if (srv_lower_case_table_names) { + ut_cpy_in_lower_case(second_table_name, old_ptr, + ptr - old_ptr); + } else { + ut_memcpy(second_table_name, old_ptr, ptr - old_ptr); + } #endif second_table_name[dot_ptr - old_ptr] = '/'; second_table_name[ptr - old_ptr] = '\0'; @@ -2051,6 +2118,44 @@ dict_scan_table_name( } /************************************************************************* +Skips one 'word', like an id. For the lexical definition of 'word', see the +code below. */ +static +char* +dict_skip_word( +/*===========*/ + /* out: scanned to */ + char* ptr, /* in: scanned to */ + ibool* success)/* out: TRUE if success, FALSE if just spaces left in + string */ +{ + *success = FALSE; + + while (isspace(*ptr)) { + ptr++; + } + + if (*ptr == '\0') { + + return(ptr); + } + + if (*ptr == '`') { + ptr++; + } + + while (!isspace(*ptr) && *ptr != ',' && *ptr != '(' && *ptr != '`' + && *ptr != '\0') { + + ptr++; + } + + *success = TRUE; + + return(ptr); +} + +/************************************************************************* Returns the number of opening brackets '(' subtracted by the number of closing brackets ')' between string and ptr. */ static @@ -2119,7 +2224,6 @@ dict_create_foreign_constraints( if (table == NULL) { return(DB_ERROR); } - loop: ptr = dict_scan_to(ptr, (char *) "FOREIGN"); @@ -2148,7 +2252,19 @@ loop: ptr = dict_accept(ptr, (char *) "(", &success); if (!success) { - goto loop; + /* MySQL allows also an index id before the '('; we + skip it */ + ptr = dict_skip_word(ptr, &success); + + if (!success) { + return(DB_CANNOT_ADD_CONSTRAINT); + } + + ptr = dict_accept(ptr, (char *) "(", &success); + + if (!success) { + return(DB_CANNOT_ADD_CONSTRAINT); + } } i = 0; @@ -2223,6 +2339,7 @@ col_loop1: if (!success) { dict_foreign_free(foreign); + return(DB_CANNOT_ADD_CONSTRAINT); } @@ -2236,6 +2353,7 @@ col_loop2: if (!success) { dict_foreign_free(foreign); + return(DB_CANNOT_ADD_CONSTRAINT); } @@ -2263,14 +2381,20 @@ col_loop2: ptr = dict_accept(ptr, "DELETE", &success); if (!success) { + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); + } + + ptr = dict_accept(ptr, "RESTRICT", &success); + if (success) { goto try_find_index; } ptr = dict_accept(ptr, "CASCADE", &success); if (success) { - foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE; goto try_find_index; @@ -2279,32 +2403,47 @@ col_loop2: ptr = dict_accept(ptr, "SET", &success); if (!success) { - - goto try_find_index; + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); } ptr = dict_accept(ptr, "NULL", &success); - if (success) { - for (j = 0; j < foreign->n_fields; j++) { - if ((dict_index_get_nth_type( + if (!success) { + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); + } + + for (j = 0; j < foreign->n_fields; j++) { + if ((dict_index_get_nth_type( foreign->foreign_index, j)->prtype) & DATA_NOT_NULL) { - /* It is not sensible to define SET NULL - if the column is not allowed to be NULL! */ + /* It is not sensible to define SET NULL + if the column is not allowed to be NULL! */ - dict_foreign_free(foreign); - return(DB_CANNOT_ADD_CONSTRAINT); - } + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); } + } - foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL; + foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL; + +try_find_index: + /* We check that there are no superfluous words like 'ON UPDATE ...' + which we do not support yet. */ - goto try_find_index; + ptr = dict_accept(ptr, (char *) "ON", &success); + + if (success) { + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); } -try_find_index: /* 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 */ @@ -2351,6 +2490,7 @@ try_find_index: referenced_table->referenced_list, foreign); } + goto loop; } @@ -2849,6 +2989,14 @@ dict_update_statistics_low( ulint size; ulint sum_of_index_sizes = 0; + /* If we have set a high innodb_force_recovery level, do not calculate + statistics, as a badly corrupted index can cause a crash in it. */ + + if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + + return; + } + /* Find out the sizes of the indexes and how many different values for the key they approximately have */ @@ -3152,16 +3300,25 @@ dict_print_info_on_foreign_keys_in_create_format( } } - buf2 += sprintf(buf2, ") REFERENCES `%s` (", + if (dict_tables_have_same_db(table->name, + foreign->referenced_table_name)) { + /* Do not print the database name of the referenced + table */ + buf2 += sprintf(buf2, ") REFERENCES `%s` (", + dict_remove_db_name( + foreign->referenced_table_name)); + } else { + buf2 += sprintf(buf2, ") REFERENCES `%s` (", foreign->referenced_table_name); - /* Change the '/' in the table name to '.' */ + /* Change the '/' in the table name to '.' */ - for (i = ut_strlen(buf); i > 0; i--) { - if (buf[i] == '/') { + for (i = ut_strlen(buf); i > 0; i--) { + if (buf[i] == '/') { - buf[i] = '.'; + buf[i] = '.'; - break; + break; + } } } |