diff options
author | unknown <marko@hundin.mysql.fi> | 2004-04-01 16:51:34 +0300 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-04-01 16:51:34 +0300 |
commit | 025ddfea288890236d4da04b46b3fff926707de3 (patch) | |
tree | fab5076a83cb8b112b16f76355f3a96a708c48ba /innobase | |
parent | 95367941561263fac5ee399dd8eb4a408690bc0d (diff) | |
download | mariadb-git-025ddfea288890236d4da04b46b3fff926707de3.tar.gz |
InnoDB cleanup: fixing buffer overflows and quoting of quotes
innobase/dict/dict0crea.c:
Remove unneeded prototypes for static functions
Remove unused parameters from some functions
Replace some assertions with compile-time checks
dict_create_add_foreigns_to_dictionary():
allocate space dynamically for the SQL, and quote quotes
innobase/dict/dict0dict.c:
Remove unnecessary prototypes for static functions
dict_tables_have_same_db(): Remove length limitation
dict_remove_db_name(): Use strchr()
dict_get_db_name_len(): Use strchr()
Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup()
Remove unnecessary strlen() calls
Allocate space dynamically for generated strings
dict_scan_id(): allow quotes within quoted strings
innobase/dict/dict0load.c:
Remove unnecessary strlen() calls
Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup()
innobase/dict/dict0mem.c:
Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup()
innobase/eval/eval0eval.c:
Make TO_CHAR() work with any machine word width
innobase/fil/fil0fil.c:
Replace mem_alloc()+strlen()+strcpy() with mem_strdup()
innobase/ibuf/ibuf0ibuf.c:
Make some global variables static
Add #ifdef UNIV_IBUF_DEBUG around debug statements
innobase/include/data0data.h:
Add #ifdef UNIV_DEBUG around dtuple_validate()
innobase/include/data0data.ic:
Replace = with == in ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N)
innobase/include/dict0dict.h:
Add const qualifiers
innobase/include/lock0lock.h:
Add UL suffixes to unsigned long masks
innobase/include/log0log.h:
Remove unused parameter "type" of log_group_write_buf()
innobase/include/mem0mem.h:
Add mem_strdup(), mem_strdupl(), mem_strdupq(), mem_heap_strdup(),
and mem_heap_strdupl()
innobase/include/mem0mem.ic:
Add mem_strdup(), mem_strdupl(), mem_strdupq(), mem_heap_strdup(),
and mem_heap_strdupl()
innobase/include/row0uins.h:
Remove unused parameter "thr" of row_undo_ins()
innobase/include/row0undo.h:
Remvoe unused parameter "thr" of row_undo_search_clust_to_pcur()
innobase/include/ut0byte.h:
Add const qualifier to ut_cpy_in_lower_case()
Remove parameter "len" of ut_cmp_in_lower_case()
innobase/include/ut0mem.h:
Add ut_strlenq(), ut_strcpyq() and ut_memcpyq()
innobase/include/ut0mem.ic:
Add ut_strlenq()
innobase/include/ut0ut.h:
Declare ut_sprintf() as a printf-style function
innobase/lock/lock0lock.c:
lock_clust_rec_modify_check_and_lock(): Remove unused variable "trx"
innobase/log/log0log.c:
Remove unused parameters
innobase/log/log0recv.c:
Remove parameter "type" from log_group_write_buf()
innobase/mem/mem0mem.c:
Simplify the initialization of block->init_block
innobase/mtr/mtr0log.c:
Add a debug assertion to mlog_parse_initial_log_record()
innobase/page/page0cur.c:
Add debug assertion to page_cur_insert_rec_write_log()
Remove hard-coded buffer size in page_cur_parse_insert_rec()
innobase/page/page0page.c:
Remove unneeded variable rec
innobase/pars/pars0opt.c:
Correct a potential buffer overflow
innobase/pars/pars0pars.c:
Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup()
innobase/row/row0ins.c:
Replace parameter "thr" with "trx" in row_ins_foreign_report_add_err()
Remove unnecessary strlen() call
Use strchr()
innobase/row/row0mysql.c:
Add row_mysql_is_recovered_tmp_table()
Add row_mysql_is_system_table()
Compare reserved table names with exact match
Use strstr() and strchr() and mem_strdupl()
Compute space needed for generated SQL, and allocate it dynamically
innobase/row/row0purge.c:
Remove unused parameters "thr"
innobase/row/row0row.c:
Simplify row_get_clust_rec()
innobase/row/row0uins.c:
Remove unused parameters "thr"
innobase/row/row0umod.c:
Remove unused variable "index"
row_undo_mod_del_unmark_sec_and_undo_update():
Remove parameter "node" and variable "rec"
Remove unused parameters "thr"
innobase/row/row0undo.c:
Remove unused parameters "thr"
innobase/srv/srv0srv.c:
Replace UT_NOT_USED() with __attribute__((unused))
innobase/srv/srv0start.c:
Remove unnecessary strlen() calls
Remove unused parameter "create_new_db" of open_or_create_log_file()
innobase/trx/trx0roll.c:
Replace mem_alloc()+strlen()+memcpy() with mem_strdup()
innobase/trx/trx0sys.c:
Remove unnecessary strlen() call
innobase/ut/ut0byte.c:
Add const qualifier to ut_cpy_in_lower_case()
Remove parameter "len" of ut_cmp_in_lower_case()
innobase/ut/ut0mem.c:
Add ut_strlenq() and ut_memcpyq()
sql/ha_innodb.cc:
Remove parameter "len" of ut_cmp_in_lower_case()
Diffstat (limited to 'innobase')
42 files changed, 1142 insertions, 1137 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 48fcb9c1e79..967818a3784 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -37,67 +37,6 @@ static dtuple_t* dict_create_sys_tables_tuple( /*=========================*/ - /* out: the tuple which should be inserted */ - dict_table_t* table, /* in: table */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ -/********************************************************************* -Based on a table object, this function builds the entry to be inserted -in the SYS_COLUMNS system table. */ -static -dtuple_t* -dict_create_sys_columns_tuple( -/*==========================*/ - /* out: the tuple which should be inserted */ - dict_table_t* table, /* in: table */ - ulint i, /* in: column number */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ -/********************************************************************* -Based on an index object, this function builds the entry to be inserted -in the SYS_INDEXES system table. */ -static -dtuple_t* -dict_create_sys_indexes_tuple( -/*==========================*/ - /* out: the tuple which should be inserted */ - dict_index_t* index, /* in: index */ - mem_heap_t* heap, /* in: memory heap from which the memory for - the built tuple is allocated */ - trx_t* trx); /* in: transaction handle */ -/********************************************************************* -Based on an index object, this function builds the entry to be inserted -in the SYS_FIELDS system table. */ -static -dtuple_t* -dict_create_sys_fields_tuple( -/*=========================*/ - /* out: the tuple which should be inserted */ - dict_index_t* index, /* in: index */ - ulint i, /* in: field number */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ -/********************************************************************* -Creates the tuple with which the index entry is searched for -writing the index tree root page number, if such a tree is created. */ -static -dtuple_t* -dict_create_search_tuple( -/*=====================*/ - /* out: the tuple for search */ - dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES - table */ - mem_heap_t* heap); /* in: memory heap from which the memory for - the built tuple is allocated */ - -/********************************************************************* -Based on a table object, this function builds the entry to be inserted -in the SYS_TABLES system table. */ -static -dtuple_t* -dict_create_sys_tables_tuple( -/*=========================*/ - /* out: the tuple which should be inserted */ dict_table_t* table, /* in: table */ mem_heap_t* heap) /* in: memory heap from which the memory for the built tuple is allocated */ @@ -331,9 +270,8 @@ dict_create_sys_indexes_tuple( /*==========================*/ /* out: the tuple which should be inserted */ dict_index_t* index, /* in: index */ - mem_heap_t* heap, /* in: memory heap from which the memory for + mem_heap_t* heap) /* in: memory heap from which the memory for the built tuple is allocated */ - trx_t* trx) /* in: transaction handle */ { dict_table_t* sys_indexes; dict_table_t* table; @@ -341,7 +279,6 @@ dict_create_sys_indexes_tuple( dfield_t* dfield; byte* ptr; - UT_NOT_USED(trx); #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ @@ -387,7 +324,9 @@ dict_create_sys_indexes_tuple( dfield_set_data(dfield, ptr, 4); /* 7: SPACE --------------------------*/ - ut_a(DICT_SYS_INDEXES_SPACE_NO_FIELD == 7); +#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 7 +#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 7" +#endif dfield = dtuple_get_nth_field(entry, 5); @@ -397,7 +336,9 @@ dict_create_sys_indexes_tuple( dfield_set_data(dfield, ptr, 4); /* 8: PAGE_NO --------------------------*/ - ut_a(DICT_SYS_INDEXES_PAGE_NO_FIELD == 8); +#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 8 +#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 8" +#endif dfield = dtuple_get_nth_field(entry, 6); @@ -565,8 +506,7 @@ dict_build_index_def_step( index->page_no = FIL_NULL; - row = dict_create_sys_indexes_tuple(index, node->heap, - thr_get_trx(thr)); + row = dict_create_sys_indexes_tuple(index, node->heap); node->ind_row = row; ins_node_set_new_row(node->ind_def, row); @@ -602,7 +542,6 @@ ulint dict_create_index_tree_step( /*========================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ - que_thr_t* thr, /* in: query thread */ ind_node_t* node) /* in: index create node */ { dict_index_t* index; @@ -615,7 +554,6 @@ dict_create_index_tree_step( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - UT_NOT_USED(thr); index = node->index; table = node->table; @@ -963,7 +901,7 @@ dict_create_index_step( if (node->state == INDEX_CREATE_INDEX_TREE) { - err = dict_create_index_tree_step(thr, node); + err = dict_create_index_tree_step(node); if (err != DB_SUCCESS) { @@ -1166,11 +1104,22 @@ dict_create_add_foreigns_to_dictionary( que_t* graph; ulint number = start_id + 1; ulint len; - ulint namelen; ulint error; char* ebuf = dict_foreign_err_buf; ulint i; - char buf[10000]; + char* sql; + char* sqlend; + /* This procedure builds an InnoDB stored procedure which will insert + the necessary rows into SYS_FOREIGN and SYS_FOREIGN_COLS. */ + static const char str1[] = "PROCEDURE ADD_FOREIGN_DEFS_PROC () IS\n" + "BEGIN\n" + "INSERT INTO SYS_FOREIGN VALUES("; + static const char str2[] = ");\n"; + static const char str3[] = + "INSERT INTO SYS_FOREIGN_COLS VALUES("; + static const char str4[] = + "COMMIT WORK;\n" + "END;\n"; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1190,58 +1139,75 @@ loop: return(DB_SUCCESS); } - /* Build an InnoDB stored procedure which will insert the necessary - rows to SYS_FOREIGN and SYS_FOREIGN_COLS */ - - len = 0; - - len += sprintf(buf, - "PROCEDURE ADD_FOREIGN_DEFS_PROC () IS\n" - "BEGIN\n"); - - namelen = strlen(table->name); - ut_a(namelen < MAX_TABLE_NAME_LEN); - if (foreign->id == NULL) { /* Generate a new constraint id */ - foreign->id = mem_heap_alloc(foreign->heap, namelen + 20); + ulint namelen = strlen(table->name); + char* id = mem_heap_alloc(foreign->heap, namelen + 20); /* no overflow if number < 1e13 */ - sprintf(foreign->id, "%s_ibfk_%lu", table->name, number); - number++; + sprintf(id, "%s_ibfk_%lu", table->name, number++); + foreign->id = id; } - ut_a(strlen(foreign->id) < MAX_IDENTIFIER_LEN); - ut_a(len < (sizeof buf) - - 46 - 2 * MAX_TABLE_NAME_LEN - MAX_IDENTIFIER_LEN - 20); + len = (sizeof str1) + (sizeof str2) + (sizeof str4) - 3 + + 9/* ' and , chars */ + 10/* 32-bit integer */ + + ut_strlenq(foreign->id, '\'') * (foreign->n_fields + 1) + + ut_strlenq(table->name, '\'') + + ut_strlenq(foreign->referenced_table_name, '\''); + + for (i = 0; i < foreign->n_fields; i++) { + len += 9/* ' and , chars */ + 10/* 32-bit integer */ + + (sizeof str3) + (sizeof str2) - 2 + + ut_strlenq(foreign->foreign_col_names[i], '\'') + + ut_strlenq(foreign->referenced_col_names[i], '\''); + } - len += sprintf(buf + len, - "INSERT INTO SYS_FOREIGN VALUES('%s', '%s', '%s', %lu);\n", - foreign->id, - table->name, - foreign->referenced_table_name, - foreign->n_fields - + (foreign->type << 24)); + sql = sqlend = mem_alloc(len + 1); + + /* INSERT INTO SYS_FOREIGN VALUES(...); */ + memcpy(sqlend, str1, (sizeof str1) - 1); + sqlend += (sizeof str1) - 1; + *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', foreign->id); + *sqlend++ = '\'', *sqlend++ = ',', *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', table->name); + *sqlend++ = '\'', *sqlend++ = ',', *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', foreign->referenced_table_name); + *sqlend++ = '\'', *sqlend++ = ','; + sqlend += sprintf(sqlend, "%010lu", + foreign->n_fields + (foreign->type << 24)); + memcpy(sqlend, str2, (sizeof str2) - 1); + sqlend += (sizeof str2) - 1; for (i = 0; i < foreign->n_fields; i++) { - ut_a(len < (sizeof buf) - - 51 - 2 * MAX_COLUMN_NAME_LEN - - MAX_IDENTIFIER_LEN - 20); - - len += sprintf(buf + len, - "INSERT INTO SYS_FOREIGN_COLS VALUES('%s', %lu, '%s', '%s');\n", - foreign->id, - i, - foreign->foreign_col_names[i], - foreign->referenced_col_names[i]); + /* INSERT INTO SYS_FOREIGN_COLS VALUES(...); */ + memcpy(sqlend, str3, (sizeof str3) - 1); + sqlend += (sizeof str3) - 1; + *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', foreign->id); + *sqlend++ = '\''; *sqlend++ = ','; + sqlend += sprintf(sqlend, "%010lu", i); + *sqlend++ = ','; *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', + foreign->foreign_col_names[i]); + *sqlend++ = '\''; *sqlend++ = ','; *sqlend++ = '\''; + sqlend = ut_strcpyq(sqlend, '\'', + foreign->referenced_col_names[i]); + *sqlend++ = '\''; + memcpy(sqlend, str2, (sizeof str2) - 1); + sqlend += (sizeof str2) - 1; } - ut_a(len < (sizeof buf) - 19); - len += sprintf(buf + len,"COMMIT WORK;\nEND;\n"); + memcpy(sqlend, str4, sizeof str4); + sqlend += sizeof str4; - graph = pars_sql(buf); + ut_a(sqlend == sql + len + 1); + + graph = pars_sql(sql); ut_a(graph); + mem_free(sql); + graph->trx = trx; trx->graph = NULL; diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 67452c154e7..0efb9935800 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -49,7 +49,10 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve hash table fixed size in bytes */ #define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data dictionary varying size in bytes */ - + +/* Identifies generated InnoDB foreign key names */ +static char dict_ibfk[] = "_ibfk_"; + /************************************************************************** Adds a column to the data dictionary hash table. */ static @@ -129,16 +132,7 @@ dict_index_build_internal_non_clust( dict_index_t* index); /* in: user representation of a non-clustered index */ /************************************************************************** -In an index tree, finds the index corresponding to a record in the tree. */ -UNIV_INLINE -dict_index_t* -dict_tree_find_index_low( -/*=====================*/ - /* out: index */ - dict_tree_t* tree, /* in: index tree */ - rec_t* rec); /* in: record for which to find correct 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( @@ -187,26 +181,18 @@ 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 */ + /* out: TRUE if same db name */ + const char* name1, /* in: table name in the form + dbname '/' tablename */ + const char* name2) /* in: table name in the form + dbname '/' tablename */ { - ulint i; - - for (i = 0; i < 100000; i++) { - if (name1[i] == '/' && name2[i] == '/') { - + for (; *name1 == *name2; name1++, name2++) { + if (*name1 == '/') { return(TRUE); } - - if (name1[i] != name2[i]) { - - return(FALSE); - } + ut_a(*name1); /* the names must contain '/' */ } - - ut_error; - return(FALSE); } @@ -219,18 +205,11 @@ 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_error; - - return(NULL); + char* s; + s = strchr(name, '/'); + ut_a(s); + if (s) s++; + return(s); } /************************************************************************ @@ -239,21 +218,14 @@ Get the database name length in a table name. */ ulint dict_get_db_name_len( /*=================*/ - /* out: database name length */ - char* name) /* in: table name in the form dbname '/' tablename */ + /* out: database name length */ + const char* name) /* in: table name in the form + dbname '/' tablename */ { - ulint i; - - for (i = 0; i < 100000 ; i++) { - if (name[i] == '/') { - - return(i); - } - } - - ut_error; - - return(0); + const char* s; + s = strchr(name, '/'); + ut_a(s); + return(s - name); } /************************************************************************ @@ -889,7 +861,6 @@ dict_table_rename_in_cache( dict_index_t* index; ulint fold; ulint old_size; - char* name_buf; char* old_name; ulint i; @@ -923,16 +894,9 @@ dict_table_rename_in_cache( /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(table->name), table); - old_name = mem_heap_alloc(table->heap, ut_strlen(table->name) + 1); - - ut_strcpy(old_name, table->name); - - name_buf = mem_heap_alloc(table->heap, ut_strlen(new_name) + 1); - - ut_memcpy(name_buf, new_name, ut_strlen(new_name) + 1); + old_name = mem_heap_strdup(table->heap, table->name); + table->name = mem_heap_strdup(table->heap, new_name); - table->name = name_buf; - /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); @@ -1000,30 +964,27 @@ dict_table_rename_in_cache( ut_strlen(table->name) + 1); } - sprintf(foreign->foreign_table_name, "%s", table->name); + strcpy(foreign->foreign_table_name, table->name); if (strchr(foreign->id, '/')) { ulint db_len; - char old_id[2000]; + char* old_id; /* This is a >= 4.0.18 format id */ - ut_a(ut_strlen(foreign->id) < 1999); - - ut_strcpy(old_id, foreign->id); + old_id = mem_strdup(foreign->id); if (ut_strlen(foreign->id) > ut_strlen(old_name) - + ut_strlen("_ibfk_") + + ((sizeof dict_ibfk) - 1) && 0 == ut_memcmp(foreign->id, old_name, ut_strlen(old_name)) && 0 == ut_memcmp( foreign->id + ut_strlen(old_name), - (char*)"_ibfk_", ut_strlen("_ibfk_"))) { + dict_ibfk, (sizeof dict_ibfk) - 1)) { /* This is a generated >= 4.0.18 format id */ - if (ut_strlen(table->name) - > ut_strlen(old_name)) { + if (ut_strlen(table->name) > ut_strlen(old_name)) { foreign->id = mem_heap_alloc( foreign->heap, ut_strlen(table->name) @@ -1032,7 +993,8 @@ dict_table_rename_in_cache( /* Replace the prefix 'databasename/tablename' with the new names */ - sprintf(foreign->id, "%s%s", table->name, + strcpy(foreign->id, table->name); + strcat(foreign->id, old_id + ut_strlen(old_name)); } else { /* This is a >= 4.0.18 format id where the user @@ -1052,9 +1014,11 @@ dict_table_rename_in_cache( ut_memcpy(foreign->id, table->name, db_len); - sprintf(foreign->id + db_len, "%s", + strcpy(foreign->id + db_len, dict_remove_db_name(old_id)); } + + mem_free(old_id); } foreign = UT_LIST_GET_NEXT(foreign_list, foreign); @@ -1073,7 +1037,7 @@ dict_table_rename_in_cache( ut_strlen(table->name) + 1); } - sprintf(foreign->referenced_table_name, "%s", table->name); + strcpy(foreign->referenced_table_name, table->name); foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } @@ -1971,7 +1935,7 @@ dict_foreign_find_index( /*====================*/ /* out: matching index, NULL if not found */ dict_table_t* table, /* in: table */ - char** columns,/* in: array of column names */ + const char** columns,/* in: array of column names */ ulint n_cols, /* in: number of columns */ dict_index_t* types_idx)/* in: NULL or an index to whose types the column types must match */ @@ -1996,11 +1960,8 @@ dict_foreign_find_index( break; } - if (ut_strlen(columns[i]) != - ut_strlen(col_name) - || 0 != ut_cmp_in_lower_case(columns[i], - col_name, - ut_strlen(col_name))) { + if (0 != ut_cmp_in_lower_case(columns[i], + col_name)) { break; } @@ -2072,9 +2033,9 @@ dict_foreign_add_to_cache( if (for_in_cache->referenced_table == NULL && ref_table) { index = dict_foreign_find_index(ref_table, - for_in_cache->referenced_col_names, - for_in_cache->n_fields, - for_in_cache->foreign_index); + (const char**) for_in_cache->referenced_col_names, + for_in_cache->n_fields, + for_in_cache->foreign_index); if (index == NULL) { mutex_enter(&dict_foreign_err_mutex); @@ -2113,9 +2074,9 @@ dict_foreign_add_to_cache( if (for_in_cache->foreign_table == NULL && for_table) { index = dict_foreign_find_index(for_table, - for_in_cache->foreign_col_names, - for_in_cache->n_fields, - for_in_cache->referenced_index); + (const char**) for_in_cache->foreign_col_names, + for_in_cache->n_fields, + for_in_cache->referenced_index); if (index == NULL) { mutex_enter(&dict_foreign_err_mutex); @@ -2165,12 +2126,12 @@ Scans from pointer onwards. Stops if is at the start of a copy of 'string' where characters are compared without case sensitivity. Stops also at '\0'. */ static -char* +const char* dict_scan_to( /*=========*/ /* out: scanned up to this */ - char* ptr, /* in: scan from */ - const char *string) /* in: look for this */ + const char* ptr, /* in: scan from */ + const char* string) /* in: look for this */ { ibool success; ulint i; @@ -2202,18 +2163,18 @@ loop: /************************************************************************* Accepts a specified string. Comparisons are case-insensitive. */ -char* +const char* dict_accept( /*========*/ - /* out: if string was accepted, the pointer - is moved after that, else ptr is returned */ - char* ptr, /* in: scan from this */ - const char* string,/* in: accept only this string as the next - non-whitespace string */ - ibool* success)/* out: TRUE if accepted */ + /* out: if string was accepted, the pointer + is moved after that, else ptr is returned */ + const char* ptr, /* in: scan from this */ + const char* string, /* in: accept only this string as the next + non-whitespace string */ + ibool* success)/* out: TRUE if accepted */ { - char* old_ptr = ptr; - char* old_ptr2; + const char* old_ptr = ptr; + const char* old_ptr2; *success = FALSE; @@ -2238,21 +2199,27 @@ dict_accept( Scans an id. For the lexical definition of an 'id', see the code below. Strips backquotes or double quotes from around the id. */ static -char* +const char* dict_scan_id( /*=========*/ /* out: scanned to */ - char* ptr, /* in: scanned to */ - char** start, /* out: start of the id; NULL if no id was + const char* ptr, /* in: scanned to */ + mem_heap_t* heap, /* in: heap where to allocate the id + (NULL=id will not be allocated, but it + will point to string near ptr) */ + const char** id, /* out,own: the id; NULL if no id was scannable */ - ulint* len, /* out: length of the id */ - ibool accept_also_dot)/* in: TRUE if also a dot can appear in a + ibool accept_also_dot) + /* in: TRUE if also a dot can appear in a non-quoted id; in a quoted id it can appear always */ { - char quote = '\0'; + char quote = '\0'; + ulint len = 0; + const char* s; + char* d; - *start = NULL; + *id = NULL; while (isspace(*ptr)) { ptr++; @@ -2266,12 +2233,23 @@ dict_scan_id( if (*ptr == '`' || *ptr == '"') { quote = *ptr++; } - - *start = ptr; + + s = ptr; if (quote) { - while (*ptr != quote && *ptr != '\0') { + for (;;) { + if (!*ptr) { + /* Syntax error */ + return(ptr); + } + if (*ptr == quote) { + ptr++; + if (*ptr != quote) { + break; + } + } ptr++; + len++; } } else { while (!isspace(*ptr) && *ptr != '(' && *ptr != ')' @@ -2280,17 +2258,25 @@ dict_scan_id( ptr++; } + + len = ptr - s; } - *len = (ulint) (ptr - *start); - - if (quote) { - if (*ptr == quote) { - ptr++; - } else { - /* Syntax error */ - *start = NULL; + if (quote && heap) { + *id = d = mem_heap_alloc(heap, len + 1); + while (len--) { + if ((*d++ = *s++) == quote) { + s++; + } } + *d++ = 0; + ut_a(*s == quote); + ut_a(s + 1 == ptr); + } else if (heap) { + *id = mem_heap_strdupl(heap, s, len); + } else { + /* no heap given: id will point to source string */ + *id = (char*) s; } return(ptr); @@ -2299,26 +2285,26 @@ dict_scan_id( /************************************************************************* Tries to scan a column name. */ static -char* +const char* dict_scan_col( /*==========*/ /* out: scanned to */ - char* ptr, /* in: scanned to */ + const char* ptr, /* in: scanned to */ ibool* success,/* out: TRUE if success */ dict_table_t* table, /* in: table in which the column is */ dict_col_t** column, /* out: pointer to column if success */ - char** column_name,/* out: pointer to column->name if - success */ - ulint* column_name_len)/* out: column name length */ + mem_heap_t* heap, /* in: heap where to allocate the name */ + const char** name) /* out,own: the column name; NULL if no name + was scannable */ { dict_col_t* col; ulint i; - + *success = FALSE; - ptr = dict_scan_id(ptr, column_name, column_name_len, TRUE); + ptr = dict_scan_id(ptr, heap, name, TRUE); - if (column_name == NULL) { + if (*name == NULL) { return(ptr); /* Syntax error */ } @@ -2331,15 +2317,12 @@ dict_scan_col( col = dict_table_get_nth_col(table, i); - if (ut_strlen(col->name) == *column_name_len - && 0 == ut_cmp_in_lower_case(col->name, - *column_name, - *column_name_len)) { + if (0 == ut_cmp_in_lower_case(col->name, *name)) { /* Found */ *success = TRUE; *column = col; - *column_name = col->name; + strcpy((char*) *name, col->name); break; } @@ -2352,33 +2335,31 @@ dict_scan_col( /************************************************************************* Scans the referenced table name from an SQL string. */ static -char* +const char* dict_scan_table_name( /*=================*/ /* out: scanned to */ - char* ptr, /* in: scanned to */ + const char* ptr, /* in: scanned to */ dict_table_t** table, /* out: table object or NULL */ - char* name, /* in: foreign key table name */ + const char* name, /* in: foreign key table name */ ibool* success,/* out: TRUE if ok name found */ - char* second_table_name)/* in/out: buffer where to store - the referenced table name; must be at least - 2500 bytes */ + mem_heap_t* heap, /* in: heap where to allocate the id */ + const char** ref_name)/* out,own: the referenced table name; + NULL if no name was scannable */ { - char* database_name = NULL; - ulint database_name_len = 999999999; /* init to a dummy value to - suppress a compiler warning */ - char* table_name = NULL; - ulint table_name_len; - char* scanned_id; - ulint scanned_id_len; - ulint i; - + const char* database_name = NULL; + ulint database_name_len = 0; + const char* table_name = NULL; + ulint table_name_len; + const char* scan_name; + char* ref; + *success = FALSE; *table = NULL; - ptr = dict_scan_id(ptr, &scanned_id, &scanned_id_len, FALSE); + ptr = dict_scan_id(ptr, heap, &scan_name, FALSE); - if (scanned_id == NULL) { + if (scan_name == NULL) { return(ptr); /* Syntax error */ } @@ -2388,10 +2369,10 @@ dict_scan_table_name( ptr++; - database_name = scanned_id; - database_name_len = scanned_id_len; + database_name = scan_name; + database_name_len = strlen(database_name); - ptr = dict_scan_id(ptr, &table_name, &table_name_len, FALSE); + ptr = dict_scan_id(ptr, heap, &table_name, FALSE); if (table_name == NULL) { @@ -2405,65 +2386,57 @@ dict_scan_table_name( ... REFERENCES `databasename.tablename` ... starting from 4.0.18 it is ... REFERENCES `databasename`.`tablename` ... */ - - for (i = 0; i < scanned_id_len; i++) { - if (scanned_id[i] == '.') { - database_name = scanned_id; - database_name_len = i; - - scanned_id = scanned_id + i + 1; - scanned_id_len -= i + 1; + const char* s; + + for (s = scan_name; *s; s++) { + if (*s == '.') { + database_name = scan_name; + database_name_len = s - scan_name; + scan_name = ++s; + break;/* to do: multiple dots? */ } } - table_name = scanned_id; - table_name_len = scanned_id_len; + table_name = scan_name; } if (database_name == NULL) { /* Use the database name of the foreign key table */ database_name = name; - database_name_len = dict_get_db_name_len(name); } - if (table_name_len + database_name_len > 2000) { + table_name_len = strlen(table_name); + + ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2); - return(ptr); /* Too long name */ - } - #ifdef __WIN__ - ut_cpy_in_lower_case(second_table_name, database_name, - database_name_len); + ut_cpy_in_lower_case(ref, database_name, database_name_len); #else if (srv_lower_case_table_names) { - ut_cpy_in_lower_case(second_table_name, database_name, - database_name_len); + ut_cpy_in_lower_case(ref, database_name, database_name_len); } else { - ut_memcpy(second_table_name, database_name, - database_name_len); + memcpy(ref, database_name, database_name_len); } #endif - second_table_name[database_name_len] = '/'; + (ref)[database_name_len] = '/'; #ifdef __WIN__ - ut_cpy_in_lower_case(second_table_name + database_name_len + 1, - table_name, table_name_len); + ut_cpy_in_lower_case(ref + database_name_len + 1, + table_name, table_name_len + 1); #else if (srv_lower_case_table_names) { - ut_cpy_in_lower_case(second_table_name + database_name_len + 1, - table_name, table_name_len); + ut_cpy_in_lower_case(ref + database_name_len + 1, + table_name, table_name_len + 1); } else { - ut_memcpy(second_table_name + database_name_len + 1, - table_name, table_name_len); + strcpy(ref + database_name_len + 1, table_name); } #endif - second_table_name[database_name_len + 1 + table_name_len] = '\0'; *success = TRUE; - - *table = dict_table_get_low(second_table_name); + *ref_name = ref; + *table = dict_table_get_low(ref); return(ptr); } @@ -2471,20 +2444,19 @@ dict_scan_table_name( /************************************************************************* Skips one id. The id is allowed to contain also '.'. */ static -char* +const 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 or a syntax error */ + /* out: scanned to */ + const char* ptr, /* in: scanned to */ + ibool* success)/* out: TRUE if success, FALSE if just spaces + left in string or a syntax error */ { - char* start; - ulint len; + const char* start; *success = FALSE; - ptr = dict_scan_id(ptr, &start, &len, TRUE); + ptr = dict_scan_id(ptr, NULL, &start, TRUE); if (start) { *success = TRUE; @@ -2528,10 +2500,10 @@ scan_more: } if (*sptr == '#' - || (strlen(sptr) >= 3 && 0 == memcmp("-- ", sptr, 3))) { + || (0 == memcmp("-- ", sptr, 3))) { for (;;) { - /* In Unix a newline is 0x0D while in Windows - it is 0x0A followed by 0x0D */ + /* In Unix a newline is 0x0A while in Windows + it is 0x0D followed by 0x0A */ if (*sptr == (char)0x0A || *sptr == (char)0x0D @@ -2544,10 +2516,9 @@ scan_more: } } - if (strlen(sptr) >= 2 && *sptr == '/' && *(sptr + 1) == '*') { + if (*sptr == '/' && *(sptr + 1) == '*') { for (;;) { - if (strlen(sptr) >= 2 - && *sptr == '*' && *(sptr + 1) == '/') { + if (*sptr == '*' && *(sptr + 1) == '/') { sptr += 2; @@ -2586,27 +2557,28 @@ dict_table_get_highest_foreign_id( char* endp; ulint biggest_id = 0; ulint id; + ulint len; ut_a(table); + len = ut_strlen(table->name); foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign) { - if (ut_strlen(foreign->id) > ut_strlen("_ibfk_") - + ut_strlen(table->name) - && 0 == ut_memcmp(foreign->id, table->name, - ut_strlen(table->name)) - && 0 == ut_memcmp(foreign->id + ut_strlen(table->name), - (char*)"_ibfk_", ut_strlen("_ibfk_"))) { + if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len + && 0 == ut_memcmp(foreign->id, table->name, len) + && 0 == ut_memcmp(foreign->id + len, + dict_ibfk, (sizeof dict_ibfk) - 1)) { /* It is of the >= 4.0.18 format */ - id = strtoul(foreign->id + ut_strlen(table->name) - + ut_strlen("_ibfk_"), + id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1), &endp, 10); - ut_a(id != biggest_id); + if (*endp == '\0') { + ut_a(id != biggest_id); - if (id > biggest_id) { - biggest_id = id; + if (id > biggest_id) { + biggest_id = id; + } } } @@ -2622,10 +2594,11 @@ static void dict_foreign_report_syntax_err( /*===========================*/ - char* name, /* in: table name */ - char* start_of_latest_foreign,/* in: start of the foreign key clause + const char* name, /* in: table name */ + const char* start_of_latest_foreign, + /* in: start of the foreign key clause in the SQL string */ - char* ptr) /* in: place of the syntax error */ + const char* ptr) /* in: place of the syntax error */ { char* buf = dict_foreign_err_buf; @@ -2652,14 +2625,16 @@ ulint dict_create_foreign_constraints_low( /*================================*/ /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create or ALTER TABLE - statement where foreign keys are declared like: + trx_t* trx, /* in: transaction */ + mem_heap_t* heap, /* in: memory heap */ + const char* sql_string, + /* in: CREATE TABLE or ALTER TABLE statement + where foreign keys are declared like: FOREIGN KEY (a, b) REFERENCES table2(c, d), table2 can be written also with the database name before it: test.table2; the default database is the database of parameter name */ - char* name) /* in: table full name in the normalized form + const char* name) /* in: table full name in the normalized form database_name/table_name */ { dict_table_t* table; @@ -2668,31 +2643,28 @@ dict_create_foreign_constraints_low( ulint highest_id_so_far = 0; dict_index_t* index; dict_foreign_t* foreign; - char* ptr = sql_string; - char* start_of_latest_foreign = sql_string; + const char* ptr = sql_string; + const char* start_of_latest_foreign = sql_string; char* buf = dict_foreign_err_buf; - char* constraint_name; /* this is NOT a null- - terminated string */ - ulint constraint_name_len; + const char* constraint_name; ibool success; ulint error; - char* ptr1; - char* ptr2; + const char* ptr1; + const char* ptr2; 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]; - char referenced_table_name[2500]; + const char* column_names[500]; + const char* referenced_table_name; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - table = dict_table_get_low(name); + table = dict_table_get_low((char*) name); if (table == NULL) { mutex_enter(&dict_foreign_err_mutex); @@ -2700,7 +2672,7 @@ dict_create_foreign_constraints_low( sprintf(buf + strlen(buf), " Error in foreign key constraint of table %.500s.\n" "Cannot find the table from the internal data dictionary of InnoDB.\n" -"Create table statement:\n%.2000\n", name, sql_string); +"Create table statement:\n%.2000s\n", name, sql_string); ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); mutex_exit(&dict_foreign_err_mutex); @@ -2729,7 +2701,7 @@ dict_create_foreign_constraints_low( buffer */ ptr = dict_scan_table_name(ptr, &table_to_alter, name, - &success, referenced_table_name); + &success, heap, &referenced_table_name); if (!success) { fprintf(stderr, "InnoDB: Error: could not find the table being ALTERED in:\n%s\n", sql_string); @@ -2757,8 +2729,8 @@ dict_create_foreign_constraints_low( loop: /* Scan either to "CONSTRAINT" or "FOREIGN", whichever is closer */ - ptr1 = dict_scan_to(ptr, (char *) "CONSTRAINT"); - ptr2 = dict_scan_to(ptr, (char *) "FOREIGN"); + ptr1 = dict_scan_to(ptr, "CONSTRAINT"); + ptr2 = dict_scan_to(ptr, "FOREIGN"); constraint_name = NULL; @@ -2768,7 +2740,7 @@ loop: the id of the constraint to system tables. */ ptr = ptr1; - ptr = dict_accept(ptr, (char *) "CONSTRAINT", &success); + ptr = dict_accept(ptr, "CONSTRAINT", &success); ut_a(success); @@ -2782,8 +2754,7 @@ loop: /* read constraint name unless got "CONSTRAINT FOREIGN" */ if (ptr != ptr2) { - ptr = dict_scan_id(ptr, &constraint_name, - &constraint_name_len, FALSE); + ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE); } } else { ptr = ptr2; @@ -2801,19 +2772,19 @@ loop: start_of_latest_foreign = ptr; - ptr = dict_accept(ptr, (char *) "FOREIGN", &success); + ptr = dict_accept(ptr, "FOREIGN", &success); if (!isspace(*ptr)) { goto loop; } - ptr = dict_accept(ptr, (char *) "KEY", &success); + ptr = dict_accept(ptr, "KEY", &success); if (!success) { goto loop; } - ptr = dict_accept(ptr, (char *) "(", &success); + ptr = dict_accept(ptr, "(", &success); if (!success) { /* MySQL allows also an index id before the '('; we @@ -2827,7 +2798,7 @@ loop: return(DB_CANNOT_ADD_CONSTRAINT); } - ptr = dict_accept(ptr, (char *) "(", &success); + ptr = dict_accept(ptr, "(", &success); if (!success) { /* We do not flag a syntax error here because in an @@ -2841,8 +2812,9 @@ loop: /* Scan the columns in the first list */ col_loop1: + ut_a(i < (sizeof column_names) / sizeof *column_names); ptr = dict_scan_col(ptr, &success, table, columns + i, - column_names + i, column_name_lens + i); + heap, column_names + i); if (!success) { mutex_enter(&dict_foreign_err_mutex); ut_sprintf_timestamp(buf); @@ -2858,13 +2830,13 @@ col_loop1: i++; - ptr = dict_accept(ptr, (char *) ",", &success); + ptr = dict_accept(ptr, ",", &success); if (success) { goto col_loop1; } - ptr = dict_accept(ptr, (char *) ")", &success); + ptr = dict_accept(ptr, ")", &success); if (!success) { dict_foreign_report_syntax_err(name, start_of_latest_foreign, @@ -2914,15 +2886,11 @@ col_loop1: db_len = dict_get_db_name_len(table->name); foreign->id = mem_heap_alloc(foreign->heap, - db_len + 1 + constraint_name_len + 1); - - ut_memcpy(foreign->id, table->name, db_len); + db_len + strlen(constraint_name) + 2); + ut_memcpy(foreign->id, table->name, db_len); foreign->id[db_len] = '/'; - - ut_memcpy(foreign->id + db_len + 1, constraint_name, - constraint_name_len); - foreign->id[db_len + 1 + constraint_name_len] = '\0'; + strcpy(foreign->id + db_len + 1, constraint_name); } foreign->foreign_table = table; @@ -2932,14 +2900,12 @@ col_loop1: foreign->foreign_col_names = mem_heap_alloc(foreign->heap, i * sizeof(void*)); for (i = 0; i < foreign->n_fields; i++) { - foreign->foreign_col_names[i] = mem_heap_alloc(foreign->heap, - 1 + ut_strlen(columns[i]->name)); - ut_memcpy(foreign->foreign_col_names[i], columns[i]->name, - 1 + ut_strlen(columns[i]->name)); + foreign->foreign_col_names[i] = + mem_heap_strdup(foreign->heap, columns[i]->name); } ptr = dict_scan_table_name(ptr, &referenced_table, name, - &success, referenced_table_name); + &success, heap, &referenced_table_name); /* Note that referenced_table can be NULL if the user has suppressed checking of foreign key constraints! */ @@ -2973,7 +2939,7 @@ col_loop1: col_loop2: ptr = dict_scan_col(ptr, &success, referenced_table, columns + i, - column_names + i, column_name_lens + i); + heap, column_names + i); i++; if (!success) { @@ -3179,21 +3145,14 @@ try_find_index: foreign->referenced_index = index; foreign->referenced_table = referenced_table; - foreign->referenced_table_name = mem_heap_alloc(foreign->heap, - 1 + ut_strlen(referenced_table_name)); - - ut_memcpy(foreign->referenced_table_name, referenced_table_name, - 1 + ut_strlen(referenced_table_name)); + foreign->referenced_table_name = mem_heap_strdup(foreign->heap, + referenced_table_name); foreign->referenced_col_names = mem_heap_alloc(foreign->heap, i * sizeof(void*)); for (i = 0; i < foreign->n_fields; i++) { foreign->referenced_col_names[i] - = mem_heap_alloc(foreign->heap, - 1 + column_name_lens[i]); - ut_memcpy(foreign->referenced_col_names[i], column_names[i], - column_name_lens[i]); - (foreign->referenced_col_names[i])[column_name_lens[i]] = '\0'; + = mem_heap_strdup(foreign->heap, column_names[i]); } /* We found an ok constraint definition: add to the lists */ @@ -3230,15 +3189,18 @@ dict_create_foreign_constraints( char* name) /* in: table full name in the normalized form database_name/table_name */ { - char* str; - ulint err; + char* str; + ulint err; + mem_heap_t* heap; str = dict_strip_comments(sql_string); + heap = mem_heap_create(10000); - err = dict_create_foreign_constraints_low(trx, str, name); + err = dict_create_foreign_constraints_low(trx, heap, str, name); + + mem_heap_free(heap); + mem_free(str); - mem_free(str); - return(err); } @@ -3258,17 +3220,15 @@ dict_foreign_parse_drop_constraints( dict_table_t* table, /* in: table */ ulint* n, /* out: number of constraints to drop */ - char*** constraints_to_drop) /* out: id's of the + const char*** constraints_to_drop) /* out: id's of the constraints to drop */ { - dict_foreign_t* foreign; - ibool success; - char* str; - char* ptr; + dict_foreign_t* foreign; + ibool success; + char* str; + const char* ptr; char* buf = dict_foreign_err_buf; - char* start; - char* id; - ulint len; + const char* id; *n = 0; @@ -3281,47 +3241,43 @@ dict_foreign_parse_drop_constraints( ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ loop: - ptr = dict_scan_to(ptr, (char *) "DROP"); + ptr = dict_scan_to(ptr, "DROP"); if (*ptr == '\0') { - ut_a(*n < 1000); - mem_free(str); return(DB_SUCCESS); } - ptr = dict_accept(ptr, (char *) "DROP", &success); + ptr = dict_accept(ptr, "DROP", &success); if (!isspace(*ptr)) { goto loop; } - ptr = dict_accept(ptr, (char *) "FOREIGN", &success); + ptr = dict_accept(ptr, "FOREIGN", &success); if (!success) { goto loop; } - ptr = dict_accept(ptr, (char *) "KEY", &success); + ptr = dict_accept(ptr, "KEY", &success); if (!success) { goto syntax_error; } - ptr = dict_scan_id(ptr, &start, &len, TRUE); + ptr = dict_scan_id(ptr, heap, &id, TRUE); - if (start == NULL) { + if (id == NULL) { goto syntax_error; } - id = mem_heap_alloc(heap, len + 1); - ut_memcpy(id, start, len); - id[len] = '\0'; + ut_a(*n < 1000); (*constraints_to_drop)[*n] = id; (*n)++; @@ -3330,9 +3286,9 @@ loop: foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign != NULL) { - if (0 == ut_strcmp(foreign->id, id) + if (0 == strcmp(foreign->id, id) || (strchr(foreign->id, '/') - && 0 == ut_strcmp(id, + && 0 == strcmp(id, dict_remove_db_name(foreign->id)))) { /* Found */ break; diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 5a5830a2517..06306ca483a 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -39,7 +39,6 @@ dict_get_first_table_name_in_db( rec_t* rec; byte* field; ulint len; - char* table_name; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG @@ -91,9 +90,7 @@ loop: /* We found one */ - table_name = mem_alloc(len + 1); - ut_memcpy(table_name, field, len); - table_name[len] = '\0'; + char* table_name = mem_strdupl(field, len); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -122,7 +119,6 @@ dict_print(void) rec_t* rec; byte* field; ulint len; - char table_name[10000]; mtr_t mtr; mutex_enter(&(dict_sys->mutex)); @@ -156,14 +152,14 @@ loop: /* We found one */ - ut_memcpy(table_name, field, len); - table_name[len] = '\0'; - + char* table_name = mem_strdupl(field, len); + btr_pcur_store_position(&pcur, &mtr); mtr_commit(&mtr); - + table = dict_table_get_low(table_name); + mem_free(table_name); if (table == NULL) { fprintf(stderr, "InnoDB: Failed to load table %s\n", @@ -205,7 +201,6 @@ dict_load_columns( byte* field; ulint len; byte* buf; - char* name_buf; char* name; ulint mtype; ulint prtype; @@ -256,12 +251,7 @@ dict_load_columns( dict_table_get_first_index(sys_columns), 4))->name)); field = rec_get_nth_field(rec, 4, &len); - - name_buf = mem_heap_alloc(heap, len + 1); - ut_memcpy(name_buf, field, len); - name_buf[len] = '\0'; - - name = name_buf; + name = mem_heap_strdupl(heap, field, len); field = rec_get_nth_field(rec, 5, &len); mtype = mach_read_from_4(field); @@ -304,7 +294,6 @@ dict_load_fields( btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; - char* col_name; ulint pos_and_prefix_len; ulint prefix_len; rec_t* rec; @@ -383,11 +372,8 @@ dict_load_fields( field = rec_get_nth_field(rec, 4, &len); - col_name = mem_heap_alloc(heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - dict_mem_index_add_field(index, col_name, 0, prefix_len); + dict_mem_index_add_field(index, + mem_heap_strdupl(heap, field, len), 0, prefix_len); btr_pcur_move_to_next_user_rec(&pcur, &mtr); } @@ -492,10 +478,7 @@ dict_load_indexes( dict_table_get_first_index(sys_indexes), 4))->name)); field = rec_get_nth_field(rec, 4, &name_len); - - name_buf = mem_heap_alloc(heap, name_len + 1); - ut_memcpy(name_buf, field, name_len); - name_buf[name_len] = '\0'; + name_buf = mem_heap_strdupl(heap, field, name_len); field = rec_get_nth_field(rec, 5, &len); n_fields = mach_read_from_4(field); @@ -544,7 +527,7 @@ dict_load_indexes( if (is_sys_table && ((type & DICT_CLUSTERED) || ((table == dict_sys->sys_tables) - && (name_len == ut_strlen("ID_IND")) + && (name_len == (sizeof "ID_IND") - 1) && (0 == ut_memcmp(name_buf, (char*)"ID_IND", name_len))))) { @@ -593,7 +576,6 @@ dict_load_table( rec_t* rec; byte* field; ulint len; - char* buf; ulint space; ulint n_cols; ulint err; @@ -674,15 +656,13 @@ dict_load_table( if (table->type == DICT_TABLE_CLUSTER_MEMBER) { ut_error; - +#if 0 /* clustered tables have not been implemented yet */ field = rec_get_nth_field(rec, 6, &len); table->mix_id = mach_read_from_8(field); field = rec_get_nth_field(rec, 8, &len); - buf = mem_heap_alloc(heap, len); - ut_memcpy(buf, field, len); - - table->cluster_name = buf; + table->cluster_name = mem_heap_strdupl(heap, field, len); +#endif } if ((table->type == DICT_TABLE_CLUSTER) @@ -751,7 +731,6 @@ dict_load_table_on_id( byte* field; ulint len; dict_table_t* table; - char* name; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG @@ -814,13 +793,8 @@ dict_load_table_on_id( /* Now we get the table name from the record */ field = rec_get_nth_field(rec, 1, &len); - - name = mem_heap_alloc(heap, len + 1); - ut_memcpy(name, field, len); - name[len] = '\0'; - /* Load the table definition to memory */ - table = dict_load_table(name); + table = dict_load_table(mem_heap_strdupl(heap, field, len)); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -867,7 +841,6 @@ dict_load_foreign_cols( btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; - char* col_name; rec_t* rec; byte* field; ulint len; @@ -912,21 +885,13 @@ dict_load_foreign_cols( ut_a(i == mach_read_from_4(field)); field = rec_get_nth_field(rec, 4, &len); - - col_name = mem_heap_alloc(foreign->heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - foreign->foreign_col_names[i] = col_name; + foreign->foreign_col_names[i] = + mem_heap_strdupl(foreign->heap, field, len); field = rec_get_nth_field(rec, 5, &len); + foreign->referenced_col_names[i] = + mem_heap_strdupl(foreign->heap, field, len); - col_name = mem_heap_alloc(foreign->heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - foreign->referenced_col_names[i] = col_name; - btr_pcur_move_to_next_user_rec(&pcur, &mtr); } @@ -1023,23 +988,15 @@ dict_load_foreign( foreign->type = foreign->n_fields >> 24; foreign->n_fields = foreign->n_fields & 0xFFFFFF; - foreign->id = mem_heap_alloc(foreign->heap, ut_strlen(id) + 1); - - ut_memcpy(foreign->id, id, ut_strlen(id) + 1); + foreign->id = mem_heap_strdup(foreign->heap, id); field = rec_get_nth_field(rec, 3, &len); - - foreign->foreign_table_name = mem_heap_alloc(foreign->heap, 1 + len); - - ut_memcpy(foreign->foreign_table_name, field, len); - foreign->foreign_table_name[len] = '\0'; + foreign->foreign_table_name = + mem_heap_strdupl(foreign->heap, field, len); field = rec_get_nth_field(rec, 4, &len); - - foreign->referenced_table_name = mem_heap_alloc(foreign->heap, - 1 + len); - ut_memcpy(foreign->referenced_table_name, field, len); - foreign->referenced_table_name[len] = '\0'; + foreign->referenced_table_name = + mem_heap_strdupl(foreign->heap, field, len); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -1153,10 +1110,7 @@ loop: /* Now we get a foreign key constraint id */ field = rec_get_nth_field(rec, 1, &len); - - id = mem_heap_alloc(heap, len + 1); - ut_memcpy(id, field, len); - id[len] = '\0'; + id = mem_heap_strdupl(heap, field, len); btr_pcur_store_position(&pcur, &mtr); diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index f8c54022c9e..c4b393d292b 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -49,9 +49,7 @@ dict_mem_table_create( table->heap = heap; - str = mem_heap_alloc(heap, 1 + ut_strlen(name)); - - ut_strcpy(str, name); + str = mem_heap_strdup(heap, name); table->type = DICT_TABLE_ORDINARY; table->name = str; @@ -146,7 +144,6 @@ dict_mem_table_add_col( ulint len, /* in: length */ ulint prec) /* in: precision */ { - char* str; dict_col_t* col; dtype_t* type; @@ -154,15 +151,11 @@ dict_mem_table_add_col( ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); table->n_def++; - - col = dict_table_get_nth_col(table, table->n_def - 1); - - str = mem_heap_alloc(table->heap, 1 + ut_strlen(name)); - ut_strcpy(str, name); + col = dict_table_get_nth_col(table, table->n_def - 1); col->ind = table->n_def - 1; - col->name = str; + col->name = mem_heap_strdup(table->heap, name); col->table = table; col->ord_part = 0; @@ -188,7 +181,6 @@ dict_mem_index_create( ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ ulint n_fields) /* in: number of fields */ { - char* str; dict_index_t* index; mem_heap_t* heap; @@ -199,13 +191,9 @@ dict_mem_index_create( index->heap = heap; - str = mem_heap_alloc(heap, 1 + ut_strlen(index_name)); - - ut_strcpy(str, index_name); - index->type = type; index->space = space; - index->name = str; + index->name = mem_heap_strdup(heap, index_name); index->table_name = table_name; index->table = NULL; index->n_def = 0; diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c index 157d4e4f98d..4e16c36b056 100644 --- a/innobase/eval/eval0eval.c +++ b/innobase/eval/eval0eval.c @@ -667,7 +667,6 @@ eval_predefined( { que_node_t* arg1; lint int_val; - byte* str1; byte* data; int func; @@ -681,21 +680,63 @@ eval_predefined( } else if (func == PARS_TO_CHAR_TOKEN) { + /* Convert number to character string as a + signed decimal integer. */ + + ulint uint_val; + int int_len; + int_val = eval_node_get_int_val(arg1); - - data = eval_node_ensure_val_buf(func_node, 11); - sprintf((char*)data, "%10li", int_val); + /* Determine the length of the string. */ + + if (int_val == 0) { + int_len = 1; /* the number 0 occupies 1 byte */ + } else { + int_len = 0; + if (int_val < 0) { + uint_val = ((ulint) -int_val - 1) + 1; + int_len++; /* reserve space for minus sign */ + } else { + uint_val = (ulint) int_val; + } + for (; uint_val > 0; int_len++) { + uint_val /= 10; + } + } + + /* allocate the string */ + data = eval_node_ensure_val_buf(func_node, int_len + 1); - dfield_set_len(que_node_get_val(func_node), 10); + /* add terminating NUL character */ + data[int_len] = 0; + + /* convert the number */ + + if (int_val == 0) { + data[0] = '0'; + } else { + int tmp; + if (int_val < 0) { + data[0] = '-'; /* preceding minus sign */ + uint_val = ((ulint) -int_val - 1) + 1; + } else { + uint_val = (ulint) int_val; + } + for (tmp = int_len; uint_val > 0; uint_val /= 10) { + data[--tmp] = '0' + (uint_val % 10); + } + } + + dfield_set_len((dfield_t*) que_node_get_val(func_node), + int_len); return; } else if (func == PARS_TO_NUMBER_TOKEN) { - str1 = dfield_get_data(que_node_get_val(arg1)); - - int_val = atoi((char*)str1); + int_val = atoi((char*) + dfield_get_data(que_node_get_val(arg1))); } else if (func == PARS_SYSDATE_TOKEN) { int_val = (lint)ut_time(); diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 9f33013d2f9..1abb1b926f2 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -288,7 +288,6 @@ fil_node_create( { fil_node_t* node; fil_space_t* space; - char* name2; fil_system_t* system = fil_system; ut_a(system); @@ -299,11 +298,7 @@ fil_node_create( node = mem_alloc(sizeof(fil_node_t)); - name2 = mem_alloc(ut_strlen(name) + 1); - - ut_strcpy(name2, name); - - node->name = name2; + node->name = mem_strdup(name); node->open = FALSE; node->size = size; node->magic_n = FIL_NODE_MAGIC_N; @@ -626,7 +621,6 @@ fil_space_create( ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */ { fil_space_t* space; - char* name2; fil_system_t* system = fil_system; ut_a(system); @@ -642,11 +636,7 @@ fil_space_create( space = mem_alloc(sizeof(fil_space_t)); - name2 = mem_alloc(ut_strlen(name) + 1); - - ut_strcpy(name2, name); - - space->name = name2; + space->name = mem_strdup(name); space->id = id; space->purpose = purpose; space->size = 0; diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index f2c631d88cd..0af47a8ccc2 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -102,9 +102,10 @@ pages, as long as it obeys the access order rules. */ #define IBUF_POOL_SIZE_PER_MAX_SIZE 2 /* The insert buffer control structure */ -ibuf_t* ibuf = NULL; +ibuf_t* ibuf = NULL; -ulint ibuf_rnd = 986058871; +static +ulint ibuf_rnd = 986058871; ulint ibuf_flush_count = 0; @@ -113,9 +114,9 @@ ulint ibuf_flush_count = 0; #define IBUF_COUNT_N_PAGES 10000 /* Buffered entry counts for file pages, used in debugging */ -ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; +static ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; -ibool ibuf_counts_inited = FALSE; +static ibool ibuf_counts_inited = FALSE; /* The start address for an insert buffer bitmap page bitmap */ #define IBUF_BITMAP PAGE_DATA @@ -129,15 +130,18 @@ ibool ibuf_counts_inited = FALSE; /* Number of bits describing a single page */ #define IBUF_BITS_PER_PAGE 4 +#if IBUF_BITS_PER_PAGE % 2 +# error "IBUF_BITS_PER_PAGE must be an even number!" +#endif /* The mutex used to block pessimistic inserts to ibuf trees */ -mutex_t ibuf_pessimistic_insert_mutex; +static mutex_t ibuf_pessimistic_insert_mutex; /* The mutex protecting the insert buffer structs */ -mutex_t ibuf_mutex; +static mutex_t ibuf_mutex; /* The mutex protecting the insert buffer bitmaps */ -mutex_t ibuf_bitmap_mutex; +static mutex_t ibuf_bitmap_mutex; /* The area in pages from which contract looks for page numbers for merge */ #define IBUF_MERGE_AREA 8 @@ -2506,16 +2510,13 @@ ibuf_merge_or_delete_for_page( dtuple_t* entry; dtuple_t* search_tuple; rec_t* ibuf_rec; - ibool closed; buf_block_t* block; page_t* bitmap_page; ibuf_data_t* ibuf_data; - ibool success; ulint n_inserts; +#ifdef UNIV_IBUF_DEBUG ulint volume; - ulint old_bits; - ulint new_bits; - dulint max_trx_id; +#endif ibool corruption_noticed = FALSE; mtr_t mtr; char err_buf[500]; @@ -2605,12 +2606,14 @@ ibuf_merge_or_delete_for_page( } n_inserts = 0; +#ifdef UNIV_IBUF_DEBUG volume = 0; +#endif loop: mtr_start(&mtr); if (page) { - success = buf_page_get_known_nowait(RW_X_LATCH, page, + ibool success = buf_page_get_known_nowait(RW_X_LATCH, page, BUF_KEEP_OLD, IB__FILE__, __LINE__, &mtr); @@ -2667,7 +2670,7 @@ loop: keep the latch to the ibuf_rec page until the insertion is finished! */ - max_trx_id = page_get_max_trx_id( + dulint max_trx_id = page_get_max_trx_id( buf_frame_align(ibuf_rec)); page_update_max_trx_id(page, max_trx_id); @@ -2686,9 +2689,8 @@ loop: n_inserts++; /* Delete the record from ibuf */ - closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple, - &mtr); - if (closed) { + if (ibuf_delete_rec(space, page_no, &pcur, search_tuple, + &mtr)) { /* Deletion was pessimistic and mtr was committed: we start from the beginning again */ @@ -2717,10 +2719,9 @@ reset_bit: ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_BUFFERED, FALSE, &mtr); if (page) { - old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, - IBUF_BITMAP_FREE, &mtr); - new_bits = ibuf_index_page_calc_free(page); - + ulint old_bits = ibuf_bitmap_page_get_bits(bitmap_page, + page_no, IBUF_BITMAP_FREE, &mtr); + ulint new_bits = ibuf_index_page_calc_free(page); #ifdef UNIV_IBUF_DEBUG /* printf("Old bits %lu new bits %lu max size %lu\n", old_bits, new_bits, diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index c4e93bec738..b100ef5b583 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -294,6 +294,7 @@ dtuple_check_typed_no_assert( /*=========================*/ /* out: TRUE if ok */ dtuple_t* tuple); /* in: tuple */ +#ifdef UNIV_DEBUG /************************************************************** Validates the consistency of a tuple which must be complete, i.e, all fields must have been set. */ @@ -303,6 +304,7 @@ dtuple_validate( /*============*/ /* out: TRUE if ok */ dtuple_t* tuple); /* in: tuple */ +#endif /* UNIV_DEBUG */ /***************************************************************** Pretty prints a dfield value according to its data type. */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index def80d3f430..697a272ccd6 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -299,7 +299,7 @@ dtuple_get_data_size( ut_ad(tuple); ut_ad(dtuple_check_typed(tuple)); - ut_ad(tuple->magic_n = DATA_TUPLE_MAGIC_N); + ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N); n_fields = tuple->n_fields; @@ -355,7 +355,7 @@ dtuple_fold( ulint fold; ut_ad(tuple); - ut_ad(tuple->magic_n = DATA_TUPLE_MAGIC_N); + ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N); ut_ad(dtuple_check_typed(tuple)); fold = ut_fold_dulint(tree_id); diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 2e51fecdb8d..f0523c5f204 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -32,20 +32,21 @@ Get the database name length in a table name. */ ulint dict_get_db_name_len( /*=================*/ - /* out: database name length */ - char* name); /* in: table name in the form dbname '/' tablename */ + /* out: database name length */ + const char* name); /* in: table name in the form + dbname '/' tablename */ /************************************************************************* Accepts a specified string. Comparisons are case-insensitive. */ -char* +const char* dict_accept( /*========*/ - /* out: if string was accepted, the pointer - is moved after that, else ptr is returned */ - char* ptr, /* in: scan from this */ - const char* string,/* in: accept only this string as the next - non-whitespace string */ - ibool* success);/* out: TRUE if accepted */ + /* out: if string was accepted, the pointer + is moved after that, else ptr is returned */ + const char* ptr, /* in: scan from this */ + const char* string, /* in: accept only this string as the next + non-whitespace string */ + ibool* success);/* out: TRUE if accepted */ /************************************************************************ Decrements the count of open MySQL handles to a table. */ @@ -216,7 +217,7 @@ dict_foreign_parse_drop_constraints( dict_table_t* table, /* in: table */ ulint* n, /* out: number of constraints to drop */ - char*** constraints_to_drop); /* out: id's of the + const char*** constraints_to_drop); /* out: id's of the constraints to drop */ /************************************************************************** Returns a table object and memoryfixes it. NOTE! This is a high-level @@ -321,7 +322,7 @@ dict_table_print_by_name( /*=====================*/ char* name); /************************************************************************** -Sprintfs to a string info on foreign keys of a table. */ +Outputs info on foreign keys of a table. */ void dict_print_info_on_foreign_keys( diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 0fd1696b882..103d28cd130 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -526,12 +526,12 @@ extern lock_sys_t* lock_sys; #define LOCK_X 5 /* exclusive */ #define LOCK_AUTO_INC 6 /* locks the auto-inc counter of a table in an exclusive mode */ -#define LOCK_MODE_MASK 0xF /* mask used to extract mode from the +#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the type_mode field in a lock */ /* Lock types */ #define LOCK_TABLE 16 /* these type values should be so high that */ #define LOCK_REC 32 /* they can be ORed to the lock mode */ -#define LOCK_TYPE_MASK 0xF0 /* mask used to extract lock type from the +#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the type_mode field in a lock */ /* Waiting lock flag */ #define LOCK_WAIT 256 /* this wait bit should be so high that diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index 9fba0c46407..3295bc2d231 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -366,7 +366,6 @@ Writes a buffer to a log file group. */ void log_group_write_buf( /*================*/ - ulint type, /* in: LOG_FLUSH or LOG_RECOVER */ log_group_t* group, /* in: log group */ byte* buf, /* in: buffer */ ulint len, /* in: buffer len; must be divisible @@ -551,7 +550,7 @@ extern log_t* log_sys; highest bit is set to 1 if this is the first log block in a log flush write segment */ -#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000 +#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000UL /* mask used to get the highest bit in the preceding field */ #define LOG_BLOCK_HDR_DATA_LEN 4 /* number of bytes of log written to diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index 9ab3b2cd754..89e2a337c99 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -271,6 +271,59 @@ mem_realloc( ulint n, /* in: desired number of bytes */ char* file_name,/* in: file name where called */ ulint line); /* in: line where called */ + +/************************************************************************** +Duplicates a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdup( +/*=======*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str); /* in: string to be copied */ +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string. */ +UNIV_INLINE +char* +mem_strdupl( +/*========*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + ulint len); /* in: length of str, in bytes */ + +/************************************************************************** +Makes a NUL-terminated quoted copy of a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdupq( +/*========*/ + /* out, own: a quoted copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + char q); /* in: quote character */ + +/************************************************************************** +Duplicates a NUL-terminated string, allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdup( +/*============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str); /* in: string to be copied */ +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string, +allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdupl( +/*=============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str, /* in: string to be copied */ + ulint len); /* in: length of str, in bytes */ + #ifdef MEM_PERIODIC_CHECK /********************************************************************** Goes through the list of all allocated mem blocks, checks their magic diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index fb4cef49ec9..c250e6948ec 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -579,3 +579,99 @@ mem_realloc( return(mem_alloc_func(n, file_name, line)); } + +/************************************************************************** +Duplicates a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdup( +/*=======*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str) /* in: string to be copied */ +{ + ulint len = strlen(str) + 1; + return(memcpy(mem_alloc(len), str, len)); +} + +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string. */ +UNIV_INLINE +char* +mem_strdupl( +/*========*/ + /* out, own: a copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + ulint len) /* in: length of str, in bytes */ +{ + char* s = mem_alloc(len + 1); + s[len] = 0; + return(memcpy(s, str, len)); +} + +/************************************************************************** +Makes a NUL-terminated quoted copy of a NUL-terminated string. */ +UNIV_INLINE +char* +mem_strdupq( +/*========*/ + /* out, own: a quoted copy of the string, + must be deallocated with mem_free */ + const char* str, /* in: string to be copied */ + char q) /* in: quote character */ +{ + char* dst; + char* d; + const char* s = str; + int len = strlen(str) + 3; + /* calculate the number of quote characters in the string */ + while((s = strchr(s, q)) != NULL) { + s++; + len++; + } + /* allocate the quoted string, and copy it */ + d = dst = mem_alloc(len); + *d++ = q; + s = str; + while(*s) { + if ((*d++ = *s++) == q) { + *d++ = q; + } + } + *d++ = q; + *d++ = '\0'; + ut_ad(len == d - dst); + return(dst); +} + +/************************************************************************** +Duplicates a NUL-terminated string, allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdup( +/*============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str) /* in: string to be copied */ +{ + ulint len = strlen(str) + 1; + return(memcpy(mem_heap_alloc(heap, len), str, len)); +} + +/************************************************************************** +Makes a NUL-terminated copy of a nonterminated string, +allocated from a memory heap. */ +UNIV_INLINE +char* +mem_heap_strdupl( +/*=============*/ + /* out, own: a copy of the string */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str, /* in: string to be copied */ + ulint len) /* in: length of str, in bytes */ +{ + char* s = mem_heap_alloc(heap, len + 1); + s[len] = 0; + return(memcpy(s, str, len)); +} diff --git a/innobase/include/row0uins.h b/innobase/include/row0uins.h index df5e072487e..fc57881f691 100644 --- a/innobase/include/row0uins.h +++ b/innobase/include/row0uins.h @@ -26,8 +26,7 @@ ulint row_undo_ins( /*=========*/ /* out: DB_SUCCESS */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr); /* in: query thread */ + undo_node_t* node); /* in: row undo node */ #ifndef UNIV_NONINL diff --git a/innobase/include/row0undo.h b/innobase/include/row0undo.h index 5402f1d9236..d64a00dcb8f 100644 --- a/innobase/include/row0undo.h +++ b/innobase/include/row0undo.h @@ -41,8 +41,7 @@ row_undo_search_clust_to_pcur( /* out: TRUE if found; NOTE the node->pcur must be closed by the caller, regardless of the return value */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr); /* in: query thread */ + undo_node_t* node); /* in: row undo node */ /*************************************************************** Undoes a row operation in a table. This is a high-level function used in SQL execution graphs. */ diff --git a/innobase/include/ut0byte.h b/innobase/include/ut0byte.h index 4fb45221899..dd13b19b864 100644 --- a/innobase/include/ut0byte.h +++ b/innobase/include/ut0byte.h @@ -235,21 +235,19 @@ Copies a string to a memory location, setting characters to lower case. */ void ut_cpy_in_lower_case( /*=================*/ - char* dest, /* in: destination */ - char* source, /* in: source */ - ulint len); /* in: string length */ + char* dest, /* in: destination */ + const char* source, /* in: source */ + ulint len); /* in: string length */ /**************************************************************** Compares two strings when converted to lower case. */ int ut_cmp_in_lower_case( /*=================*/ - /* out: -1, 0, 1 if str1 < str2, str1 == str2, - str1 > str2, respectively */ - char* str1, /* in: string1 */ - char* str2, /* in: string2 */ - ulint len); /* in: length of both strings */ - + /* out: -1, 0, 1 if str1 < str2, str1 == str2, + str1 > str2, respectively */ + const char* str1, /* in: string1 */ + const char* str2); /* in: string2 */ #ifndef UNIV_NONINL #include "ut0byte.ic" diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 13ee8d5f5fa..bfda5ded40c 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -76,6 +76,39 @@ int ut_strcmp(void* str1, void* str2); /************************************************************************** +Determine the length of a string when it is quoted with ut_strcpyq(). */ +UNIV_INLINE +ulint +ut_strlenq( +/*=======*/ + /* out: length of the string when quoted */ + const char* str, /* in: null-terminated string */ + char q); /* in: the quote character */ + +/************************************************************************** +Make a quoted copy of a string. */ + +char* +ut_strcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src); /* in: null-terminated string */ + +/************************************************************************** +Make a quoted copy of a fixed-length string. */ + +char* +ut_memcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src, /* in: string to be quoted */ + ulint len); /* in: length of src */ + +/************************************************************************** Catenates two strings into newly allocated memory. The memory must be freed using mem_free. */ diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic index 1049aee8ecc..951d9538424 100644 --- a/innobase/include/ut0mem.ic +++ b/innobase/include/ut0mem.ic @@ -48,3 +48,23 @@ ut_strcmp(void* str1, void* str2) return(strcmp((char*)str1, (char*)str2)); } +/************************************************************************** +Determine the length of a string when it is quoted with ut_strcpyq(). */ +UNIV_INLINE +ulint +ut_strlenq( +/*=======*/ + /* out: length of the string when quoted */ + const char* str, /* in: null-terminated string */ + char q) /* in: the quote character */ +{ + ulint len; + + for (len = 0; *str; len++, str++) { + if (*str == q) { + len++; + } + } + + return(len); +} diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 8ec23b23dcd..637c9a68174 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -28,7 +28,9 @@ ut_sprintf( /*=======*/ char* buf, /* in/out: buffer where to print */ const char* format, /* in: format of prints */ - ...); /* in: arguments to be printed */ + ...) /* in: arguments to be printed */ + __attribute__((__format__ (__printf__, 2, 3))); + /************************************************************ Gets the high 32 bits in a ulint. That is makes a shift >> 32, but since there seem to be compiler bugs in both gcc and Visual C++, diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index c706ebceaec..812eea91d90 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -4592,7 +4592,6 @@ lock_clust_rec_modify_check_and_lock( dict_index_t* index, /* in: clustered index */ que_thr_t* thr) /* in: query thread */ { - trx_t* trx; ulint err; if (flags & BTR_NO_LOCKING_FLAG) { @@ -4602,8 +4601,6 @@ lock_clust_rec_modify_check_and_lock( ut_ad(index->type & DICT_CLUSTERED); - trx = thr_get_trx(thr); - lock_mutex_enter_kernel(); ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 8b4cbe034b9..3bc562eefb6 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -1015,7 +1015,7 @@ log_io_complete( return; } - if ((ulint)group & 0x1) { + if ((ulint)group & 0x1UL) { /* It was a checkpoint write */ group = (log_group_t*)((ulint)group - 1); @@ -1070,7 +1070,6 @@ static void log_group_file_header_flush( /*========================*/ - ulint type, /* in: LOG_FLUSH or LOG_RECOVER */ log_group_t* group, /* in: log group */ ulint nth_file, /* in: header to the nth file in the log file space */ @@ -1079,9 +1078,6 @@ log_group_file_header_flush( { byte* buf; ulint dest_offset; - - UT_NOT_USED(type); - #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ @@ -1136,7 +1132,6 @@ Writes a buffer to a log file group. */ void log_group_write_buf( /*================*/ - ulint type, /* in: LOG_FLUSH or LOG_RECOVER */ log_group_t* group, /* in: log group */ byte* buf, /* in: buffer */ ulint len, /* in: buffer len; must be divisible @@ -1177,7 +1172,7 @@ loop: && write_header) { /* We start to write a new log file instance in the group */ - log_group_file_header_flush(type, group, + log_group_file_header_flush(group, next_offset / group->file_size, start_lsn); } @@ -1396,7 +1391,7 @@ loop: /* Do the write to the log files */ while (group) { - log_group_write_buf(LOG_FLUSH, group, + log_group_write_buf(group, log_sys->buf + area_start, area_end - area_start, ut_dulint_align_down(log_sys->written_to_all_lsn, @@ -2137,11 +2132,11 @@ void log_archived_file_name_gen( /*=======================*/ char* buf, /* in: buffer where to write */ - ulint id, /* in: group id */ + ulint id __attribute__((unused)), + /* in: group id; + currently we only archive the first group */ ulint file_no)/* in: file number */ { - UT_NOT_USED(id); /* Currently we only archive the first group */ - sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, file_no); } diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 7f06fb587cc..1e88b677093 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -274,8 +274,7 @@ recv_truncate_group( len = ut_dulint_minus(end_lsn, start_lsn); - log_group_write_buf(LOG_RECOVER, group, log_sys->buf, len, - start_lsn, 0); + log_group_write_buf(group, log_sys->buf, len, start_lsn, 0); if (ut_dulint_cmp(end_lsn, finish_lsn) >= 0) { return; @@ -330,8 +329,7 @@ recv_copy_group( len = ut_dulint_minus(end_lsn, start_lsn); - log_group_write_buf(LOG_RECOVER, group, log_sys->buf, len, - start_lsn, 0); + log_group_write_buf(group, log_sys->buf, len, start_lsn, 0); if (ut_dulint_cmp(end_lsn, recovered_lsn) >= 0) { @@ -523,7 +521,7 @@ recv_find_max_checkpoint( "InnoDB: the problem may be that during an earlier attempt you managed\n" "InnoDB: to create the InnoDB data files, but log file creation failed.\n" "InnoDB: If that is the case, please refer to section 3.1 of\n" -"InnoDB: http://www.innodb.com/ibman.html\n"); +"InnoDB: http://www.innodb.com/ibman.php\n"); return(DB_ERROR); } diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c index 6de8d0c5f20..e1b9a762381 100644 --- a/innobase/mem/mem0mem.c +++ b/innobase/mem/mem0mem.c @@ -196,12 +196,7 @@ mem_heap_create_block( mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE); block->free_block = NULL; - - if (init_block != NULL) { - block->init_block = TRUE; - } else { - block->init_block = FALSE; - } + block->init_block = (init_block != NULL); ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); diff --git a/innobase/mtr/mtr0log.c b/innobase/mtr/mtr0log.c index 91ff588713d..e3ba531bcb8 100644 --- a/innobase/mtr/mtr0log.c +++ b/innobase/mtr/mtr0log.c @@ -95,6 +95,7 @@ mlog_parse_initial_log_record( } *type = (byte)((ulint)*ptr & ~MLOG_SINGLE_REC_FLAG); + ut_ad(*type <= MLOG_BIGGEST_TYPE); ptr++; @@ -171,13 +172,13 @@ mlog_parse_nbytes( } if (type == MLOG_1BYTE) { - if (val > 0xFF) { + if (val > 0xFFUL) { recv_sys->found_corrupt_log = TRUE; return(NULL); } } else if (type == MLOG_2BYTES) { - if (val > 0xFFFF) { + if (val > 0xFFFFUL) { recv_sys->found_corrupt_log = TRUE; return(NULL); @@ -234,7 +235,7 @@ mlog_write_ulint( mach_write_to_4(ptr, val); } - log_ptr = mlog_open(mtr, 30); + log_ptr = mlog_open(mtr, 11 + 2 + 5); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { @@ -276,7 +277,7 @@ mlog_write_dulint( mach_write_to_8(ptr, val); - log_ptr = mlog_open(mtr, 30); + log_ptr = mlog_open(mtr, 11 + 2 + 9); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index 890452cfceb..ce9e4327c18 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -479,6 +479,7 @@ page_cur_insert_rec_write_log( ulint i; ut_a(rec_size < UNIV_PAGE_SIZE); + ut_ad(rec_size == rec_get_size(insert_rec)); log_ptr = mlog_open(mtr, 30 + MLOG_BUF_MARGIN); @@ -630,8 +631,8 @@ page_cur_parse_insert_rec( return(NULL); } - extra_info_yes = end_seg_len & 0x1; - end_seg_len = end_seg_len / 2; + extra_info_yes = end_seg_len & 0x1UL; + end_seg_len >>= 1; if (end_seg_len >= UNIV_PAGE_SIZE) { recv_sys->found_corrupt_log = TRUE; @@ -694,7 +695,7 @@ page_cur_parse_insert_rec( mismatch_index = rec_get_size(cursor_rec) - end_seg_len; } - if (mismatch_index + end_seg_len < 1024) { + if (mismatch_index + end_seg_len < sizeof buf1) { buf = buf1; } else { buf = mem_alloc(mismatch_index + end_seg_len); @@ -726,7 +727,7 @@ page_cur_parse_insert_rec( page_cur_rec_insert(&cursor, buf + origin_offset, mtr); - if (mismatch_index + end_seg_len >= 1024) { + if (buf != buf1) { mem_free(buf); } diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 21adcdea635..7ebcb853448 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -1604,7 +1604,7 @@ page_validate( page_cur_set_before_first(page, &cur); for (;;) { - rec = (&cur)->rec; + rec = cur.rec; if (!page_rec_validate(rec)) { goto func_exit; @@ -1793,16 +1793,13 @@ page_find_rec_with_heap_no( ulint heap_no)/* in: heap number */ { page_cur_t cur; - rec_t* rec; page_cur_set_before_first(page, &cur); for (;;) { - rec = (&cur)->rec; - - if (rec_get_heap_no(rec) == heap_no) { + if (rec_get_heap_no(cur.rec) == heap_no) { - return(rec); + return(cur.rec); } if (page_cur_is_after_last(&cur)) { diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c index 4faf83b47a3..e9ed59e5c00 100644 --- a/innobase/pars/pars0opt.c +++ b/innobase/pars/pars0opt.c @@ -532,8 +532,8 @@ opt_search_plan_for_table( ulint best_goodness; ulint best_last_op = 0; /* remove warning */ ulint mix_id_pos; - que_node_t* index_plan[128]; - que_node_t* best_index_plan[128]; + que_node_t* index_plan[256]; + que_node_t* best_index_plan[256]; plan = sel_node_get_nth_plan(sel_node, i); diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index 5bbfca831f2..dda97d295fb 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -1745,8 +1745,6 @@ pars_sql( sym_node_t* sym_node; mem_heap_t* heap; que_t* graph; - ulint len; - char* buf; ut_ad(str); @@ -1758,12 +1756,8 @@ pars_sql( #endif /* UNIV_SYNC_DEBUG */ pars_sym_tab_global = sym_tab_create(heap); - len = ut_strlen(str); - buf = mem_heap_alloc(heap, len + 1); - ut_memcpy(buf, str, len + 1); - - pars_sym_tab_global->sql_string = buf; - pars_sym_tab_global->string_len = len; + pars_sym_tab_global->sql_string = mem_heap_strdup(heap, str); + pars_sym_tab_global->string_len = strlen(str); pars_sym_tab_global->next_char_pos = 0; yyparse(); diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 84968ea4e20..590d2b52e07 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -568,8 +568,7 @@ static void row_ins_foreign_report_add_err( /*===========================*/ - que_thr_t* thr, /* in: query thread whose run_node - is an insert node */ + trx_t* trx, /* in: transaction */ dict_foreign_t* foreign, /* in: foreign key constraint */ rec_t* rec, /* in: a record in the parent table: it does not match entry because we @@ -582,7 +581,7 @@ row_ins_foreign_report_add_err( mutex_enter(&dict_foreign_err_mutex); ut_sprintf_timestamp(buf); sprintf(buf + strlen(buf), " Transaction:\n"); - trx_print(buf + strlen(buf), thr_get_trx(thr)); + trx_print(buf + strlen(buf), trx); sprintf(buf + strlen(buf), "Foreign key constraint fails for table %.500s:\n", foreign->foreign_table_name); @@ -661,15 +660,10 @@ row_ins_foreign_check_on_constraint( the MySQL query cache for table */ ut_a(ut_strlen(table->name) < 998); - - ut_memcpy(table_name_buf, table->name, ut_strlen(table->name) + 1); - - ptr = table_name_buf; - - while (*ptr != '/') { - ptr++; - } + strcpy(table_name_buf, table->name); + ptr = strchr(table_name_buf, '/'); + ut_a(ptr); *ptr = '\0'; /* We call a function in ha_innodb.cc */ @@ -1200,11 +1194,6 @@ run_again: break; } -/* printf( -"FOREIGN: Found matching record from %s %s\n", - check_index->table_name, check_index->name); - rec_print(rec); -*/ if (check_ref) { err = DB_SUCCESS; @@ -1244,7 +1233,7 @@ run_again: if (check_ref) { err = DB_NO_REFERENCED_ROW; row_ins_foreign_report_add_err( - thr, foreign, rec, entry); + thr_get_trx(thr), foreign, rec, entry); } else { err = DB_SUCCESS; } @@ -1260,7 +1249,7 @@ next_rec: if (check_ref) { rec = btr_pcur_get_rec(&pcur); row_ins_foreign_report_add_err( - thr, foreign, rec, entry); + thr_get_trx(thr), foreign, rec, entry); err = DB_NO_REFERENCED_ROW; } else { err = DB_SUCCESS; @@ -2167,15 +2156,8 @@ row_ins_step( error_handling: trx->error_state = err; - if (err == DB_SUCCESS) { - /* Ok: do nothing */ - - } else if (err == DB_LOCK_WAIT) { - - return(NULL); - } else { - /* SQL error detected */ - + if (err != DB_SUCCESS) { + /* err == DB_LOCK_WAIT or SQL error detected */ return(NULL); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 693928dea3e..006cce74859 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -44,6 +44,51 @@ struct row_mysql_drop_struct{ UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list; ibool row_mysql_drop_list_inited = FALSE; +/* Magic table names for invoking various monitor threads */ +static const char S_innodb_monitor[] = "innodb_monitor"; +static const char S_innodb_lock_monitor[] = "innodb_lock_monitor"; +static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor"; +static const char S_innodb_table_monitor[] = "innodb_table_monitor"; +static const char S_innodb_mem_validate[] = "innodb_mem_validate"; + +/* Name suffix for recovered orphaned temporary tables */ +static const char S_recover_innodb_tmp_table[] = "_recover_innodb_tmp_table"; +/*********************************************************************** +Determine if the given name ends in the suffix reserved for recovered +orphaned temporary tables. */ +static +ibool +row_mysql_is_recovered_tmp_table( +/*=============================*/ + /* out: TRUE if table name ends in + the reserved suffix */ + const char* name) +{ + ulint namelen = strlen(name) + 1; + return(namelen >= sizeof S_recover_innodb_tmp_table + && !memcmp(name + namelen - + sizeof S_recover_innodb_tmp_table, + S_recover_innodb_tmp_table, + sizeof S_recover_innodb_tmp_table)); +} + +/*********************************************************************** +Determine if the given name is a name reserved for MySQL system tables. */ +static +ibool +row_mysql_is_system_table( +/*======================*/ + /* out: TRUE if name is a MySQL + system table name */ + const char* name) +{ + if (memcmp(name, "mysql/", 6)) { + return(FALSE); + } + return(0 == strcmp(name + 6, "host") + || 0 == strcmp(name + 6, "user") + || 0 == strcmp(name + 6, "db")); +} /*********************************************************************** Reads a MySQL format variable-length field (like VARCHAR) length and returns pointer to the field data. */ @@ -900,11 +945,7 @@ row_update_for_mysql( upd_node_t* node; dict_table_t* table = prebuilt->table; trx_t* trx = prebuilt->trx; -/* mem_heap_t* heap; - dtuple_t* search_tuple; - dtuple_t* row_tuple; - mtr_t mtr; */ - + ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); UT_NOT_USED(mysql_rec); @@ -1147,34 +1188,30 @@ row_mysql_recover_tmp_table( dict_table_t* table, /* in: table definition */ trx_t* trx) /* in: transaction handle */ { - char* ptr; - char old_name[1000]; - - ut_memcpy(old_name, table->name, ut_strlen(table->name) + 1); + const char* ptr = strstr(table->name, "/rsql"); - ptr = old_name; - - for (;;) { - if (ptr >= old_name + ut_strlen(table->name) - 6) { - trx_commit_for_mysql(trx); - - return(DB_ERROR); - } - - if (0 == ut_memcmp(ptr, (char*)"/rsql", 5)) { - ptr++; - *ptr = '#'; - - break; - } - - ptr++; + if (!ptr) { + /* table name does not begin with "/rsql" */ + trx_commit_for_mysql(trx); + return(DB_ERROR); + } + else { + int status; + int namelen = strlen(table->name); + char* old_name = mem_strdupl(table->name, namelen); + /* replace "rsql" with "#sql" */ + old_name[ptr - table->name + 1] = '#'; + /* remove "_recover_innodb_tmp_table" suffix */ + ut_ad(namelen > (int) sizeof S_recover_innodb_tmp_table); + ut_ad(!strcmp(old_name + namelen + 1 - + sizeof S_recover_innodb_tmp_table, + S_recover_innodb_tmp_table)); + old_name[namelen + 1 - sizeof S_recover_innodb_tmp_table] = 0; + status = row_rename_table_for_mysql(old_name, + table->name, trx); + mem_free(old_name); + return(status); } - - old_name[ut_strlen(table->name) - - ut_strlen("_recover_innodb_tmp_table")] = '\0'; - - return(row_rename_table_for_mysql(old_name, table->name, trx)); } /************************************************************************* @@ -1248,10 +1285,10 @@ row_mysql_unlock_data_dictionary( } /************************************************************************* -Does a table creation operation for MySQL. If the name of the created -table ends to characters INNODB_MONITOR, then this also starts -printing of monitor output by the master thread. */ - +Does a table creation operation for MySQL. If the name of the table +to be created is equal with one of the predefined magic table names, +then this also starts printing the corresponding monitor output by +the master thread. */ int row_create_table_for_mysql( /*=======================*/ @@ -1263,7 +1300,6 @@ row_create_table_for_mysql( mem_heap_t* heap; que_thr_t* thr; ulint namelen; - ulint keywordlen; ulint err; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1288,10 +1324,8 @@ row_create_table_for_mysql( trx->op_info = (char *) "creating table"; - if (0 == ut_strcmp(table->name, (char*)"mysql/host") - || 0 == ut_strcmp(table->name, (char*)"mysql/user") - || 0 == ut_strcmp(table->name, (char*)"mysql/db")) { - + if (row_mysql_is_system_table(table->name)) { + fprintf(stderr, "InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n" "InnoDB: MySQL system tables must be of the MyISAM type!\n", @@ -1304,13 +1338,7 @@ row_create_table_for_mysql( trx_start_if_not_started(trx); - namelen = ut_strlen(table->name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(table->name)) { /* MySQL prevents accessing of tables whose name begins with #sql, that is temporary tables. If mysqld crashes in @@ -1322,15 +1350,13 @@ row_create_table_for_mysql( return(row_mysql_recover_tmp_table(table, trx)); } - namelen = ut_strlen(table->name); - - keywordlen = ut_strlen((char *) "innodb_monitor"); + namelen = strlen(table->name) + 1; - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_monitor", keywordlen)) { + if (namelen == sizeof S_innodb_monitor + && !memcmp(table->name, S_innodb_monitor, + sizeof S_innodb_monitor)) { - /* Table name ends to characters innodb_monitor: + /* Table equals "innodb_monitor": start monitor prints */ srv_print_innodb_monitor = TRUE; @@ -1339,47 +1365,28 @@ row_create_table_for_mysql( of InnoDB monitor prints */ os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen((char *) "innodb_lock_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_lock_monitor", keywordlen)) { + } else if (namelen == sizeof S_innodb_lock_monitor + && !memcmp(table->name, S_innodb_lock_monitor, + sizeof S_innodb_lock_monitor)) { srv_print_innodb_monitor = TRUE; srv_print_innodb_lock_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen((char *) "innodb_tablespace_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_tablespace_monitor", - keywordlen)) { + } else if (namelen == sizeof S_innodb_tablespace_monitor + && !memcmp(table->name, S_innodb_tablespace_monitor, + sizeof S_innodb_tablespace_monitor)) { srv_print_innodb_tablespace_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen((char *) "innodb_table_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char *) "innodb_table_monitor", - keywordlen)) { + } else if (namelen == sizeof S_innodb_table_monitor + && !memcmp(table->name, S_innodb_table_monitor, + sizeof S_innodb_table_monitor)) { srv_print_innodb_table_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } - - keywordlen = ut_strlen("innodb_mem_validate"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(table->name + namelen - keywordlen, - (char*)"innodb_mem_validate", keywordlen)) { - + } else if (namelen == sizeof S_innodb_mem_validate + && !memcmp(table->name, S_innodb_mem_validate, + sizeof S_innodb_mem_validate)) { /* We define here a debugging feature intended for developers */ @@ -1468,8 +1475,6 @@ row_create_index_for_mysql( ind_node_t* node; mem_heap_t* heap; que_thr_t* thr; - ulint namelen; - ulint keywordlen; ulint err; ulint i, j; @@ -1482,7 +1487,7 @@ row_create_index_for_mysql( trx->op_info = (char *) "creating index"; /* Check that the same column does not appear twice in the index. - Starting from 4.0.14 InnoDB should be able to cope with that, but + Starting from 4.0.14, InnoDB should be able to cope with that, but safer not to allow them. */ for (i = 0; i < dict_index_get_n_fields(index); i++) { @@ -1508,14 +1513,7 @@ row_create_index_for_mysql( trx_start_if_not_started(trx); - namelen = ut_strlen(index->table_name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp( - index->table_name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(index->table_name)) { return(DB_SUCCESS); } @@ -1576,8 +1574,6 @@ row_table_add_foreign_constraints( char* name) /* in: table full name in the normalized form database_name/table_name */ { - ulint namelen; - ulint keywordlen; ulint err; #ifdef UNIV_SYNC_DEBUG @@ -1590,14 +1586,7 @@ row_table_add_foreign_constraints( trx_start_if_not_started(trx); - namelen = ut_strlen(name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp( - name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(name)) { return(DB_SUCCESS); } @@ -1781,9 +1770,7 @@ row_add_table_to_background_drop_list( drop = mem_alloc(sizeof(row_mysql_drop_t)); - drop->table_name = mem_alloc(1 + ut_strlen(table->name)); - - ut_memcpy(drop->table_name, table->name, 1 + ut_strlen(table->name)); + drop->table_name = mem_strdup(table->name); mutex_enter(&kernel_mutex); @@ -1817,83 +1804,15 @@ row_drop_table_for_mysql( que_thr_t* thr; que_t* graph; ulint err; - char* str1; - char* str2; - ulint len; ulint namelen; - ulint keywordlen; ibool locked_dictionary = FALSE; - char buf[10000]; - - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - ut_a(name != NULL); - - if (srv_created_new_raw) { - fprintf(stderr, - "InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" - "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); - - return(DB_ERROR); - } - - trx->op_info = (char *) "dropping table"; - - trx_start_if_not_started(trx); - - namelen = ut_strlen(name); - keywordlen = ut_strlen((char *) "innodb_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_monitor", keywordlen)) { - - /* Table name ends to characters innodb_monitor: - stop monitor prints */ - - srv_print_innodb_monitor = FALSE; - srv_print_innodb_lock_monitor = FALSE; - } - - keywordlen = ut_strlen((char *) "innodb_lock_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_lock_monitor", - keywordlen)) { - - srv_print_innodb_monitor = FALSE; - srv_print_innodb_lock_monitor = FALSE; - } - - keywordlen = ut_strlen((char *) "innodb_tablespace_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_tablespace_monitor", - keywordlen)) { - - srv_print_innodb_tablespace_monitor = FALSE; - } - - keywordlen = ut_strlen((char *) "innodb_table_monitor"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(name + namelen - keywordlen, - (char *) "innodb_table_monitor", - keywordlen)) { - - srv_print_innodb_table_monitor = FALSE; - } - + char* quoted_name; + char* sql; /* We use the private SQL parser of Innobase to generate the query graphs needed in deleting the dictionary data from system tables in Innobase. Deleting a row from SYS_INDEXES table also frees the file segments of the B-tree associated with the index. */ - - str1 = (char *) + static const char str1[] = "PROCEDURE DROP_TABLE_PROC () IS\n" "table_name CHAR;\n" "sys_foreign_id CHAR;\n" @@ -1902,10 +1821,9 @@ row_drop_table_for_mysql( "foreign_id CHAR;\n" "found INT;\n" "BEGIN\n" - "table_name := '"; - - str2 = (char *) - "';\n" + "table_name := "; + static const char str2[] = + ";\n" "SELECT ID INTO table_id\n" "FROM SYS_TABLES\n" "WHERE NAME = table_name;\n" @@ -1955,14 +1873,60 @@ row_drop_table_for_mysql( "COMMIT WORK;\n" "END;\n"; - len = ut_strlen(str1); + ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + ut_a(name != NULL); + + if (srv_created_new_raw) { + fputs( + "InnoDB: A new raw disk partition was initialized or\n" + "InnoDB: innodb_force_recovery is on: we do not allow\n" + "InnoDB: database modifications by the user. Shut down\n" + "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); + + return(DB_ERROR); + } + + trx->op_info = (char *) "dropping table"; + + trx_start_if_not_started(trx); + + namelen = strlen(name) + 1; - ut_memcpy(buf, str1, len); - ut_memcpy(buf + len, name, ut_strlen(name)); + if (namelen == sizeof S_innodb_monitor + && !memcmp(name, S_innodb_monitor, + sizeof S_innodb_monitor)) { + + /* Table name equals "innodb_monitor": + stop monitor prints */ + + srv_print_innodb_monitor = FALSE; + srv_print_innodb_lock_monitor = FALSE; + } else if (namelen == sizeof S_innodb_lock_monitor + && !memcmp(name, S_innodb_lock_monitor, + sizeof S_innodb_lock_monitor)) { - len += ut_strlen(name); + srv_print_innodb_monitor = FALSE; + srv_print_innodb_lock_monitor = FALSE; + } else if (namelen == sizeof S_innodb_tablespace_monitor + && !memcmp(name, S_innodb_tablespace_monitor, + sizeof S_innodb_tablespace_monitor)) { + + srv_print_innodb_tablespace_monitor = FALSE; + } else if (namelen == sizeof S_innodb_table_monitor + && !memcmp(name, S_innodb_table_monitor, + sizeof S_innodb_table_monitor)) { + + srv_print_innodb_table_monitor = FALSE; + } - ut_memcpy(buf + len, str2, ut_strlen(str2) + 1); + quoted_name = mem_strdupq(name, '\''); + namelen = strlen(quoted_name); + sql = mem_alloc((sizeof str1) + (sizeof str2) - 2 + 1 + namelen); + memcpy(sql, str1, (sizeof str1) - 1); + memcpy(sql + (sizeof str1) - 1, quoted_name, namelen); + memcpy(sql + (sizeof str1) - 1 + namelen, str2, sizeof str2); /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ @@ -1981,9 +1945,10 @@ row_drop_table_for_mysql( ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - graph = pars_sql(buf); + graph = pars_sql(sql); ut_a(graph); + mem_free(sql); graph->trx = trx; trx->graph = NULL; @@ -2144,9 +2109,10 @@ loop: row_mysql_lock_data_dictionary(trx); while ((table_name = dict_get_first_table_name_in_db(name))) { - ut_a(memcmp(table_name, name, strlen(name)) == 0); + ut_a(strcmp(table_name, name) == 0); table = dict_table_get_low(table_name); +fprintf(stderr, "drop %p:%s\n", table, table_name); ut_a(table); @@ -2197,19 +2163,11 @@ static ibool row_is_mysql_tmp_table_name( /*========================*/ - /* out: TRUE if temporary table */ - char* name) /* in: table name in the form 'database/tablename' */ + /* out: TRUE if temporary table */ + const char* name) /* in: table name in the form + 'database/tablename' */ { - ulint i; - - for (i = 0; i + 5 <= ut_strlen(name); i++) { - if (ut_memcmp(name + i, (char*)"/#sql", 5) == 0) { - - return(TRUE); - } - } - - return(FALSE); + return(strstr(name, "/#sql") != NULL); } /************************************************************************* @@ -2227,39 +2185,112 @@ row_rename_table_for_mysql( que_thr_t* thr; que_t* graph = NULL; ulint err; - char* str1; - char* str2; - char* str3; + /* We use the private SQL parser of Innobase to generate the + query graphs needed in deleting the dictionary data from system + tables in Innobase. Deleting a row from SYS_INDEXES table also + frees the file segments of the B-tree associated with the index. */ + static const char str1[] = + "PROCEDURE RENAME_TABLE_PROC () IS\n" + "new_table_name CHAR;\n" + "old_table_name CHAR;\n" + "gen_constr_prefix CHAR;\n" + "new_db_name CHAR;\n" + "foreign_id CHAR;\n" + "new_foreign_id CHAR;\n" + "old_db_name_len INT;\n" + "old_t_name_len INT;\n" + "new_db_name_len INT;\n" + "id_len INT;\n" + "found INT;\n" + "BEGIN\n" + "new_table_name := '"; + static const char str2[] = + "';\nold_table_name := '"; + static const char str3[] = + "';\n" + "UPDATE SYS_TABLES SET NAME = new_table_name\n" + "WHERE NAME = old_table_name;\n"; + static const char str4a1[] = /* drop some constraints of tmp tables */ + "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '"; + static const char str4a2[] = "';\n" + "DELETE FROM SYS_FOREIGN WHERE ID = '"; + static const char str4a3[] = "';\n"; + static const char str4b[] = /* rename all constraints */ + "found := 1;\n" + "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" + "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" + "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" + "old_t_name_len := LENGTH(old_table_name);\n" + "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = old_table_name;\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE\n" + " UPDATE SYS_FOREIGN\n" + " SET FOR_NAME = new_table_name\n" + " WHERE ID = foreign_id;\n" + " id_len := LENGTH(foreign_id);\n" + " IF (INSTR(foreign_id, '/') > 0) THEN\n" + " IF (INSTR(foreign_id,\n" + " gen_constr_prefix) > 0)\n" + " THEN\n" + " new_foreign_id :=\n" + " CONCAT(new_table_name,\n" + " SUBSTR(foreign_id, old_t_name_len,\n" + " id_len - old_t_name_len));\n" + " ELSE\n" + " new_foreign_id :=\n" + " CONCAT(new_db_name,\n" + " SUBSTR(foreign_id,\n" + " old_db_name_len,\n" + " id_len - old_db_name_len));\n" + " END IF;\n" + " UPDATE SYS_FOREIGN\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " UPDATE SYS_FOREIGN_COLS\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " END IF;\n" + " END IF;\n" + "END LOOP;\n" + "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" + "WHERE REF_NAME = old_table_name;\n"; + static const char str5[] = + "END;\n"; + mem_heap_t* heap = NULL; - char** constraints_to_drop = NULL; + const char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; ibool recovering_temp_table = FALSE; - ulint namelen; - ulint keywordlen; ulint len; ulint i; - char* db_name; - char buf[10000]; + /* length of database name; 0 if not renaming to a temporary table */ + ulint db_name_len; + char* sql; + char* sqlend; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(old_name != NULL); ut_a(new_name != NULL); if (srv_created_new_raw || srv_force_recovery) { - fprintf(stderr, + fputs( "InnoDB: A new raw disk partition was initialized or\n" "InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n"); + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); trx_commit_for_mysql(trx); return(DB_ERROR); } - if (0 == ut_strcmp(new_name, (char*)"mysql/host") - || 0 == ut_strcmp(new_name, (char*)"mysql/user") - || 0 == ut_strcmp(new_name, (char*)"mysql/db")) { + if (row_mysql_is_system_table(new_name)) { fprintf(stderr, "InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n" @@ -2273,21 +2304,15 @@ row_rename_table_for_mysql( trx->op_info = (char *) "renaming table"; trx_start_if_not_started(trx); - namelen = ut_strlen(new_name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp(new_name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { + if (row_mysql_is_recovered_tmp_table(new_name)) { recovering_temp_table = TRUE; - } + } /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ - if (!recovering_temp_table) { + if (!recovering_temp_table) { row_mysql_lock_data_dictionary(trx); } @@ -2299,26 +2324,12 @@ row_rename_table_for_mysql( goto funct_exit; } - str1 = (char *) - "PROCEDURE RENAME_TABLE_PROC () IS\n" - "new_table_name CHAR;\n" - "old_table_name CHAR;\n" - "gen_constr_prefix CHAR;\n" - "new_db_name CHAR;\n" - "foreign_id CHAR;\n" - "new_foreign_id CHAR;\n" - "old_db_name_len INT;\n" - "old_t_name_len INT;\n" - "new_db_name_len INT;\n" - "id_len INT;\n" - "found INT;\n" - "BEGIN\n" - "new_table_name :='"; - - str2 = (char *) - "';\nold_table_name := '"; + /* calculate the length of the SQL string */ + 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)) { + db_name_len = dict_get_db_name_len(old_name) + 1; /* MySQL is doing an ALTER TABLE command and it renames the original table to a temporary table name. We want to preserve @@ -2336,31 +2347,57 @@ row_rename_table_for_mysql( goto funct_exit; } - - str3 = mem_heap_alloc(heap, - 1000 + 1000 * n_constraints_to_drop); - *str3 = '\0'; - sprintf(str3, - "';\n" - "UPDATE SYS_TABLES SET NAME = new_table_name\n" - "WHERE NAME = old_table_name;\n"); - - db_name = mem_heap_alloc(heap, 1 + dict_get_db_name_len( - old_name)); - ut_memcpy(db_name, old_name, dict_get_db_name_len(old_name)); - db_name[dict_get_db_name_len(old_name)] = '\0'; + /* reserve space for all database names */ + len += 2 * n_constraints_to_drop + * (ut_strlenq(old_name, '\'') + - ut_strlenq(old_name + db_name_len, '\'')); + + for (i = 0; i < n_constraints_to_drop; i++) { + ulint addlen + = 2 * ut_strlenq(constraints_to_drop[i], '\'') + + ((sizeof str4a1) + (sizeof str4a2) + + (sizeof str4a3) - 3); + if (!strchr(constraints_to_drop[i], '/')) { + addlen *= 2; + } + len += addlen; + } + } else { + db_name_len = 0; + len += (sizeof str4b) - 1; + } + + sql = sqlend = mem_alloc(len + 1); + memcpy(sql, str1, (sizeof str1) - 1); + sqlend += (sizeof str1) - 1; + sqlend = ut_strcpyq(sqlend, '\'', new_name); + memcpy(sqlend, str2, (sizeof str2) - 1); + sqlend += (sizeof str2) - 1; + sqlend = ut_strcpyq(sqlend, '\'', old_name); + memcpy(sqlend, str3, (sizeof str3) - 1); + sqlend += (sizeof str3) - 1; + + if (db_name_len) { /* Internally, old format < 4.0.18 constraints have as the constraint id <number>_<number>, while new format constraints have <databasename>/<constraintname>. */ for (i = 0; i < n_constraints_to_drop; i++) { - - sprintf(str3 + strlen(str3), - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s/%s';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '%s/%s';\n", - db_name, constraints_to_drop[i], - db_name, constraints_to_drop[i]); + memcpy(sqlend, str4a1, (sizeof str4a1) - 1); + sqlend += (sizeof str4a1) - 1; + sqlend = ut_memcpyq(sqlend, '\'', + old_name, db_name_len); + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a2, (sizeof str4a2) - 1); + sqlend += (sizeof str4a2) - 1; + sqlend = ut_memcpyq(sqlend, '\'', + old_name, db_name_len); + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a3, (sizeof str4a3) - 1); + sqlend += (sizeof str4a3) - 1; if (!strchr(constraints_to_drop[i], '/')) { /* If this happens to be an old format @@ -2368,90 +2405,33 @@ row_rename_table_for_mysql( format constraints contain '/', it does no harm to run these DELETEs anyway. */ - sprintf(str3 + strlen(str3), - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '%s';\n", - constraints_to_drop[i], - constraints_to_drop[i]); + memcpy(sqlend, str4a1, (sizeof str4a1) - 1); + sqlend += (sizeof str4a1) - 1; + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a2, (sizeof str4a2) - 1); + sqlend += (sizeof str4a2) - 1; + sqlend = ut_strcpyq(sqlend, '\'', + constraints_to_drop[i]); + memcpy(sqlend, str4a3, (sizeof str4a3) - 1); + sqlend += (sizeof str4a3) - 1; } } + } + else { + memcpy(sqlend, str4b, (sizeof str4b) - 1); + sqlend += (sizeof str4b) - 1; + } - sprintf(str3 + strlen(str3), - "END;\n"); + memcpy(sqlend, str5, sizeof str5); + sqlend += sizeof str5; - ut_a(strlen(str3) < 1000 + 1000 * n_constraints_to_drop); - } else { - str3 = (char*) - "';\n" - "UPDATE SYS_TABLES SET NAME = new_table_name\n" - "WHERE NAME = old_table_name;\n" - "found := 1;\n" - "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" - "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" - "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" - "old_t_name_len := LENGTH(old_table_name);\n" - "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = old_table_name;\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE\n" - " UPDATE SYS_FOREIGN\n" - " SET FOR_NAME = new_table_name\n" - " WHERE ID = foreign_id;\n" - " id_len := LENGTH(foreign_id);\n" - " IF (INSTR(foreign_id, '/') > 0) THEN\n" - " IF (INSTR(foreign_id,\n" - " gen_constr_prefix) > 0)\n" - " THEN\n" - " new_foreign_id :=\n" - " CONCAT(new_table_name,\n" - " SUBSTR(foreign_id, old_t_name_len,\n" - " id_len - old_t_name_len));\n" - " ELSE\n" - " new_foreign_id :=\n" - " CONCAT(new_db_name,\n" - " SUBSTR(foreign_id,\n" - " old_db_name_len,\n" - " id_len - old_db_name_len));\n" - " END IF;\n" - " UPDATE SYS_FOREIGN\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " UPDATE SYS_FOREIGN_COLS\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " END IF;\n" - " END IF;\n" - "END LOOP;\n" - "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" - "WHERE REF_NAME = old_table_name;\n" - "END;\n"; - } - - len = ut_strlen(str1); - - ut_memcpy(buf, str1, len); - - ut_memcpy(buf + len, new_name, ut_strlen(new_name)); - - len += ut_strlen(new_name); - - ut_memcpy(buf + len, str2, ut_strlen(str2)); - - len += ut_strlen(str2); - - ut_memcpy(buf + len, old_name, ut_strlen(old_name)); - - len += ut_strlen(old_name); - - ut_memcpy(buf + len, str3, ut_strlen(str3) + 1); - - graph = pars_sql(buf); + ut_a(sqlend == sql + len + 1); + + graph = pars_sql(sql); ut_a(graph); + mem_free(sql); graph->trx = trx; trx->graph = NULL; @@ -2609,7 +2589,7 @@ loop: template */ rec = buf + mach_read_from_4(buf); - + if (prev_entry != NULL) { matched_fields = 0; matched_bytes = 0; diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index bd3742ad589..a2c60079e66 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -91,7 +91,6 @@ row_purge_remove_clust_if_poss_low( /* out: TRUE if success, or if not found, or if modified after the delete marking */ purge_node_t* node, /* in: row purge node */ - que_thr_t* thr, /* in: query thread */ ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { dict_index_t* index; @@ -101,8 +100,6 @@ row_purge_remove_clust_if_poss_low( ulint err; mtr_t mtr; - UT_NOT_USED(thr); - index = dict_table_get_first_index(node->table); pcur = &(node->pcur); @@ -156,23 +153,20 @@ static void row_purge_remove_clust_if_poss( /*===========================*/ - purge_node_t* node, /* in: row purge node */ - que_thr_t* thr) /* in: query thread */ + purge_node_t* node) /* in: row purge node */ { ibool success; ulint n_tries = 0; /* printf("Purge: Removing clustered record\n"); */ - success = row_purge_remove_clust_if_poss_low(node, thr, - BTR_MODIFY_LEAF); + success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_LEAF); if (success) { return; } retry: - success = row_purge_remove_clust_if_poss_low(node, thr, - BTR_MODIFY_TREE); + success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database and restart with more file space */ @@ -196,7 +190,6 @@ row_purge_remove_sec_if_poss_low( /*=============================*/ /* out: TRUE if success or if not found */ purge_node_t* node, /* in: row purge node */ - que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry, /* in: index entry */ ulint mode) /* in: latch mode BTR_MODIFY_LEAF or @@ -211,8 +204,6 @@ row_purge_remove_sec_if_poss_low( mtr_t mtr; mtr_t* mtr_vers; - UT_NOT_USED(thr); - log_free_check(); mtr_start(&mtr); @@ -284,7 +275,6 @@ void row_purge_remove_sec_if_poss( /*=========================*/ purge_node_t* node, /* in: row purge node */ - que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */ { @@ -293,14 +283,14 @@ row_purge_remove_sec_if_poss( /* printf("Purge: Removing secondary record\n"); */ - success = row_purge_remove_sec_if_poss_low(node, thr, index, entry, + success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_LEAF); if (success) { return; } retry: - success = row_purge_remove_sec_if_poss_low(node, thr, index, entry, + success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database @@ -324,14 +314,13 @@ static void row_purge_del_mark( /*===============*/ - purge_node_t* node, /* in: row purge node */ - que_thr_t* thr) /* in: query thread */ + purge_node_t* node) /* in: row purge node */ { mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; - ut_ad(node && thr); + ut_ad(node); heap = mem_heap_create(1024); @@ -341,14 +330,14 @@ row_purge_del_mark( /* Build the index entry */ entry = row_build_index_entry(node->row, index, heap); - row_purge_remove_sec_if_poss(node, thr, index, entry); + row_purge_remove_sec_if_poss(node, index, entry); node->index = dict_table_get_next_index(node->index); } mem_heap_free(heap); - row_purge_remove_clust_if_poss(node, thr); + row_purge_remove_clust_if_poss(node); } /*************************************************************** @@ -358,8 +347,7 @@ static void row_purge_upd_exist_or_extern( /*==========================*/ - purge_node_t* node, /* in: row purge node */ - que_thr_t* thr) /* in: query thread */ + purge_node_t* node) /* in: row purge node */ { mem_heap_t* heap; dtuple_t* entry; @@ -375,7 +363,7 @@ row_purge_upd_exist_or_extern( ulint i; mtr_t mtr; - ut_ad(node && thr); + ut_ad(node); if (node->rec_type == TRX_UNDO_UPD_DEL_REC) { @@ -392,7 +380,7 @@ row_purge_upd_exist_or_extern( /* Build the older version of the index entry */ entry = row_build_index_entry(node->row, index, heap); - row_purge_remove_sec_if_poss(node, thr, index, entry); + row_purge_remove_sec_if_poss(node, index, entry); } node->index = dict_table_get_next_index(node->index); @@ -519,7 +507,7 @@ row_purge_parse_undo_rec( mutex_enter(&(dict_sys->mutex)); - node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); + node->table = dict_table_get_on_id_low(table_id, trx); mutex_exit(&(dict_sys->mutex)); @@ -609,12 +597,12 @@ row_purge( dict_table_get_first_index(node->table)); if (node->rec_type == TRX_UNDO_DEL_MARK_REC) { - row_purge_del_mark(node, thr); + row_purge_del_mark(node); } else if (updated_extern || node->rec_type == TRX_UNDO_UPD_EXIST_REC) { - row_purge_upd_exist_or_extern(node, thr); + row_purge_upd_exist_or_extern(node); } if (node->found_clust) { diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 6820cb5bccd..327a47f4009 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -568,7 +568,7 @@ row_get_clust_rec( found = row_search_on_row_ref(&pcur, mode, table, ref, mtr); - clust_rec = btr_pcur_get_rec(&pcur); + clust_rec = found ? btr_pcur_get_rec(&pcur) : NULL; mem_heap_free(heap); @@ -576,11 +576,6 @@ row_get_clust_rec( *clust_index = dict_table_get_first_index(table); - if (!found) { - - return(NULL); - } - return(clust_rec); } diff --git a/innobase/row/row0uins.c b/innobase/row/row0uins.c index fff67dcd627..df2cdb6359d 100644 --- a/innobase/row/row0uins.c +++ b/innobase/row/row0uins.c @@ -37,8 +37,7 @@ ulint row_undo_ins_remove_clust_rec( /*==========================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ - undo_node_t* node, /* in: undo node */ - que_thr_t* thr) /* in: query thread */ + undo_node_t* node) /* in: undo node */ { btr_cur_t* btr_cur; ibool success; @@ -46,8 +45,6 @@ row_undo_ins_remove_clust_rec( ulint n_tries = 0; mtr_t mtr; - UT_NOT_USED(thr); - mtr_start(&mtr); success = btr_pcur_restore_position(BTR_MODIFY_LEAF, &(node->pcur), @@ -126,8 +123,7 @@ row_undo_ins_remove_sec_low( depending on whether we wish optimistic or pessimistic descent down the index tree */ dict_index_t* index, /* in: index */ - dtuple_t* entry, /* in: index entry to remove */ - que_thr_t* thr) /* in: query thread */ + dtuple_t* entry) /* in: index entry to remove */ { btr_pcur_t pcur; btr_cur_t* btr_cur; @@ -136,8 +132,6 @@ row_undo_ins_remove_sec_low( ulint err; mtr_t mtr; - UT_NOT_USED(thr); - log_free_check(); mtr_start(&mtr); @@ -148,15 +142,6 @@ row_undo_ins_remove_sec_low( if (!found) { /* Not found */ - /* FIXME: remove printfs in the final version */ - - /* printf( - "--UNDO INS: Record not found from page %lu index %s\n", - buf_frame_get_page_no(btr_cur_get_rec(btr_cur)), - index->name); */ - - /* ibuf_print(); */ - btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -192,15 +177,14 @@ row_undo_ins_remove_sec( /*====================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ dict_index_t* index, /* in: index */ - dtuple_t* entry, /* in: index entry to insert */ - que_thr_t* thr) /* in: query thread */ + dtuple_t* entry) /* in: index entry to insert */ { ulint err; ulint n_tries = 0; /* Try first optimistic descent to the B-tree */ - err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry, thr); + err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry); if (err == DB_SUCCESS) { @@ -209,7 +193,7 @@ row_undo_ins_remove_sec( /* Try then pessimistic descent to the B-tree */ retry: - err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry, thr); + err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database @@ -233,8 +217,7 @@ static void row_undo_ins_parse_undo_rec( /*========================*/ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr __attribute__((unused))) /* in: query thread */ + undo_node_t* node) /* in: row undo node */ { dict_index_t* clust_index; byte* ptr; @@ -244,7 +227,7 @@ row_undo_ins_parse_undo_rec( ulint dummy; ibool dummy_extern; - ut_ad(node && thr); + ut_ad(node); ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy, &dummy_extern, &undo_no, &table_id); @@ -273,22 +256,21 @@ ulint row_undo_ins( /*=========*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr) /* in: query thread */ + undo_node_t* node) /* in: row undo node */ { dtuple_t* entry; ibool found; ulint err; - - ut_ad(node && thr); + + ut_ad(node); ut_ad(node->state == UNDO_NODE_INSERT); - row_undo_ins_parse_undo_rec(node, thr); + row_undo_ins_parse_undo_rec(node); if (node->table == NULL) { found = FALSE; } else { - found = row_undo_search_clust_to_pcur(node, thr); + found = row_undo_search_clust_to_pcur(node); } if (!found) { @@ -303,7 +285,7 @@ row_undo_ins( while (node->index != NULL) { entry = row_build_index_entry(node->row, node->index, node->heap); - err = row_undo_ins_remove_sec(node->index, entry, thr); + err = row_undo_ins_remove_sec(node->index, entry); if (err != DB_SUCCESS) { @@ -313,7 +295,7 @@ row_undo_ins( node->index = dict_table_get_next_index(node->index); } - err = row_undo_ins_remove_clust_rec(node, thr); + err = row_undo_ins_remove_clust_rec(node); return(err); } diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 34c3aaf9142..5dde60029f0 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -95,14 +95,11 @@ row_undo_mod_clust_low( ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { big_rec_t* dummy_big_rec; - dict_index_t* index; btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; ibool success; - index = dict_table_get_first_index(node->table); - pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); @@ -317,13 +314,6 @@ row_undo_mod_del_mark_or_remove_sec_low( if (!found) { /* Not found */ - /* FIXME: remove printfs in the final version */ - - /* printf( - "--UNDO MOD: Record not found from page %lu index %s\n", - buf_frame_get_page_no(btr_cur_get_rec(btr_cur)), - index->name); */ - btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -421,7 +411,6 @@ row_undo_mod_del_unmark_sec_and_undo_update( DB_OUT_OF_FILE_SPACE */ ulint mode, /* in: search mode: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ - undo_node_t* node, /* in: row undo node */ que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */ @@ -430,15 +419,12 @@ row_undo_mod_del_unmark_sec_and_undo_update( btr_pcur_t pcur; btr_cur_t* btr_cur; upd_t* update; - rec_t* rec; ulint err = DB_SUCCESS; ibool found; big_rec_t* dummy_big_rec; mtr_t mtr; char err_buf[1000]; - UT_NOT_USED(node); - log_free_check(); mtr_start(&mtr); @@ -463,15 +449,13 @@ row_undo_mod_del_unmark_sec_and_undo_update( } else { btr_cur = btr_pcur_get_btr_cur(&pcur); - rec = btr_cur_get_rec(btr_cur); - err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, FALSE, thr, &mtr); ut_a(err == DB_SUCCESS); heap = mem_heap_create(100); update = row_upd_build_sec_rec_difference_binary(index, entry, - rec, heap); + btr_cur_get_rec(btr_cur), heap); if (upd_get_n_fields(update) == 0) { /* Do nothing */ @@ -566,11 +550,11 @@ row_undo_mod_del_mark_sec( err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_LEAF, - node, thr, index, entry); + thr, index, entry); if (err == DB_FAIL) { err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_TREE, - node, thr, index, entry); + thr, index, entry); } if (err != DB_SUCCESS) { @@ -649,12 +633,12 @@ row_undo_mod_upd_exist_sec( node->update, NULL); err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_LEAF, - node, thr, index, entry); + thr, index, entry); if (err == DB_FAIL) { err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_TREE, - node, thr, index, entry); + thr, index, entry); } if (err != DB_SUCCESS) { @@ -745,7 +729,7 @@ row_undo_mod( if (node->table == NULL) { found = FALSE; } else { - found = row_undo_search_clust_to_pcur(node, thr); + found = row_undo_search_clust_to_pcur(node); } if (!found) { diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index 78cfe70c260..a3ea42e1425 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -144,8 +144,7 @@ row_undo_search_clust_to_pcur( /* out: TRUE if found; NOTE the node->pcur must be closed by the caller, regardless of the return value */ - undo_node_t* node, /* in: row undo node */ - que_thr_t* thr) /* in: query thread */ + undo_node_t* node) /* in: row undo node */ { dict_index_t* clust_index; ibool found; @@ -153,8 +152,6 @@ row_undo_search_clust_to_pcur( ibool ret; rec_t* rec; - UT_NOT_USED(thr); - mtr_start(&mtr); clust_index = dict_table_get_first_index(node->table); @@ -269,7 +266,7 @@ row_undo( if (node->state == UNDO_NODE_INSERT) { - err = row_undo_ins(node, thr); + err = row_undo_ins(node); node->state = UNDO_NODE_FETCH_NEXT; } else { diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 0be0ab957af..e4eb3a7f556 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1576,7 +1576,8 @@ ulint srv_lock_timeout_and_monitor_thread( /*================================*/ /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by + void* arg __attribute__((unused))) + /* in: a dummy parameter required by os_thread_create */ { srv_slot_t* slot; @@ -1593,7 +1594,6 @@ srv_lock_timeout_and_monitor_thread( printf("Lock timeout thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); #endif - UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); last_table_monitor_time = time(NULL); last_monitor_time = time(NULL); @@ -1738,7 +1738,7 @@ exit_func: os_thread_exit(NULL); #ifndef __WIN__ - return(NULL); + return(NULL); #else return(0); #endif @@ -1756,12 +1756,12 @@ ulint srv_error_monitor_thread( /*=====================*/ /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by + void* arg __attribute__((unused))) + /* in: a dummy parameter required by os_thread_create */ { ulint cnt = 0; - UT_NOT_USED(arg); #ifdef UNIV_DEBUG_THREAD_CREATION printf("Error monitor thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); @@ -1801,7 +1801,7 @@ loop: os_thread_exit(NULL); #ifndef __WIN__ - return(NULL); + return(NULL); #else return(0); #endif @@ -1857,7 +1857,8 @@ ulint srv_master_thread( /*==============*/ /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by + void* arg __attribute__((unused))) + /* in: a dummy parameter required by os_thread_create */ { os_event_t event; @@ -1876,8 +1877,6 @@ srv_master_thread( ibool skip_sleep = FALSE; ulint i; - UT_NOT_USED(arg); - #ifdef UNIV_DEBUG_THREAD_CREATION printf("Master thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 0491aed29f5..d505c8779dc 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -159,17 +159,13 @@ srv_parse_data_file_paths_and_sizes( str++; } - if (strlen(str) >= ut_strlen(":autoextend") - && 0 == ut_memcmp(str, (char*)":autoextend", - ut_strlen(":autoextend"))) { + if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { - str += ut_strlen(":autoextend"); + str += (sizeof ":autoextend") - 1; - if (strlen(str) >= ut_strlen(":max:") - && 0 == ut_memcmp(str, (char*)":max:", - ut_strlen(":max:"))) { + if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { - str += ut_strlen(":max:"); + str += (sizeof ":max:") - 1; size = strtoul(str, &endp, 10); @@ -198,10 +194,7 @@ srv_parse_data_file_paths_and_sizes( str += 3; } - if (strlen(str) >= 3 - && *str == 'r' - && *(str + 1) == 'a' - && *(str + 2) == 'w') { + if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; } @@ -263,19 +256,15 @@ srv_parse_data_file_paths_and_sizes( (*data_file_names)[i] = path; (*data_file_sizes)[i] = size; - if (strlen(str) >= ut_strlen(":autoextend") - && 0 == ut_memcmp(str, (char*)":autoextend", - ut_strlen(":autoextend"))) { + if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) { *is_auto_extending = TRUE; - str += ut_strlen(":autoextend"); + str += (sizeof ":autoextend") - 1; - if (strlen(str) >= ut_strlen(":max:") - && 0 == ut_memcmp(str, (char*)":max:", - ut_strlen(":max:"))) { + if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { - str += ut_strlen(":max:"); + str += (sizeof ":max:") - 1; size = strtoul(str, &endp, 10); @@ -309,10 +298,7 @@ srv_parse_data_file_paths_and_sizes( (*data_file_is_raw_partition)[i] = SRV_NEW_RAW; } - if (strlen(str) >= 3 - && *str == 'r' - && *(str + 1) == 'a' - && *(str + 2) == 'w') { + if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; if ((*data_file_is_raw_partition)[i] == 0) { @@ -454,12 +440,10 @@ srv_normalize_path_for_win( char* str __attribute__((unused))) /* in/out: null-terminated character string */ { #ifdef __WIN__ - ulint i; + for (; *str; str++) { - for (i = 0; i < ut_strlen(str); i++) { - - if (str[i] == '/') { - str[i] = '\\'; + if (*str == '/') { + *str = '\\'; } } #endif @@ -528,8 +512,6 @@ ulint open_or_create_log_file( /*====================*/ /* out: DB_SUCCESS or error code */ - ibool create_new_db, /* in: TRUE if we should create a - new database */ ibool* log_file_created, /* out: TRUE if new log file created */ ibool log_file_has_been_opened,/* in: TRUE if a log file has been @@ -544,8 +526,6 @@ open_or_create_log_file( ulint size_high; char name[10000]; - UT_NOT_USED(create_new_db); - *log_file_created = FALSE; srv_normalize_path_for_win(srv_log_group_home_dirs[k]); @@ -1149,8 +1129,7 @@ NetWare. */ for (i = 0; i < srv_n_log_files; i++) { - err = open_or_create_log_file(create_new_db, - &log_file_created, + err = open_or_create_log_file(&log_file_created, log_opened, k, i); if (err != DB_SUCCESS) { diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index c00c6f0c862..82d101304d5 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -301,8 +301,7 @@ trx_savepoint_for_mysql( savep = mem_alloc(sizeof(trx_named_savept_t)); - savep->name = mem_alloc(1 + ut_strlen(savepoint_name)); - ut_memcpy(savep->name, savepoint_name, 1 + ut_strlen(savepoint_name)); + savep->name = mem_strdup(savepoint_name); savep->savept = trx_savept_take(trx); diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index d4c14a5509c..493a5e94e79 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -576,8 +576,7 @@ trx_sys_update_mysql_binlog_offset( MLOG_4BYTES, mtr); } - if (0 != ut_memcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, - file_name, 1 + ut_strlen(file_name))) { + if (0 != strcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, file_name)) { mlog_write_string((byte*) (sys_header + field + TRX_SYS_MYSQL_LOG_NAME), diff --git a/innobase/ut/ut0byte.c b/innobase/ut/ut0byte.c index 02bdf2065ee..4ec7e0f405e 100644 --- a/innobase/ut/ut0byte.c +++ b/innobase/ut/ut0byte.c @@ -36,9 +36,9 @@ Copies a string to a memory location, setting characters to lower case. */ void ut_cpy_in_lower_case( /*=================*/ - char* dest, /* in: destination */ - char* source,/* in: source */ - ulint len) /* in: string length */ + char* dest, /* in: destination */ + const char* source, /* in: source */ + ulint len) /* in: string length */ { ulint i; @@ -53,23 +53,27 @@ Compares two strings when converted to lower case. */ int ut_cmp_in_lower_case( /*=================*/ - /* out: -1, 0, 1 if str1 < str2, str1 == str2, - str1 > str2, respectively */ - char* str1, /* in: string1 */ - char* str2, /* in: string2 */ - ulint len) /* in: length of both strings */ + /* out: -1, 0, 1 if str1 < str2, str1 == str2, + str1 > str2, respectively */ + const char* str1, /* in: string1 */ + const char* str2) /* in: string2 */ { - ulint i; - - for (i = 0; i < len; i++) { - if (tolower(str1[i]) < tolower(str2[i])) { - return(-1); - } - - if (tolower(str1[i]) > tolower(str2[i])) { - return(1); - } - } + for (;;) { + int c1, c2; + if (!*str1) { + return(*str2 ? -1 : 0); + } else if (!*str2) { + return 1; + } + c1 = tolower(*str1++); + c2 = tolower(*str2++); + if (c1 < c2) { + return(-1); + } + if (c1 > c2) { + return(1); + } + } - return(0); + return(0); } diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index f5d207d8bba..1fcaf9febbe 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -106,7 +106,7 @@ ut_malloc_low( /* Make an intentional seg fault so that we get a stack trace */ - printf("%lu\n", *ut_mem_null_ptr); + if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; } if (set_to_zero) { @@ -195,6 +195,49 @@ ut_free_all_mem(void) } /************************************************************************** +Make a quoted copy of a string. */ + +char* +ut_strcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src) /* in: null-terminated string */ +{ + while (*src) { + if ((*dest++ = *src++) == q) { + *dest++ = q; + } + } + + return(dest); +} + +/************************************************************************** +Make a quoted copy of a fixed-length string. */ + +char* +ut_memcpyq( +/*=======*/ + /* out: pointer to end of dest */ + char* dest, /* in: output buffer */ + char q, /* in: the quote character */ + const char* src, /* in: string to be quoted */ + ulint len) /* in: length of src */ +{ + const char* srcend = src + len; + + while (src < srcend) { + if ((*dest++ = *src++) == q) { + *dest++ = q; + } + } + + return(dest); +} + +/************************************************************************** Catenates two strings into newly allocated memory. The memory must be freed using mem_free. */ @@ -215,9 +258,7 @@ ut_str_catenate( str = mem_alloc(len1 + len2 + 1); ut_memcpy(str, str1, len1); - ut_memcpy(str + len1, str2, len2); - - str[len1 + len2] = '\0'; + ut_memcpy(str + len1, str2, len2 + 1); return(str); } |