Commit 025ddfea authored by unknown's avatar unknown

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