mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 19:11:46 +01:00
branches/zip: Merge revisions 583:634 from trunk.
This commit is contained in:
parent
ecb6a00408
commit
645e56909f
42 changed files with 2782 additions and 1812 deletions
|
@ -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/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 \
|
||||
cmakelists.txt
|
||||
CMakeLists.txt
|
||||
|
||||
noinst_LIBRARIES = libinnobase.a
|
||||
libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \
|
||||
|
|
|
@ -618,9 +618,9 @@ btr_page_get_father_for_rec(
|
|||
buf_page_print(buf_frame_align(node_ptr), 0);
|
||||
|
||||
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);
|
||||
ut_print_name(stderr, NULL, index->name);
|
||||
ut_print_name(stderr, NULL, FALSE, index->name);
|
||||
fprintf(stderr, ",\n"
|
||||
"InnoDB: father ptr page no %lu, child page no %lu\n",
|
||||
(ulong)
|
||||
|
|
|
@ -488,7 +488,7 @@ retry_page_get:
|
|||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return;
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
/* Insert to the insert buffer did not succeed:
|
||||
|
@ -626,6 +626,7 @@ retry_page_get:
|
|||
|| mode != PAGE_CUR_LE);
|
||||
}
|
||||
|
||||
func_exit:
|
||||
if (has_search_latch) {
|
||||
|
||||
rw_lock_s_lock(&btr_search_latch);
|
||||
|
|
|
@ -293,3 +293,36 @@ dtype_print(
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
, FALSE, trx);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
fprintf(stderr, "InnoDB: error %lu in creation\n",
|
||||
|
@ -1261,7 +1261,7 @@ dict_foreign_eval_sql(
|
|||
ulint error;
|
||||
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) {
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
|
@ -1269,9 +1269,9 @@ dict_foreign_eval_sql(
|
|||
ut_print_timestamp(ef);
|
||||
fputs(" Error in foreign key constraint creation for table ",
|
||||
ef);
|
||||
ut_print_name(ef, trx, table->name);
|
||||
ut_print_name(ef, trx, TRUE, table->name);
|
||||
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."
|
||||
" (Note that internally InnoDB adds 'databasename/'\n"
|
||||
"in front of the user-defined constraint name).\n",
|
||||
|
@ -1299,7 +1299,7 @@ dict_foreign_eval_sql(
|
|||
ut_print_timestamp(ef);
|
||||
fputs(" Internal error in foreign key constraint creation"
|
||||
" for table ", ef);
|
||||
ut_print_name(ef, trx, table->name);
|
||||
ut_print_name(ef, trx, TRUE, table->name);
|
||||
fputs(".\n"
|
||||
"See the MySQL .err log in the datadir for more information.\n", ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
|
351
dict/dict0dict.c
351
dict/dict0dict.c
|
@ -26,6 +26,9 @@ Created 1/8/1996 Heikki Tuuri
|
|||
#include "pars0sym.h"
|
||||
#include "que0que.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 */
|
||||
|
||||
|
@ -55,6 +58,42 @@ static char dict_ibfk[] = "_ibfk_";
|
|||
|
||||
#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.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
|
@ -77,6 +116,17 @@ void
|
|||
innobase_casedn_str(
|
||||
/*================*/
|
||||
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 */
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -227,7 +277,7 @@ dict_tables_have_same_db(
|
|||
|
||||
/************************************************************************
|
||||
Return the end of table name where we have removed dbname and '/'. */
|
||||
static
|
||||
|
||||
const char*
|
||||
dict_remove_db_name(
|
||||
/*================*/
|
||||
|
@ -853,6 +903,7 @@ dict_table_add_to_cache(
|
|||
ulint fold;
|
||||
ulint id_fold;
|
||||
ulint i;
|
||||
ulint row_len;
|
||||
|
||||
dict_table_add_system_columns(table);
|
||||
|
||||
|
@ -861,6 +912,24 @@ dict_table_add_to_cache(
|
|||
fold = ut_fold_string(table->name);
|
||||
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 */
|
||||
{
|
||||
dict_table_t* table2;
|
||||
|
@ -1403,6 +1472,7 @@ dict_index_add_to_cache(
|
|||
|
||||
ut_ad(mem_heap_validate(index->heap));
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
dict_index_t* index2;
|
||||
index2 = UT_LIST_GET_FIRST(table->indexes);
|
||||
|
@ -1412,10 +1482,11 @@ dict_index_add_to_cache(
|
|||
|
||||
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);
|
||||
|
||||
|
@ -2048,6 +2119,7 @@ dict_foreign_find(
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/*************************************************************************
|
||||
Tries to find an index whose first fields are the columns in the array,
|
||||
in the same order. */
|
||||
|
@ -2064,7 +2136,6 @@ dict_foreign_find_index(
|
|||
ibool check_charsets)/* in: whether to check charsets.
|
||||
only has an effect if types_idx != NULL. */
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
dict_index_t* index;
|
||||
const char* col_name;
|
||||
ulint i;
|
||||
|
@ -2110,13 +2181,6 @@ dict_foreign_find_index(
|
|||
}
|
||||
|
||||
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);
|
||||
if (fk->foreign_index) {
|
||||
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(
|
||||
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
|
||||
"for correct foreign key definition.\n",
|
||||
|
@ -2315,12 +2379,13 @@ dict_scan_to(
|
|||
|
||||
/*************************************************************************
|
||||
Accepts a specified string. Comparisons are case-insensitive. */
|
||||
|
||||
static
|
||||
const char*
|
||||
dict_accept(
|
||||
/*========*/
|
||||
/* out: if string was accepted, the pointer
|
||||
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* string, /* in: accept only this string as the next
|
||||
non-whitespace string */
|
||||
|
@ -2331,7 +2396,7 @@ dict_accept(
|
|||
|
||||
*success = FALSE;
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
while (my_isspace(cs, *ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
|
@ -2356,12 +2421,15 @@ const char*
|
|||
dict_scan_id(
|
||||
/*=========*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
mem_heap_t* heap, /* in: heap where to allocate the id
|
||||
(NULL=id will not be allocated, but it
|
||||
will point to string near ptr) */
|
||||
const char** id, /* out,own: the id; NULL if no id was
|
||||
scannable */
|
||||
ibool table_id,/* in: TRUE=convert the allocated id
|
||||
as a table name; FALSE=convert to UTF-8 */
|
||||
ibool accept_also_dot)
|
||||
/* in: TRUE if also a dot can appear in a
|
||||
non-quoted id; in a quoted id it can appear
|
||||
|
@ -2370,13 +2438,12 @@ dict_scan_id(
|
|||
char quote = '\0';
|
||||
ulint len = 0;
|
||||
const char* s;
|
||||
char* d;
|
||||
ulint id_len;
|
||||
byte* b;
|
||||
char* str;
|
||||
char* dst;
|
||||
|
||||
*id = NULL;
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
while (my_isspace(cs, *ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
|
@ -2407,7 +2474,7 @@ dict_scan_id(
|
|||
len++;
|
||||
}
|
||||
} else {
|
||||
while (!isspace(*ptr) && *ptr != '(' && *ptr != ')'
|
||||
while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')'
|
||||
&& (accept_also_dot || *ptr != '.')
|
||||
&& *ptr != ',' && *ptr != '\0') {
|
||||
|
||||
|
@ -2417,43 +2484,50 @@ dict_scan_id(
|
|||
len = ptr - s;
|
||||
}
|
||||
|
||||
if (quote && heap) {
|
||||
*id = d = mem_heap_alloc(heap, len + 1);
|
||||
if (UNIV_UNLIKELY(!heap)) {
|
||||
/* 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--) {
|
||||
if ((*d++ = *s++) == quote) {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
*d++ = 0;
|
||||
ut_a(*s == quote);
|
||||
ut_a(s + 1 == ptr);
|
||||
} else if (heap) {
|
||||
*id = mem_heap_strdupl(heap, s, len);
|
||||
len = d - str;
|
||||
ut_ad(*s == quote);
|
||||
ut_ad(s + 1 == ptr);
|
||||
} else {
|
||||
/* no heap given: id will point to source string */
|
||||
*id = s;
|
||||
str = mem_heap_strdupl(heap, s, len);
|
||||
}
|
||||
|
||||
if (heap && !quote) {
|
||||
/* EMS MySQL Manager sometimes adds characters 0xA0 (in
|
||||
latin1, a 'non-breakable space') to the end of a table name.
|
||||
But isspace(0xA0) is not true, which confuses our foreign key
|
||||
parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
|
||||
and 0xA0 are at the end of the string.
|
||||
if (!table_id) {
|
||||
convert_id:
|
||||
/* Convert the identifier from connection character set
|
||||
to UTF-8. */
|
||||
len = 3 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
TODO: we should lex the string using thd->charset_info, and
|
||||
my_isspace(). Only after that, convert id names to UTF-8. */
|
||||
innobase_convert_from_id(dst, str, len);
|
||||
} 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);
|
||||
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';
|
||||
}
|
||||
innobase_convert_from_table_id(dst, str, len);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
@ -2466,6 +2540,7 @@ const char*
|
|||
dict_scan_col(
|
||||
/*==========*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
ibool* success,/* out: TRUE if success */
|
||||
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
|
||||
was scannable */
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
dict_col_t* col;
|
||||
ulint i;
|
||||
|
||||
*success = FALSE;
|
||||
|
||||
ptr = dict_scan_id(ptr, heap, name, TRUE);
|
||||
ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE);
|
||||
|
||||
if (*name == NULL) {
|
||||
|
||||
|
@ -2508,13 +2582,6 @@ dict_scan_col(
|
|||
}
|
||||
|
||||
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(
|
||||
/*=================*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
dict_table_t** table, /* out: table object or NULL */
|
||||
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;
|
||||
NULL if no name was scannable */
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
const char* database_name = NULL;
|
||||
ulint database_name_len = 0;
|
||||
const char* table_name = NULL;
|
||||
|
@ -2543,7 +2610,7 @@ dict_scan_table_name(
|
|||
*success = FALSE;
|
||||
*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) {
|
||||
|
||||
|
@ -2558,7 +2625,7 @@ dict_scan_table_name(
|
|||
database_name = scan_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) {
|
||||
|
||||
|
@ -2614,13 +2681,6 @@ dict_scan_table_name(
|
|||
*table = dict_table_get_low(ref);
|
||||
|
||||
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(
|
||||
/*===========*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
ibool* success)/* out: TRUE if success, FALSE if just spaces
|
||||
left in string or a syntax error */
|
||||
|
@ -2638,7 +2699,7 @@ dict_skip_word(
|
|||
|
||||
*success = FALSE;
|
||||
|
||||
ptr = dict_scan_id(ptr, NULL, &start, TRUE);
|
||||
ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE);
|
||||
|
||||
if (start) {
|
||||
*success = TRUE;
|
||||
|
@ -2816,6 +2877,7 @@ dict_create_foreign_constraints_low(
|
|||
/* out: error code or DB_SUCCESS */
|
||||
trx_t* trx, /* in: transaction */
|
||||
mem_heap_t* heap, /* in: memory heap */
|
||||
struct charset_info_st* cs,/* in: the character set of sql_string */
|
||||
const char* sql_string,
|
||||
/* in: CREATE TABLE or ALTER TABLE statement
|
||||
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
|
||||
case look for the table being altered */
|
||||
|
||||
ptr = dict_accept(ptr, "ALTER", &success);
|
||||
ptr = dict_accept(cs, ptr, "ALTER", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "TABLE", &success);
|
||||
ptr = dict_accept(cs, ptr, "TABLE", &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 */
|
||||
|
||||
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);
|
||||
if (!success) {
|
||||
fprintf(stderr,
|
||||
|
@ -2929,21 +2991,22 @@ loop:
|
|||
of the constraint to system tables. */
|
||||
ptr = ptr1;
|
||||
|
||||
ptr = dict_accept(ptr, "CONSTRAINT", &success);
|
||||
ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
|
||||
|
||||
ut_a(success);
|
||||
|
||||
if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') {
|
||||
if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
while (my_isspace(cs, *ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* read constraint name unless got "CONSTRAINT FOREIGN" */
|
||||
if (ptr != ptr2) {
|
||||
ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE);
|
||||
ptr = dict_scan_id(cs, ptr, heap,
|
||||
&constraint_name, FALSE, FALSE);
|
||||
}
|
||||
} else {
|
||||
ptr = ptr2;
|
||||
|
@ -2973,28 +3036,28 @@ loop:
|
|||
|
||||
start_of_latest_foreign = ptr;
|
||||
|
||||
ptr = dict_accept(ptr, "FOREIGN", &success);
|
||||
ptr = dict_accept(cs, ptr, "FOREIGN", &success);
|
||||
|
||||
if (!success) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (!isspace(*ptr)) {
|
||||
if (!my_isspace(cs, *ptr)) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "KEY", &success);
|
||||
ptr = dict_accept(cs, ptr, "KEY", &success);
|
||||
|
||||
if (!success) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "(", &success);
|
||||
ptr = dict_accept(cs, ptr, "(", &success);
|
||||
|
||||
if (!success) {
|
||||
/* MySQL allows also an index id before the '('; we
|
||||
skip it */
|
||||
ptr = dict_skip_word(ptr, &success);
|
||||
ptr = dict_skip_word(cs, ptr, &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_report_syntax_err(name,
|
||||
|
@ -3003,7 +3066,7 @@ loop:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "(", &success);
|
||||
ptr = dict_accept(cs, ptr, "(", &success);
|
||||
|
||||
if (!success) {
|
||||
/* We do not flag a syntax error here because in an
|
||||
|
@ -3018,7 +3081,7 @@ loop:
|
|||
/* Scan the columns in the first list */
|
||||
col_loop1:
|
||||
ut_a(i < (sizeof column_names) / sizeof *column_names);
|
||||
ptr = dict_scan_col(ptr, &success, table, columns + i,
|
||||
ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
|
||||
heap, column_names + i);
|
||||
if (!success) {
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
|
@ -3032,13 +3095,13 @@ col_loop1:
|
|||
|
||||
i++;
|
||||
|
||||
ptr = dict_accept(ptr, ",", &success);
|
||||
ptr = dict_accept(cs, ptr, ",", &success);
|
||||
|
||||
if (success) {
|
||||
goto col_loop1;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, ")", &success);
|
||||
ptr = dict_accept(cs, ptr, ")", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||
|
@ -3055,7 +3118,7 @@ col_loop1:
|
|||
mutex_enter(&dict_foreign_err_mutex);
|
||||
dict_foreign_error_report_low(ef, name);
|
||||
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"
|
||||
"as the first columns. Constraint:\n%s\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);
|
||||
}
|
||||
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,
|
||||
ptr);
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
|
@ -3107,7 +3170,7 @@ col_loop1:
|
|||
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);
|
||||
|
||||
/* Note that referenced_table can be NULL if the user has suppressed
|
||||
|
@ -3126,7 +3189,7 @@ col_loop1:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "(", &success);
|
||||
ptr = dict_accept(cs, ptr, "(", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3139,7 +3202,7 @@ col_loop1:
|
|||
i = 0;
|
||||
|
||||
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);
|
||||
i++;
|
||||
|
||||
|
@ -3156,13 +3219,13 @@ col_loop2:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, ",", &success);
|
||||
ptr = dict_accept(cs, ptr, ",", &success);
|
||||
|
||||
if (success) {
|
||||
goto col_loop2;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, ")", &success);
|
||||
ptr = dict_accept(cs, ptr, ")", &success);
|
||||
|
||||
if (!success || foreign->n_fields != i) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3178,17 +3241,17 @@ col_loop2:
|
|||
scan_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) {
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "DELETE", &success);
|
||||
ptr = dict_accept(cs, ptr, "DELETE", &success);
|
||||
|
||||
if (!success) {
|
||||
ptr = dict_accept(ptr, "UPDATE", &success);
|
||||
ptr = dict_accept(cs, ptr, "UPDATE", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3205,13 +3268,13 @@ scan_on_conditions:
|
|||
n_on_deletes++;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "RESTRICT", &success);
|
||||
ptr = dict_accept(cs, ptr, "RESTRICT", &success);
|
||||
|
||||
if (success) {
|
||||
goto scan_on_conditions;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "CASCADE", &success);
|
||||
ptr = dict_accept(cs, ptr, "CASCADE", &success);
|
||||
|
||||
if (success) {
|
||||
if (is_on_delete) {
|
||||
|
@ -3223,10 +3286,10 @@ scan_on_conditions:
|
|||
goto scan_on_conditions;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "NO", &success);
|
||||
ptr = dict_accept(cs, ptr, "NO", &success);
|
||||
|
||||
if (success) {
|
||||
ptr = dict_accept(ptr, "ACTION", &success);
|
||||
ptr = dict_accept(cs, ptr, "ACTION", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3245,7 +3308,7 @@ scan_on_conditions:
|
|||
goto scan_on_conditions;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "SET", &success);
|
||||
ptr = dict_accept(cs, ptr, "SET", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3254,7 +3317,7 @@ scan_on_conditions:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "NULL", &success);
|
||||
ptr = dict_accept(cs, ptr, "NULL", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3364,6 +3427,25 @@ try_find_index:
|
|||
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
|
||||
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
|
||||
any foreign keys are found. */
|
||||
{
|
||||
char* str;
|
||||
ulint err;
|
||||
mem_heap_t* heap;
|
||||
char* str;
|
||||
ulint err;
|
||||
mem_heap_t* heap;
|
||||
|
||||
ut_a(trx && trx->mysql_thd);
|
||||
|
||||
str = dict_strip_comments(sql_string);
|
||||
heap = mem_heap_create(10000);
|
||||
|
||||
err = dict_create_foreign_constraints_low(trx, heap, str, name,
|
||||
reject_fks);
|
||||
err = dict_create_foreign_constraints_low(trx, heap,
|
||||
innobase_get_charset(trx->mysql_thd),
|
||||
str, name, reject_fks);
|
||||
|
||||
mem_heap_free(heap);
|
||||
mem_free(str);
|
||||
|
@ -3426,12 +3511,17 @@ dict_foreign_parse_drop_constraints(
|
|||
const char*** constraints_to_drop) /* out: id's of the
|
||||
constraints to drop */
|
||||
{
|
||||
dict_foreign_t* foreign;
|
||||
ibool success;
|
||||
char* str;
|
||||
const char* ptr;
|
||||
const char* id;
|
||||
FILE* ef = dict_foreign_err_file;
|
||||
dict_foreign_t* foreign;
|
||||
ibool success;
|
||||
char* str;
|
||||
const char* ptr;
|
||||
const char* id;
|
||||
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;
|
||||
|
||||
|
@ -3452,28 +3542,28 @@ loop:
|
|||
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;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "FOREIGN", &success);
|
||||
ptr = dict_accept(cs, ptr, "FOREIGN", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "KEY", &success);
|
||||
ptr = dict_accept(cs, ptr, "KEY", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto syntax_error;
|
||||
}
|
||||
|
||||
ptr = dict_scan_id(ptr, heap, &id, TRUE);
|
||||
ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE);
|
||||
|
||||
if (id == NULL) {
|
||||
|
||||
|
@ -3506,12 +3596,12 @@ loop:
|
|||
ut_print_timestamp(ef);
|
||||
fputs(
|
||||
" 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"
|
||||
"in SQL command\n", ef);
|
||||
fputs(str, 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);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -3528,7 +3618,7 @@ syntax_error:
|
|||
ut_print_timestamp(ef);
|
||||
fputs(
|
||||
" 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"
|
||||
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
@ -3537,6 +3627,7 @@ syntax_error:
|
|||
|
||||
return(DB_CANNOT_DROP_CONSTRAINT);
|
||||
}
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
|
||||
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
|
||||
|
||||
|
@ -4206,11 +4297,11 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
}
|
||||
|
||||
fputs(" CONSTRAINT ", file);
|
||||
ut_print_name(file, trx, stripped_id);
|
||||
ut_print_name(file, trx, FALSE, stripped_id);
|
||||
fputs(" FOREIGN KEY (", file);
|
||||
|
||||
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) {
|
||||
fputs(", ", file);
|
||||
} else {
|
||||
|
@ -4223,7 +4314,7 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
if (dict_tables_have_same_db(foreign->foreign_table_name,
|
||||
foreign->referenced_table_name)) {
|
||||
/* 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));
|
||||
} else {
|
||||
/* Look for the '/' in the table name */
|
||||
|
@ -4233,9 +4324,10 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
i++;
|
||||
}
|
||||
|
||||
ut_print_namel(file, trx, foreign->referenced_table_name, i);
|
||||
ut_print_namel(file, trx, TRUE,
|
||||
foreign->referenced_table_name, i);
|
||||
putc('.', file);
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, TRUE,
|
||||
foreign->referenced_table_name + i + 1);
|
||||
}
|
||||
|
||||
|
@ -4243,7 +4335,8 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
putc('(', file);
|
||||
|
||||
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) {
|
||||
fputs(", ", file);
|
||||
} else {
|
||||
|
@ -4317,12 +4410,12 @@ dict_print_info_on_foreign_keys(
|
|||
putc(' ', file);
|
||||
}
|
||||
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, FALSE,
|
||||
foreign->foreign_col_names[i]);
|
||||
}
|
||||
|
||||
fputs(") REFER ", file);
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, TRUE,
|
||||
foreign->referenced_table_name);
|
||||
putc('(', file);
|
||||
|
||||
|
@ -4330,7 +4423,7 @@ dict_print_info_on_foreign_keys(
|
|||
if (i) {
|
||||
putc(' ', file);
|
||||
}
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, FALSE,
|
||||
foreign->referenced_col_names[i]);
|
||||
}
|
||||
|
||||
|
@ -4377,7 +4470,7 @@ dict_index_name_print(
|
|||
const dict_index_t* index) /* in: index to print */
|
||||
{
|
||||
fputs("index ", file);
|
||||
ut_print_name(file, trx, index->name);
|
||||
ut_print_name(file, trx, FALSE, index->name);
|
||||
fputs(" of table ", file);
|
||||
ut_print_name(file, trx, index->table_name);
|
||||
ut_print_name(file, trx, TRUE, index->table_name);
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ loop:
|
|||
|
||||
if (table == NULL) {
|
||||
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);
|
||||
} else {
|
||||
/* The table definition was corrupt if there
|
||||
|
|
|
@ -81,6 +81,8 @@ dict_mem_table_create(
|
|||
|
||||
table->stat_modified_counter = 0;
|
||||
|
||||
table->max_row_size = 0;
|
||||
|
||||
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
|
||||
|
||||
table->autoinc_inited = FALSE;
|
||||
|
|
|
@ -43,6 +43,7 @@ have disables the InnoDB inlining in this file. */
|
|||
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
|
||||
|
||||
#ifdef WITH_INNOBASE_STORAGE_ENGINE
|
||||
|
||||
#include "ha_innodb.h"
|
||||
|
||||
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_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_comment[]=
|
||||
"Supports transactions, row-level locking, and foreign keys";
|
||||
|
||||
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
|
||||
};
|
||||
handlerton innobase_hton;
|
||||
|
||||
|
||||
static handler *innobase_create_handler(TABLE_SHARE *table)
|
||||
static handler *innobase_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
|
||||
{
|
||||
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.
|
||||
|
||||
|
@ -736,6 +754,21 @@ innobase_casedn_str(
|
|||
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. */
|
||||
extern "C"
|
||||
|
@ -863,10 +896,9 @@ ha_innobase::ha_innobase(TABLE_SHARE *table_arg)
|
|||
HA_NULL_IN_KEY |
|
||||
HA_CAN_INDEX_BLOBS |
|
||||
HA_CAN_SQL_HANDLER |
|
||||
HA_NOT_EXACT_COUNT |
|
||||
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS |
|
||||
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
|
||||
HA_PRIMARY_KEY_IN_READ_INDEX |
|
||||
HA_CAN_GEOMETRY |
|
||||
HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
|
||||
HA_TABLE_SCAN_ON_INDEX),
|
||||
start_of_scan(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! */
|
||||
extern "C"
|
||||
int
|
||||
mysql_get_identifier_quote_char(
|
||||
/*============================*/
|
||||
/* out: quote character to be
|
||||
used in SQL identifiers; EOF if none */
|
||||
void
|
||||
innobase_print_identifier(
|
||||
/*======================*/
|
||||
FILE* f, /* in: output stream */
|
||||
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 */
|
||||
ulint namelen)/* in: length of name */
|
||||
{
|
||||
if (!trx || !trx->mysql_thd) {
|
||||
return(EOF);
|
||||
const char* s = name;
|
||||
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. */
|
||||
|
||||
bool
|
||||
int
|
||||
innobase_init(void)
|
||||
/*===============*/
|
||||
/* out: &innobase_hton, or NULL on error */
|
||||
{
|
||||
static char current_dir[3]; /* Set if using current lib */
|
||||
int err;
|
||||
|
@ -1262,11 +1340,54 @@ innobase_init(void)
|
|||
|
||||
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)
|
||||
goto error;
|
||||
DBUG_RETURN(0); // nothing else to do
|
||||
|
||||
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. */
|
||||
if (sizeof(ulint) == 4) {
|
||||
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 */
|
||||
|
||||
/* 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
|
||||
retrieval of just those column values MySQL needs in its processing. */
|
||||
static
|
||||
void
|
||||
build_template(
|
||||
ha_innobase::build_template(
|
||||
/*===========*/
|
||||
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
|
||||
THD* thd, /* in: current user thread, used
|
||||
only if templ_type is
|
||||
ROW_MYSQL_REC_FIELDS */
|
||||
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 */
|
||||
{
|
||||
dict_index_t* index;
|
||||
|
@ -3054,8 +3174,8 @@ build_template(
|
|||
goto include_field;
|
||||
}
|
||||
|
||||
if (table->file->ha_get_bit_in_read_set(i+1) ||
|
||||
table->file->ha_get_bit_in_write_set(i+1)) {
|
||||
if (bitmap_is_set(table->read_set, i) ||
|
||||
bitmap_is_set(table->write_set, i)) {
|
||||
/* This field is needed in the query */
|
||||
|
||||
goto include_field;
|
||||
|
@ -4690,7 +4810,7 @@ ha_innobase::create(
|
|||
/* Get the transaction associated with the current thd, or create one
|
||||
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
|
||||
possible adaptive hash latch to avoid deadlocks of threads */
|
||||
|
@ -4795,20 +4915,9 @@ ha_innobase::create(
|
|||
}
|
||||
}
|
||||
|
||||
if (current_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;
|
||||
}
|
||||
|
||||
if (thd->query != NULL) {
|
||||
error = row_table_add_foreign_constraints(trx,
|
||||
q.str, norm_name,
|
||||
thd->query, norm_name,
|
||||
create_info->options & HA_LEX_CREATE_TMP_TABLE);
|
||||
|
||||
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
|
||||
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
|
||||
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. */
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
records = (ha_rows)n_rows;
|
||||
deleted = 0;
|
||||
data_file_length = ((ulonglong)
|
||||
stats.records = (ha_rows)n_rows;
|
||||
stats.deleted = 0;
|
||||
stats.data_file_length = ((ulonglong)
|
||||
ib_table->stat_clustered_index_size)
|
||||
* UNIV_PAGE_SIZE;
|
||||
index_file_length = ((ulonglong)
|
||||
stats.index_file_length = ((ulonglong)
|
||||
ib_table->stat_sum_of_other_index_sizes)
|
||||
* UNIV_PAGE_SIZE;
|
||||
delete_length = 0;
|
||||
check_time = 0;
|
||||
stats.delete_length = 0;
|
||||
stats.check_time = 0;
|
||||
|
||||
if (records == 0) {
|
||||
mean_rec_length = 0;
|
||||
if (stats.records == 0) {
|
||||
stats.mean_rec_length = 0;
|
||||
} 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) {
|
||||
|
||||
rec_per_key = records;
|
||||
rec_per_key = stats.records;
|
||||
} else {
|
||||
rec_per_key = (ha_rows)(records /
|
||||
rec_per_key = (ha_rows)(stats.records /
|
||||
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*)"";
|
||||
|
@ -5994,8 +6103,7 @@ ha_innobase::extra(
|
|||
/*===============*/
|
||||
/* out: 0 or error number */
|
||||
enum ha_extra_function operation)
|
||||
/* in: HA_EXTRA_RETRIEVE_ALL_COLS or some
|
||||
other flag */
|
||||
/* in: HA_EXTRA_FLUSH or some other flag */
|
||||
{
|
||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||
|
||||
|
@ -6009,13 +6117,6 @@ ha_innobase::extra(
|
|||
row_mysql_prebuilt_free_blob_heap(prebuilt);
|
||||
}
|
||||
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:
|
||||
prebuilt->keep_other_fields_on_keyread = 0;
|
||||
prebuilt->read_just_key = 0;
|
||||
|
@ -6023,16 +6124,6 @@ ha_innobase::extra(
|
|||
case HA_EXTRA_NO_KEYREAD:
|
||||
prebuilt->read_just_key = 0;
|
||||
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:
|
||||
prebuilt->read_just_key = 1;
|
||||
break;
|
||||
|
@ -6046,6 +6137,18 @@ ha_innobase::extra(
|
|||
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
|
||||
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
|
||||
|
@ -6504,7 +6607,7 @@ innodb_show_status(
|
|||
|
||||
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)) {
|
||||
result= TRUE;
|
||||
}
|
||||
|
@ -6531,7 +6634,7 @@ innodb_mutex_show_status(
|
|||
ulint rw_lock_count_os_wait= 0;
|
||||
ulint rw_lock_count_os_yield= 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");
|
||||
|
||||
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
|
||||
|
@ -6558,7 +6661,7 @@ innodb_mutex_show_status(
|
|||
mutex->count_os_yield,
|
||||
mutex->lspent_time/1000);
|
||||
|
||||
if (stat_print(thd, innobase_hton.name,
|
||||
if (stat_print(thd, innobase_hton_name,
|
||||
hton_name_len, buf1, buf1len,
|
||||
buf2, buf2len)) {
|
||||
#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_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)) {
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
@ -6825,6 +6928,17 @@ ha_innobase::store_lock(
|
|||
&& !thd->tablespace_op
|
||||
&& thd->lex->sql_command != SQLCOM_TRUNCATE
|
||||
&& 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) {
|
||||
|
||||
lock_type = TL_WRITE_ALLOW_WRITE;
|
||||
|
@ -6994,17 +7108,21 @@ func_exit_early:
|
|||
return(error);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
/*******************************************************************************
|
||||
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
|
||||
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
|
||||
ha_innobase::get_auto_increment()
|
||||
/*=============================*/
|
||||
/* out: auto-increment column value, -1 if error
|
||||
(deadlock or lock wait timeout) */
|
||||
void ha_innobase::get_auto_increment(
|
||||
/*=================================*/
|
||||
ulonglong offset, /* in */
|
||||
ulonglong increment, /* in */
|
||||
ulonglong nb_desired_values, /* in */
|
||||
ulonglong *first_value, /* out */
|
||||
ulonglong *nb_reserved_values) /* out */
|
||||
{
|
||||
longlong nr;
|
||||
int error;
|
||||
|
@ -7019,10 +7137,13 @@ ha_innobase::get_auto_increment()
|
|||
ut_print_timestamp(stderr);
|
||||
sql_print_error("Error %lu in ::get_auto_increment()",
|
||||
(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 */
|
||||
|
@ -7490,15 +7611,17 @@ bool ha_innobase::check_if_incompatible_data(
|
|||
return COMPATIBLE_DATA_YES;
|
||||
}
|
||||
|
||||
struct st_mysql_storage_engine innobase_storage_engine=
|
||||
{ MYSQL_HANDLERTON_INTERFACE_VERSION, &innobase_hton};
|
||||
|
||||
mysql_declare_plugin(innobase)
|
||||
{
|
||||
MYSQL_STORAGE_ENGINE_PLUGIN,
|
||||
&innobase_hton,
|
||||
&innobase_storage_engine,
|
||||
innobase_hton_name,
|
||||
"Innobase OY",
|
||||
innobase_hton_comment,
|
||||
NULL, /* Plugin Init */
|
||||
"Supports transactions, row-level locking, and foreign keys",
|
||||
innobase_init, /* Plugin Init */
|
||||
NULL, /* Plugin Deinit */
|
||||
0x0100 /* 1.0 */,
|
||||
0
|
||||
|
@ -7506,3 +7629,4 @@ mysql_declare_plugin(innobase)
|
|||
mysql_declare_plugin_end;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ typedef struct st_innobase_share {
|
|||
} INNOBASE_SHARE;
|
||||
|
||||
|
||||
struct row_prebuilt_struct;
|
||||
|
||||
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
|
||||
uint full_name_len,
|
||||
ulonglong *unused);
|
||||
|
@ -89,7 +91,7 @@ class ha_innobase: public handler
|
|||
const char* table_type() const { return("InnoDB");}
|
||||
const char *index_type(uint key_number) { return "BTREE"; }
|
||||
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
|
||||
{
|
||||
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_part_length() const;
|
||||
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 close(void);
|
||||
|
@ -147,20 +148,10 @@ class ha_innobase: public handler
|
|||
int optimize(THD* thd,HA_CHECK_OPT* check_opt);
|
||||
int discard_or_import_tablespace(my_bool discard);
|
||||
int extra(enum ha_extra_function operation);
|
||||
int reset();
|
||||
int external_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 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);
|
||||
ha_rows records_in_range(uint inx, key_range *min_key, key_range
|
||||
*max_key);
|
||||
|
@ -181,7 +172,10 @@ class ha_innobase: public handler
|
|||
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||
enum thr_lock_type lock_type);
|
||||
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);
|
||||
|
||||
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);
|
||||
bool check_if_incompatible_data(HA_CREATE_INFO *info,
|
||||
uint table_changes);
|
||||
void build_template(struct row_prebuilt_struct *prebuilt, THD *thd,
|
||||
TABLE *table, uint templ_type);
|
||||
};
|
||||
|
||||
extern SHOW_VAR innodb_status_variables[];
|
||||
|
@ -249,7 +245,7 @@ extern ulong srv_thread_concurrency;
|
|||
extern ulong srv_commit_concurrency;
|
||||
}
|
||||
|
||||
bool innobase_init(void);
|
||||
int innobase_init(void);
|
||||
int innobase_end(ha_panic_function type);
|
||||
bool innobase_flush_logs(void);
|
||||
uint innobase_get_free_space(void);
|
||||
|
|
|
@ -330,6 +330,16 @@ dtype_get_min_size(
|
|||
/* out: minimum size */
|
||||
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
|
||||
the fixed length of the type, otherwise 0. */
|
||||
UNIV_INLINE
|
||||
|
|
|
@ -44,18 +44,15 @@ dict_get_db_name_len(
|
|||
/* out: database name length */
|
||||
const char* name); /* in: table name in the form
|
||||
dbname '/' tablename */
|
||||
/*************************************************************************
|
||||
Accepts a specified string. Comparisons are case-insensitive. */
|
||||
/************************************************************************
|
||||
Return the end of table name where we have removed dbname and '/'. */
|
||||
|
||||
const char*
|
||||
dict_accept(
|
||||
/*========*/
|
||||
/* out: if string was accepted, the pointer
|
||||
is moved after that, else ptr is returned */
|
||||
const char* ptr, /* in: scan from this */
|
||||
const char* string, /* in: accept only this string as the next
|
||||
non-whitespace string */
|
||||
ibool* success);/* out: TRUE if accepted */
|
||||
dict_remove_db_name(
|
||||
/*================*/
|
||||
/* out: table name */
|
||||
const char* name); /* in: table name in the form
|
||||
dbname '/' tablename */
|
||||
/************************************************************************
|
||||
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
|
||||
foreign key */
|
||||
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
|
||||
the foreign key constraints declared in the string. This function
|
||||
|
|
|
@ -344,6 +344,12 @@ struct dict_table_struct{
|
|||
had an IX lock on */
|
||||
UT_LIST_BASE_NODE_T(lock_t)
|
||||
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;
|
||||
/* this field is used to specify in simulations
|
||||
|
|
|
@ -69,57 +69,59 @@
|
|||
PARS_WHERE_TOKEN = 295,
|
||||
PARS_FOR_TOKEN = 296,
|
||||
PARS_DDOT_TOKEN = 297,
|
||||
PARS_CONSISTENT_TOKEN = 298,
|
||||
PARS_READ_TOKEN = 299,
|
||||
PARS_ORDER_TOKEN = 300,
|
||||
PARS_BY_TOKEN = 301,
|
||||
PARS_ASC_TOKEN = 302,
|
||||
PARS_DESC_TOKEN = 303,
|
||||
PARS_INSERT_TOKEN = 304,
|
||||
PARS_INTO_TOKEN = 305,
|
||||
PARS_VALUES_TOKEN = 306,
|
||||
PARS_UPDATE_TOKEN = 307,
|
||||
PARS_SET_TOKEN = 308,
|
||||
PARS_DELETE_TOKEN = 309,
|
||||
PARS_CURRENT_TOKEN = 310,
|
||||
PARS_OF_TOKEN = 311,
|
||||
PARS_CREATE_TOKEN = 312,
|
||||
PARS_TABLE_TOKEN = 313,
|
||||
PARS_INDEX_TOKEN = 314,
|
||||
PARS_UNIQUE_TOKEN = 315,
|
||||
PARS_CLUSTERED_TOKEN = 316,
|
||||
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317,
|
||||
PARS_ON_TOKEN = 318,
|
||||
PARS_ASSIGN_TOKEN = 319,
|
||||
PARS_DECLARE_TOKEN = 320,
|
||||
PARS_CURSOR_TOKEN = 321,
|
||||
PARS_SQL_TOKEN = 322,
|
||||
PARS_OPEN_TOKEN = 323,
|
||||
PARS_FETCH_TOKEN = 324,
|
||||
PARS_CLOSE_TOKEN = 325,
|
||||
PARS_NOTFOUND_TOKEN = 326,
|
||||
PARS_TO_CHAR_TOKEN = 327,
|
||||
PARS_TO_NUMBER_TOKEN = 328,
|
||||
PARS_TO_BINARY_TOKEN = 329,
|
||||
PARS_BINARY_TO_NUMBER_TOKEN = 330,
|
||||
PARS_SUBSTR_TOKEN = 331,
|
||||
PARS_REPLSTR_TOKEN = 332,
|
||||
PARS_CONCAT_TOKEN = 333,
|
||||
PARS_INSTR_TOKEN = 334,
|
||||
PARS_LENGTH_TOKEN = 335,
|
||||
PARS_SYSDATE_TOKEN = 336,
|
||||
PARS_PRINTF_TOKEN = 337,
|
||||
PARS_ASSERT_TOKEN = 338,
|
||||
PARS_RND_TOKEN = 339,
|
||||
PARS_RND_STR_TOKEN = 340,
|
||||
PARS_ROW_PRINTF_TOKEN = 341,
|
||||
PARS_COMMIT_TOKEN = 342,
|
||||
PARS_ROLLBACK_TOKEN = 343,
|
||||
PARS_WORK_TOKEN = 344,
|
||||
PARS_UNSIGNED_TOKEN = 345,
|
||||
PARS_EXIT_TOKEN = 346,
|
||||
PARS_FUNCTION_TOKEN = 347,
|
||||
NEG = 348
|
||||
PARS_READ_TOKEN = 298,
|
||||
PARS_ORDER_TOKEN = 299,
|
||||
PARS_BY_TOKEN = 300,
|
||||
PARS_ASC_TOKEN = 301,
|
||||
PARS_DESC_TOKEN = 302,
|
||||
PARS_INSERT_TOKEN = 303,
|
||||
PARS_INTO_TOKEN = 304,
|
||||
PARS_VALUES_TOKEN = 305,
|
||||
PARS_UPDATE_TOKEN = 306,
|
||||
PARS_SET_TOKEN = 307,
|
||||
PARS_DELETE_TOKEN = 308,
|
||||
PARS_CURRENT_TOKEN = 309,
|
||||
PARS_OF_TOKEN = 310,
|
||||
PARS_CREATE_TOKEN = 311,
|
||||
PARS_TABLE_TOKEN = 312,
|
||||
PARS_INDEX_TOKEN = 313,
|
||||
PARS_UNIQUE_TOKEN = 314,
|
||||
PARS_CLUSTERED_TOKEN = 315,
|
||||
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 316,
|
||||
PARS_ON_TOKEN = 317,
|
||||
PARS_ASSIGN_TOKEN = 318,
|
||||
PARS_DECLARE_TOKEN = 319,
|
||||
PARS_CURSOR_TOKEN = 320,
|
||||
PARS_SQL_TOKEN = 321,
|
||||
PARS_OPEN_TOKEN = 322,
|
||||
PARS_FETCH_TOKEN = 323,
|
||||
PARS_CLOSE_TOKEN = 324,
|
||||
PARS_NOTFOUND_TOKEN = 325,
|
||||
PARS_TO_CHAR_TOKEN = 326,
|
||||
PARS_TO_NUMBER_TOKEN = 327,
|
||||
PARS_TO_BINARY_TOKEN = 328,
|
||||
PARS_BINARY_TO_NUMBER_TOKEN = 329,
|
||||
PARS_SUBSTR_TOKEN = 330,
|
||||
PARS_REPLSTR_TOKEN = 331,
|
||||
PARS_CONCAT_TOKEN = 332,
|
||||
PARS_INSTR_TOKEN = 333,
|
||||
PARS_LENGTH_TOKEN = 334,
|
||||
PARS_SYSDATE_TOKEN = 335,
|
||||
PARS_PRINTF_TOKEN = 336,
|
||||
PARS_ASSERT_TOKEN = 337,
|
||||
PARS_RND_TOKEN = 338,
|
||||
PARS_RND_STR_TOKEN = 339,
|
||||
PARS_ROW_PRINTF_TOKEN = 340,
|
||||
PARS_COMMIT_TOKEN = 341,
|
||||
PARS_ROLLBACK_TOKEN = 342,
|
||||
PARS_WORK_TOKEN = 343,
|
||||
PARS_UNSIGNED_TOKEN = 344,
|
||||
PARS_EXIT_TOKEN = 345,
|
||||
PARS_FUNCTION_TOKEN = 346,
|
||||
PARS_LOCK_TOKEN = 347,
|
||||
PARS_SHARE_TOKEN = 348,
|
||||
PARS_MODE_TOKEN = 349,
|
||||
NEG = 350
|
||||
};
|
||||
#endif
|
||||
#define PARS_INT_LIT 258
|
||||
|
@ -162,57 +164,59 @@
|
|||
#define PARS_WHERE_TOKEN 295
|
||||
#define PARS_FOR_TOKEN 296
|
||||
#define PARS_DDOT_TOKEN 297
|
||||
#define PARS_CONSISTENT_TOKEN 298
|
||||
#define PARS_READ_TOKEN 299
|
||||
#define PARS_ORDER_TOKEN 300
|
||||
#define PARS_BY_TOKEN 301
|
||||
#define PARS_ASC_TOKEN 302
|
||||
#define PARS_DESC_TOKEN 303
|
||||
#define PARS_INSERT_TOKEN 304
|
||||
#define PARS_INTO_TOKEN 305
|
||||
#define PARS_VALUES_TOKEN 306
|
||||
#define PARS_UPDATE_TOKEN 307
|
||||
#define PARS_SET_TOKEN 308
|
||||
#define PARS_DELETE_TOKEN 309
|
||||
#define PARS_CURRENT_TOKEN 310
|
||||
#define PARS_OF_TOKEN 311
|
||||
#define PARS_CREATE_TOKEN 312
|
||||
#define PARS_TABLE_TOKEN 313
|
||||
#define PARS_INDEX_TOKEN 314
|
||||
#define PARS_UNIQUE_TOKEN 315
|
||||
#define PARS_CLUSTERED_TOKEN 316
|
||||
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317
|
||||
#define PARS_ON_TOKEN 318
|
||||
#define PARS_ASSIGN_TOKEN 319
|
||||
#define PARS_DECLARE_TOKEN 320
|
||||
#define PARS_CURSOR_TOKEN 321
|
||||
#define PARS_SQL_TOKEN 322
|
||||
#define PARS_OPEN_TOKEN 323
|
||||
#define PARS_FETCH_TOKEN 324
|
||||
#define PARS_CLOSE_TOKEN 325
|
||||
#define PARS_NOTFOUND_TOKEN 326
|
||||
#define PARS_TO_CHAR_TOKEN 327
|
||||
#define PARS_TO_NUMBER_TOKEN 328
|
||||
#define PARS_TO_BINARY_TOKEN 329
|
||||
#define PARS_BINARY_TO_NUMBER_TOKEN 330
|
||||
#define PARS_SUBSTR_TOKEN 331
|
||||
#define PARS_REPLSTR_TOKEN 332
|
||||
#define PARS_CONCAT_TOKEN 333
|
||||
#define PARS_INSTR_TOKEN 334
|
||||
#define PARS_LENGTH_TOKEN 335
|
||||
#define PARS_SYSDATE_TOKEN 336
|
||||
#define PARS_PRINTF_TOKEN 337
|
||||
#define PARS_ASSERT_TOKEN 338
|
||||
#define PARS_RND_TOKEN 339
|
||||
#define PARS_RND_STR_TOKEN 340
|
||||
#define PARS_ROW_PRINTF_TOKEN 341
|
||||
#define PARS_COMMIT_TOKEN 342
|
||||
#define PARS_ROLLBACK_TOKEN 343
|
||||
#define PARS_WORK_TOKEN 344
|
||||
#define PARS_UNSIGNED_TOKEN 345
|
||||
#define PARS_EXIT_TOKEN 346
|
||||
#define PARS_FUNCTION_TOKEN 347
|
||||
#define NEG 348
|
||||
#define PARS_READ_TOKEN 298
|
||||
#define PARS_ORDER_TOKEN 299
|
||||
#define PARS_BY_TOKEN 300
|
||||
#define PARS_ASC_TOKEN 301
|
||||
#define PARS_DESC_TOKEN 302
|
||||
#define PARS_INSERT_TOKEN 303
|
||||
#define PARS_INTO_TOKEN 304
|
||||
#define PARS_VALUES_TOKEN 305
|
||||
#define PARS_UPDATE_TOKEN 306
|
||||
#define PARS_SET_TOKEN 307
|
||||
#define PARS_DELETE_TOKEN 308
|
||||
#define PARS_CURRENT_TOKEN 309
|
||||
#define PARS_OF_TOKEN 310
|
||||
#define PARS_CREATE_TOKEN 311
|
||||
#define PARS_TABLE_TOKEN 312
|
||||
#define PARS_INDEX_TOKEN 313
|
||||
#define PARS_UNIQUE_TOKEN 314
|
||||
#define PARS_CLUSTERED_TOKEN 315
|
||||
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 316
|
||||
#define PARS_ON_TOKEN 317
|
||||
#define PARS_ASSIGN_TOKEN 318
|
||||
#define PARS_DECLARE_TOKEN 319
|
||||
#define PARS_CURSOR_TOKEN 320
|
||||
#define PARS_SQL_TOKEN 321
|
||||
#define PARS_OPEN_TOKEN 322
|
||||
#define PARS_FETCH_TOKEN 323
|
||||
#define PARS_CLOSE_TOKEN 324
|
||||
#define PARS_NOTFOUND_TOKEN 325
|
||||
#define PARS_TO_CHAR_TOKEN 326
|
||||
#define PARS_TO_NUMBER_TOKEN 327
|
||||
#define PARS_TO_BINARY_TOKEN 328
|
||||
#define PARS_BINARY_TO_NUMBER_TOKEN 329
|
||||
#define PARS_SUBSTR_TOKEN 330
|
||||
#define PARS_REPLSTR_TOKEN 331
|
||||
#define PARS_CONCAT_TOKEN 332
|
||||
#define PARS_INSTR_TOKEN 333
|
||||
#define PARS_LENGTH_TOKEN 334
|
||||
#define PARS_SYSDATE_TOKEN 335
|
||||
#define PARS_PRINTF_TOKEN 336
|
||||
#define PARS_ASSERT_TOKEN 337
|
||||
#define PARS_RND_TOKEN 338
|
||||
#define PARS_RND_STR_TOKEN 339
|
||||
#define PARS_ROW_PRINTF_TOKEN 340
|
||||
#define PARS_COMMIT_TOKEN 341
|
||||
#define PARS_ROLLBACK_TOKEN 342
|
||||
#define PARS_WORK_TOKEN 343
|
||||
#define PARS_UNSIGNED_TOKEN 344
|
||||
#define PARS_EXIT_TOKEN 345
|
||||
#define PARS_FUNCTION_TOKEN 346
|
||||
#define PARS_LOCK_TOKEN 347
|
||||
#define PARS_SHARE_TOKEN 348
|
||||
#define PARS_MODE_TOKEN 349
|
||||
#define NEG 350
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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_open_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_clustered_token;
|
||||
|
||||
|
|
|
@ -143,14 +143,12 @@ que_thr_stop_for_mysql(
|
|||
/*===================*/
|
||||
que_thr_t* thr); /* in: query thread */
|
||||
/**************************************************************************
|
||||
Runs query threads. Note that the individual query thread which is run
|
||||
within this function may change if, e.g., the OS thread executing this
|
||||
function uses a threshold amount of resources. */
|
||||
Run a query thread. Handles lock waits. */
|
||||
|
||||
void
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -337,9 +322,14 @@ Evaluate the given SQL */
|
|||
ulint
|
||||
que_eval_sql(
|
||||
/*=========*/
|
||||
pars_info_t* info, /* out: error code or DB_SUCCESS */
|
||||
const char* sql, /* in: info struct, or NULL */
|
||||
/* out: error code or DB_SUCCESS */
|
||||
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 */
|
||||
|
||||
/* Query graph query thread node: the fields are protected by the kernel
|
||||
mutex with the exceptions named below */
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ Created 10/10/1995 Heikki Tuuri
|
|||
|
||||
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
|
||||
thread starts running */
|
||||
extern os_event_t srv_lock_timeout_thread_event;
|
||||
|
|
|
@ -362,7 +362,7 @@ rw_lock_s_unlock_func(
|
|||
|
||||
/* Reset the shared lock by decrementing the reader count */
|
||||
|
||||
ut_ad(lock->reader_count > 0);
|
||||
ut_a(lock->reader_count > 0);
|
||||
lock->reader_count--;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
|
|
@ -266,11 +266,9 @@ trx_end_lock_wait(
|
|||
/********************************************************************
|
||||
Sends a signal to a trx object. */
|
||||
|
||||
ibool
|
||||
void
|
||||
trx_sig_send(
|
||||
/*=========*/
|
||||
/* out: TRUE if the signal was
|
||||
successfully delivered */
|
||||
trx_t* trx, /* in: trx handle */
|
||||
ulint type, /* in: signal type */
|
||||
ulint sender, /* in: TRX_SIG_SELF or
|
||||
|
|
|
@ -222,16 +222,19 @@ ut_print_filename(
|
|||
FILE* f, /* in: output stream */
|
||||
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. */
|
||||
|
||||
struct trx_struct;
|
||||
|
||||
void
|
||||
ut_print_name(
|
||||
/*==========*/
|
||||
FILE* f, /* in: output stream */
|
||||
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 */
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -242,6 +245,8 @@ ut_print_namel(
|
|||
/*===========*/
|
||||
FILE* f, /* in: output stream */
|
||||
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 */
|
||||
ulint namelen);/* in: length of name */
|
||||
|
||||
|
|
|
@ -1863,7 +1863,7 @@ lock_rec_enqueue_waiting(
|
|||
fputs(
|
||||
" InnoDB: Error: a record lock wait happens in a dictionary operation!\n"
|
||||
"InnoDB: Table name ", stderr);
|
||||
ut_print_name(stderr, trx, index->table_name);
|
||||
ut_print_name(stderr, trx, TRUE, index->table_name);
|
||||
fputs(".\n"
|
||||
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
|
||||
stderr);
|
||||
|
@ -1908,7 +1908,7 @@ lock_rec_enqueue_waiting(
|
|||
if (lock_print_waits) {
|
||||
fprintf(stderr, "Lock wait for trx %lu in index ",
|
||||
(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 */
|
||||
|
||||
|
@ -3635,7 +3635,7 @@ lock_table_enqueue_waiting(
|
|||
fputs(
|
||||
" InnoDB: Error: a table lock wait happens in a dictionary operation!\n"
|
||||
"InnoDB: Table name ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(".\n"
|
||||
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
|
||||
stderr);
|
||||
|
@ -4158,7 +4158,8 @@ lock_table_print(
|
|||
ut_a(lock_get_type(lock) == LOCK_TABLE);
|
||||
|
||||
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",
|
||||
(ulong) (lock->trx)->id.high, (ulong) (lock->trx)->id.low);
|
||||
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
ERROR 42S22: Unknown column 't1.id' in 'where clause'
|
||||
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),
|
||||
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
|
||||
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=0;
|
||||
drop table t1;
|
||||
|
@ -2610,18 +2610,18 @@ v INT,
|
|||
CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
|
||||
) ENGINE=InnoDB;
|
||||
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 t2 VALUES(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;
|
||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
DROP TABLE t1;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
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;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
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 t3 values(1);
|
||||
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);
|
||||
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 t4 values(1);
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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 t4;
|
||||
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;
|
||||
insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,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);
|
||||
select hex(s1) from t2;
|
||||
hex(s1)
|
||||
|
@ -2980,11 +2980,11 @@ select hex(s1) from t2;
|
|||
hex(s1)
|
||||
4100
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
select hex(s1) from t2;
|
||||
hex(s1)
|
||||
|
@ -2998,11 +2998,11 @@ select hex(s1) from t2;
|
|||
hex(s1)
|
||||
4200
|
||||
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;
|
||||
update t2 set s1=0x4120;
|
||||
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;
|
||||
select a,hex(s1) from t1;
|
||||
a hex(s1)
|
||||
|
@ -3028,7 +3028,7 @@ hex(s1)
|
|||
12
|
||||
delete from t1 where a=1;
|
||||
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;
|
||||
a hex(s1)
|
||||
2 12
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,5 +1,274 @@
|
|||
-- source include/have_innodb.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4;
|
||||
--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;
|
||||
|
|
664
pars/lexyy.c
664
pars/lexyy.c
File diff suppressed because it is too large
Load diff
1356
pars/pars0grm.c
1356
pars/pars0grm.c
File diff suppressed because it is too large
Load diff
208
pars/pars0grm.h
208
pars/pars0grm.h
|
@ -69,57 +69,59 @@
|
|||
PARS_WHERE_TOKEN = 295,
|
||||
PARS_FOR_TOKEN = 296,
|
||||
PARS_DDOT_TOKEN = 297,
|
||||
PARS_CONSISTENT_TOKEN = 298,
|
||||
PARS_READ_TOKEN = 299,
|
||||
PARS_ORDER_TOKEN = 300,
|
||||
PARS_BY_TOKEN = 301,
|
||||
PARS_ASC_TOKEN = 302,
|
||||
PARS_DESC_TOKEN = 303,
|
||||
PARS_INSERT_TOKEN = 304,
|
||||
PARS_INTO_TOKEN = 305,
|
||||
PARS_VALUES_TOKEN = 306,
|
||||
PARS_UPDATE_TOKEN = 307,
|
||||
PARS_SET_TOKEN = 308,
|
||||
PARS_DELETE_TOKEN = 309,
|
||||
PARS_CURRENT_TOKEN = 310,
|
||||
PARS_OF_TOKEN = 311,
|
||||
PARS_CREATE_TOKEN = 312,
|
||||
PARS_TABLE_TOKEN = 313,
|
||||
PARS_INDEX_TOKEN = 314,
|
||||
PARS_UNIQUE_TOKEN = 315,
|
||||
PARS_CLUSTERED_TOKEN = 316,
|
||||
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317,
|
||||
PARS_ON_TOKEN = 318,
|
||||
PARS_ASSIGN_TOKEN = 319,
|
||||
PARS_DECLARE_TOKEN = 320,
|
||||
PARS_CURSOR_TOKEN = 321,
|
||||
PARS_SQL_TOKEN = 322,
|
||||
PARS_OPEN_TOKEN = 323,
|
||||
PARS_FETCH_TOKEN = 324,
|
||||
PARS_CLOSE_TOKEN = 325,
|
||||
PARS_NOTFOUND_TOKEN = 326,
|
||||
PARS_TO_CHAR_TOKEN = 327,
|
||||
PARS_TO_NUMBER_TOKEN = 328,
|
||||
PARS_TO_BINARY_TOKEN = 329,
|
||||
PARS_BINARY_TO_NUMBER_TOKEN = 330,
|
||||
PARS_SUBSTR_TOKEN = 331,
|
||||
PARS_REPLSTR_TOKEN = 332,
|
||||
PARS_CONCAT_TOKEN = 333,
|
||||
PARS_INSTR_TOKEN = 334,
|
||||
PARS_LENGTH_TOKEN = 335,
|
||||
PARS_SYSDATE_TOKEN = 336,
|
||||
PARS_PRINTF_TOKEN = 337,
|
||||
PARS_ASSERT_TOKEN = 338,
|
||||
PARS_RND_TOKEN = 339,
|
||||
PARS_RND_STR_TOKEN = 340,
|
||||
PARS_ROW_PRINTF_TOKEN = 341,
|
||||
PARS_COMMIT_TOKEN = 342,
|
||||
PARS_ROLLBACK_TOKEN = 343,
|
||||
PARS_WORK_TOKEN = 344,
|
||||
PARS_UNSIGNED_TOKEN = 345,
|
||||
PARS_EXIT_TOKEN = 346,
|
||||
PARS_FUNCTION_TOKEN = 347,
|
||||
NEG = 348
|
||||
PARS_READ_TOKEN = 298,
|
||||
PARS_ORDER_TOKEN = 299,
|
||||
PARS_BY_TOKEN = 300,
|
||||
PARS_ASC_TOKEN = 301,
|
||||
PARS_DESC_TOKEN = 302,
|
||||
PARS_INSERT_TOKEN = 303,
|
||||
PARS_INTO_TOKEN = 304,
|
||||
PARS_VALUES_TOKEN = 305,
|
||||
PARS_UPDATE_TOKEN = 306,
|
||||
PARS_SET_TOKEN = 307,
|
||||
PARS_DELETE_TOKEN = 308,
|
||||
PARS_CURRENT_TOKEN = 309,
|
||||
PARS_OF_TOKEN = 310,
|
||||
PARS_CREATE_TOKEN = 311,
|
||||
PARS_TABLE_TOKEN = 312,
|
||||
PARS_INDEX_TOKEN = 313,
|
||||
PARS_UNIQUE_TOKEN = 314,
|
||||
PARS_CLUSTERED_TOKEN = 315,
|
||||
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 316,
|
||||
PARS_ON_TOKEN = 317,
|
||||
PARS_ASSIGN_TOKEN = 318,
|
||||
PARS_DECLARE_TOKEN = 319,
|
||||
PARS_CURSOR_TOKEN = 320,
|
||||
PARS_SQL_TOKEN = 321,
|
||||
PARS_OPEN_TOKEN = 322,
|
||||
PARS_FETCH_TOKEN = 323,
|
||||
PARS_CLOSE_TOKEN = 324,
|
||||
PARS_NOTFOUND_TOKEN = 325,
|
||||
PARS_TO_CHAR_TOKEN = 326,
|
||||
PARS_TO_NUMBER_TOKEN = 327,
|
||||
PARS_TO_BINARY_TOKEN = 328,
|
||||
PARS_BINARY_TO_NUMBER_TOKEN = 329,
|
||||
PARS_SUBSTR_TOKEN = 330,
|
||||
PARS_REPLSTR_TOKEN = 331,
|
||||
PARS_CONCAT_TOKEN = 332,
|
||||
PARS_INSTR_TOKEN = 333,
|
||||
PARS_LENGTH_TOKEN = 334,
|
||||
PARS_SYSDATE_TOKEN = 335,
|
||||
PARS_PRINTF_TOKEN = 336,
|
||||
PARS_ASSERT_TOKEN = 337,
|
||||
PARS_RND_TOKEN = 338,
|
||||
PARS_RND_STR_TOKEN = 339,
|
||||
PARS_ROW_PRINTF_TOKEN = 340,
|
||||
PARS_COMMIT_TOKEN = 341,
|
||||
PARS_ROLLBACK_TOKEN = 342,
|
||||
PARS_WORK_TOKEN = 343,
|
||||
PARS_UNSIGNED_TOKEN = 344,
|
||||
PARS_EXIT_TOKEN = 345,
|
||||
PARS_FUNCTION_TOKEN = 346,
|
||||
PARS_LOCK_TOKEN = 347,
|
||||
PARS_SHARE_TOKEN = 348,
|
||||
PARS_MODE_TOKEN = 349,
|
||||
NEG = 350
|
||||
};
|
||||
#endif
|
||||
#define PARS_INT_LIT 258
|
||||
|
@ -162,57 +164,59 @@
|
|||
#define PARS_WHERE_TOKEN 295
|
||||
#define PARS_FOR_TOKEN 296
|
||||
#define PARS_DDOT_TOKEN 297
|
||||
#define PARS_CONSISTENT_TOKEN 298
|
||||
#define PARS_READ_TOKEN 299
|
||||
#define PARS_ORDER_TOKEN 300
|
||||
#define PARS_BY_TOKEN 301
|
||||
#define PARS_ASC_TOKEN 302
|
||||
#define PARS_DESC_TOKEN 303
|
||||
#define PARS_INSERT_TOKEN 304
|
||||
#define PARS_INTO_TOKEN 305
|
||||
#define PARS_VALUES_TOKEN 306
|
||||
#define PARS_UPDATE_TOKEN 307
|
||||
#define PARS_SET_TOKEN 308
|
||||
#define PARS_DELETE_TOKEN 309
|
||||
#define PARS_CURRENT_TOKEN 310
|
||||
#define PARS_OF_TOKEN 311
|
||||
#define PARS_CREATE_TOKEN 312
|
||||
#define PARS_TABLE_TOKEN 313
|
||||
#define PARS_INDEX_TOKEN 314
|
||||
#define PARS_UNIQUE_TOKEN 315
|
||||
#define PARS_CLUSTERED_TOKEN 316
|
||||
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317
|
||||
#define PARS_ON_TOKEN 318
|
||||
#define PARS_ASSIGN_TOKEN 319
|
||||
#define PARS_DECLARE_TOKEN 320
|
||||
#define PARS_CURSOR_TOKEN 321
|
||||
#define PARS_SQL_TOKEN 322
|
||||
#define PARS_OPEN_TOKEN 323
|
||||
#define PARS_FETCH_TOKEN 324
|
||||
#define PARS_CLOSE_TOKEN 325
|
||||
#define PARS_NOTFOUND_TOKEN 326
|
||||
#define PARS_TO_CHAR_TOKEN 327
|
||||
#define PARS_TO_NUMBER_TOKEN 328
|
||||
#define PARS_TO_BINARY_TOKEN 329
|
||||
#define PARS_BINARY_TO_NUMBER_TOKEN 330
|
||||
#define PARS_SUBSTR_TOKEN 331
|
||||
#define PARS_REPLSTR_TOKEN 332
|
||||
#define PARS_CONCAT_TOKEN 333
|
||||
#define PARS_INSTR_TOKEN 334
|
||||
#define PARS_LENGTH_TOKEN 335
|
||||
#define PARS_SYSDATE_TOKEN 336
|
||||
#define PARS_PRINTF_TOKEN 337
|
||||
#define PARS_ASSERT_TOKEN 338
|
||||
#define PARS_RND_TOKEN 339
|
||||
#define PARS_RND_STR_TOKEN 340
|
||||
#define PARS_ROW_PRINTF_TOKEN 341
|
||||
#define PARS_COMMIT_TOKEN 342
|
||||
#define PARS_ROLLBACK_TOKEN 343
|
||||
#define PARS_WORK_TOKEN 344
|
||||
#define PARS_UNSIGNED_TOKEN 345
|
||||
#define PARS_EXIT_TOKEN 346
|
||||
#define PARS_FUNCTION_TOKEN 347
|
||||
#define NEG 348
|
||||
#define PARS_READ_TOKEN 298
|
||||
#define PARS_ORDER_TOKEN 299
|
||||
#define PARS_BY_TOKEN 300
|
||||
#define PARS_ASC_TOKEN 301
|
||||
#define PARS_DESC_TOKEN 302
|
||||
#define PARS_INSERT_TOKEN 303
|
||||
#define PARS_INTO_TOKEN 304
|
||||
#define PARS_VALUES_TOKEN 305
|
||||
#define PARS_UPDATE_TOKEN 306
|
||||
#define PARS_SET_TOKEN 307
|
||||
#define PARS_DELETE_TOKEN 308
|
||||
#define PARS_CURRENT_TOKEN 309
|
||||
#define PARS_OF_TOKEN 310
|
||||
#define PARS_CREATE_TOKEN 311
|
||||
#define PARS_TABLE_TOKEN 312
|
||||
#define PARS_INDEX_TOKEN 313
|
||||
#define PARS_UNIQUE_TOKEN 314
|
||||
#define PARS_CLUSTERED_TOKEN 315
|
||||
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 316
|
||||
#define PARS_ON_TOKEN 317
|
||||
#define PARS_ASSIGN_TOKEN 318
|
||||
#define PARS_DECLARE_TOKEN 319
|
||||
#define PARS_CURSOR_TOKEN 320
|
||||
#define PARS_SQL_TOKEN 321
|
||||
#define PARS_OPEN_TOKEN 322
|
||||
#define PARS_FETCH_TOKEN 323
|
||||
#define PARS_CLOSE_TOKEN 324
|
||||
#define PARS_NOTFOUND_TOKEN 325
|
||||
#define PARS_TO_CHAR_TOKEN 326
|
||||
#define PARS_TO_NUMBER_TOKEN 327
|
||||
#define PARS_TO_BINARY_TOKEN 328
|
||||
#define PARS_BINARY_TO_NUMBER_TOKEN 329
|
||||
#define PARS_SUBSTR_TOKEN 330
|
||||
#define PARS_REPLSTR_TOKEN 331
|
||||
#define PARS_CONCAT_TOKEN 332
|
||||
#define PARS_INSTR_TOKEN 333
|
||||
#define PARS_LENGTH_TOKEN 334
|
||||
#define PARS_SYSDATE_TOKEN 335
|
||||
#define PARS_PRINTF_TOKEN 336
|
||||
#define PARS_ASSERT_TOKEN 337
|
||||
#define PARS_RND_TOKEN 338
|
||||
#define PARS_RND_STR_TOKEN 339
|
||||
#define PARS_ROW_PRINTF_TOKEN 340
|
||||
#define PARS_COMMIT_TOKEN 341
|
||||
#define PARS_ROLLBACK_TOKEN 342
|
||||
#define PARS_WORK_TOKEN 343
|
||||
#define PARS_UNSIGNED_TOKEN 344
|
||||
#define PARS_EXIT_TOKEN 345
|
||||
#define PARS_FUNCTION_TOKEN 346
|
||||
#define PARS_LOCK_TOKEN 347
|
||||
#define PARS_SHARE_TOKEN 348
|
||||
#define PARS_MODE_TOKEN 349
|
||||
#define NEG 350
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@ yylex(void);
|
|||
%token PARS_WHERE_TOKEN
|
||||
%token PARS_FOR_TOKEN
|
||||
%token PARS_DDOT_TOKEN
|
||||
%token PARS_CONSISTENT_TOKEN
|
||||
%token PARS_READ_TOKEN
|
||||
%token PARS_ORDER_TOKEN
|
||||
%token PARS_BY_TOKEN
|
||||
|
@ -120,6 +119,9 @@ yylex(void);
|
|||
%token PARS_UNSIGNED_TOKEN
|
||||
%token PARS_EXIT_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_NOT_TOKEN
|
||||
|
@ -132,9 +134,11 @@ yylex(void);
|
|||
/* Grammar follows */
|
||||
%%
|
||||
|
||||
top_statement:
|
||||
procedure_definition ';'
|
||||
|
||||
statement:
|
||||
procedure_definition ';'
|
||||
| stored_procedure_call
|
||||
stored_procedure_call
|
||||
| predefined_procedure_call ';'
|
||||
| while_statement ';'
|
||||
| for_statement ';'
|
||||
|
@ -301,10 +305,10 @@ for_update_clause:
|
|||
{ $$ = &pars_update_token; }
|
||||
;
|
||||
|
||||
consistent_read_clause:
|
||||
lock_shared_clause:
|
||||
/* Nothing */ { $$ = NULL; }
|
||||
| PARS_CONSISTENT_TOKEN PARS_READ_TOKEN
|
||||
{ $$ = &pars_consistent_token; }
|
||||
| PARS_LOCK_TOKEN PARS_IN_TOKEN PARS_SHARE_TOKEN PARS_MODE_TOKEN
|
||||
{ $$ = &pars_share_token; }
|
||||
;
|
||||
|
||||
order_direction:
|
||||
|
@ -324,7 +328,7 @@ select_statement:
|
|||
PARS_FROM_TOKEN table_list
|
||||
search_condition
|
||||
for_update_clause
|
||||
consistent_read_clause
|
||||
lock_shared_clause
|
||||
order_by_clause { $$ = pars_select_statement($2, $4, $5,
|
||||
$6, $7, $8); }
|
||||
;
|
||||
|
|
|
@ -325,10 +325,6 @@ In the state 'id', only two actions are possible (defined below). */
|
|||
return(PARS_FOR_TOKEN);
|
||||
}
|
||||
|
||||
"CONSISTENT" {
|
||||
return(PARS_CONSISTENT_TOKEN);
|
||||
}
|
||||
|
||||
"READ" {
|
||||
return(PARS_READ_TOKEN);
|
||||
}
|
||||
|
@ -517,6 +513,18 @@ In the state 'id', only two actions are possible (defined below). */
|
|||
return(PARS_FUNCTION_TOKEN);
|
||||
}
|
||||
|
||||
"LOCK" {
|
||||
return(PARS_LOCK_TOKEN);
|
||||
}
|
||||
|
||||
"SHARE" {
|
||||
return(PARS_SHARE_TOKEN);
|
||||
}
|
||||
|
||||
"MODE" {
|
||||
return(PARS_MODE_TOKEN);
|
||||
}
|
||||
|
||||
{ID} {
|
||||
yylval = sym_tab_add_id(pars_sym_tab_global,
|
||||
(byte*)yytext,
|
||||
|
|
|
@ -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_open_token = {PARS_OPEN_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_clustered_token = {PARS_CLUSTERED_TOKEN};
|
||||
|
||||
|
@ -699,8 +699,7 @@ pars_select_statement(
|
|||
sym_node_t* table_list, /* in: table list */
|
||||
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* consistent_read,/* in: NULL or
|
||||
&pars_consistent_token */
|
||||
pars_res_word_t* lock_shared, /* in: NULL or &pars_share_token */
|
||||
order_node_t* order_by) /* in: NULL or an order-by node */
|
||||
{
|
||||
select_node->state = SEL_NODE_OPEN;
|
||||
|
@ -734,19 +733,24 @@ pars_select_statement(
|
|||
}
|
||||
|
||||
if (for_update) {
|
||||
ut_a(!consistent_read);
|
||||
ut_a(!lock_shared);
|
||||
|
||||
select_node->set_x_locks = TRUE;
|
||||
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 {
|
||||
select_node->set_x_locks = FALSE;
|
||||
select_node->row_lock_mode = LOCK_S;
|
||||
}
|
||||
|
||||
if (consistent_read) {
|
||||
select_node->consistent_read = TRUE;
|
||||
} else {
|
||||
select_node->consistent_read = FALSE;
|
||||
select_node->read_view = NULL;
|
||||
}
|
||||
|
||||
select_node->order_by = order_by;
|
||||
|
@ -976,7 +980,7 @@ pars_update_statement(
|
|||
sel_node = pars_select_list(NULL, NULL);
|
||||
|
||||
pars_select_statement(sel_node, table_sym, search_cond, NULL,
|
||||
NULL, NULL);
|
||||
&pars_share_token, NULL);
|
||||
node->searched_update = TRUE;
|
||||
sel_node->common.parent = node;
|
||||
}
|
||||
|
@ -1857,8 +1861,9 @@ pars_sql(
|
|||
#endif /* UNIV_SYNC_DEBUG */
|
||||
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->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->info = info;
|
||||
|
||||
|
|
140
que/que0que.c
140
que/que0que.c
|
@ -715,27 +715,6 @@ que_graph_try_free(
|
|||
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. */
|
||||
static
|
||||
|
@ -813,11 +792,10 @@ que_thr_move_to_run_state(
|
|||
Decrements the query thread reference counts in the query graph and the
|
||||
transaction. May start signal handling, e.g., a rollback.
|
||||
*** NOTE ***:
|
||||
This and que_thr_stop_for_mysql are
|
||||
the only functions where the reference count can be decremented and
|
||||
this function may only be called from inside que_run_threads or
|
||||
que_thr_check_if_switch! These restrictions exist to make the rollback code
|
||||
easier to maintain. */
|
||||
This and que_thr_stop_for_mysql are the only functions where the reference
|
||||
count can be decremented and this function may only be called from inside
|
||||
que_run_threads or que_thr_check_if_switch! These restrictions exist to make
|
||||
the rollback code easier to maintain. */
|
||||
static
|
||||
void
|
||||
que_thr_dec_refer_count(
|
||||
|
@ -836,7 +814,7 @@ que_thr_dec_refer_count(
|
|||
ibool stopped;
|
||||
|
||||
fork = thr->common.parent;
|
||||
trx = thr->graph->trx;
|
||||
trx = thr_get_trx(thr);
|
||||
sess = trx->sess;
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
@ -856,6 +834,12 @@ que_thr_dec_refer_count(
|
|||
stderr); */
|
||||
|
||||
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;
|
||||
} else {
|
||||
ut_a(0);
|
||||
|
@ -1200,7 +1184,10 @@ que_thr_step(
|
|||
trx_t* trx;
|
||||
ulint type;
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
ut_ad(thr->state == QUE_THR_RUNNING);
|
||||
ut_a(trx->error_state == DB_SUCCESS);
|
||||
|
||||
thr->resource++;
|
||||
|
||||
|
@ -1236,7 +1223,6 @@ que_thr_step(
|
|||
threads doing updating or inserting at the moment! */
|
||||
|
||||
if (thr->prev_node == que_node_get_parent(node)) {
|
||||
trx = thr_get_trx(thr);
|
||||
trx->last_sql_stat_start.least_undo_no
|
||||
= trx->undo_no;
|
||||
}
|
||||
|
@ -1298,24 +1284,28 @@ que_thr_step(
|
|||
old_thr->prev_node = node;
|
||||
}
|
||||
|
||||
if (thr) {
|
||||
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
|
||||
}
|
||||
|
||||
return(thr);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Runs query threads. Note that the individual query thread which is run
|
||||
within this function may change if, e.g., the OS thread executing this
|
||||
function uses a threshold amount of resources. */
|
||||
|
||||
Run a query thread until it finishes or encounters e.g. a lock wait. */
|
||||
static
|
||||
void
|
||||
que_run_threads(
|
||||
/*============*/
|
||||
que_thr_t* thr) /* in: query thread which is run initially */
|
||||
que_run_threads_low(
|
||||
/*================*/
|
||||
que_thr_t* thr) /* in: query thread */
|
||||
{
|
||||
que_thr_t* next_thr;
|
||||
ulint cumul_resource;
|
||||
ulint loop_count;
|
||||
|
||||
ut_ad(thr->state == QUE_THR_RUNNING);
|
||||
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!mutex_own(&kernel_mutex));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
@ -1340,10 +1330,15 @@ loop:
|
|||
next_thr = que_thr_step(thr);
|
||||
/*-------------------------*/
|
||||
|
||||
ut_a(!next_thr || (thr_get_trx(next_thr)->error_state == DB_SUCCESS));
|
||||
|
||||
loop_count++;
|
||||
|
||||
if (next_thr != thr) {
|
||||
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);
|
||||
|
||||
if (next_thr == NULL) {
|
||||
|
@ -1359,20 +1354,89 @@ 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
|
||||
que_eval_sql(
|
||||
/*=========*/
|
||||
pars_info_t* info, /* out: error code or DB_SUCCESS */
|
||||
const char* sql, /* in: info struct, or NULL */
|
||||
/* out: error code or DB_SUCCESS */
|
||||
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 */
|
||||
{
|
||||
que_thr_t* thr;
|
||||
que_t* graph;
|
||||
|
||||
ut_a(trx->error_state == DB_SUCCESS);
|
||||
|
||||
if (reserve_dict_mutex) {
|
||||
mutex_enter(&dict_sys->mutex);
|
||||
}
|
||||
|
||||
graph = pars_sql(info, sql);
|
||||
|
||||
if (reserve_dict_mutex) {
|
||||
mutex_exit(&dict_sys->mutex);
|
||||
}
|
||||
|
||||
ut_a(graph);
|
||||
|
||||
graph->trx = trx;
|
||||
|
|
|
@ -607,7 +607,7 @@ row_ins_set_detailed(
|
|||
rewind(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);
|
||||
dict_print_info_on_foreign_key_in_create_format(
|
||||
srv_misc_tmpfile,
|
||||
|
@ -649,22 +649,22 @@ row_ins_foreign_report_err(
|
|||
trx_print(ef, trx, 600);
|
||||
|
||||
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);
|
||||
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
|
||||
TRUE);
|
||||
putc('\n', ef);
|
||||
fputs(errstr, 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) {
|
||||
fputs(" tuple:\n", ef);
|
||||
dtuple_print(ef, entry);
|
||||
}
|
||||
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);
|
||||
ut_print_name(ef, trx, foreign->foreign_index->name);
|
||||
ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
|
||||
if (rec) {
|
||||
fputs(", there is a record:\n", ef);
|
||||
rec_print(ef, rec, foreign->foreign_index);
|
||||
|
@ -702,20 +702,20 @@ row_ins_foreign_report_add_err(
|
|||
fputs(" Transaction:\n", ef);
|
||||
trx_print(ef, trx, 600);
|
||||
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);
|
||||
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
|
||||
TRUE);
|
||||
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) {
|
||||
fputs(" tuple:\n", ef);
|
||||
dtuple_print(ef, entry);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
if (rec && page_rec_is_supremum(rec)) {
|
||||
/* If the cursor ended on a supremum record, it is better
|
||||
|
@ -1283,16 +1283,19 @@ run_again:
|
|||
fputs(" Transaction:\n", ef);
|
||||
trx_print(ef, trx, 600);
|
||||
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);
|
||||
dict_print_info_on_foreign_key_in_create_format(ef,
|
||||
trx, foreign, TRUE);
|
||||
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);
|
||||
dtuple_print(ef, entry);
|
||||
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);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
|
122
row/row0mysql.c
122
row/row0mysql.c
|
@ -680,7 +680,7 @@ row_prebuilt_free(
|
|||
"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name",
|
||||
(ulong) prebuilt->magic_n,
|
||||
(ulong) prebuilt->magic_n2);
|
||||
ut_print_name(stderr, NULL, prebuilt->table->name);
|
||||
ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -773,7 +773,7 @@ row_update_prebuilt_trx(
|
|||
"InnoDB: Error: trying to use a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name",
|
||||
(ulong) prebuilt->magic_n);
|
||||
ut_print_name(stderr, NULL, prebuilt->table->name);
|
||||
ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -1094,7 +1094,8 @@ row_insert_for_mysql(
|
|||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name",
|
||||
(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);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -1329,7 +1330,8 @@ row_update_for_mysql(
|
|||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name",
|
||||
(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);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -1941,7 +1943,7 @@ row_create_table_for_mysql(
|
|||
|
||||
fputs(" InnoDB: Warning: cannot create table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(" because tablespace full\n", stderr);
|
||||
|
||||
if (dict_table_get_low(table->name)) {
|
||||
|
@ -1954,7 +1956,7 @@ row_create_table_for_mysql(
|
|||
ut_print_timestamp(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"
|
||||
"InnoDB: data dictionary. Have you deleted the .frm file\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);
|
||||
|
||||
fputs(" InnoDB: Error: column ", stderr);
|
||||
ut_print_name(stderr, trx,
|
||||
ut_print_name(stderr, trx, FALSE,
|
||||
dict_index_get_nth_field(index, i)->name);
|
||||
fputs(" appears twice in ", stderr);
|
||||
dict_index_name_print(stderr, trx, index);
|
||||
|
@ -2196,7 +2198,7 @@ row_drop_table_for_mysql_in_background(
|
|||
trx->check_foreigns = FALSE;
|
||||
|
||||
/* 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); */
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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); */
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
@ -2429,7 +2431,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
if (table->space == 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: is in the system tablespace 0 which cannot be discarded\n", stderr);
|
||||
err = DB_ERROR;
|
||||
|
@ -2441,7 +2443,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: though there is a foreign key check running on it.\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);
|
||||
|
||||
fputs(" Cannot DISCARD table ", ef);
|
||||
ut_print_name(ef, trx, name);
|
||||
ut_print_name(ef, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"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);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -2501,7 +2503,8 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
"BEGIN\n"
|
||||
"SELECT ID INTO old_id\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"
|
||||
" COMMIT WORK;\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"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
, FALSE, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
trx->error_state = DB_SUCCESS;
|
||||
|
@ -2590,7 +2593,7 @@ row_import_tablespace_for_mysql(
|
|||
if (!success) {
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", stderr);
|
||||
|
||||
|
@ -2611,7 +2614,7 @@ row_import_tablespace_for_mysql(
|
|||
if (!table) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: does not exist in the InnoDB data dictionary\n"
|
||||
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
|
||||
|
@ -2625,7 +2628,7 @@ row_import_tablespace_for_mysql(
|
|||
if (table->space == 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: is in the system tablespace 0 which cannot be imported\n", stderr);
|
||||
err = DB_ERROR;
|
||||
|
@ -2638,7 +2641,7 @@ row_import_tablespace_for_mysql(
|
|||
fputs(
|
||||
" InnoDB: Error: you are trying to IMPORT a tablespace\n"
|
||||
"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"
|
||||
"InnoDB: during the lifetime of the mysqld process!\n", stderr);
|
||||
|
||||
|
@ -2663,7 +2666,7 @@ row_import_tablespace_for_mysql(
|
|||
fputs(
|
||||
" InnoDB: cannot find or open in the database directory the .ibd file of\n"
|
||||
"InnoDB: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
|
||||
stderr);
|
||||
|
@ -2783,10 +2786,10 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
|
|||
ut_print_timestamp(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"
|
||||
"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);
|
||||
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) {
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: because there is a foreign key check running on it.\n",
|
||||
stderr);
|
||||
|
@ -2910,7 +2913,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
|
|||
" WHERE TABLE_ID = :old_id;\n"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
, FALSE, trx);
|
||||
|
||||
if (err != 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;
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: after truncating it. Background processes may corrupt the table!\n",
|
||||
stderr);
|
||||
|
@ -3045,7 +3048,7 @@ row_drop_table_for_mysql(
|
|||
ut_print_timestamp(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"
|
||||
"InnoDB: data dictionary though MySQL is trying to drop it.\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);
|
||||
|
||||
fputs(" Cannot drop table ", ef);
|
||||
ut_print_name(ef, trx, name);
|
||||
ut_print_name(ef, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"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);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -3103,7 +3106,7 @@ row_drop_table_for_mysql(
|
|||
if (added) {
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: though there are still open handles to it.\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) {
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: though there is a foreign key check running on it.\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"
|
||||
"SELECT ID INTO table_id\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"
|
||||
" COMMIT WORK;\n"
|
||||
" RETURN;\n"
|
||||
|
@ -3188,7 +3192,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
"found := 1;\n"
|
||||
"SELECT ID INTO sys_foreign_id\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"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
|
@ -3202,7 +3207,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\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"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
|
@ -3214,7 +3220,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO index_id\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"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
|
@ -3227,7 +3234,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
"DELETE FROM SYS_TABLES WHERE ID = table_id;\n"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
, FALSE, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
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);
|
||||
fputs(" InnoDB: Error: not able to remove table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs(" from the dictionary cache!\n", stderr);
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
@ -3277,7 +3284,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
fprintf(stderr,
|
||||
"InnoDB: We removed now the InnoDB internal data dictionary entry\n"
|
||||
"InnoDB: of table ");
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fprintf(stderr, ".\n");
|
||||
|
||||
goto funct_exit;
|
||||
|
@ -3289,14 +3296,14 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
fprintf(stderr,
|
||||
"InnoDB: We removed now the InnoDB internal data dictionary entry\n"
|
||||
"InnoDB: of table ");
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fprintf(stderr, ".\n");
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: not able to delete tablespace %lu of table ",
|
||||
(ulong) space_id);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("!\n", stderr);
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
@ -3364,10 +3371,10 @@ loop:
|
|||
ut_print_timestamp(stderr);
|
||||
fputs(
|
||||
" InnoDB: Warning: MySQL is trying to drop database ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"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);
|
||||
|
||||
os_thread_sleep(1000000);
|
||||
|
@ -3383,10 +3390,10 @@ loop:
|
|||
|
||||
if (err != DB_SUCCESS) {
|
||||
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 ",
|
||||
(ulint) err);
|
||||
ut_print_name(stderr, trx, table_name);
|
||||
ut_print_name(stderr, trx, TRUE, table_name);
|
||||
putc('\n', stderr);
|
||||
break;
|
||||
}
|
||||
|
@ -3436,7 +3443,7 @@ row_delete_constraint_low(
|
|||
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n"
|
||||
"DELETE FROM SYS_FOREIGN WHERE ID = :id;\n"
|
||||
"END;\n"
|
||||
, trx));
|
||||
, FALSE, trx));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -3543,7 +3550,7 @@ row_rename_table_for_mysql(
|
|||
ut_print_timestamp(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"
|
||||
"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"
|
||||
|
@ -3559,7 +3566,7 @@ row_rename_table_for_mysql(
|
|||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, old_name);
|
||||
ut_print_name(stderr, trx, TRUE, old_name);
|
||||
fputs(
|
||||
" does not have an .ibd file in the database directory.\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"
|
||||
" WHERE NAME = :old_table_name;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
, FALSE, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
|
@ -3639,7 +3646,8 @@ row_rename_table_for_mysql(
|
|||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\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"
|
||||
" found := 0;\n"
|
||||
" ELSE\n"
|
||||
|
@ -3675,7 +3683,7 @@ row_rename_table_for_mysql(
|
|||
"WHERE REF_NAME = :old_table_name\n"
|
||||
" AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
, FALSE, trx);
|
||||
|
||||
} else if (n_constraints_to_drop > 0) {
|
||||
/* Drop some constraints of tmp tables. */
|
||||
|
@ -3704,17 +3712,17 @@ end:
|
|||
"InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n"
|
||||
"InnoDB: to have the same internal name in case-insensitive comparison.\n"
|
||||
"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"
|
||||
"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"
|
||||
"InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n"
|
||||
"InnoDB: You can look for further help from\n"
|
||||
"InnoDB: http://dev.mysql.com/doc/mysql/en/"
|
||||
"InnoDB_troubleshooting_datadict.html\n"
|
||||
"InnoDB: If table ", stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs(
|
||||
" 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"
|
||||
|
@ -3742,9 +3750,9 @@ end:
|
|||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error in table rename, cannot rename ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, old_name);
|
||||
ut_print_name(stderr, trx, TRUE, old_name);
|
||||
fputs(" to ", stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
putc('\n', stderr);
|
||||
err = DB_ERROR;
|
||||
|
||||
|
@ -3763,7 +3771,7 @@ end:
|
|||
if (old_is_tmp) {
|
||||
fputs(" InnoDB: Error: in ALTER TABLE ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs("\n"
|
||||
"InnoDB: has or is referenced in foreign key constraints\n"
|
||||
"InnoDB: which are not compatible with the new table definition.\n",
|
||||
|
@ -3772,7 +3780,7 @@ end:
|
|||
fputs(
|
||||
" InnoDB: Error: in RENAME TABLE table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs("\n"
|
||||
"InnoDB: is referenced in foreign key constraints\n"
|
||||
"InnoDB: which are not compatible with the new table definition.\n",
|
||||
|
@ -3986,7 +3994,7 @@ row_check_table_for_mysql(
|
|||
|
||||
while (index != NULL) {
|
||||
/* fputs("Validating index ", stderr);
|
||||
ut_print_name(stderr, index->name);
|
||||
ut_print_name(stderr, trx, FALSE, index->name);
|
||||
putc('\n', stderr); */
|
||||
|
||||
if (!btr_validate_tree(index->tree, prebuilt->trx)) {
|
||||
|
|
|
@ -440,12 +440,12 @@ row_build_row_ref_in_tuple(
|
|||
|
||||
ut_a(ref && index && rec);
|
||||
|
||||
if (!index->table) {
|
||||
if (UNIV_UNLIKELY(!index->table)) {
|
||||
fputs("InnoDB: table ", stderr);
|
||||
notfound:
|
||||
ut_print_name(stderr, trx, index->table_name);
|
||||
ut_print_name(stderr, trx, TRUE, index->table_name);
|
||||
fputs(" for index ", stderr);
|
||||
ut_print_name(stderr, trx, index->name);
|
||||
ut_print_name(stderr, trx, FALSE, index->name);
|
||||
fputs(" not found\n", stderr);
|
||||
ut_error;
|
||||
}
|
||||
|
|
142
row/row0sel.c
142
row/row0sel.c
|
@ -45,6 +45,9 @@ to que_run_threads: this is to allow canceling runaway queries */
|
|||
|
||||
#define SEL_COST_LIMIT 100
|
||||
|
||||
/* The lower limit for what we consider a "big" row */
|
||||
#define BIG_ROW_SIZE 1024
|
||||
|
||||
/* Flags for search shortcut */
|
||||
#define SEL_FOUND 0
|
||||
#define SEL_EXHAUSTED 1
|
||||
|
@ -302,19 +305,45 @@ row_sel_fetch_columns(
|
|||
}
|
||||
|
||||
while (column) {
|
||||
mem_heap_t* heap = NULL;
|
||||
ibool needs_copy;
|
||||
|
||||
field_no = column->field_nos[index_type];
|
||||
|
||||
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,
|
||||
len);
|
||||
} else {
|
||||
val = que_node_get_val(column);
|
||||
dfield_set_data(val, data, len);
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
plan->n_rows_fetched++;
|
||||
ret = SEL_FOUND;
|
||||
func_exit:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(SEL_FOUND);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1214,7 +1244,8 @@ table_loop:
|
|||
mtr_start(&mtr);
|
||||
|
||||
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) {
|
||||
rw_lock_s_lock(&btr_search_latch);
|
||||
|
||||
|
@ -1328,6 +1359,12 @@ rec_loop:
|
|||
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level == TRX_ISO_READ_COMMITTED) {
|
||||
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
|
||||
goto skip_lock;
|
||||
}
|
||||
|
||||
lock_type = LOCK_REC_NOT_GAP;
|
||||
} else {
|
||||
lock_type = LOCK_ORDINARY;
|
||||
|
@ -1346,6 +1383,7 @@ rec_loop:
|
|||
}
|
||||
}
|
||||
|
||||
skip_lock:
|
||||
if (page_rec_is_infimum(rec)) {
|
||||
|
||||
/* The infimum record on a page cannot be in the result set,
|
||||
|
@ -1376,6 +1414,12 @@ rec_loop:
|
|||
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level == TRX_ISO_READ_COMMITTED) {
|
||||
|
||||
if (page_rec_is_supremum(rec)) {
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
lock_type = LOCK_REC_NOT_GAP;
|
||||
} else {
|
||||
lock_type = LOCK_ORDINARY;
|
||||
|
@ -1602,7 +1646,8 @@ rec_loop:
|
|||
}
|
||||
|
||||
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 */
|
||||
|
||||
|
@ -1888,9 +1933,8 @@ row_sel_step(
|
|||
err = lock_table(0, table_node->table,
|
||||
i_lock_mode, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
thr_get_trx(thr)->error_state = err;
|
||||
|
||||
que_thr_handle_error(thr, DB_ERROR,
|
||||
NULL, 0);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
@ -1926,17 +1970,8 @@ row_sel_step(
|
|||
|
||||
thr->graph->last_sel_node = node;
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
/* Ok: do nothing */
|
||||
|
||||
} 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);
|
||||
if (err != DB_SUCCESS) {
|
||||
thr_get_trx(thr)->error_state = err;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
@ -1997,7 +2032,7 @@ fetch_step(
|
|||
fprintf(stderr,
|
||||
"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);
|
||||
}
|
||||
|
@ -2546,6 +2581,7 @@ row_sel_store_mysql_rec(
|
|||
{
|
||||
mysql_row_templ_t* templ;
|
||||
mem_heap_t* extern_field_heap = NULL;
|
||||
mem_heap_t* heap;
|
||||
byte* data;
|
||||
ulint len;
|
||||
ulint i;
|
||||
|
@ -2570,7 +2606,19 @@ row_sel_store_mysql_rec(
|
|||
|
||||
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
|
||||
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,
|
||||
offsets, templ->rec_field_no, &len,
|
||||
extern_field_heap);
|
||||
heap);
|
||||
|
||||
ut_a(len != UNIV_SQL_NULL);
|
||||
} else {
|
||||
|
@ -2589,48 +2637,6 @@ row_sel_store_mysql_rec(
|
|||
}
|
||||
|
||||
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(
|
||||
mysql_rec + templ->mysql_col_offset,
|
||||
templ, data, len);
|
||||
|
@ -3250,7 +3256,7 @@ row_search_for_mysql(
|
|||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name ",
|
||||
(ulong) prebuilt->magic_n);
|
||||
ut_print_name(stderr, trx, prebuilt->table->name);
|
||||
ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -3536,15 +3542,13 @@ shortcut_fails_too_big_rec:
|
|||
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& 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
|
||||
word there */
|
||||
ibool success;
|
||||
|
||||
dict_accept(*trx->mysql_query_str, "SELECT", &success);
|
||||
|
||||
if (success) {
|
||||
if (dict_str_starts_with_keyword(trx->mysql_thd,
|
||||
*trx->mysql_query_str, "SELECT")) {
|
||||
/* It is a plain locking SELECT and the isolation
|
||||
level is low: do not lock gaps */
|
||||
|
||||
|
|
|
@ -2008,12 +2008,7 @@ row_upd_step(
|
|||
error_handling:
|
||||
trx->error_state = err;
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
/* Ok: do nothing */
|
||||
} else if (err == DB_LOCK_WAIT) {
|
||||
|
||||
return(NULL);
|
||||
} else {
|
||||
if (err != DB_SUCCESS) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ ibool srv_error_monitor_active = FALSE;
|
|||
|
||||
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 */
|
||||
|
||||
/* The following three are dir paths which are catenated before file
|
||||
|
|
|
@ -843,7 +843,7 @@ trx_undo_update_rec_get_update(
|
|||
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n"
|
||||
"InnoDB: Run also CHECK TABLE ",
|
||||
(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"
|
||||
"InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
|
||||
(ulong) n_fields, (ulong) i, ptr);
|
||||
|
|
|
@ -241,7 +241,7 @@ trx_rollback_to_savepoint_for_mysql(
|
|||
if (trx->conc_state == TRX_NOT_STARTED) {
|
||||
ut_print_timestamp(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);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ loop:
|
|||
|
||||
if (table) {
|
||||
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);
|
||||
|
||||
err = row_drop_table_for_mysql(table->name, trx, TRUE);
|
||||
|
@ -1286,7 +1286,6 @@ trx_rollback_step(
|
|||
que_thr_t* thr) /* in: query thread */
|
||||
{
|
||||
roll_node_t* node;
|
||||
ibool success;
|
||||
ulint sig_no;
|
||||
trx_savept_t* savept;
|
||||
|
||||
|
@ -1313,19 +1312,13 @@ trx_rollback_step(
|
|||
|
||||
/* Send a rollback signal to the transaction */
|
||||
|
||||
success = trx_sig_send(thr_get_trx(thr),
|
||||
sig_no, TRX_SIG_SELF,
|
||||
thr, savept, NULL);
|
||||
trx_sig_send(thr_get_trx(thr), sig_no, TRX_SIG_SELF, thr,
|
||||
savept, NULL);
|
||||
|
||||
thr->state = QUE_THR_SIG_REPLY_WAIT;
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
if (!success) {
|
||||
/* Error in delivering the rollback signal */
|
||||
que_thr_handle_error(thr, DB_ERROR, NULL, 0);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -1223,11 +1223,9 @@ trx_sig_is_compatible(
|
|||
/********************************************************************
|
||||
Sends a signal to a trx object. */
|
||||
|
||||
ibool
|
||||
void
|
||||
trx_sig_send(
|
||||
/*=========*/
|
||||
/* out: TRUE if the signal was
|
||||
successfully delivered */
|
||||
trx_t* trx, /* in: trx handle */
|
||||
ulint type, /* in: signal type */
|
||||
ulint sender, /* in: TRX_SIG_SELF or
|
||||
|
@ -1254,11 +1252,9 @@ trx_sig_send(
|
|||
|
||||
if (!trx_sig_is_compatible(trx, type, sender)) {
|
||||
/* The signal is not compatible with the other signals in
|
||||
the queue: do nothing */
|
||||
the queue: die */
|
||||
|
||||
ut_error;
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Queue the signal object */
|
||||
|
@ -1299,11 +1295,6 @@ trx_sig_send(
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1314,8 +1305,6 @@ trx_sig_send(
|
|||
|
||||
trx_sig_start_handle(trx, next_thr);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -1541,7 +1530,6 @@ trx_commit_step(
|
|||
{
|
||||
commit_node_t* node;
|
||||
que_thr_t* next_thr;
|
||||
ibool success;
|
||||
|
||||
node = thr->run_node;
|
||||
|
||||
|
@ -1562,16 +1550,11 @@ trx_commit_step(
|
|||
|
||||
/* Send the commit signal to the transaction */
|
||||
|
||||
success = trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT,
|
||||
TRX_SIG_SELF, thr, NULL, &next_thr);
|
||||
trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, TRX_SIG_SELF,
|
||||
thr, NULL, &next_thr);
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
if (!success) {
|
||||
/* Error in delivering the commit signal */
|
||||
que_thr_handle_error(thr, DB_ERROR, NULL, 0);
|
||||
}
|
||||
|
||||
return(next_thr);
|
||||
}
|
||||
|
||||
|
|
52
ut/ut0ut.c
52
ut/ut0ut.c
|
@ -20,18 +20,21 @@ Created 5/11/1994 Heikki Tuuri
|
|||
|
||||
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! */
|
||||
extern
|
||||
int
|
||||
mysql_get_identifier_quote_char(
|
||||
/*============================*/
|
||||
/* out: quote character to be
|
||||
used in SQL identifiers; EOF if none */
|
||||
void
|
||||
innobase_print_identifier(
|
||||
/*======================*/
|
||||
FILE* f, /* in: output stream */
|
||||
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 */
|
||||
ulint namelen);/* in: length of name */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/************************************************************
|
||||
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 */
|
||||
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 */
|
||||
{
|
||||
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 */
|
||||
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 */
|
||||
ulint namelen)/* in: length of name */
|
||||
{
|
||||
const char* s = name;
|
||||
const char* e = s + namelen;
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
int q = '"';
|
||||
fwrite(name, 1, namelen, f);
|
||||
#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
|
||||
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);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
Loading…
Add table
Reference in a new issue