1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-13 20:03:16 +03:00

branches/zip: Merge revisions 583:634 from trunk.

This commit is contained in:
marko
2006-06-13 20:23:26 +00:00
parent af445f4b77
commit 7f8cb7aab9
42 changed files with 2782 additions and 1812 deletions

View File

@@ -77,7 +77,7 @@ EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr
include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \ include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \
include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \ include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \
include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \ include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \
cmakelists.txt CMakeLists.txt
noinst_LIBRARIES = libinnobase.a noinst_LIBRARIES = libinnobase.a
libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \ libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \

View File

@@ -618,9 +618,9 @@ btr_page_get_father_for_rec(
buf_page_print(buf_frame_align(node_ptr), 0); buf_page_print(buf_frame_align(node_ptr), 0);
fputs("InnoDB: Corruption of an index tree: table ", stderr); fputs("InnoDB: Corruption of an index tree: table ", stderr);
ut_print_name(stderr, NULL, index->table_name); ut_print_name(stderr, NULL, TRUE, index->table_name);
fputs(", index ", stderr); fputs(", index ", stderr);
ut_print_name(stderr, NULL, index->name); ut_print_name(stderr, NULL, FALSE, index->name);
fprintf(stderr, ",\n" fprintf(stderr, ",\n"
"InnoDB: father ptr page no %lu, child page no %lu\n", "InnoDB: father ptr page no %lu, child page no %lu\n",
(ulong) (ulong)

View File

@@ -488,7 +488,7 @@ retry_page_get:
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
} }
return; goto func_exit;
} }
/* Insert to the insert buffer did not succeed: /* Insert to the insert buffer did not succeed:
@@ -626,6 +626,7 @@ retry_page_get:
|| mode != PAGE_CUR_LE); || mode != PAGE_CUR_LE);
} }
func_exit:
if (has_search_latch) { if (has_search_latch) {
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);

View File

@@ -293,3 +293,36 @@ dtype_print(
fprintf(stderr, " len %lu prec %lu", (ulong) len, (ulong) type->prec); fprintf(stderr, " len %lu prec %lu", (ulong) len, (ulong) type->prec);
} }
/***************************************************************************
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information. */
ulint
dtype_get_max_size(
/*===============*/
/* out: maximum size (ULINT_MAX for
unbounded types) */
const dtype_t* type) /* in: type */
{
switch (type->mtype) {
case DATA_SYS:
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
case DATA_MYSQL:
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
case DATA_VARMYSQL:
return(type->len);
case DATA_BLOB:
return(ULINT_MAX);
default:
ut_error;
}
return(ULINT_MAX);
}

View File

@@ -1212,7 +1212,7 @@ dict_create_or_check_foreign_constraint_tables(void)
"CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);\n" "CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);\n"
"COMMIT WORK;\n" "COMMIT WORK;\n"
"END;\n" "END;\n"
, trx); , FALSE, trx);
if (error != DB_SUCCESS) { if (error != DB_SUCCESS) {
fprintf(stderr, "InnoDB: error %lu in creation\n", fprintf(stderr, "InnoDB: error %lu in creation\n",
@@ -1261,7 +1261,7 @@ dict_foreign_eval_sql(
ulint error; ulint error;
FILE* ef = dict_foreign_err_file; FILE* ef = dict_foreign_err_file;
error = que_eval_sql(info, sql, trx); error = que_eval_sql(info, sql, FALSE, trx);
if (error == DB_DUPLICATE_KEY) { if (error == DB_DUPLICATE_KEY) {
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
@@ -1269,9 +1269,9 @@ dict_foreign_eval_sql(
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs(" Error in foreign key constraint creation for table ", fputs(" Error in foreign key constraint creation for table ",
ef); ef);
ut_print_name(ef, trx, table->name); ut_print_name(ef, trx, TRUE, table->name);
fputs(".\nA foreign key constraint of name ", ef); fputs(".\nA foreign key constraint of name ", ef);
ut_print_name(ef, trx, foreign->id); ut_print_name(ef, trx, FALSE, foreign->id);
fputs("\nalready exists." fputs("\nalready exists."
" (Note that internally InnoDB adds 'databasename/'\n" " (Note that internally InnoDB adds 'databasename/'\n"
"in front of the user-defined constraint name).\n", "in front of the user-defined constraint name).\n",
@@ -1299,7 +1299,7 @@ dict_foreign_eval_sql(
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs(" Internal error in foreign key constraint creation" fputs(" Internal error in foreign key constraint creation"
" for table ", ef); " for table ", ef);
ut_print_name(ef, trx, table->name); ut_print_name(ef, trx, TRUE, table->name);
fputs(".\n" fputs(".\n"
"See the MySQL .err log in the datadir for more information.\n", ef); "See the MySQL .err log in the datadir for more information.\n", ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);

View File

@@ -26,6 +26,9 @@ Created 1/8/1996 Heikki Tuuri
#include "pars0sym.h" #include "pars0sym.h"
#include "que0que.h" #include "que0que.h"
#include "rem0cmp.h" #include "rem0cmp.h"
#ifndef UNIV_HOTBACKUP
# include "m_ctype.h" /* my_isspace() */
#endif /* !UNIV_HOTBACKUP */
dict_sys_t* dict_sys = NULL; /* the dictionary system */ dict_sys_t* dict_sys = NULL; /* the dictionary system */
@@ -55,6 +58,42 @@ static char dict_ibfk[] = "_ibfk_";
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
/********************************************************************** /**********************************************************************
Converts an identifier to a table name.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
extern
void
innobase_convert_from_table_id(
/*===========================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes;
should be at least 5 * strlen(to) + 1 */
/**********************************************************************
Converts an identifier to UTF-8.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
extern
void
innobase_convert_from_id(
/*=====================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes;
should be at least 3 * strlen(to) + 1 */
/**********************************************************************
Removes the filename encoding of a table or database name.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
extern
void
innobase_convert_from_filename(
/*===========================*/
char* s); /* in: identifier; out: decoded identifier */
/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively. Compares NUL-terminated UTF-8 strings case insensitively.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
@@ -77,6 +116,17 @@ void
innobase_casedn_str( innobase_casedn_str(
/*================*/ /*================*/
char* a); /* in/out: string to put in lower case */ char* a); /* in/out: string to put in lower case */
/**************************************************************************
Determines the connection character set.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
struct charset_info_st*
innobase_get_charset(
/*=================*/
/* out: connection character set */
void* mysql_thd); /* in: MySQL thread handle */
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
/************************************************************************** /**************************************************************************
@@ -227,7 +277,7 @@ dict_tables_have_same_db(
/************************************************************************ /************************************************************************
Return the end of table name where we have removed dbname and '/'. */ Return the end of table name where we have removed dbname and '/'. */
static
const char* const char*
dict_remove_db_name( dict_remove_db_name(
/*================*/ /*================*/
@@ -853,6 +903,7 @@ dict_table_add_to_cache(
ulint fold; ulint fold;
ulint id_fold; ulint id_fold;
ulint i; ulint i;
ulint row_len;
dict_table_add_system_columns(table); dict_table_add_system_columns(table);
@@ -861,6 +912,24 @@ dict_table_add_to_cache(
fold = ut_fold_string(table->name); fold = ut_fold_string(table->name);
id_fold = ut_fold_dulint(table->id); id_fold = ut_fold_dulint(table->id);
row_len = 0;
for (i = 0; i < table->n_def; i++) {
ulint col_len = dtype_get_max_size(
dict_col_get_type(dict_table_get_nth_col(table, i)));
/* If we have a single unbounded field, or several gigantic
fields, mark the maximum row size as ULINT_MAX. */
if (ut_max(col_len, row_len) >= (ULINT_MAX / 2)) {
row_len = ULINT_MAX;
break;
}
row_len += col_len;
}
table->max_row_size = row_len;
/* Look for a table with the same name: error if such exists */ /* Look for a table with the same name: error if such exists */
{ {
dict_table_t* table2; dict_table_t* table2;
@@ -1403,6 +1472,7 @@ dict_index_add_to_cache(
ut_ad(mem_heap_validate(index->heap)); ut_ad(mem_heap_validate(index->heap));
#ifdef UNIV_DEBUG
{ {
dict_index_t* index2; dict_index_t* index2;
index2 = UT_LIST_GET_FIRST(table->indexes); index2 = UT_LIST_GET_FIRST(table->indexes);
@@ -1412,10 +1482,11 @@ dict_index_add_to_cache(
index2 = UT_LIST_GET_NEXT(indexes, index2); index2 = UT_LIST_GET_NEXT(indexes, index2);
} }
ut_a(!dict_index_is_clust(index)
|| UT_LIST_GET_LEN(table->indexes) == 0);
} }
#endif /* UNIV_DEBUG */
ut_a(!dict_index_is_clust(index)
|| UT_LIST_GET_LEN(table->indexes) == 0);
success = dict_index_find_cols(table, index); success = dict_index_find_cols(table, index);
@@ -2048,6 +2119,7 @@ dict_foreign_find(
return(NULL); return(NULL);
} }
#ifndef UNIV_HOTBACKUP
/************************************************************************* /*************************************************************************
Tries to find an index whose first fields are the columns in the array, Tries to find an index whose first fields are the columns in the array,
in the same order. */ in the same order. */
@@ -2064,7 +2136,6 @@ dict_foreign_find_index(
ibool check_charsets)/* in: whether to check charsets. ibool check_charsets)/* in: whether to check charsets.
only has an effect if types_idx != NULL. */ only has an effect if types_idx != NULL. */
{ {
#ifndef UNIV_HOTBACKUP
dict_index_t* index; dict_index_t* index;
const char* col_name; const char* col_name;
ulint i; ulint i;
@@ -2110,13 +2181,6 @@ dict_foreign_find_index(
} }
return(NULL); return(NULL);
#else /* UNIV_HOTBACKUP */
/* This function depends on MySQL code that is not included in
InnoDB Hot Backup builds. Besides, this function should never
be called in InnoDB Hot Backup. */
ut_error;
return(NULL);
#endif /* UNIV_HOTBACKUP */
} }
/************************************************************************** /**************************************************************************
@@ -2152,7 +2216,7 @@ dict_foreign_error_report(
putc('\n', file); putc('\n', file);
if (fk->foreign_index) { if (fk->foreign_index) {
fputs("The index in the foreign key in table is ", file); fputs("The index in the foreign key in table is ", file);
ut_print_name(file, NULL, fk->foreign_index->name); ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
fputs( fputs(
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" "\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
"for correct foreign key definition.\n", "for correct foreign key definition.\n",
@@ -2315,12 +2379,13 @@ dict_scan_to(
/************************************************************************* /*************************************************************************
Accepts a specified string. Comparisons are case-insensitive. */ Accepts a specified string. Comparisons are case-insensitive. */
static
const 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 */
struct charset_info_st* cs,/* in: the character set of ptr */
const 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 */
@@ -2331,7 +2396,7 @@ dict_accept(
*success = FALSE; *success = FALSE;
while (isspace(*ptr)) { while (my_isspace(cs, *ptr)) {
ptr++; ptr++;
} }
@@ -2356,12 +2421,15 @@ const char*
dict_scan_id( dict_scan_id(
/*=========*/ /*=========*/
/* out: scanned to */ /* out: scanned to */
struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */ const char* ptr, /* in: scanned to */
mem_heap_t* heap, /* in: heap where to allocate the id mem_heap_t* heap, /* in: heap where to allocate the id
(NULL=id will not be allocated, but it (NULL=id will not be allocated, but it
will point to string near ptr) */ will point to string near ptr) */
const char** id, /* out,own: the id; NULL if no id was const char** id, /* out,own: the id; NULL if no id was
scannable */ scannable */
ibool table_id,/* in: TRUE=convert the allocated id
as a table name; FALSE=convert to UTF-8 */
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
@@ -2370,13 +2438,12 @@ dict_scan_id(
char quote = '\0'; char quote = '\0';
ulint len = 0; ulint len = 0;
const char* s; const char* s;
char* d; char* str;
ulint id_len; char* dst;
byte* b;
*id = NULL; *id = NULL;
while (isspace(*ptr)) { while (my_isspace(cs, *ptr)) {
ptr++; ptr++;
} }
@@ -2407,7 +2474,7 @@ dict_scan_id(
len++; len++;
} }
} else { } else {
while (!isspace(*ptr) && *ptr != '(' && *ptr != ')' while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')'
&& (accept_also_dot || *ptr != '.') && (accept_also_dot || *ptr != '.')
&& *ptr != ',' && *ptr != '\0') { && *ptr != ',' && *ptr != '\0') {
@@ -2417,43 +2484,50 @@ dict_scan_id(
len = ptr - s; len = ptr - s;
} }
if (quote && heap) { if (UNIV_UNLIKELY(!heap)) {
*id = d = mem_heap_alloc(heap, len + 1); /* no heap given: id will point to source string */
*id = s;
return(ptr);
}
if (quote) {
char* d;
str = d = mem_heap_alloc(heap, len + 1);
while (len--) { while (len--) {
if ((*d++ = *s++) == quote) { if ((*d++ = *s++) == quote) {
s++; s++;
} }
} }
*d++ = 0; *d++ = 0;
ut_a(*s == quote); len = d - str;
ut_a(s + 1 == ptr); ut_ad(*s == quote);
} else if (heap) { ut_ad(s + 1 == ptr);
*id = mem_heap_strdupl(heap, s, len);
} else { } else {
/* no heap given: id will point to source string */ str = mem_heap_strdupl(heap, s, len);
*id = s;
} }
if (heap && !quote) { if (!table_id) {
/* EMS MySQL Manager sometimes adds characters 0xA0 (in convert_id:
latin1, a 'non-breakable space') to the end of a table name. /* Convert the identifier from connection character set
But isspace(0xA0) is not true, which confuses our foreign key to UTF-8. */
parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2 len = 3 * len + 1;
and 0xA0 are at the end of the string. *id = dst = mem_heap_alloc(heap, len);
TODO: we should lex the string using thd->charset_info, and innobase_convert_from_id(dst, str, len);
my_isspace(). Only after that, convert id names to UTF-8. */ } else if (!strncmp(str, srv_mysql50_table_name_prefix,
sizeof srv_mysql50_table_name_prefix)) {
/* This is a pre-5.1 table name
containing chars other than [A-Za-z0-9].
Discard the prefix and use raw UTF-8 encoding. */
str += sizeof srv_mysql50_table_name_prefix;
len -= sizeof srv_mysql50_table_name_prefix;
goto convert_id;
} else {
/* Encode using filename-safe characters. */
len = 5 * len + 1;
*id = dst = mem_heap_alloc(heap, len);
b = (byte*)(*id); innobase_convert_from_table_id(dst, str, len);
id_len = strlen((char*) b);
if (id_len >= 3 && b[id_len - 1] == 0xA0
&& b[id_len - 2] == 0xC2) {
/* Strip the 2 last bytes */
b[id_len - 2] = '\0';
}
} }
return(ptr); return(ptr);
@@ -2466,6 +2540,7 @@ const char*
dict_scan_col( dict_scan_col(
/*==========*/ /*==========*/
/* out: scanned to */ /* out: scanned to */
struct charset_info_st* cs,/* in: the character set of ptr */
const 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 */
@@ -2474,13 +2549,12 @@ dict_scan_col(
const char** name) /* out,own: the column name; NULL if no name const char** name) /* out,own: the column name; NULL if no name
was scannable */ was scannable */
{ {
#ifndef UNIV_HOTBACKUP
dict_col_t* col; dict_col_t* col;
ulint i; ulint i;
*success = FALSE; *success = FALSE;
ptr = dict_scan_id(ptr, heap, name, TRUE); ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE);
if (*name == NULL) { if (*name == NULL) {
@@ -2508,13 +2582,6 @@ dict_scan_col(
} }
return(ptr); return(ptr);
#else /* UNIV_HOTBACKUP */
/* This function depends on MySQL code that is not included in
InnoDB Hot Backup builds. Besides, this function should never
be called in InnoDB Hot Backup. */
ut_error;
return(NULL);
#endif /* UNIV_HOTBACKUP */
} }
/************************************************************************* /*************************************************************************
@@ -2524,6 +2591,7 @@ const char*
dict_scan_table_name( dict_scan_table_name(
/*=================*/ /*=================*/
/* out: scanned to */ /* out: scanned to */
struct charset_info_st* cs,/* in: the character set of ptr */
const 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 */
const char* name, /* in: foreign key table name */ const char* name, /* in: foreign key table name */
@@ -2532,7 +2600,6 @@ dict_scan_table_name(
const char** ref_name)/* out,own: the table name; const char** ref_name)/* out,own: the table name;
NULL if no name was scannable */ NULL if no name was scannable */
{ {
#ifndef UNIV_HOTBACKUP
const char* database_name = NULL; const char* database_name = NULL;
ulint database_name_len = 0; ulint database_name_len = 0;
const char* table_name = NULL; const char* table_name = NULL;
@@ -2543,7 +2610,7 @@ dict_scan_table_name(
*success = FALSE; *success = FALSE;
*table = NULL; *table = NULL;
ptr = dict_scan_id(ptr, heap, &scan_name, FALSE); ptr = dict_scan_id(cs, ptr, heap, &scan_name, TRUE, FALSE);
if (scan_name == NULL) { if (scan_name == NULL) {
@@ -2558,7 +2625,7 @@ dict_scan_table_name(
database_name = scan_name; database_name = scan_name;
database_name_len = strlen(database_name); database_name_len = strlen(database_name);
ptr = dict_scan_id(ptr, heap, &table_name, FALSE); ptr = dict_scan_id(cs, ptr, heap, &table_name, TRUE, FALSE);
if (table_name == NULL) { if (table_name == NULL) {
@@ -2614,13 +2681,6 @@ dict_scan_table_name(
*table = dict_table_get_low(ref); *table = dict_table_get_low(ref);
return(ptr); return(ptr);
#else /* UNIV_HOTBACKUP */
/* This function depends on MySQL code that is not included in
InnoDB Hot Backup builds. Besides, this function should never
be called in InnoDB Hot Backup. */
ut_error;
return(NULL);
#endif /* UNIV_HOTBACKUP */
} }
/************************************************************************* /*************************************************************************
@@ -2630,6 +2690,7 @@ const char*
dict_skip_word( dict_skip_word(
/*===========*/ /*===========*/
/* out: scanned to */ /* out: scanned to */
struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */ const char* ptr, /* in: scanned to */
ibool* success)/* out: TRUE if success, FALSE if just spaces ibool* success)/* out: TRUE if success, FALSE if just spaces
left in string or a syntax error */ left in string or a syntax error */
@@ -2638,7 +2699,7 @@ dict_skip_word(
*success = FALSE; *success = FALSE;
ptr = dict_scan_id(ptr, NULL, &start, TRUE); ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE);
if (start) { if (start) {
*success = TRUE; *success = TRUE;
@@ -2816,6 +2877,7 @@ 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 */
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
struct charset_info_st* cs,/* in: the character set of sql_string */
const char* sql_string, const char* sql_string,
/* in: CREATE TABLE or ALTER TABLE statement /* in: CREATE TABLE or ALTER TABLE statement
where foreign keys are declared like: where foreign keys are declared like:
@@ -2873,14 +2935,14 @@ dict_create_foreign_constraints_low(
/* First check if we are actually doing an ALTER TABLE, and in that /* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */ case look for the table being altered */
ptr = dict_accept(ptr, "ALTER", &success); ptr = dict_accept(cs, ptr, "ALTER", &success);
if (!success) { if (!success) {
goto loop; goto loop;
} }
ptr = dict_accept(ptr, "TABLE", &success); ptr = dict_accept(cs, ptr, "TABLE", &success);
if (!success) { if (!success) {
@@ -2889,7 +2951,7 @@ dict_create_foreign_constraints_low(
/* We are doing an ALTER TABLE: scan the table name we are altering */ /* We are doing an ALTER TABLE: scan the table name we are altering */
ptr = dict_scan_table_name(ptr, &table_to_alter, name, ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
&success, heap, &referenced_table_name); &success, heap, &referenced_table_name);
if (!success) { if (!success) {
fprintf(stderr, fprintf(stderr,
@@ -2929,21 +2991,22 @@ loop:
of the constraint to system tables. */ of the constraint to system tables. */
ptr = ptr1; ptr = ptr1;
ptr = dict_accept(ptr, "CONSTRAINT", &success); ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
ut_a(success); ut_a(success);
if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') { if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') {
goto loop; goto loop;
} }
while (isspace(*ptr)) { while (my_isspace(cs, *ptr)) {
ptr++; ptr++;
} }
/* 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, heap, &constraint_name, FALSE); ptr = dict_scan_id(cs, ptr, heap,
&constraint_name, FALSE, FALSE);
} }
} else { } else {
ptr = ptr2; ptr = ptr2;
@@ -2973,28 +3036,28 @@ loop:
start_of_latest_foreign = ptr; start_of_latest_foreign = ptr;
ptr = dict_accept(ptr, "FOREIGN", &success); ptr = dict_accept(cs, ptr, "FOREIGN", &success);
if (!success) { if (!success) {
goto loop; goto loop;
} }
if (!isspace(*ptr)) { if (!my_isspace(cs, *ptr)) {
goto loop; goto loop;
} }
ptr = dict_accept(ptr, "KEY", &success); ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) { if (!success) {
goto loop; goto loop;
} }
ptr = dict_accept(ptr, "(", &success); ptr = dict_accept(cs, ptr, "(", &success);
if (!success) { if (!success) {
/* MySQL allows also an index id before the '('; we /* MySQL allows also an index id before the '('; we
skip it */ skip it */
ptr = dict_skip_word(ptr, &success); ptr = dict_skip_word(cs, ptr, &success);
if (!success) { if (!success) {
dict_foreign_report_syntax_err(name, dict_foreign_report_syntax_err(name,
@@ -3003,7 +3066,7 @@ loop:
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
} }
ptr = dict_accept(ptr, "(", &success); ptr = dict_accept(cs, 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
@@ -3018,7 +3081,7 @@ 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); ut_a(i < (sizeof column_names) / sizeof *column_names);
ptr = dict_scan_col(ptr, &success, table, columns + i, ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
heap, column_names + i); heap, column_names + i);
if (!success) { if (!success) {
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
@@ -3032,13 +3095,13 @@ col_loop1:
i++; i++;
ptr = dict_accept(ptr, ",", &success); ptr = dict_accept(cs, ptr, ",", &success);
if (success) { if (success) {
goto col_loop1; goto col_loop1;
} }
ptr = dict_accept(ptr, ")", &success); ptr = dict_accept(cs, 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,
@@ -3055,7 +3118,7 @@ col_loop1:
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name); dict_foreign_error_report_low(ef, name);
fputs("There is no index in table ", ef); fputs("There is no index in table ", ef);
ut_print_name(ef, NULL, name); ut_print_name(ef, NULL, TRUE, name);
fprintf(ef, " where the columns appear\n" fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n" "as the first columns. Constraint:\n%s\n"
"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" "See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
@@ -3065,9 +3128,9 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
} }
ptr = dict_accept(ptr, "REFERENCES", &success); ptr = dict_accept(cs, ptr, "REFERENCES", &success);
if (!success || !isspace(*ptr)) { if (!success || !my_isspace(cs, *ptr)) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign, dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr); ptr);
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
@@ -3107,7 +3170,7 @@ col_loop1:
mem_heap_strdup(foreign->heap, columns[i]->name); mem_heap_strdup(foreign->heap, columns[i]->name);
} }
ptr = dict_scan_table_name(ptr, &referenced_table, name, ptr = dict_scan_table_name(cs, ptr, &referenced_table, name,
&success, heap, &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
@@ -3126,7 +3189,7 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
} }
ptr = dict_accept(ptr, "(", &success); ptr = dict_accept(cs, ptr, "(", &success);
if (!success) { if (!success) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
@@ -3139,7 +3202,7 @@ col_loop1:
i = 0; i = 0;
col_loop2: col_loop2:
ptr = dict_scan_col(ptr, &success, referenced_table, columns + i, ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
heap, column_names + i); heap, column_names + i);
i++; i++;
@@ -3156,13 +3219,13 @@ col_loop2:
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
} }
ptr = dict_accept(ptr, ",", &success); ptr = dict_accept(cs, ptr, ",", &success);
if (success) { if (success) {
goto col_loop2; goto col_loop2;
} }
ptr = dict_accept(ptr, ")", &success); ptr = dict_accept(cs, ptr, ")", &success);
if (!success || foreign->n_fields != i) { if (!success || foreign->n_fields != i) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
@@ -3178,17 +3241,17 @@ col_loop2:
scan_on_conditions: scan_on_conditions:
/* Loop here as long as we can find ON ... conditions */ /* Loop here as long as we can find ON ... conditions */
ptr = dict_accept(ptr, "ON", &success); ptr = dict_accept(cs, ptr, "ON", &success);
if (!success) { if (!success) {
goto try_find_index; goto try_find_index;
} }
ptr = dict_accept(ptr, "DELETE", &success); ptr = dict_accept(cs, ptr, "DELETE", &success);
if (!success) { if (!success) {
ptr = dict_accept(ptr, "UPDATE", &success); ptr = dict_accept(cs, ptr, "UPDATE", &success);
if (!success) { if (!success) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
@@ -3205,13 +3268,13 @@ scan_on_conditions:
n_on_deletes++; n_on_deletes++;
} }
ptr = dict_accept(ptr, "RESTRICT", &success); ptr = dict_accept(cs, ptr, "RESTRICT", &success);
if (success) { if (success) {
goto scan_on_conditions; goto scan_on_conditions;
} }
ptr = dict_accept(ptr, "CASCADE", &success); ptr = dict_accept(cs, ptr, "CASCADE", &success);
if (success) { if (success) {
if (is_on_delete) { if (is_on_delete) {
@@ -3223,10 +3286,10 @@ scan_on_conditions:
goto scan_on_conditions; goto scan_on_conditions;
} }
ptr = dict_accept(ptr, "NO", &success); ptr = dict_accept(cs, ptr, "NO", &success);
if (success) { if (success) {
ptr = dict_accept(ptr, "ACTION", &success); ptr = dict_accept(cs, ptr, "ACTION", &success);
if (!success) { if (!success) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
@@ -3245,7 +3308,7 @@ scan_on_conditions:
goto scan_on_conditions; goto scan_on_conditions;
} }
ptr = dict_accept(ptr, "SET", &success); ptr = dict_accept(cs, ptr, "SET", &success);
if (!success) { if (!success) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
@@ -3254,7 +3317,7 @@ scan_on_conditions:
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
} }
ptr = dict_accept(ptr, "NULL", &success); ptr = dict_accept(cs, ptr, "NULL", &success);
if (!success) { if (!success) {
dict_foreign_free(foreign); dict_foreign_free(foreign);
@@ -3364,6 +3427,25 @@ try_find_index:
goto loop; goto loop;
} }
/**************************************************************************
Determines whether a string starts with the specified keyword. */
ibool
dict_str_starts_with_keyword(
/*=========================*/
/* out: TRUE if str starts
with keyword */
void* mysql_thd, /* in: MySQL thread handle */
const char* str, /* in: string to scan for keyword */
const char* keyword) /* in: keyword to look for */
{
struct charset_info_st* cs = innobase_get_charset(mysql_thd);
ibool success;
dict_accept(cs, str, keyword, &success);
return(success);
}
/************************************************************************* /*************************************************************************
Scans a table create SQL string and adds to the data dictionary the foreign Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after key constraints declared in the string. This function should be called after
@@ -3391,15 +3473,18 @@ dict_create_foreign_constraints(
code DB_CANNOT_ADD_CONSTRAINT if code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */ any foreign keys are found. */
{ {
char* str; char* str;
ulint err; ulint err;
mem_heap_t* heap; mem_heap_t* heap;
ut_a(trx && trx->mysql_thd);
str = dict_strip_comments(sql_string); str = dict_strip_comments(sql_string);
heap = mem_heap_create(10000); heap = mem_heap_create(10000);
err = dict_create_foreign_constraints_low(trx, heap, str, name, err = dict_create_foreign_constraints_low(trx, heap,
reject_fks); innobase_get_charset(trx->mysql_thd),
str, name, reject_fks);
mem_heap_free(heap); mem_heap_free(heap);
mem_free(str); mem_free(str);
@@ -3426,12 +3511,17 @@ dict_foreign_parse_drop_constraints(
const 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;
const char* ptr; const char* ptr;
const char* id; const char* id;
FILE* ef = dict_foreign_err_file; FILE* ef = dict_foreign_err_file;
struct charset_info_st* cs;
ut_a(trx && trx->mysql_thd);
cs = innobase_get_charset(trx->mysql_thd);
*n = 0; *n = 0;
@@ -3452,28 +3542,28 @@ loop:
return(DB_SUCCESS); return(DB_SUCCESS);
} }
ptr = dict_accept(ptr, "DROP", &success); ptr = dict_accept(cs, ptr, "DROP", &success);
if (!isspace(*ptr)) { if (!my_isspace(cs, *ptr)) {
goto loop; goto loop;
} }
ptr = dict_accept(ptr, "FOREIGN", &success); ptr = dict_accept(cs, ptr, "FOREIGN", &success);
if (!success) { if (!success) {
goto loop; goto loop;
} }
ptr = dict_accept(ptr, "KEY", &success); ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) { if (!success) {
goto syntax_error; goto syntax_error;
} }
ptr = dict_scan_id(ptr, heap, &id, TRUE); ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE);
if (id == NULL) { if (id == NULL) {
@@ -3506,12 +3596,12 @@ loop:
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs( fputs(
" Error in dropping of a foreign key constraint of table ", ef); " Error in dropping of a foreign key constraint of table ", ef);
ut_print_name(ef, NULL, table->name); ut_print_name(ef, NULL, TRUE, table->name);
fputs(",\n" fputs(",\n"
"in SQL command\n", ef); "in SQL command\n", ef);
fputs(str, ef); fputs(str, ef);
fputs("\nCannot find a constraint with the given id ", ef); fputs("\nCannot find a constraint with the given id ", ef);
ut_print_name(ef, NULL, id); ut_print_name(ef, NULL, FALSE, id);
fputs(".\n", ef); fputs(".\n", ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
@@ -3528,7 +3618,7 @@ syntax_error:
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs( fputs(
" Syntax error in dropping of a foreign key constraint of table ", ef); " Syntax error in dropping of a foreign key constraint of table ", ef);
ut_print_name(ef, NULL, table->name); ut_print_name(ef, NULL, TRUE, table->name);
fprintf(ef, ",\n" fprintf(ef, ",\n"
"close to:\n%s\n in SQL command\n%s\n", ptr, str); "close to:\n%s\n in SQL command\n%s\n", ptr, str);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
@@ -3537,6 +3627,7 @@ syntax_error:
return(DB_CANNOT_DROP_CONSTRAINT); return(DB_CANNOT_DROP_CONSTRAINT);
} }
#endif /* UNIV_HOTBACKUP */
/*==================== END OF FOREIGN KEY PROCESSING ====================*/ /*==================== END OF FOREIGN KEY PROCESSING ====================*/
@@ -4206,11 +4297,11 @@ dict_print_info_on_foreign_key_in_create_format(
} }
fputs(" CONSTRAINT ", file); fputs(" CONSTRAINT ", file);
ut_print_name(file, trx, stripped_id); ut_print_name(file, trx, FALSE, stripped_id);
fputs(" FOREIGN KEY (", file); fputs(" FOREIGN KEY (", file);
for (i = 0;;) { for (i = 0;;) {
ut_print_name(file, trx, foreign->foreign_col_names[i]); ut_print_name(file, trx, FALSE, foreign->foreign_col_names[i]);
if (++i < foreign->n_fields) { if (++i < foreign->n_fields) {
fputs(", ", file); fputs(", ", file);
} else { } else {
@@ -4223,7 +4314,7 @@ dict_print_info_on_foreign_key_in_create_format(
if (dict_tables_have_same_db(foreign->foreign_table_name, if (dict_tables_have_same_db(foreign->foreign_table_name,
foreign->referenced_table_name)) { foreign->referenced_table_name)) {
/* Do not print the database name of the referenced table */ /* Do not print the database name of the referenced table */
ut_print_name(file, trx, dict_remove_db_name( ut_print_name(file, trx, TRUE, dict_remove_db_name(
foreign->referenced_table_name)); foreign->referenced_table_name));
} else { } else {
/* Look for the '/' in the table name */ /* Look for the '/' in the table name */
@@ -4233,9 +4324,10 @@ dict_print_info_on_foreign_key_in_create_format(
i++; i++;
} }
ut_print_namel(file, trx, foreign->referenced_table_name, i); ut_print_namel(file, trx, TRUE,
foreign->referenced_table_name, i);
putc('.', file); putc('.', file);
ut_print_name(file, trx, ut_print_name(file, trx, TRUE,
foreign->referenced_table_name + i + 1); foreign->referenced_table_name + i + 1);
} }
@@ -4243,7 +4335,8 @@ dict_print_info_on_foreign_key_in_create_format(
putc('(', file); putc('(', file);
for (i = 0;;) { for (i = 0;;) {
ut_print_name(file, trx, foreign->referenced_col_names[i]); ut_print_name(file, trx, FALSE,
foreign->referenced_col_names[i]);
if (++i < foreign->n_fields) { if (++i < foreign->n_fields) {
fputs(", ", file); fputs(", ", file);
} else { } else {
@@ -4317,12 +4410,12 @@ dict_print_info_on_foreign_keys(
putc(' ', file); putc(' ', file);
} }
ut_print_name(file, trx, ut_print_name(file, trx, FALSE,
foreign->foreign_col_names[i]); foreign->foreign_col_names[i]);
} }
fputs(") REFER ", file); fputs(") REFER ", file);
ut_print_name(file, trx, ut_print_name(file, trx, TRUE,
foreign->referenced_table_name); foreign->referenced_table_name);
putc('(', file); putc('(', file);
@@ -4330,7 +4423,7 @@ dict_print_info_on_foreign_keys(
if (i) { if (i) {
putc(' ', file); putc(' ', file);
} }
ut_print_name(file, trx, ut_print_name(file, trx, FALSE,
foreign->referenced_col_names[i]); foreign->referenced_col_names[i]);
} }
@@ -4377,7 +4470,7 @@ dict_index_name_print(
const dict_index_t* index) /* in: index to print */ const dict_index_t* index) /* in: index to print */
{ {
fputs("index ", file); fputs("index ", file);
ut_print_name(file, trx, index->name); ut_print_name(file, trx, FALSE, index->name);
fputs(" of table ", file); fputs(" of table ", file);
ut_print_name(file, trx, index->table_name); ut_print_name(file, trx, TRUE, index->table_name);
} }

View File

@@ -184,7 +184,7 @@ loop:
if (table == NULL) { if (table == NULL) {
fputs("InnoDB: Failed to load table ", stderr); fputs("InnoDB: Failed to load table ", stderr);
ut_print_namel(stderr, NULL, (char*) field, len); ut_print_namel(stderr, NULL, TRUE, (char*) field, len);
putc('\n', stderr); putc('\n', stderr);
} else { } else {
/* The table definition was corrupt if there /* The table definition was corrupt if there

View File

@@ -81,6 +81,8 @@ dict_mem_table_create(
table->stat_modified_counter = 0; table->stat_modified_counter = 0;
table->max_row_size = 0;
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX); mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
table->autoinc_inited = FALSE; table->autoinc_inited = FALSE;

View File

@@ -43,6 +43,7 @@ have disables the InnoDB inlining in this file. */
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1)) #define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
#ifdef WITH_INNOBASE_STORAGE_ENGINE #ifdef WITH_INNOBASE_STORAGE_ENGINE
#include "ha_innodb.h" #include "ha_innodb.h"
pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
@@ -204,54 +205,16 @@ static int innobase_rollback(THD* thd, bool all);
static int innobase_rollback_to_savepoint(THD* thd, void *savepoint); static int innobase_rollback_to_savepoint(THD* thd, void *savepoint);
static int innobase_savepoint(THD* thd, void *savepoint); static int innobase_savepoint(THD* thd, void *savepoint);
static int innobase_release_savepoint(THD* thd, void *savepoint); static int innobase_release_savepoint(THD* thd, void *savepoint);
static handler *innobase_create_handler(TABLE_SHARE *table); static handler *innobase_create_handler(TABLE_SHARE *table,
MEM_ROOT *mem_root);
static const char innobase_hton_name[]= "InnoDB"; static const char innobase_hton_name[]= "InnoDB";
static const char innobase_hton_comment[]=
"Supports transactions, row-level locking, and foreign keys";
handlerton innobase_hton = { handlerton innobase_hton;
MYSQL_HANDLERTON_INTERFACE_VERSION,
innobase_hton_name,
SHOW_OPTION_YES,
innobase_hton_comment,
DB_TYPE_INNODB,
innobase_init,
0, /* slot */
sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */
innobase_close_connection,
innobase_savepoint,
innobase_rollback_to_savepoint,
innobase_release_savepoint,
innobase_commit, /* commit */
innobase_rollback, /* rollback */
innobase_xa_prepare, /* prepare */
innobase_xa_recover, /* recover */
innobase_commit_by_xid, /* commit_by_xid */
innobase_rollback_by_xid, /* rollback_by_xid */
innobase_create_cursor_view,
innobase_set_cursor_view,
innobase_close_cursor_view,
innobase_create_handler, /* Create a new handler */
innobase_drop_database, /* Drop a database */
innobase_end, /* Panic call */
innobase_start_trx_and_assign_read_view, /* Start Consistent Snapshot */
innobase_flush_logs, /* Flush logs */
innobase_show_status, /* Show status */
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* alter_tablespace */
NULL, /* Fill FILES table */
HTON_NO_FLAGS,
NULL, /* binlog_func */
NULL, /* binlog_log_query */
innobase_release_temporary_latches
};
static handler *innobase_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
static handler *innobase_create_handler(TABLE_SHARE *table)
{ {
return new ha_innobase(table); return new (mem_root) ha_innobase(table);
} }
@@ -706,6 +669,61 @@ innobase_get_cset_width(
} }
} }
/**********************************************************************
Converts an identifier to a table name.
NOTE that the exact prototype of this function has to be in
/innobase/dict/dict0dict.c! */
extern "C"
void
innobase_convert_from_table_id(
/*===========================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len) /* in: length of 'to', in bytes */
{
uint errors;
strconvert(current_thd->charset(), from,
&my_charset_filename, to, len, &errors);
}
/**********************************************************************
Converts an identifier to UTF-8.
NOTE that the exact prototype of this function has to be in
/innobase/dict/dict0dict.c! */
extern "C"
void
innobase_convert_from_id(
/*=====================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len) /* in: length of 'to', in bytes */
{
uint errors;
strconvert(current_thd->charset(), from,
system_charset_info, to, len, &errors);
}
/**********************************************************************
Removes the filename encoding of a table or database name.
NOTE that the exact prototype of this function has to be in
/innobase/dict/dict0dict.c! */
extern "C"
void
innobase_convert_from_filename(
/*===========================*/
char* s) /* in: identifier; out: decoded identifier */
{
uint errors;
strconvert(&my_charset_filename, s,
system_charset_info, s, strlen(s), &errors);
}
/********************************************************************** /**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively. Compares NUL-terminated UTF-8 strings case insensitively.
@@ -736,6 +754,21 @@ innobase_casedn_str(
my_casedn_str(system_charset_info, a); my_casedn_str(system_charset_info, a);
} }
/**************************************************************************
Determines the connection character set.
NOTE that the exact prototype of this function has to be in
/innobase/dict/dict0dict.c! */
extern "C"
struct charset_info_st*
innobase_get_charset(
/*=================*/
/* out: connection character set */
void* mysql_thd) /* in: MySQL thread handle */
{
return(((THD*) mysql_thd)->charset());
}
/************************************************************************* /*************************************************************************
Creates a temporary file. */ Creates a temporary file. */
extern "C" extern "C"
@@ -863,10 +896,9 @@ ha_innobase::ha_innobase(TABLE_SHARE *table_arg)
HA_NULL_IN_KEY | HA_NULL_IN_KEY |
HA_CAN_INDEX_BLOBS | HA_CAN_INDEX_BLOBS |
HA_CAN_SQL_HANDLER | HA_CAN_SQL_HANDLER |
HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_IN_READ_INDEX |
HA_CAN_GEOMETRY | HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX), HA_TABLE_SCAN_ON_INDEX),
start_of_scan(0), start_of_scan(0),
num_write_row(0) num_write_row(0)
@@ -1135,23 +1167,70 @@ innobase_invalidate_query_cache(
} }
/********************************************************************* /*********************************************************************
Get the quote character to be used in SQL identifiers. Display an SQL identifier.
This definition must match the one in innobase/ut/ut0ut.c! */ This definition must match the one in innobase/ut/ut0ut.c! */
extern "C" extern "C"
int void
mysql_get_identifier_quote_char( innobase_print_identifier(
/*============================*/ /*======================*/
/* out: quote character to be FILE* f, /* in: output stream */
used in SQL identifiers; EOF if none */
trx_t* trx, /* in: transaction */ trx_t* trx, /* in: transaction */
ibool table_id,/* in: TRUE=print a table name,
FALSE=print other identifier */
const char* name, /* in: name to print */ const char* name, /* in: name to print */
ulint namelen)/* in: length of name */ ulint namelen)/* in: length of name */
{ {
if (!trx || !trx->mysql_thd) { const char* s = name;
return(EOF); char* qname = NULL;
int q;
if (table_id) {
/* Decode the table name. The filename_to_tablename()
function expects a NUL-terminated string. The input and
output strings buffers must not be shared. The function
only produces more output when the name contains other
characters than [0-9A-Z_a-z]. */
char* temp_name = my_malloc(namelen + 1, MYF(MY_WME));
uint qnamelen = namelen
+ (1 + sizeof srv_mysql50_table_name_prefix);
if (temp_name) {
qname = my_malloc(qnamelen, MYF(MY_WME));
if (qname) {
memcpy(temp_name, name, namelen);
temp_name[namelen] = 0;
s = qname;
namelen = filename_to_tablename(temp_name,
qname, qnamelen);
}
my_free(temp_name, MYF(0));
}
} }
return(get_quote_char_for_identifier((THD*) trx->mysql_thd,
name, (int) namelen)); if (!trx || !trx->mysql_thd) {
q = '"';
} else {
q = get_quote_char_for_identifier((THD*) trx->mysql_thd,
s, (int) namelen);
}
if (q == EOF) {
fwrite(s, 1, namelen, f);
} else {
const char* e = s + namelen;
putc(q, f);
while (s < e) {
int c = *s++;
if (c == q) {
putc(c, f);
}
putc(c, f);
}
putc(q, f);
}
my_free(qname, MYF(MY_ALLOW_ZERO_PTR));
} }
/************************************************************************** /**************************************************************************
@@ -1250,10 +1329,9 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/************************************************************************* /*************************************************************************
Opens an InnoDB database. */ Opens an InnoDB database. */
bool int
innobase_init(void) innobase_init(void)
/*===============*/ /*===============*/
/* out: &innobase_hton, or NULL on error */
{ {
static char current_dir[3]; /* Set if using current lib */ static char current_dir[3]; /* Set if using current lib */
int err; int err;
@@ -1262,11 +1340,54 @@ innobase_init(void)
DBUG_ENTER("innobase_init"); DBUG_ENTER("innobase_init");
innobase_hton.state=have_innodb;
innobase_hton.db_type= DB_TYPE_INNODB;
innobase_hton.savepoint_offset=sizeof(trx_named_savept_t);
innobase_hton.close_connection=innobase_close_connection;
innobase_hton.savepoint_set=innobase_savepoint;
innobase_hton.savepoint_rollback=innobase_rollback_to_savepoint;
innobase_hton.savepoint_release=innobase_release_savepoint;
innobase_hton.commit=innobase_commit;
innobase_hton.rollback=innobase_rollback;
innobase_hton.prepare=innobase_xa_prepare;
innobase_hton.recover=innobase_xa_recover;
innobase_hton.commit_by_xid=innobase_commit_by_xid;
innobase_hton.rollback_by_xid=innobase_rollback_by_xid;
innobase_hton.create_cursor_read_view=innobase_create_cursor_view;
innobase_hton.set_cursor_read_view=innobase_set_cursor_view;
innobase_hton.close_cursor_read_view=innobase_close_cursor_view;
innobase_hton.create=innobase_create_handler;
innobase_hton.drop_database=innobase_drop_database;
innobase_hton.panic=innobase_end;
innobase_hton.start_consistent_snapshot=innobase_start_trx_and_assign_read_view;
innobase_hton.flush_logs=innobase_flush_logs;
innobase_hton.show_status=innobase_show_status;
innobase_hton.flags=HTON_NO_FLAGS;
innobase_hton.release_temporary_latches=innobase_release_temporary_latches;
if (have_innodb != SHOW_OPTION_YES) if (have_innodb != SHOW_OPTION_YES)
goto error; DBUG_RETURN(0); // nothing else to do
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
#ifdef UNIV_DEBUG
static const char test_filename[] = "-@";
char test_tablename[sizeof test_filename
+ sizeof srv_mysql50_table_name_prefix];
if ((sizeof test_tablename) - 1
!= filename_to_tablename(test_filename, test_tablename,
sizeof test_tablename)
|| strncmp(test_tablename,
srv_mysql50_table_name_prefix,
sizeof srv_mysql50_table_name_prefix)
|| strcmp(test_tablename
+ sizeof srv_mysql50_table_name_prefix,
test_filename)) {
sql_print_error("tablename encoding has been changed");
goto error;
}
#endif /* UNIV_DEBUG */
/* Check that values don't overflow on 32-bit systems. */ /* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) { if (sizeof(ulint) == 4) {
if (innobase_buffer_pool_size > UINT_MAX32) { if (innobase_buffer_pool_size > UINT_MAX32) {
@@ -2341,7 +2462,7 @@ ha_innobase::open(
} }
} }
block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL stats.block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
in query optimization */ in query optimization */
/* Init table lock structure */ /* Init table lock structure */
@@ -2936,16 +3057,15 @@ ha_innobase::store_key_val_for_row(
/****************************************************************** /******************************************************************
Builds a 'template' to the prebuilt struct. The template is used in fast Builds a 'template' to the prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */ retrieval of just those column values MySQL needs in its processing. */
static
void void
build_template( ha_innobase::build_template(
/*===========*/ /*===========*/
row_prebuilt_t* prebuilt, /* in: prebuilt struct */ row_prebuilt_t* prebuilt, /* in: prebuilt struct */
THD* thd, /* in: current user thread, used THD* thd, /* in: current user thread, used
only if templ_type is only if templ_type is
ROW_MYSQL_REC_FIELDS */ ROW_MYSQL_REC_FIELDS */
TABLE* table, /* in: MySQL table */ TABLE* table, /* in: MySQL table */
ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or uint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
ROW_MYSQL_REC_FIELDS */ ROW_MYSQL_REC_FIELDS */
{ {
dict_index_t* index; dict_index_t* index;
@@ -3054,8 +3174,8 @@ build_template(
goto include_field; goto include_field;
} }
if (table->file->ha_get_bit_in_read_set(i+1) || if (bitmap_is_set(table->read_set, i) ||
table->file->ha_get_bit_in_write_set(i+1)) { bitmap_is_set(table->write_set, i)) {
/* This field is needed in the query */ /* This field is needed in the query */
goto include_field; goto include_field;
@@ -4690,7 +4810,7 @@ ha_innobase::create(
/* Get the transaction associated with the current thd, or create one /* Get the transaction associated with the current thd, or create one
if not yet created */ if not yet created */
parent_trx = check_trx_exists(current_thd); parent_trx = check_trx_exists(thd);
/* In case MySQL calls this in the middle of a SELECT query, release /* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */ possible adaptive hash latch to avoid deadlocks of threads */
@@ -4795,20 +4915,9 @@ ha_innobase::create(
} }
} }
if (current_thd->query != NULL) { if (thd->query != NULL) {
LEX_STRING q;
if (thd->convert_string(&q, system_charset_info,
current_thd->query,
current_thd->query_length,
current_thd->charset())) {
error = HA_ERR_OUT_OF_MEM;
goto cleanup;
}
error = row_table_add_foreign_constraints(trx, error = row_table_add_foreign_constraints(trx,
q.str, norm_name, thd->query, norm_name,
create_info->options & HA_LEX_CREATE_TMP_TABLE); create_info->options & HA_LEX_CREATE_TMP_TABLE);
error = convert_error_code_to_mysql(error, NULL); error = convert_error_code_to_mysql(error, NULL);
@@ -4964,7 +5073,7 @@ ha_innobase::delete_table(
/* Get the transaction associated with the current thd, or create one /* Get the transaction associated with the current thd, or create one
if not yet created */ if not yet created */
parent_trx = check_trx_exists(current_thd); parent_trx = check_trx_exists(thd);
/* In case MySQL calls this in the middle of a SELECT query, release /* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */ possible adaptive hash latch to avoid deadlocks of threads */
@@ -5451,7 +5560,7 @@ ha_innobase::info(
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
if (os_file_get_status(path,&stat_info)) { if (os_file_get_status(path,&stat_info)) {
create_time = stat_info.ctime; stats.create_time = stat_info.ctime;
} }
} }
@@ -5479,21 +5588,21 @@ ha_innobase::info(
n_rows++; n_rows++;
} }
records = (ha_rows)n_rows; stats.records = (ha_rows)n_rows;
deleted = 0; stats.deleted = 0;
data_file_length = ((ulonglong) stats.data_file_length = ((ulonglong)
ib_table->stat_clustered_index_size) ib_table->stat_clustered_index_size)
* UNIV_PAGE_SIZE; * UNIV_PAGE_SIZE;
index_file_length = ((ulonglong) stats.index_file_length = ((ulonglong)
ib_table->stat_sum_of_other_index_sizes) ib_table->stat_sum_of_other_index_sizes)
* UNIV_PAGE_SIZE; * UNIV_PAGE_SIZE;
delete_length = 0; stats.delete_length = 0;
check_time = 0; stats.check_time = 0;
if (records == 0) { if (stats.records == 0) {
mean_rec_length = 0; stats.mean_rec_length = 0;
} else { } else {
mean_rec_length = (ulong) (data_file_length / records); stats.mean_rec_length = (ulong) (stats.data_file_length / stats.records);
} }
} }
@@ -5542,9 +5651,9 @@ ha_innobase::info(
if (index->stat_n_diff_key_vals[j + 1] == 0) { if (index->stat_n_diff_key_vals[j + 1] == 0) {
rec_per_key = records; rec_per_key = stats.records;
} else { } else {
rec_per_key = (ha_rows)(records / rec_per_key = (ha_rows)(stats.records /
index->stat_n_diff_key_vals[j + 1]); index->stat_n_diff_key_vals[j + 1]);
} }
@@ -5599,7 +5708,7 @@ ha_innobase::info(
} }
} }
auto_increment_value = auto_inc; stats.auto_increment_value = auto_inc;
} }
prebuilt->trx->op_info = (char*)""; prebuilt->trx->op_info = (char*)"";
@@ -5994,8 +6103,7 @@ ha_innobase::extra(
/*===============*/ /*===============*/
/* out: 0 or error number */ /* out: 0 or error number */
enum ha_extra_function operation) enum ha_extra_function operation)
/* in: HA_EXTRA_RETRIEVE_ALL_COLS or some /* in: HA_EXTRA_FLUSH or some other flag */
other flag */
{ {
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
@@ -6009,13 +6117,6 @@ ha_innobase::extra(
row_mysql_prebuilt_free_blob_heap(prebuilt); row_mysql_prebuilt_free_blob_heap(prebuilt);
} }
break; break;
case HA_EXTRA_RESET:
if (prebuilt->blob_heap) {
row_mysql_prebuilt_free_blob_heap(prebuilt);
}
prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_RESET_STATE: case HA_EXTRA_RESET_STATE:
prebuilt->keep_other_fields_on_keyread = 0; prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0; prebuilt->read_just_key = 0;
@@ -6023,16 +6124,6 @@ ha_innobase::extra(
case HA_EXTRA_NO_KEYREAD: case HA_EXTRA_NO_KEYREAD:
prebuilt->read_just_key = 0; prebuilt->read_just_key = 0;
break; break;
case HA_EXTRA_RETRIEVE_ALL_COLS:
prebuilt->hint_need_to_fetch_extra_cols
= ROW_RETRIEVE_ALL_COLS;
break;
case HA_EXTRA_RETRIEVE_PRIMARY_KEY:
if (prebuilt->hint_need_to_fetch_extra_cols == 0) {
prebuilt->hint_need_to_fetch_extra_cols
= ROW_RETRIEVE_PRIMARY_KEY;
}
break;
case HA_EXTRA_KEYREAD: case HA_EXTRA_KEYREAD:
prebuilt->read_just_key = 1; prebuilt->read_just_key = 1;
break; break;
@@ -6046,6 +6137,18 @@ ha_innobase::extra(
return(0); return(0);
} }
int ha_innobase::reset()
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
if (prebuilt->blob_heap) {
row_mysql_prebuilt_free_blob_heap(prebuilt);
}
prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
return 0;
}
/********************************************************************** /**********************************************************************
MySQL calls this function at the start of each SQL statement inside LOCK MySQL calls this function at the start of each SQL statement inside LOCK
TABLES. Inside LOCK TABLES the ::external_lock method does not work to TABLES. Inside LOCK TABLES the ::external_lock method does not work to
@@ -6504,7 +6607,7 @@ innodb_show_status(
bool result = FALSE; bool result = FALSE;
if (stat_print(thd, innobase_hton.name, strlen(innobase_hton.name), if (stat_print(thd, innobase_hton_name, strlen(innobase_hton_name),
STRING_WITH_LEN(""), str, flen)) { STRING_WITH_LEN(""), str, flen)) {
result= TRUE; result= TRUE;
} }
@@ -6531,7 +6634,7 @@ innodb_mutex_show_status(
ulint rw_lock_count_os_wait= 0; ulint rw_lock_count_os_wait= 0;
ulint rw_lock_count_os_yield= 0; ulint rw_lock_count_os_yield= 0;
ulonglong rw_lock_wait_time= 0; ulonglong rw_lock_wait_time= 0;
uint hton_name_len= strlen(innobase_hton.name), buf1len, buf2len; uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
DBUG_ENTER("innodb_mutex_show_status"); DBUG_ENTER("innodb_mutex_show_status");
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER #ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
@@ -6558,7 +6661,7 @@ innodb_mutex_show_status(
mutex->count_os_yield, mutex->count_os_yield,
mutex->lspent_time/1000); mutex->lspent_time/1000);
if (stat_print(thd, innobase_hton.name, if (stat_print(thd, innobase_hton_name,
hton_name_len, buf1, buf1len, hton_name_len, buf1, buf1len,
buf2, buf2len)) { buf2, buf2len)) {
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER #ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
@@ -6588,7 +6691,7 @@ innodb_mutex_show_status(
rw_lock_count_os_wait, rw_lock_count_os_yield, rw_lock_count_os_wait, rw_lock_count_os_yield,
rw_lock_wait_time/1000); rw_lock_wait_time/1000);
if (stat_print(thd, innobase_hton.name, hton_name_len, if (stat_print(thd, innobase_hton_name, hton_name_len,
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) { STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@@ -6825,6 +6928,17 @@ ha_innobase::store_lock(
&& !thd->tablespace_op && !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE && thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_OPTIMIZE && thd->lex->sql_command != SQLCOM_OPTIMIZE
#ifdef __WIN__
/* For alter table on win32 for succesful operation
completion it is used TL_WRITE(=10) lock instead of
TL_WRITE_ALLOW_READ(=6), however here in innodb handler
TL_WRITE is lifted to TL_WRITE_ALLOW_WRITE, which causes
race condition when several clients do alter table
simultaneously (bug #17264). This fix avoids the problem. */
&& thd->lex->sql_command != SQLCOM_ALTER_TABLE
#endif
&& thd->lex->sql_command != SQLCOM_CREATE_TABLE) { && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
lock_type = TL_WRITE_ALLOW_WRITE; lock_type = TL_WRITE_ALLOW_WRITE;
@@ -6994,17 +7108,21 @@ func_exit_early:
return(error); return(error);
} }
/*********************************************************************** /*******************************************************************************
This function initializes the auto-inc counter if it has not been This function initializes the auto-inc counter if it has not been
initialized yet. This function does not change the value of the auto-inc initialized yet. This function does not change the value of the auto-inc
counter if it already has been initialized. Returns the value of the counter if it already has been initialized. Returns the value of the
auto-inc counter. */ auto-inc counter in *first_value, and ULONGLONG_MAX in *nb_reserved_values (as
we have a table-level lock). offset, increment, nb_desired_values are ignored.
*first_value is set to -1 if error (deadlock or lock wait timeout) */
ulonglong void ha_innobase::get_auto_increment(
ha_innobase::get_auto_increment() /*=================================*/
/*=============================*/ ulonglong offset, /* in */
/* out: auto-increment column value, -1 if error ulonglong increment, /* in */
(deadlock or lock wait timeout) */ ulonglong nb_desired_values, /* in */
ulonglong *first_value, /* out */
ulonglong *nb_reserved_values) /* out */
{ {
longlong nr; longlong nr;
int error; int error;
@@ -7019,10 +7137,13 @@ ha_innobase::get_auto_increment()
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
sql_print_error("Error %lu in ::get_auto_increment()", sql_print_error("Error %lu in ::get_auto_increment()",
(ulong) error); (ulong) error);
return(~(ulonglong) 0); *first_value= (~(ulonglong) 0);
return;
} }
return((ulonglong) nr); *first_value= (ulonglong) nr;
/* table-level autoinc lock reserves up to +inf */
*nb_reserved_values= ULONGLONG_MAX;
} }
/* See comment in handler.h */ /* See comment in handler.h */
@@ -7490,15 +7611,17 @@ bool ha_innobase::check_if_incompatible_data(
return COMPATIBLE_DATA_YES; return COMPATIBLE_DATA_YES;
} }
struct st_mysql_storage_engine innobase_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION, &innobase_hton};
mysql_declare_plugin(innobase) mysql_declare_plugin(innobase)
{ {
MYSQL_STORAGE_ENGINE_PLUGIN, MYSQL_STORAGE_ENGINE_PLUGIN,
&innobase_hton, &innobase_storage_engine,
innobase_hton_name, innobase_hton_name,
"Innobase OY", "Innobase OY",
innobase_hton_comment, "Supports transactions, row-level locking, and foreign keys",
NULL, /* Plugin Init */ innobase_init, /* Plugin Init */
NULL, /* Plugin Deinit */ NULL, /* Plugin Deinit */
0x0100 /* 1.0 */, 0x0100 /* 1.0 */,
0 0
@@ -7506,3 +7629,4 @@ mysql_declare_plugin(innobase)
mysql_declare_plugin_end; mysql_declare_plugin_end;
#endif #endif

View File

@@ -33,6 +33,8 @@ typedef struct st_innobase_share {
} INNOBASE_SHARE; } INNOBASE_SHARE;
struct row_prebuilt_struct;
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name, my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
uint full_name_len, uint full_name_len,
ulonglong *unused); ulonglong *unused);
@@ -89,7 +91,7 @@ class ha_innobase: public handler
const char* table_type() const { return("InnoDB");} const char* table_type() const { return("InnoDB");}
const char *index_type(uint key_number) { return "BTREE"; } const char *index_type(uint key_number) { return "BTREE"; }
const char** bas_ext() const; const char** bas_ext() const;
ulong table_flags() const { return int_table_flags; } ulonglong table_flags() const { return int_table_flags; }
ulong index_flags(uint idx, uint part, bool all_parts) const ulong index_flags(uint idx, uint part, bool all_parts) const
{ {
return (HA_READ_NEXT | return (HA_READ_NEXT |
@@ -109,7 +111,6 @@ class ha_innobase: public handler
uint max_supported_key_length() const { return 3500; } uint max_supported_key_length() const { return 3500; }
uint max_supported_key_part_length() const; uint max_supported_key_part_length() const;
const key_map *keys_to_use_for_scanning() { return &key_map_full; } const key_map *keys_to_use_for_scanning() { return &key_map_full; }
bool has_transactions() { return 1;}
int open(const char *name, int mode, uint test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
@@ -147,20 +148,10 @@ class ha_innobase: public handler
int optimize(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd,HA_CHECK_OPT* check_opt);
int discard_or_import_tablespace(my_bool discard); int discard_or_import_tablespace(my_bool discard);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int reset();
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
int transactional_table_lock(THD *thd, int lock_type); int transactional_table_lock(THD *thd, int lock_type);
int start_stmt(THD *thd, thr_lock_type lock_type); int start_stmt(THD *thd, thr_lock_type lock_type);
int ha_retrieve_all_cols()
{
ha_set_all_bits_in_read_set();
return extra(HA_EXTRA_RETRIEVE_ALL_COLS);
}
int ha_retrieve_all_pk()
{
ha_set_primary_key_in_read_set();
return extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
}
void position(byte *record); void position(byte *record);
ha_rows records_in_range(uint inx, key_range *min_key, key_range ha_rows records_in_range(uint inx, key_range *min_key, key_range
*max_key); *max_key);
@@ -181,7 +172,10 @@ class ha_innobase: public handler
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
void init_table_handle_for_HANDLER(); void init_table_handle_for_HANDLER();
ulonglong get_auto_increment(); virtual void get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values,
ulonglong *first_value,
ulonglong *nb_reserved_values);
int reset_auto_increment(ulonglong value); int reset_auto_increment(ulonglong value);
virtual bool get_error_message(int error, String *buf); virtual bool get_error_message(int error, String *buf);
@@ -207,6 +201,8 @@ class ha_innobase: public handler
int cmp_ref(const byte *ref1, const byte *ref2); int cmp_ref(const byte *ref1, const byte *ref2);
bool check_if_incompatible_data(HA_CREATE_INFO *info, bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes); uint table_changes);
void build_template(struct row_prebuilt_struct *prebuilt, THD *thd,
TABLE *table, uint templ_type);
}; };
extern SHOW_VAR innodb_status_variables[]; extern SHOW_VAR innodb_status_variables[];
@@ -249,7 +245,7 @@ extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency; extern ulong srv_commit_concurrency;
} }
bool innobase_init(void); int innobase_init(void);
int innobase_end(ha_panic_function type); int innobase_end(ha_panic_function type);
bool innobase_flush_logs(void); bool innobase_flush_logs(void);
uint innobase_get_free_space(void); uint innobase_get_free_space(void);

View File

@@ -330,6 +330,16 @@ dtype_get_min_size(
/* out: minimum size */ /* out: minimum size */
const dtype_t* type); /* in: type */ const dtype_t* type); /* in: type */
/*************************************************************************** /***************************************************************************
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information. */
ulint
dtype_get_max_size(
/*===============*/
/* out: maximum size (ULINT_MAX for
unbounded types) */
const dtype_t* type); /* in: type */
/***************************************************************************
Returns a stored SQL NULL size for a type. For fixed length types it is Returns a stored SQL NULL size for a type. For fixed length types it is
the fixed length of the type, otherwise 0. */ the fixed length of the type, otherwise 0. */
UNIV_INLINE UNIV_INLINE

View File

@@ -44,18 +44,15 @@ dict_get_db_name_len(
/* out: database name length */ /* out: database name length */
const char* name); /* in: table name in the form const char* name); /* in: table name in the form
dbname '/' tablename */ dbname '/' tablename */
/************************************************************************* /************************************************************************
Accepts a specified string. Comparisons are case-insensitive. */ Return the end of table name where we have removed dbname and '/'. */
const char* const char*
dict_accept( dict_remove_db_name(
/*========*/ /*================*/
/* out: if string was accepted, the pointer /* out: table name */
is moved after that, else ptr is returned */ const char* name); /* in: table name in the form
const char* ptr, /* in: scan from this */ dbname '/' tablename */
const char* string, /* in: accept only this string as the next
non-whitespace string */
ibool* success);/* out: TRUE if accepted */
/************************************************************************ /************************************************************************
Decrements the count of open MySQL handles to a table. */ Decrements the count of open MySQL handles to a table. */
@@ -226,6 +223,17 @@ dict_table_referenced_by_foreign_key(
/* out: TRUE if table is referenced by a /* out: TRUE if table is referenced by a
foreign key */ foreign key */
dict_table_t* table); /* in: InnoDB table */ dict_table_t* table); /* in: InnoDB table */
/**************************************************************************
Determines whether a string starts with the specified keyword. */
ibool
dict_str_starts_with_keyword(
/*=========================*/
/* out: TRUE if str starts
with keyword */
void* mysql_thd, /* in: MySQL thread handle */
const char* str, /* in: string to scan for keyword */
const char* keyword); /* in: keyword to look for */
/************************************************************************* /*************************************************************************
Scans a table create SQL string and adds to the data dictionary Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function the foreign key constraints declared in the string. This function

View File

@@ -344,6 +344,12 @@ struct dict_table_struct{
had an IX lock on */ had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t) UT_LIST_BASE_NODE_T(lock_t)
locks; /* list of locks on the table */ locks; /* list of locks on the table */
ulint max_row_size;
/* maximum size of a single row in the
table, not guaranteed to be especially
accurate. it's ULINT_MAX if there are
unbounded variable-width fields. initialized
in dict_table_add_to_cache. */
/*----------------------*/ /*----------------------*/
ibool does_not_fit_in_memory; ibool does_not_fit_in_memory;
/* this field is used to specify in simulations /* this field is used to specify in simulations

View File

@@ -69,57 +69,59 @@
PARS_WHERE_TOKEN = 295, PARS_WHERE_TOKEN = 295,
PARS_FOR_TOKEN = 296, PARS_FOR_TOKEN = 296,
PARS_DDOT_TOKEN = 297, PARS_DDOT_TOKEN = 297,
PARS_CONSISTENT_TOKEN = 298, PARS_READ_TOKEN = 298,
PARS_READ_TOKEN = 299, PARS_ORDER_TOKEN = 299,
PARS_ORDER_TOKEN = 300, PARS_BY_TOKEN = 300,
PARS_BY_TOKEN = 301, PARS_ASC_TOKEN = 301,
PARS_ASC_TOKEN = 302, PARS_DESC_TOKEN = 302,
PARS_DESC_TOKEN = 303, PARS_INSERT_TOKEN = 303,
PARS_INSERT_TOKEN = 304, PARS_INTO_TOKEN = 304,
PARS_INTO_TOKEN = 305, PARS_VALUES_TOKEN = 305,
PARS_VALUES_TOKEN = 306, PARS_UPDATE_TOKEN = 306,
PARS_UPDATE_TOKEN = 307, PARS_SET_TOKEN = 307,
PARS_SET_TOKEN = 308, PARS_DELETE_TOKEN = 308,
PARS_DELETE_TOKEN = 309, PARS_CURRENT_TOKEN = 309,
PARS_CURRENT_TOKEN = 310, PARS_OF_TOKEN = 310,
PARS_OF_TOKEN = 311, PARS_CREATE_TOKEN = 311,
PARS_CREATE_TOKEN = 312, PARS_TABLE_TOKEN = 312,
PARS_TABLE_TOKEN = 313, PARS_INDEX_TOKEN = 313,
PARS_INDEX_TOKEN = 314, PARS_UNIQUE_TOKEN = 314,
PARS_UNIQUE_TOKEN = 315, PARS_CLUSTERED_TOKEN = 315,
PARS_CLUSTERED_TOKEN = 316, PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 316,
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317, PARS_ON_TOKEN = 317,
PARS_ON_TOKEN = 318, PARS_ASSIGN_TOKEN = 318,
PARS_ASSIGN_TOKEN = 319, PARS_DECLARE_TOKEN = 319,
PARS_DECLARE_TOKEN = 320, PARS_CURSOR_TOKEN = 320,
PARS_CURSOR_TOKEN = 321, PARS_SQL_TOKEN = 321,
PARS_SQL_TOKEN = 322, PARS_OPEN_TOKEN = 322,
PARS_OPEN_TOKEN = 323, PARS_FETCH_TOKEN = 323,
PARS_FETCH_TOKEN = 324, PARS_CLOSE_TOKEN = 324,
PARS_CLOSE_TOKEN = 325, PARS_NOTFOUND_TOKEN = 325,
PARS_NOTFOUND_TOKEN = 326, PARS_TO_CHAR_TOKEN = 326,
PARS_TO_CHAR_TOKEN = 327, PARS_TO_NUMBER_TOKEN = 327,
PARS_TO_NUMBER_TOKEN = 328, PARS_TO_BINARY_TOKEN = 328,
PARS_TO_BINARY_TOKEN = 329, PARS_BINARY_TO_NUMBER_TOKEN = 329,
PARS_BINARY_TO_NUMBER_TOKEN = 330, PARS_SUBSTR_TOKEN = 330,
PARS_SUBSTR_TOKEN = 331, PARS_REPLSTR_TOKEN = 331,
PARS_REPLSTR_TOKEN = 332, PARS_CONCAT_TOKEN = 332,
PARS_CONCAT_TOKEN = 333, PARS_INSTR_TOKEN = 333,
PARS_INSTR_TOKEN = 334, PARS_LENGTH_TOKEN = 334,
PARS_LENGTH_TOKEN = 335, PARS_SYSDATE_TOKEN = 335,
PARS_SYSDATE_TOKEN = 336, PARS_PRINTF_TOKEN = 336,
PARS_PRINTF_TOKEN = 337, PARS_ASSERT_TOKEN = 337,
PARS_ASSERT_TOKEN = 338, PARS_RND_TOKEN = 338,
PARS_RND_TOKEN = 339, PARS_RND_STR_TOKEN = 339,
PARS_RND_STR_TOKEN = 340, PARS_ROW_PRINTF_TOKEN = 340,
PARS_ROW_PRINTF_TOKEN = 341, PARS_COMMIT_TOKEN = 341,
PARS_COMMIT_TOKEN = 342, PARS_ROLLBACK_TOKEN = 342,
PARS_ROLLBACK_TOKEN = 343, PARS_WORK_TOKEN = 343,
PARS_WORK_TOKEN = 344, PARS_UNSIGNED_TOKEN = 344,
PARS_UNSIGNED_TOKEN = 345, PARS_EXIT_TOKEN = 345,
PARS_EXIT_TOKEN = 346, PARS_FUNCTION_TOKEN = 346,
PARS_FUNCTION_TOKEN = 347, PARS_LOCK_TOKEN = 347,
NEG = 348 PARS_SHARE_TOKEN = 348,
PARS_MODE_TOKEN = 349,
NEG = 350
}; };
#endif #endif
#define PARS_INT_LIT 258 #define PARS_INT_LIT 258
@@ -162,57 +164,59 @@
#define PARS_WHERE_TOKEN 295 #define PARS_WHERE_TOKEN 295
#define PARS_FOR_TOKEN 296 #define PARS_FOR_TOKEN 296
#define PARS_DDOT_TOKEN 297 #define PARS_DDOT_TOKEN 297
#define PARS_CONSISTENT_TOKEN 298 #define PARS_READ_TOKEN 298
#define PARS_READ_TOKEN 299 #define PARS_ORDER_TOKEN 299
#define PARS_ORDER_TOKEN 300 #define PARS_BY_TOKEN 300
#define PARS_BY_TOKEN 301 #define PARS_ASC_TOKEN 301
#define PARS_ASC_TOKEN 302 #define PARS_DESC_TOKEN 302
#define PARS_DESC_TOKEN 303 #define PARS_INSERT_TOKEN 303
#define PARS_INSERT_TOKEN 304 #define PARS_INTO_TOKEN 304
#define PARS_INTO_TOKEN 305 #define PARS_VALUES_TOKEN 305
#define PARS_VALUES_TOKEN 306 #define PARS_UPDATE_TOKEN 306
#define PARS_UPDATE_TOKEN 307 #define PARS_SET_TOKEN 307
#define PARS_SET_TOKEN 308 #define PARS_DELETE_TOKEN 308
#define PARS_DELETE_TOKEN 309 #define PARS_CURRENT_TOKEN 309
#define PARS_CURRENT_TOKEN 310 #define PARS_OF_TOKEN 310
#define PARS_OF_TOKEN 311 #define PARS_CREATE_TOKEN 311
#define PARS_CREATE_TOKEN 312 #define PARS_TABLE_TOKEN 312
#define PARS_TABLE_TOKEN 313 #define PARS_INDEX_TOKEN 313
#define PARS_INDEX_TOKEN 314 #define PARS_UNIQUE_TOKEN 314
#define PARS_UNIQUE_TOKEN 315 #define PARS_CLUSTERED_TOKEN 315
#define PARS_CLUSTERED_TOKEN 316 #define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 316
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317 #define PARS_ON_TOKEN 317
#define PARS_ON_TOKEN 318 #define PARS_ASSIGN_TOKEN 318
#define PARS_ASSIGN_TOKEN 319 #define PARS_DECLARE_TOKEN 319
#define PARS_DECLARE_TOKEN 320 #define PARS_CURSOR_TOKEN 320
#define PARS_CURSOR_TOKEN 321 #define PARS_SQL_TOKEN 321
#define PARS_SQL_TOKEN 322 #define PARS_OPEN_TOKEN 322
#define PARS_OPEN_TOKEN 323 #define PARS_FETCH_TOKEN 323
#define PARS_FETCH_TOKEN 324 #define PARS_CLOSE_TOKEN 324
#define PARS_CLOSE_TOKEN 325 #define PARS_NOTFOUND_TOKEN 325
#define PARS_NOTFOUND_TOKEN 326 #define PARS_TO_CHAR_TOKEN 326
#define PARS_TO_CHAR_TOKEN 327 #define PARS_TO_NUMBER_TOKEN 327
#define PARS_TO_NUMBER_TOKEN 328 #define PARS_TO_BINARY_TOKEN 328
#define PARS_TO_BINARY_TOKEN 329 #define PARS_BINARY_TO_NUMBER_TOKEN 329
#define PARS_BINARY_TO_NUMBER_TOKEN 330 #define PARS_SUBSTR_TOKEN 330
#define PARS_SUBSTR_TOKEN 331 #define PARS_REPLSTR_TOKEN 331
#define PARS_REPLSTR_TOKEN 332 #define PARS_CONCAT_TOKEN 332
#define PARS_CONCAT_TOKEN 333 #define PARS_INSTR_TOKEN 333
#define PARS_INSTR_TOKEN 334 #define PARS_LENGTH_TOKEN 334
#define PARS_LENGTH_TOKEN 335 #define PARS_SYSDATE_TOKEN 335
#define PARS_SYSDATE_TOKEN 336 #define PARS_PRINTF_TOKEN 336
#define PARS_PRINTF_TOKEN 337 #define PARS_ASSERT_TOKEN 337
#define PARS_ASSERT_TOKEN 338 #define PARS_RND_TOKEN 338
#define PARS_RND_TOKEN 339 #define PARS_RND_STR_TOKEN 339
#define PARS_RND_STR_TOKEN 340 #define PARS_ROW_PRINTF_TOKEN 340
#define PARS_ROW_PRINTF_TOKEN 341 #define PARS_COMMIT_TOKEN 341
#define PARS_COMMIT_TOKEN 342 #define PARS_ROLLBACK_TOKEN 342
#define PARS_ROLLBACK_TOKEN 343 #define PARS_WORK_TOKEN 343
#define PARS_WORK_TOKEN 344 #define PARS_UNSIGNED_TOKEN 344
#define PARS_UNSIGNED_TOKEN 345 #define PARS_EXIT_TOKEN 345
#define PARS_EXIT_TOKEN 346 #define PARS_FUNCTION_TOKEN 346
#define PARS_FUNCTION_TOKEN 347 #define PARS_LOCK_TOKEN 347
#define NEG 348 #define PARS_SHARE_TOKEN 348
#define PARS_MODE_TOKEN 349
#define NEG 350

View File

@@ -63,7 +63,7 @@ extern pars_res_word_t pars_asc_token;
extern pars_res_word_t pars_desc_token; extern pars_res_word_t pars_desc_token;
extern pars_res_word_t pars_open_token; extern pars_res_word_t pars_open_token;
extern pars_res_word_t pars_close_token; extern pars_res_word_t pars_close_token;
extern pars_res_word_t pars_consistent_token; extern pars_res_word_t pars_share_token;
extern pars_res_word_t pars_unique_token; extern pars_res_word_t pars_unique_token;
extern pars_res_word_t pars_clustered_token; extern pars_res_word_t pars_clustered_token;

View File

@@ -143,14 +143,12 @@ que_thr_stop_for_mysql(
/*===================*/ /*===================*/
que_thr_t* thr); /* in: query thread */ que_thr_t* thr); /* in: query thread */
/************************************************************************** /**************************************************************************
Runs query threads. Note that the individual query thread which is run Run a query thread. Handles lock waits. */
within this function may change if, e.g., the OS thread executing this
function uses a threshold amount of resources. */
void void
que_run_threads( que_run_threads(
/*============*/ /*============*/
que_thr_t* thr); /* in: query thread which is run initially */ que_thr_t* thr); /* in: query thread */
/************************************************************************** /**************************************************************************
After signal handling is finished, returns control to a query graph error After signal handling is finished, returns control to a query graph error
handling routine. (Currently, just returns the control to the root of the handling routine. (Currently, just returns the control to the root of the
@@ -163,19 +161,6 @@ que_fork_error_handle(
que_t* fork); /* in: query graph which was run before signal que_t* fork); /* in: query graph which was run before signal
handling started, NULL not allowed */ handling started, NULL not allowed */
/************************************************************************** /**************************************************************************
Handles an SQL error noticed during query thread execution. At the moment,
does nothing! */
void
que_thr_handle_error(
/*=================*/
que_thr_t* thr, /* in: query thread */
ulint err_no, /* in: error number */
byte* err_str,/* in, own: error string or NULL; NOTE: the
function will take care of freeing of the
string! */
ulint err_len);/* in: error string length */
/**************************************************************************
Moves a suspended query thread to the QUE_THR_RUNNING state and releases Moves a suspended query thread to the QUE_THR_RUNNING state and releases
a single worker thread to execute it. This function should be used to end a single worker thread to execute it. This function should be used to end
the wait state of a query thread waiting for a lock or a stored procedure the wait state of a query thread waiting for a lock or a stored procedure
@@ -337,9 +322,14 @@ Evaluate the given SQL */
ulint ulint
que_eval_sql( que_eval_sql(
/*=========*/ /*=========*/
pars_info_t* info, /* out: error code or DB_SUCCESS */ /* out: error code or DB_SUCCESS */
const char* sql, /* in: info struct, or NULL */ pars_info_t* info, /* in: info struct, or NULL */
const char* sql, /* in: SQL string */
ibool reserve_dict_mutex,
/* in: if TRUE, acquire/release
dict_sys->mutex around call to pars_sql. */
trx_t* trx); /* in: trx */ trx_t* trx); /* in: trx */
/* Query graph query thread node: the fields are protected by the kernel /* Query graph query thread node: the fields are protected by the kernel
mutex with the exceptions named below */ mutex with the exceptions named below */

View File

@@ -18,6 +18,9 @@ Created 10/10/1995 Heikki Tuuri
extern const char* srv_main_thread_op_info; extern const char* srv_main_thread_op_info;
/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
extern const char srv_mysql50_table_name_prefix[9];
/* When this event is set the lock timeout and InnoDB monitor /* When this event is set the lock timeout and InnoDB monitor
thread starts running */ thread starts running */
extern os_event_t srv_lock_timeout_thread_event; extern os_event_t srv_lock_timeout_thread_event;

View File

@@ -362,7 +362,7 @@ rw_lock_s_unlock_func(
/* Reset the shared lock by decrementing the reader count */ /* Reset the shared lock by decrementing the reader count */
ut_ad(lock->reader_count > 0); ut_a(lock->reader_count > 0);
lock->reader_count--; lock->reader_count--;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG

View File

@@ -266,11 +266,9 @@ trx_end_lock_wait(
/******************************************************************** /********************************************************************
Sends a signal to a trx object. */ Sends a signal to a trx object. */
ibool void
trx_sig_send( trx_sig_send(
/*=========*/ /*=========*/
/* out: TRUE if the signal was
successfully delivered */
trx_t* trx, /* in: trx handle */ trx_t* trx, /* in: trx handle */
ulint type, /* in: signal type */ ulint type, /* in: signal type */
ulint sender, /* in: TRX_SIG_SELF or ulint sender, /* in: TRX_SIG_SELF or

View File

@@ -222,16 +222,19 @@ ut_print_filename(
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
const char* name); /* in: name to print */ const char* name); /* in: name to print */
/* Forward declaration of transaction handle */
struct trx_struct;
/************************************************************************** /**************************************************************************
Outputs a NUL-terminated string, quoted as an SQL identifier. */ Outputs a NUL-terminated string, quoted as an SQL identifier. */
struct trx_struct;
void void
ut_print_name( ut_print_name(
/*==========*/ /*==========*/
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
struct trx_struct*trx, /* in: transaction */ struct trx_struct*trx, /* in: transaction */
ibool table_id,/* in: TRUE=print a table name,
FALSE=print other identifier */
const char* name); /* in: name to print */ const char* name); /* in: name to print */
/************************************************************************** /**************************************************************************
@@ -242,6 +245,8 @@ ut_print_namel(
/*===========*/ /*===========*/
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
struct trx_struct*trx, /* in: transaction (NULL=no quotes) */ struct trx_struct*trx, /* in: transaction (NULL=no quotes) */
ibool table_id,/* in: TRUE=print a table name,
FALSE=print other identifier */
const char* name, /* in: name to print */ const char* name, /* in: name to print */
ulint namelen);/* in: length of name */ ulint namelen);/* in: length of name */

View File

@@ -1863,7 +1863,7 @@ lock_rec_enqueue_waiting(
fputs( fputs(
" InnoDB: Error: a record lock wait happens in a dictionary operation!\n" " InnoDB: Error: a record lock wait happens in a dictionary operation!\n"
"InnoDB: Table name ", stderr); "InnoDB: Table name ", stderr);
ut_print_name(stderr, trx, index->table_name); ut_print_name(stderr, trx, TRUE, index->table_name);
fputs(".\n" fputs(".\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
stderr); stderr);
@@ -1908,7 +1908,7 @@ lock_rec_enqueue_waiting(
if (lock_print_waits) { if (lock_print_waits) {
fprintf(stderr, "Lock wait for trx %lu in index ", fprintf(stderr, "Lock wait for trx %lu in index ",
(ulong) ut_dulint_get_low(trx->id)); (ulong) ut_dulint_get_low(trx->id));
ut_print_name(stderr, trx, index->name); ut_print_name(stderr, trx, FALSE, index->name);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
@@ -3635,7 +3635,7 @@ lock_table_enqueue_waiting(
fputs( fputs(
" InnoDB: Error: a table lock wait happens in a dictionary operation!\n" " InnoDB: Error: a table lock wait happens in a dictionary operation!\n"
"InnoDB: Table name ", stderr); "InnoDB: Table name ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs(".\n" fputs(".\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
stderr); stderr);
@@ -4158,7 +4158,8 @@ lock_table_print(
ut_a(lock_get_type(lock) == LOCK_TABLE); ut_a(lock_get_type(lock) == LOCK_TABLE);
fputs("TABLE LOCK table ", file); fputs("TABLE LOCK table ", file);
ut_print_name(file, lock->trx, lock->un_member.tab_lock.table->name); ut_print_name(file, lock->trx, TRUE,
lock->un_member.tab_lock.table->name);
fprintf(file, " trx id %lu %lu", fprintf(file, " trx id %lu %lu",
(ulong) (lock->trx)->id.high, (ulong) (lock->trx)->id.low); (ulong) (lock->trx)->id.high, (ulong) (lock->trx)->id.low);

View File

@@ -1370,9 +1370,9 @@ insert into `t2`values ( 1 ) ;
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb; create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
insert into `t3`values ( 1 ) ; insert into `t3`values ( 1 ) ;
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
ERROR 42S22: Unknown column 't1.id' in 'where clause' ERROR 42S22: Unknown column 't1.id' in 'where clause'
drop table t3,t2,t1; drop table t3,t2,t1;
@@ -1384,7 +1384,7 @@ foreign key(pid) references t1(id) on delete cascade) engine=innodb;
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6), insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14); (8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
delete from t1 where id=0; delete from t1 where id=0;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
delete from t1 where id=15; delete from t1 where id=15;
delete from t1 where id=0; delete from t1 where id=0;
drop table t1; drop table t1;
@@ -2610,18 +2610,18 @@ v INT,
CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id) CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
) ENGINE=InnoDB; ) ENGINE=InnoDB;
INSERT INTO t2 VALUES(2); INSERT INTO t2 VALUES(2);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`)) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(1); INSERT INTO t2 VALUES(1);
DELETE FROM t1 WHERE id = 1; DELETE FROM t1 WHERE id = 1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
DROP TABLE t1; DROP TABLE t1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
SET FOREIGN_KEY_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;
DROP TABLE t1; DROP TABLE t1;
SET FOREIGN_KEY_CHECKS=1; SET FOREIGN_KEY_CHECKS=1;
INSERT INTO t2 VALUES(3); INSERT INTO t2 VALUES(3);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`)) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
DROP TABLE t2; DROP TABLE t2;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1; create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2); insert into t1 values (1),(2);
@@ -2899,23 +2899,23 @@ create table t4(a int primary key,constraint foreign key(a)references t3(a)) row
insert into t1 values(1); insert into t1 values(1);
insert into t3 values(1); insert into t3 values(1);
insert into t2 values(2); insert into t2 values(2);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
insert into t4 values(2); insert into t4 values(2);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`)) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
insert into t2 values(1); insert into t2 values(1);
insert into t4 values(1); insert into t4 values(1);
update t1 set a=2; update t1 set a=2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
update t2 set a=2; update t2 set a=2;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
update t3 set a=2; update t3 set a=2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
update t4 set a=2; update t4 set a=2;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`)) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
truncate t1; truncate t1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
truncate t3; truncate t3;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`)) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
truncate t2; truncate t2;
truncate t4; truncate t4;
truncate t1; truncate t1;
@@ -2970,7 +2970,7 @@ create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innod
create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb; create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42); insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
insert into t2 values(0x42); insert into t2 values(0x42);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
insert into t2 values(0x41); insert into t2 values(0x41);
select hex(s1) from t2; select hex(s1) from t2;
hex(s1) hex(s1)
@@ -2980,11 +2980,11 @@ select hex(s1) from t2;
hex(s1) hex(s1)
4100 4100
update t1 set s1=0x12 where a=1; update t1 set s1=0x12 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x12345678 where a=1; update t1 set s1=0x12345678 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x123457 where a=1; update t1 set s1=0x123457 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x1220 where a=1; update t1 set s1=0x1220 where a=1;
select hex(s1) from t2; select hex(s1) from t2;
hex(s1) hex(s1)
@@ -2998,11 +2998,11 @@ select hex(s1) from t2;
hex(s1) hex(s1)
4200 4200
delete from t1 where a=1; delete from t1 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
delete from t1 where a=2; delete from t1 where a=2;
update t2 set s1=0x4120; update t2 set s1=0x4120;
delete from t1; delete from t1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
delete from t1 where a!=3; delete from t1 where a!=3;
select a,hex(s1) from t1; select a,hex(s1) from t1;
a hex(s1) a hex(s1)
@@ -3028,7 +3028,7 @@ hex(s1)
12 12
delete from t1 where a=1; delete from t1 where a=1;
delete from t1 where a=2; delete from t1 where a=2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
select a,hex(s1) from t1; select a,hex(s1) from t1;
a hex(s1) a hex(s1)
2 12 2 12

View File

@@ -1 +1,328 @@
drop table if exists t1; drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4;
create table t1 (
c_id int(11) not null default '0',
org_id int(11) default null,
unique key contacts$c_id (c_id),
key contacts$org_id (org_id)
) engine=innodb;
insert into t1 values
(2,null),(120,null),(141,null),(218,7), (128,1),
(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3),
(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4);
create table t2 (
slai_id int(11) not null default '0',
owner_tbl int(11) default null,
owner_id int(11) default null,
sla_id int(11) default null,
inc_web int(11) default null,
inc_email int(11) default null,
inc_chat int(11) default null,
inc_csr int(11) default null,
inc_total int(11) default null,
time_billed int(11) default null,
activedate timestamp null default null,
expiredate timestamp null default null,
state int(11) default null,
sla_set int(11) default null,
unique key t2$slai_id (slai_id),
key t2$owner_id (owner_id),
key t2$sla_id (sla_id)
) engine=innodb;
insert into t2(slai_id, owner_tbl, owner_id, sla_id) values
(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7),
(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12);
flush tables;
select si.slai_id
from t1 c join t2 si on
((si.owner_tbl = 3 and si.owner_id = c.org_id) or
( si.owner_tbl = 2 and si.owner_id = c.c_id))
where
c.c_id = 218 and expiredate is null;
slai_id
12
select * from t1 where org_id is null;
c_id org_id
2 NULL
120 NULL
141 NULL
select si.slai_id
from t1 c join t2 si on
((si.owner_tbl = 3 and si.owner_id = c.org_id) or
( si.owner_tbl = 2 and si.owner_id = c.c_id))
where
c.c_id = 218 and expiredate is null;
slai_id
12
drop table t1, t2;
create table t1m (a int) engine=myisam;
create table t1i (a int) engine=innodb;
create table t2m (a int) engine=myisam;
create table t2i (a int) engine=innodb;
insert into t2m values (5);
insert into t2i values (5);
select min(a) from t1m;
min(a)
NULL
select min(7) from t1m;
min(7)
NULL
select min(7) from DUAL;
min(7)
NULL
explain select min(7) from t2m join t1m;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
select min(7) from t2m join t1m;
min(7)
NULL
select max(a) from t1m;
max(a)
NULL
select max(7) from t1m;
max(7)
NULL
select max(7) from DUAL;
max(7)
NULL
explain select max(7) from t2m join t1m;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
select max(7) from t2m join t1m;
max(7)
NULL
select 1, min(a) from t1m where a=99;
1 min(a)
1 NULL
select 1, min(a) from t1m where 1=99;
1 min(a)
1 NULL
select 1, min(1) from t1m where a=99;
1 min(1)
1 NULL
select 1, min(1) from t1m where 1=99;
1 min(1)
1 NULL
select 1, max(a) from t1m where a=99;
1 max(a)
1 NULL
select 1, max(a) from t1m where 1=99;
1 max(a)
1 NULL
select 1, max(1) from t1m where a=99;
1 max(1)
1 NULL
select 1, max(1) from t1m where 1=99;
1 max(1)
1 NULL
select min(a) from t1i;
min(a)
NULL
select min(7) from t1i;
min(7)
NULL
select min(7) from DUAL;
min(7)
NULL
explain select min(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
1 SIMPLE t1i ALL NULL NULL NULL NULL 1
select min(7) from t2i join t1i;
min(7)
NULL
select max(a) from t1i;
max(a)
NULL
select max(7) from t1i;
max(7)
NULL
select max(7) from DUAL;
max(7)
NULL
explain select max(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
1 SIMPLE t1i ALL NULL NULL NULL NULL 1
select max(7) from t2i join t1i;
max(7)
NULL
select 1, min(a) from t1i where a=99;
1 min(a)
1 NULL
select 1, min(a) from t1i where 1=99;
1 min(a)
1 NULL
select 1, min(1) from t1i where a=99;
1 min(1)
1 NULL
select 1, min(1) from t1i where 1=99;
1 min(1)
1 NULL
select 1, max(a) from t1i where a=99;
1 max(a)
1 NULL
select 1, max(a) from t1i where 1=99;
1 max(a)
1 NULL
select 1, max(1) from t1i where a=99;
1 max(1)
1 NULL
select 1, max(1) from t1i where 1=99;
1 max(1)
1 NULL
explain select count(*), min(7), max(7) from t1m, t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
1 SIMPLE t1i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t1m, t1i;
count(*) min(7) max(7)
0 NULL NULL
explain select count(*), min(7), max(7) from t1m, t2i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t1m, t2i;
count(*) min(7) max(7)
0 NULL NULL
explain select count(*), min(7), max(7) from t2m, t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2m system NULL NULL NULL NULL 1
1 SIMPLE t1i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t2m, t1i;
count(*) min(7) max(7)
0 NULL NULL
drop table t1m, t1i, t2m, t2i;
create table t1 (
a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
);
insert into t1 (a1, a2, b, c, d) values
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
create table t4 (
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
) engine=innodb;
insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
create index idx12672_0 on t4 (a1);
create index idx12672_1 on t4 (a1,a2,b,c);
create index idx12672_2 on t4 (a1,a2,b);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
select distinct a1 from t4 where pk_col not in (1,2,3,4);
a1
a
b
c
d
drop table t1,t4;
create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b)
) engine=innodb;
select distinct a from t1;
a
drop table t1;
create table t1(a int, key(a)) engine=innodb;
insert into t1 values(1);
select a, count(a) from t1 group by a with rollup;
a count(a)
1 1
NULL 1
drop table t1;
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb;
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
alter table t1 drop primary key, add primary key (f2, f1);
explain select distinct f1 a, f1 b from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary
explain select distinct f1, f2 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary
drop table t1;
set storage_engine=innodb;
CREATE TABLE t1 (a int, b int);
insert into t1 values (1,1),(1,2);
CREATE TABLE t2 (primary key (a)) select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
drop table if exists t2;
Warnings:
Note 1051 Unknown table 't2'
CREATE TEMPORARY TABLE t2 (primary key (a)) select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
drop table if exists t2;
Warnings:
Note 1051 Unknown table 't2'
CREATE TABLE t2 (a int, b int, primary key (a));
BEGIN;
INSERT INTO t2 values(100,100);
CREATE TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from t2;
a b
100 100
ROLLBACK;
SELECT * from t2;
a b
100 100
TRUNCATE table t2;
INSERT INTO t2 select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from t2;
a b
drop table t2;
CREATE TEMPORARY TABLE t2 (a int, b int, primary key (a));
BEGIN;
INSERT INTO t2 values(100,100);
CREATE TEMPORARY TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from t2;
a b
100 100
COMMIT;
BEGIN;
INSERT INTO t2 values(101,101);
CREATE TEMPORARY TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from t2;
a b
100 100
101 101
ROLLBACK;
SELECT * from t2;
a b
100 100
TRUNCATE table t2;
INSERT INTO t2 select * from t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from t2;
a b
drop table t1,t2;

View File

@@ -1,5 +1,274 @@
-- source include/have_innodb.inc -- source include/have_innodb.inc
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4;
--enable_warnings --enable_warnings
# BUG#16798: Uninitialized row buffer reads in ref-or-null optimizer
# (repeatable only w/innodb).
create table t1 (
c_id int(11) not null default '0',
org_id int(11) default null,
unique key contacts$c_id (c_id),
key contacts$org_id (org_id)
) engine=innodb;
insert into t1 values
(2,null),(120,null),(141,null),(218,7), (128,1),
(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3),
(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4);
create table t2 (
slai_id int(11) not null default '0',
owner_tbl int(11) default null,
owner_id int(11) default null,
sla_id int(11) default null,
inc_web int(11) default null,
inc_email int(11) default null,
inc_chat int(11) default null,
inc_csr int(11) default null,
inc_total int(11) default null,
time_billed int(11) default null,
activedate timestamp null default null,
expiredate timestamp null default null,
state int(11) default null,
sla_set int(11) default null,
unique key t2$slai_id (slai_id),
key t2$owner_id (owner_id),
key t2$sla_id (sla_id)
) engine=innodb;
insert into t2(slai_id, owner_tbl, owner_id, sla_id) values
(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7),
(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12);
flush tables;
select si.slai_id
from t1 c join t2 si on
((si.owner_tbl = 3 and si.owner_id = c.org_id) or
( si.owner_tbl = 2 and si.owner_id = c.c_id))
where
c.c_id = 218 and expiredate is null;
select * from t1 where org_id is null;
select si.slai_id
from t1 c join t2 si on
((si.owner_tbl = 3 and si.owner_id = c.org_id) or
( si.owner_tbl = 2 and si.owner_id = c.c_id))
where
c.c_id = 218 and expiredate is null;
drop table t1, t2;
#
# Bug #12882 min/max inconsistent on empty table
#
--disable_warnings
create table t1m (a int) engine=myisam;
create table t1i (a int) engine=innodb;
create table t2m (a int) engine=myisam;
create table t2i (a int) engine=innodb;
--enable_warnings
insert into t2m values (5);
insert into t2i values (5);
# test with MyISAM
select min(a) from t1m;
select min(7) from t1m;
select min(7) from DUAL;
explain select min(7) from t2m join t1m;
select min(7) from t2m join t1m;
select max(a) from t1m;
select max(7) from t1m;
select max(7) from DUAL;
explain select max(7) from t2m join t1m;
select max(7) from t2m join t1m;
select 1, min(a) from t1m where a=99;
select 1, min(a) from t1m where 1=99;
select 1, min(1) from t1m where a=99;
select 1, min(1) from t1m where 1=99;
select 1, max(a) from t1m where a=99;
select 1, max(a) from t1m where 1=99;
select 1, max(1) from t1m where a=99;
select 1, max(1) from t1m where 1=99;
# test with InnoDB
select min(a) from t1i;
select min(7) from t1i;
select min(7) from DUAL;
explain select min(7) from t2i join t1i;
select min(7) from t2i join t1i;
select max(a) from t1i;
select max(7) from t1i;
select max(7) from DUAL;
explain select max(7) from t2i join t1i;
select max(7) from t2i join t1i;
select 1, min(a) from t1i where a=99;
select 1, min(a) from t1i where 1=99;
select 1, min(1) from t1i where a=99;
select 1, min(1) from t1i where 1=99;
select 1, max(a) from t1i where a=99;
select 1, max(a) from t1i where 1=99;
select 1, max(1) from t1i where a=99;
select 1, max(1) from t1i where 1=99;
# mixed MyISAM/InnoDB test
explain select count(*), min(7), max(7) from t1m, t1i;
select count(*), min(7), max(7) from t1m, t1i;
explain select count(*), min(7), max(7) from t1m, t2i;
select count(*), min(7), max(7) from t1m, t2i;
explain select count(*), min(7), max(7) from t2m, t1i;
select count(*), min(7), max(7) from t2m, t1i;
drop table t1m, t1i, t2m, t2i;
#
# Bug #12672: primary key implcitly included in every innodb index
# (was part of group_min_max.test)
#
create table t1 (
a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
);
insert into t1 (a1, a2, b, c, d) values
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
--disable_warnings
create table t4 (
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
) engine=innodb;
--enable_warnings
insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
create index idx12672_0 on t4 (a1);
create index idx12672_1 on t4 (a1,a2,b,c);
create index idx12672_2 on t4 (a1,a2,b);
analyze table t1;
select distinct a1 from t4 where pk_col not in (1,2,3,4);
drop table t1,t4;
#
# Bug #6142: a problem with the empty innodb table
# (was part of group_min_max.test)
#
--disable_warnings
create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b)
) engine=innodb;
--enable_warnings
select distinct a from t1;
drop table t1;
#
# Bug #9798: group by with rollup
# (was part of group_min_max.test)
#
--disable_warnings
create table t1(a int, key(a)) engine=innodb;
--enable_warnings
insert into t1 values(1);
select a, count(a) from t1 group by a with rollup;
drop table t1;
#
# Bug #13293 Wrongly used index results in endless loop.
# (was part of group_min_max.test)
#
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb;
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
alter table t1 drop primary key, add primary key (f2, f1);
explain select distinct f1 a, f1 b from t1;
explain select distinct f1, f2 from t1;
drop table t1;
#
# Test of behaviour with CREATE ... SELECT
#
set storage_engine=innodb;
CREATE TABLE t1 (a int, b int);
insert into t1 values (1,1),(1,2);
--error 1062
CREATE TABLE t2 (primary key (a)) select * from t1;
# This should give warning
drop table if exists t2;
--error 1062
CREATE TEMPORARY TABLE t2 (primary key (a)) select * from t1;
# This should give warning
drop table if exists t2;
CREATE TABLE t2 (a int, b int, primary key (a));
BEGIN;
INSERT INTO t2 values(100,100);
--error 1062
CREATE TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1;
SELECT * from t2;
ROLLBACK;
SELECT * from t2;
TRUNCATE table t2;
--error 1062
INSERT INTO t2 select * from t1;
SELECT * from t2;
drop table t2;
CREATE TEMPORARY TABLE t2 (a int, b int, primary key (a));
BEGIN;
INSERT INTO t2 values(100,100);
--error 1062
CREATE TEMPORARY TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1;
SELECT * from t2;
COMMIT;
BEGIN;
INSERT INTO t2 values(101,101);
--error 1062
CREATE TEMPORARY TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1;
SELECT * from t2;
ROLLBACK;
SELECT * from t2;
TRUNCATE table t2;
--error 1062
INSERT INTO t2 select * from t1;
SELECT * from t2;
drop table t1,t2;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -69,57 +69,59 @@
PARS_WHERE_TOKEN = 295, PARS_WHERE_TOKEN = 295,
PARS_FOR_TOKEN = 296, PARS_FOR_TOKEN = 296,
PARS_DDOT_TOKEN = 297, PARS_DDOT_TOKEN = 297,
PARS_CONSISTENT_TOKEN = 298, PARS_READ_TOKEN = 298,
PARS_READ_TOKEN = 299, PARS_ORDER_TOKEN = 299,
PARS_ORDER_TOKEN = 300, PARS_BY_TOKEN = 300,
PARS_BY_TOKEN = 301, PARS_ASC_TOKEN = 301,
PARS_ASC_TOKEN = 302, PARS_DESC_TOKEN = 302,
PARS_DESC_TOKEN = 303, PARS_INSERT_TOKEN = 303,
PARS_INSERT_TOKEN = 304, PARS_INTO_TOKEN = 304,
PARS_INTO_TOKEN = 305, PARS_VALUES_TOKEN = 305,
PARS_VALUES_TOKEN = 306, PARS_UPDATE_TOKEN = 306,
PARS_UPDATE_TOKEN = 307, PARS_SET_TOKEN = 307,
PARS_SET_TOKEN = 308, PARS_DELETE_TOKEN = 308,
PARS_DELETE_TOKEN = 309, PARS_CURRENT_TOKEN = 309,
PARS_CURRENT_TOKEN = 310, PARS_OF_TOKEN = 310,
PARS_OF_TOKEN = 311, PARS_CREATE_TOKEN = 311,
PARS_CREATE_TOKEN = 312, PARS_TABLE_TOKEN = 312,
PARS_TABLE_TOKEN = 313, PARS_INDEX_TOKEN = 313,
PARS_INDEX_TOKEN = 314, PARS_UNIQUE_TOKEN = 314,
PARS_UNIQUE_TOKEN = 315, PARS_CLUSTERED_TOKEN = 315,
PARS_CLUSTERED_TOKEN = 316, PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 316,
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317, PARS_ON_TOKEN = 317,
PARS_ON_TOKEN = 318, PARS_ASSIGN_TOKEN = 318,
PARS_ASSIGN_TOKEN = 319, PARS_DECLARE_TOKEN = 319,
PARS_DECLARE_TOKEN = 320, PARS_CURSOR_TOKEN = 320,
PARS_CURSOR_TOKEN = 321, PARS_SQL_TOKEN = 321,
PARS_SQL_TOKEN = 322, PARS_OPEN_TOKEN = 322,
PARS_OPEN_TOKEN = 323, PARS_FETCH_TOKEN = 323,
PARS_FETCH_TOKEN = 324, PARS_CLOSE_TOKEN = 324,
PARS_CLOSE_TOKEN = 325, PARS_NOTFOUND_TOKEN = 325,
PARS_NOTFOUND_TOKEN = 326, PARS_TO_CHAR_TOKEN = 326,
PARS_TO_CHAR_TOKEN = 327, PARS_TO_NUMBER_TOKEN = 327,
PARS_TO_NUMBER_TOKEN = 328, PARS_TO_BINARY_TOKEN = 328,
PARS_TO_BINARY_TOKEN = 329, PARS_BINARY_TO_NUMBER_TOKEN = 329,
PARS_BINARY_TO_NUMBER_TOKEN = 330, PARS_SUBSTR_TOKEN = 330,
PARS_SUBSTR_TOKEN = 331, PARS_REPLSTR_TOKEN = 331,
PARS_REPLSTR_TOKEN = 332, PARS_CONCAT_TOKEN = 332,
PARS_CONCAT_TOKEN = 333, PARS_INSTR_TOKEN = 333,
PARS_INSTR_TOKEN = 334, PARS_LENGTH_TOKEN = 334,
PARS_LENGTH_TOKEN = 335, PARS_SYSDATE_TOKEN = 335,
PARS_SYSDATE_TOKEN = 336, PARS_PRINTF_TOKEN = 336,
PARS_PRINTF_TOKEN = 337, PARS_ASSERT_TOKEN = 337,
PARS_ASSERT_TOKEN = 338, PARS_RND_TOKEN = 338,
PARS_RND_TOKEN = 339, PARS_RND_STR_TOKEN = 339,
PARS_RND_STR_TOKEN = 340, PARS_ROW_PRINTF_TOKEN = 340,
PARS_ROW_PRINTF_TOKEN = 341, PARS_COMMIT_TOKEN = 341,
PARS_COMMIT_TOKEN = 342, PARS_ROLLBACK_TOKEN = 342,
PARS_ROLLBACK_TOKEN = 343, PARS_WORK_TOKEN = 343,
PARS_WORK_TOKEN = 344, PARS_UNSIGNED_TOKEN = 344,
PARS_UNSIGNED_TOKEN = 345, PARS_EXIT_TOKEN = 345,
PARS_EXIT_TOKEN = 346, PARS_FUNCTION_TOKEN = 346,
PARS_FUNCTION_TOKEN = 347, PARS_LOCK_TOKEN = 347,
NEG = 348 PARS_SHARE_TOKEN = 348,
PARS_MODE_TOKEN = 349,
NEG = 350
}; };
#endif #endif
#define PARS_INT_LIT 258 #define PARS_INT_LIT 258
@@ -162,57 +164,59 @@
#define PARS_WHERE_TOKEN 295 #define PARS_WHERE_TOKEN 295
#define PARS_FOR_TOKEN 296 #define PARS_FOR_TOKEN 296
#define PARS_DDOT_TOKEN 297 #define PARS_DDOT_TOKEN 297
#define PARS_CONSISTENT_TOKEN 298 #define PARS_READ_TOKEN 298
#define PARS_READ_TOKEN 299 #define PARS_ORDER_TOKEN 299
#define PARS_ORDER_TOKEN 300 #define PARS_BY_TOKEN 300
#define PARS_BY_TOKEN 301 #define PARS_ASC_TOKEN 301
#define PARS_ASC_TOKEN 302 #define PARS_DESC_TOKEN 302
#define PARS_DESC_TOKEN 303 #define PARS_INSERT_TOKEN 303
#define PARS_INSERT_TOKEN 304 #define PARS_INTO_TOKEN 304
#define PARS_INTO_TOKEN 305 #define PARS_VALUES_TOKEN 305
#define PARS_VALUES_TOKEN 306 #define PARS_UPDATE_TOKEN 306
#define PARS_UPDATE_TOKEN 307 #define PARS_SET_TOKEN 307
#define PARS_SET_TOKEN 308 #define PARS_DELETE_TOKEN 308
#define PARS_DELETE_TOKEN 309 #define PARS_CURRENT_TOKEN 309
#define PARS_CURRENT_TOKEN 310 #define PARS_OF_TOKEN 310
#define PARS_OF_TOKEN 311 #define PARS_CREATE_TOKEN 311
#define PARS_CREATE_TOKEN 312 #define PARS_TABLE_TOKEN 312
#define PARS_TABLE_TOKEN 313 #define PARS_INDEX_TOKEN 313
#define PARS_INDEX_TOKEN 314 #define PARS_UNIQUE_TOKEN 314
#define PARS_UNIQUE_TOKEN 315 #define PARS_CLUSTERED_TOKEN 315
#define PARS_CLUSTERED_TOKEN 316 #define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 316
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317 #define PARS_ON_TOKEN 317
#define PARS_ON_TOKEN 318 #define PARS_ASSIGN_TOKEN 318
#define PARS_ASSIGN_TOKEN 319 #define PARS_DECLARE_TOKEN 319
#define PARS_DECLARE_TOKEN 320 #define PARS_CURSOR_TOKEN 320
#define PARS_CURSOR_TOKEN 321 #define PARS_SQL_TOKEN 321
#define PARS_SQL_TOKEN 322 #define PARS_OPEN_TOKEN 322
#define PARS_OPEN_TOKEN 323 #define PARS_FETCH_TOKEN 323
#define PARS_FETCH_TOKEN 324 #define PARS_CLOSE_TOKEN 324
#define PARS_CLOSE_TOKEN 325 #define PARS_NOTFOUND_TOKEN 325
#define PARS_NOTFOUND_TOKEN 326 #define PARS_TO_CHAR_TOKEN 326
#define PARS_TO_CHAR_TOKEN 327 #define PARS_TO_NUMBER_TOKEN 327
#define PARS_TO_NUMBER_TOKEN 328 #define PARS_TO_BINARY_TOKEN 328
#define PARS_TO_BINARY_TOKEN 329 #define PARS_BINARY_TO_NUMBER_TOKEN 329
#define PARS_BINARY_TO_NUMBER_TOKEN 330 #define PARS_SUBSTR_TOKEN 330
#define PARS_SUBSTR_TOKEN 331 #define PARS_REPLSTR_TOKEN 331
#define PARS_REPLSTR_TOKEN 332 #define PARS_CONCAT_TOKEN 332
#define PARS_CONCAT_TOKEN 333 #define PARS_INSTR_TOKEN 333
#define PARS_INSTR_TOKEN 334 #define PARS_LENGTH_TOKEN 334
#define PARS_LENGTH_TOKEN 335 #define PARS_SYSDATE_TOKEN 335
#define PARS_SYSDATE_TOKEN 336 #define PARS_PRINTF_TOKEN 336
#define PARS_PRINTF_TOKEN 337 #define PARS_ASSERT_TOKEN 337
#define PARS_ASSERT_TOKEN 338 #define PARS_RND_TOKEN 338
#define PARS_RND_TOKEN 339 #define PARS_RND_STR_TOKEN 339
#define PARS_RND_STR_TOKEN 340 #define PARS_ROW_PRINTF_TOKEN 340
#define PARS_ROW_PRINTF_TOKEN 341 #define PARS_COMMIT_TOKEN 341
#define PARS_COMMIT_TOKEN 342 #define PARS_ROLLBACK_TOKEN 342
#define PARS_ROLLBACK_TOKEN 343 #define PARS_WORK_TOKEN 343
#define PARS_WORK_TOKEN 344 #define PARS_UNSIGNED_TOKEN 344
#define PARS_UNSIGNED_TOKEN 345 #define PARS_EXIT_TOKEN 345
#define PARS_EXIT_TOKEN 346 #define PARS_FUNCTION_TOKEN 346
#define PARS_FUNCTION_TOKEN 347 #define PARS_LOCK_TOKEN 347
#define NEG 348 #define PARS_SHARE_TOKEN 348
#define PARS_MODE_TOKEN 349
#define NEG 350

View File

@@ -70,7 +70,6 @@ yylex(void);
%token PARS_WHERE_TOKEN %token PARS_WHERE_TOKEN
%token PARS_FOR_TOKEN %token PARS_FOR_TOKEN
%token PARS_DDOT_TOKEN %token PARS_DDOT_TOKEN
%token PARS_CONSISTENT_TOKEN
%token PARS_READ_TOKEN %token PARS_READ_TOKEN
%token PARS_ORDER_TOKEN %token PARS_ORDER_TOKEN
%token PARS_BY_TOKEN %token PARS_BY_TOKEN
@@ -120,6 +119,9 @@ yylex(void);
%token PARS_UNSIGNED_TOKEN %token PARS_UNSIGNED_TOKEN
%token PARS_EXIT_TOKEN %token PARS_EXIT_TOKEN
%token PARS_FUNCTION_TOKEN %token PARS_FUNCTION_TOKEN
%token PARS_LOCK_TOKEN
%token PARS_SHARE_TOKEN
%token PARS_MODE_TOKEN
%left PARS_AND_TOKEN PARS_OR_TOKEN %left PARS_AND_TOKEN PARS_OR_TOKEN
%left PARS_NOT_TOKEN %left PARS_NOT_TOKEN
@@ -132,9 +134,11 @@ yylex(void);
/* Grammar follows */ /* Grammar follows */
%% %%
top_statement:
procedure_definition ';'
statement: statement:
procedure_definition ';' stored_procedure_call
| stored_procedure_call
| predefined_procedure_call ';' | predefined_procedure_call ';'
| while_statement ';' | while_statement ';'
| for_statement ';' | for_statement ';'
@@ -301,10 +305,10 @@ for_update_clause:
{ $$ = &pars_update_token; } { $$ = &pars_update_token; }
; ;
consistent_read_clause: lock_shared_clause:
/* Nothing */ { $$ = NULL; } /* Nothing */ { $$ = NULL; }
| PARS_CONSISTENT_TOKEN PARS_READ_TOKEN | PARS_LOCK_TOKEN PARS_IN_TOKEN PARS_SHARE_TOKEN PARS_MODE_TOKEN
{ $$ = &pars_consistent_token; } { $$ = &pars_share_token; }
; ;
order_direction: order_direction:
@@ -324,7 +328,7 @@ select_statement:
PARS_FROM_TOKEN table_list PARS_FROM_TOKEN table_list
search_condition search_condition
for_update_clause for_update_clause
consistent_read_clause lock_shared_clause
order_by_clause { $$ = pars_select_statement($2, $4, $5, order_by_clause { $$ = pars_select_statement($2, $4, $5,
$6, $7, $8); } $6, $7, $8); }
; ;

View File

@@ -325,10 +325,6 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_FOR_TOKEN); return(PARS_FOR_TOKEN);
} }
"CONSISTENT" {
return(PARS_CONSISTENT_TOKEN);
}
"READ" { "READ" {
return(PARS_READ_TOKEN); return(PARS_READ_TOKEN);
} }
@@ -517,6 +513,18 @@ In the state 'id', only two actions are possible (defined below). */
return(PARS_FUNCTION_TOKEN); return(PARS_FUNCTION_TOKEN);
} }
"LOCK" {
return(PARS_LOCK_TOKEN);
}
"SHARE" {
return(PARS_SHARE_TOKEN);
}
"MODE" {
return(PARS_MODE_TOKEN);
}
{ID} { {ID} {
yylval = sym_tab_add_id(pars_sym_tab_global, yylval = sym_tab_add_id(pars_sym_tab_global,
(byte*)yytext, (byte*)yytext,

View File

@@ -72,7 +72,7 @@ pars_res_word_t pars_asc_token = {PARS_ASC_TOKEN};
pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN}; pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN};
pars_res_word_t pars_open_token = {PARS_OPEN_TOKEN}; pars_res_word_t pars_open_token = {PARS_OPEN_TOKEN};
pars_res_word_t pars_close_token = {PARS_CLOSE_TOKEN}; pars_res_word_t pars_close_token = {PARS_CLOSE_TOKEN};
pars_res_word_t pars_consistent_token = {PARS_CONSISTENT_TOKEN}; pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN}; pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN}; pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
@@ -699,8 +699,7 @@ pars_select_statement(
sym_node_t* table_list, /* in: table list */ sym_node_t* table_list, /* in: table list */
que_node_t* search_cond, /* in: search condition or NULL */ que_node_t* search_cond, /* in: search condition or NULL */
pars_res_word_t* for_update, /* in: NULL or &pars_update_token */ pars_res_word_t* for_update, /* in: NULL or &pars_update_token */
pars_res_word_t* consistent_read,/* in: NULL or pars_res_word_t* lock_shared, /* in: NULL or &pars_share_token */
&pars_consistent_token */
order_node_t* order_by) /* in: NULL or an order-by node */ order_node_t* order_by) /* in: NULL or an order-by node */
{ {
select_node->state = SEL_NODE_OPEN; select_node->state = SEL_NODE_OPEN;
@@ -734,19 +733,24 @@ pars_select_statement(
} }
if (for_update) { if (for_update) {
ut_a(!consistent_read); ut_a(!lock_shared);
select_node->set_x_locks = TRUE; select_node->set_x_locks = TRUE;
select_node->row_lock_mode = LOCK_X; select_node->row_lock_mode = LOCK_X;
select_node->consistent_read = FALSE;
select_node->read_view = NULL;
} else if (lock_shared){
select_node->set_x_locks = FALSE;
select_node->row_lock_mode = LOCK_S;
select_node->consistent_read = FALSE;
select_node->read_view = NULL;
} else { } else {
select_node->set_x_locks = FALSE; select_node->set_x_locks = FALSE;
select_node->row_lock_mode = LOCK_S; select_node->row_lock_mode = LOCK_S;
}
if (consistent_read) {
select_node->consistent_read = TRUE; select_node->consistent_read = TRUE;
} else {
select_node->consistent_read = FALSE;
select_node->read_view = NULL;
} }
select_node->order_by = order_by; select_node->order_by = order_by;
@@ -976,7 +980,7 @@ pars_update_statement(
sel_node = pars_select_list(NULL, NULL); sel_node = pars_select_list(NULL, NULL);
pars_select_statement(sel_node, table_sym, search_cond, NULL, pars_select_statement(sel_node, table_sym, search_cond, NULL,
NULL, NULL); &pars_share_token, NULL);
node->searched_update = TRUE; node->searched_update = TRUE;
sel_node->common.parent = node; sel_node->common.parent = node;
} }
@@ -1857,8 +1861,9 @@ 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);
pars_sym_tab_global->sql_string = mem_heap_strdup(heap, str);
pars_sym_tab_global->string_len = strlen(str); pars_sym_tab_global->string_len = strlen(str);
pars_sym_tab_global->sql_string = mem_heap_dup(heap, str,
pars_sym_tab_global->string_len + 1);
pars_sym_tab_global->next_char_pos = 0; pars_sym_tab_global->next_char_pos = 0;
pars_sym_tab_global->info = info; pars_sym_tab_global->info = info;

View File

@@ -715,27 +715,6 @@ que_graph_try_free(
return(FALSE); return(FALSE);
} }
/**************************************************************************
Handles an SQL error noticed during query thread execution. Currently,
does nothing! */
void
que_thr_handle_error(
/*=================*/
que_thr_t* thr __attribute__((unused)),
/* in: query thread */
ulint err_no __attribute__((unused)),
/* in: error number */
byte* err_str __attribute__((unused)),
/* in, own: error string or NULL; NOTE: the
function will take care of freeing of the
string! */
ulint err_len __attribute__((unused)))
/* in: error string length */
{
/* Does nothing */
}
/******************************************************************** /********************************************************************
Performs an execution step on a thr node. */ Performs an execution step on a thr node. */
static static
@@ -813,11 +792,10 @@ que_thr_move_to_run_state(
Decrements the query thread reference counts in the query graph and the Decrements the query thread reference counts in the query graph and the
transaction. May start signal handling, e.g., a rollback. transaction. May start signal handling, e.g., a rollback.
*** NOTE ***: *** NOTE ***:
This and que_thr_stop_for_mysql are This and que_thr_stop_for_mysql are the only functions where the reference
the only functions where the reference count can be decremented and count can be decremented and this function may only be called from inside
this function may only be called from inside que_run_threads or que_run_threads or que_thr_check_if_switch! These restrictions exist to make
que_thr_check_if_switch! These restrictions exist to make the rollback code the rollback code easier to maintain. */
easier to maintain. */
static static
void void
que_thr_dec_refer_count( que_thr_dec_refer_count(
@@ -836,7 +814,7 @@ que_thr_dec_refer_count(
ibool stopped; ibool stopped;
fork = thr->common.parent; fork = thr->common.parent;
trx = thr->graph->trx; trx = thr_get_trx(thr);
sess = trx->sess; sess = trx->sess;
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
@@ -856,6 +834,12 @@ que_thr_dec_refer_count(
stderr); */ stderr); */
if (next_thr && *next_thr == NULL) { if (next_thr && *next_thr == NULL) {
/* Normally srv_suspend_mysql_thread resets
the state to DB_SUCCESS before waiting, but
in this case we have to do it here,
otherwise nobody does it. */
trx->error_state = DB_SUCCESS;
*next_thr = thr; *next_thr = thr;
} else { } else {
ut_a(0); ut_a(0);
@@ -1200,7 +1184,10 @@ que_thr_step(
trx_t* trx; trx_t* trx;
ulint type; ulint type;
trx = thr_get_trx(thr);
ut_ad(thr->state == QUE_THR_RUNNING); ut_ad(thr->state == QUE_THR_RUNNING);
ut_a(trx->error_state == DB_SUCCESS);
thr->resource++; thr->resource++;
@@ -1236,7 +1223,6 @@ que_thr_step(
threads doing updating or inserting at the moment! */ threads doing updating or inserting at the moment! */
if (thr->prev_node == que_node_get_parent(node)) { if (thr->prev_node == que_node_get_parent(node)) {
trx = thr_get_trx(thr);
trx->last_sql_stat_start.least_undo_no trx->last_sql_stat_start.least_undo_no
= trx->undo_no; = trx->undo_no;
} }
@@ -1298,24 +1284,28 @@ que_thr_step(
old_thr->prev_node = node; old_thr->prev_node = node;
} }
if (thr) {
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
}
return(thr); return(thr);
} }
/************************************************************************** /**************************************************************************
Runs query threads. Note that the individual query thread which is run Run a query thread until it finishes or encounters e.g. a lock wait. */
within this function may change if, e.g., the OS thread executing this static
function uses a threshold amount of resources. */
void void
que_run_threads( que_run_threads_low(
/*============*/ /*================*/
que_thr_t* thr) /* in: query thread which is run initially */ que_thr_t* thr) /* in: query thread */
{ {
que_thr_t* next_thr; que_thr_t* next_thr;
ulint cumul_resource; ulint cumul_resource;
ulint loop_count; ulint loop_count;
ut_ad(thr->state == QUE_THR_RUNNING); ut_ad(thr->state == QUE_THR_RUNNING);
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(!mutex_own(&kernel_mutex)); ut_ad(!mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@@ -1340,10 +1330,15 @@ loop:
next_thr = que_thr_step(thr); next_thr = que_thr_step(thr);
/*-------------------------*/ /*-------------------------*/
ut_a(!next_thr || (thr_get_trx(next_thr)->error_state == DB_SUCCESS));
loop_count++; loop_count++;
if (next_thr != thr) { if (next_thr != thr) {
ut_a(next_thr == NULL); ut_a(next_thr == NULL);
/* This can change next_thr to a non-NULL value if there was
a lock wait that already completed. */
que_thr_dec_refer_count(thr, &next_thr); que_thr_dec_refer_count(thr, &next_thr);
if (next_thr == NULL) { if (next_thr == NULL) {
@@ -1359,20 +1354,89 @@ loop:
goto loop; goto loop;
} }
/**************************************************************************
Run a query thread. Handles lock waits. */
void
que_run_threads(
/*============*/
que_thr_t* thr) /* in: query thread */
{
loop:
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
que_run_threads_low(thr);
mutex_enter(&kernel_mutex);
switch (thr->state) {
case QUE_THR_RUNNING:
/* There probably was a lock wait, but it already ended
before we came here: continue running thr */
mutex_exit(&kernel_mutex);
goto loop;
case QUE_THR_LOCK_WAIT:
mutex_exit(&kernel_mutex);
/* The ..._mysql_... function works also for InnoDB's
internal threads. Let us wait that the lock wait ends. */
srv_suspend_mysql_thread(thr);
if (thr_get_trx(thr)->error_state != DB_SUCCESS) {
/* thr was chosen as a deadlock victim or there was
a lock wait timeout */
que_thr_dec_refer_count(thr, NULL);
return;
}
goto loop;
case QUE_THR_COMPLETED:
case QUE_THR_COMMAND_WAIT:
/* Do nothing */
break;
default:
ut_error;
}
mutex_exit(&kernel_mutex);
}
/************************************************************************* /*************************************************************************
Evaluate the given SQL */ Evaluate the given SQL. */
ulint ulint
que_eval_sql( que_eval_sql(
/*=========*/ /*=========*/
pars_info_t* info, /* out: error code or DB_SUCCESS */ /* out: error code or DB_SUCCESS */
const char* sql, /* in: info struct, or NULL */ pars_info_t* info, /* in: info struct, or NULL */
const char* sql, /* in: SQL string */
ibool reserve_dict_mutex,
/* in: if TRUE, acquire/release
dict_sys->mutex around call to pars_sql. */
trx_t* trx) /* in: trx */ trx_t* trx) /* in: trx */
{ {
que_thr_t* thr; que_thr_t* thr;
que_t* graph; que_t* graph;
ut_a(trx->error_state == DB_SUCCESS);
if (reserve_dict_mutex) {
mutex_enter(&dict_sys->mutex);
}
graph = pars_sql(info, sql); graph = pars_sql(info, sql);
if (reserve_dict_mutex) {
mutex_exit(&dict_sys->mutex);
}
ut_a(graph); ut_a(graph);
graph->trx = trx; graph->trx = trx;

View File

@@ -607,7 +607,7 @@ row_ins_set_detailed(
rewind(srv_misc_tmpfile); rewind(srv_misc_tmpfile);
if (os_file_set_eof(srv_misc_tmpfile)) { if (os_file_set_eof(srv_misc_tmpfile)) {
ut_print_name(srv_misc_tmpfile, trx, ut_print_name(srv_misc_tmpfile, trx, TRUE,
foreign->foreign_table_name); foreign->foreign_table_name);
dict_print_info_on_foreign_key_in_create_format( dict_print_info_on_foreign_key_in_create_format(
srv_misc_tmpfile, srv_misc_tmpfile,
@@ -649,22 +649,22 @@ row_ins_foreign_report_err(
trx_print(ef, trx, 600); trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef); fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
fputs(":\n", ef); fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign, dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
TRUE); TRUE);
putc('\n', ef); putc('\n', ef);
fputs(errstr, ef); fputs(errstr, ef);
fputs(" in parent table, in index ", ef); fputs(" in parent table, in index ", ef);
ut_print_name(ef, trx, foreign->referenced_index->name); ut_print_name(ef, trx, FALSE, foreign->referenced_index->name);
if (entry) { if (entry) {
fputs(" tuple:\n", ef); fputs(" tuple:\n", ef);
dtuple_print(ef, entry); dtuple_print(ef, entry);
} }
fputs("\nBut in child table ", ef); fputs("\nBut in child table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
fputs(", in index ", ef); fputs(", in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name); ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
if (rec) { if (rec) {
fputs(", there is a record:\n", ef); fputs(", there is a record:\n", ef);
rec_print(ef, rec, foreign->foreign_index); rec_print(ef, rec, foreign->foreign_index);
@@ -702,20 +702,20 @@ row_ins_foreign_report_add_err(
fputs(" Transaction:\n", ef); fputs(" Transaction:\n", ef);
trx_print(ef, trx, 600); trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef); fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
fputs(":\n", ef); fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign, dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
TRUE); TRUE);
fputs("\nTrying to add in child table, in index ", ef); fputs("\nTrying to add in child table, in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name); ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
if (entry) { if (entry) {
fputs(" tuple:\n", ef); fputs(" tuple:\n", ef);
dtuple_print(ef, entry); dtuple_print(ef, entry);
} }
fputs("\nBut in parent table ", ef); fputs("\nBut in parent table ", ef);
ut_print_name(ef, trx, foreign->referenced_table_name); ut_print_name(ef, trx, TRUE, foreign->referenced_table_name);
fputs(", in index ", ef); fputs(", in index ", ef);
ut_print_name(ef, trx, foreign->referenced_index->name); ut_print_name(ef, trx, FALSE, foreign->referenced_index->name);
fputs(",\nthe closest match we can find is record:\n", ef); fputs(",\nthe closest match we can find is record:\n", ef);
if (rec && page_rec_is_supremum(rec)) { if (rec && page_rec_is_supremum(rec)) {
/* If the cursor ended on a supremum record, it is better /* If the cursor ended on a supremum record, it is better
@@ -1283,16 +1283,19 @@ run_again:
fputs(" Transaction:\n", ef); fputs(" Transaction:\n", ef);
trx_print(ef, trx, 600); trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef); fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE,
foreign->foreign_table_name);
fputs(":\n", ef); fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef, dict_print_info_on_foreign_key_in_create_format(ef,
trx, foreign, TRUE); trx, foreign, TRUE);
fputs("\nTrying to add to index ", ef); fputs("\nTrying to add to index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name); ut_print_name(ef, trx, FALSE,
foreign->foreign_index->name);
fputs(" tuple:\n", ef); fputs(" tuple:\n", ef);
dtuple_print(ef, entry); dtuple_print(ef, entry);
fputs("\nBut the parent table ", ef); fputs("\nBut the parent table ", ef);
ut_print_name(ef, trx, foreign->referenced_table_name); ut_print_name(ef, trx, TRUE,
foreign->referenced_table_name);
fputs("\nor its .ibd file does not currently exist!\n", ef); fputs("\nor its .ibd file does not currently exist!\n", ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);

View File

@@ -680,7 +680,7 @@ row_prebuilt_free(
"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name", "InnoDB: table handle. Magic n %lu, magic n2 %lu, table name",
(ulong) prebuilt->magic_n, (ulong) prebuilt->magic_n,
(ulong) prebuilt->magic_n2); (ulong) prebuilt->magic_n2);
ut_print_name(stderr, NULL, prebuilt->table->name); ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
putc('\n', stderr); putc('\n', stderr);
mem_analyze_corruption(prebuilt); mem_analyze_corruption(prebuilt);
@@ -773,7 +773,7 @@ row_update_prebuilt_trx(
"InnoDB: Error: trying to use a corrupt\n" "InnoDB: Error: trying to use a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name", "InnoDB: table handle. Magic n %lu, table name",
(ulong) prebuilt->magic_n); (ulong) prebuilt->magic_n);
ut_print_name(stderr, NULL, prebuilt->table->name); ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
putc('\n', stderr); putc('\n', stderr);
mem_analyze_corruption(prebuilt); mem_analyze_corruption(prebuilt);
@@ -1094,7 +1094,8 @@ row_insert_for_mysql(
"InnoDB: Error: trying to free a corrupt\n" "InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name", "InnoDB: table handle. Magic n %lu, table name",
(ulong) prebuilt->magic_n); (ulong) prebuilt->magic_n);
ut_print_name(stderr, prebuilt->trx, prebuilt->table->name); ut_print_name(stderr, prebuilt->trx, TRUE,
prebuilt->table->name);
putc('\n', stderr); putc('\n', stderr);
mem_analyze_corruption(prebuilt); mem_analyze_corruption(prebuilt);
@@ -1329,7 +1330,8 @@ row_update_for_mysql(
"InnoDB: Error: trying to free a corrupt\n" "InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name", "InnoDB: table handle. Magic n %lu, table name",
(ulong) prebuilt->magic_n); (ulong) prebuilt->magic_n);
ut_print_name(stderr, prebuilt->trx, prebuilt->table->name); ut_print_name(stderr, prebuilt->trx, TRUE,
prebuilt->table->name);
putc('\n', stderr); putc('\n', stderr);
mem_analyze_corruption(prebuilt); mem_analyze_corruption(prebuilt);
@@ -1941,7 +1943,7 @@ row_create_table_for_mysql(
fputs(" InnoDB: Warning: cannot create table ", fputs(" InnoDB: Warning: cannot create table ",
stderr); stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs(" because tablespace full\n", stderr); fputs(" because tablespace full\n", stderr);
if (dict_table_get_low(table->name)) { if (dict_table_get_low(table->name)) {
@@ -1954,7 +1956,7 @@ row_create_table_for_mysql(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr); fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs(" already exists in InnoDB internal\n" fputs(" already exists in InnoDB internal\n"
"InnoDB: data dictionary. Have you deleted the .frm file\n" "InnoDB: data dictionary. Have you deleted the .frm file\n"
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n" "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
@@ -2031,7 +2033,7 @@ row_create_index_for_mysql(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: column ", stderr); fputs(" InnoDB: Error: column ", stderr);
ut_print_name(stderr, trx, ut_print_name(stderr, trx, FALSE,
dict_index_get_nth_field(index, i)->name); dict_index_get_nth_field(index, i)->name);
fputs(" appears twice in ", stderr); fputs(" appears twice in ", stderr);
dict_index_name_print(stderr, trx, index); dict_index_name_print(stderr, trx, index);
@@ -2196,7 +2198,7 @@ row_drop_table_for_mysql_in_background(
trx->check_foreigns = FALSE; trx->check_foreigns = FALSE;
/* fputs("InnoDB: Error: Dropping table ", stderr); /* fputs("InnoDB: Error: Dropping table ", stderr);
ut_print_name(stderr, name); ut_print_name(stderr, trx, TRUE, name);
fputs(" in background drop list\n", stderr); */ fputs(" in background drop list\n", stderr); */
/* Try to drop the table in InnoDB */ /* Try to drop the table in InnoDB */
@@ -2360,7 +2362,7 @@ row_add_table_to_background_drop_list(
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop); UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
/* fputs("InnoDB: Adding table ", stderr); /* fputs("InnoDB: Adding table ", stderr);
ut_print_name(stderr, drop->table_name); ut_print_name(stderr, trx, TRUE, drop->table_name);
fputs(" to background drop list\n", stderr); */ fputs(" to background drop list\n", stderr); */
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
@@ -2429,7 +2431,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
if (table->space == 0) { if (table->space == 0) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr); fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("\n" fputs("\n"
"InnoDB: is in the system tablespace 0 which cannot be discarded\n", stderr); "InnoDB: is in the system tablespace 0 which cannot be discarded\n", stderr);
err = DB_ERROR; err = DB_ERROR;
@@ -2441,7 +2443,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: You are trying to DISCARD table ", stderr); fputs(" InnoDB: You are trying to DISCARD table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n" fputs("\n"
"InnoDB: though there is a foreign key check running on it.\n" "InnoDB: though there is a foreign key check running on it.\n"
"InnoDB: Cannot discard the table.\n", "InnoDB: Cannot discard the table.\n",
@@ -2475,10 +2477,10 @@ do not allow the discard. We also reserve the data dictionary latch. */
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs(" Cannot DISCARD table ", ef); fputs(" Cannot DISCARD table ", ef);
ut_print_name(ef, trx, name); ut_print_name(ef, trx, TRUE, name);
fputs("\n" fputs("\n"
"because it is referenced by ", ef); "because it is referenced by ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
putc('\n', ef); putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
@@ -2501,7 +2503,8 @@ do not allow the discard. We also reserve the data dictionary latch. */
"BEGIN\n" "BEGIN\n"
"SELECT ID INTO old_id\n" "SELECT ID INTO old_id\n"
"FROM SYS_TABLES\n" "FROM SYS_TABLES\n"
"WHERE NAME = :table_name;\n" "WHERE NAME = :table_name\n"
"LOCK IN SHARE MODE;\n"
"IF (SQL % NOTFOUND) THEN\n" "IF (SQL % NOTFOUND) THEN\n"
" COMMIT WORK;\n" " COMMIT WORK;\n"
" RETURN;\n" " RETURN;\n"
@@ -2514,7 +2517,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
" WHERE TABLE_ID = old_id;\n" " WHERE TABLE_ID = old_id;\n"
"COMMIT WORK;\n" "COMMIT WORK;\n"
"END;\n" "END;\n"
, trx); , FALSE, trx);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
@@ -2590,7 +2593,7 @@ row_import_tablespace_for_mysql(
if (!success) { if (!success) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: cannot reset lsn's in table ", stderr); fputs(" InnoDB: Error: cannot reset lsn's in table ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("\n" fputs("\n"
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", stderr); "InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", stderr);
@@ -2611,7 +2614,7 @@ row_import_tablespace_for_mysql(
if (!table) { if (!table) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: table ", stderr); fputs(" InnoDB: table ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("\n" fputs("\n"
"InnoDB: does not exist in the InnoDB data dictionary\n" "InnoDB: does not exist in the InnoDB data dictionary\n"
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", "InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
@@ -2625,7 +2628,7 @@ row_import_tablespace_for_mysql(
if (table->space == 0) { if (table->space == 0) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr); fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("\n" fputs("\n"
"InnoDB: is in the system tablespace 0 which cannot be imported\n", stderr); "InnoDB: is in the system tablespace 0 which cannot be imported\n", stderr);
err = DB_ERROR; err = DB_ERROR;
@@ -2638,7 +2641,7 @@ row_import_tablespace_for_mysql(
fputs( fputs(
" InnoDB: Error: you are trying to IMPORT a tablespace\n" " InnoDB: Error: you are trying to IMPORT a tablespace\n"
"InnoDB: ", stderr); "InnoDB: ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs(", though you have not called DISCARD on it yet\n" fputs(", though you have not called DISCARD on it yet\n"
"InnoDB: during the lifetime of the mysqld process!\n", stderr); "InnoDB: during the lifetime of the mysqld process!\n", stderr);
@@ -2663,7 +2666,7 @@ row_import_tablespace_for_mysql(
fputs( fputs(
" InnoDB: cannot find or open in the database directory the .ibd file of\n" " InnoDB: cannot find or open in the database directory the .ibd file of\n"
"InnoDB: table ", stderr); "InnoDB: table ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("\n" fputs("\n"
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", "InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
stderr); stderr);
@@ -2783,10 +2786,10 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs(" Cannot truncate table ", ef); fputs(" Cannot truncate table ", ef);
ut_print_name(ef, trx, table->name); ut_print_name(ef, trx, TRUE, table->name);
fputs(" by DROP+CREATE\n" fputs(" by DROP+CREATE\n"
"InnoDB: because it is referenced by ", ef); "InnoDB: because it is referenced by ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
putc('\n', ef); putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
@@ -2803,7 +2806,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
if (table->n_foreign_key_checks_running > 0) { if (table->n_foreign_key_checks_running > 0) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Cannot truncate table ", stderr); fputs(" InnoDB: Cannot truncate table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs(" by DROP+CREATE\n" fputs(" by DROP+CREATE\n"
"InnoDB: because there is a foreign key check running on it.\n", "InnoDB: because there is a foreign key check running on it.\n",
stderr); stderr);
@@ -2910,7 +2913,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
" WHERE TABLE_ID = :old_id;\n" " WHERE TABLE_ID = :old_id;\n"
"COMMIT WORK;\n" "COMMIT WORK;\n"
"END;\n" "END;\n"
, trx); , FALSE, trx);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
@@ -2918,7 +2921,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to assign a new identifier to table ", stderr); fputs(" InnoDB: Unable to assign a new identifier to table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n" fputs("\n"
"InnoDB: after truncating it. Background processes may corrupt the table!\n", "InnoDB: after truncating it. Background processes may corrupt the table!\n",
stderr); stderr);
@@ -3045,7 +3048,7 @@ row_drop_table_for_mysql(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr); fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs(" does not exist in the InnoDB internal\n" fputs(" does not exist in the InnoDB internal\n"
"InnoDB: data dictionary though MySQL is trying to drop it.\n" "InnoDB: data dictionary though MySQL is trying to drop it.\n"
"InnoDB: Have you copied the .frm file of the table to the\n" "InnoDB: Have you copied the .frm file of the table to the\n"
@@ -3081,10 +3084,10 @@ row_drop_table_for_mysql(
ut_print_timestamp(ef); ut_print_timestamp(ef);
fputs(" Cannot drop table ", ef); fputs(" Cannot drop table ", ef);
ut_print_name(ef, trx, name); ut_print_name(ef, trx, TRUE, name);
fputs("\n" fputs("\n"
"because it is referenced by ", ef); "because it is referenced by ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name); ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
putc('\n', ef); putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
@@ -3103,7 +3106,7 @@ row_drop_table_for_mysql(
if (added) { if (added) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr); fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n" fputs("\n"
"InnoDB: though there are still open handles to it.\n" "InnoDB: though there are still open handles to it.\n"
"InnoDB: Adding the table to the background drop queue.\n", "InnoDB: Adding the table to the background drop queue.\n",
@@ -3136,7 +3139,7 @@ fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
if (added) { if (added) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: You are trying to drop table ", stderr); fputs(" InnoDB: You are trying to drop table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n" fputs("\n"
"InnoDB: though there is a foreign key check running on it.\n" "InnoDB: though there is a foreign key check running on it.\n"
"InnoDB: Adding the table to the background drop queue.\n", "InnoDB: Adding the table to the background drop queue.\n",
@@ -3180,7 +3183,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
"BEGIN\n" "BEGIN\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"
"LOCK IN SHARE MODE;\n"
"IF (SQL % NOTFOUND) THEN\n" "IF (SQL % NOTFOUND) THEN\n"
" COMMIT WORK;\n" " COMMIT WORK;\n"
" RETURN;\n" " RETURN;\n"
@@ -3188,7 +3192,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
"found := 1;\n" "found := 1;\n"
"SELECT ID INTO sys_foreign_id\n" "SELECT ID INTO sys_foreign_id\n"
"FROM SYS_TABLES\n" "FROM SYS_TABLES\n"
"WHERE NAME = 'SYS_FOREIGN';\n" "WHERE NAME = 'SYS_FOREIGN'\n"
"LOCK IN SHARE MODE;\n"
"IF (SQL % NOTFOUND) THEN\n" "IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n" " found := 0;\n"
"END IF;\n" "END IF;\n"
@@ -3202,7 +3207,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
" SELECT ID INTO foreign_id\n" " SELECT ID INTO foreign_id\n"
" FROM SYS_FOREIGN\n" " FROM SYS_FOREIGN\n"
" WHERE FOR_NAME = :table_name\n" " WHERE FOR_NAME = :table_name\n"
" AND TO_BINARY(FOR_NAME) = TO_BINARY(:table_name);\n" " AND TO_BINARY(FOR_NAME) = TO_BINARY(:table_name)\n"
" LOCK IN SHARE MODE;\n"
" IF (SQL % NOTFOUND) THEN\n" " IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n" " found := 0;\n"
" ELSE" " ELSE"
@@ -3214,7 +3220,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
"WHILE found = 1 LOOP\n" "WHILE found = 1 LOOP\n"
" SELECT ID INTO index_id\n" " SELECT ID INTO index_id\n"
" FROM SYS_INDEXES\n" " FROM SYS_INDEXES\n"
" WHERE TABLE_ID = table_id;\n" " WHERE TABLE_ID = table_id\n"
" LOCK IN SHARE MODE;\n"
" IF (SQL % NOTFOUND) THEN\n" " IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n" " found := 0;\n"
" ELSE" " ELSE"
@@ -3227,7 +3234,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
"DELETE FROM SYS_TABLES WHERE ID = table_id;\n" "DELETE FROM SYS_TABLES WHERE ID = table_id;\n"
"COMMIT WORK;\n" "COMMIT WORK;\n"
"END;\n" "END;\n"
, trx); , FALSE, trx);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
ut_a(err == DB_OUT_OF_FILE_SPACE); ut_a(err == DB_OUT_OF_FILE_SPACE);
@@ -3259,7 +3266,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: not able to remove table ", fputs(" InnoDB: Error: not able to remove table ",
stderr); stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs(" from the dictionary cache!\n", stderr); fputs(" from the dictionary cache!\n", stderr);
err = DB_ERROR; err = DB_ERROR;
} }
@@ -3277,7 +3284,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: We removed now the InnoDB internal data dictionary entry\n" "InnoDB: We removed now the InnoDB internal data dictionary entry\n"
"InnoDB: of table "); "InnoDB: of table ");
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, ".\n"); fprintf(stderr, ".\n");
goto funct_exit; goto funct_exit;
@@ -3289,14 +3296,14 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: We removed now the InnoDB internal data dictionary entry\n" "InnoDB: We removed now the InnoDB internal data dictionary entry\n"
"InnoDB: of table "); "InnoDB: of table ");
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, ".\n"); fprintf(stderr, ".\n");
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: not able to delete tablespace %lu of table ", " InnoDB: Error: not able to delete tablespace %lu of table ",
(ulong) space_id); (ulong) space_id);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("!\n", stderr); fputs("!\n", stderr);
err = DB_ERROR; err = DB_ERROR;
} }
@@ -3364,10 +3371,10 @@ loop:
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs( fputs(
" InnoDB: Warning: MySQL is trying to drop database ", stderr); " InnoDB: Warning: MySQL is trying to drop database ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fputs("\n" fputs("\n"
"InnoDB: though there are still open handles to table ", stderr); "InnoDB: though there are still open handles to table ", stderr);
ut_print_name(stderr, trx, table_name); ut_print_name(stderr, trx, TRUE, table_name);
fputs(".\n", stderr); fputs(".\n", stderr);
os_thread_sleep(1000000); os_thread_sleep(1000000);
@@ -3383,10 +3390,10 @@ loop:
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
fputs("InnoDB: DROP DATABASE ", stderr); fputs("InnoDB: DROP DATABASE ", stderr);
ut_print_name(stderr, trx, name); ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, " failed with error %lu for table ", fprintf(stderr, " failed with error %lu for table ",
(ulint) err); (ulint) err);
ut_print_name(stderr, trx, table_name); ut_print_name(stderr, trx, TRUE, table_name);
putc('\n', stderr); putc('\n', stderr);
break; break;
} }
@@ -3436,7 +3443,7 @@ row_delete_constraint_low(
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n"
"DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n"
"END;\n" "END;\n"
, trx)); , FALSE, trx));
} }
/******************************************************************** /********************************************************************
@@ -3543,7 +3550,7 @@ row_rename_table_for_mysql(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr); fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, old_name); ut_print_name(stderr, trx, TRUE, old_name);
fputs(" does not exist in the InnoDB internal\n" fputs(" does not exist in the InnoDB internal\n"
"InnoDB: data dictionary though MySQL is trying to rename the table.\n" "InnoDB: data dictionary though MySQL is trying to rename the table.\n"
"InnoDB: Have you copied the .frm file of the table to the\n" "InnoDB: Have you copied the .frm file of the table to the\n"
@@ -3559,7 +3566,7 @@ row_rename_table_for_mysql(
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr); fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, old_name); ut_print_name(stderr, trx, TRUE, old_name);
fputs( fputs(
" does not have an .ibd file in the database directory.\n" " does not have an .ibd file in the database directory.\n"
"InnoDB: You can look for further help from\n" "InnoDB: You can look for further help from\n"
@@ -3602,7 +3609,7 @@ row_rename_table_for_mysql(
"UPDATE SYS_TABLES SET NAME = :new_table_name\n" "UPDATE SYS_TABLES SET NAME = :new_table_name\n"
" WHERE NAME = :old_table_name;\n" " WHERE NAME = :old_table_name;\n"
"END;\n" "END;\n"
, trx); , FALSE, trx);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
@@ -3639,7 +3646,8 @@ row_rename_table_for_mysql(
" SELECT ID INTO foreign_id\n" " SELECT ID INTO foreign_id\n"
" FROM SYS_FOREIGN\n" " FROM SYS_FOREIGN\n"
" WHERE FOR_NAME = :old_table_name\n" " WHERE FOR_NAME = :old_table_name\n"
" AND TO_BINARY(FOR_NAME) = TO_BINARY(:old_table_name);\n" " AND TO_BINARY(FOR_NAME) = TO_BINARY(:old_table_name)\n"
" LOCK IN SHARE MODE;\n"
" IF (SQL % NOTFOUND) THEN\n" " IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n" " found := 0;\n"
" ELSE\n" " ELSE\n"
@@ -3675,7 +3683,7 @@ row_rename_table_for_mysql(
"WHERE REF_NAME = :old_table_name\n" "WHERE REF_NAME = :old_table_name\n"
" AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);\n" " AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);\n"
"END;\n" "END;\n"
, trx); , FALSE, trx);
} else if (n_constraints_to_drop > 0) { } else if (n_constraints_to_drop > 0) {
/* Drop some constraints of tmp tables. */ /* Drop some constraints of tmp tables. */
@@ -3704,17 +3712,17 @@ end:
"InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n" "InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n"
"InnoDB: to have the same internal name in case-insensitive comparison.\n" "InnoDB: to have the same internal name in case-insensitive comparison.\n"
"InnoDB: 2) table ", stderr); "InnoDB: 2) table ", stderr);
ut_print_name(stderr, trx, new_name); ut_print_name(stderr, trx, TRUE, new_name);
fputs(" exists in the InnoDB internal data\n" fputs(" exists in the InnoDB internal data\n"
"InnoDB: dictionary though MySQL is trying rename table ", stderr); "InnoDB: dictionary though MySQL is trying rename table ", stderr);
ut_print_name(stderr, trx, old_name); ut_print_name(stderr, trx, TRUE, old_name);
fputs(" to it.\n" fputs(" to it.\n"
"InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n" "InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n"
"InnoDB: You can look for further help from\n" "InnoDB: You can look for further help from\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/" "InnoDB: http://dev.mysql.com/doc/mysql/en/"
"InnoDB_troubleshooting_datadict.html\n" "InnoDB_troubleshooting_datadict.html\n"
"InnoDB: If table ", stderr); "InnoDB: If table ", stderr);
ut_print_name(stderr, trx, new_name); ut_print_name(stderr, trx, TRUE, new_name);
fputs( fputs(
" is a temporary table #sql..., then it can be that\n" " is a temporary table #sql..., then it can be that\n"
"InnoDB: there are still queries running on the table, and it will be\n" "InnoDB: there are still queries running on the table, and it will be\n"
@@ -3742,9 +3750,9 @@ end:
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error in table rename, cannot rename ", fputs(" InnoDB: Error in table rename, cannot rename ",
stderr); stderr);
ut_print_name(stderr, trx, old_name); ut_print_name(stderr, trx, TRUE, old_name);
fputs(" to ", stderr); fputs(" to ", stderr);
ut_print_name(stderr, trx, new_name); ut_print_name(stderr, trx, TRUE, new_name);
putc('\n', stderr); putc('\n', stderr);
err = DB_ERROR; err = DB_ERROR;
@@ -3763,7 +3771,7 @@ end:
if (old_is_tmp) { if (old_is_tmp) {
fputs(" InnoDB: Error: in ALTER TABLE ", fputs(" InnoDB: Error: in ALTER TABLE ",
stderr); stderr);
ut_print_name(stderr, trx, new_name); ut_print_name(stderr, trx, TRUE, new_name);
fputs("\n" fputs("\n"
"InnoDB: has or is referenced in foreign key constraints\n" "InnoDB: has or is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n", "InnoDB: which are not compatible with the new table definition.\n",
@@ -3772,7 +3780,7 @@ end:
fputs( fputs(
" InnoDB: Error: in RENAME TABLE table ", " InnoDB: Error: in RENAME TABLE table ",
stderr); stderr);
ut_print_name(stderr, trx, new_name); ut_print_name(stderr, trx, TRUE, new_name);
fputs("\n" fputs("\n"
"InnoDB: is referenced in foreign key constraints\n" "InnoDB: is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n", "InnoDB: which are not compatible with the new table definition.\n",
@@ -3986,7 +3994,7 @@ row_check_table_for_mysql(
while (index != NULL) { while (index != NULL) {
/* fputs("Validating index ", stderr); /* fputs("Validating index ", stderr);
ut_print_name(stderr, index->name); ut_print_name(stderr, trx, FALSE, index->name);
putc('\n', stderr); */ putc('\n', stderr); */
if (!btr_validate_tree(index->tree, prebuilt->trx)) { if (!btr_validate_tree(index->tree, prebuilt->trx)) {

View File

@@ -440,12 +440,12 @@ row_build_row_ref_in_tuple(
ut_a(ref && index && rec); ut_a(ref && index && rec);
if (!index->table) { if (UNIV_UNLIKELY(!index->table)) {
fputs("InnoDB: table ", stderr); fputs("InnoDB: table ", stderr);
notfound: notfound:
ut_print_name(stderr, trx, index->table_name); ut_print_name(stderr, trx, TRUE, index->table_name);
fputs(" for index ", stderr); fputs(" for index ", stderr);
ut_print_name(stderr, trx, index->name); ut_print_name(stderr, trx, FALSE, index->name);
fputs(" not found\n", stderr); fputs(" not found\n", stderr);
ut_error; ut_error;
} }

View File

@@ -45,6 +45,9 @@ to que_run_threads: this is to allow canceling runaway queries */
#define SEL_COST_LIMIT 100 #define SEL_COST_LIMIT 100
/* The lower limit for what we consider a "big" row */
#define BIG_ROW_SIZE 1024
/* Flags for search shortcut */ /* Flags for search shortcut */
#define SEL_FOUND 0 #define SEL_FOUND 0
#define SEL_EXHAUSTED 1 #define SEL_EXHAUSTED 1
@@ -302,19 +305,45 @@ row_sel_fetch_columns(
} }
while (column) { while (column) {
mem_heap_t* heap = NULL;
ibool needs_copy;
field_no = column->field_nos[index_type]; field_no = column->field_nos[index_type];
if (field_no != ULINT_UNDEFINED) { if (field_no != ULINT_UNDEFINED) {
data = rec_get_nth_field(rec, offsets, field_no, &len); if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
field_no))) {
if (column->copy_val) { /* Copy an externally stored field to the
temporary heap */
heap = mem_heap_create(1);
data = btr_rec_copy_externally_stored_field(
rec, offsets, field_no, &len, heap);
ut_a(len != UNIV_SQL_NULL);
needs_copy = TRUE;
} else {
data = rec_get_nth_field(rec, offsets,
field_no, &len);
needs_copy = column->copy_val;
}
if (needs_copy) {
eval_node_copy_and_alloc_val(column, data, eval_node_copy_and_alloc_val(column, data,
len); len);
} else { } else {
val = que_node_get_val(column); val = que_node_get_val(column);
dfield_set_data(val, data, len); dfield_set_data(val, data, len);
} }
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
} }
column = UT_LIST_GET_NEXT(col_var_list, column); column = UT_LIST_GET_NEXT(col_var_list, column);
@@ -1106,11 +1135,12 @@ row_sel_try_search_shortcut(
ut_ad(plan->pcur.latch_mode == node->latch_mode); ut_ad(plan->pcur.latch_mode == node->latch_mode);
plan->n_rows_fetched++; plan->n_rows_fetched++;
ret = SEL_FOUND;
func_exit: func_exit:
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
} }
return(SEL_FOUND); return(ret);
} }
/************************************************************************* /*************************************************************************
@@ -1214,7 +1244,8 @@ table_loop:
mtr_start(&mtr); mtr_start(&mtr);
if (consistent_read && plan->unique_search && !plan->pcur_is_open if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust) { && !plan->must_get_clust
&& (plan->table->max_row_size < BIG_ROW_SIZE)) {
if (!search_latch_locked) { if (!search_latch_locked) {
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);
@@ -1328,6 +1359,12 @@ rec_loop:
if (srv_locks_unsafe_for_binlog if (srv_locks_unsafe_for_binlog
|| trx->isolation_level == TRX_ISO_READ_COMMITTED) { || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
if (page_rec_is_supremum(next_rec)) {
goto skip_lock;
}
lock_type = LOCK_REC_NOT_GAP; lock_type = LOCK_REC_NOT_GAP;
} else { } else {
lock_type = LOCK_ORDINARY; lock_type = LOCK_ORDINARY;
@@ -1346,6 +1383,7 @@ rec_loop:
} }
} }
skip_lock:
if (page_rec_is_infimum(rec)) { if (page_rec_is_infimum(rec)) {
/* The infimum record on a page cannot be in the result set, /* The infimum record on a page cannot be in the result set,
@@ -1376,6 +1414,12 @@ rec_loop:
if (srv_locks_unsafe_for_binlog if (srv_locks_unsafe_for_binlog
|| trx->isolation_level == TRX_ISO_READ_COMMITTED) { || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
if (page_rec_is_supremum(rec)) {
goto next_rec;
}
lock_type = LOCK_REC_NOT_GAP; lock_type = LOCK_REC_NOT_GAP;
} else { } else {
lock_type = LOCK_ORDINARY; lock_type = LOCK_ORDINARY;
@@ -1602,7 +1646,8 @@ rec_loop:
} }
if ((plan->n_rows_fetched <= SEL_PREFETCH_LIMIT) if ((plan->n_rows_fetched <= SEL_PREFETCH_LIMIT)
|| plan->unique_search || plan->no_prefetch) { || plan->unique_search || plan->no_prefetch
|| (plan->table->max_row_size >= BIG_ROW_SIZE)) {
/* No prefetch in operation: go to the next table */ /* No prefetch in operation: go to the next table */
@@ -1888,9 +1933,8 @@ row_sel_step(
err = lock_table(0, table_node->table, err = lock_table(0, table_node->table,
i_lock_mode, thr); i_lock_mode, thr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
thr_get_trx(thr)->error_state = err;
que_thr_handle_error(thr, DB_ERROR,
NULL, 0);
return(NULL); return(NULL);
} }
@@ -1926,17 +1970,8 @@ row_sel_step(
thr->graph->last_sel_node = node; thr->graph->last_sel_node = node;
if (err == DB_SUCCESS) { if (err != DB_SUCCESS) {
/* Ok: do nothing */ thr_get_trx(thr)->error_state = err;
} else if (err == DB_LOCK_WAIT) {
return(NULL);
} else {
/* SQL error detected */
fprintf(stderr, "SQL error %lu\n", (ulong) err);
que_thr_handle_error(thr, DB_ERROR, NULL, 0);
return(NULL); return(NULL);
} }
@@ -1997,7 +2032,7 @@ fetch_step(
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: fetch called on a closed cursor\n"); "InnoDB: Error: fetch called on a closed cursor\n");
que_thr_handle_error(thr, DB_ERROR, NULL, 0); thr_get_trx(thr)->error_state = DB_ERROR;
return(NULL); return(NULL);
} }
@@ -2546,6 +2581,7 @@ row_sel_store_mysql_rec(
{ {
mysql_row_templ_t* templ; mysql_row_templ_t* templ;
mem_heap_t* extern_field_heap = NULL; mem_heap_t* extern_field_heap = NULL;
mem_heap_t* heap;
byte* data; byte* data;
ulint len; ulint len;
ulint i; ulint i;
@@ -2570,7 +2606,19 @@ row_sel_store_mysql_rec(
ut_a(!prebuilt->trx->has_search_latch); ut_a(!prebuilt->trx->has_search_latch);
extern_field_heap = mem_heap_create(UNIV_PAGE_SIZE); if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
if (prebuilt->blob_heap == NULL) {
prebuilt->blob_heap =
mem_heap_create(UNIV_PAGE_SIZE);
}
heap = prebuilt->blob_heap;
} else {
extern_field_heap =
mem_heap_create(UNIV_PAGE_SIZE);
heap = extern_field_heap;
}
/* NOTE: if we are retrieving a big BLOB, we may /* NOTE: if we are retrieving a big BLOB, we may
already run out of memory in the next call, which already run out of memory in the next call, which
@@ -2578,7 +2626,7 @@ row_sel_store_mysql_rec(
data = btr_rec_copy_externally_stored_field(rec, data = btr_rec_copy_externally_stored_field(rec,
offsets, templ->rec_field_no, &len, offsets, templ->rec_field_no, &len,
extern_field_heap); heap);
ut_a(len != UNIV_SQL_NULL); ut_a(len != UNIV_SQL_NULL);
} else { } else {
@@ -2589,48 +2637,6 @@ row_sel_store_mysql_rec(
} }
if (len != UNIV_SQL_NULL) { if (len != UNIV_SQL_NULL) {
if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
ut_a(prebuilt->templ_contains_blob);
/* A heuristic test that we can allocate the
memory for a big BLOB. We have a safety margin
of 1000000 bytes. Since the test takes some
CPU time, we do not use it for small BLOBs. */
if (UNIV_UNLIKELY(len > 2000000)
&& UNIV_UNLIKELY(!ut_test_malloc(
len + 1000000))) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: could not allocate %lu + 1000000 bytes to retrieve\n"
"InnoDB: a big column. Table name ", (ulong) len);
ut_print_name(stderr,
prebuilt->trx,
prebuilt->table->name);
putc('\n', stderr);
if (extern_field_heap) {
mem_heap_free(
extern_field_heap);
}
return(FALSE);
}
/* Copy the BLOB data to the BLOB heap of
prebuilt */
if (prebuilt->blob_heap == NULL) {
prebuilt->blob_heap =
mem_heap_create(len);
}
data = memcpy(mem_heap_alloc(
prebuilt->blob_heap, len),
data, len);
}
row_sel_field_store_in_mysql_format( row_sel_field_store_in_mysql_format(
mysql_rec + templ->mysql_col_offset, mysql_rec + templ->mysql_col_offset,
templ, data, len); templ, data, len);
@@ -3250,7 +3256,7 @@ row_search_for_mysql(
"InnoDB: Error: trying to free a corrupt\n" "InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name ", "InnoDB: table handle. Magic n %lu, table name ",
(ulong) prebuilt->magic_n); (ulong) prebuilt->magic_n);
ut_print_name(stderr, trx, prebuilt->table->name); ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
putc('\n', stderr); putc('\n', stderr);
mem_analyze_corruption(prebuilt); mem_analyze_corruption(prebuilt);
@@ -3536,15 +3542,13 @@ shortcut_fails_too_big_rec:
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
&& prebuilt->select_lock_type != LOCK_NONE && prebuilt->select_lock_type != LOCK_NONE
&& trx->mysql_query_str) { && trx->mysql_query_str && trx->mysql_thd) {
/* Scan the MySQL query string; check if SELECT is the first /* Scan the MySQL query string; check if SELECT is the first
word there */ word there */
ibool success;
dict_accept(*trx->mysql_query_str, "SELECT", &success); if (dict_str_starts_with_keyword(trx->mysql_thd,
*trx->mysql_query_str, "SELECT")) {
if (success) {
/* It is a plain locking SELECT and the isolation /* It is a plain locking SELECT and the isolation
level is low: do not lock gaps */ level is low: do not lock gaps */

View File

@@ -2008,12 +2008,7 @@ row_upd_step(
error_handling: error_handling:
trx->error_state = err; trx->error_state = err;
if (err == DB_SUCCESS) { if (err != DB_SUCCESS) {
/* Ok: do nothing */
} else if (err == DB_LOCK_WAIT) {
return(NULL);
} else {
return(NULL); return(NULL);
} }

View File

@@ -68,6 +68,9 @@ ibool srv_error_monitor_active = FALSE;
const char* srv_main_thread_op_info = ""; const char* srv_main_thread_op_info = "";
/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
const char srv_mysql50_table_name_prefix[9] = "#mysql50#";
/* Server parameters which are read from the initfile */ /* Server parameters which are read from the initfile */
/* The following three are dir paths which are catenated before file /* The following three are dir paths which are catenated before file

View File

@@ -843,7 +843,7 @@ trx_undo_update_rec_get_update(
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n"
"InnoDB: Run also CHECK TABLE ", "InnoDB: Run also CHECK TABLE ",
(ulong) dict_index_get_n_fields(index)); (ulong) dict_index_get_n_fields(index));
ut_print_name(stderr, trx, index->table_name); ut_print_name(stderr, trx, TRUE, index->table_name);
fprintf(stderr, "\n" fprintf(stderr, "\n"
"InnoDB: n_fields = %lu, i = %lu, ptr %p\n", "InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
(ulong) n_fields, (ulong) i, ptr); (ulong) n_fields, (ulong) i, ptr);

View File

@@ -241,7 +241,7 @@ trx_rollback_to_savepoint_for_mysql(
if (trx->conc_state == TRX_NOT_STARTED) { if (trx->conc_state == TRX_NOT_STARTED) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: transaction has a savepoint ", stderr); fputs(" InnoDB: Error: transaction has a savepoint ", stderr);
ut_print_name(stderr, trx, savep->name); ut_print_name(stderr, trx, FALSE, savep->name);
fputs(" though it is not started\n", stderr); fputs(" though it is not started\n", stderr);
return(DB_ERROR); return(DB_ERROR);
} }
@@ -544,7 +544,7 @@ loop:
if (table) { if (table) {
fputs("InnoDB: Table found: dropping table ", stderr); fputs("InnoDB: Table found: dropping table ", stderr);
ut_print_name(stderr, trx, table->name); ut_print_name(stderr, trx, TRUE, table->name);
fputs(" in recovery\n", stderr); fputs(" in recovery\n", stderr);
err = row_drop_table_for_mysql(table->name, trx, TRUE); err = row_drop_table_for_mysql(table->name, trx, TRUE);
@@ -1286,7 +1286,6 @@ trx_rollback_step(
que_thr_t* thr) /* in: query thread */ que_thr_t* thr) /* in: query thread */
{ {
roll_node_t* node; roll_node_t* node;
ibool success;
ulint sig_no; ulint sig_no;
trx_savept_t* savept; trx_savept_t* savept;
@@ -1313,19 +1312,13 @@ trx_rollback_step(
/* Send a rollback signal to the transaction */ /* Send a rollback signal to the transaction */
success = trx_sig_send(thr_get_trx(thr), trx_sig_send(thr_get_trx(thr), sig_no, TRX_SIG_SELF, thr,
sig_no, TRX_SIG_SELF, savept, NULL);
thr, savept, NULL);
thr->state = QUE_THR_SIG_REPLY_WAIT; thr->state = QUE_THR_SIG_REPLY_WAIT;
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
if (!success) {
/* Error in delivering the rollback signal */
que_thr_handle_error(thr, DB_ERROR, NULL, 0);
}
return(NULL); return(NULL);
} }

View File

@@ -1223,11 +1223,9 @@ trx_sig_is_compatible(
/******************************************************************** /********************************************************************
Sends a signal to a trx object. */ Sends a signal to a trx object. */
ibool void
trx_sig_send( trx_sig_send(
/*=========*/ /*=========*/
/* out: TRUE if the signal was
successfully delivered */
trx_t* trx, /* in: trx handle */ trx_t* trx, /* in: trx handle */
ulint type, /* in: signal type */ ulint type, /* in: signal type */
ulint sender, /* in: TRX_SIG_SELF or ulint sender, /* in: TRX_SIG_SELF or
@@ -1254,11 +1252,9 @@ trx_sig_send(
if (!trx_sig_is_compatible(trx, type, sender)) { if (!trx_sig_is_compatible(trx, type, sender)) {
/* The signal is not compatible with the other signals in /* The signal is not compatible with the other signals in
the queue: do nothing */ the queue: die */
ut_error; ut_error;
return(FALSE);
} }
/* Queue the signal object */ /* Queue the signal object */
@@ -1299,11 +1295,6 @@ trx_sig_send(
} }
if ((sender != TRX_SIG_SELF) || (type == TRX_SIG_BREAK_EXECUTION)) { if ((sender != TRX_SIG_SELF) || (type == TRX_SIG_BREAK_EXECUTION)) {
/* The following call will add a TRX_SIG_ERROR_OCCURRED
signal to the end of the queue, if the session is not yet
in the error state: */
ut_error; ut_error;
} }
@@ -1314,8 +1305,6 @@ trx_sig_send(
trx_sig_start_handle(trx, next_thr); trx_sig_start_handle(trx, next_thr);
} }
return(TRUE);
} }
/******************************************************************** /********************************************************************
@@ -1541,7 +1530,6 @@ trx_commit_step(
{ {
commit_node_t* node; commit_node_t* node;
que_thr_t* next_thr; que_thr_t* next_thr;
ibool success;
node = thr->run_node; node = thr->run_node;
@@ -1562,16 +1550,11 @@ trx_commit_step(
/* Send the commit signal to the transaction */ /* Send the commit signal to the transaction */
success = trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, TRX_SIG_SELF,
TRX_SIG_SELF, thr, NULL, &next_thr); thr, NULL, &next_thr);
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
if (!success) {
/* Error in delivering the commit signal */
que_thr_handle_error(thr, DB_ERROR, NULL, 0);
}
return(next_thr); return(next_thr);
} }

View File

@@ -20,18 +20,21 @@ Created 5/11/1994 Heikki Tuuri
ibool ut_always_false = FALSE; ibool ut_always_false = FALSE;
#ifndef UNIV_HOTBACKUP
/********************************************************************* /*********************************************************************
Get the quote character to be used in SQL identifiers. Display an SQL identifier.
This definition must match the one in sql/ha_innodb.cc! */ This definition must match the one in sql/ha_innodb.cc! */
extern extern
int void
mysql_get_identifier_quote_char( innobase_print_identifier(
/*============================*/ /*======================*/
/* out: quote character to be FILE* f, /* in: output stream */
used in SQL identifiers; EOF if none */
trx_t* trx, /* in: transaction */ trx_t* trx, /* in: transaction */
ibool table_id,/* in: TRUE=print a table name,
FALSE=print other identifier */
const char* name, /* in: name to print */ const char* name, /* in: name to print */
ulint namelen);/* in: length of name */ ulint namelen);/* in: length of name */
#endif /* !UNIV_HOTBACKUP */
/************************************************************ /************************************************************
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,
@@ -398,9 +401,11 @@ ut_print_name(
/*==========*/ /*==========*/
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */ trx_t* trx, /* in: transaction */
ibool table_id,/* in: TRUE=print a table name,
FALSE=print other identifier */
const char* name) /* in: name to print */ const char* name) /* in: name to print */
{ {
ut_print_namel(f, trx, name, strlen(name)); ut_print_namel(f, trx, table_id, name, strlen(name));
} }
/************************************************************************** /**************************************************************************
@@ -411,29 +416,28 @@ ut_print_namel(
/*===========*/ /*===========*/
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction (NULL=no quotes) */ trx_t* trx, /* in: transaction (NULL=no quotes) */
ibool table_id,/* in: TRUE=print a table name,
FALSE=print other identifier */
const char* name, /* in: name to print */ const char* name, /* in: name to print */
ulint namelen)/* in: length of name */ ulint namelen)/* in: length of name */
{ {
const char* s = name;
const char* e = s + namelen;
#ifdef UNIV_HOTBACKUP #ifdef UNIV_HOTBACKUP
int q = '"'; fwrite(name, 1, namelen, f);
#else #else
int q = mysql_get_identifier_quote_char(trx, name, namelen); char* slash = strchr(name, '/');
if (UNIV_LIKELY_NULL(slash)) {
/* Print the database name and table name separately. */
ut_ad(table_id);
innobase_print_identifier(f, trx, TRUE, name, slash - name);
putc('.', f);
innobase_print_identifier(f, trx, TRUE, slash + 1,
namelen - (slash - name) - 1);
} else {
innobase_print_identifier(f, trx, table_id, name, namelen);
}
#endif #endif
if (q == EOF) {
fwrite(name, 1, namelen, f);
return;
}
putc(q, f);
while (s < e) {
int c = *s++;
if (c == q) {
putc(c, f);
}
putc(c, f);
}
putc(q, f);
} }
/************************************************************************** /**************************************************************************