Merge 5.1-bugteam into main.

This commit is contained in:
Davi Arnaut 2008-07-22 15:24:31 -03:00
commit afeab2052f
56 changed files with 1438 additions and 499 deletions

View File

@ -2101,6 +2101,37 @@ static bool add_line(String &buffer,char *line,char *in_string,
continue;
}
}
else if (!*ml_comment && !*in_string &&
(end_of_line - pos) >= 10 &&
!my_strnncoll(charset_info, (uchar*) pos, 10,
(const uchar*) "delimiter ", 10))
{
// Flush previously accepted characters
if (out != line)
{
buffer.append(line, (uint32) (out - line));
out= line;
}
// Flush possible comments in the buffer
if (!buffer.is_empty())
{
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
DBUG_RETURN(1);
buffer.length(0);
}
/*
Delimiter wants the get rest of the given line as argument to
allow one to change ';' to ';;' and back
*/
buffer.append(pos);
if (com_delimiter(&buffer, pos) > 0)
DBUG_RETURN(1);
buffer.length(0);
break;
}
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
{
// Found a statement. Continue parsing after the delimiter

View File

@ -171,6 +171,8 @@ static ulonglong timer_now(void);
static ulonglong progress_start= 0;
static ulong connection_retry_sleep= 100000; /* Microseconds */
/* Precompiled re's */
static my_regex_t ps_re; /* the query can be run using PS protocol */
static my_regex_t sp_re; /* the query can be run as a SP */
@ -495,6 +497,9 @@ void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
static int match_expected_error(struct st_command *command,
unsigned int err_errno,
const char *err_sqlstate);
void handle_error(struct st_command*,
unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds);
@ -848,29 +853,25 @@ void check_command_args(struct st_command *command,
DBUG_VOID_RETURN;
}
void handle_command_error(struct st_command *command, uint error)
{
DBUG_ENTER("handle_command_error");
DBUG_PRINT("enter", ("error: %d", error));
if (error != 0)
{
uint i;
int i;
if (command->abort_on_error)
die("command \"%.*s\" failed with error %d",
command->first_word_len, command->query, error);
for (i= 0; i < command->expected_errors.count; i++)
i= match_expected_error(command, error, NULL);
if (i >= 0)
{
DBUG_PRINT("info", ("expected error: %d",
command->expected_errors.err[i].code.errnum));
if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
(command->expected_errors.err[i].code.errnum == error))
{
DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
command->first_word_len, command->query, error));
DBUG_VOID_RETURN;
}
DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
command->first_word_len, command->query, error));
DBUG_VOID_RETURN;
}
die("command \"%.*s\" failed with wrong error: %d",
command->first_word_len, command->query, error);
@ -2465,8 +2466,8 @@ void do_exec(struct st_command *command)
error= pclose(res_file);
if (error > 0)
{
uint status= WEXITSTATUS(error), i;
my_bool ok= 0;
uint status= WEXITSTATUS(error);
int i;
if (command->abort_on_error)
{
@ -2478,19 +2479,13 @@ void do_exec(struct st_command *command)
DBUG_PRINT("info",
("error: %d, status: %d", error, status));
for (i= 0; i < command->expected_errors.count; i++)
{
DBUG_PRINT("info", ("expected error: %d",
command->expected_errors.err[i].code.errnum));
if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
(command->expected_errors.err[i].code.errnum == status))
{
ok= 1;
DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
command->first_argument, status));
}
}
if (!ok)
i= match_expected_error(command, status, NULL);
if (i >= 0)
DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
command->first_argument, status));
else
{
dynstr_free(&ds_cmd);
die("command \"%s\" failed with wrong error: %d",
@ -4290,7 +4285,6 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host,
int port, const char *sock)
{
int failed_attempts= 0;
static ulong connection_retry_sleep= 100000; /* Microseconds */
DBUG_ENTER("safe_connect");
while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
@ -4357,6 +4351,7 @@ int connect_n_handle_errors(struct st_command *command,
const char* db, int port, const char* sock)
{
DYNAMIC_STRING *ds;
int failed_attempts= 0;
ds= &ds_res;
@ -4385,9 +4380,41 @@ int connect_n_handle_errors(struct st_command *command,
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1);
}
if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS))
{
/*
If we have used up all our connections check whether this
is expected (by --error). If so, handle the error right away.
Otherwise, give it some extra time to rule out race-conditions.
If extra-time doesn't help, we have an unexpected error and
must abort -- just proceeding to handle_error() when second
and third chances are used up will handle that for us.
There are various user-limits of which only max_user_connections
and max_connections_per_hour apply at connect time. For the
the second to create a race in our logic, we'd need a limits
test that runs without a FLUSH for longer than an hour, so we'll
stay clear of trying to work out which exact user-limit was
exceeded.
*/
if (((mysql_errno(con) == ER_TOO_MANY_USER_CONNECTIONS) ||
(mysql_errno(con) == ER_USER_LIMIT_REACHED)) &&
(failed_attempts++ < opt_max_connect_retries))
{
int i;
i= match_expected_error(command, mysql_errno(con), mysql_sqlstate(con));
if (i >= 0)
goto do_handle_error; /* expected error, handle */
my_sleep(connection_retry_sleep); /* unexpected error, wait */
continue; /* and give it 1 more chance */
}
do_handle_error:
var_set_errno(mysql_errno(con));
handle_error(command, mysql_errno(con), mysql_error(con),
mysql_sqlstate(con), ds);
@ -6149,6 +6176,56 @@ end:
}
/*
Check whether given error is in list of expected errors
SYNOPSIS
match_expected_error()
PARAMETERS
command the current command (and its expect-list)
err_errno error number of the error that actually occurred
err_sqlstate SQL-state that was thrown, or NULL for impossible
(file-ops, diff, etc.)
RETURNS
-1 for not in list, index in list of expected errors otherwise
NOTE
If caller needs to know whether the list was empty, they should
check command->expected_errors.count.
*/
static int match_expected_error(struct st_command *command,
unsigned int err_errno,
const char *err_sqlstate)
{
uint i;
for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
{
if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
(command->expected_errors.err[i].code.errnum == err_errno))
return i;
if (command->expected_errors.err[i].type == ERR_SQLSTATE)
{
/*
NULL is quite likely, but not in conjunction with a SQL-state expect!
*/
if (unlikely(err_sqlstate == NULL))
die("expecting a SQL-state (%s) from query '%s' which cannot produce one...",
command->expected_errors.err[i].code.sqlstate, command->query);
if (strncmp(command->expected_errors.err[i].code.sqlstate,
err_sqlstate, SQLSTATE_LENGTH) == 0)
return i;
}
}
return -1;
}
/*
Handle errors which occurred during execution
@ -6169,7 +6246,7 @@ void handle_error(struct st_command *command,
unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds)
{
uint i;
int i;
DBUG_ENTER("handle_error");
@ -6195,34 +6272,30 @@ void handle_error(struct st_command *command,
DBUG_PRINT("info", ("expected_errors.count: %d",
command->expected_errors.count));
for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
i= match_expected_error(command, err_errno, err_sqlstate);
if (i >= 0)
{
if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
(command->expected_errors.err[i].code.errnum == err_errno)) ||
((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
(strncmp(command->expected_errors.err[i].code.sqlstate,
err_sqlstate, SQLSTATE_LENGTH) == 0)))
if (!disable_result_log)
{
if (!disable_result_log)
if (command->expected_errors.count == 1)
{
if (command->expected_errors.count == 1)
{
/* Only log error if there is one possible error */
dynstr_append_mem(ds, "ERROR ", 6);
replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
(command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
/* Only log error if there is one possible error */
dynstr_append_mem(ds, "ERROR ", 6);
replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds,"\n",1);
}
/* OK */
DBUG_VOID_RETURN;
/* Don't log error if we may not get an error */
else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
(command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
}
/* OK */
DBUG_VOID_RETURN;
}
DBUG_PRINT("info",("i: %d expected_errors: %d", i,
@ -6237,7 +6310,7 @@ void handle_error(struct st_command *command,
dynstr_append_mem(ds, "\n", 1);
}
if (i)
if (command->expected_errors.count > 0)
{
if (command->expected_errors.err[0].type == ERR_ERRNO)
die("query '%s' failed with wrong errno %d: '%s', instead of %d...",

View File

@ -1103,6 +1103,24 @@ 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
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY

View File

@ -1,32 +1,35 @@
############## mysql-test\t\query_prealloc_size_basic.test ###############
# #
# Variable Name: query_prealloc_size #
# Scope: GLOBAL | SESSION #
# Access Type: Dynamic #
# Data Type: numeric #
# Default Value: 8192 #
# Range: 8192-4294967295 #
# #
# #
# Creation Date: 2008-02-07 #
# Author: Rizwan #
# #
# Description: Test Cases of Dynamic System Variable query_prealloc_size #
# that checks the behavior of this variable in the following ways#
# * Default Value #
# * Valid & Invalid values #
# * Scope & Access method #
# * Data Integrity #
# #
# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
# server-system-variables.html #
# #
###############################################################################
################# mysql-test\t\query_prealloc_size_basic.test ##################
# #
# Variable Name: query_prealloc_size #
# Scope: GLOBAL | SESSION #
# Access Type: Dynamic #
# Data Type: numeric #
# Default Value: 8192 #
# Range: 8192-4294967295 #
# #
# #
# Creation Date: 2008-02-07 #
# Author: Rizwan #
# #
# Description: Test Cases of Dynamic System Variable query_prealloc_size #
# that checks the behavior of this variable in the following ways #
# * Default Value #
# * Valid & Invalid values #
# * Scope & Access method #
# * Data Integrity #
# #
# Reference: #
# http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html #
# #
# Last Modification: #
# 2008-07-14 hhunger removed values for 64 bit platforms. #
# #
################################################################################
--source include/load_sysvars.inc
########################################################################
# START OF query_prealloc_size TESTS #
# START OF query_prealloc_size TESTS #
########################################################################
@ -42,7 +45,7 @@ SELECT @start_session_value;
--echo '#--------------------FN_DYNVARS_005_01-------------------------#'
########################################################################
# Display the DEFAULT value of myisam_block_size #
# Display the DEFAULT value of myisam_block_size #
########################################################################
SET @@global.query_prealloc_size = 100;
@ -56,7 +59,7 @@ SELECT @@session.query_prealloc_size ;
--echo '#--------------------FN_DYNVARS_005_02-------------------------#'
########################################################################
# Check the DEFAULT value of query_prealloc_size #
# Check the DEFAULT value of query_prealloc_size #
########################################################################
SET @@global.query_prealloc_size = DEFAULT;
@ -67,30 +70,32 @@ SELECT @@session.query_prealloc_size = 8192;
--echo '#--------------------FN_DYNVARS_005_03-------------------------#'
##################################################################################
# Change the value of query_prealloc_size to a valid value for GLOBAL Scope #
##################################################################################
################################################################################
# Change the value of query_prealloc_size to a valid value for GLOBAL Scope #
################################################################################
SET @@global.query_prealloc_size = 8192;
SELECT @@global.query_prealloc_size ;
SET @@global.query_prealloc_size = 4294967295;
SELECT @@global.query_prealloc_size ;
# Due to problems with 64 bit machines having less than 6 GB main memory.
#SET @@global.query_prealloc_size = 4294967295;
#SELECT @@global.query_prealloc_size ;
SET @@global.query_prealloc_size = 655354;
SELECT @@global.query_prealloc_size ;
--echo '#--------------------FN_DYNVARS_005_04-------------------------#'
###################################################################################
# Change the value of query_prealloc_size to a valid value for SESSION Scope #
###################################################################################
##################################################################################
# Change the value of query_prealloc_size to a valid value for SESSION Scope #
##################################################################################
SET @@session.query_prealloc_size = 8192;
SELECT @@session.query_prealloc_size ;
SET @@session.query_prealloc_size = 4294967295;
SELECT @@session.query_prealloc_size ;
# Due to problems with 64 bit machines having less than 6 GB main memory.
#SET @@session.query_prealloc_size = 4294967295;
#SELECT @@session.query_prealloc_size ;
SET @@session.query_prealloc_size = 655345;
SELECT @@session.query_prealloc_size ;
@ -100,7 +105,7 @@ SELECT @@session.query_prealloc_size ;
--echo '#------------------FN_DYNVARS_005_05-----------------------#'
####################################################################
# Change the value of query_prealloc_size to an invalid value #
# Change the value of query_prealloc_size to an invalid value #
####################################################################
SET @@global.query_prealloc_size = 0;
@ -109,8 +114,9 @@ SELECT @@global.query_prealloc_size ;
SET @@global.query_prealloc_size = -1024;
SELECT @@global.query_prealloc_size ;
SET @@global.query_prealloc_size = 429496729533;
SELECT @@global.query_prealloc_size ;
# Due to problems with 64 bit machines having less than 6 GB main memory.
#SET @@global.query_prealloc_size = 429496729533;
#SELECT @@global.query_prealloc_size ;
--Error ER_PARSE_ERROR
@ -161,8 +167,8 @@ SELECT @@session.query_prealloc_size ;
####################################################################
SELECT @@global.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
SELECT @@global.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='query_prealloc_size ';
--echo '#------------------FN_DYNVARS_005_07-----------------------#'
@ -170,8 +176,8 @@ WHERE VARIABLE_NAME='query_prealloc_size ';
# Check if the value in SESSION Table matches value in variable #
####################################################################
SELECT @@session.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
SELECT @@session.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='query_prealloc_size ';
@ -188,18 +194,19 @@ SELECT @@global.query_prealloc_size ;
--echo '#---------------------FN_DYNVARS_001_09----------------------#'
####################################################################################
# Check if accessing variable with and without GLOBAL point to same variable #
####################################################################################
################################################################################
# Check if accessing variable with and without GLOBAL point to same variable #
################################################################################
SET @@global.query_prealloc_size = 10;
SELECT @@query_prealloc_size = @@global.query_prealloc_size ;
--echo '#---------------------FN_DYNVARS_001_10----------------------#'
########################################################################################################
# Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable #
########################################################################################################
##############################################################################
# Check if accessing variable with SESSION,LOCAL and without SCOPE points to #
# to the same session variable #
##############################################################################
SET @@query_prealloc_size = 100;
SELECT @@query_prealloc_size = @@local.query_prealloc_size ;
@ -207,9 +214,9 @@ SELECT @@local.query_prealloc_size = @@session.query_prealloc_size ;
--echo '#---------------------FN_DYNVARS_001_11----------------------#'
###################################################################################
# Check if query_prealloc_size can be accessed with and without @@ sign #
###################################################################################
################################################################################
# Check if query_prealloc_size can be accessed with and without @@ sign #
################################################################################
SET query_prealloc_size = 1;
SELECT @@query_prealloc_size ;
@ -235,5 +242,6 @@ SELECT @@session.query_prealloc_size ;
#############################################################
# END OF query_prealloc_size TESTS #
# END OF query_prealloc_size TESTS #
#############################################################

View File

@ -1,5 +1,6 @@
set @old_concurrent_insert= @@global.concurrent_insert;
set @@global.concurrent_insert= 0;
drop table if exists t1;
create table t1 (
`a&b` int,
`a<b` int,

View File

@ -569,4 +569,10 @@ insert into t1 values (),(),(),(),(),(),(),(),(),();
select a from t1 where a not in (a,a,a) group by a;
a
drop table t1;
create table t1 (id int);
select * from t1 where NOT id in (select null union all select 1);
id
select * from t1 where NOT id in (null, 1);
id
drop table t1;
End of 5.1 tests

View File

@ -1362,6 +1362,21 @@ 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 index t1_b PRIMARY 4 NULL 8 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
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,

View File

@ -38,8 +38,6 @@ t2
t3
Tables_in_test
t1
delimiter
1
_
Test delimiter : from command line
a

View File

@ -14,6 +14,7 @@ select otto from (select 1 as otto) as t1;
otto
1
mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22...
mysqltest: At line 1: expecting a SQL-state (00000) from query 'remove_file MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp' which cannot produce one...
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000...

View File

@ -0,0 +1,306 @@
use test;
SELECT
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
1
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
;
1
1
prepare stmt from
"
SELECT
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
1
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
"
;
execute stmt;
1
1
drop view if exists view_overflow;
CREATE VIEW view_overflow AS
SELECT
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
1
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
;
SELECT * from view_overflow;
1
1
drop view view_overflow;
drop procedure if exists proc_overflow;
CREATE PROCEDURE proc_overflow()
BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
select 1;
select 2;
select 3;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END $$
call proc_overflow();
1
1
2
2
3
3
drop procedure proc_overflow;
drop function if exists func_overflow;
create function func_overflow() returns int
BEGIN
DECLARE x int default 0;
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
SET x=x+1;
SET x=x+2;
SET x=x+3;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
return x;
END $$
select func_overflow();
func_overflow()
6
drop function func_overflow;
drop table if exists table_overflow;
create table table_overflow(a int, b int);
create trigger trigger_overflow before insert on table_overflow
for each row
BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
SET NEW.b := NEW.a;
SET NEW.b := NEW.b + 1;
SET NEW.b := NEW.b + 2;
SET NEW.b := NEW.b + 3;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END $$
insert into table_overflow set a=10;
insert into table_overflow set a=20;
select * from table_overflow;
a b
10 16
20 26
drop table table_overflow;
drop procedure if exists proc_35577;
CREATE PROCEDURE proc_35577()
BEGIN
DECLARE z_done INT DEFAULT 0;
DECLARE t_done VARCHAR(5000);
outer_loop: LOOP
IF t_done=1 THEN
LEAVE outer_loop;
END IF;
inner_block:BEGIN
DECLARE z_done INT DEFAULT 0;
SET z_done = 0;
inner_loop: LOOP
IF z_done=1 THEN
LEAVE inner_loop;
END IF;
IF (t_done = 'a') THEN
IF (t_done <> 0) THEN
IF ( t_done > 0) THEN
IF (t_done = 'a') THEN
SET t_done = 'a';
ELSEIF (t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
END IF;
END IF;
END IF;
END IF;
END LOOP inner_loop;
END inner_block;
END LOOP outer_loop;
END $$
drop procedure proc_35577;
drop procedure if exists p_37269;
create procedure p_37269()
begin
declare done int default 0;
declare varb int default 0;
declare vara int default 0;
repeat
select now();
until done end repeat;
while varb do
select now();
begin
select now();
repeat
select now();
until done end repeat;
if vara then
select now();
repeat
select now();
loop
select now();
end loop;
repeat
select now();
label1: while varb do
select now();
end while label1;
if vara then
select now();
repeat
select now();
until done end repeat;
begin
select now();
while varb do
select now();
label1: while varb do
select now();
end while label1;
if vara then
select now();
while varb do
select now();
loop
select now();
end loop;
repeat
select now();
loop
select now();
while varb do
select now();
end while;
repeat
select now();
label1: loop
select now();
if vara then
select now();
end if;
end loop label1;
until done end repeat;
end loop;
until done end repeat;
end while;
end if;
end while;
end;
end if;
until done end repeat;
until done end repeat;
end if;
end;
end while;
end $$
drop procedure p_37269;
drop procedure if exists p_37228;
create procedure p_37228 ()
BEGIN
DECLARE v INT DEFAULT 123;
IF (v > 1) THEN SET v = 1;
ELSEIF (v < 10) THEN SET v = 10;
ELSEIF (v < 11) THEN SET v = 11;
ELSEIF (v < 12) THEN SET v = 12;
ELSEIF (v < 13) THEN SET v = 13;
ELSEIF (v < 14) THEN SET v = 14;
ELSEIF (v < 15) THEN SET v = 15;
ELSEIF (v < 16) THEN SET v = 16;
ELSEIF (v < 17) THEN SET v = 17;
ELSEIF (v < 18) THEN SET v = 18;
ELSEIF (v < 19) THEN SET v = 19;
ELSEIF (v < 20) THEN SET v = 20;
ELSEIF (v < 21) THEN SET v = 21;
ELSEIF (v < 22) THEN SET v = 22;
ELSEIF (v < 23) THEN SET v = 23;
ELSEIF (v < 24) THEN SET v = 24;
ELSEIF (v < 25) THEN SET v = 25;
ELSEIF (v < 26) THEN SET v = 26;
ELSEIF (v < 27) THEN SET v = 27;
ELSEIF (v < 28) THEN SET v = 28;
ELSEIF (v < 29) THEN SET v = 29;
ELSEIF (v < 30) THEN SET v = 30;
ELSEIF (v < 31) THEN SET v = 31;
ELSEIF (v < 32) THEN SET v = 32;
ELSEIF (v < 33) THEN SET v = 33;
ELSEIF (v < 34) THEN SET v = 34;
ELSEIF (v < 35) THEN SET v = 35;
ELSEIF (v < 36) THEN SET v = 36;
ELSEIF (v < 37) THEN SET v = 37;
ELSEIF (v < 38) THEN SET v = 38;
ELSEIF (v < 39) THEN SET v = 39;
END IF;
END $$
drop procedure p_37228;

View File

@ -35,10 +35,6 @@ SET @@global.query_prealloc_size = 8192;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
8192
SET @@global.query_prealloc_size = 4294967295;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
SET @@global.query_prealloc_size = 655354;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
@ -48,10 +44,6 @@ SET @@session.query_prealloc_size = 8192;
SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
8192
SET @@session.query_prealloc_size = 4294967295;
SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
4294966272
SET @@session.query_prealloc_size = 655345;
SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
@ -69,37 +61,31 @@ Warning 1292 Truncated incorrect query_prealloc_size value: '0'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
8192
SET @@global.query_prealloc_size = 429496729533;
Warnings:
Warning 1292 Truncated incorrect query_prealloc_size value: '429496729533'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
SET @@global.query_prealloc_size = 65530.34.;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
8192
SET @@global.query_prealloc_size = test;
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
8192
SET @@global.query_prealloc_size = "test";
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
8192
SET @@global.query_prealloc_size = 'test';
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
8192
SET @@global.query_prealloc_size = ON;
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
8192
SET @@session.query_prealloc_size = 0;
Warnings:
Warning 1292 Truncated incorrect query_prealloc_size value: '0'
@ -128,14 +114,14 @@ SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
8192
'#------------------FN_DYNVARS_005_06-----------------------#'
SELECT @@global.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
SELECT @@global.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='query_prealloc_size ';
@@global.query_prealloc_size = VARIABLE_VALUE
1
'#------------------FN_DYNVARS_005_07-----------------------#'
SELECT @@session.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
SELECT @@session.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='query_prealloc_size ';
@@session.query_prealloc_size = VARIABLE_VALUE
1

View File

@ -35,10 +35,6 @@ SET @@global.query_prealloc_size = 8192;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
8192
SET @@global.query_prealloc_size = 4294967295;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
4294966272
SET @@global.query_prealloc_size = 655354;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
@ -48,10 +44,6 @@ SET @@session.query_prealloc_size = 8192;
SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
8192
SET @@session.query_prealloc_size = 4294967295;
SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
4294966272
SET @@session.query_prealloc_size = 655345;
SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
@ -69,35 +61,31 @@ Warning 1292 Truncated incorrect query_prealloc_size value: '0'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
8192
SET @@global.query_prealloc_size = 429496729533;
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
429496728576
SET @@global.query_prealloc_size = 65530.34.;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
429496728576
8192
SET @@global.query_prealloc_size = test;
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
429496728576
8192
SET @@global.query_prealloc_size = "test";
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
429496728576
8192
SET @@global.query_prealloc_size = 'test';
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
429496728576
8192
SET @@global.query_prealloc_size = ON;
ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
SELECT @@global.query_prealloc_size ;
@@global.query_prealloc_size
429496728576
8192
SET @@session.query_prealloc_size = 0;
Warnings:
Warning 1292 Truncated incorrect query_prealloc_size value: '0'
@ -126,14 +114,14 @@ SELECT @@session.query_prealloc_size ;
@@session.query_prealloc_size
8192
'#------------------FN_DYNVARS_005_06-----------------------#'
SELECT @@global.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
SELECT @@global.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='query_prealloc_size ';
@@global.query_prealloc_size = VARIABLE_VALUE
1
'#------------------FN_DYNVARS_005_07-----------------------#'
SELECT @@session.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
SELECT @@session.query_prealloc_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='query_prealloc_size ';
@@session.query_prealloc_size = VARIABLE_VALUE
1

View File

@ -9,42 +9,5 @@ stop slave;
change master to master_port=SLAVE_PORT;
start slave;
*** must be having the replicate-same-server-id IO thread error ***
show slave status;
Slave_IO_State
Master_Host 127.0.0.1
Master_User root
Master_Port SLAVE_PORT
Connect_Retry 1
Master_Log_File
Read_Master_Log_Pos 4
Relay_Log_File slave-relay-bin.000001
Relay_Log_Pos 4
Relay_Master_Log_File
Slave_IO_Running No
Slave_SQL_Running #
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table #
Last_Errno #
Last_Error #
Skip_Counter 0
Exec_Master_Log_Pos 0
Relay_Log_Space 106
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master NULL
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 1593
Last_IO_Error Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
Last_SQL_Errno #
Last_SQL_Error #
Slave_IO_Errno= 1593
Slave_IO_Error= Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

View File

@ -76,9 +76,9 @@ drop table t1,t2;
create temporary table t3 (f int);
create temporary table t4 (f int);
create table t5 (f int);
select id from information_schema.processlist where command='Binlog Dump' into @id;
kill @id;
stop slave;
insert into t5 select * from t4;
start slave;
select * from t5 /* must be 1 after reconnection */;
f
drop temporary table t4;

View File

@ -12,4 +12,4 @@
rpl_redirect : Failure is sporadic and and the test is superfluous (mats)
rpl_innodb_bug28430 : Failure on Solaris Bug #36793
rpl_server_id1 : Bug #36818 rpl_server_id1 fails expecting slave has stopped (azundris)
rpl_temporary : BUG#38269 2008-07-21 Sven valgrind error in pushbuild

View File

@ -10,17 +10,15 @@ reset master;
# replicate ourselves
stop slave;
source include/wait_for_slave_to_stop.inc;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval change master to master_port=$SLAVE_MYPORT;
start slave;
let $slave_param= Last_IO_Errno;
let $slave_param_value= 1593;
source include/wait_for_slave_param.inc;
--echo *** must be having the replicate-same-server-id IO thread error ***
source include/wait_for_slave_io_to_stop.inc;
--replace_result $SLAVE_MYPORT SLAVE_PORT
--replace_column 12 # 16 # 19 # 20 # 18 # 37 # 38 #
query_vertical show slave status;
# End of 4.1 tests
let $last_io_errno= query_get_value("show slave status", Last_IO_Errno, 1);
let $last_io_error= query_get_value("show slave status", Last_IO_Error, 1);
echo Slave_IO_Errno= $last_io_errno;
echo Slave_IO_Error= $last_io_error;

View File

@ -138,20 +138,21 @@ sync_slave_with_master;
#
# Bug#17284 erroneous temp table cleanup on slave
# The test targets at verifying that reconnected slave
# retained the former session's temporary tables
#
connection master;
create temporary table t4 (f int);
create table t5 (f int);
sync_slave_with_master;
# connection slave
stop slave; # to prepare for reconnecting w/o waiting for timeout
connection master;
# find dumper's $id
select id from information_schema.processlist where command='Binlog Dump' into @id;
kill @id; # to stimulate reconnection by slave w/o timeout
insert into t5 select * from t4;
save_master_pos;
connection slave;
start slave;
sync_with_master;
select * from t5 /* must be 1 after reconnection */;

View File

@ -6,6 +6,9 @@
# the data is actually in the table).
set @old_concurrent_insert= @@global.concurrent_insert;
set @@global.concurrent_insert= 0;
--disable_warnings
drop table if exists t1;
--enable_warnings
# Test of the xml output of the 'mysql' and 'mysqldump' clients -- makes
# sure that basic encoding issues are handled properly

View File

@ -11,7 +11,6 @@
##############################################################################
federated_transactions : Bug#29523 Transactions do not work
csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
user_limits : Bug#23921 random failure of user_limits.test
thread_cache_size_func : Bug#36733 main.thread_cache_size_func fails randomly
binlog_cache_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
bulk_insert_buffer_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
@ -95,3 +94,6 @@ tmp_table_size_basic_64 : Bug #36522: Some tests of system variabl
transaction_alloc_block_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
transaction_prealloc_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
wait_timeout_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
log_tables.test : Bug #37798: main.log_tables fails randomly on powermacg5 and windows
slow_query_log_func.test : Bug #37962: *_func tests containing sleeps/race conditions

View File

@ -417,4 +417,13 @@ insert into t1 values (),(),(),(),(),(),(),(),(),();
select a from t1 where a not in (a,a,a) group by a;
drop table t1;
#
# Bug #37761: IN handles NULL differently for table-subquery and value-list
#
create table t1 (id int);
select * from t1 where NOT id in (select null union all select 1);
select * from t1 where NOT id in (null, 1);
drop table t1;
--echo End of 5.1 tests

View File

@ -60,12 +60,6 @@ use test//
show tables//
delimiter ; # Reset delimiter
#
# Bug #33812: mysql client incorrectly parsing DELIMITER
#
select a as delimiter from t1
delimiter ; # Reset delimiter
#
# Bug #36244: MySQL CLI doesn't recognize standalone -- as comment
# before DELIMITER statement

View File

@ -91,6 +91,10 @@ select otto from (select 1 as otto) as t1;
--error 1
--exec echo "error S42S22; select otto from (select 1 as otto) as t1;" | $MYSQL_TEST 2>&1
# expecting a SQL-state for a command that can't give one should fail
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1
--exec echo "error S00000; remove_file $MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp;" | $MYSQL_TEST 2>&1
# ----------------------------------------------------------------------------

View File

@ -0,0 +1,402 @@
# Copyright (C) 2008 Sun Microsystems, Inc
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# These tests are designed to cause an internal parser stack overflow,
# and trigger my_yyoverflow().
#
use test;
SELECT
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
1
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
;
prepare stmt from
"
SELECT
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
1
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
"
;
execute stmt;
--disable_warnings
drop view if exists view_overflow;
--enable_warnings
CREATE VIEW view_overflow AS
SELECT
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
1
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
;
SELECT * from view_overflow;
drop view view_overflow;
--disable_warnings
drop procedure if exists proc_overflow;
--enable_warnings
delimiter $$;
CREATE PROCEDURE proc_overflow()
BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
select 1;
select 2;
select 3;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END $$
delimiter ;$$
call proc_overflow();
drop procedure proc_overflow;
--disable_warnings
drop function if exists func_overflow;
--enable_warnings
delimiter $$;
create function func_overflow() returns int
BEGIN
DECLARE x int default 0;
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
SET x=x+1;
SET x=x+2;
SET x=x+3;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
return x;
END $$
delimiter ;$$
select func_overflow();
drop function func_overflow;
--disable_warnings
drop table if exists table_overflow;
--enable_warnings
create table table_overflow(a int, b int);
delimiter $$;
create trigger trigger_overflow before insert on table_overflow
for each row
BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
SET NEW.b := NEW.a;
SET NEW.b := NEW.b + 1;
SET NEW.b := NEW.b + 2;
SET NEW.b := NEW.b + 3;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END; END; END; END; END; END; END; END; END; END; END; END;
END $$
delimiter ;$$
insert into table_overflow set a=10;
insert into table_overflow set a=20;
select * from table_overflow;
drop table table_overflow;
--disable_warnings
drop procedure if exists proc_35577;
--enable_warnings
delimiter $$;
CREATE PROCEDURE proc_35577()
BEGIN
DECLARE z_done INT DEFAULT 0;
DECLARE t_done VARCHAR(5000);
outer_loop: LOOP
IF t_done=1 THEN
LEAVE outer_loop;
END IF;
inner_block:BEGIN
DECLARE z_done INT DEFAULT 0;
SET z_done = 0;
inner_loop: LOOP
IF z_done=1 THEN
LEAVE inner_loop;
END IF;
IF (t_done = 'a') THEN
IF (t_done <> 0) THEN
IF ( t_done > 0) THEN
IF (t_done = 'a') THEN
SET t_done = 'a';
ELSEIF (t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
ELSEIF(t_done = 'a') THEN
SET t_done = 'a';
END IF;
END IF;
END IF;
END IF;
END LOOP inner_loop;
END inner_block;
END LOOP outer_loop;
END $$
delimiter ;$$
drop procedure proc_35577;
#
# Bug#37269 (parser crash when creating stored procedure)
#
--disable_warnings
drop procedure if exists p_37269;
--enable_warnings
delimiter $$;
create procedure p_37269()
begin
declare done int default 0;
declare varb int default 0;
declare vara int default 0;
repeat
select now();
until done end repeat;
while varb do
select now();
begin
select now();
repeat
select now();
until done end repeat;
if vara then
select now();
repeat
select now();
loop
select now();
end loop;
repeat
select now();
label1: while varb do
select now();
end while label1;
if vara then
select now();
repeat
select now();
until done end repeat;
begin
select now();
while varb do
select now();
label1: while varb do
select now();
end while label1;
if vara then
select now();
while varb do
select now();
loop
select now();
end loop;
repeat
select now();
loop
select now();
while varb do
select now();
end while;
repeat
select now();
label1: loop
select now();
if vara then
select now();
end if;
end loop label1;
until done end repeat;
end loop;
until done end repeat;
end while;
end if;
end while;
end;
end if;
until done end repeat;
until done end repeat;
end if;
end;
end while;
end $$
delimiter ;$$
drop procedure p_37269;
#
# Bug#37228 (Sever crashes when creating stored procedure with more than
# 10 IF/ELSEIF)
#
--disable_warnings
drop procedure if exists p_37228;
--enable_warnings
delimiter $$;
create procedure p_37228 ()
BEGIN
DECLARE v INT DEFAULT 123;
IF (v > 1) THEN SET v = 1;
ELSEIF (v < 10) THEN SET v = 10;
ELSEIF (v < 11) THEN SET v = 11;
ELSEIF (v < 12) THEN SET v = 12;
ELSEIF (v < 13) THEN SET v = 13;
ELSEIF (v < 14) THEN SET v = 14;
ELSEIF (v < 15) THEN SET v = 15;
ELSEIF (v < 16) THEN SET v = 16;
ELSEIF (v < 17) THEN SET v = 17;
ELSEIF (v < 18) THEN SET v = 18;
ELSEIF (v < 19) THEN SET v = 19;
ELSEIF (v < 20) THEN SET v = 20;
ELSEIF (v < 21) THEN SET v = 21;
ELSEIF (v < 22) THEN SET v = 22;
ELSEIF (v < 23) THEN SET v = 23;
ELSEIF (v < 24) THEN SET v = 24;
ELSEIF (v < 25) THEN SET v = 25;
ELSEIF (v < 26) THEN SET v = 26;
ELSEIF (v < 27) THEN SET v = 27;
ELSEIF (v < 28) THEN SET v = 28;
ELSEIF (v < 29) THEN SET v = 29;
ELSEIF (v < 30) THEN SET v = 30;
ELSEIF (v < 31) THEN SET v = 31;
ELSEIF (v < 32) THEN SET v = 32;
ELSEIF (v < 33) THEN SET v = 33;
ELSEIF (v < 34) THEN SET v = 34;
ELSEIF (v < 35) THEN SET v = 35;
ELSEIF (v < 36) THEN SET v = 36;
ELSEIF (v < 37) THEN SET v = 37;
ELSEIF (v < 38) THEN SET v = 38;
ELSEIF (v < 39) THEN SET v = 39;
END IF;
END $$
delimiter ;$$
drop procedure p_37228;

View File

@ -1439,10 +1439,10 @@ Event_job_data::execute(THD *thd, bool drop)
thd->query_length= sp_sql.length();
{
Lex_input_stream lip(thd, thd->query, thd->query_length);
Parser_state parser_state(thd, thd->query, thd->query_length);
lex_start(thd);
if (parse_sql(thd, &lip, creation_ctx))
if (parse_sql(thd, & parser_state, creation_ctx))
{
sql_print_error("Event Scheduler: "
"%serror during compilation of %s.%s",

View File

@ -452,7 +452,7 @@ Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table,
READ_RECORD read_record_info;
DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s");
init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE);
/*
rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
@ -925,7 +925,7 @@ Event_db_repository::drop_events_by_field(THD *thd,
DBUG_VOID_RETURN;
/* only enabled events are in memory, so we go now and delete the rest */
init_read_record(&read_record_info, thd, table, NULL, 1, 0);
init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE);
while (!ret && !(read_record_info.read_record(&read_record_info)) )
{
char *et_field= get_field(thd->mem_root, table->field[field]);

View File

@ -1149,7 +1149,7 @@ Events::load_events_from_db(THD *thd)
DBUG_RETURN(TRUE);
}
init_read_record(&read_record_info, thd, table, NULL, 0, 1);
init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE);
while (!(read_record_info.read_record(&read_record_info)))
{
Event_queue_element *et;

View File

@ -6644,6 +6644,7 @@ struct Check_field_param {
Field *field;
};
#ifdef HAVE_REPLICATION
static bool
check_field_for_37426(const void *param_arg)
{
@ -6655,7 +6656,7 @@ check_field_for_37426(const void *param_arg)
param->field->row_pack_length()));
return param->field->row_pack_length() > 255;
}
#endif
int Field_string::compatible_field_size(uint field_metadata,
const Relay_log_info *rli_arg)

View File

@ -410,6 +410,56 @@ static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
DBUG_RETURN(tmp);
}
#ifndef DBUG_OFF
/*
Print a text, SQL-like record representation into dbug trace.
Note: this function is a work in progress: at the moment
- column read bitmap is ignored (can print garbage for unused columns)
- there is no quoting
*/
static void dbug_print_record(TABLE *table, bool print_rowid)
{
char buff[1024];
Field **pfield;
String tmp(buff,sizeof(buff),&my_charset_bin);
DBUG_LOCK_FILE;
fprintf(DBUG_FILE, "record (");
for (pfield= table->field; *pfield ; pfield++)
fprintf(DBUG_FILE, "%s%s", (*pfield)->field_name, (pfield[1])? ", ":"");
fprintf(DBUG_FILE, ") = ");
fprintf(DBUG_FILE, "(");
for (pfield= table->field; *pfield ; pfield++)
{
Field *field= *pfield;
if (field->is_null())
fwrite("NULL", sizeof(char), 4, DBUG_FILE);
if (field->type() == MYSQL_TYPE_BIT)
(void) field->val_int_as_str(&tmp, 1);
else
field->val_str(&tmp);
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
if (pfield[1])
fwrite(", ", sizeof(char), 2, DBUG_FILE);
}
fprintf(DBUG_FILE, ")");
if (print_rowid)
{
fprintf(DBUG_FILE, " rowid ");
for (uint i=0; i < table->file->ref_length; i++)
{
fprintf(DBUG_FILE, "%x", (uchar)table->file->ref[i]);
}
}
fprintf(DBUG_FILE, "\n");
DBUG_UNLOCK_FILE;
}
#endif
/**
Search after sort_keys and write them into tempfile.
@ -488,13 +538,10 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
current_thd->variables.read_buff_size);
}
READ_RECORD read_record_info;
if (quick_select)
{
if (select->quick->reset())
DBUG_RETURN(HA_POS_ERROR);
init_read_record(&read_record_info, current_thd, select->quick->head,
select, 1, 1);
}
/* Remember original bitmaps */
@ -514,12 +561,13 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
{
if (quick_select)
{
if ((error= read_record_info.read_record(&read_record_info)))
if ((error= select->quick->get_next()))
{
error= HA_ERR_END_OF_FILE;
break;
}
file->position(sort_form->record[0]);
DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
}
else /* Not quick-select */
{
@ -576,15 +624,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
if (thd->is_error())
break;
}
if (quick_select)
{
/*
index_merge quick select uses table->sort when retrieving rows, so free
resoures it has allocated.
*/
end_read_record(&read_record_info);
}
else
if (!quick_select)
{
(void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */
if (!next_pos)

View File

@ -1618,23 +1618,23 @@ bool mysql_xa_recover(THD *thd)
@return
always 0
*/
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
void *unused)
{
handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
hton->release_temporary_latches(hton, thd);
return FALSE;
}
int ha_release_temporary_latches(THD *thd)
{
plugin_foreach(thd, release_temporary_latches, MYSQL_STORAGE_ENGINE_PLUGIN,
NULL);
Ha_trx_info *info;
/*
Note that below we assume that only transactional storage engines
may need release_temporary_latches(). If this will ever become false,
we could iterate on thd->open_tables instead (and remove duplicates
as if (!seen[hton->slot]) { seen[hton->slot]=1; ... }).
*/
for (info= thd->transaction.stmt.ha_list; info; info= info->next())
{
handlerton *hton= info->ht();
if (hton && hton->release_temporary_latches)
hton->release_temporary_latches(hton, thd);
}
return 0;
}

View File

@ -3758,6 +3758,7 @@ longlong Item_func_in::val_int()
return (longlong) (!null_value && tmp != negated);
}
have_null= 0;
for (uint i= 1 ; i < arg_count ; i++)
{
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
@ -3766,9 +3767,8 @@ longlong Item_func_in::val_int()
if (!(value_added_map & (1 << (uint)cmp_type)))
{
in_item->store_value(args[0]);
if ((null_value=args[0]->null_value))
if ((null_value= args[0]->null_value))
return 0;
have_null= 0;
value_added_map|= 1 << (uint)cmp_type;
}
if (!in_item->cmp(args[i]) && !args[i]->null_value)

View File

@ -3070,6 +3070,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
int ret = 0;
bool exit_loop= 0;
LOG_INFO log_info;
THD *thd= current_thd;
DBUG_ENTER("purge_logs");
DBUG_PRINT("info",("to_log= %s",to_log));
@ -3095,10 +3096,13 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
/*
It's not fatal if we can't stat a log file that does not exist;
If we could not stat, we won't delete.
*/
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
*/
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to execute my_stat on file '%s'",
log_info.log_file_name);
my_errno= 0;
@ -3108,13 +3112,24 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
/*
Other than ENOENT are fatal
*/
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with getting info on being purged %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with getting info on being purged %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
else
{
sql_print_information("Failed to delete log file '%s'; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
error= LOG_INFO_FATAL;
goto err;
}
@ -3131,27 +3146,42 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
{
if (my_errno == ENOENT)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to delete file '%s'",
log_info.log_file_name);
my_errno= 0;
}
else
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
else
{
sql_print_information("Failed to delete file '%s'; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
if (my_errno == EMFILE)
{
DBUG_PRINT("info",
("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
error= LOG_INFO_EMFILE;
goto err;
}
error= LOG_INFO_FATAL;
goto err;
@ -3204,7 +3234,8 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
int error;
LOG_INFO log_info;
MY_STAT stat_area;
THD *thd= current_thd;
DBUG_ENTER("purge_logs_before_date");
pthread_mutex_lock(&LOCK_index);
@ -3226,12 +3257,15 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
{
/*
It's not fatal if we can't stat a log file that does not exist.
*/
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
sql_print_information("Failed to execute my_stat on file '%s'",
log_info.log_file_name);
*/
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to execute my_stat on file '%s'",
log_info.log_file_name);
my_errno= 0;
}
else
@ -3239,13 +3273,21 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
/*
Other than ENOENT are fatal
*/
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with getting info on being purged %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with getting info on being purged %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
else
{
sql_print_information("Failed to delete log file '%s'",
log_info.log_file_name);
}
error= LOG_INFO_FATAL;
goto err;
}
@ -3259,22 +3301,33 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
if (my_errno == ENOENT)
{
/* It's not fatal even if we can't delete a log file */
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to delete file '%s'",
log_info.log_file_name);
my_errno= 0;
}
else
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
else
{
sql_print_information("Failed to delete log file '%s'",
log_info.log_file_name);
}
error= LOG_INFO_FATAL;
goto err;
}

View File

@ -44,6 +44,8 @@
#include "sql_plugin.h"
#include "scheduler.h"
class Parser_state;
/**
Query type constants.
@ -804,8 +806,8 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
bool test_if_data_home_dir(const char *dir);
bool parse_sql(THD *thd,
class Lex_input_stream *lip,
class Object_creation_ctx *creation_ctx);
Parser_state *parser_state,
Object_creation_ctx *creation_ctx);
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
@ -2173,8 +2175,8 @@ ulonglong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(uchar *,uint,char,char);
void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
SQL_SELECT *select,
int use_record_cache, bool print_errors);
SQL_SELECT *select, int use_record_cache,
bool print_errors, bool disable_rr_cache);
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bool print_error, uint idx);
void end_read_record(READ_RECORD *info);

View File

@ -7936,6 +7936,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
handler *file= head->file;
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
/* We're going to just read rowids. */
file->extra(HA_EXTRA_KEYREAD);
head->prepare_for_position();
@ -7994,15 +7995,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
}
DBUG_PRINT("info", ("ok"));
/* ok, all row ids are in Unique */
/*
Ok all rowids are in the Unique now. The next call will initialize
head->sort structure so it can be used to iterate through the rowids
sequence.
*/
result= unique->get(head);
delete unique;
doing_pk_scan= FALSE;
/* index_merge currently doesn't support "using index" at all */
file->extra(HA_EXTRA_NO_KEYREAD);
/* start table scan */
init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
DBUG_RETURN(result);
}
@ -8028,6 +8031,7 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
{
result= HA_ERR_END_OF_FILE;
end_read_record(&read_record);
free_io_cache(head);
/* All rows from Unique have been retrieved, do a clustered PK scan */
if (pk_quick_select)
{
@ -8556,7 +8560,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;
@ -8598,10 +8603,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, 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, last_range->min_key,
last_range->min_length) :
file->index_prev(record));
if (!result)
{
if (cmp_prev(*rev_it.ref()) == 0)
@ -8625,7 +8631,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_map(record, last_range->max_key,
last_range->max_keypart_map,
@ -8634,6 +8642,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_map(record, last_range->max_key,
last_range->max_keypart_map,
@ -8731,54 +8741,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

@ -686,12 +686,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

@ -86,6 +86,23 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
The temporary file is normally used when the references doesn't fit into
a properly sized memory buffer. For most small queries the references
are stored in the memory buffer.
SYNOPSIS
init_read_record()
info OUT read structure
thd Thread handle
table Table the data [originally] comes from.
select SQL_SELECT structure. We may select->quick or
select->file as data source
use_record_cache Call file->extra_opt(HA_EXTRA_CACHE,...)
if we're going to do sequential read and some
additional conditions are satisfied.
print_error Copy this to info->print_error
disable_rr_cache Don't use rr_from_cache (used by sort-union
index-merge which produces rowid sequences that
are already ordered)
DESCRIPTION
This function sets up reading data via one of the methods:
The temporary file is also used when performing an update where a key is
modified.
@ -140,7 +157,8 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
*/
void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
SQL_SELECT *select,
int use_record_cache, bool print_error)
int use_record_cache, bool print_error,
bool disable_rr_cache)
{
IO_CACHE *tempfile;
DBUG_ENTER("init_read_record");
@ -191,7 +209,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
it doesn't make sense to use cache - we don't read from the table
and table->sort.io_cache is read sequentially
*/
if (!table->sort.addon_field &&
if (!disable_rr_cache &&
!table->sort.addon_field &&
! (specialflag & SPECIAL_SAFE_MODE) &&
thd->variables.read_rnd_buff_size &&
!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&

View File

@ -617,12 +617,12 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
thd->spcont= NULL;
{
Lex_input_stream lip(thd, defstr.c_ptr(), defstr.length());
Parser_state parser_state(thd, defstr.c_ptr(), defstr.length());
lex_start(thd);
thd->push_internal_handler(&warning_handler);
ret= parse_sql(thd, &lip, creation_ctx) || newlex.sphead == NULL;
ret= parse_sql(thd, & parser_state, creation_ctx) || newlex.sphead == NULL;
thd->pop_internal_handler();
/*

View File

@ -627,14 +627,14 @@ void
sp_head::set_body_start(THD *thd, const char *begin_ptr)
{
m_body_begin= begin_ptr;
thd->m_lip->body_utf8_start(thd, begin_ptr);
thd->m_parser_state->m_lip.body_utf8_start(thd, begin_ptr);
}
void
sp_head::set_stmt_end(THD *thd)
{
Lex_input_stream *lip= thd->m_lip; /* shortcut */
Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
/* Make the string of parameters. */

View File

@ -324,7 +324,8 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
acl_cache->clear(1); // Clear locked hostname cache
init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0,
FALSE);
table->use_all_columns();
VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50));
while (!(read_record_info.read_record(&read_record_info)))
@ -373,7 +374,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
end_read_record(&read_record_info);
freeze_size(&acl_hosts);
init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0);
init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE);
table->use_all_columns();
VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100));
password_length= table->field[2]->field_length /
@ -561,7 +562,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
end_read_record(&read_record_info);
freeze_size(&acl_users);
init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0);
init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE);
table->use_all_columns();
VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100));
while (!(read_record_info.read_record(&read_record_info)))

View File

@ -529,7 +529,7 @@ THD::THD()
bootstrap(0),
derived_tables_processing(FALSE),
spcont(NULL),
m_lip(NULL)
m_parser_state(NULL)
{
ulong tmp;

View File

@ -75,7 +75,7 @@ class Load_log_event;
class Slave_log_event;
class sp_rcontext;
class sp_cache;
class Lex_input_stream;
class Parser_state;
class Rows_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
@ -1771,13 +1771,11 @@ public:
} binlog_evt_union;
/**
Character input stream consumed by the lexical analyser,
used during parsing.
Note that since the parser is not re-entrant, we keep only one input
stream here. This member is valid only when executing code during parsing,
and may point to invalid memory after that.
Internal parser state.
Note that since the parser is not re-entrant, we keep only one parser
state here. This member is valid only when executing code during parsing.
*/
Lex_input_stream *m_lip;
Parser_state *m_parser_state;
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *work_part_info;

View File

@ -245,7 +245,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE);
}
if (usable_index==MAX_KEY)
init_read_record(&info,thd,table,select,1,1);
init_read_record(&info, thd, table, select, 1, 1, FALSE);
else
init_read_record_idx(&info, thd, table, 1, usable_index);
@ -834,7 +834,7 @@ int multi_delete::do_deletes()
}
READ_RECORD info;
init_read_record(&info,thd,table,NULL,0,1);
init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
/*
Ignore any rows not found in reference tables as they may already have
been deleted by foreign key handling

View File

@ -186,7 +186,7 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields,
int count= 0;
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, topics, select,1,0);
init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE);
while (!read_record_info.read_record(&read_record_info))
{
if (!select->cond->val_int()) // Doesn't match like
@ -226,7 +226,7 @@ int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields,
int count= 0;
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, keywords, select,1,0);
init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE);
while (!read_record_info.read_record(&read_record_info) && count<2)
{
if (!select->cond->val_int()) // Dosn't match like
@ -350,7 +350,7 @@ int search_categories(THD *thd, TABLE *categories,
DBUG_ENTER("search_categories");
init_read_record(&read_record_info, thd, categories, select,1,0);
init_read_record(&read_record_info, thd, categories, select,1,0,FALSE);
while (!read_record_info.read_record(&read_record_info))
{
if (select && !select->cond->val_int())
@ -384,7 +384,7 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
DBUG_ENTER("get_all_items_for_category");
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, items, select,1,0);
init_read_record(&read_record_info, thd, items, select,1,0,FALSE);
while (!read_record_info.read_record(&read_record_info))
{
if (!select->cond->val_int())

View File

@ -371,13 +371,6 @@ void lex_end(LEX *lex)
{
DBUG_ENTER("lex_end");
DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
if (lex->yacc_yyss)
{
my_free(lex->yacc_yyss, MYF(0));
my_free(lex->yacc_yyvs, MYF(0));
lex->yacc_yyss= 0;
lex->yacc_yyvs= 0;
}
/* release used plugins */
plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer,
@ -387,6 +380,14 @@ void lex_end(LEX *lex)
DBUG_VOID_RETURN;
}
Yacc_state::~Yacc_state()
{
if (yacc_yyss)
{
my_free(yacc_yyss, MYF(0));
my_free(yacc_yyvs, MYF(0));
}
}
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
{
@ -726,7 +727,7 @@ int MYSQLlex(void *arg, void *yythd)
uint length;
enum my_lex_states state;
THD *thd= (THD *)yythd;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
LEX *lex= thd->lex;
YYSTYPE *yylval=(YYSTYPE*) arg;
CHARSET_INFO *cs= thd->charset();
@ -2128,7 +2129,7 @@ void Query_tables_list::destroy_query_tables_list()
*/
st_lex::st_lex()
:result(0), yacc_yyss(0), yacc_yyvs(0),
:result(0),
sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
{

View File

@ -1513,7 +1513,6 @@ typedef struct st_lex : public Query_tables_list
LEX_STRING comment, ident;
LEX_USER *grant_user;
XID *xid;
uchar* yacc_yyss, *yacc_yyvs;
THD *thd;
/* maintain a list of used plugins for this LEX */
@ -1847,6 +1846,59 @@ typedef struct st_lex : public Query_tables_list
}
} LEX;
/**
The internal state of the syntax parser.
This object is only available during parsing,
and is private to the syntax parser implementation (sql_yacc.yy).
*/
class Yacc_state
{
public:
Yacc_state()
: yacc_yyss(NULL), yacc_yyvs(NULL)
{}
~Yacc_state();
/**
Bison internal state stack, yyss, when dynamically allocated using
my_yyoverflow().
*/
uchar *yacc_yyss;
/**
Bison internal semantic value stack, yyvs, when dynamically allocated using
my_yyoverflow().
*/
uchar *yacc_yyvs;
/*
TODO: move more attributes from the LEX structure here.
*/
};
/**
Internal state of the parser.
The complete state consist of:
- state data used during lexical parsing,
- state data used during syntactic parsing.
*/
class Parser_state
{
public:
Parser_state(THD *thd, const char* buff, unsigned int length)
: m_lip(thd, buff, length), m_yacc()
{}
~Parser_state()
{}
Lex_input_stream m_lip;
Yacc_state m_yacc;
};
struct st_lex_local: public st_lex
{
static void *operator new(size_t size) throw()

View File

@ -5323,29 +5323,35 @@ bool check_stack_overrun(THD *thd, long margin,
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
{
LEX *lex= current_thd->lex;
Yacc_state *state= & current_thd->m_parser_state->m_yacc;
ulong old_info=0;
DBUG_ASSERT(state);
if ((uint) *yystacksize >= MY_YACC_MAX)
return 1;
if (!lex->yacc_yyvs)
if (!state->yacc_yyvs)
old_info= *yystacksize;
*yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
if (!(lex->yacc_yyvs= (uchar*)
my_realloc(lex->yacc_yyvs,
*yystacksize*sizeof(**yyvs),
MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
!(lex->yacc_yyss= (uchar*)
my_realloc(lex->yacc_yyss,
*yystacksize*sizeof(**yyss),
MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
if (!(state->yacc_yyvs= (uchar*)
my_realloc(state->yacc_yyvs,
*yystacksize*sizeof(**yyvs),
MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
!(state->yacc_yyss= (uchar*)
my_realloc(state->yacc_yyss,
*yystacksize*sizeof(**yyss),
MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
return 1;
if (old_info)
{ // Copy old info from stack
memcpy(lex->yacc_yyss, (uchar*) *yyss, old_info*sizeof(**yyss));
memcpy(lex->yacc_yyvs, (uchar*) *yyvs, old_info*sizeof(**yyvs));
{
/*
Only copy the old stack on the first call to my_yyoverflow(),
when replacing a static stack (YYINITDEPTH) by a dynamic stack.
For subsequent calls, my_realloc already did preserve the old stack.
*/
memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
}
*yyss=(short*) lex->yacc_yyss;
*yyvs=(YYSTYPE*) lex->yacc_yyvs;
*yyss= (short*) state->yacc_yyss;
*yyvs= (YYSTYPE*) state->yacc_yyvs;
return 0;
}
@ -5609,10 +5615,10 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
Lex_input_stream lip(thd, inBuf, length);
Parser_state parser_state(thd, inBuf, length);
bool err= parse_sql(thd, &lip, NULL);
*found_semicolon= lip.found_semicolon;
bool err= parse_sql(thd, & parser_state, NULL);
*found_semicolon= parser_state.m_lip.found_semicolon;
if (!err)
{
@ -5697,11 +5703,11 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
bool error= 0;
DBUG_ENTER("mysql_test_parse_for_slave");
Lex_input_stream lip(thd, inBuf, length);
Parser_state parser_state(thd, inBuf, length);
lex_start(thd);
mysql_reset_thd_for_next_command(thd);
if (!parse_sql(thd, &lip, NULL) &&
if (!parse_sql(thd, & parser_state, NULL) &&
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
error= 1; /* Ignore question */
thd->end_statement();
@ -6740,7 +6746,7 @@ bool check_simple_select()
if (lex->current_select != &lex->select_lex)
{
char command[80];
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
strmake(command, lip->yylval->symbol.str,
min(lip->yylval->symbol.length, sizeof(command)-1));
my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
@ -7417,7 +7423,7 @@ extern int MYSQLparse(void *thd); // from sql_yacc.cc
instead of MYSQLparse().
@param thd Thread context.
@param lip Lexer context.
@param parser_state Parser state.
@param creation_ctx Object creation context.
@return Error status.
@ -7426,10 +7432,10 @@ extern int MYSQLparse(void *thd); // from sql_yacc.cc
*/
bool parse_sql(THD *thd,
Lex_input_stream *lip,
Parser_state *parser_state,
Object_creation_ctx *creation_ctx)
{
DBUG_ASSERT(thd->m_lip == NULL);
DBUG_ASSERT(thd->m_parser_state == NULL);
/* Backup creation context. */
@ -7438,9 +7444,9 @@ bool parse_sql(THD *thd,
if (creation_ctx)
backup_ctx= creation_ctx->set_n_backup(thd);
/* Set Lex_input_stream. */
/* Set parser state. */
thd->m_lip= lip;
thd->m_parser_state= parser_state;
/* Parse the query. */
@ -7451,9 +7457,9 @@ bool parse_sql(THD *thd,
DBUG_ASSERT(!mysql_parse_status ||
mysql_parse_status && thd->is_error());
/* Reset Lex_input_stream. */
/* Reset parser state. */
thd->m_lip= NULL;
thd->m_parser_state= NULL;
/* Restore creation context. */

View File

@ -3767,7 +3767,7 @@ bool mysql_unpack_partition(THD *thd,
thd->lex= &lex;
thd->variables.character_set_client= system_charset_info;
Lex_input_stream lip(thd, part_buf, part_info_len);
Parser_state parser_state(thd, part_buf, part_info_len);
lex_start(thd);
*work_part_info_used= false;
@ -3797,7 +3797,7 @@ bool mysql_unpack_partition(THD *thd,
lex.part_info->part_state= part_state;
lex.part_info->part_state_len= part_state_len;
DBUG_PRINT("info", ("Parse: %s", part_buf));
if (parse_sql(thd, &lip, NULL))
if (parse_sql(thd, & parser_state, NULL))
{
thd->free_items();
goto end;

View File

@ -1361,7 +1361,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
goto end;
}
table= tables.table;
init_read_record(&read_record_info, new_thd, table, NULL, 1, 0);
init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE);
table->use_all_columns();
/*
there're no other threads running yet, so we don't need a mutex.
@ -1882,7 +1882,7 @@ static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
}
result= (int) tmp;
}
*(int*)save= -result;
*(my_bool *) save= -result;
return 0;
err:
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
@ -2063,7 +2063,7 @@ err:
static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save)
{
*(my_bool *) tgt= *(int *) save ? 1 : 0;
*(my_bool *) tgt= *(my_bool *) save ? TRUE : FALSE;
}

View File

@ -3017,11 +3017,11 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
Lex_input_stream lip(thd, thd->query, thd->query_length);
lip.stmt_prepare_mode= TRUE;
Parser_state parser_state(thd, thd->query, thd->query_length);
parser_state.m_lip.stmt_prepare_mode= TRUE;
lex_start(thd);
error= parse_sql(thd, &lip, NULL) ||
error= parse_sql(thd, & parser_state, NULL) ||
thd->is_error() ||
init_param_array(this);

View File

@ -11713,7 +11713,7 @@ join_init_read_record(JOIN_TAB *tab)
if (tab->select && tab->select->quick && tab->select->quick->reset())
return 1;
init_read_record(&tab->read_record, tab->join->thd, tab->table,
tab->select,1,1);
tab->select,1,1, FALSE);
return (*tab->read_record.read_record)(&tab->read_record);
}
@ -12508,6 +12508,9 @@ part_of_refkey(TABLE *table,Field *field)
@note
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.
@retval
1 key is ok.
@ -12580,11 +12583,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

@ -182,7 +182,8 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
free_root(&mem, MYF(0));
init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0);
init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0,
FALSE);
while (!(read_record_info.read_record(&read_record_info)))
{
/* return_val is already TRUE, so no need to set */

View File

@ -7113,7 +7113,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
/* Tell handler that we have values for all columns in the to table */
to->use_all_columns();
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
if (ignore)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0;

View File

@ -1287,7 +1287,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
thd->variables.sql_mode= (ulong)*trg_sql_mode;
Lex_input_stream lip(thd, trg_create_str->str, trg_create_str->length);
Parser_state parser_state(thd,
trg_create_str->str,
trg_create_str->length);
Trigger_creation_ctx *creation_ctx=
Trigger_creation_ctx::create(thd,
@ -1300,7 +1302,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
lex_start(thd);
thd->spcont= NULL;
if (parse_sql(thd, &lip, creation_ctx))
if (parse_sql(thd, & parser_state, creation_ctx))
{
/* Currently sphead is always deleted in case of a parse error */
DBUG_ASSERT(lex.sphead == 0);

View File

@ -152,7 +152,7 @@ void udf_init()
}
table= tables.table;
init_read_record(&read_record_info, new_thd, table, NULL,1,0);
init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE);
table->use_all_columns();
while (!(error= read_record_info.read_record(&read_record_info)))
{

View File

@ -457,7 +457,7 @@ int mysql_update(THD *thd,
*/
if (used_index == MAX_KEY || (select && select->quick))
init_read_record(&info,thd,table,select,0,1);
init_read_record(&info, thd, table, select, 0, 1, FALSE);
else
init_read_record_idx(&info, thd, table, 1, used_index);
@ -523,7 +523,7 @@ int mysql_update(THD *thd,
if (select && select->quick && select->quick->reset())
goto err;
table->file->try_semi_consistent_read(1);
init_read_record(&info,thd,table,select,0,1);
init_read_record(&info, thd, table, select, 0, 1, FALSE);
updated= found= 0;
/* Generate an error when trying to set a NOT NULL field to NULL. */

View File

@ -1147,9 +1147,9 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
char old_db_buf[NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
Lex_input_stream lip(thd,
table->select_stmt.str,
table->select_stmt.length);
Parser_state parser_state(thd,
table->select_stmt.str,
table->select_stmt.length);
/*
Use view db name as thread default database, in order to ensure
@ -1193,7 +1193,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
/* Parse the query. */
parse_status= parse_sql(thd, &lip, table->view_creation_ctx);
parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
/* Restore environment. */

View File

@ -28,6 +28,7 @@
#define YYPARSE_PARAM yythd
#define YYLEX_PARAM yythd
#define YYTHD ((THD *)yythd)
#define YYLIP (& YYTHD->m_parser_state->m_lip)
#define MYSQL_YACC
#define YYINITDEPTH 100
@ -121,7 +122,7 @@ const LEX_STRING null_lex_str= {0,0};
void my_parse_error(const char *s)
{
THD *thd= current_thd;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
const char *yytext= lip->get_tok_start();
/* Push an error into the error stack */
@ -1356,11 +1357,11 @@ query:
MYSQL_YYABORT;
}
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
thd->m_lip->found_semicolon= NULL;
YYLIP->found_semicolon= NULL;
}
| verb_clause
{
Lex_input_stream *lip = YYTHD->m_lip;
Lex_input_stream *lip = YYLIP;
if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
! lip->stmt_prepare_mode &&
@ -1386,7 +1387,7 @@ query:
| verb_clause END_OF_INPUT
{
/* Single query, not terminated. */
YYTHD->m_lip->found_semicolon= NULL;
YYLIP->found_semicolon= NULL;
}
;
@ -1917,7 +1918,7 @@ ev_sql_stmt:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
/*
This stops the following :
@ -2574,7 +2575,7 @@ sp_proc_stmt_statement:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
lex->sphead->reset_lex(thd);
lex->sphead->m_tmp_query= lip->get_tok_start();
@ -2583,7 +2584,7 @@ sp_proc_stmt_statement:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
sp_head *sp= lex->sphead;
sp->m_flags|= sp_get_flags_for_command(lex);
@ -6455,17 +6456,13 @@ select_item:
remember_name:
{
THD *thd= YYTHD;
Lex_input_stream *lip= thd->m_lip;
$$= (char*) lip->get_cpp_tok_start();
$$= (char*) YYLIP->get_cpp_tok_start();
}
;
remember_end:
{
THD *thd= YYTHD;
Lex_input_stream *lip= thd->m_lip;
$$= (char*) lip->get_cpp_tok_end();
$$= (char*) YYLIP->get_cpp_tok_end();
}
;
@ -9645,7 +9642,7 @@ load:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
@ -9686,10 +9683,7 @@ load_data:
}
opt_duplicate INTO
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->fname_end= lip->get_ptr();
Lex->fname_end= YYLIP->get_ptr();
}
TABLE_SYM table_ident
{
@ -9924,7 +9918,7 @@ param_marker:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
Item_param *item;
if (! lex->parsing_options.allows_variable)
{
@ -9956,7 +9950,7 @@ literal:
| NULL_SYM
{
$$ = new Item_null();
YYTHD->m_lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
}
| FALSE_SYM { $$= new Item_int((char*) "FALSE",0,1); }
| TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); }
@ -10086,7 +10080,7 @@ simple_ident:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
sp_variable_t *spv;
sp_pcontext *spc = lex->spcont;
if (spc && (spv = spc->find_variable(&$1)))
@ -10776,7 +10770,7 @@ option_type_value:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
@ -10807,7 +10801,7 @@ option_type_value:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
@ -12076,19 +12070,17 @@ view_select:
{
THD *thd= YYTHD;
LEX *lex= Lex;
Lex_input_stream *lip= thd->m_lip;
lex->parsing_options.allows_variable= FALSE;
lex->parsing_options.allows_select_into= FALSE;
lex->parsing_options.allows_select_procedure= FALSE;
lex->parsing_options.allows_derived= FALSE;
lex->create_view_select.str= (char *) lip->get_cpp_ptr();
lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr();
}
view_select_aux view_check_option
{
THD *thd= YYTHD;
LEX *lex= Lex;
Lex_input_stream *lip= thd->m_lip;
uint len= lip->get_cpp_ptr() - lex->create_view_select.str;
uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
void *create_view_select= thd->memdup(lex->create_view_select.str, len);
lex->create_view_select.length= len;
lex->create_view_select.str= (char *) create_view_select;
@ -12131,26 +12123,20 @@ trigger_tail:
ON
remember_name /* $7 */
{ /* $8 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->raw_trg_on_table_name_begin= lip->get_tok_start();
Lex->raw_trg_on_table_name_begin= YYLIP->get_tok_start();
}
table_ident /* $9 */
FOR_SYM
remember_name /* $11 */
{ /* $12 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->raw_trg_on_table_name_end= lip->get_tok_start();
Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start();
}
EACH_SYM
ROW_SYM
{ /* $15 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
sp_head *sp;
if (lex->sphead)
@ -12254,7 +12240,7 @@ sf_tail:
{ /* $5 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
sp_head *sp;
const char* tmp_param_begin;
@ -12282,11 +12268,7 @@ sf_tail:
sp_fdparam_list /* $6 */
')' /* $7 */
{ /* $8 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_param_end= lip->get_cpp_tok_start();
Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
}
RETURNS_SYM /* $9 */
{ /* $10 */
@ -12323,7 +12305,7 @@ sf_tail:
{ /* $14 */
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
Lex_input_stream *lip= YYLIP;
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
@ -12408,33 +12390,28 @@ sp_tail:
}
'('
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
const char* tmp_param_begin;
tmp_param_begin= lip->get_cpp_tok_start();
tmp_param_begin= YYLIP->get_cpp_tok_start();
tmp_param_begin++;
lex->sphead->m_param_begin= tmp_param_begin;
Lex->sphead->m_param_begin= tmp_param_begin;
}
sp_pdparam_list
')'
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_param_end= lip->get_cpp_tok_start();
lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
sp_c_chistics
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
Lex_input_stream *lip= thd->m_lip;
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
}
sp_proc_stmt
{