mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
merge
BitKeeper/etc/logging_ok: auto-union configure.in: Auto merged BitKeeper/deleted/.del-identity.result~e41453a364242503: Auto merged BitKeeper/deleted/.del-identity.test~326f469b59105404: Auto merged include/my_pthread.h: Auto merged innobase/dict/dict0crea.c: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/dict/dict0load.c: Auto merged innobase/include/univ.i: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/pars/pars0opt.c: Auto merged innobase/que/que0que.c: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/row/row0upd.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/sync/sync0sync.c: Auto merged innobase/trx/trx0trx.c: Auto merged libmysql/libmysql.c: Auto merged myisam/myisampack.c: Auto merged mysql-test/t/func_test.test: Auto merged mysql-test/t/show_check.test: Auto merged mysql-test/t/variables.test: Auto merged mysys/my_pthread.c: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/mysql_priv.h: Auto merged sql/share/danish/errmsg.txt: Auto merged sql/share/english/errmsg.txt: Auto merged sql/share/french/errmsg.txt: Auto merged sql/share/german/errmsg.txt: Auto merged sql/share/greek/errmsg.txt: Auto merged sql/share/hungarian/errmsg.txt: Auto merged sql/sql_show.cc: Auto merged sql/share/italian/errmsg.txt: Auto merged sql/share/japanese/errmsg.txt: Auto merged sql/share/korean/errmsg.txt: Auto merged sql/share/norwegian-ny/errmsg.txt: Auto merged sql/share/norwegian/errmsg.txt: Auto merged sql/share/polish/errmsg.txt: Auto merged sql/share/portuguese/errmsg.txt: Auto merged sql/share/romanian/errmsg.txt: Auto merged sql/share/russian/errmsg.txt: Auto merged sql/share/slovak/errmsg.txt: Auto merged sql/share/spanish/errmsg.txt: Auto merged sql/share/swedish/errmsg.txt: Auto merged sql/share/ukrainian/errmsg.txt: Auto merged
This commit is contained in:
commit
0a03601fab
80 changed files with 1118 additions and 390 deletions
|
@ -6,6 +6,7 @@ Sinisa@sinisa.nasamreza.org
|
|||
ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
|
||||
arjen@co3064164-a.bitbike.com
|
||||
arjen@fred.bitbike.com
|
||||
arjen@george.bitbike.com
|
||||
bell@sanja.is.com.ua
|
||||
davida@isil.mysql.com
|
||||
heikki@donna.mysql.fi
|
||||
|
@ -20,6 +21,7 @@ jcole@sarvik.tfr.cafe.ee
|
|||
jcole@tetra.spaceapes.com
|
||||
jorge@linux.jorge.mysql.com
|
||||
kaj@work.mysql.com
|
||||
lenz@kallisto.mysql.com
|
||||
miguel@hegel.local
|
||||
miguel@light.local
|
||||
monty@bitch.mysql.fi
|
||||
|
@ -51,5 +53,3 @@ tonu@x3.internalnet
|
|||
venu@work.mysql.com
|
||||
zak@balfor.local
|
||||
zak@linux.local
|
||||
arjen@george.bitbike.com
|
||||
lenz@kallisto.mysql.com
|
||||
|
|
|
@ -30378,6 +30378,9 @@ stored into a temporary table) is calculated in MySQL Version
|
|||
@item expr2 or expr3 returns an integer @tab integer
|
||||
@end multitable
|
||||
|
||||
If expr2 and expr3 are strings, then the result is case sensitive if
|
||||
both strings are case sensitive. (Starting from 3.23.51)
|
||||
|
||||
@findex CASE
|
||||
@item CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
|
||||
@item CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END
|
||||
|
@ -49420,19 +49423,32 @@ not yet 100% confident in this code.
|
|||
|
||||
@node News-3.23.51, News-3.23.50, News-3.23.x, News-3.23.x
|
||||
@appendixsubsec Changes in release 3.23.51
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Fixed @code{SIGINT} and @code{SIGQUIT} problems in @code{mysql}.
|
||||
@item
|
||||
Fixed bug in character table converts when used with big ( > 64K) strings.
|
||||
Fixed the result from @code{IF()} is case in-sensitive if the 2 and
|
||||
third arguments are case sensitive.
|
||||
@end itemize
|
||||
|
||||
@node News-3.23.50, News-3.23.49, News-3.23.51, News-3.23.x
|
||||
@appendixsubsec Changes in release 3.23.50
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Fixed problem with @code{crash-me} and gcc 3.0.4.
|
||||
@item
|
||||
Fixed that @code{@@@@unknown_variable} doesn't hang server.
|
||||
@item
|
||||
Added @code{@@@@VERSION} as a synonym for @code{VERSION()}.
|
||||
@item
|
||||
@code{SHOW VARIABLES LIKE 'xxx'} is now case insensitive.
|
||||
@item
|
||||
Fixed timeout for @code{GET_LOCK()} on HPUX with DCE threads.
|
||||
@item
|
||||
Fixed memory allocation bug in the glibc library used to build Linux
|
||||
binaries, which caused mysqld to die in 'free()'.
|
||||
@item
|
||||
Fixed @code{SIGINT} and @code{SIGQUIT} problems in @code{mysql}.
|
||||
@item
|
||||
Fixed bug in character table converts when used with big ( > 64K) strings.
|
||||
@item
|
||||
@code{InnoDB} now retains foreign key constraints through @code{ALTER TABLE}
|
||||
and @code{CREATE/DROP INDEX}.
|
||||
@item
|
||||
|
|
12
configure.in
12
configure.in
|
@ -882,9 +882,9 @@ case $SYSTEM_TYPE in
|
|||
CFLAGS="$CFLAGS -DHAVE_BROKEN_GETPASS -DSOLARIS";
|
||||
;;
|
||||
*hpux10.20*)
|
||||
echo "Enabling snprintf workaround for hpux 10.20"
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_SNPRINTF -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX -DSIGNAL_WITH_VIO_CLOSE"
|
||||
CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_SNPRINTF -D_INCLUDE_LONGLONG -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX -DSIGNAL_WITH_VIO_CLOSE"
|
||||
echo "Enabling workarounds for hpux 10.20"
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_SNPRINTF -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX -DSIGNAL_WITH_VIO_CLOSE -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_SNPRINTF -D_INCLUDE_LONGLONG -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX -DSIGNAL_WITH_VIO_CLOSE -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
if test "$with_named_thread" = "no"
|
||||
then
|
||||
echo "Using --with-named-thread=-lpthread"
|
||||
|
@ -892,9 +892,9 @@ case $SYSTEM_TYPE in
|
|||
fi
|
||||
;;
|
||||
*hpux11.*)
|
||||
echo "Enabling pread/pwrite workaround for hpux 11"
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS"
|
||||
CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS"
|
||||
echo "Enabling workarounds for hpux 11"
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
if test "$with_named_thread" = "no"
|
||||
then
|
||||
echo "Using --with-named-thread=-lpthread"
|
||||
|
|
|
@ -20,8 +20,9 @@ LDADD = libdbug.a ../strings/libmystrings.a
|
|||
pkglib_LIBRARIES = libdbug.a
|
||||
noinst_HEADERS = dbug_long.h
|
||||
libdbug_a_SOURCES = dbug.c sanity.c
|
||||
EXTRA_DIST = example1.c example2.c example3.c user.r monty.doc readme.prof \
|
||||
main.c factorial.c
|
||||
EXTRA_DIST = example1.c example2.c example3.c \
|
||||
user.r monty.doc readme.prof \
|
||||
main.c factorial.c dbug_analyze.c
|
||||
|
||||
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
|
||||
__math.h time.h __time.h unistd.h __unistd.h types.h \
|
||||
|
@ -32,7 +33,7 @@ OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
|
|||
sleep.h specific.h version.h pwd.h timers.h uio.h \
|
||||
cdefs.h machdep.h signal.h __signal.h util.h
|
||||
|
||||
# Must be linked with libs thta are not compiled yet
|
||||
# Must be linked with libs that are not compiled yet
|
||||
extra_progs: factorial dbug_analyze
|
||||
|
||||
factorial: main.o factorial.o
|
||||
|
|
|
@ -10,3 +10,11 @@ giving a double ':'. (As in "O,c::\tmp\log")
|
|||
|
||||
DBUG_DUMP("keyword",memory-position,length) writes a hexdump of the
|
||||
given memory-area to the outputfile.
|
||||
|
||||
All changes that I or other people at MySQL AB have done to all files
|
||||
in the dbug library (Mainly in dbug.c, dbug_analyze.c, dbug_long.h,
|
||||
dbug.h) are put in public domain, as the rest of the dbug.c library)
|
||||
|
||||
To my knowledge, all code in dbug library are in public domain.
|
||||
|
||||
Michael Widenius
|
||||
|
|
|
@ -349,6 +349,13 @@ extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
|
|||
#undef HAVE_GETHOSTBYADDR_R /* No definition */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
|
||||
extern int my_pthread_cond_timedwait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
struct timespec *abstime);
|
||||
#define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C))
|
||||
#endif
|
||||
|
||||
#if defined(OS2)
|
||||
#define my_pthread_getspecific(T,A) ((T) &(A))
|
||||
#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
|
||||
|
|
|
@ -228,6 +228,7 @@ btr_cur_search_to_nth_level(
|
|||
ulint insert_planned;
|
||||
ulint buf_mode;
|
||||
ulint estimate;
|
||||
ulint ignore_sec_unique;
|
||||
ulint root_height = 0; /* remove warning */
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
btr_search_t* info;
|
||||
|
@ -246,7 +247,9 @@ btr_cur_search_to_nth_level(
|
|||
#endif
|
||||
insert_planned = latch_mode & BTR_INSERT;
|
||||
estimate = latch_mode & BTR_ESTIMATE;
|
||||
latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE);
|
||||
ignore_sec_unique = latch_mode & BTR_IGNORE_SEC_UNIQUE;
|
||||
latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE
|
||||
| BTR_IGNORE_SEC_UNIQUE);
|
||||
|
||||
ut_ad(!insert_planned || (mode == PAGE_CUR_LE));
|
||||
|
||||
|
@ -343,7 +346,8 @@ btr_cur_search_to_nth_level(
|
|||
|
||||
rw_latch = latch_mode;
|
||||
|
||||
if (insert_planned && ibuf_should_try(index)) {
|
||||
if (insert_planned && ibuf_should_try(index,
|
||||
ignore_sec_unique)) {
|
||||
|
||||
/* Try insert to the insert buffer if the
|
||||
page is not in the buffer pool */
|
||||
|
@ -356,7 +360,6 @@ retry_page_get:
|
|||
buf_mode,
|
||||
IB__FILE__, __LINE__,
|
||||
mtr);
|
||||
|
||||
if (page == NULL) {
|
||||
/* This must be a search to perform an insert;
|
||||
try insert to the insert buffer */
|
||||
|
@ -365,7 +368,7 @@ retry_page_get:
|
|||
ut_ad(insert_planned);
|
||||
ut_ad(cursor->thr);
|
||||
|
||||
if (ibuf_should_try(index) &&
|
||||
if (ibuf_should_try(index, ignore_sec_unique) &&
|
||||
ibuf_insert(tuple, index, space, page_no,
|
||||
cursor->thr)) {
|
||||
/* Insertion to the insert buffer succeeded */
|
||||
|
|
|
@ -1201,7 +1201,8 @@ loop:
|
|||
ut_dulint_get_low(id),
|
||||
table->name,
|
||||
foreign->referenced_table_name,
|
||||
foreign->n_fields);
|
||||
foreign->n_fields
|
||||
+ (foreign->type << 24));
|
||||
|
||||
for (i = 0; i < foreign->n_fields; i++) {
|
||||
|
||||
|
|
|
@ -1652,7 +1652,7 @@ dict_foreign_find_index(
|
|||
->col->name;
|
||||
if (ut_strlen(columns[i]) !=
|
||||
ut_strlen(col_name)
|
||||
|| 0 != ut_memcmp(columns[i],
|
||||
|| 0 != ut_cmp_in_lower_case(columns[i],
|
||||
col_name,
|
||||
ut_strlen(col_name))) {
|
||||
break;
|
||||
|
@ -1857,8 +1857,9 @@ dict_scan_col(
|
|||
ibool* success,/* out: TRUE if success */
|
||||
dict_table_t* table, /* in: table in which the column is */
|
||||
dict_col_t** column, /* out: pointer to column if success */
|
||||
char** column_name)/* out: pointer to column->name if
|
||||
char** column_name,/* out: pointer to column->name if
|
||||
success */
|
||||
ulint* column_name_len)/* out: column name length */
|
||||
{
|
||||
dict_col_t* col;
|
||||
char* old_ptr;
|
||||
|
@ -1886,20 +1887,28 @@ dict_scan_col(
|
|||
ptr++;
|
||||
}
|
||||
|
||||
for (i = 0; i < dict_table_get_n_cols(table); i++) {
|
||||
*column_name_len = (ulint)(ptr - old_ptr);
|
||||
|
||||
if (table == NULL) {
|
||||
*success = TRUE;
|
||||
*column = NULL;
|
||||
*column_name = old_ptr;
|
||||
} else {
|
||||
for (i = 0; i < dict_table_get_n_cols(table); i++) {
|
||||
|
||||
col = dict_table_get_nth_col(table, i);
|
||||
col = dict_table_get_nth_col(table, i);
|
||||
|
||||
if (ut_strlen(col->name) == (ulint)(ptr - old_ptr)
|
||||
&& 0 == ut_cmp_in_lower_case(col->name, old_ptr,
|
||||
if (ut_strlen(col->name) == (ulint)(ptr - old_ptr)
|
||||
&& 0 == ut_cmp_in_lower_case(col->name, old_ptr,
|
||||
(ulint)(ptr - old_ptr))) {
|
||||
/* Found */
|
||||
/* Found */
|
||||
|
||||
*success = TRUE;
|
||||
*column = col;
|
||||
*column_name = col->name;
|
||||
*success = TRUE;
|
||||
*column = col;
|
||||
*column_name = col->name;
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1918,14 +1927,18 @@ dict_scan_table_name(
|
|||
/*=================*/
|
||||
/* out: scanned to */
|
||||
char* ptr, /* in: scanned to */
|
||||
dict_table_t** table, /* out: table object or NULL if error */
|
||||
char* name) /* in: foreign key table name */
|
||||
dict_table_t** table, /* out: table object or NULL */
|
||||
char* name, /* in: foreign key table name */
|
||||
ibool* success,/* out: TRUE if ok name found */
|
||||
char* second_table_name)/* in/out: buffer where to store
|
||||
the referenced table name; must be at least
|
||||
2500 bytes */
|
||||
{
|
||||
char* dot_ptr = NULL;
|
||||
char* old_ptr;
|
||||
ulint i;
|
||||
char second_table_name[10000];
|
||||
|
||||
*success = FALSE;
|
||||
*table = NULL;
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
|
@ -1951,7 +1964,7 @@ dict_scan_table_name(
|
|||
ptr++;
|
||||
}
|
||||
|
||||
if (ptr - old_ptr > 9000) {
|
||||
if (ptr - old_ptr > 2000) {
|
||||
return(old_ptr);
|
||||
}
|
||||
|
||||
|
@ -1982,6 +1995,8 @@ dict_scan_table_name(
|
|||
second_table_name[ptr - old_ptr] = '\0';
|
||||
}
|
||||
|
||||
*success = TRUE;
|
||||
|
||||
*table = dict_table_get_low(second_table_name);
|
||||
|
||||
if (*ptr == '`') {
|
||||
|
@ -2047,9 +2062,12 @@ dict_create_foreign_constraints(
|
|||
ibool success;
|
||||
ulint error;
|
||||
ulint i;
|
||||
dict_col_t* columns[1000];
|
||||
char* column_names[1000];
|
||||
|
||||
ulint j;
|
||||
dict_col_t* columns[500];
|
||||
char* column_names[500];
|
||||
ulint column_name_lens[500];
|
||||
char referenced_table_name[2500];
|
||||
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
table = dict_table_get_low(name);
|
||||
|
@ -2094,7 +2112,7 @@ loop:
|
|||
/* Scan the columns in the first list */
|
||||
col_loop1:
|
||||
ptr = dict_scan_col(ptr, &success, table, columns + i,
|
||||
column_names + i);
|
||||
column_names + i, column_name_lens + i);
|
||||
if (!success) {
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
@ -2145,9 +2163,13 @@ col_loop1:
|
|||
1 + ut_strlen(columns[i]->name));
|
||||
}
|
||||
|
||||
ptr = dict_scan_table_name(ptr, &referenced_table, name);
|
||||
ptr = dict_scan_table_name(ptr, &referenced_table, name,
|
||||
&success, referenced_table_name);
|
||||
|
||||
if (!referenced_table) {
|
||||
/* Note that referenced_table can be NULL if the user has suppressed
|
||||
checking of foreign key constraints! */
|
||||
|
||||
if (!success || (!referenced_table && trx->check_foreigns)) {
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
|
@ -2165,7 +2187,7 @@ col_loop1:
|
|||
|
||||
col_loop2:
|
||||
ptr = dict_scan_col(ptr, &success, referenced_table, columns + i,
|
||||
column_names + i);
|
||||
column_names + i, column_name_lens + i);
|
||||
i++;
|
||||
|
||||
if (!success) {
|
||||
|
@ -2187,43 +2209,104 @@ col_loop2:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "ON", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "DELETE", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "CASCADE", &success);
|
||||
|
||||
if (success) {
|
||||
|
||||
foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE;
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "SET", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "NULL", &success);
|
||||
|
||||
if (success) {
|
||||
for (j = 0; j < foreign->n_fields; j++) {
|
||||
if ((dict_index_get_nth_type(
|
||||
foreign->foreign_index, j)->prtype)
|
||||
& DATA_NOT_NULL) {
|
||||
|
||||
/* It is not sensible to define SET NULL
|
||||
if the column is not allowed to be NULL! */
|
||||
|
||||
dict_foreign_free(foreign);
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL;
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
try_find_index:
|
||||
/* Try to find an index which contains the columns as the first fields
|
||||
and in the right order, and the types are the same as in
|
||||
foreign->foreign_index */
|
||||
|
||||
index = dict_foreign_find_index(referenced_table, column_names, i,
|
||||
if (referenced_table) {
|
||||
index = dict_foreign_find_index(referenced_table,
|
||||
column_names, i,
|
||||
foreign->foreign_index);
|
||||
|
||||
if (!index) {
|
||||
dict_foreign_free(foreign);
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
if (!index) {
|
||||
dict_foreign_free(foreign);
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
} else {
|
||||
ut_a(trx->check_foreigns == FALSE);
|
||||
index = NULL;
|
||||
}
|
||||
|
||||
foreign->referenced_index = index;
|
||||
foreign->referenced_table = referenced_table;
|
||||
|
||||
foreign->referenced_table_name = mem_heap_alloc(foreign->heap,
|
||||
1 + ut_strlen(referenced_table->name));
|
||||
1 + ut_strlen(referenced_table_name));
|
||||
|
||||
ut_memcpy(foreign->referenced_table_name, referenced_table->name,
|
||||
1 + ut_strlen(referenced_table->name));
|
||||
ut_memcpy(foreign->referenced_table_name, referenced_table_name,
|
||||
1 + ut_strlen(referenced_table_name));
|
||||
|
||||
foreign->referenced_col_names = mem_heap_alloc(foreign->heap,
|
||||
i * sizeof(void*));
|
||||
for (i = 0; i < foreign->n_fields; i++) {
|
||||
foreign->referenced_col_names[i]
|
||||
= mem_heap_alloc(foreign->heap,
|
||||
1 + ut_strlen(columns[i]->name));
|
||||
ut_memcpy(
|
||||
foreign->referenced_col_names[i], columns[i]->name,
|
||||
1 + ut_strlen(columns[i]->name));
|
||||
1 + column_name_lens[i]);
|
||||
ut_memcpy(foreign->referenced_col_names[i], column_names[i],
|
||||
column_name_lens[i]);
|
||||
(foreign->referenced_col_names[i])[column_name_lens[i]] = '\0';
|
||||
}
|
||||
|
||||
/* We found an ok constraint definition: add to the lists */
|
||||
|
||||
UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign);
|
||||
UT_LIST_ADD_LAST(referenced_list, referenced_table->referenced_list,
|
||||
|
||||
if (referenced_table) {
|
||||
UT_LIST_ADD_LAST(referenced_list,
|
||||
referenced_table->referenced_list,
|
||||
foreign);
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -3039,6 +3122,14 @@ dict_print_info_on_foreign_keys_in_create_format(
|
|||
|
||||
buf2 += sprintf(buf2, ")");
|
||||
|
||||
if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
|
||||
buf2 += sprintf(buf2, " ON DELETE CASCADE");
|
||||
}
|
||||
|
||||
if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
|
||||
buf2 += sprintf(buf2, " ON DELETE SET NULL");
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
||||
}
|
||||
|
||||
|
|
|
@ -946,6 +946,11 @@ dict_load_foreign(
|
|||
foreign->n_fields = mach_read_from_4(rec_get_nth_field(rec, 5, &len));
|
||||
|
||||
ut_a(len == 4);
|
||||
|
||||
/* We store the type to the bits 24-31 of n_fields */
|
||||
|
||||
foreign->type = foreign->n_fields >> 24;
|
||||
foreign->n_fields = foreign->n_fields & 0xFFFFFF;
|
||||
|
||||
foreign->id = mem_heap_alloc(foreign->heap, ut_strlen(id) + 1);
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ dict_mem_table_create(
|
|||
table->mem_fix = 0;
|
||||
|
||||
table->n_mysql_handles_opened = 0;
|
||||
|
||||
table->n_foreign_key_checks_running = 0;
|
||||
|
||||
table->cached = FALSE;
|
||||
|
||||
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
|
||||
|
@ -235,6 +236,7 @@ dict_mem_foreign_create(void)
|
|||
|
||||
foreign->id = NULL;
|
||||
|
||||
foreign->type = 0;
|
||||
foreign->foreign_table_name = NULL;
|
||||
foreign->foreign_table = NULL;
|
||||
foreign->foreign_col_names = NULL;
|
||||
|
|
|
@ -49,6 +49,12 @@ inserted to the index, at the searched position */
|
|||
/* This flag ORed to latch mode says that we do the search in query
|
||||
optimization */
|
||||
#define BTR_ESTIMATE 1024
|
||||
|
||||
/* This flag ORed to latch mode says that we can ignore possible
|
||||
UNIQUE definition on secondary indexes when we decide if we can use the
|
||||
insert buffer to speed up inserts */
|
||||
#define BTR_IGNORE_SEC_UNIQUE 2048
|
||||
|
||||
/******************************************************************
|
||||
Gets a buffer page and declares its latching order level. */
|
||||
UNIV_INLINE
|
||||
|
|
|
@ -249,6 +249,8 @@ struct dict_foreign_struct{
|
|||
this memory heap */
|
||||
char* id; /* id of the constraint as a
|
||||
null-terminated string */
|
||||
ulint type; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE
|
||||
or DICT_FOREIGN_ON_DELETE_SET_NULL */
|
||||
char* foreign_table_name;/* foreign table name */
|
||||
dict_table_t* foreign_table; /* table where the foreign key is */
|
||||
char** foreign_col_names;/* names of the columns in the
|
||||
|
@ -278,6 +280,9 @@ struct dict_foreign_struct{
|
|||
table */
|
||||
};
|
||||
|
||||
#define DICT_FOREIGN_ON_DELETE_CASCADE 1
|
||||
#define DICT_FOREIGN_ON_DELETE_SET_NULL 2
|
||||
|
||||
#define DICT_INDEX_MAGIC_N 76789786
|
||||
|
||||
/* Data structure for a database table */
|
||||
|
@ -313,6 +318,12 @@ struct dict_table_struct{
|
|||
NOT allowed until this count gets to zero;
|
||||
MySQL does NOT itself check the number of
|
||||
open handles at drop */
|
||||
ulint n_foreign_key_checks_running;
|
||||
/* count of how many foreign key check
|
||||
operations are currently being performed
|
||||
on the table: we cannot drop the table while
|
||||
there are foreign key checks running on
|
||||
it! */
|
||||
ibool cached; /* TRUE if the table object has been added
|
||||
to the dictionary cache */
|
||||
lock_t* auto_inc_lock;/* a buffer for an auto-inc lock
|
||||
|
@ -359,17 +370,16 @@ struct dict_table_struct{
|
|||
after database startup or table creation */
|
||||
ulint stat_modified_counter;
|
||||
/* when a row is inserted, updated, or deleted,
|
||||
we add the row length to this number; we
|
||||
calculate new estimates for the stat_...
|
||||
values for the table and the indexes at an
|
||||
interval of 2 GB or when about 1 / 16 of table
|
||||
has been modified; also
|
||||
when the estimate operation is called
|
||||
for MySQL SHOW TABLE STATUS; the counter is
|
||||
reset to zero at statistics calculation;
|
||||
this counter
|
||||
is not protected by any latch, because this
|
||||
is only used for heuristics */
|
||||
we add 1 to this number; we calculate new
|
||||
estimates for the stat_... values for the
|
||||
table and the indexes at an interval of 2 GB
|
||||
or when about 1 / 16 of table has been
|
||||
modified; also when the estimate operation is
|
||||
called for MySQL SHOW TABLE STATUS; the
|
||||
counter is reset to zero at statistics
|
||||
calculation; this counter is not protected by
|
||||
any latch, because this is only used for
|
||||
heuristics */
|
||||
/*----------------------*/
|
||||
mutex_t autoinc_mutex;
|
||||
/* mutex protecting the autoincrement
|
||||
|
|
|
@ -127,7 +127,11 @@ UNIV_INLINE
|
|||
ibool
|
||||
ibuf_should_try(
|
||||
/*============*/
|
||||
dict_index_t* index); /* in: index where to insert */
|
||||
dict_index_t* index, /* in: index where to insert */
|
||||
ulint ignore_sec_unique); /* in: if != 0, we should
|
||||
ignore UNIQUE constraint on
|
||||
a secondary index when we
|
||||
decide */
|
||||
/**********************************************************************
|
||||
Returns TRUE if the current OS thread is performing an insert buffer
|
||||
routine. */
|
||||
|
|
|
@ -81,10 +81,16 @@ UNIV_INLINE
|
|||
ibool
|
||||
ibuf_should_try(
|
||||
/*============*/
|
||||
dict_index_t* index) /* in: index where to insert */
|
||||
dict_index_t* index, /* in: index where to insert */
|
||||
ulint ignore_sec_unique) /* in: if != 0, we should
|
||||
ignore UNIQUE constraint on
|
||||
a secondary index when we
|
||||
decide */
|
||||
{
|
||||
if (!(index->type & (DICT_CLUSTERED | DICT_UNIQUE))
|
||||
&& ibuf->meter > IBUF_THRESHOLD) {
|
||||
if (!(index->type & DICT_CLUSTERED)
|
||||
&& (ignore_sec_unique || !(index->type & DICT_UNIQUE))
|
||||
&& ibuf->meter > IBUF_THRESHOLD) {
|
||||
|
||||
ibuf_flush_count++;
|
||||
|
||||
if (ibuf_flush_count % 8 == 0) {
|
||||
|
|
|
@ -25,12 +25,6 @@ extern ibool os_has_said_disk_full;
|
|||
|
||||
#define UNIV_NON_BUFFERED_IO
|
||||
|
||||
#else
|
||||
|
||||
#if defined(HAVE_AIO_H) && defined(HAVE_LIBRT)
|
||||
#define POSIX_ASYNC_IO
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __WIN__
|
||||
|
@ -347,6 +341,8 @@ os_aio_windows_handle(
|
|||
void** message2,
|
||||
ulint* type); /* out: OS_FILE_WRITE or ..._READ */
|
||||
#endif
|
||||
|
||||
/* Currently we do not use Posix async i/o */
|
||||
#ifdef POSIX_ASYNC_IO
|
||||
/**************************************************************************
|
||||
This function is only used in Posix asynchronous i/o. Waits for an aio
|
||||
|
|
|
@ -149,9 +149,9 @@ void
|
|||
os_mutex_free(
|
||||
/*==========*/
|
||||
os_mutex_t mutex); /* in: mutex to free */
|
||||
#ifndef _WIN32
|
||||
/**************************************************************
|
||||
Acquires ownership of a fast mutex. */
|
||||
Acquires ownership of a fast mutex. Currently in Windows this is the same
|
||||
as os_fast_mutex_lock! */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
os_fast_mutex_trylock(
|
||||
|
@ -160,7 +160,6 @@ os_fast_mutex_trylock(
|
|||
was reserved by another
|
||||
thread */
|
||||
os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
|
||||
#endif
|
||||
/**************************************************************
|
||||
Releases ownership of a fast mutex. */
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ Created 9/6/1995 Heikki Tuuri
|
|||
#include <winbase.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
/**************************************************************
|
||||
Acquires ownership of a fast mutex. */
|
||||
Acquires ownership of a fast mutex. Currently in Windows this is the same
|
||||
as os_fast_mutex_lock! */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
os_fast_mutex_trylock(
|
||||
|
@ -23,20 +23,11 @@ os_fast_mutex_trylock(
|
|||
os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
int ret;
|
||||
EnterCriticalSection(fast_mutex);
|
||||
|
||||
/* TODO: TryEnterCriticalSection is probably not found from
|
||||
NT versions < 4! */
|
||||
ret = TryEnterCriticalSection(fast_mutex);
|
||||
|
||||
if (ret) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
return(0);
|
||||
#else
|
||||
return((ulint) pthread_mutex_trylock(fast_mutex));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -209,6 +209,27 @@ row_update_for_mysql(
|
|||
row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
|
||||
handle */
|
||||
/*************************************************************************
|
||||
Creates an query graph node of 'update' type to be used in the MySQL
|
||||
interface. */
|
||||
|
||||
upd_node_t*
|
||||
row_create_update_node_for_mysql(
|
||||
/*=============================*/
|
||||
/* out, own: update node */
|
||||
dict_table_t* table, /* in: table to update */
|
||||
mem_heap_t* heap); /* in: mem heap from which allocated */
|
||||
/**************************************************************************
|
||||
Does a cascaded delete or set null in a foreign key operation. */
|
||||
|
||||
ulint
|
||||
row_update_cascade_for_mysql(
|
||||
/*=========================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
que_thr_t* thr, /* in: query thread */
|
||||
upd_node_t* node, /* in: update node used in the cascade
|
||||
or set null operation */
|
||||
dict_table_t* table); /* in: table where we do the operation */
|
||||
/*************************************************************************
|
||||
Does a table creation operation for MySQL. If the name of the created
|
||||
table ends to characters INNODB_MONITOR, then this also starts
|
||||
printing of monitor output by the master thread. */
|
||||
|
|
|
@ -312,6 +312,11 @@ struct upd_node_struct{
|
|||
ibool in_mysql_interface;
|
||||
/* TRUE if the update node was created
|
||||
for the MySQL interface */
|
||||
upd_node_t* cascade_node;/* NULL or an update node template which
|
||||
is used to implement ON DELETE CASCADE
|
||||
or ... SET NULL for foreign keys */
|
||||
mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
|
||||
node is created */
|
||||
sel_node_t* select; /* query graph subtree implementing a base
|
||||
table cursor: the rows returned will be
|
||||
updated */
|
||||
|
@ -322,6 +327,11 @@ struct upd_node_struct{
|
|||
of the MySQL interface */
|
||||
dict_table_t* table; /* table where updated */
|
||||
upd_t* update; /* update vector for the row */
|
||||
ulint update_n_fields;
|
||||
/* when this struct is used to implement
|
||||
a cascade operation for foreign keys, we store
|
||||
here the size of the buffer allocated for use
|
||||
as the update vector */
|
||||
sym_node_list_t columns;/* symbol table nodes for the columns
|
||||
to retrieve from the table */
|
||||
ibool has_clust_rec_x_lock;
|
||||
|
|
|
@ -359,12 +359,17 @@ V
|
|||
Memory pool mutex */
|
||||
|
||||
/* Latching order levels */
|
||||
|
||||
/* User transaction locks are higher than any of the latch levels below:
|
||||
no latches are allowed when a thread goes to wait for a normal table
|
||||
or row lock! */
|
||||
#define SYNC_USER_TRX_LOCK 9999
|
||||
#define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress
|
||||
latching order checking */
|
||||
#define SYNC_LEVEL_NONE 2000 /* default: level not defined */
|
||||
#define SYNC_FOREIGN_KEY_CHECK 1001
|
||||
#define SYNC_DICT 1000
|
||||
#define SYNC_DICT_AUTOINC_MUTEX 999
|
||||
#define SYNC_FOREIGN_KEY_CHECK 998
|
||||
#define SYNC_PURGE_IS_RUNNING 997
|
||||
#define SYNC_DICT_HEADER 995
|
||||
#define SYNC_IBUF_HEADER 914
|
||||
|
@ -429,7 +434,7 @@ implementation of a mutual exclusion semaphore. */
|
|||
struct mutex_struct {
|
||||
ulint lock_word; /* This ulint is the target of the atomic
|
||||
test-and-set instruction in Win32 */
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
os_fast_mutex_t
|
||||
os_fast_mutex; /* In other systems we use this OS mutex
|
||||
in place of lock_word */
|
||||
|
|
|
@ -53,7 +53,7 @@ mutex_test_and_set(
|
|||
1 */
|
||||
mutex_t* mutex) /* in: mutex */
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
ulint res;
|
||||
ulint* lw; /* assembler code is used to ensure that
|
||||
lock_word is loaded from memory */
|
||||
|
@ -120,7 +120,7 @@ mutex_reset_lock_word(
|
|||
/*==================*/
|
||||
mutex_t* mutex) /* in: mutex */
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
ulint* lw; /* assembler code is used to ensure that
|
||||
lock_word is loaded from memory */
|
||||
ut_ad(mutex);
|
||||
|
|
|
@ -259,7 +259,7 @@ therefore 256 */
|
|||
/* The offset of the transaction system header on the page */
|
||||
#define TRX_SYS FSEG_PAGE_DATA
|
||||
|
||||
/* Transaction system header; protected by trx_sys->mutex */
|
||||
/* Transaction system header */
|
||||
/*-------------------------------------------------------------*/
|
||||
#define TRX_SYS_TRX_ID_STORE 0 /* the maximum trx id or trx number
|
||||
modulo TRX_SYS_TRX_ID_UPDATE_MARGIN
|
||||
|
|
|
@ -93,7 +93,6 @@ trx_sysf_get(
|
|||
{
|
||||
trx_sysf_t* header;
|
||||
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
ut_ad(mtr);
|
||||
|
||||
header = TRX_SYS + buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
|
||||
|
|
|
@ -298,6 +298,17 @@ struct trx_struct{
|
|||
of view of concurrency control:
|
||||
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
|
||||
... */
|
||||
ibool check_foreigns; /* normally TRUE, but if the user
|
||||
wants to suppress foreign key checks,
|
||||
(in table imports, for example) we
|
||||
set this FALSE */
|
||||
ibool check_unique_secondary;
|
||||
/* normally TRUE, but if the user
|
||||
wants to speed up inserts by
|
||||
suppressing unique key checks
|
||||
for secondary indexes when we decide
|
||||
if we can use the insert buffer for
|
||||
them, we set this FALSE */
|
||||
dulint id; /* transaction id */
|
||||
dulint no; /* transaction serialization number ==
|
||||
max trx id when the transaction is
|
||||
|
@ -328,6 +339,9 @@ struct trx_struct{
|
|||
/* how many tables the current SQL
|
||||
statement uses, except those
|
||||
in consistent read */
|
||||
ibool has_dict_foreign_key_check_lock;
|
||||
/* TRUE if the trx currently holds
|
||||
an s-lock on dict_foreign_... */
|
||||
ibool has_search_latch;
|
||||
/* TRUE if this trx has latched the
|
||||
search system latch in S-mode */
|
||||
|
|
|
@ -14,6 +14,13 @@ Created 1/20/1994 Heikki Tuuri
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
/* When compiling for Itanium IA64, undefine the flag below to prevent use
|
||||
of 32-bit assembler */
|
||||
|
||||
#ifndef WIN64
|
||||
#define UNIV_CAN_USE_X86_ASSEMBLER
|
||||
#endif
|
||||
|
||||
/* If you want to check for errors with compiler level -W4,
|
||||
comment out the above include of windows.h and let the following defines
|
||||
be defined:
|
||||
|
@ -71,13 +78,14 @@ memory is read outside the allocated blocks. */
|
|||
*/
|
||||
|
||||
/* Make a non-inline debug version */
|
||||
|
||||
/*
|
||||
#define UNIV_DEBUG
|
||||
#define UNIV_MEM_DEBUG
|
||||
#define UNIV_SEARCH_DEBUG
|
||||
#define UNIV_SYNC_DEBUG
|
||||
|
||||
#define UNIV_IBUF_DEBUG
|
||||
#define UNIV_SYNC_DEBUG
|
||||
#define UNIV_SEARCH_DEBUG
|
||||
#define UNIV_SYNC_PERF_STAT
|
||||
#define UNIV_SEARCH_PERF_STAT
|
||||
*/
|
||||
|
|
|
@ -1535,6 +1535,8 @@ lock_rec_enqueue_waiting(
|
|||
|
||||
if (que_thr_stop(thr)) {
|
||||
|
||||
ut_a(0);
|
||||
|
||||
return(DB_QUE_THR_SUSPENDED);
|
||||
}
|
||||
|
||||
|
@ -2919,6 +2921,7 @@ lock_table_enqueue_waiting(
|
|||
stopped anyway */
|
||||
|
||||
if (que_thr_stop(thr)) {
|
||||
ut_a(0);
|
||||
|
||||
return(DB_QUE_THR_SUSPENDED);
|
||||
}
|
||||
|
|
|
@ -526,7 +526,8 @@ opt_search_plan_for_table(
|
|||
dict_index_t* best_index;
|
||||
ulint n_fields;
|
||||
ulint goodness;
|
||||
ulint last_op;
|
||||
ulint last_op = 75946965; /* Eliminate a Purify
|
||||
warning */
|
||||
ulint best_goodness;
|
||||
ulint best_last_op = 0; /* remove warning */
|
||||
ulint mix_id_pos;
|
||||
|
|
|
@ -555,6 +555,12 @@ que_graph_free_recursive(
|
|||
btr_pcur_free_for_mysql(upd->pcur);
|
||||
}
|
||||
|
||||
que_graph_free_recursive(upd->cascade_node);
|
||||
|
||||
if (upd->cascade_heap) {
|
||||
mem_heap_free(upd->cascade_heap);
|
||||
}
|
||||
|
||||
que_graph_free_recursive(upd->select);
|
||||
|
||||
mem_heap_free(upd->heap);
|
||||
|
@ -1110,9 +1116,6 @@ que_thr_move_to_run_state_for_mysql(
|
|||
trx->n_active_thrs++;
|
||||
|
||||
thr->is_active = TRUE;
|
||||
|
||||
ut_ad((thr->graph)->n_active_thrs == 1);
|
||||
ut_ad(trx->n_active_thrs == 1);
|
||||
}
|
||||
|
||||
thr->state = QUE_THR_RUNNING;
|
||||
|
|
|
@ -355,6 +355,223 @@ row_ins_dupl_error_with_rec(
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Either deletes or sets the referencing columns SQL NULL in a child row.
|
||||
Used in ON DELETE ... clause for foreign keys when a parent row is
|
||||
deleted. */
|
||||
static
|
||||
ulint
|
||||
row_ins_foreign_delete_or_set_null(
|
||||
/*===============================*/
|
||||
/* out: DB_SUCCESS, DB_LOCK_WAIT,
|
||||
or error code */
|
||||
que_thr_t* thr, /* in: query thread whose run_node
|
||||
is an update node */
|
||||
dict_foreign_t* foreign, /* in: foreign key constraint whose
|
||||
type is != 0 */
|
||||
btr_pcur_t* pcur, /* in: cursor placed on a matching
|
||||
index record in the child table */
|
||||
mtr_t* mtr) /* in: mtr holding the latch of pcur
|
||||
page */
|
||||
{
|
||||
upd_node_t* node;
|
||||
upd_node_t* cascade;
|
||||
dict_table_t* table = foreign->foreign_table;
|
||||
dict_index_t* index;
|
||||
dict_index_t* clust_index;
|
||||
dtuple_t* ref;
|
||||
mem_heap_t* tmp_heap;
|
||||
rec_t* rec;
|
||||
rec_t* clust_rec;
|
||||
upd_t* update;
|
||||
ulint err;
|
||||
ulint i;
|
||||
char err_buf[1000];
|
||||
|
||||
ut_a(thr && foreign && pcur && mtr);
|
||||
|
||||
node = thr->run_node;
|
||||
|
||||
if (node->cascade_node == NULL) {
|
||||
/* Extend our query graph by creating a child to current
|
||||
update node. The child is used in the cascade or set null
|
||||
operation. */
|
||||
|
||||
node->cascade_heap = mem_heap_create(128);
|
||||
node->cascade_node = row_create_update_node_for_mysql(
|
||||
table, node->cascade_heap);
|
||||
que_node_set_parent(node->cascade_node, node);
|
||||
}
|
||||
|
||||
/* Initialize cascade_node to do the operation we want. Note that we
|
||||
use the SAME cascade node to do all foreign key operations of the
|
||||
SQL DELETE: the table of the cascade node may change if there are
|
||||
several child tables to the table where the delete is done! */
|
||||
|
||||
cascade = node->cascade_node;
|
||||
|
||||
cascade->table = table;
|
||||
|
||||
if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE ) {
|
||||
cascade->is_delete = TRUE;
|
||||
} else {
|
||||
cascade->is_delete = FALSE;
|
||||
|
||||
if (foreign->n_fields > cascade->update_n_fields) {
|
||||
/* We have to make the update vector longer */
|
||||
|
||||
cascade->update = upd_create(foreign->n_fields,
|
||||
node->cascade_heap);
|
||||
cascade->update_n_fields = foreign->n_fields;
|
||||
}
|
||||
}
|
||||
|
||||
index = btr_pcur_get_btr_cur(pcur)->index;
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
if (index->type & DICT_CLUSTERED) {
|
||||
/* pcur is already positioned in the clustered index of
|
||||
the child table */
|
||||
|
||||
clust_index = index;
|
||||
clust_rec = rec;
|
||||
} else {
|
||||
/* We have to look for the record in the clustered index
|
||||
in the child table */
|
||||
|
||||
clust_index = dict_table_get_first_index(table);
|
||||
|
||||
tmp_heap = mem_heap_create(256);
|
||||
|
||||
ref = row_build_row_ref(ROW_COPY_POINTERS, index, rec,
|
||||
tmp_heap);
|
||||
btr_pcur_open_with_no_init(clust_index, ref,
|
||||
PAGE_CUR_LE, BTR_SEARCH_LEAF,
|
||||
cascade->pcur, 0, mtr);
|
||||
|
||||
mem_heap_free(tmp_heap);
|
||||
|
||||
clust_rec = btr_pcur_get_rec(cascade->pcur);
|
||||
}
|
||||
|
||||
if (!page_rec_is_user_rec(clust_rec)) {
|
||||
fprintf(stderr, "InnoDB: error in cascade of a foreign key op\n"
|
||||
"InnoDB: index %s table %s\n", index->name,
|
||||
index->table->name);
|
||||
|
||||
rec_sprintf(err_buf, 900, rec);
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
|
||||
rec_sprintf(err_buf, 900, clust_rec);
|
||||
fprintf(stderr, "InnoDB: clustered record %s\n", err_buf);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Make a detailed bug report and send it\n");
|
||||
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
|
||||
|
||||
err = DB_SUCCESS;
|
||||
|
||||
goto nonstandard_exit_func;
|
||||
}
|
||||
|
||||
/* Set an X-lock on the row to delete or update in the child table */
|
||||
|
||||
err = lock_table(0, table, LOCK_IX, thr);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
err = lock_clust_rec_read_check_and_lock(0, clust_rec,
|
||||
clust_index, LOCK_X, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
goto nonstandard_exit_func;
|
||||
}
|
||||
|
||||
if (rec_get_deleted_flag(clust_rec)) {
|
||||
/* This should never happen since we already have an S-lock
|
||||
on non-delete-marked clust_rec or secondary index record! */
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: error 2 in cascade of a foreign key op\n"
|
||||
"InnoDB: index %s table %s\n", index->name,
|
||||
index->table->name);
|
||||
|
||||
rec_sprintf(err_buf, 900, rec);
|
||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||
|
||||
rec_sprintf(err_buf, 900, clust_rec);
|
||||
fprintf(stderr, "InnoDB: clustered record %s\n", err_buf);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Make a detailed bug report and send it\n");
|
||||
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
|
||||
|
||||
ut_a(0);
|
||||
|
||||
goto nonstandard_exit_func;
|
||||
}
|
||||
|
||||
if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
|
||||
/* Build the appropriate update vector which sets
|
||||
foreign->n_fields first fields in rec to SQL NULL */
|
||||
|
||||
update = cascade->update;
|
||||
|
||||
update->info_bits = 0;
|
||||
update->n_fields = foreign->n_fields;
|
||||
|
||||
for (i = 0; i < foreign->n_fields; i++) {
|
||||
(update->fields + i)->field_no
|
||||
= dict_table_get_nth_col_pos(table,
|
||||
dict_index_get_nth_col_no(index, i));
|
||||
(update->fields + i)->exp = NULL;
|
||||
(update->fields + i)->new_val.len = UNIV_SQL_NULL;
|
||||
(update->fields + i)->new_val.data = NULL;
|
||||
(update->fields + i)->extern_storage = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store pcur position and initialize or store the cascade node
|
||||
pcur stored position */
|
||||
|
||||
btr_pcur_store_position(pcur, mtr);
|
||||
|
||||
if (index == clust_index) {
|
||||
btr_pcur_copy_stored_position(cascade->pcur, pcur);
|
||||
} else {
|
||||
btr_pcur_store_position(cascade->pcur, mtr);
|
||||
}
|
||||
|
||||
mtr_commit(mtr);
|
||||
|
||||
ut_a(cascade->pcur->rel_pos == BTR_PCUR_ON);
|
||||
|
||||
cascade->state = UPD_NODE_UPDATE_CLUSTERED;
|
||||
|
||||
err = row_update_cascade_for_mysql(thr, cascade,
|
||||
foreign->foreign_table);
|
||||
mtr_start(mtr);
|
||||
|
||||
/* Restore pcur position */
|
||||
|
||||
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
|
||||
|
||||
return(err);
|
||||
|
||||
nonstandard_exit_func:
|
||||
|
||||
btr_pcur_store_position(pcur, mtr);
|
||||
|
||||
mtr_commit(mtr);
|
||||
mtr_start(mtr);
|
||||
|
||||
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Sets a shared lock on a record. Used in locking possible duplicate key
|
||||
records. */
|
||||
|
@ -416,6 +633,13 @@ row_ins_check_foreign_constraint(
|
|||
|
||||
ut_ad(rw_lock_own(&dict_foreign_key_check_lock, RW_LOCK_SHARED));
|
||||
|
||||
if (thr_get_trx(thr)->check_foreigns == FALSE) {
|
||||
/* The user has suppressed foreign key checks currently for
|
||||
this session */
|
||||
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/* If any of the foreign key fields in entry is SQL NULL, we
|
||||
suppress the foreign key check: this is compatible with Oracle,
|
||||
for example */
|
||||
|
@ -478,8 +702,8 @@ row_ins_check_foreign_constraint(
|
|||
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
/* Try to place a lock on the index record */
|
||||
|
||||
/* Try to place a lock on the index record */
|
||||
|
||||
err = row_ins_set_shared_rec_lock(rec, check_index, thr);
|
||||
|
||||
|
@ -501,11 +725,21 @@ row_ins_check_foreign_constraint(
|
|||
|
||||
if (check_ref) {
|
||||
err = DB_SUCCESS;
|
||||
|
||||
break;
|
||||
} else if (foreign->type != 0) {
|
||||
err =
|
||||
row_ins_foreign_delete_or_set_null(
|
||||
thr, foreign, &pcur, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
err = DB_ROW_IS_REFERENCED;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,6 +768,8 @@ next_rec:
|
|||
}
|
||||
}
|
||||
|
||||
btr_pcur_close(&pcur);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
/* Restore old value */
|
||||
|
@ -561,6 +797,10 @@ row_ins_check_foreign_constraints(
|
|||
{
|
||||
dict_foreign_t* foreign;
|
||||
ulint err;
|
||||
trx_t* trx;
|
||||
ibool got_s_lock = FALSE;
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
|
||||
|
@ -569,16 +809,26 @@ row_ins_check_foreign_constraints(
|
|||
|
||||
if (foreign->referenced_table == NULL) {
|
||||
dict_table_get(foreign->referenced_table_name,
|
||||
thr_get_trx(thr));
|
||||
trx);
|
||||
}
|
||||
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
if (!trx->has_dict_foreign_key_check_lock) {
|
||||
got_s_lock = TRUE;
|
||||
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
|
||||
trx->has_dict_foreign_key_check_lock = TRUE;
|
||||
}
|
||||
|
||||
err = row_ins_check_foreign_constraint(TRUE, foreign,
|
||||
table, index, entry, thr);
|
||||
if (got_s_lock) {
|
||||
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
|
||||
trx->has_dict_foreign_key_check_lock = FALSE;
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
@ -868,13 +1118,14 @@ row_ins_index_entry_low(
|
|||
ulint n_ext_vec,/* in: number of fields in ext_vec */
|
||||
que_thr_t* thr) /* in: query thread */
|
||||
{
|
||||
btr_cur_t cursor;
|
||||
btr_cur_t cursor;
|
||||
ulint ignore_sec_unique = 0;
|
||||
ulint modify = 0; /* remove warning */
|
||||
rec_t* insert_rec;
|
||||
rec_t* rec;
|
||||
ulint err;
|
||||
ulint n_unique;
|
||||
big_rec_t* big_rec = NULL;
|
||||
big_rec_t* big_rec = NULL;
|
||||
mtr_t mtr;
|
||||
|
||||
log_free_check();
|
||||
|
@ -887,8 +1138,13 @@ row_ins_index_entry_low(
|
|||
the function will return in both low_match and up_match of the
|
||||
cursor sensible values */
|
||||
|
||||
if (!(thr_get_trx(thr)->check_unique_secondary)) {
|
||||
ignore_sec_unique = BTR_IGNORE_SEC_UNIQUE;
|
||||
}
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
|
||||
mode | BTR_INSERT, &cursor, 0, &mtr);
|
||||
mode | BTR_INSERT | ignore_sec_unique,
|
||||
&cursor, 0, &mtr);
|
||||
|
||||
if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
|
||||
/* The insertion was made to the insert buffer already during
|
||||
|
|
|
@ -499,29 +499,24 @@ UNIV_INLINE
|
|||
void
|
||||
row_update_statistics_if_needed(
|
||||
/*============================*/
|
||||
row_prebuilt_t* prebuilt) /* in: prebuilt struct */
|
||||
dict_table_t* table) /* in: table */
|
||||
{
|
||||
ulint counter;
|
||||
|
||||
counter = prebuilt->table->stat_modified_counter;
|
||||
counter = table->stat_modified_counter;
|
||||
|
||||
/* Since the physical size of an InnoDB row is bigger than the
|
||||
MySQL row len, we put a safety factor 2 below */
|
||||
|
||||
counter += 2 * prebuilt->mysql_row_len;
|
||||
|
||||
prebuilt->table->stat_modified_counter = counter;
|
||||
table->stat_modified_counter = counter + 1;
|
||||
|
||||
/* Calculate new statistics if 1 / 16 of table has been modified
|
||||
since the last time a statistics batch was run, or if
|
||||
stat_modified_counter > 2 000 000 000 (to avoid wrap-around) */
|
||||
stat_modified_counter > 2 000 000 000 (to avoid wrap-around).
|
||||
We calculate statistics at most every 16th round, since we may have
|
||||
a counter table which is very small and updated very often. */
|
||||
|
||||
if (counter > 2000000000
|
||||
|| ((ib_longlong)counter >
|
||||
(UNIV_PAGE_SIZE * prebuilt->table->stat_clustered_index_size)
|
||||
/ 16)) {
|
||||
|| ((ib_longlong)counter > 16 + table->stat_n_rows / 16)) {
|
||||
|
||||
dict_update_statistics(prebuilt->table);
|
||||
dict_update_statistics(table);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,7 +707,7 @@ run_again:
|
|||
prebuilt->table->stat_n_rows--;
|
||||
}
|
||||
|
||||
row_update_statistics_if_needed(prebuilt);
|
||||
row_update_statistics_if_needed(prebuilt->table);
|
||||
trx->op_info = (char *) "";
|
||||
|
||||
return((int) err);
|
||||
|
@ -745,6 +740,43 @@ row_prebuild_sel_graph(
|
|||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Creates an query graph node of 'update' type to be used in the MySQL
|
||||
interface. */
|
||||
|
||||
upd_node_t*
|
||||
row_create_update_node_for_mysql(
|
||||
/*=============================*/
|
||||
/* out, own: update node */
|
||||
dict_table_t* table, /* in: table to update */
|
||||
mem_heap_t* heap) /* in: mem heap from which allocated */
|
||||
{
|
||||
upd_node_t* node;
|
||||
|
||||
node = upd_node_create(heap);
|
||||
|
||||
node->in_mysql_interface = TRUE;
|
||||
node->is_delete = FALSE;
|
||||
node->searched_update = FALSE;
|
||||
node->select_will_do_update = FALSE;
|
||||
node->select = NULL;
|
||||
node->pcur = btr_pcur_create_for_mysql();
|
||||
node->table = table;
|
||||
|
||||
node->update = upd_create(dict_table_get_n_cols(table), heap);
|
||||
|
||||
node->update_n_fields = dict_table_get_n_cols(table);
|
||||
|
||||
UT_LIST_INIT(node->columns);
|
||||
node->has_clust_rec_x_lock = TRUE;
|
||||
node->cmpl_info = 0;
|
||||
|
||||
node->table_sym = NULL;
|
||||
node->col_assign_list = NULL;
|
||||
|
||||
return(node);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Gets pointer to a prebuilt update vector used in updates. If the update
|
||||
graph has not yet been built in the prebuilt struct, then this function
|
||||
|
@ -767,26 +799,9 @@ row_get_prebuilt_update_vector(
|
|||
/* Not called before for this handle: create an update node
|
||||
and query graph to the prebuilt struct */
|
||||
|
||||
node = upd_node_create(prebuilt->heap);
|
||||
|
||||
node = row_create_update_node_for_mysql(table, prebuilt->heap);
|
||||
|
||||
prebuilt->upd_node = node;
|
||||
|
||||
node->in_mysql_interface = TRUE;
|
||||
node->is_delete = FALSE;
|
||||
node->searched_update = FALSE;
|
||||
node->select_will_do_update = FALSE;
|
||||
node->select = NULL;
|
||||
node->pcur = btr_pcur_create_for_mysql();
|
||||
node->table = table;
|
||||
|
||||
node->update = upd_create(dict_table_get_n_cols(table),
|
||||
prebuilt->heap);
|
||||
UT_LIST_INIT(node->columns);
|
||||
node->has_clust_rec_x_lock = TRUE;
|
||||
node->cmpl_info = 0;
|
||||
|
||||
node->table_sym = NULL;
|
||||
node->col_assign_list = NULL;
|
||||
|
||||
prebuilt->upd_graph =
|
||||
que_node_get_parent(
|
||||
|
@ -914,7 +929,7 @@ run_again:
|
|||
|
||||
que_thr_stop_for_mysql_no_error(thr, trx);
|
||||
|
||||
if (prebuilt->upd_node->is_delete) {
|
||||
if (node->is_delete) {
|
||||
if (prebuilt->table->stat_n_rows > 0) {
|
||||
prebuilt->table->stat_n_rows--;
|
||||
}
|
||||
|
@ -924,13 +939,66 @@ run_again:
|
|||
srv_n_rows_updated++;
|
||||
}
|
||||
|
||||
row_update_statistics_if_needed(prebuilt);
|
||||
row_update_statistics_if_needed(prebuilt->table);
|
||||
|
||||
trx->op_info = (char *) "";
|
||||
|
||||
return((int) err);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Does a cascaded delete or set null in a foreign key operation. */
|
||||
|
||||
ulint
|
||||
row_update_cascade_for_mysql(
|
||||
/*=========================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
que_thr_t* thr, /* in: query thread */
|
||||
upd_node_t* node, /* in: update node used in the cascade
|
||||
or set null operation */
|
||||
dict_table_t* table) /* in: table where we do the operation */
|
||||
{
|
||||
ulint err;
|
||||
trx_t* trx;
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
run_again:
|
||||
thr->run_node = node;
|
||||
thr->prev_node = node;
|
||||
|
||||
row_upd_step(thr);
|
||||
|
||||
err = trx->error_state;
|
||||
|
||||
if (err == DB_LOCK_WAIT) {
|
||||
que_thr_stop_for_mysql(thr);
|
||||
|
||||
row_mysql_handle_errors(&err, trx, thr, NULL);
|
||||
|
||||
goto run_again;
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
if (node->is_delete) {
|
||||
if (table->stat_n_rows > 0) {
|
||||
table->stat_n_rows--;
|
||||
}
|
||||
|
||||
srv_n_rows_deleted++;
|
||||
} else {
|
||||
srv_n_rows_updated++;
|
||||
}
|
||||
|
||||
row_update_statistics_if_needed(table);
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Checks if a table is such that we automatically created a clustered
|
||||
index on it (on row id). */
|
||||
|
@ -1171,6 +1239,7 @@ row_create_table_for_mysql(
|
|||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
heap = mem_heap_create(512);
|
||||
|
@ -1223,6 +1292,8 @@ row_create_table_for_mysql(
|
|||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
|
||||
que_graph_free((que_t*) que_node_get_parent(thr));
|
||||
|
||||
trx->op_info = (char *) "";
|
||||
|
@ -1270,6 +1341,7 @@ row_create_index_for_mysql(
|
|||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
heap = mem_heap_create(512);
|
||||
|
@ -1300,6 +1372,7 @@ row_create_index_for_mysql(
|
|||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
|
||||
que_graph_free((que_t*) que_node_get_parent(thr));
|
||||
|
||||
|
@ -1355,6 +1428,7 @@ row_table_add_foreign_constraints(
|
|||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
trx->dict_operation = TRUE;
|
||||
|
@ -1379,6 +1453,7 @@ row_table_add_foreign_constraints(
|
|||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
|
||||
return((int) err);
|
||||
}
|
||||
|
@ -1473,7 +1548,8 @@ loop:
|
|||
goto already_dropped;
|
||||
}
|
||||
|
||||
if (table->n_mysql_handles_opened > 0) {
|
||||
if (table->n_mysql_handles_opened > 0
|
||||
|| table->n_foreign_key_checks_running > 0) {
|
||||
|
||||
return(n_tables + n_tables_dropped);
|
||||
}
|
||||
|
@ -1722,6 +1798,9 @@ row_drop_table_for_mysql(
|
|||
no deadlocks can occur then in these operations */
|
||||
|
||||
if (!has_dict_mutex) {
|
||||
/* Prevent foreign key checks while we are dropping the table */
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
|
@ -1734,9 +1813,6 @@ row_drop_table_for_mysql(
|
|||
|
||||
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
||||
|
||||
/* Prevent foreign key checks while we are dropping the table */
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
|
||||
/* Prevent purge from running while we are dropping the table */
|
||||
rw_lock_s_lock(&(purge_sys->purge_is_running));
|
||||
|
||||
|
@ -1771,6 +1847,22 @@ row_drop_table_for_mysql(
|
|||
goto funct_exit;
|
||||
}
|
||||
|
||||
if (table->n_foreign_key_checks_running > 0) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: You are trying to drop table %s\n"
|
||||
"InnoDB: though there are foreign key check running on it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
table->name);
|
||||
|
||||
row_add_table_to_background_drop_list(table);
|
||||
|
||||
err = DB_SUCCESS;
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* Remove any locks there are on the table or its records */
|
||||
|
||||
lock_reset_all_on_table(table);
|
||||
|
@ -1798,10 +1890,9 @@ row_drop_table_for_mysql(
|
|||
funct_exit:
|
||||
rw_lock_s_unlock(&(purge_sys->purge_is_running));
|
||||
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
|
||||
if (!has_dict_mutex) {
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
}
|
||||
|
||||
que_graph_free(graph);
|
||||
|
@ -1837,6 +1928,7 @@ row_drop_database_for_mysql(
|
|||
|
||||
trx_start_if_not_started(trx);
|
||||
loop:
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
while ((table_name = dict_get_first_table_name_in_db(name))) {
|
||||
|
@ -1878,6 +1970,7 @@ loop:
|
|||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
|
@ -2014,6 +2107,7 @@ row_rename_table_for_mysql(
|
|||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
table = dict_table_get_low(old_name);
|
||||
|
@ -2095,6 +2189,7 @@ row_rename_table_for_mysql(
|
|||
}
|
||||
funct_exit:
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
||||
|
||||
que_graph_free(graph);
|
||||
|
||||
|
|
|
@ -2116,8 +2116,14 @@ row_sel_store_mysql_rec(
|
|||
extern_field_heap = NULL;
|
||||
}
|
||||
} else {
|
||||
mysql_rec[templ->mysql_null_byte_offset] |=
|
||||
if (!templ->mysql_null_bit_mask) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to return an SQL NULL field in a non-null\n"
|
||||
"innoDB: column! Table name %s\n", prebuilt->table->name);
|
||||
} else {
|
||||
mysql_rec[templ->mysql_null_byte_offset] |=
|
||||
(byte) (templ->mysql_null_bit_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,8 +73,7 @@ steps of query graph execution. */
|
|||
|
||||
/*************************************************************************
|
||||
Checks if index currently is mentioned as a referenced index in a foreign
|
||||
key constraint. This function also loads into the dictionary cache the
|
||||
possible referencing table. */
|
||||
key constraint. */
|
||||
static
|
||||
ibool
|
||||
row_upd_index_is_referenced(
|
||||
|
@ -85,44 +84,28 @@ row_upd_index_is_referenced(
|
|||
the referencing table has been dropped when
|
||||
we leave this function: this function is only
|
||||
for heuristic use! */
|
||||
dict_index_t* index) /* in: index */
|
||||
dict_index_t* index, /* in: index */
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
dict_table_t* table = index->table;
|
||||
dict_table_t* table = index->table;
|
||||
dict_foreign_t* foreign;
|
||||
ulint phase = 1;
|
||||
|
||||
try_again:
|
||||
if (!UT_LIST_GET_FIRST(table->referenced_list)) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (phase == 2) {
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
if (!trx->has_dict_foreign_key_check_lock) {
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
}
|
||||
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
|
||||
while (foreign) {
|
||||
if (foreign->referenced_index == index) {
|
||||
if (foreign->foreign_table == NULL) {
|
||||
if (phase == 2) {
|
||||
dict_table_get_low(foreign->
|
||||
foreign_table_name);
|
||||
} else {
|
||||
phase = 2;
|
||||
rw_lock_s_unlock(
|
||||
&dict_foreign_key_check_lock);
|
||||
goto try_again;
|
||||
}
|
||||
}
|
||||
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
|
||||
if (phase == 2) {
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
if (!trx->has_dict_foreign_key_check_lock) {
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
@ -131,10 +114,8 @@ try_again:
|
|||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
||||
}
|
||||
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
|
||||
if (phase == 2) {
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
if (!trx->has_dict_foreign_key_check_lock) {
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
|
@ -160,8 +141,17 @@ row_upd_check_references_constraints(
|
|||
dict_foreign_t* foreign;
|
||||
mem_heap_t* heap;
|
||||
dtuple_t* entry;
|
||||
trx_t* trx;
|
||||
rec_t* rec;
|
||||
ulint err;
|
||||
ibool got_s_lock = FALSE;
|
||||
|
||||
if (UT_LIST_GET_FIRST(table->referenced_list) == NULL) {
|
||||
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
|
@ -173,17 +163,61 @@ row_upd_check_references_constraints(
|
|||
|
||||
mtr_start(mtr);
|
||||
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
if (!trx->has_dict_foreign_key_check_lock) {
|
||||
got_s_lock = TRUE;
|
||||
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
|
||||
trx->has_dict_foreign_key_check_lock = TRUE;
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
|
||||
while (foreign) {
|
||||
if (foreign->referenced_index == index) {
|
||||
if (foreign->foreign_table == NULL) {
|
||||
dict_table_get(foreign->foreign_table_name,
|
||||
trx);
|
||||
}
|
||||
|
||||
if (foreign->foreign_table) {
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
(foreign->foreign_table
|
||||
->n_foreign_key_checks_running)++;
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
/* NOTE that if the thread ends up waiting for a lock
|
||||
we will release dict_foreign_key_check_lock
|
||||
temporarily! But the counter on the table
|
||||
protects 'foreign' from being dropped while the check
|
||||
is running. */
|
||||
|
||||
err = row_ins_check_foreign_constraint(FALSE, foreign,
|
||||
table, index, entry, thr);
|
||||
|
||||
if (foreign->foreign_table) {
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
ut_a(foreign->foreign_table
|
||||
->n_foreign_key_checks_running > 0);
|
||||
|
||||
(foreign->foreign_table
|
||||
->n_foreign_key_checks_running)--;
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
if (got_s_lock) {
|
||||
rw_lock_s_unlock(
|
||||
&dict_foreign_key_check_lock);
|
||||
trx->has_dict_foreign_key_check_lock
|
||||
= FALSE;
|
||||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(err);
|
||||
|
@ -193,7 +227,11 @@ row_upd_check_references_constraints(
|
|||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
||||
}
|
||||
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
if (got_s_lock) {
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
trx->has_dict_foreign_key_check_lock = FALSE;
|
||||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
|
@ -222,6 +260,9 @@ upd_node_create(
|
|||
node->index = NULL;
|
||||
node->update = NULL;
|
||||
|
||||
node->cascade_heap = NULL;
|
||||
node->cascade_node = NULL;
|
||||
|
||||
node->select = NULL;
|
||||
|
||||
node->heap = mem_heap_create(128);
|
||||
|
@ -1027,7 +1068,7 @@ row_upd_sec_index_entry(
|
|||
|
||||
index = node->index;
|
||||
|
||||
check_ref = row_upd_index_is_referenced(index);
|
||||
check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr));
|
||||
|
||||
heap = mem_heap_create(1024);
|
||||
|
||||
|
@ -1391,7 +1432,7 @@ row_upd_clust_step(
|
|||
|
||||
index = dict_table_get_first_index(node->table);
|
||||
|
||||
check_ref = row_upd_index_is_referenced(index);
|
||||
check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr));
|
||||
|
||||
pcur = node->pcur;
|
||||
|
||||
|
|
|
@ -2026,15 +2026,18 @@ srv_suspend_mysql_thread(
|
|||
/*=====================*/
|
||||
/* out: TRUE if the lock wait timeout was
|
||||
exceeded */
|
||||
que_thr_t* thr) /* in: query thread associated with
|
||||
the MySQL OS thread */
|
||||
que_thr_t* thr) /* in: query thread associated with the MySQL
|
||||
OS thread */
|
||||
{
|
||||
srv_slot_t* slot;
|
||||
os_event_t event;
|
||||
double wait_time;
|
||||
|
||||
trx_t* trx;
|
||||
|
||||
ut_ad(!mutex_own(&kernel_mutex));
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
os_event_set(srv_lock_timeout_thread_event);
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
@ -2070,10 +2073,21 @@ srv_suspend_mysql_thread(
|
|||
|
||||
srv_conc_force_exit_innodb(thr_get_trx(thr));
|
||||
|
||||
/* Release possible foreign key check latch */
|
||||
if (trx->has_dict_foreign_key_check_lock) {
|
||||
|
||||
rw_lock_s_unlock(&dict_foreign_key_check_lock);
|
||||
}
|
||||
|
||||
/* Wait for the release */
|
||||
|
||||
os_event_wait(event);
|
||||
|
||||
if (trx->has_dict_foreign_key_check_lock) {
|
||||
|
||||
rw_lock_s_lock(&dict_foreign_key_check_lock);
|
||||
}
|
||||
|
||||
/* Return back inside InnoDB */
|
||||
|
||||
srv_conc_force_enter_innodb(thr_get_trx(thr));
|
||||
|
|
|
@ -220,7 +220,7 @@ mutex_create_func(
|
|||
char* cfile_name, /* in: file name where created */
|
||||
ulint cline) /* in: file line where created */
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
mutex_reset_lock_word(mutex);
|
||||
#else
|
||||
os_fast_mutex_init(&(mutex->os_fast_mutex));
|
||||
|
@ -273,7 +273,7 @@ mutex_free(
|
|||
|
||||
mutex_exit(&mutex_list_mutex);
|
||||
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
os_fast_mutex_free(&(mutex->os_fast_mutex));
|
||||
#endif
|
||||
/* If we free the mutex protecting the mutex list (freeing is
|
||||
|
@ -1009,7 +1009,7 @@ sync_thread_add_level(
|
|||
} else if (level == SYNC_ANY_LATCH) {
|
||||
ut_a(sync_thread_levels_g(array, SYNC_ANY_LATCH));
|
||||
} else if (level == SYNC_TRX_SYS_HEADER) {
|
||||
ut_a(sync_thread_levels_contain(array, SYNC_KERNEL));
|
||||
ut_a(sync_thread_levels_g(array, SYNC_TRX_SYS_HEADER));
|
||||
} else if (level == SYNC_DOUBLEWRITE) {
|
||||
ut_a(sync_thread_levels_g(array, SYNC_DOUBLEWRITE));
|
||||
} else if (level == SYNC_BUF_BLOCK) {
|
||||
|
|
|
@ -438,7 +438,6 @@ trx_sys_update_mysql_binlog_offset(
|
|||
trx_sysf_t* sys_header;
|
||||
char namebuf[TRX_SYS_MYSQL_LOG_NAME_LEN];
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad(trx->mysql_log_file_name);
|
||||
|
||||
memset(namebuf, ' ', TRX_SYS_MYSQL_LOG_NAME_LEN - 1);
|
||||
|
@ -524,7 +523,7 @@ trx_sys_print_mysql_binlog_offset(void)
|
|||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Last MySQL binlog file offset %lu %lu, file name %s\n",
|
||||
"InnoDB: Last MySQL binlog file position %lu %lu, file name %s\n",
|
||||
mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
|
||||
+ TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
|
||||
mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
|
||||
|
|
|
@ -71,6 +71,9 @@ trx_create(
|
|||
trx->type = TRX_USER;
|
||||
trx->conc_state = TRX_NOT_STARTED;
|
||||
|
||||
trx->check_foreigns = TRUE;
|
||||
trx->check_unique_secondary = TRUE;
|
||||
|
||||
trx->dict_operation = FALSE;
|
||||
|
||||
trx->mysql_thd = NULL;
|
||||
|
@ -113,6 +116,7 @@ trx_create(
|
|||
trx->lock_heap = mem_heap_create_in_buffer(256);
|
||||
UT_LIST_INIT(trx->trx_locks);
|
||||
|
||||
trx->has_dict_foreign_key_check_lock = FALSE;
|
||||
trx->has_search_latch = FALSE;
|
||||
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
|
||||
|
||||
|
@ -703,8 +707,7 @@ trx_commit_off_kernel(
|
|||
|
||||
/*-------------------------------------*/
|
||||
|
||||
/* Only in some performance tests the variable srv_flush..
|
||||
will be set to FALSE: */
|
||||
/* Most MySQL users run with srv_flush.. set to FALSE: */
|
||||
|
||||
if (srv_flush_log_at_trx_commit) {
|
||||
|
||||
|
|
|
@ -240,7 +240,6 @@ static struct option long_options[] =
|
|||
{"force", no_argument, 0, 'f'},
|
||||
{"join", required_argument, 0, 'j'},
|
||||
{"help", no_argument, 0, '?'},
|
||||
{"packlength",required_argument, 0, 'p'},
|
||||
{"silent", no_argument, 0, 's'},
|
||||
{"tmpdir", required_argument, 0, 'T'},
|
||||
{"test", no_argument, 0, 't'},
|
||||
|
@ -252,7 +251,7 @@ static struct option long_options[] =
|
|||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("%s Ver 1.12 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
|
||||
printf("%s Ver 1.13 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
|
|
35
mysql-test/r/func_if.result
Normal file
35
mysql-test/r/func_if.result
Normal file
|
@ -0,0 +1,35 @@
|
|||
IF(0,"ERROR","this") IF(1,"is","ERROR") IF(NULL,"ERROR","a") IF(1,2,3)|0 IF(1,2.0,3.0)+0
|
||||
this is a 2 2.0
|
||||
s
|
||||
a
|
||||
A
|
||||
a
|
||||
aa
|
||||
AA
|
||||
aaa
|
||||
BBB
|
||||
s
|
||||
a
|
||||
A
|
||||
a
|
||||
aa
|
||||
AA
|
||||
aaa
|
||||
BBB
|
||||
s
|
||||
A
|
||||
AA
|
||||
BBB
|
||||
a
|
||||
a
|
||||
aa
|
||||
aaa
|
||||
s
|
||||
A
|
||||
AA
|
||||
a
|
||||
a
|
||||
aa
|
||||
aaa
|
||||
sum(if(num is null,0.00,num))
|
||||
nan
|
|
@ -1,6 +0,0 @@
|
|||
select last_insert_id(345);
|
||||
last_insert_id(345)
|
||||
345
|
||||
select @@IDENTITY,last_insert_id();
|
||||
@@IDENTITY last_insert_id()
|
||||
345 345
|
30
mysql-test/t/func_if.test
Normal file
30
mysql-test/t/func_if.test
Normal file
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Init section
|
||||
#
|
||||
drop table if exists t1;
|
||||
|
||||
#
|
||||
# Simple IF tests
|
||||
#
|
||||
|
||||
select IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0 ;
|
||||
|
||||
#
|
||||
# Test of IF and case-sensitiveness
|
||||
#
|
||||
CREATE TABLE t1 (st varchar(255) NOT NULL, u int(11) NOT NULL) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('a',1),('A',1),('aa',1),('AA',1),('a',1),('aaa',0),('BBB',0);
|
||||
select if(1,st,st) s from t1 order by s;
|
||||
select if(u=1,st,st) s from t1 order by s;
|
||||
select if(u=1,binary st,st) s from t1 order by s;
|
||||
select if(u=1,st,binary st) s from t1 where st like "%a%" order by s;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Problem with IF()
|
||||
#
|
||||
|
||||
create table t1 (num double(12,2));
|
||||
insert into t1 values (144.54);
|
||||
select sum(if(num is null,0.00,num)) from t1;
|
||||
drop table t1;
|
|
@ -11,7 +11,6 @@ select 'abc' like '%c','abcabc' like '%c', "ab" like "", "ab" like "a", "ab" li
|
|||
select "Det här är svenska" regexp "h[[:alpha:]]+r", "aba" regexp "^(a|b)*$";
|
||||
select "aba" regexp concat("^","a");
|
||||
select !0,NOT 0=1,!(0=0),1 AND 1,1 && 0,0 OR 1,1 || NULL, 1=1 or 1=1 and 1=0;
|
||||
select IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0 ;
|
||||
select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between "max" and "my" and 3=3;
|
||||
select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
|
||||
select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
|
||||
|
@ -24,13 +23,3 @@ select -1.49 or -1.49,0.6 or 0.6;
|
|||
select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
|
||||
select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
|
||||
select 1 and 0 or 2, 2 or 1 and 0;
|
||||
|
||||
#
|
||||
# Problem with IF()
|
||||
#
|
||||
|
||||
drop table if exists t1;
|
||||
create table t1 (num double(12,2));
|
||||
insert into t1 values (144.54);
|
||||
select sum(if(num is null,0.00,num)) from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
select last_insert_id(345);
|
||||
select @@IDENTITY,last_insert_id();
|
|
@ -20,6 +20,7 @@ drop table t1;
|
|||
|
||||
#show variables;
|
||||
show variables like "wait_timeout%";
|
||||
show variables like "WAIT_timeout%";
|
||||
show variables like "this_doesn't_exists%";
|
||||
show table status from test like "this_doesn't_exists%";
|
||||
show databases;
|
||||
|
|
|
@ -27,3 +27,14 @@ SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666;
|
|||
ALTER TABLE t1 DROP PRIMARY KEY;
|
||||
select * from t1 where c_id=@min_cid OR c_id=@max_cid;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test system variables
|
||||
#
|
||||
|
||||
select @@VERSION=version();
|
||||
select last_insert_id(345);
|
||||
select @@IDENTITY,last_insert_id();
|
||||
select @@identity;
|
||||
--error 1193
|
||||
select @@unknown_variable;
|
||||
|
|
|
@ -410,9 +410,23 @@ int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr)
|
|||
|
||||
#endif
|
||||
|
||||
/* Change functions on HP to work according to POSIX */
|
||||
|
||||
#ifdef HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT
|
||||
#undef pthread_cond_timedwait
|
||||
|
||||
int my_pthread_cond_timedwait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
struct timespec *abstime)
|
||||
{
|
||||
int error=pthread_cond_timedwait(cond,mutex,abstime);
|
||||
return error == EAGAIN ? ETIMEDOUT : error;
|
||||
}
|
||||
#endif /* HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT */
|
||||
|
||||
/*
|
||||
** Emulate SOLARIS style calls, not because it's better, but just to make the
|
||||
** usage of getbostbyname_r simpler.
|
||||
Emulate SOLARIS style calls, not because it's better, but just to make the
|
||||
usage of getbostbyname_r simpler.
|
||||
*/
|
||||
|
||||
#if !defined(my_gethostbyname_r) && defined(HAVE_GETHOSTBYNAME_R)
|
||||
|
|
|
@ -490,8 +490,12 @@ Item_func_if::fix_length_and_dec()
|
|||
decimals=max(args[1]->decimals,args[2]->decimals);
|
||||
enum Item_result arg1_type=args[1]->result_type();
|
||||
enum Item_result arg2_type=args[2]->result_type();
|
||||
binary=1;
|
||||
if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
|
||||
{
|
||||
cached_result_type = STRING_RESULT;
|
||||
binary=args[1]->binary | args[2]->binary;
|
||||
}
|
||||
else if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
|
||||
cached_result_type = REAL_RESULT;
|
||||
else
|
||||
|
|
|
@ -59,7 +59,7 @@ bool
|
|||
Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
|
||||
{
|
||||
Item **arg,**arg_end;
|
||||
char buff[sizeof(double)]; // Max argument in function
|
||||
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||
binary=0;
|
||||
used_tables_cache=0;
|
||||
const_item_cache=1;
|
||||
|
@ -1087,7 +1087,7 @@ bool
|
|||
udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
|
||||
uint arg_count, Item **arguments)
|
||||
{
|
||||
char buff[sizeof(double)]; // Max argument in function
|
||||
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||
DBUG_ENTER("Item_udf_func::fix_fields");
|
||||
|
||||
if (thd)
|
||||
|
@ -1607,7 +1607,7 @@ longlong Item_func_get_lock::val_int()
|
|||
set_timespec(abstime,timeout);
|
||||
while (!thd->killed &&
|
||||
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
|
||||
!= ETIME && error != ETIMEDOUT && ull->locked) ;
|
||||
!= ETIME && error != ETIMEDOUT && error != EINVAL && ull->locked) ;
|
||||
if (thd->killed)
|
||||
error=EINTR; // Return NULL
|
||||
if (ull->locked)
|
||||
|
@ -2248,9 +2248,12 @@ double Item_func_match::val()
|
|||
|
||||
Item *get_system_var(LEX_STRING name)
|
||||
{
|
||||
if (!strcmp(name.str,"IDENTITY"))
|
||||
if (!my_strcasecmp(name.str,"IDENTITY"))
|
||||
return new Item_int((char*) "@@IDENTITY",
|
||||
current_thd->insert_id(),21);
|
||||
my_error(ER_UNKNOWN_SYSTEM_VARIABLE,MYF(0),name);
|
||||
if (!my_strcasecmp(name.str,"VERSION"))
|
||||
return new Item_string("@@VERSION",server_version,
|
||||
(uint) strlen(server_version));
|
||||
net_printf(¤t_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -75,22 +75,30 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
|
|||
#define MAX_FIELDS_BEFORE_HASH 32
|
||||
#define USER_VARS_HASH_SIZE 16
|
||||
#define STACK_MIN_SIZE 8192 // Abort if less stack during eval.
|
||||
#define STACK_BUFF_ALLOC 32 // For stack overrun checks
|
||||
#ifndef MYSQLD_NET_RETRY_COUNT
|
||||
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
|
||||
#endif
|
||||
#define TEMP_POOL_SIZE 128
|
||||
/* The following parameters is to decide when to use an extra cache to
|
||||
optimise seeks when reading a big table in sorted order */
|
||||
/*
|
||||
The following parameters is to decide when to use an extra cache to
|
||||
optimise seeks when reading a big table in sorted order
|
||||
*/
|
||||
#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024)
|
||||
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
|
||||
|
||||
// The following is used to decide if MySQL should use table scanning
|
||||
// instead of reading with keys. The number says how many evaluation of the
|
||||
// WHERE clause is comparable to reading one extra row from a table.
|
||||
/*
|
||||
The following is used to decide if MySQL should use table scanning
|
||||
instead of reading with keys. The number says how many evaluation of the
|
||||
WHERE clause is comparable to reading one extra row from a table.
|
||||
*/
|
||||
#define TIME_FOR_COMPARE 5 // 5 compares == one read
|
||||
// Number of rows in a reference table when refereed through a not unique key.
|
||||
// This value is only used when we don't know anything about the key
|
||||
// distribution.
|
||||
|
||||
/*
|
||||
Number of rows in a reference table when refereed through a not unique key.
|
||||
This value is only used when we don't know anything about the key
|
||||
distribution.
|
||||
*/
|
||||
#define MATCHING_ROWS_IN_OTHER_TABLE 10
|
||||
|
||||
/* Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used) */
|
||||
|
|
|
@ -101,6 +101,16 @@ extern "C" { // Because of SCO 3.2V4.2
|
|||
#endif /* NEED_SYS_SYSLOG_H */
|
||||
int allow_severity = LOG_INFO;
|
||||
int deny_severity = LOG_WARNING;
|
||||
|
||||
#ifdef __linux__
|
||||
#define my_fromhost(A) fromhost()
|
||||
#define my_hosts_access(A) hosts_access()
|
||||
#define my_eval_client(A) eval_client()
|
||||
#else
|
||||
#define my_fromhost(A) fromhost(A)
|
||||
#define my_hosts_access(A) hosts_access(A)
|
||||
#define my_eval_client(A) eval_client(A)
|
||||
#endif
|
||||
#endif /* HAVE_LIBWRAP */
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
|
@ -984,24 +994,22 @@ static void server_init(void)
|
|||
IPaddr.sin_addr.s_addr = my_bind_addr;
|
||||
IPaddr.sin_port = (unsigned short) htons((unsigned short) mysql_port);
|
||||
(void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
|
||||
for(;;)
|
||||
if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
|
||||
sizeof(IPaddr)) < 0)
|
||||
{
|
||||
if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
|
||||
sizeof(IPaddr)) >= 0)
|
||||
break;
|
||||
DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
|
||||
sql_perror("Can't start server: Bind on TCP/IP port");/* Had a loop here */
|
||||
sql_perror("Can't start server: Bind on TCP/IP port");
|
||||
sql_print_error("Do you already have another mysqld server running on port: %d ?",mysql_port);
|
||||
unireg_abort(1);
|
||||
}
|
||||
if (listen(ip_sock,(int) back_log) < 0)
|
||||
{
|
||||
sql_perror("Can't start server: listen() on TCP/IP port");
|
||||
sql_print_error("Error: listen() on TCP/IP failed with error %d",
|
||||
socket_errno);
|
||||
unireg_abort(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (mysqld_chroot)
|
||||
set_root(mysqld_chroot);
|
||||
set_user(mysqld_user); // Works also with mysqld_user==NULL
|
||||
|
@ -2332,7 +2340,6 @@ static void create_new_thread(THD *thd)
|
|||
if (cached_thread_count > wake_thread)
|
||||
{
|
||||
start_cached_thread(thd);
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2359,9 +2366,9 @@ static void create_new_thread(THD *thd)
|
|||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
}
|
||||
DBUG_PRINT("info",("Thread created"));
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -2505,24 +2512,16 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
|
|||
struct request_info req;
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
|
||||
#ifndef __linux__
|
||||
fromhost(&req);
|
||||
if (!hosts_access(&req))
|
||||
my_fromhost(&req);
|
||||
if (!my_hosts_access(&req))
|
||||
{
|
||||
/*
|
||||
This may be stupid but refuse() includes an exit(0)
|
||||
which we surely don't want...
|
||||
clean_exit() - same stupid thing ...
|
||||
*/
|
||||
syslog(deny_severity, "refused connect from %s", eval_client(&req));
|
||||
#else
|
||||
fromhost();
|
||||
if (!hosts_access())
|
||||
{
|
||||
syslog(deny_severity, "refused connect from %s", eval_client());
|
||||
#endif
|
||||
if (req.sink)
|
||||
((void (*)(int))req.sink)(req.fd);
|
||||
syslog(deny_severity, "refused connect from %s",
|
||||
my_eval_client(&req));
|
||||
|
||||
/*
|
||||
C++ sucks (the gibberish in front just translates the supplied
|
||||
|
@ -2530,7 +2529,10 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
|
|||
to a void(*sink)(int) if you omit the cast, the C++ compiler
|
||||
will cry...
|
||||
*/
|
||||
(void) shutdown(new_sock,2); // This looks fine to me...
|
||||
if (req.sink)
|
||||
((void (*)(int))req.sink)(req.fd);
|
||||
|
||||
(void) shutdown(new_sock,2);
|
||||
(void) closesocket(new_sock);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
"S-Bíťová chyba při zápisu na master",
|
||||
"-BŽádný sloupec nemá vytvořen fulltextový index",
|
||||
"Nemohu prov-Bést zadaný příkaz, protože existují aktivní zamčené tabulky nebo aktivní transakce",
|
||||
"Nezn-Bámá systémová proměnná '%-.64'",
|
||||
"Nezn-Bámá systémová proměnná '%-.64s'",
|
||||
"Tabulka '%-.64s' je ozna-Bčena jako porušená a měla by být opravena",
|
||||
"Tabulka '%-.64s' je ozna-Bčena jako porušená a poslední (automatická?) oprava se nezdařila",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
"Netværksfejl ved skrivning til master",
|
||||
"Kan ikke finde en FULLTEXT nøgle som svarer til kolonne listen",
|
||||
"Kan ikke udføre den givne kommando fordi der findes aktive, låste tabeller eller fordi der udføres en transaktion",
|
||||
"Ukendt systemvariabel '%-.64'",
|
||||
"Ukendt systemvariabel '%-.64s'",
|
||||
"Tabellen '%-.64s' er markeret med fejl og bør repareres",
|
||||
"Tabellen '%-.64s' er markeret med fejl og sidste (automatiske?) REPAIR fejlede",
|
||||
"Advarsel: Visse data i tabeller der ikke understøtter transaktioner kunne ikke tilbagestilles",
|
||||
|
|
|
@ -202,7 +202,7 @@
|
|||
"Net fout tijdens schrijven naar master",
|
||||
"Kan geen FULLTEXT index vinden passend bij de kolom lijst",
|
||||
"Kan het gegeven commando niet uitvoeren, want u heeft actieve gelockte tabellen of een actieve transactie",
|
||||
"Onbekende systeem variabele '%-.64'",
|
||||
"Onbekende systeem variabele '%-.64s'",
|
||||
"Tabel '%-.64s' staat als gecrashed gemarkeerd en dient te worden gerepareerd",
|
||||
"Tabel '%-.64s' staat als gecrashed gemarkeerd en de laatste (automatische?) reparatie poging mislukte",
|
||||
"Waarschuwing: Roll back mislukt voor sommige buiten transacties gewijzigde tabellen",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -199,7 +199,7 @@
|
|||
"Net error writing to master",
|
||||
"Ei suutnud leida FULLTEXT indeksit, mis kattuks kasutatud tulpadega",
|
||||
"Ei suuda täita antud käsku kuna on aktiivseid lukke või käimasolev transaktsioon",
|
||||
"Tundmatu süsteemne muutuja '%-.64'",
|
||||
"Tundmatu süsteemne muutuja '%-.64s'",
|
||||
"Tabel '%-.64s' on märgitud vigaseks ja tuleb parandada",
|
||||
"Tabel '%-.64s' on märgitud vigaseks ja viimane (automaatne?) parandus ebaõnnestus",
|
||||
"Hoiatus: mõnesid transaktsioone mittetoetavaid tabeleid ei suudetud tagasi kerida",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
"Netzfehler beim Schreiben zum Master",
|
||||
"Kann keinen FULLTEXT-Index finden der der Spaltenliste entspricht",
|
||||
"Kann das aktuelle Kommando wegen aktiver Tabellensperre oder aktiver Transaktion nicht ausführen",
|
||||
"Unbekannte System-Variabel '%-.64'",
|
||||
"Unbekannte System-Variabel '%-.64s'",
|
||||
"Tabelle '%-.64s' ist als defekt makiert und sollte repariert werden",
|
||||
"Tabelle '%-.64s' ist als defekt makiert und der letzte (automatische) Reparaturversuch schlug fehl.",
|
||||
"Warnung: Das Rollback konnte bei einigen Tabellen, die nicht mittels Transaktionen geändert wurden, nicht ausgeführt werden.",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -196,7 +196,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Errore di rete durante l'invio al master",
|
||||
"Impossibile trovare un indice FULLTEXT che corrisponda all'elenco delle colonne",
|
||||
"Impossibile eseguire il comando richiesto: tabelle sotto lock o transazione in atto",
|
||||
"Variabile di sistema '%-.64' sconosciuta",
|
||||
"Variabile di sistema '%-.64s' sconosciuta",
|
||||
"La tabella '%-.64s' e` segnalata come corrotta e deve essere riparata",
|
||||
"La tabella '%-.64s' e` segnalata come corrotta e l'ultima ricostruzione (automatica?) e` fallita",
|
||||
"Attenzione: Alcune delle modifiche alle tabelle non transazionali non possono essere ripristinate (roll back impossibile)",
|
||||
|
|
|
@ -196,7 +196,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -196,7 +196,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -196,7 +196,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Erro de rede na gravação do 'master'",
|
||||
"Não pode encontrar índice FULLTEXT que combine com a lista de colunas",
|
||||
"Não pode executar o comando dado porque você tem tabelas ativas travadas ou uma 'transaction' ativa",
|
||||
"Variável de sistema '%-.64' desconhecida",
|
||||
"Variável de sistema '%-.64s' desconhecida",
|
||||
"Tabela '%-.64s' está marcada como danificada e deve ser reparada",
|
||||
"Tabela '%-.64s' está marcada como danificada e a última reparação (automática?) falhou",
|
||||
"Aviso: Algumas tabelas não-transacionais alteradas não puderam ser reconstituídas ('rolled back')",
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
"Сетевая ошибка при писании мастеру",
|
||||
"FULLTEXT индекс, соответствующий заданному списку столбцов, не найден",
|
||||
"Не могу выполнить комманду из-за активных locked таблиц или активной транзакции",
|
||||
"Неизвестная системная переменная '%-.64'",
|
||||
"Неизвестная системная переменная '%-.64s'",
|
||||
"Таблица '%-.64s' помечена как испорченная и должна быть исправлена",
|
||||
"Таблица '%-.64s' помечена как испорченная и последняя попытка исправления (автоматическая?) не удалась",
|
||||
"Предупреждение: некоторые нетранзакционные таблицы не подчиняются ROLLBACK",
|
||||
|
|
|
@ -202,7 +202,7 @@
|
|||
"Net error writing to master",
|
||||
"Can't find FULLTEXT index matching the column list",
|
||||
"Can't execute the given command because you have active locked tables or an active transaction",
|
||||
"Unknown system variable '%-.64'",
|
||||
"Unknown system variable '%-.64s'",
|
||||
"Table '%-.64s' is marked as crashed and should be repaired",
|
||||
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
|
||||
"Warning: Some non-transactional changed tables couldn't be rolled back",
|
||||
|
|
|
@ -195,7 +195,7 @@
|
|||
"Error de red escribiendo para el master",
|
||||
"No puedo encontrar índice FULLTEXT correspondiendo a la lista de columnas",
|
||||
"No puedo ejecutar el comando dado porque tienes tablas bloqueadas o una transición activa",
|
||||
"Desconocida variable de sistema '%-.64'",
|
||||
"Desconocida variable de sistema '%-.64s'",
|
||||
"Tabla '%-.64s' está marcada como crashed y debe ser reparada",
|
||||
"Tabla '%-.64s' está marcada como crashed y la última reparación (automactica?) falló",
|
||||
"Aviso: Algunas tablas no transancionales no pueden tener rolled back",
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
"Fick nätverksfel vid skrivning till master",
|
||||
"Hittar inte ett FULLTEXT index i kolumnlistan",
|
||||
"Kan inte exekvera kommandot emedan du har en låst tabell eller an aktiv transaktion",
|
||||
"Okänd system variabel '%-.64'",
|
||||
"Okänd system variabel '%-.64s'",
|
||||
"Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE",
|
||||
"Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades",
|
||||
"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK",
|
||||
|
|
|
@ -199,7 +199,7 @@
|
|||
"Мережева помилка запису до головного",
|
||||
"Не можу знайти FULLTEXT ╕ндекс, що в╕дпов╕да╓ перел╕ку стовбц╕в",
|
||||
"Не можу виконати подану команду тому, що таблиця заблокована або викону╓ться транзакц╕я",
|
||||
"疽屢켓皐 譚戇터适 謐┧适 '%-.64'",
|
||||
"疽屢켓皐 譚戇터适 謐┧适 '%-.64s'",
|
||||
"Таблицю '%-.64s' марковано як з╕псовану та ╖╖ потр╕бно в╕дновити",
|
||||
"Таблицю '%-.64s' марковано як з╕псовану та останн╓ (автоматичне?) в╕дновлення не вдалося",
|
||||
"Застереження: Деяк╕ нетранзакц╕йн╕ зм╕ни таблиць не можна буде повернути",
|
||||
|
|
|
@ -570,21 +570,30 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
|||
{
|
||||
packet->length(0);
|
||||
net_store_data(packet,convert, table->table_name);
|
||||
// a hack - we need to reserve some space for the length before
|
||||
// we know what it is - let's assume that the length of create table
|
||||
// statement will fit into 3 bytes ( 16 MB max :-) )
|
||||
/*
|
||||
A hack - we need to reserve some space for the length before
|
||||
we know what it is - let's assume that the length of create table
|
||||
statement will fit into 3 bytes ( 16 MB max :-) )
|
||||
*/
|
||||
ulong store_len_offset = packet->length();
|
||||
packet->length(store_len_offset + 4);
|
||||
if (store_create_info(thd, table, packet))
|
||||
DBUG_RETURN(-1);
|
||||
ulong create_len = packet->length() - store_len_offset - 4;
|
||||
if (create_len > 0x00ffffff) // better readable in HEX ...
|
||||
DBUG_RETURN(1); // just in case somebody manages to create a table
|
||||
// with *that* much stuff in the definition
|
||||
{
|
||||
/*
|
||||
Just in case somebody manages to create a table
|
||||
with *that* much stuff in the definition
|
||||
*/
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
// now we have to store the length in three bytes, even if it would fit
|
||||
// into fewer, so we cannot use net_store_data() anymore,
|
||||
// and do it ourselves
|
||||
/*
|
||||
Now we have to store the length in three bytes, even if it would fit
|
||||
into fewer bytes, so we cannot use net_store_data() anymore,
|
||||
and do it ourselves
|
||||
*/
|
||||
char* p = (char*)packet->ptr() + store_len_offset;
|
||||
*p++ = (char) 253; // The client the length is stored using 3-bytes
|
||||
int3store(p, create_len);
|
||||
|
@ -1148,7 +1157,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
|
|||
pthread_mutex_lock(&LOCK_status);
|
||||
for (i=0; variables[i].name; i++)
|
||||
{
|
||||
if (!(wild && wild[0] && wild_compare(variables[i].name,wild)))
|
||||
if (!(wild && wild[0] && wild_case_compare(variables[i].name,wild)))
|
||||
{
|
||||
packet2.length(0);
|
||||
net_store_data(&packet2,convert,variables[i].name);
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* File : bfill.c
|
||||
Author : Richard A. O'Keefe.
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* File : bmove.c
|
||||
Author : Richard A. O'Keefe.
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* This file is for Japanese EUC charset, and created by tommy@valley.ne.jp.
|
||||
*/
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* File : strend.c
|
||||
Author : Richard A. O'Keefe.
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* File : strstr.c
|
||||
Author : Monty
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* File : strxmov.c
|
||||
Author : Richard A. O'Keefe.
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
/* Copyright (C) 2002 MySQL AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* File : strxnmov.c
|
||||
Author : Richard A. O'Keefe.
|
||||
|
|
Loading…
Reference in a new issue