summaryrefslogtreecommitdiff
path: root/innobase/row
diff options
context:
space:
mode:
authorunknown <aivanov@mysql.com>2005-12-12 21:06:59 +0300
committerunknown <aivanov@mysql.com>2005-12-12 21:06:59 +0300
commit8e3f95b555c4ed94bb5c1720969a060d20ed6536 (patch)
tree35392e37ca8b9a00df52afbe11acee443b2f1edb /innobase/row
parent5aeb69296a4e134f0215da3e6bcce4956b7d76ad (diff)
downloadmariadb-git-8e3f95b555c4ed94bb5c1720969a060d20ed6536.tar.gz
Fix BUG#12071: "Windows hang: 'Opening tables' or 'Waiting for
table' lockup". Changes from the innodb-4.1-ss11 snapshot. Do not call os_file-create_tmpfile() at runtime. Instead, create a tempfile at startup and guard access to it with a mutex. Also, fix bugs: 10511: "Wrong padding of UCS2 CHAR columns in ON UPDATE CASCADE"; 13778: "If FOREIGN_KEY_CHECKS=0, one can create inconsistent FOREIGN KEYs". When FOREIGN_KEY_CHECKS=0 we still need to check that datatypes between foreign key references are compatible. Also, added test cases (also for bug 9802). innobase/dict/dict0dict.c: Changes from the innodb-4.1-ss11 snapshot innobase/dict/dict0load.c: Changes from the innodb-4.1-ss11 snapshot innobase/include/dict0dict.h: Changes from the innodb-4.1-ss11 snapshot innobase/include/dict0load.h: Changes from the innodb-4.1-ss11 snapshot innobase/include/os0file.h: Changes from the innodb-4.1-ss11 snapshot innobase/include/rem0cmp.h: Changes from the innodb-4.1-ss11 snapshot innobase/include/srv0srv.h: Changes from the innodb-4.1-ss11 snapshot innobase/rem/rem0cmp.c: Changes from the innodb-4.1-ss11 snapshot innobase/row/row0ins.c: Changes from the innodb-4.1-ss11 snapshot innobase/row/row0mysql.c: Changes from the innodb-4.1-ss11 snapshot innobase/srv/srv0srv.c: Changes from the innodb-4.1-ss11 snapshot innobase/srv/srv0start.c: Changes from the innodb-4.1-ss11 snapshot libmysqld/ha_blackhole.cc: Changes from the innodb-4.1-ss11 snapshot mysql-test/r/innodb.result: Changes from the innodb-4.1-ss11 snapshot mysql-test/t/innodb.test: Changes from the innodb-4.1-ss11 snapshot sql/ha_innodb.cc: Changes from the innodb-4.1-ss11 snapshot
Diffstat (limited to 'innobase/row')
-rw-r--r--innobase/row/row0ins.c74
-rw-r--r--innobase/row/row0mysql.c64
2 files changed, 63 insertions, 75 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 456bb51d424..26ae0e6cc76 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -522,7 +522,7 @@ row_ins_cascade_calc_update_vec(
&& ufield->new_val.len
< dtype_get_fixed_size(type)) {
- ulint cset;
+ ulint cset;
ufield->new_val.data =
mem_heap_alloc(heap,
@@ -530,42 +530,42 @@ row_ins_cascade_calc_update_vec(
ufield->new_val.len =
dtype_get_fixed_size(type);
- /* Handle UCS2 strings differently.
- As no new collations will be
- introduced in 4.1, we hardcode the
- charset-collation codes here.
- In 5.0, the logic is based on
- mbminlen. */
- cset = dtype_get_charset_coll(
- dtype_get_prtype(type));
-
- if (cset == 35/*ucs2_general_ci*/
- || cset == 90/*ucs2_bin*/
- || (cset >= 128/*ucs2_unicode_ci*/
- && cset <= 144
- /*ucs2_persian_ci*/)) {
- /* space=0x0020 */
- ulint i;
- for (i = 0;
- i < ufield->new_val.len;
- i += 2) {
- mach_write_to_2(((byte*)
- ufield->new_val.data)
- + i, 0x0020);
- }
- } else {
- ut_a(dtype_get_pad_char(type)
- != ULINT_UNDEFINED);
-
- memset(ufield->new_val.data,
- (byte)dtype_get_pad_char(
- type),
- ufield->new_val.len);
- }
-
- memcpy(ufield->new_val.data,
- parent_ufield->new_val.data,
- parent_ufield->new_val.len);
+ /* Handle UCS2 strings differently.
+ As no new collations will be
+ introduced in 4.1, we hardcode the
+ charset-collation codes here.
+ In 5.0, the logic is based on
+ mbminlen. */
+ cset = dtype_get_charset_coll(
+ dtype_get_prtype(type));
+
+ if (cset == 35/*ucs2_general_ci*/
+ || cset == 90/*ucs2_bin*/
+ || (cset >= 128/*ucs2_unicode_ci*/
+ && cset <= 144
+ /*ucs2_persian_ci*/)) {
+ /* space=0x0020 */
+ ulint i;
+ for (i = 0;
+ i < ufield->new_val.len;
+ i += 2) {
+ mach_write_to_2(((byte*)
+ ufield->new_val.data)
+ + i, 0x0020);
+ }
+ } else {
+ ut_a(dtype_get_pad_char(type)
+ != ULINT_UNDEFINED);
+
+ memset(ufield->new_val.data,
+ (byte)dtype_get_pad_char(
+ type),
+ ufield->new_val.len);
+ }
+
+ memcpy(ufield->new_val.data,
+ parent_ufield->new_val.data,
+ parent_ufield->new_val.len);
}
ufield->extern_storage = FALSE;
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 7ce5c766e06..ba50e6a3511 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1804,7 +1804,7 @@ row_table_add_foreign_constraints(
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
- err = dict_load_foreigns(name, trx->check_foreigns);
+ err = dict_load_foreigns(name, TRUE);
}
if (err != DB_SUCCESS) {
@@ -2963,7 +2963,8 @@ row_rename_table_for_mysql(
mem_heap_t* heap = NULL;
const char** constraints_to_drop = NULL;
ulint n_constraints_to_drop = 0;
- ibool recovering_temp_table = FALSE;
+ ibool recovering_temp_table = FALSE;
+ ibool old_is_tmp, new_is_tmp;
ulint len;
ulint i;
ibool success;
@@ -3003,6 +3004,9 @@ row_rename_table_for_mysql(
trx->op_info = "renaming table";
trx_start_if_not_started(trx);
+ old_is_tmp = row_is_mysql_tmp_table_name(old_name);
+ new_is_tmp = row_is_mysql_tmp_table_name(new_name);
+
if (row_mysql_is_recovered_tmp_table(new_name)) {
recovering_temp_table = TRUE;
@@ -3047,7 +3051,7 @@ row_rename_table_for_mysql(
len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
- if (row_is_mysql_tmp_table_name(new_name)) {
+ if (new_is_tmp) {
db_name_len = dict_get_db_name_len(old_name) + 1;
/* MySQL is doing an ALTER TABLE command and it renames the
@@ -3200,7 +3204,7 @@ row_rename_table_for_mysql(
the table is stored in a single-table tablespace */
success = dict_table_rename_in_cache(table, new_name,
- !row_is_mysql_tmp_table_name(new_name));
+ !new_is_tmp);
if (!success) {
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, FALSE, NULL);
@@ -3217,19 +3221,16 @@ row_rename_table_for_mysql(
goto funct_exit;
}
- err = dict_load_foreigns(new_name, trx->check_foreigns);
-
- if (row_is_mysql_tmp_table_name(old_name)) {
+ /* We only want to switch off some of the type checking in
+ an ALTER, not in a RENAME. */
+
+ err = dict_load_foreigns(new_name,
+ old_is_tmp ? trx->check_foreigns : TRUE);
- /* MySQL is doing an ALTER TABLE command and it
- renames the created temporary table to the name
- of the original table. In the ALTER TABLE we maybe
- created some FOREIGN KEY constraints for the temporary
- table. But we want to load also the foreign key
- constraint definitions for the original table name. */
+ if (err != DB_SUCCESS) {
+ ut_print_timestamp(stderr);
- if (err != DB_SUCCESS) {
- ut_print_timestamp(stderr);
+ if (old_is_tmp) {
fputs(" InnoDB: Error: in ALTER TABLE ",
stderr);
ut_print_name(stderr, trx, new_name);
@@ -3237,36 +3238,23 @@ row_rename_table_for_mysql(
"InnoDB: has or is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n",
stderr);
-
- ut_a(dict_table_rename_in_cache(table,
- old_name, FALSE));
- trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE,
- NULL);
- trx->error_state = DB_SUCCESS;
- }
- } else {
- if (err != DB_SUCCESS) {
-
- ut_print_timestamp(stderr);
-
+ } else {
fputs(
" InnoDB: Error: in RENAME TABLE table ",
stderr);
ut_print_name(stderr, trx, new_name);
fputs("\n"
- "InnoDB: is referenced in foreign key constraints\n"
- "InnoDB: which are not compatible with the new table definition.\n",
+ "InnoDB: is referenced in foreign key constraints\n"
+ "InnoDB: which are not compatible with the new table definition.\n",
stderr);
-
- ut_a(dict_table_rename_in_cache(table,
- old_name, FALSE));
-
- trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE,
- NULL);
- trx->error_state = DB_SUCCESS;
}
+
+ ut_a(dict_table_rename_in_cache(table,
+ old_name, FALSE));
+ trx->error_state = DB_SUCCESS;
+ trx_general_rollback_for_mysql(trx, FALSE,
+ NULL);
+ trx->error_state = DB_SUCCESS;
}
}
funct_exit: