Merge mysql-5.0-bugteam into mysql-5.0
This commit is contained in:
commit
7e35139c8f
@ -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,
|
static int run_command(char* cmd,
|
||||||
DYNAMIC_STRING *ds_res)
|
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
|
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
|
||||||
Return 0 if path found
|
mechanism will be used when we run our sub-shells with popen() later.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
static void find_tool(char *tool_executable_name, const char *tool_name,
|
||||||
static my_bool get_full_path_to_executable(char* path)
|
const char *self_name)
|
||||||
{
|
{
|
||||||
my_bool ret;
|
char *last_fn_libchar;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
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;
|
DYNAMIC_STRING ds_tmp;
|
||||||
DBUG_ENTER("find_tool");
|
DBUG_ENTER("find_tool");
|
||||||
DBUG_PRINT("enter", ("progname: %s", my_progname));
|
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))
|
if (init_dynamic_string(&ds_tmp, "", 32, 32))
|
||||||
die("Out of memory");
|
die("Out of memory");
|
||||||
|
|
||||||
/* Initialize path with the full path to this program */
|
last_fn_libchar= strrchr(self_name, FN_LIBCHAR);
|
||||||
if (get_full_path_to_executable(path))
|
|
||||||
|
if (last_fn_libchar == NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Easy way to get full executable path failed, try
|
mysql_upgrade was found by the shell searching the path. A sibling
|
||||||
other methods
|
next to us should be found the same way.
|
||||||
*/
|
*/
|
||||||
if (my_progname[0] == FN_LIBCHAR)
|
strncpy(tool_executable_name, tool_name, FN_REFLEN);
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verbose("Looking for '%s' as: %s", tool_name, tool_executable_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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Make sure it can be executed
|
Make sure it can be executed
|
||||||
*/
|
*/
|
||||||
if (run_tool(tool_path,
|
if (run_tool(tool_executable_name,
|
||||||
&ds_tmp, /* Get output from command, discard*/
|
&ds_tmp, /* Get output from command, discard*/
|
||||||
"--help",
|
"--help",
|
||||||
"2>&1",
|
"2>&1",
|
||||||
IF_WIN("> NUL", "> /dev/null"),
|
IF_WIN("> NUL", "> /dev/null"),
|
||||||
NULL))
|
NULL))
|
||||||
die("Can't execute '%s'", tool_path);
|
die("Can't execute '%s'", tool_executable_name);
|
||||||
|
|
||||||
dynstr_free(&ds_tmp);
|
dynstr_free(&ds_tmp);
|
||||||
|
|
||||||
@ -748,11 +714,20 @@ static const char *load_default_groups[]=
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char self_name[FN_REFLEN];
|
||||||
|
|
||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
#ifdef __NETWARE__
|
#ifdef __NETWARE__
|
||||||
setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
|
setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
|
||||||
#endif
|
#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))
|
if (init_dynamic_string(&ds_args, "", 512, 256))
|
||||||
die("Out of memory");
|
die("Out of memory");
|
||||||
|
|
||||||
@ -774,10 +749,10 @@ int main(int argc, char **argv)
|
|||||||
dynstr_append(&ds_args, " ");
|
dynstr_append(&ds_args, " ");
|
||||||
|
|
||||||
/* Find mysql */
|
/* 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 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
|
Read the mysql_upgrade_info file to check if mysql_upgrade
|
||||||
|
@ -131,3 +131,49 @@ drop table t1;
|
|||||||
select if(0, 18446744073709551610, 18446744073709551610);
|
select if(0, 18446744073709551610, 18446744073709551610);
|
||||||
if(0, 18446744073709551610, 18446744073709551610)
|
if(0, 18446744073709551610, 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
|
||||||
|
@ -1246,4 +1246,19 @@ set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
|
|||||||
set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
|
set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
|
||||||
set global innodb_commit_concurrency=0;
|
set global innodb_commit_concurrency=0;
|
||||||
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
|
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
|
End of 5.0 tests
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4396,4 +4396,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
Warnings:
|
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))))
|
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;
|
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.
|
End of 5.0 tests.
|
||||||
|
@ -108,3 +108,46 @@ drop table t1;
|
|||||||
select if(0, 18446744073709551610, 18446744073709551610);
|
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
|
||||||
|
@ -996,4 +996,22 @@ set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
|
|||||||
set global innodb_commit_concurrency=0;
|
set global innodb_commit_concurrency=0;
|
||||||
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
|
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
|
--echo End of 5.0 tests
|
||||||
|
@ -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;
|
SET @@global.query_cache_size=0;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# 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
|
||||||
|
@ -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);
|
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
|
||||||
DROP TABLE t1;
|
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.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
@ -1382,7 +1382,7 @@ restart:
|
|||||||
/* We don't need the page in the cache: we are going to write on disk */
|
/* We don't need the page in the cache: we are going to write on disk */
|
||||||
hash_link->requests--;
|
hash_link->requests--;
|
||||||
unlink_hash(keycache, hash_link);
|
unlink_hash(keycache, hash_link);
|
||||||
return 0;
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
if (!(block->status & BLOCK_IN_FLUSH))
|
if (!(block->status & BLOCK_IN_FLUSH))
|
||||||
{
|
{
|
||||||
@ -1399,7 +1399,7 @@ restart:
|
|||||||
flag (see the code below that handles reading requests).
|
flag (see the code below that handles reading requests).
|
||||||
*/
|
*/
|
||||||
free_block(keycache, block);
|
free_block(keycache, block);
|
||||||
return 0;
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
/* Wait intil the page is flushed on disk */
|
/* Wait intil the page is flushed on disk */
|
||||||
hash_link->requests--;
|
hash_link->requests--;
|
||||||
@ -1429,7 +1429,7 @@ restart:
|
|||||||
/* Invalidate page in the block if it has not been done yet */
|
/* Invalidate page in the block if it has not been done yet */
|
||||||
if (block->status)
|
if (block->status)
|
||||||
free_block(keycache, block);
|
free_block(keycache, block);
|
||||||
return 0;
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page_status == PAGE_READ &&
|
if (page_status == PAGE_READ &&
|
||||||
|
@ -202,7 +202,7 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
|
|||||||
{
|
{
|
||||||
if (mem_root->error_handler)
|
if (mem_root->error_handler)
|
||||||
(*mem_root->error_handler)();
|
(*mem_root->error_handler)();
|
||||||
return((gptr) 0); /* purecov: inspected */
|
DBUG_RETURN((gptr) 0); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
mem_root->block_num++;
|
mem_root->block_num++;
|
||||||
next->next= *prev;
|
next->next= *prev;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
-- The system tables of MySQL Server
|
-- The system tables of MySQL Server
|
||||||
--
|
--
|
||||||
|
|
||||||
|
set sql_mode='';
|
||||||
set storage_engine=myisam;
|
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';
|
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';
|
||||||
|
@ -48,7 +48,8 @@ class Field
|
|||||||
Field(const Item &); /* Prevent use of these */
|
Field(const Item &); /* Prevent use of these */
|
||||||
void operator=(Field &);
|
void operator=(Field &);
|
||||||
public:
|
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); }
|
static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); }
|
||||||
|
|
||||||
char *ptr; // Position to field in record
|
char *ptr; // Position to field in record
|
||||||
|
12
sql/item.cc
12
sql/item.cc
@ -429,8 +429,11 @@ uint Item::decimal_precision() const
|
|||||||
Item_result restype= result_type();
|
Item_result restype= result_type();
|
||||||
|
|
||||||
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
|
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);
|
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)
|
if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
|
||||||
{
|
{
|
||||||
decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
|
decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
|
||||||
int precision= min(max(prev_decimal_int_part, item->decimal_int_part())
|
int item_int_part= item->decimal_int_part();
|
||||||
+ decimals, DECIMAL_MAX_PRECISION);
|
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;
|
unsigned_flag&= item->unsigned_flag;
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length(precision, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
|
@ -439,9 +439,9 @@ class Item {
|
|||||||
Item(const Item &); /* Prevent use of these */
|
Item(const Item &); /* Prevent use of these */
|
||||||
void operator=(Item &);
|
void operator=(Item &);
|
||||||
public:
|
public:
|
||||||
static void *operator new(size_t size)
|
static void *operator new(size_t size) throw ()
|
||||||
{ return (void*) sql_alloc((uint) size); }
|
{ 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); }
|
{ 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,size_t size) { TRASH(ptr, size); }
|
||||||
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
||||||
|
@ -2098,8 +2098,11 @@ Item_func_ifnull::fix_length_and_dec()
|
|||||||
|
|
||||||
uint Item_func_ifnull::decimal_precision() const
|
uint Item_func_ifnull::decimal_precision() const
|
||||||
{
|
{
|
||||||
int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
|
int arg0_int_part= args[0]->decimal_int_part();
|
||||||
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
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
|
uint Item_func_if::decimal_precision() const
|
||||||
{
|
{
|
||||||
int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
|
int arg1_prec= args[1]->decimal_int_part();
|
||||||
decimals);
|
int arg2_prec= args[2]->decimal_int_part();
|
||||||
|
int precision=max(arg1_prec,arg2_prec) + decimals;
|
||||||
return min(precision, DECIMAL_MAX_PRECISION);
|
return min(precision, DECIMAL_MAX_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1156,9 +1156,10 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
|||||||
void Item_func_additive_op::result_precision()
|
void Item_func_additive_op::result_precision()
|
||||||
{
|
{
|
||||||
decimals= max(args[0]->decimals, args[1]->decimals);
|
decimals= max(args[0]->decimals, args[1]->decimals);
|
||||||
int max_int_part= max(args[0]->decimal_precision() - args[0]->decimals,
|
int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
|
||||||
args[1]->decimal_precision() - args[1]->decimals);
|
int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
|
||||||
int precision= min(max_int_part + 1 + decimals, DECIMAL_MAX_PRECISION);
|
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 */
|
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
|
||||||
if (result_type() == INT_RESULT)
|
if (result_type() == INT_RESULT)
|
||||||
@ -1267,8 +1268,8 @@ void Item_func_mul::result_precision()
|
|||||||
else
|
else
|
||||||
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
|
||||||
decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
|
decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
|
||||||
int precision= min(args[0]->decimal_precision() + args[1]->decimal_precision(),
|
uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
|
||||||
DECIMAL_MAX_PRECISION);
|
uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag);
|
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()
|
void Item_func_div::result_precision()
|
||||||
{
|
{
|
||||||
uint precision=min(args[0]->decimal_precision() + prec_increment,
|
uint arg_prec= args[0]->decimal_precision() + prec_increment;
|
||||||
DECIMAL_MAX_PRECISION);
|
uint precision=min(arg_prec, DECIMAL_MAX_PRECISION);
|
||||||
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
|
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
|
||||||
if (result_type() == INT_RESULT)
|
if (result_type() == INT_RESULT)
|
||||||
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
|
||||||
|
@ -7099,7 +7099,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
|
|||||||
|
|
||||||
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
|
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
|
||||||
uint used_key_parts_arg)
|
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;
|
QUICK_RANGE *r;
|
||||||
|
|
||||||
@ -7141,10 +7142,11 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
int result;
|
int result;
|
||||||
if (last_range)
|
if (last_range)
|
||||||
{ // Already read through key
|
{ // Already read through key
|
||||||
result = ((last_range->flag & EQ_RANGE)
|
result = ((last_range->flag & EQ_RANGE &&
|
||||||
? file->index_next_same(record, (byte*) last_range->min_key,
|
used_key_parts <= head->key_info[index].key_parts) ?
|
||||||
last_range->min_length) :
|
file->index_next_same(record, (byte*) last_range->min_key,
|
||||||
file->index_prev(record));
|
last_range->min_length) :
|
||||||
|
file->index_prev(record));
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
if (cmp_prev(*rev_it.ref()) == 0)
|
if (cmp_prev(*rev_it.ref()) == 0)
|
||||||
@ -7168,7 +7170,9 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
continue;
|
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,
|
result= file->index_read(record, (byte*) last_range->max_key,
|
||||||
last_range->max_length, HA_READ_KEY_EXACT);
|
last_range->max_length, HA_READ_KEY_EXACT);
|
||||||
@ -7176,6 +7180,8 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
|
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));
|
range_reads_after_key(last_range));
|
||||||
result=file->index_read(record, (byte*) last_range->max_key,
|
result=file->index_read(record, (byte*) last_range->max_key,
|
||||||
last_range->max_length,
|
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)
|
void QUICK_RANGE_SELECT::add_info_string(String *str)
|
||||||
{
|
{
|
||||||
KEY *key_info= head->key_info + index;
|
KEY *key_info= head->key_info + index;
|
||||||
|
@ -667,12 +667,10 @@ public:
|
|||||||
int get_type() { return QS_TYPE_RANGE_DESC; }
|
int get_type() { return QS_TYPE_RANGE_DESC; }
|
||||||
private:
|
private:
|
||||||
bool range_reads_after_key(QUICK_RANGE *range);
|
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(); }
|
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
|
||||||
List<QUICK_RANGE> rev_ranges;
|
List<QUICK_RANGE> rev_ranges;
|
||||||
List_iterator<QUICK_RANGE> rev_it;
|
List_iterator<QUICK_RANGE> rev_it;
|
||||||
|
uint used_key_parts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -4737,7 +4737,7 @@ ER_SLAVE_IGNORED_TABLE
|
|||||||
swe "Slav SQL tråden ignorerade frågan pga en replicate-*-table regel"
|
swe "Slav SQL tråden ignorerade frågan pga en replicate-*-table regel"
|
||||||
ER_INCORRECT_GLOBAL_LOCAL_VAR
|
ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||||
eng "Variable '%-.64s' is a %s variable"
|
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"
|
ger "Variable '%-.64s' ist eine %s-Variable"
|
||||||
spa "Variable '%-.64s' es una %s variable"
|
spa "Variable '%-.64s' es una %s variable"
|
||||||
swe "Variabel '%-.64s' är av typ %s"
|
swe "Variabel '%-.64s' är av typ %s"
|
||||||
|
@ -446,7 +446,7 @@ sp_head::operator new(size_t size) throw()
|
|||||||
init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
|
init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
|
||||||
sp= (sp_head *) alloc_root(&own_root, size);
|
sp= (sp_head *) alloc_root(&own_root, size);
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
return NULL;
|
DBUG_RETURN(NULL);
|
||||||
sp->main_mem_root= own_root;
|
sp->main_mem_root= own_root;
|
||||||
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
|
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
|
||||||
DBUG_RETURN(sp);
|
DBUG_RETURN(sp);
|
||||||
|
@ -5430,7 +5430,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
|
|||||||
|
|
||||||
while ((tmp_user_name= 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)))
|
if (!(user_name= get_current_user(thd, tmp_user_name)))
|
||||||
{
|
{
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
|
@ -2516,7 +2516,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
|
|||||||
tmp++)
|
tmp++)
|
||||||
unlink_table(tmp);
|
unlink_table(tmp);
|
||||||
}
|
}
|
||||||
return (n);
|
return test(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -111,7 +111,8 @@ class Select_materialize: public select_union
|
|||||||
select_result *result; /* the result object of the caller (PS or SP) */
|
select_result *result; /* the result object of the caller (PS or SP) */
|
||||||
public:
|
public:
|
||||||
Materialized_cursor *materialized_cursor;
|
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);
|
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)))
|
if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result)))
|
||||||
{
|
{
|
||||||
delete result_materialize;
|
delete result_materialize;
|
||||||
|
result_materialize= NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +214,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
|
|||||||
if ((rc= materialized_cursor->open(0)))
|
if ((rc= materialized_cursor->open(0)))
|
||||||
{
|
{
|
||||||
delete materialized_cursor;
|
delete materialized_cursor;
|
||||||
|
materialized_cursor= NULL;
|
||||||
goto err_open;
|
goto err_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,11 +331,11 @@ public:
|
|||||||
bool no_table_names_allowed; /* used for global order by */
|
bool no_table_names_allowed; /* used for global order by */
|
||||||
bool no_error; /* suppress error message (convert it to warnings) */
|
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);
|
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); }
|
{ 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,size_t size) { TRASH(ptr, size); }
|
||||||
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
{
|
{
|
||||||
return (void*) sql_alloc((uint) size);
|
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);
|
return (void*) sql_alloc((uint) size);
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ public:
|
|||||||
struct ilink
|
struct ilink
|
||||||
{
|
{
|
||||||
struct ilink **prev,*next;
|
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));
|
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
|
||||||
}
|
}
|
||||||
|
@ -7069,11 +7069,23 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
|||||||
thd->thread_stack= (char*) &tmp_thd;
|
thd->thread_stack= (char*) &tmp_thd;
|
||||||
thd->store_globals();
|
thd->store_globals();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thd)
|
if (thd)
|
||||||
{
|
{
|
||||||
(void)acl_reload(thd);
|
bool reload_acl_failed= acl_reload(thd);
|
||||||
(void)grant_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)
|
if (tmp_thd)
|
||||||
{
|
{
|
||||||
delete 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;
|
tmp_write_to_binlog= 0;
|
||||||
if (lock_global_read_lock(thd))
|
if (lock_global_read_lock(thd))
|
||||||
return 1; // Killed
|
return 1; // Killed
|
||||||
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
|
if (close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
|
||||||
tables);
|
tables))
|
||||||
|
result= 1;
|
||||||
|
|
||||||
if (make_global_read_lock_block_commit(thd)) // Killed
|
if (make_global_read_lock_block_commit(thd)) // Killed
|
||||||
{
|
{
|
||||||
/* Don't leave things in a half-locked state */
|
/* 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
|
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();
|
my_dbopt_cleanup();
|
||||||
}
|
}
|
||||||
if (options & REFRESH_HOSTS)
|
if (options & REFRESH_HOSTS)
|
||||||
@ -7193,8 +7210,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
|||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
if (options & REFRESH_DES_KEY_FILE)
|
if (options & REFRESH_DES_KEY_FILE)
|
||||||
{
|
{
|
||||||
if (des_key_file)
|
if (des_key_file && load_des_key_file(des_key_file))
|
||||||
result=load_des_key_file(des_key_file);
|
result= 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
|
@ -6469,6 +6469,12 @@ void JOIN::cleanup(bool full)
|
|||||||
if (tmp_join)
|
if (tmp_join)
|
||||||
tmp_table_param.copy_field= 0;
|
tmp_table_param.copy_field= 0;
|
||||||
group_fields.delete_elements();
|
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
|
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.
|
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
|
used_key_parts is set to correct key parts used if return value != 0
|
||||||
test_if_order_by_key()
|
(On other cases, used_key_part may be changed).
|
||||||
order Sort order
|
Note that the value may actually be greater than the number of index
|
||||||
table Table to sort
|
key parts. This can happen for storage engines that have the primary
|
||||||
idx Index to check
|
key parts as a suffix for every secondary key.
|
||||||
used_key_parts Return value for used key parts.
|
|
||||||
|
|
||||||
|
@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
|
@return indication if the key can be used for sorting
|
||||||
used_key_parts is set to correct key parts used if return value != 0
|
@retval 1 key can be used for reading data in order.
|
||||||
(On other cases, used_key_part may be changed)
|
@retval 0 Key can't be used
|
||||||
|
@retval -1 Reverse read on the key can be used
|
||||||
RETURN
|
*/
|
||||||
1 key is ok.
|
|
||||||
0 Key can't be used
|
|
||||||
-1 Reverse key can be used
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||||
uint *used_key_parts)
|
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
|
reverse=flag; // Remember if reverse
|
||||||
key_part++;
|
key_part++;
|
||||||
}
|
}
|
||||||
*used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
|
if (on_primary_key)
|
||||||
(uint) (key_part - table->key_info[idx].key_part);
|
{
|
||||||
if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
|
uint used_key_parts_secondary= table->key_info[idx].key_parts;
|
||||||
HA_READ_PREV))
|
uint used_key_parts_pk=
|
||||||
reverse= 0; // Index can't be used
|
(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);
|
DBUG_RETURN(reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public:
|
|||||||
Alloced_length=str.Alloced_length; alloced=0;
|
Alloced_length=str.Alloced_length; alloced=0;
|
||||||
str_charset=str.str_charset;
|
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); }
|
{ return (void*) alloc_root(mem_root, (uint) size); }
|
||||||
static void operator delete(void *ptr_arg,size_t size)
|
static void operator delete(void *ptr_arg,size_t size)
|
||||||
{ TRASH(ptr_arg, size); }
|
{ TRASH(ptr_arg, size); }
|
||||||
|
1775
sql/sql_yacc.yy
1775
sql/sql_yacc.yy
File diff suppressed because it is too large
Load Diff
@ -21,10 +21,35 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void sql_alloc_error_handler(void)
|
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));
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
rm -f TAGS
|
rm -f TAGS
|
||||||
filter='\.cc$\|\.c$\|\.h$\|\.yy$'
|
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
|
do
|
||||||
etags -o TAGS --append $f
|
etags -o TAGS --append $f
|
||||||
done
|
done
|
||||||
|
@ -16189,6 +16189,38 @@ static void test_bug32265()
|
|||||||
DBUG_VOID_RETURN;
|
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
|
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_bug29306", test_bug29306 },
|
||||||
{ "test_bug31669", test_bug31669 },
|
{ "test_bug31669", test_bug31669 },
|
||||||
{ "test_bug32265", test_bug32265 },
|
{ "test_bug32265", test_bug32265 },
|
||||||
|
{ "test_bug38486", test_bug38486 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user