diff options
author | unknown <aivanov@mysql.com> | 2006-04-21 01:07:37 +0400 |
---|---|---|
committer | unknown <aivanov@mysql.com> | 2006-04-21 01:07:37 +0400 |
commit | 7ee05d7c713c0958cd56248b7b7397d72fea3941 (patch) | |
tree | 31ecaf555285cc75ca6c78a278663dcc1fc1c253 /innobase | |
parent | 6b63f270c6c9d31c72bb2ca5131c490e367be515 (diff) | |
download | mariadb-git-7ee05d7c713c0958cd56248b7b7397d72fea3941.tar.gz |
Applied innodb-5.0-ss476 snapshot.
Fix BUG#18934: "InnoDB crashes when table uses column like DB_ROW_ID".
Also, fix memory leaks in row_create_table_for_mysql() in rare
corner cases.
innobase/dict/dict0dict.c:
Applied innodb-5.0-ss476 snapshot.
Refuse tables that use reserved column names (Bug#18934).
innobase/dict/dict0load.c:
Applied innodb-5.0-ss476 snapshot.
dict_load_table(): Refuse to load tables with other TYPE
than DICT_TABLE_ORDINARY.
innobase/dict/dict0mem.c:
Applied innodb-5.0-ss476 snapshot.
Add dict_mem_table_free(), use it instead of duplicating
the code everywhere.
innobase/ibuf/ibuf0ibuf.c:
Applied innodb-5.0-ss476 snapshot.
innobase/include/dict0dict.h:
Applied innodb-5.0-ss476 snapshot.
Refuse tables that use reserved column name (Bug#18934).
innobase/include/dict0mem.h:
Applied innodb-5.0-ss476 snapshot.
Add dict_mem_table_free(), use it instead of duplicating
the code everywhere.
innobase/include/univ.i:
Applied innodb-5.0-ss476 snapshot.
innobase/log/log0recv.c:
Applied innodb-5.0-ss476 snapshot.
innobase/row/row0mysql.c:
Applied innodb-5.0-ss476 snapshot.
Refuse tables that use reserved column names (Bug#18934).
mysql-test/r/innodb.result:
Applied innodb-5.0-ss476 snapshot.
Fix result for test case for Bug#18934.
(Other changes are to be restored by the next cset).
mysql-test/t/innodb.test:
Applied innodb-5.0-ss476 snapshot.
Fix result for test case for Bug#18934.
(Removed test case for Bug#14360 is to be restored by the next cset).
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/dict/dict0dict.c | 38 | ||||
-rw-r--r-- | innobase/dict/dict0load.c | 17 | ||||
-rw-r--r-- | innobase/dict/dict0mem.c | 18 | ||||
-rw-r--r-- | innobase/ibuf/ibuf0ibuf.c | 6 | ||||
-rw-r--r-- | innobase/include/dict0dict.h | 9 | ||||
-rw-r--r-- | innobase/include/dict0mem.h | 7 | ||||
-rw-r--r-- | innobase/include/univ.i | 3 | ||||
-rw-r--r-- | innobase/log/log0recv.c | 6 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 18 |
9 files changed, 106 insertions, 16 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 653addd9ede..bad8886d0be 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1249,15 +1249,13 @@ dict_table_remove_from_cache( /* Remove table from LRU list of tables */ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); - mutex_free(&(table->autoinc_mutex)); - size = mem_heap_get_size(table->heap); ut_ad(dict_sys->size >= size); dict_sys->size -= size; - mem_heap_free(table->heap); + dict_mem_table_free(table); } /************************************************************************** @@ -1378,6 +1376,38 @@ dict_col_reposition_in_cache( HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col); } +/******************************************************************** +If the given column name is reserved for InnoDB system columns, return +TRUE. */ + +ibool +dict_col_name_is_reserved( +/*======================*/ + /* out: TRUE if name is reserved */ + const char* name) /* in: column name */ +{ + /* This check reminds that if a new system column is added to + the program, it should be dealt with here. */ +#if DATA_N_SYS_COLS != 4 +#error "DATA_N_SYS_COLS != 4" +#endif + + static const char* reserved_names[] = { + "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID" + }; + + ulint i; + + for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) { + if (strcmp(name, reserved_names[i]) == 0) { + + return(TRUE); + } + } + + return(FALSE); +} + /************************************************************************** Adds an index to the dictionary cache. */ @@ -1551,7 +1581,7 @@ dict_index_remove_from_cache( dict_sys->size -= size; - mem_heap_free(index->heap); + dict_mem_index_free(index); } /*********************************************************************** diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 6415cc56b61..bd93a719f6c 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -767,7 +767,7 @@ dict_load_table( if (!btr_pcur_is_on_user_rec(&pcur, &mtr) || rec_get_deleted_flag(rec, sys_tables->comp)) { /* Not found */ - + err_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); @@ -779,11 +779,8 @@ dict_load_table( /* Check if the table name in record is the searched one */ if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) { - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + + goto err_exit; } ut_a(0 == ut_strcmp("SPACE", @@ -844,6 +841,14 @@ dict_load_table( field = rec_get_nth_field_old(rec, 5, &len); table->type = mach_read_from_4(field); + if (UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: table %s: unknown table type %lu\n", + name, (ulong) table->type); + goto err_exit; + } + if (table->type == DICT_TABLE_CLUSTER_MEMBER) { ut_error; #if 0 /* clustered tables have not been implemented yet */ diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index eec35310039..98ef44a4969 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -97,6 +97,21 @@ dict_mem_table_create( return(table); } +/******************************************************************** +Free a table memory object. */ + +void +dict_mem_table_free( +/*================*/ + dict_table_t* table) /* in: table */ +{ + ut_ad(table); + ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); + + mutex_free(&(table->autoinc_mutex)); + mem_heap_free(table->heap); +} + /************************************************************************** Creates a cluster memory object. */ @@ -290,5 +305,8 @@ dict_mem_index_free( /*================*/ dict_index_t* index) /* in: index */ { + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + mem_heap_free(index->heap); } diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index d7fa48b6e66..e4694ed52ae 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -1160,9 +1160,9 @@ ibuf_dummy_index_free( dict_index_t* index) /* in: dummy index */ { dict_table_t* table = index->table; - mem_heap_free(index->heap); - mutex_free(&(table->autoinc_mutex)); - mem_heap_free(table->heap); + + dict_mem_index_free(index); + dict_mem_table_free(table); } /************************************************************************* diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 4396611e529..642037494b5 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -98,6 +98,15 @@ ulint dict_col_get_clust_pos( /*===================*/ dict_col_t* col); +/******************************************************************** +If the given column name is reserved for InnoDB system columns, return +TRUE. */ + +ibool +dict_col_name_is_reserved( +/*======================*/ + /* out: TRUE if name is reserved */ + const char* name); /* in: column name */ /************************************************************************ Initializes the autoinc counter. It is not an error to initialize an already initialized counter. */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 7eec86d0bcb..3c10e82342b 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -56,6 +56,13 @@ dict_mem_table_create( a member of a cluster */ ulint n_cols, /* in: number of columns */ ibool comp); /* in: TRUE=compact page format */ +/******************************************************************** +Free a table memory object. */ + +void +dict_mem_table_free( +/*================*/ + dict_table_t* table); /* in: table */ /************************************************************************** Creates a cluster memory object. */ diff --git a/innobase/include/univ.i b/innobase/include/univ.i index 04b254a8221..bc3bd031f0c 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -261,6 +261,9 @@ it is read or written. */ /* Tell the compiler that cond is unlikely to hold */ #define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE) +/* Compile-time constant of the given array's size. */ +#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0])) + #include <stdio.h> #include "ut0dbg.h" #include "ut0ut.h" diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 42e854398ba..7c56fe35d48 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -890,9 +890,9 @@ recv_parse_or_apply_log_rec_body( ut_ad(!page || ptr); if (index) { dict_table_t* table = index->table; - mem_heap_free(index->heap); - mutex_free(&(table->autoinc_mutex)); - mem_heap_free(table->heap); + + dict_mem_index_free(index); + dict_mem_table_free(table); } return(ptr); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 937056c300e..89b82882d93 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1673,7 +1673,9 @@ row_mysql_recover_tmp_table( if (!ptr) { /* table name does not begin with "/rsql" */ + dict_mem_table_free(table); trx_commit_for_mysql(trx); + return(DB_ERROR); } else { @@ -1785,6 +1787,7 @@ row_create_table_for_mysql( const char* table_name; ulint table_name_len; ulint err; + ulint i; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG @@ -1802,6 +1805,7 @@ row_create_table_for_mysql( "InnoDB: with raw, and innodb_force_... is removed.\n", stderr); + dict_mem_table_free(table); trx_commit_for_mysql(trx); return(DB_ERROR); @@ -1816,11 +1820,25 @@ row_create_table_for_mysql( "InnoDB: MySQL system tables must be of the MyISAM type!\n", table->name); + dict_mem_table_free(table); trx_commit_for_mysql(trx); return(DB_ERROR); } + /* Check that no reserved column names are used. */ + for (i = 0; i < dict_table_get_n_user_cols(table); i++) { + dict_col_t* col = dict_table_get_nth_col(table, i); + + if (dict_col_name_is_reserved(col->name)) { + + dict_mem_table_free(table); + trx_commit_for_mysql(trx); + + return(DB_ERROR); + } + } + trx_start_if_not_started(trx); if (row_mysql_is_recovered_tmp_table(table->name)) { |