diff options
author | unknown <monty@mysql.com> | 2004-11-09 04:06:44 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-11-09 04:06:44 +0200 |
commit | e0bf844c8ac4cd1efc9547637baac5201775a1c7 (patch) | |
tree | a936b651bfe5aa74bd01c17224531d16117c29d9 /innobase | |
parent | 20c82f5c014e9902f234f925a218895f3b91b154 (diff) | |
parent | db67626196992923be83c12302d03cad35cf80f9 (diff) | |
download | mariadb-git-e0bf844c8ac4cd1efc9547637baac5201775a1c7.tar.gz |
merge on pull
BitKeeper/etc/logging_ok:
auto-union
BitKeeper/deleted/.del-Makefile.am:
Delete: Docs/Images/Makefile.am
configure.in:
Auto merged
innobase/include/row0mysql.h:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
innobase/row/row0mysql.c:
Auto merged
mysql-test/r/ps.result:
Auto merged
mysql-test/t/ps.test:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/item.cc:
Auto merged
sql/item.h:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/table.cc:
Auto merged
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/dict/dict0crea.c | 16 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 4 | ||||
-rw-r--r-- | innobase/dict/dict0load.c | 35 | ||||
-rw-r--r-- | innobase/eval/eval0eval.c | 18 | ||||
-rw-r--r-- | innobase/ibuf/ibuf0ibuf.c | 6 | ||||
-rw-r--r-- | innobase/include/lock0lock.h | 8 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 6 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 13 | ||||
-rw-r--r-- | innobase/pars/pars0pars.c | 8 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 29 |
10 files changed, 124 insertions, 19 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 137964b26c1..cbdc0aab53c 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -1067,6 +1067,12 @@ dict_create_or_check_foreign_constraint_tables(void) there are 2 secondary indexes on SYS_FOREIGN, and they are defined just like below */ + /* NOTE: when designing InnoDB's foreign key support in 2001, we made + an error and made the table names and the foreign key id of type + 'CHAR' (internally, really a VARCHAR). We should have made the type + VARBINARY, like in other InnoDB system tables, to get a clean + design. */ + str = "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n" "BEGIN\n" @@ -1284,9 +1290,17 @@ loop: fputs(".\nA foreign key constraint of name ", ef); ut_print_name(ef, trx, foreign->id); fputs("\nalready exists." - " (Note that internally InnoDB adds 'databasename/'\n" + " (Note that internally InnoDB adds 'databasename/'\n" "in front of the user-defined constraint name).\n", ef); + fputs("Note that InnoDB's FOREIGN KEY system tables store\n" + "constraint names as case-insensitive, with the\n" + "MySQL standard latin1_swedish_ci collation. If you\n" + "create tables or databases whose names differ only in\n" + "the character case, then collisions in constraint\n" + "names can occur. Workaround: name your constraints\n" + "explicitly with unique names.\n", + ef); mutex_exit(&dict_foreign_err_mutex); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index c3d0d8d9ac1..bc08fc2437e 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -156,7 +156,7 @@ dict_index_build_internal_non_clust( dict_index_t* index); /* in: user representation of a non-clustered index */ /************************************************************************** -Removes a foreign constraint struct from the dictionet cache. */ +Removes a foreign constraint struct from the dictionary cache. */ static void dict_foreign_remove_from_cache( @@ -606,7 +606,7 @@ dict_table_get_on_id( dict_table_t* table; if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 - || trx->dict_operation) { + || trx->dict_operation_lock_mode == RW_X_LATCH) { /* It is a system table which will always exist in the table cache: we avoid acquiring the dictionary mutex, because if we are doing a rollback to handle an error in TABLE diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index d430eadc97b..8fc6eb9141e 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -19,7 +19,9 @@ Created 4/24/1996 Heikki Tuuri #include "mach0data.h" #include "dict0dict.h" #include "dict0boot.h" +#include "rem0cmp.h" #include "srv0start.h" +#include "srv0srv.h" /************************************************************************ Finds the first table name in the given database. */ @@ -123,6 +125,13 @@ dict_print(void) ulint len; mtr_t mtr; + /* Enlarge the fatal semaphore wait timeout during the InnoDB table + monitor printout */ + + mutex_enter(&kernel_mutex); + srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */ + mutex_exit(&kernel_mutex); + mutex_enter(&(dict_sys->mutex)); mtr_start(&mtr); @@ -145,6 +154,12 @@ loop: mutex_exit(&(dict_sys->mutex)); + /* Restore the fatal semaphore wait timeout */ + + mutex_enter(&kernel_mutex); + srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */ + mutex_exit(&kernel_mutex); + return; } @@ -1242,12 +1257,26 @@ loop: rec = btr_pcur_get_rec(&pcur); field = rec_get_nth_field(rec, 0, &len); - /* Check if the table name in record is the one searched for */ - if (len != ut_strlen(table_name) - || 0 != ut_memcmp(field, table_name, len)) { + /* Check if the table name in the record is the one searched for; the + following call does the comparison in the latin1_swedish_ci + charset-collation, in a case-insensitive way. */ + if (0 != cmp_data_data(dfield_get_type(dfield), + dfield_get_data(dfield), dfield_get_len(dfield), + field, len)) { + goto load_next_index; } + + /* Since table names in SYS_FOREIGN are stored in a case-insensitive + order, we have to check that the table name matches also in a binary + string comparison. On Unix, MySQL allows table names that only differ + in character case. */ + + if (0 != ut_memcmp(field, table_name, len)) { + + goto next_rec; + } if (rec_get_deleted_flag(rec)) { diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c index ebb6cb1b7d9..5b2d1f857b1 100644 --- a/innobase/eval/eval0eval.c +++ b/innobase/eval/eval0eval.c @@ -627,7 +627,11 @@ eval_concat( } /********************************************************************* -Evaluates a predefined function node. */ +Evaluates a predefined function node. If the first argument is an integer, +this function looks at the second argument which is the integer length in +bytes, and converts the integer to a VARCHAR. +If the first argument is of some other type, this function converts it to +BINARY. */ UNIV_INLINE void eval_to_binary( @@ -638,12 +642,24 @@ eval_to_binary( que_node_t* arg2; dfield_t* dfield; byte* str1; + ulint len; ulint len1; arg1 = func_node->args; str1 = dfield_get_data(que_node_get_val(arg1)); + if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) { + + len = dfield_get_len(que_node_get_val(arg1)); + + dfield = que_node_get_val(func_node); + + dfield_set_data(dfield, str1, len); + + return; + } + arg2 = que_node_get_next(arg1); len1 = (ulint)eval_node_get_int_val(arg2); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index b3c8ade2414..2191cdc0ee6 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -2866,6 +2866,8 @@ ibuf_delete_rec( #ifdef UNIV_IBUF_DEBUG ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1); +#else + UT_NOT_USED(space); #endif ibuf_data_sizes_update(ibuf_data, root, mtr); @@ -3267,11 +3269,11 @@ leave_loop: ibuf_data->n_merged_recs += n_inserts; mutex_exit(&ibuf_mutex); - + /* fprintf(stderr, "InnoDB: Discarded %lu ibuf entries for space %lu\n", (ulong) n_inserts, (ulong) space); - + */ ibuf_exit(); mem_heap_free(heap); diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 9f525042dcc..f8435e14d97 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -463,6 +463,14 @@ lock_rec_hash( ulint space, /* in: space */ ulint page_no);/* in: page number */ /************************************************************************* +Gets the table covered by an IX table lock. */ + +dict_table_t* +lock_get_ix_table( +/*==============*/ + /* out: the table covered by the lock */ + lock_t* lock); /* in: table lock */ +/************************************************************************* Checks that a transaction id is sensible, i.e., not in the future. */ ibool diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 581f1bcade3..d4634482752 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -175,8 +175,12 @@ int row_lock_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ - row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL + row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL table handle */ + dict_table_t* table); /* in: table to LOCK_IX, or NULL + if prebuilt->table should be + locked as LOCK_TABLE_EXP | + prebuilt->select_lock_type */ /************************************************************************* Does an insert for MySQL. */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 44eee53212a..98def88fa31 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -395,6 +395,19 @@ lock_rec_get_nth_bit( return(ut_bit_get_nth(b, bit_index)); } +/************************************************************************* +Gets the table covered by an IX table lock. */ + +dict_table_t* +lock_get_ix_table( +/*==============*/ + /* out: the table covered by the lock */ + lock_t* lock) /* in: table lock */ +{ + ut_a(lock->type_mode == (LOCK_TABLE | LOCK_IX)); + return(lock->un_member.tab_lock.table); +} + /*************************************************************************/ #define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex) diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index 846cb060a7e..16d630dd318 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -259,9 +259,13 @@ pars_resolve_func_data_type( dtype_set(que_node_get_data_type(node), DATA_VARCHAR, DATA_ENGLISH, 0, 0); } else if (func == PARS_TO_BINARY_TOKEN) { - ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT); - dtype_set(que_node_get_data_type(node), DATA_VARCHAR, + if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) { + dtype_set(que_node_get_data_type(node), DATA_VARCHAR, DATA_ENGLISH, 0, 0); + } else { + dtype_set(que_node_get_data_type(node), DATA_BINARY, + 0, 0, 0); + } } else if (func == PARS_TO_NUMBER_TOKEN) { ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_VARCHAR); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 9ca0b7306fc..6ac8c943dc6 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -779,8 +779,12 @@ int row_lock_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ - row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL + row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL table handle */ + dict_table_t* table) /* in: table to LOCK_IX, or NULL + if prebuilt->table should be + locked as LOCK_TABLE_EXP | + prebuilt->select_lock_type */ { trx_t* trx = prebuilt->trx; que_thr_t* thr; @@ -813,8 +817,12 @@ run_again: trx_start_if_not_started(trx); - err = lock_table(LOCK_TABLE_EXP, prebuilt->table, - prebuilt->select_lock_type, thr); + if (table) { + err = lock_table(0, table, LOCK_IX, thr); + } else { + err = lock_table(LOCK_TABLE_EXP, prebuilt->table, + prebuilt->select_lock_type, thr); + } trx->error_state = err; @@ -2365,7 +2373,8 @@ row_drop_table_for_mysql( "WHILE found = 1 LOOP\n" " SELECT ID INTO foreign_id\n" " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = table_name;\n" + " WHERE FOR_NAME = table_name\n" + " AND TO_BINARY(FOR_NAME) = TO_BINARY(table_name);\n" " IF (SQL % NOTFOUND) THEN\n" " found := 0;\n" " ELSE" @@ -2820,7 +2829,8 @@ row_rename_table_for_mysql( "WHILE found = 1 LOOP\n" " SELECT ID INTO foreign_id\n" " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = old_table_name;\n" + " WHERE FOR_NAME = old_table_name\n" + " AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);\n" " IF (SQL % NOTFOUND) THEN\n" " found := 0;\n" " ELSE\n" @@ -2853,7 +2863,8 @@ row_rename_table_for_mysql( " END IF;\n" "END LOOP;\n" "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" - "WHERE REF_NAME = old_table_name;\n"; + "WHERE REF_NAME = old_table_name\n" + " AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);\n"; static const char str5[] = "END;\n"; @@ -3063,7 +3074,11 @@ row_rename_table_for_mysql( if (err != DB_SUCCESS) { if (err == DB_DUPLICATE_KEY) { ut_print_timestamp(stderr); - fputs(" InnoDB: Error: table ", stderr); + fputs( + " InnoDB: Error; possible reasons:\n" + "InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n" + "InnoDB: to have the same internal name in case-insensitive comparison.\n" + "InnoDB: 2) table ", stderr); ut_print_name(stderr, trx, new_name); fputs(" exists in the InnoDB internal data\n" "InnoDB: dictionary though MySQL is trying rename table ", stderr); |