Merge from main branch.

This commit is contained in:
Joerg Bruehe 2008-08-15 12:49:31 +02:00
commit 28e884d9e2
47 changed files with 3659 additions and 556 deletions

View file

@ -259,6 +259,10 @@ get_one_option(int optid, const struct my_option *opt,
}
/**
Run a command using the shell, storing its output in the supplied dynamic
string.
*/
static int run_command(char* cmd,
DYNAMIC_STRING *ds_res)
{
@ -331,36 +335,16 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...)
}
/*
Try to get the full path to this exceutable
Return 0 if path found
/**
Look for the filename of given tool, with the presumption that it is in the
same directory as mysql_upgrade and that the same executable-searching
mechanism will be used when we run our sub-shells with popen() later.
*/
static my_bool get_full_path_to_executable(char* path)
static void find_tool(char *tool_executable_name, const char *tool_name,
const char *self_name)
{
my_bool ret;
DBUG_ENTER("get_full_path_to_executable");
#ifdef __WIN__
ret= (GetModuleFileName(NULL, path, FN_REFLEN) == 0);
#else
/* my_readlink returns 0 if a symlink was read */
ret= (my_readlink(path, "/proc/self/exe", MYF(0)) != 0);
/* Might also want to try with /proc/$$/exe if the above fails */
#endif
DBUG_PRINT("exit", ("path: %s", path));
DBUG_RETURN(ret);
}
char *last_fn_libchar;
/*
Look for the tool in the same directory as mysql_upgrade.
*/
static void find_tool(char *tool_path, const char *tool_name)
{
char path[FN_REFLEN];
DYNAMIC_STRING ds_tmp;
DBUG_ENTER("find_tool");
DBUG_PRINT("enter", ("progname: %s", my_progname));
@ -368,77 +352,59 @@ static void find_tool(char *tool_path, const char *tool_name)
if (init_dynamic_string(&ds_tmp, "", 32, 32))
die("Out of memory");
/* Initialize path with the full path to this program */
if (get_full_path_to_executable(path))
last_fn_libchar= strrchr(self_name, FN_LIBCHAR);
if (last_fn_libchar == NULL)
{
/*
Easy way to get full executable path failed, try
other methods
mysql_upgrade was found by the shell searching the path. A sibling
next to us should be found the same way.
*/
if (my_progname[0] == FN_LIBCHAR)
{
/* 1. my_progname contains full path */
strmake(path, my_progname, FN_REFLEN);
}
else if (my_progname[0] == '.')
{
/* 2. my_progname contains relative path, prepend wd */
char buf[FN_REFLEN];
my_getwd(buf, FN_REFLEN, MYF(0));
my_snprintf(path, FN_REFLEN, "%s%s", buf, my_progname);
}
else
{
/* 3. Just go for it and hope tool is in path */
path[0]= 0;
}
strncpy(tool_executable_name, tool_name, FN_REFLEN);
}
DBUG_PRINT("info", ("path: '%s'", path));
/* Chop off binary name (i.e mysql-upgrade) from path */
dirname_part(path, path);
/*
When running in a not yet installed build and using libtool,
the program(mysql_upgrade) will be in .libs/ and executed
through a libtool wrapper in order to use the dynamic libraries
from this build. The same must be done for the tools(mysql and
mysqlcheck). Thus if path ends in .libs/, step up one directory
and execute the tools from there
*/
path[max((strlen(path)-1), 0)]= 0; /* Chop off last / */
if (strncmp(path + dirname_length(path), ".libs", 5) == 0)
else
{
DBUG_PRINT("info", ("Chopping off .libs from '%s'", path));
int len;
/* Chop off .libs */
dirname_part(path, path);
/*
mysql_upgrade was run absolutely or relatively. We can find a sibling
by replacing our name after the LIBCHAR with the new tool name.
*/
/*
When running in a not yet installed build and using libtool,
the program(mysql_upgrade) will be in .libs/ and executed
through a libtool wrapper in order to use the dynamic libraries
from this build. The same must be done for the tools(mysql and
mysqlcheck). Thus if path ends in .libs/, step up one directory
and execute the tools from there
*/
if (((last_fn_libchar - 6) >= self_name) &&
(strncmp(last_fn_libchar - 5, ".libs", 5) == 0) &&
(*(last_fn_libchar - 6) == FN_LIBCHAR))
{
DBUG_PRINT("info", ("Chopping off \".libs\" from end of path"));
last_fn_libchar -= 6;
}
len= last_fn_libchar - self_name;
my_snprintf(tool_executable_name, FN_REFLEN, "%.*s%c%s",
len, self_name, FN_LIBCHAR, tool_name);
}
DBUG_PRINT("info", ("path: '%s'", path));
/* Format name of the tool to search for */
fn_format(tool_path, tool_name,
path, "", MYF(MY_REPLACE_DIR));
verbose("Looking for '%s' in: %s", tool_name, tool_path);
/* Make sure the tool exists */
if (my_access(tool_path, F_OK) != 0)
die("Can't find '%s'", tool_path);
verbose("Looking for '%s' as: %s", tool_name, tool_executable_name);
/*
Make sure it can be executed
*/
if (run_tool(tool_path,
if (run_tool(tool_executable_name,
&ds_tmp, /* Get output from command, discard*/
"--help",
"2>&1",
IF_WIN("> NUL", "> /dev/null"),
NULL))
die("Can't execute '%s'", tool_path);
die("Can't execute '%s'", tool_executable_name);
dynstr_free(&ds_tmp);
@ -748,11 +714,20 @@ static const char *load_default_groups[]=
int main(int argc, char **argv)
{
char self_name[FN_REFLEN];
MY_INIT(argv[0]);
#ifdef __NETWARE__
setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
#endif
#if __WIN__
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
{
strncpy(self_name, argv[0], FN_REFLEN);
}
if (init_dynamic_string(&ds_args, "", 512, 256))
die("Out of memory");
@ -774,10 +749,10 @@ int main(int argc, char **argv)
dynstr_append(&ds_args, " ");
/* Find mysql */
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"));
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);
/* Find mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"));
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
/*
Read the mysql_upgrade_info file to check if mysql_upgrade

View file

@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
AM_INIT_AUTOMAKE(mysql, 5.0.68)
AM_INIT_AUTOMAKE(mysql, 5.0.70)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=68
NDB_VERSION_BUILD=70
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?

View file

@ -2260,6 +2260,7 @@ buf_print(void)
ut_a(buf_validate());
}
#ifdef UNIV_DEBUG
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
@ -2290,6 +2291,7 @@ buf_get_latched_pages_number(void)
mutex_exit(&(buf_pool->mutex));
return fixed_pages_number;
}
#endif /* UNIV_DEBUG */
/*************************************************************************
Returns the number of pending buf pool ios. */

View file

@ -3554,7 +3554,7 @@ loop:
ptr = dict_accept(ptr, "FOREIGN", &success);
if (!success) {
if (!success || !ib_isspace(*ptr)) {
goto loop;
}

View file

@ -495,7 +495,15 @@ Prints info of the buffer pool data structure. */
void
buf_print(void);
/*============*/
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
ulint
buf_get_latched_pages_number(void);
/*==============================*/
#endif /* UNIV_DEBUG */
/************************************************************************
Prints a page to stderr. */
@ -503,12 +511,7 @@ void
buf_page_print(
/*===========*/
byte* read_buf); /* in: a database page */
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
ulint
buf_get_latched_pages_number(void);
/*==============================*/
/*************************************************************************
Returns the number of pending buf pool ios. */

View file

@ -531,7 +531,9 @@ struct export_var_struct{
ulint innodb_buffer_pool_pages_dirty;
ulint innodb_buffer_pool_pages_misc;
ulint innodb_buffer_pool_pages_free;
#ifdef UNIV_DEBUG
ulint innodb_buffer_pool_pages_latched;
#endif /* UNIV_DEBUG */
ulint innodb_buffer_pool_read_requests;
ulint innodb_buffer_pool_reads;
ulint innodb_buffer_pool_wait_free;

View file

@ -237,6 +237,7 @@ trx_undo_set_state_at_finish(
/*=========================*/
/* out: undo log segment header page,
x-latched */
trx_rseg_t* rseg, /* in: rollback segment memory object */
trx_t* trx, /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
mtr_t* mtr); /* in: mtr */

View file

@ -1803,7 +1803,9 @@ srv_export_innodb_status(void)
export_vars.innodb_buffer_pool_pages_data= UT_LIST_GET_LEN(buf_pool->LRU);
export_vars.innodb_buffer_pool_pages_dirty= UT_LIST_GET_LEN(buf_pool->flush_list);
export_vars.innodb_buffer_pool_pages_free= UT_LIST_GET_LEN(buf_pool->free);
#ifdef UNIV_DEBUG
export_vars.innodb_buffer_pool_pages_latched= buf_get_latched_pages_number();
#endif /* UNIV_DEBUG */
export_vars.innodb_buffer_pool_pages_total= buf_pool->curr_size;
export_vars.innodb_buffer_pool_pages_misc= buf_pool->max_size -
UT_LIST_GET_LEN(buf_pool->LRU) - UT_LIST_GET_LEN(buf_pool->free);

View file

@ -761,8 +761,8 @@ trx_commit_off_kernel(
mutex_enter(&(rseg->mutex));
if (trx->insert_undo != NULL) {
trx_undo_set_state_at_finish(trx, trx->insert_undo,
&mtr);
trx_undo_set_state_at_finish(
rseg, trx, trx->insert_undo, &mtr);
}
undo = trx->update_undo;
@ -777,8 +777,8 @@ trx_commit_off_kernel(
because only a single OS thread is allowed to do the
transaction commit for this transaction. */
update_hdr_page = trx_undo_set_state_at_finish(trx,
undo, &mtr);
update_hdr_page = trx_undo_set_state_at_finish(
rseg, trx, undo, &mtr);
/* We have to do the cleanup for the update log while
holding the rseg mutex because update log headers

View file

@ -1724,6 +1724,7 @@ trx_undo_set_state_at_finish(
/*=========================*/
/* out: undo log segment header page,
x-latched */
trx_rseg_t* rseg, /* in: rollback segment memory object */
trx_t* trx __attribute__((unused)), /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
mtr_t* mtr) /* in: mtr */
@ -1732,8 +1733,10 @@ trx_undo_set_state_at_finish(
trx_upagef_t* page_hdr;
page_t* undo_page;
ulint state;
ut_ad(trx && undo && mtr);
ut_ad(trx);
ut_ad(undo);
ut_ad(mtr);
if (undo->id >= TRX_RSEG_N_SLOTS) {
fprintf(stderr, "InnoDB: Error: undo->id is %lu\n",
@ -1747,9 +1750,23 @@ trx_undo_set_state_at_finish(
seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
< TRX_UNDO_PAGE_REUSE_LIMIT) {
state = TRX_UNDO_CACHED;
if (undo->size == 1
&& mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
< TRX_UNDO_PAGE_REUSE_LIMIT) {
/* This is a heuristic to avoid the problem of all UNDO
slots ending up in one of the UNDO lists. Previously if
the server crashed with all the slots in one of the lists,
transactions that required the slots of a different type
would fail for lack of slots. */
if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500
&& UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
state = TRX_UNDO_CACHED;
} else {
state = TRX_UNDO_TO_FREE;
}
} else if (undo->type == TRX_UNDO_INSERT) {
@ -1759,7 +1776,7 @@ trx_undo_set_state_at_finish(
}
undo->state = state;
mlog_write_ulint(seg_hdr + TRX_UNDO_STATE, state, MLOG_2BYTES, mtr);
return(undo_page);

View file

@ -131,3 +131,49 @@ drop table t1;
select if(0, 18446744073709551610, 18446744073709551610);
if(0, 18446744073709551610, 18446744073709551610)
18446744073709551610
CREATE TABLE t1(a DECIMAL(10,3));
SELECT t1.a,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1
FROM t1;
a IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((R
DROP TABLE t1;
End of 5.0 tests

View file

@ -0,0 +1,6 @@
drop table if exists t1;
create table t1(a int not null auto_increment primary key) engine=innodb;
insert into t1 set a = -1;
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK

View file

@ -0,0 +1 @@
SET storage_engine=InnoDB;

View file

@ -1246,4 +1246,19 @@ set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
ENGINE=InnoDB;
INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range t1_b t1_b 5 NULL 4 Using where
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
a b c
8 1 1
7 1 1
6 1 1
5 1 1
4 1 1
DROP TABLE t1;
End of 5.0 tests

File diff suppressed because it is too large Load diff

View file

@ -4396,4 +4396,15 @@ id select_type table type possible_keys key key_len ref rows Extra
Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (<cache>(1) = <ref_null_helper>(1))))
DROP TABLE t1;
CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a));
INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a));
INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
pk a
1 10
3 30
2 20
DROP TABLE t1,t2;
End of 5.0 tests.

View file

@ -108,3 +108,46 @@ drop table t1;
select if(0, 18446744073709551610, 18446744073709551610);
#
# Bug #37662: nested if() inside sum() is parsed in exponential time
#
CREATE TABLE t1(a DECIMAL(10,3));
# check : should be fast. more than few secs means failure.
SELECT t1.a,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,
IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1
FROM t1;
DROP TABLE t1;
--echo End of 5.0 tests

View file

@ -0,0 +1,16 @@
-- source include/have_innodb.inc
# embedded server ignores 'delayed', so skip this
-- source include/not_embedded.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
#
# Bug 34286
#
create table t1(a int not null auto_increment primary key) engine=innodb;
insert into t1 set a = -1;
# NOTE: The database needs to be shutdown and restarted (here) for
# the test to work. It's included for reference only.
optimize table t1;

View file

@ -0,0 +1,16 @@
#
# Bug#35220 ALTER TABLE too picky on reserved word "foreign"
# http://bugs.mysql.com/35220
#
-- source include/have_innodb.inc
SET storage_engine=InnoDB;
# we care only that the following SQL commands do not produce errors
-- disable_query_log
-- disable_result_log
CREATE TABLE bug35220 (foreign_col INT, dummy_cant_delete_all_columns INT);
ALTER TABLE bug35220 DROP foreign_col;
DROP TABLE bug35220;

View file

@ -996,4 +996,22 @@ set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
#
# Bug #37830: ORDER BY ASC/DESC - no difference
#
CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
ENGINE=InnoDB;
INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
# should be range access
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
# should produce '8 7 6 5 4' for a
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
DROP TABLE t1;
--echo End of 5.0 tests

View file

@ -38,3 +38,59 @@ drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t2
SET @@global.query_cache_size=0;
# End of 4.1 tests
#
# Bug#33362: Query cache invalidation (truncate) may hang if cached query uses many tables
#
let $c= 255;
while ($c)
{
eval CREATE TABLE t$c (a INT);
eval INSERT INTO t$c VALUES ($c);
dec $c;
}
let $c= 254;
let $str= t255;
while ($c)
{
let $str= t$c,$str;
dec $c;
}
eval CREATE TABLE t0 (a INT) ENGINE=MERGE UNION($str);
SET GLOBAL query_cache_size = 1048576;
FLUSH STATUS;
SELECT a FROM t0 WHERE a = 1;
SHOW STATUS LIKE "Qcache_queries_in_cache";
let $c= 255;
let $i= 1;
FLUSH TABLES;
while ($c)
{
eval TRUNCATE TABLE t$c;
eval SELECT a FROM t$i;
dec $c;
inc $i;
}
SELECT a FROM t0;
DROP TABLE t0;
let $c= 255;
while ($c)
{
eval DROP TABLE t$c;
dec $c;
}
SET @@global.query_cache_size = 0;
--echo End of 5.1 tests

View file

@ -3295,5 +3295,17 @@ EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
DROP TABLE t1;
#
# Bug #38191: Server crash with subquery containing DISTINCT and ORDER BY
#
CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a));
INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a));
INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
DROP TABLE t1,t2;
--echo End of 5.0 tests.

View file

@ -1382,7 +1382,7 @@ restart:
/* We don't need the page in the cache: we are going to write on disk */
hash_link->requests--;
unlink_hash(keycache, hash_link);
return 0;
DBUG_RETURN(0);
}
if (!(block->status & BLOCK_IN_FLUSH))
{
@ -1399,7 +1399,7 @@ restart:
flag (see the code below that handles reading requests).
*/
free_block(keycache, block);
return 0;
DBUG_RETURN(0);
}
/* Wait intil the page is flushed on disk */
hash_link->requests--;
@ -1429,7 +1429,7 @@ restart:
/* Invalidate page in the block if it has not been done yet */
if (block->status)
free_block(keycache, block);
return 0;
DBUG_RETURN(0);
}
if (page_status == PAGE_READ &&

View file

@ -202,7 +202,7 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
{
if (mem_root->error_handler)
(*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */
DBUG_RETURN((gptr) 0); /* purecov: inspected */
}
mem_root->block_num++;
next->next= *prev;

View file

@ -2,6 +2,7 @@
-- The system tables of MySQL Server
--
set sql_mode='';
set storage_engine=myisam;
CREATE TABLE IF NOT EXISTS db ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges';

View file

@ -48,7 +48,8 @@ class Field
Field(const Item &); /* Prevent use of these */
void operator=(Field &);
public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
static void *operator new(size_t size) throw ()
{ return (void*) sql_alloc((uint) size); }
static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); }
char *ptr; // Position to field in record

View file

@ -244,8 +244,10 @@ struct show_var_st innodb_status_variables[]= {
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
{"buffer_pool_pages_free",
(char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
#ifdef UNIV_DEBUG
{"buffer_pool_pages_latched",
(char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
#endif /* UNIV_DEBUG */
{"buffer_pool_pages_misc",
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
{"buffer_pool_pages_total",
@ -4250,7 +4252,7 @@ ha_innobase::rnd_pos(
int error;
uint keynr = active_index;
DBUG_ENTER("rnd_pos");
DBUG_DUMP("key", (uchar *)pos, ref_length);
DBUG_DUMP("key", (uchar*) pos, ref_length);
statistic_increment(current_thd->status_var.ha_read_rnd_count,
&LOCK_status);
@ -6882,6 +6884,12 @@ ha_innobase::innobase_read_and_init_auto_inc(
from a table when no table has been locked in ::external_lock(). */
prebuilt->trx->n_mysql_tables_in_use++;
/* Since we will perform a MySQL SELECT query to determine the
auto-inc value, set prebuilt->sql_stat_start = TRUE so that it
is performed like any normal SELECT, regardless of the context
we come here. */
prebuilt->sql_stat_start = TRUE;
error = index_last(table->record[1]);
prebuilt->trx->n_mysql_tables_in_use--;

View file

@ -429,8 +429,11 @@ uint Item::decimal_precision() const
Item_result restype= result_type();
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
return min(my_decimal_length_to_precision(max_length, decimals, unsigned_flag),
DECIMAL_MAX_PRECISION);
{
uint prec=
my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
return min(prec, DECIMAL_MAX_PRECISION);
}
return min(max_length, DECIMAL_MAX_PRECISION);
}
@ -6838,8 +6841,9 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
{
decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
int precision= min(max(prev_decimal_int_part, item->decimal_int_part())
+ decimals, DECIMAL_MAX_PRECISION);
int item_int_part= item->decimal_int_part();
int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
int precision= min(item_prec, DECIMAL_MAX_PRECISION);
unsigned_flag&= item->unsigned_flag;
max_length= my_decimal_precision_to_length(precision, decimals,
unsigned_flag);

View file

@ -439,9 +439,9 @@ class Item {
Item(const Item &); /* Prevent use of these */
void operator=(Item &);
public:
static void *operator new(size_t size)
static void *operator new(size_t size) throw ()
{ return (void*) sql_alloc((uint) size); }
static void *operator new(size_t size, MEM_ROOT *mem_root)
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, (uint) size); }
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}

View file

@ -2098,8 +2098,11 @@ Item_func_ifnull::fix_length_and_dec()
uint Item_func_ifnull::decimal_precision() const
{
int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
int arg0_int_part= args[0]->decimal_int_part();
int arg1_int_part= args[1]->decimal_int_part();
int max_int_part= max(arg0_int_part, arg1_int_part);
int precision= max_int_part + decimals;
return min(precision, DECIMAL_MAX_PRECISION);
}
@ -2281,8 +2284,9 @@ Item_func_if::fix_length_and_dec()
uint Item_func_if::decimal_precision() const
{
int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
decimals);
int arg1_prec= args[1]->decimal_int_part();
int arg2_prec= args[2]->decimal_int_part();
int precision=max(arg1_prec,arg2_prec) + decimals;
return min(precision, DECIMAL_MAX_PRECISION);
}

View file

@ -1156,9 +1156,10 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
void Item_func_additive_op::result_precision()
{
decimals= max(args[0]->decimals, args[1]->decimals);
int max_int_part= max(args[0]->decimal_precision() - args[0]->decimals,
args[1]->decimal_precision() - args[1]->decimals);
int precision= min(max_int_part + 1 + decimals, DECIMAL_MAX_PRECISION);
int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
int est_prec= max(arg1_int, arg2_int) + 1 + decimals;
int precision= min(est_prec, DECIMAL_MAX_PRECISION);
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if (result_type() == INT_RESULT)
@ -1267,8 +1268,8 @@ void Item_func_mul::result_precision()
else
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
int precision= min(args[0]->decimal_precision() + args[1]->decimal_precision(),
DECIMAL_MAX_PRECISION);
uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag);
}
@ -1315,8 +1316,8 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
void Item_func_div::result_precision()
{
uint precision=min(args[0]->decimal_precision() + prec_increment,
DECIMAL_MAX_PRECISION);
uint arg_prec= args[0]->decimal_precision() + prec_increment;
uint precision=min(arg_prec, DECIMAL_MAX_PRECISION);
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if (result_type() == INT_RESULT)
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;

View file

@ -7099,7 +7099,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
uint used_key_parts_arg)
: QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
: QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
used_key_parts (used_key_parts_arg)
{
QUICK_RANGE *r;
@ -7141,10 +7142,11 @@ int QUICK_SELECT_DESC::get_next()
int result;
if (last_range)
{ // Already read through key
result = ((last_range->flag & EQ_RANGE)
? file->index_next_same(record, (byte*) last_range->min_key,
last_range->min_length) :
file->index_prev(record));
result = ((last_range->flag & EQ_RANGE &&
used_key_parts <= head->key_info[index].key_parts) ?
file->index_next_same(record, (byte*) last_range->min_key,
last_range->min_length) :
file->index_prev(record));
if (!result)
{
if (cmp_prev(*rev_it.ref()) == 0)
@ -7168,7 +7170,9 @@ int QUICK_SELECT_DESC::get_next()
continue;
}
if (last_range->flag & EQ_RANGE)
if (last_range->flag & EQ_RANGE &&
used_key_parts <= head->key_info[index].key_parts)
{
result= file->index_read(record, (byte*) last_range->max_key,
last_range->max_length, HA_READ_KEY_EXACT);
@ -7176,6 +7180,8 @@ int QUICK_SELECT_DESC::get_next()
else
{
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
(last_range->flag & EQ_RANGE &&
used_key_parts > head->key_info[index].key_parts) ||
range_reads_after_key(last_range));
result=file->index_read(record, (byte*) last_range->max_key,
last_range->max_length,
@ -7273,54 +7279,6 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
}
/* TRUE if we are reading over a key that may have a NULL value */
#ifdef NOT_USED
bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
uint used_key_parts)
{
uint offset, end;
KEY_PART *key_part = key_parts,
*key_part_end= key_part+used_key_parts;
for (offset= 0, end = min(range_arg->min_length, range_arg->max_length) ;
offset < end && key_part != key_part_end ;
offset+= key_part++->store_length)
{
if (!memcmp((char*) range_arg->min_key+offset,
(char*) range_arg->max_key+offset,
key_part->store_length))
continue;
if (key_part->null_bit && range_arg->min_key[offset])
return 1; // min_key is null and max_key isn't
// Range doesn't cover NULL. This is ok if there is no more null parts
break;
}
/*
If the next min_range is > NULL, then we can use this, even if
it's a NULL key
Example: SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
*/
if (key_part != key_part_end && key_part->null_bit)
{
if (offset >= range_arg->min_length || range_arg->min_key[offset])
return 1; // Could be null
key_part++;
}
/*
If any of the key parts used in the ORDER BY could be NULL, we can't
use the key to sort the data.
*/
for (; key_part != key_part_end ; key_part++)
if (key_part->null_bit)
return 1; // Covers null part
return 0;
}
#endif
void QUICK_RANGE_SELECT::add_info_string(String *str)
{
KEY *key_info= head->key_info + index;

View file

@ -667,12 +667,10 @@ public:
int get_type() { return QS_TYPE_RANGE_DESC; }
private:
bool range_reads_after_key(QUICK_RANGE *range);
#ifdef NOT_USED
bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
#endif
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
List<QUICK_RANGE> rev_ranges;
List_iterator<QUICK_RANGE> rev_it;
uint used_key_parts;
};

View file

@ -4737,7 +4737,7 @@ ER_SLAVE_IGNORED_TABLE
swe "Slav SQL tråden ignorerade frågan pga en replicate-*-table regel"
ER_INCORRECT_GLOBAL_LOCAL_VAR
eng "Variable '%-.64s' is a %s variable"
serbian "Incorrect foreign key definition for '%-.64s': %s"
serbian "Promenljiva '%-.64s' je %s promenljiva"
ger "Variable '%-.64s' ist eine %s-Variable"
spa "Variable '%-.64s' es una %s variable"
swe "Variabel '%-.64s' är av typ %s"

View file

@ -446,7 +446,7 @@ sp_head::operator new(size_t size) throw()
init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
sp= (sp_head *) alloc_root(&own_root, size);
if (sp == NULL)
return NULL;
DBUG_RETURN(NULL);
sp->main_mem_root= own_root;
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
DBUG_RETURN(sp);

View file

@ -5430,7 +5430,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
while ((tmp_user_name= user_list++))
{
user_name= get_current_user(thd, tmp_user_name);
if (!(user_name= get_current_user(thd, tmp_user_name)))
{
result= TRUE;

View file

@ -2516,7 +2516,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
tmp++)
unlink_table(tmp);
}
return (n);
return test(n);
}
/*

View file

@ -111,7 +111,8 @@ class Select_materialize: public select_union
select_result *result; /* the result object of the caller (PS or SP) */
public:
Materialized_cursor *materialized_cursor;
Select_materialize(select_result *result_arg) :result(result_arg) {}
Select_materialize(select_result *result_arg) :result(result_arg),
materialized_cursor(0) {}
virtual bool send_fields(List<Item> &list, uint flags);
};
@ -155,6 +156,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result)))
{
delete result_materialize;
result_materialize= NULL;
return 1;
}
@ -212,6 +214,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if ((rc= materialized_cursor->open(0)))
{
delete materialized_cursor;
materialized_cursor= NULL;
goto err_open;
}

View file

@ -331,11 +331,11 @@ public:
bool no_table_names_allowed; /* used for global order by */
bool no_error; /* suppress error message (convert it to warnings) */
static void *operator new(size_t size)
static void *operator new(size_t size) throw ()
{
return (void*) sql_alloc((uint) size);
}
static void *operator new(size_t size, MEM_ROOT *mem_root)
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, (uint) size); }
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}

View file

@ -27,7 +27,7 @@ public:
{
return (void*) sql_alloc((uint) size);
}
static void *operator new[](size_t size)
static void *operator new[](size_t size) throw ()
{
return (void*) sql_alloc((uint) size);
}
@ -466,7 +466,7 @@ public:
struct ilink
{
struct ilink **prev,*next;
static void *operator new(size_t size)
static void *operator new(size_t size) throw ()
{
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
}

View file

@ -7069,11 +7069,23 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
thd->thread_stack= (char*) &tmp_thd;
thd->store_globals();
}
if (thd)
{
(void)acl_reload(thd);
(void)grant_reload(thd);
bool reload_acl_failed= acl_reload(thd);
bool reload_grants_failed= grant_reload(thd);
if (reload_acl_failed || reload_grants_failed)
{
result= 1;
/*
When an error is returned, my_message may have not been called and
the client will hang waiting for a response.
*/
my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed");
}
}
if (tmp_thd)
{
delete tmp_thd;
@ -7159,8 +7171,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog= 0;
if (lock_global_read_lock(thd))
return 1; // Killed
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
tables);
if (close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
tables))
result= 1;
if (make_global_read_lock_block_commit(thd)) // Killed
{
/* Don't leave things in a half-locked state */
@ -7169,7 +7183,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
}
else
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
{
if (close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables))
result= 1;
}
my_dbopt_cleanup();
}
if (options & REFRESH_HOSTS)
@ -7193,8 +7210,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
#ifdef OPENSSL
if (options & REFRESH_DES_KEY_FILE)
{
if (des_key_file)
result=load_des_key_file(des_key_file);
if (des_key_file && load_des_key_file(des_key_file))
result= 1;
}
#endif
#ifdef HAVE_REPLICATION

View file

@ -6469,6 +6469,12 @@ void JOIN::cleanup(bool full)
if (tmp_join)
tmp_table_param.copy_field= 0;
group_fields.delete_elements();
/*
Ensure that the above delete_elements() would not be called
twice for the same list.
*/
if (tmp_join && tmp_join != this)
tmp_join->group_fields= group_fields;
/*
We can't call delete_elements() on copy_funcs as this will cause
problems in free_elements() as some of the elements are then deleted.
@ -12088,26 +12094,25 @@ part_of_refkey(TABLE *table,Field *field)
}
/*****************************************************************************
Test if one can use the key to resolve ORDER BY
/**
Test if a key can be used to resolve ORDER BY
SYNOPSIS
test_if_order_by_key()
order Sort order
table Table to sort
idx Index to check
used_key_parts Return value for used key parts.
used_key_parts is set to correct key parts used if return value != 0
(On other cases, used_key_part may be changed).
Note that the value may actually be greater than the number of index
key parts. This can happen for storage engines that have the primary
key parts as a suffix for every secondary key.
@param order Sort order
@param table Table to sort
@param idx Index to check
@param[out] used_key_parts Return value for used key parts.
NOTES
used_key_parts is set to correct key parts used if return value != 0
(On other cases, used_key_part may be changed)
RETURN
1 key is ok.
0 Key can't be used
-1 Reverse key can be used
*****************************************************************************/
@return indication if the key can be used for sorting
@retval 1 key can be used for reading data in order.
@retval 0 Key can't be used
@retval -1 Reverse read on the key can be used
*/
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
uint *used_key_parts)
@ -12172,11 +12177,27 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
reverse=flag; // Remember if reverse
key_part++;
}
*used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
(uint) (key_part - table->key_info[idx].key_part);
if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
HA_READ_PREV))
reverse= 0; // Index can't be used
if (on_primary_key)
{
uint used_key_parts_secondary= table->key_info[idx].key_parts;
uint used_key_parts_pk=
(uint) (key_part - table->key_info[table->s->primary_key].key_part);
*used_key_parts= used_key_parts_pk + used_key_parts_secondary;
if (reverse == -1 &&
(!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
HA_READ_PREV) ||
!(table->file->index_flags(table->s->primary_key,
used_key_parts_pk - 1, 1) & HA_READ_PREV)))
reverse= 0; // Index can't be used
}
else
{
*used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
if (reverse == -1 &&
!(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
reverse= 0; // Index can't be used
}
DBUG_RETURN(reverse);
}

View file

@ -78,7 +78,7 @@ public:
Alloced_length=str.Alloced_length; alloced=0;
str_charset=str.str_charset;
}
static void *operator new(size_t size, MEM_ROOT *mem_root)
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, (uint) size); }
static void operator delete(void *ptr_arg,size_t size)
{ TRASH(ptr_arg, size); }

File diff suppressed because it is too large Load diff

View file

@ -21,10 +21,35 @@
extern "C" {
void sql_alloc_error_handler(void)
{
THD *thd=current_thd;
if (thd) // QQ; To be removed
thd->fatal_error(); /* purecov: inspected */
sql_print_error(ER(ER_OUT_OF_RESOURCES));
THD *thd=current_thd;
if (thd)
{
/*
This thread is Out Of Memory.
An OOM condition is a fatal error.
It should not be caught by error handlers in stored procedures.
Also, recording that SQL condition in the condition area could
cause more memory allocations, which in turn could raise more
OOM conditions, causing recursion in the error handling code itself.
As a result, my_error() should not be invoked, and the
thread diagnostics area is set to an error status directly.
The visible result for a client application will be:
- a query fails with an ER_OUT_OF_RESOURCES error,
returned in the error packet.
- SHOW ERROR/SHOW WARNINGS may be empty.
*/
NET *net= &thd->net;
thd->fatal_error();
if (!net->last_error[0]) // Return only first message
{
strmake(net->last_error, ER(ER_OUT_OF_RESOURCES),
sizeof(net->last_error)-1);
net->last_errno= ER_OUT_OF_RESOURCES;
}
}
}
}

View file

@ -2,8 +2,11 @@
rm -f TAGS
filter='\.cc$\|\.c$\|\.h$\|\.yy$'
files=`bk -r sfiles -gU | grep $filter `
for f in $files ;
list="find . -type f"
bzr root >/dev/null 2>/dev/null && list="bzr ls --kind=file --versioned"
$list |grep $filter |while read f;
do
etags -o TAGS --append $f
done

View file

@ -16189,6 +16189,38 @@ static void test_bug32265()
DBUG_VOID_RETURN;
}
/**
Bug#38486 Crash when using cursor protocol
*/
static void test_bug38486(void)
{
MYSQL_STMT *stmt;
const char *stmt_text;
unsigned long type= CURSOR_TYPE_READ_ONLY;
DBUG_ENTER("test_bug38486");
myheader("test_bug38486");
stmt= mysql_stmt_init(mysql);
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
stmt_text= "CREATE TABLE t1 (a INT)";
mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
stmt= mysql_stmt_init(mysql);
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
stmt_text= "INSERT INTO t1 VALUES (1)";
mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
DBUG_VOID_RETURN;
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
@ -16483,6 +16515,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug29306", test_bug29306 },
{ "test_bug31669", test_bug31669 },
{ "test_bug32265", test_bug32265 },
{ "test_bug38486", test_bug38486 },
{ 0, 0 }
};