mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-base
into lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-rt-merge
This commit is contained in:
@@ -598,3 +598,97 @@ handler a2 read a last;
|
|||||||
handler a2 read a prev;
|
handler a2 read a prev;
|
||||||
handler a2 close;
|
handler a2 close;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#31397 Inconsistent drop table behavior of handler tables.
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
--enable_warnings
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
flush tables;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
handler t1_alias close;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
handler t1_alias read first;
|
||||||
|
drop table t1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler t1_alias read next;
|
||||||
|
|
||||||
|
# Test that temporary tables associated with handlers are properly dropped.
|
||||||
|
|
||||||
|
create table t1 (a int);
|
||||||
|
create temporary table t2 (a int, key(a));
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a2 read a first;
|
||||||
|
drop table t1, t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler a2 read a next;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler a1 close;
|
||||||
|
|
||||||
|
# Alter table drop handlers
|
||||||
|
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
create table t2 like t1;
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a1 read a first;
|
||||||
|
handler a2 read a first;
|
||||||
|
alter table t1 add b int;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler a1 close;
|
||||||
|
handler a2 close;
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
|
# Rename table drop handlers
|
||||||
|
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler a1 read a first;
|
||||||
|
rename table t1 to t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler a1 read a first;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
# Optimize table drop handlers
|
||||||
|
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
create table t2 like t1;
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a1 read a first;
|
||||||
|
handler a2 read a first;
|
||||||
|
optimize table t1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler a1 close;
|
||||||
|
handler a2 close;
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
|
# Flush tables causes handlers reopen
|
||||||
|
|
||||||
|
create table t1 (a int, b char(1), key a(a), key b(a,b));
|
||||||
|
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
|
||||||
|
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
|
||||||
|
handler t1 open;
|
||||||
|
handler t1 read a first;
|
||||||
|
handler t1 read a next;
|
||||||
|
flush tables;
|
||||||
|
handler t1 read a next;
|
||||||
|
handler t1 read a next;
|
||||||
|
flush tables with read lock;
|
||||||
|
handler t1 read a next;
|
||||||
|
unlock tables;
|
||||||
|
drop table t1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
handler t1 read a next;
|
||||||
|
@@ -3,6 +3,10 @@ drop database if exists mysqltest_db1;
|
|||||||
drop database if exists mysqltest_db2;
|
drop database if exists mysqltest_db2;
|
||||||
create database events_test;
|
create database events_test;
|
||||||
use events_test;
|
use events_test;
|
||||||
|
select * from information_schema.global_variables where variable_name like 'event_scheduler';
|
||||||
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
|
EVENT_SCHEDULER ON
|
||||||
|
SET GLOBAL event_scheduler = 'OFF';
|
||||||
CREATE EVENT lower_case ON SCHEDULE EVERY 1 MINUTE DO SELECT 1;
|
CREATE EVENT lower_case ON SCHEDULE EVERY 1 MINUTE DO SELECT 1;
|
||||||
CREATE EVENT Lower_case ON SCHEDULE EVERY 2 MINUTE DO SELECT 2;
|
CREATE EVENT Lower_case ON SCHEDULE EVERY 2 MINUTE DO SELECT 2;
|
||||||
ERROR HY000: Event 'Lower_case' already exists
|
ERROR HY000: Event 'Lower_case' already exists
|
||||||
|
@@ -637,3 +637,94 @@ a b
|
|||||||
8 i
|
8 i
|
||||||
handler a2 close;
|
handler a2 close;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
flush tables;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
handler t1_alias close;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
handler t1_alias read first;
|
||||||
|
a
|
||||||
|
drop table t1;
|
||||||
|
handler t1_alias read next;
|
||||||
|
ERROR 42S02: Unknown table 't1_alias' in HANDLER
|
||||||
|
create table t1 (a int);
|
||||||
|
create temporary table t2 (a int, key(a));
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a2 read a first;
|
||||||
|
a
|
||||||
|
drop table t1, t2;
|
||||||
|
handler a2 read a next;
|
||||||
|
ERROR 42S02: Unknown table 'a2' in HANDLER
|
||||||
|
handler a1 close;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
create table t2 like t1;
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a1 read a first;
|
||||||
|
a
|
||||||
|
handler a2 read a first;
|
||||||
|
a
|
||||||
|
alter table t1 add b int;
|
||||||
|
handler a1 close;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
handler a2 close;
|
||||||
|
drop table t1, t2;
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler a1 read a first;
|
||||||
|
a
|
||||||
|
rename table t1 to t2;
|
||||||
|
handler a1 read a first;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
drop table t2;
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
create table t2 like t1;
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a1 read a first;
|
||||||
|
a
|
||||||
|
handler a2 read a first;
|
||||||
|
a
|
||||||
|
optimize table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
handler a1 close;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
handler a2 close;
|
||||||
|
drop table t1, t2;
|
||||||
|
create table t1 (a int, b char(1), key a(a), key b(a,b));
|
||||||
|
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
|
||||||
|
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
|
||||||
|
handler t1 open;
|
||||||
|
handler t1 read a first;
|
||||||
|
a b
|
||||||
|
0 a
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
1 b
|
||||||
|
flush tables;
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
0 a
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
1 b
|
||||||
|
flush tables with read lock;
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
0 a
|
||||||
|
unlock tables;
|
||||||
|
drop table t1;
|
||||||
|
handler t1 read a next;
|
||||||
|
ERROR 42S02: Unknown table 't1' in HANDLER
|
||||||
|
@@ -637,3 +637,94 @@ a b
|
|||||||
8 i
|
8 i
|
||||||
handler a2 close;
|
handler a2 close;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
flush tables;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
handler t1_alias close;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
handler t1 open as t1_alias;
|
||||||
|
handler t1_alias read first;
|
||||||
|
a
|
||||||
|
drop table t1;
|
||||||
|
handler t1_alias read next;
|
||||||
|
ERROR 42S02: Unknown table 't1_alias' in HANDLER
|
||||||
|
create table t1 (a int);
|
||||||
|
create temporary table t2 (a int, key(a));
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a2 read a first;
|
||||||
|
a
|
||||||
|
drop table t1, t2;
|
||||||
|
handler a2 read a next;
|
||||||
|
ERROR 42S02: Unknown table 'a2' in HANDLER
|
||||||
|
handler a1 close;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
create table t2 like t1;
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a1 read a first;
|
||||||
|
a
|
||||||
|
handler a2 read a first;
|
||||||
|
a
|
||||||
|
alter table t1 add b int;
|
||||||
|
handler a1 close;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
handler a2 close;
|
||||||
|
drop table t1, t2;
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler a1 read a first;
|
||||||
|
a
|
||||||
|
rename table t1 to t2;
|
||||||
|
handler a1 read a first;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
drop table t2;
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
create table t2 like t1;
|
||||||
|
handler t1 open as a1;
|
||||||
|
handler t2 open as a2;
|
||||||
|
handler a1 read a first;
|
||||||
|
a
|
||||||
|
handler a2 read a first;
|
||||||
|
a
|
||||||
|
optimize table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status Table is already up to date
|
||||||
|
handler a1 close;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in HANDLER
|
||||||
|
handler a2 close;
|
||||||
|
drop table t1, t2;
|
||||||
|
create table t1 (a int, b char(1), key a(a), key b(a,b));
|
||||||
|
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
|
||||||
|
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
|
||||||
|
handler t1 open;
|
||||||
|
handler t1 read a first;
|
||||||
|
a b
|
||||||
|
0 a
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
1 b
|
||||||
|
flush tables;
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
0 a
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
1 b
|
||||||
|
flush tables with read lock;
|
||||||
|
handler t1 read a next;
|
||||||
|
a b
|
||||||
|
0 a
|
||||||
|
unlock tables;
|
||||||
|
drop table t1;
|
||||||
|
handler t1 read a next;
|
||||||
|
ERROR 42S02: Unknown table 't1' in HANDLER
|
||||||
|
@@ -125,3 +125,14 @@ drop function bug27563;
|
|||||||
drop procedure proc27563;
|
drop procedure proc27563;
|
||||||
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
|
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
|
||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
|
#
|
||||||
|
# Bug#19723: kill of active connection yields different error code
|
||||||
|
# depending on platform.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Connection: con2.
|
||||||
|
KILL CONNECTION_ID();
|
||||||
|
# CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing
|
||||||
|
# of close of the connection socket
|
||||||
|
SELECT 1;
|
||||||
|
Got one of the listed errors
|
||||||
|
@@ -4,3 +4,6 @@ select 1+1;
|
|||||||
select 1+2;
|
select 1+2;
|
||||||
1+2
|
1+2
|
||||||
3
|
3
|
||||||
|
SHOW GLOBAL VARIABLES LIKE 'thread_handling';
|
||||||
|
Variable_name Value
|
||||||
|
thread_handling no-threads
|
||||||
|
1
mysql-test/t/events_bugs-master.opt
Normal file
1
mysql-test/t/events_bugs-master.opt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--event-scheduler
|
@@ -9,6 +9,21 @@ drop database if exists mysqltest_db2;
|
|||||||
create database events_test;
|
create database events_test;
|
||||||
use events_test;
|
use events_test;
|
||||||
|
|
||||||
|
#
|
||||||
|
# START: Bug #31332 --event-scheduler option misbehaving
|
||||||
|
#
|
||||||
|
|
||||||
|
# NOTE!! this test must come first! It's testing that the --event-scheduler
|
||||||
|
# option with no argument in events_bugs-master.opt turns the scheduler on.
|
||||||
|
|
||||||
|
select * from information_schema.global_variables where variable_name like 'event_scheduler';
|
||||||
|
|
||||||
|
SET GLOBAL event_scheduler = 'OFF';
|
||||||
|
|
||||||
|
#
|
||||||
|
# END: Bug #31332
|
||||||
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# START - 16415: Events: event names are case sensitive
|
# START - 16415: Events: event names are case sensitive
|
||||||
#
|
#
|
||||||
|
@@ -1143,6 +1143,7 @@ END$$
|
|||||||
|
|
||||||
DELIMITER ;$$
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
let $wait_timeout= 300;
|
||||||
let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status';
|
let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status';
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
@@ -304,3 +304,21 @@ while ($i)
|
|||||||
dec $i ;
|
dec $i ;
|
||||||
}
|
}
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#19723: kill of active connection yields different error code
|
||||||
|
--echo # depending on platform.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Connection: con2.
|
||||||
|
--connection con2
|
||||||
|
|
||||||
|
KILL CONNECTION_ID();
|
||||||
|
|
||||||
|
--echo # CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing
|
||||||
|
--echo # of close of the connection socket
|
||||||
|
--error 2013, 2006
|
||||||
|
SELECT 1;
|
||||||
|
@@ -3,3 +3,4 @@
|
|||||||
#
|
#
|
||||||
select 1+1;
|
select 1+1;
|
||||||
select 1+2;
|
select 1+2;
|
||||||
|
SHOW GLOBAL VARIABLES LIKE 'thread_handling';
|
||||||
|
@@ -45,27 +45,9 @@ call bug4902_2()|
|
|||||||
call bug4902_2()|
|
call bug4902_2()|
|
||||||
drop procedure bug4902_2|
|
drop procedure bug4902_2|
|
||||||
|
|
||||||
|
|
||||||
# Disable until bug#17244 is fixed
|
|
||||||
--disable_parsing
|
|
||||||
#
|
#
|
||||||
# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
|
# BUG#3583: query cache doesn't work for stored procedures
|
||||||
#
|
#
|
||||||
--disable_warnings
|
|
||||||
drop function if exists bug5278|
|
|
||||||
--enable_warnings
|
|
||||||
create function bug5278 () returns char
|
|
||||||
begin
|
|
||||||
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
|
|
||||||
return 'okay';
|
|
||||||
end|
|
|
||||||
|
|
||||||
--error 1133
|
|
||||||
select bug5278()|
|
|
||||||
--error 1133
|
|
||||||
select bug5278()|
|
|
||||||
drop function bug5278|
|
|
||||||
--enable_parsing
|
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1|
|
drop table if exists t1|
|
||||||
@@ -74,9 +56,6 @@ create table t1 (
|
|||||||
id char(16) not null default '',
|
id char(16) not null default '',
|
||||||
data int not null
|
data int not null
|
||||||
)|
|
)|
|
||||||
#
|
|
||||||
# BUG#3583: query cache doesn't work for stored procedures
|
|
||||||
#
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop procedure if exists bug3583|
|
drop procedure if exists bug3583|
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
@@ -146,7 +146,7 @@ bool
|
|||||||
Events::set_opt_event_scheduler(char *argument)
|
Events::set_opt_event_scheduler(char *argument)
|
||||||
{
|
{
|
||||||
if (argument == NULL)
|
if (argument == NULL)
|
||||||
opt_event_scheduler= Events::EVENTS_DISABLED;
|
opt_event_scheduler= Events::EVENTS_ON;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
@@ -356,10 +356,35 @@ String *Item_func_concat::val_str(String *str)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Two big const strings
|
{ // Two big const strings
|
||||||
if (tmp_value.alloc(max_length) ||
|
/*
|
||||||
tmp_value.copy(*res) ||
|
NOTE: We should be prudent in the initial allocation unit -- the
|
||||||
tmp_value.append(*res2))
|
size of the arguments is a function of data distribution, which
|
||||||
|
can be any. Instead of overcommitting at the first row, we grow
|
||||||
|
the allocated amount by the factor of 2. This ensures that no
|
||||||
|
more than 25% of memory will be overcommitted on average.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint concat_len= res->length() + res2->length();
|
||||||
|
|
||||||
|
if (tmp_value.alloced_length() < concat_len)
|
||||||
|
{
|
||||||
|
if (tmp_value.alloced_length() == 0)
|
||||||
|
{
|
||||||
|
if (tmp_value.alloc(concat_len))
|
||||||
|
goto null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
|
||||||
|
|
||||||
|
if (tmp_value.realloc(new_len))
|
||||||
|
goto null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_value.copy(*res) || tmp_value.append(*res2))
|
||||||
goto null;
|
goto null;
|
||||||
|
|
||||||
res= &tmp_value;
|
res= &tmp_value;
|
||||||
use_as_buff=str;
|
use_as_buff=str;
|
||||||
}
|
}
|
||||||
@@ -679,8 +704,33 @@ String *Item_func_concat_ws::val_str(String *str)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Two big const strings
|
{ // Two big const strings
|
||||||
if (tmp_value.alloc(max_length) ||
|
/*
|
||||||
tmp_value.copy(*res) ||
|
NOTE: We should be prudent in the initial allocation unit -- the
|
||||||
|
size of the arguments is a function of data distribution, which can
|
||||||
|
be any. Instead of overcommitting at the first row, we grow the
|
||||||
|
allocated amount by the factor of 2. This ensures that no more than
|
||||||
|
25% of memory will be overcommitted on average.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint concat_len= res->length() + sep_str->length() + res2->length();
|
||||||
|
|
||||||
|
if (tmp_value.alloced_length() < concat_len)
|
||||||
|
{
|
||||||
|
if (tmp_value.alloced_length() == 0)
|
||||||
|
{
|
||||||
|
if (tmp_value.alloc(concat_len))
|
||||||
|
goto null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
|
||||||
|
|
||||||
|
if (tmp_value.realloc(new_len))
|
||||||
|
goto null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_value.copy(*res) ||
|
||||||
tmp_value.append(*sep_str) ||
|
tmp_value.append(*sep_str) ||
|
||||||
tmp_value.append(*res2))
|
tmp_value.append(*res2))
|
||||||
goto null;
|
goto null;
|
||||||
|
@@ -1289,12 +1289,9 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
|
|||||||
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
|
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
|
||||||
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
|
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
|
||||||
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
|
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
|
||||||
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
|
void mysql_ha_flush(THD *thd);
|
||||||
bool is_locked);
|
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables);
|
||||||
/* mysql_ha_flush mode_flags bits */
|
void mysql_ha_cleanup(THD *thd);
|
||||||
#define MYSQL_HA_CLOSE_FINAL 0x00
|
|
||||||
#define MYSQL_HA_REOPEN_ON_USAGE 0x01
|
|
||||||
#define MYSQL_HA_FLUSH_ALL 0x02
|
|
||||||
|
|
||||||
/* sql_base.cc */
|
/* sql_base.cc */
|
||||||
#define TMP_TABLE_KEY_EXTRA 8
|
#define TMP_TABLE_KEY_EXTRA 8
|
||||||
|
@@ -2596,7 +2596,12 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||||||
thd->is_slave_error= 1; // needed to catch query errors during replication
|
thd->is_slave_error= 1; // needed to catch query errors during replication
|
||||||
|
|
||||||
if (!thd->no_warnings_for_error)
|
if (!thd->no_warnings_for_error)
|
||||||
|
{
|
||||||
|
thd->no_warnings_for_error= TRUE;
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
|
||||||
|
thd->no_warnings_for_error= FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
thd->lex->current_select == 0 if lex structure is not inited
|
thd->lex->current_select == 0 if lex structure is not inited
|
||||||
(not query command (COM_QUERY))
|
(not query command (COM_QUERY))
|
||||||
@@ -4599,8 +4604,13 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
|
|||||||
sock == unix_sock ? VIO_LOCALHOST: 0)) ||
|
sock == unix_sock ? VIO_LOCALHOST: 0)) ||
|
||||||
my_net_init(&thd->net,vio_tmp))
|
my_net_init(&thd->net,vio_tmp))
|
||||||
{
|
{
|
||||||
if (vio_tmp)
|
/*
|
||||||
vio_delete(vio_tmp);
|
Only delete the temporary vio if we didn't already attach it to the
|
||||||
|
NET object. The destructor in THD will delete any initialized net
|
||||||
|
structure.
|
||||||
|
*/
|
||||||
|
if (vio_tmp && thd->net.vio != vio_tmp)
|
||||||
|
vio_delete(vio_tmp);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(void) shutdown(new_sock, SHUT_RDWR);
|
(void) shutdown(new_sock, SHUT_RDWR);
|
||||||
@@ -7745,12 +7755,13 @@ mysqld_get_one_option(int optid,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_ONE_THREAD:
|
case OPT_ONE_THREAD:
|
||||||
global_system_variables.thread_handling= 2;
|
global_system_variables.thread_handling=
|
||||||
|
SCHEDULER_ONE_THREAD_PER_CONNECTION;
|
||||||
break;
|
break;
|
||||||
case OPT_THREAD_HANDLING:
|
case OPT_THREAD_HANDLING:
|
||||||
{
|
{
|
||||||
global_system_variables.thread_handling=
|
global_system_variables.thread_handling=
|
||||||
find_type_or_exit(argument, &thread_handling_typelib, opt->name);
|
find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_FT_BOOLEAN_SYNTAX:
|
case OPT_FT_BOOLEAN_SYNTAX:
|
||||||
|
@@ -40,7 +40,7 @@ public:
|
|||||||
|
|
||||||
enum scheduler_types
|
enum scheduler_types
|
||||||
{
|
{
|
||||||
SCHEDULER_ONE_THREAD_PER_CONNECTION=1,
|
SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
|
||||||
SCHEDULER_NO_THREADS,
|
SCHEDULER_NO_THREADS,
|
||||||
SCHEDULER_POOL_OF_THREADS
|
SCHEDULER_POOL_OF_THREADS
|
||||||
};
|
};
|
||||||
|
@@ -465,14 +465,16 @@ check_routine_name(LEX_STRING *ident)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void *
|
void *
|
||||||
sp_head::operator new(size_t size)
|
sp_head::operator new(size_t size) throw()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("sp_head::operator new");
|
DBUG_ENTER("sp_head::operator new");
|
||||||
MEM_ROOT own_root;
|
MEM_ROOT own_root;
|
||||||
sp_head *sp;
|
sp_head *sp;
|
||||||
|
|
||||||
init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
|
init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
|
||||||
sp= (sp_head *) alloc_root(&own_root, size);
|
sp= (sp_head *) alloc_root(&own_root, size);
|
||||||
|
if (sp == NULL)
|
||||||
|
return NULL;
|
||||||
sp->main_mem_root= own_root;
|
sp->main_mem_root= own_root;
|
||||||
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
|
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
|
||||||
DBUG_RETURN(sp);
|
DBUG_RETURN(sp);
|
||||||
@@ -483,6 +485,10 @@ sp_head::operator delete(void *ptr, size_t size)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("sp_head::operator delete");
|
DBUG_ENTER("sp_head::operator delete");
|
||||||
MEM_ROOT own_root;
|
MEM_ROOT own_root;
|
||||||
|
|
||||||
|
if (ptr == NULL)
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
sp_head *sp= (sp_head *) ptr;
|
sp_head *sp= (sp_head *) ptr;
|
||||||
|
|
||||||
/* Make a copy of main_mem_root as free_root will free the sp */
|
/* Make a copy of main_mem_root as free_root will free the sp */
|
||||||
@@ -536,6 +542,9 @@ sp_head::init(LEX *lex)
|
|||||||
|
|
||||||
lex->spcont= m_pcont= new sp_pcontext();
|
lex->spcont= m_pcont= new sp_pcontext();
|
||||||
|
|
||||||
|
if (!lex->spcont)
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Altough trg_table_fields list is used only in triggers we init for all
|
Altough trg_table_fields list is used only in triggers we init for all
|
||||||
types of stored procedures to simplify reset_lex()/restore_lex() code.
|
types of stored procedures to simplify reset_lex()/restore_lex() code.
|
||||||
@@ -1069,7 +1078,7 @@ sp_head::execute(THD *thd)
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/* init per-instruction memroot */
|
/* init per-instruction memroot */
|
||||||
init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
|
init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
|
||||||
|
|
||||||
DBUG_ASSERT(!(m_flags & IS_INVOKED));
|
DBUG_ASSERT(!(m_flags & IS_INVOKED));
|
||||||
m_flags|= IS_INVOKED;
|
m_flags|= IS_INVOKED;
|
||||||
@@ -1961,16 +1970,29 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reset lex during parsing, before we parse a sub statement.
|
/**
|
||||||
void
|
@brief Reset lex during parsing, before we parse a sub statement.
|
||||||
|
|
||||||
|
@param thd Thread handler.
|
||||||
|
|
||||||
|
@return Error state
|
||||||
|
@retval true An error occurred.
|
||||||
|
@retval false Success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
sp_head::reset_lex(THD *thd)
|
sp_head::reset_lex(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("sp_head::reset_lex");
|
DBUG_ENTER("sp_head::reset_lex");
|
||||||
LEX *sublex;
|
LEX *sublex;
|
||||||
LEX *oldlex= thd->lex;
|
LEX *oldlex= thd->lex;
|
||||||
|
|
||||||
|
sublex= new (thd->mem_root)st_lex_local;
|
||||||
|
if (sublex == 0)
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
thd->lex= sublex;
|
||||||
(void)m_lex.push_front(oldlex);
|
(void)m_lex.push_front(oldlex);
|
||||||
thd->lex= sublex= new st_lex;
|
|
||||||
|
|
||||||
/* Reset most stuff. */
|
/* Reset most stuff. */
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
@@ -1991,7 +2013,7 @@ sp_head::reset_lex(THD *thd)
|
|||||||
sublex->interval_list.empty();
|
sublex->interval_list.empty();
|
||||||
sublex->type= 0;
|
sublex->type= 0;
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore lex during parsing, after we have parsed a sub statement.
|
// Restore lex during parsing, after we have parsed a sub statement.
|
||||||
@@ -3856,7 +3878,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
|
|||||||
|
|
||||||
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
|
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
|
||||||
{
|
{
|
||||||
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST));
|
thd->fatal_error();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
table->db_length= strlen(db);
|
table->db_length= strlen(db);
|
||||||
|
@@ -260,10 +260,10 @@ public:
|
|||||||
Security_context m_security_ctx;
|
Security_context m_security_ctx;
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
operator new(size_t size);
|
operator new(size_t size) throw ();
|
||||||
|
|
||||||
static void
|
static void
|
||||||
operator delete(void *ptr, size_t size);
|
operator delete(void *ptr, size_t size) throw ();
|
||||||
|
|
||||||
sp_head();
|
sp_head();
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resets lex in 'thd' and keeps a copy of the old one.
|
// Resets lex in 'thd' and keeps a copy of the old one.
|
||||||
void
|
bool
|
||||||
reset_lex(THD *thd);
|
reset_lex(THD *thd);
|
||||||
|
|
||||||
// Restores lex in 'thd' from our copy, but keeps some status from the
|
// Restores lex in 'thd' from our copy, but keeps some status from the
|
||||||
|
@@ -87,7 +87,6 @@ bool Prelock_error_handler::safely_trapped_errors()
|
|||||||
@defgroup Data_Dictionary Data Dictionary
|
@defgroup Data_Dictionary Data Dictionary
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TABLE *unused_tables; /* Used by mysql_test */
|
TABLE *unused_tables; /* Used by mysql_test */
|
||||||
HASH open_cache; /* Used by mysql_test */
|
HASH open_cache; /* Used by mysql_test */
|
||||||
static HASH table_def_cache;
|
static HASH table_def_cache;
|
||||||
@@ -929,8 +928,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
|
|||||||
thd->proc_info="Flushing tables";
|
thd->proc_info="Flushing tables";
|
||||||
|
|
||||||
close_old_data_files(thd,thd->open_tables,1,1);
|
close_old_data_files(thd,thd->open_tables,1,1);
|
||||||
mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL,
|
mysql_ha_flush(thd);
|
||||||
TRUE);
|
|
||||||
bool found=1;
|
bool found=1;
|
||||||
/* Wait until all threads has closed all the tables we had locked */
|
/* Wait until all threads has closed all the tables we had locked */
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
@@ -2516,7 +2515,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
deadlock may occur.
|
deadlock may occur.
|
||||||
*/
|
*/
|
||||||
if (thd->handler_tables)
|
if (thd->handler_tables)
|
||||||
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
|
mysql_ha_flush(thd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Actually try to find the table in the open_cache.
|
Actually try to find the table in the open_cache.
|
||||||
@@ -3136,7 +3135,7 @@ bool wait_for_tables(THD *thd)
|
|||||||
{
|
{
|
||||||
thd->some_tables_deleted=0;
|
thd->some_tables_deleted=0;
|
||||||
close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
|
close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
|
||||||
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
|
mysql_ha_flush(thd);
|
||||||
if (!table_is_used(thd->open_tables,1))
|
if (!table_is_used(thd->open_tables,1))
|
||||||
break;
|
break;
|
||||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||||
@@ -3554,7 +3553,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
temporary mem_root for new .frm parsing.
|
temporary mem_root for new .frm parsing.
|
||||||
TODO: variables for size
|
TODO: variables for size
|
||||||
*/
|
*/
|
||||||
init_alloc_root(&new_frm_mem, 8024, 8024);
|
init_sql_alloc(&new_frm_mem, 8024, 8024);
|
||||||
|
|
||||||
thd->current_tablenr= 0;
|
thd->current_tablenr= 0;
|
||||||
restart:
|
restart:
|
||||||
|
@@ -678,9 +678,7 @@ void THD::cleanup(void)
|
|||||||
lock=locked_tables; locked_tables=0;
|
lock=locked_tables; locked_tables=0;
|
||||||
close_thread_tables(this);
|
close_thread_tables(this);
|
||||||
}
|
}
|
||||||
mysql_ha_flush(this, (TABLE_LIST*) 0,
|
mysql_ha_cleanup(this);
|
||||||
MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL, FALSE);
|
|
||||||
hash_free(&handler_tables_hash);
|
|
||||||
delete_dynamic(&user_var_events);
|
delete_dynamic(&user_var_events);
|
||||||
hash_free(&user_vars);
|
hash_free(&user_vars);
|
||||||
close_temporary_tables(this);
|
close_temporary_tables(this);
|
||||||
@@ -818,7 +816,20 @@ void THD::awake(THD::killed_state state_to_set)
|
|||||||
if (!slave_thread)
|
if (!slave_thread)
|
||||||
thread_scheduler.post_kill_notification(this);
|
thread_scheduler.post_kill_notification(this);
|
||||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||||
close_active_vio();
|
if (this != current_thd)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
In addition to a signal, let's close the socket of the thread that
|
||||||
|
is being killed. This is to make sure it does not block if the
|
||||||
|
signal is lost. This needs to be done only on platforms where
|
||||||
|
signals are not a reliable interruption mechanism.
|
||||||
|
|
||||||
|
If we're killing ourselves, we know that we're not blocked, so this
|
||||||
|
hack is not used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
close_active_vio();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (mysys_var)
|
if (mysys_var)
|
||||||
|
@@ -65,9 +65,6 @@
|
|||||||
static enum enum_ha_read_modes rkey_to_rnext[]=
|
static enum enum_ha_read_modes rkey_to_rnext[]=
|
||||||
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
|
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
|
||||||
|
|
||||||
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get hash key and hash key length.
|
Get hash key and hash key length.
|
||||||
|
|
||||||
@@ -119,13 +116,15 @@ static void mysql_ha_hash_free(TABLE_LIST *tables)
|
|||||||
|
|
||||||
@param thd Thread identifier.
|
@param thd Thread identifier.
|
||||||
@param tables A list of tables with the first entry to close.
|
@param tables A list of tables with the first entry to close.
|
||||||
|
@param is_locked If LOCK_open is locked.
|
||||||
|
|
||||||
@note Though this function takes a list of tables, only the first list entry
|
@note Though this function takes a list of tables, only the first list entry
|
||||||
will be closed.
|
will be closed.
|
||||||
@note Broadcasts refresh if it closed the table.
|
@note Broadcasts refresh if it closed a table with old version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
|
static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
|
||||||
|
bool is_locked)
|
||||||
{
|
{
|
||||||
TABLE **table_ptr;
|
TABLE **table_ptr;
|
||||||
|
|
||||||
@@ -143,13 +142,15 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
|
|||||||
if (*table_ptr)
|
if (*table_ptr)
|
||||||
{
|
{
|
||||||
(*table_ptr)->file->ha_index_or_rnd_end();
|
(*table_ptr)->file->ha_index_or_rnd_end();
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
if (! is_locked)
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
if (close_thread_table(thd, table_ptr))
|
if (close_thread_table(thd, table_ptr))
|
||||||
{
|
{
|
||||||
/* Tell threads waiting for refresh that something has happened */
|
/* Tell threads waiting for refresh that something has happened */
|
||||||
broadcast_refresh();
|
broadcast_refresh();
|
||||||
}
|
}
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
if (! is_locked)
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
}
|
}
|
||||||
else if (tables->table)
|
else if (tables->table)
|
||||||
{
|
{
|
||||||
@@ -305,7 +306,7 @@ err:
|
|||||||
if (hash_tables)
|
if (hash_tables)
|
||||||
my_free((char*) hash_tables, MYF(0));
|
my_free((char*) hash_tables, MYF(0));
|
||||||
if (tables->table)
|
if (tables->table)
|
||||||
mysql_ha_close_table(thd, tables);
|
mysql_ha_close_table(thd, tables, FALSE);
|
||||||
DBUG_PRINT("exit",("ERROR"));
|
DBUG_PRINT("exit",("ERROR"));
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@@ -339,7 +340,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
|
|||||||
(uchar*) tables->alias,
|
(uchar*) tables->alias,
|
||||||
strlen(tables->alias) + 1)))
|
strlen(tables->alias) + 1)))
|
||||||
{
|
{
|
||||||
mysql_ha_close_table(thd, hash_tables);
|
mysql_ha_close_table(thd, hash_tables, FALSE);
|
||||||
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
|
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -478,7 +479,7 @@ retry:
|
|||||||
|
|
||||||
if (need_reopen)
|
if (need_reopen)
|
||||||
{
|
{
|
||||||
mysql_ha_close_table(thd, tables);
|
mysql_ha_close_table(thd, tables, FALSE);
|
||||||
hash_tables->table= NULL;
|
hash_tables->table= NULL;
|
||||||
/*
|
/*
|
||||||
The lock might have been aborted, we need to manually reset
|
The lock might have been aborted, we need to manually reset
|
||||||
@@ -669,163 +670,131 @@ err0:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Flush (close) a list of HANDLER tables.
|
Scan the handler tables hash for matching tables.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread identifier.
|
||||||
mysql_ha_flush()
|
@param tables The list of tables to remove.
|
||||||
thd Thread identifier.
|
|
||||||
tables The list of tables to close. If NULL,
|
|
||||||
close all HANDLER tables [marked as flushed].
|
|
||||||
mode_flags MYSQL_HA_CLOSE_FINAL finally close the table.
|
|
||||||
MYSQL_HA_REOPEN_ON_USAGE mark for reopen.
|
|
||||||
MYSQL_HA_FLUSH_ALL flush all tables, not only
|
|
||||||
those marked for flush.
|
|
||||||
is_locked If LOCK_open is locked.
|
|
||||||
|
|
||||||
DESCRIPTION
|
@return Pointer to head of linked list (TABLE_LIST::next_local) of matching
|
||||||
The list of HANDLER tables may be NULL, in which case all HANDLER
|
TABLE_LIST elements from handler_tables_hash. Otherwise, NULL if no
|
||||||
tables are closed (if MYSQL_HA_FLUSH_ALL) is set.
|
table was matched.
|
||||||
If 'tables' is NULL and MYSQL_HA_FLUSH_ALL is not set,
|
|
||||||
all HANDLER tables marked for flush are closed.
|
|
||||||
Broadcasts refresh for every table closed.
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
Since mysql_ha_flush() is called when the base table has to be closed,
|
|
||||||
we compare real table names, not aliases. Hence, database names matter.
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
|
static TABLE_LIST *mysql_ha_find(THD *thd, TABLE_LIST *tables)
|
||||||
bool is_locked)
|
|
||||||
{
|
{
|
||||||
TABLE_LIST *tmp_tables;
|
TABLE_LIST *hash_tables, *head= NULL, *first= tables;
|
||||||
TABLE **table_ptr;
|
DBUG_ENTER("mysql_ha_find");
|
||||||
bool did_lock= FALSE;
|
|
||||||
DBUG_ENTER("mysql_ha_flush");
|
|
||||||
DBUG_PRINT("enter", ("tables: 0x%lx mode_flags: 0x%02x",
|
|
||||||
(long) tables, mode_flags));
|
|
||||||
|
|
||||||
if (tables)
|
/* search for all handlers with matching table names */
|
||||||
|
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
|
||||||
{
|
{
|
||||||
/* Close all tables in the list. */
|
hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
|
||||||
for (tmp_tables= tables ; tmp_tables; tmp_tables= tmp_tables->next_local)
|
for (tables= first; tables; tables= tables->next_local)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info-in-tables-list",("'%s'.'%s' as '%s'",
|
if ((! *tables->db ||
|
||||||
tmp_tables->db, tmp_tables->table_name,
|
! my_strcasecmp(&my_charset_latin1, hash_tables->db, tables->db)) &&
|
||||||
tmp_tables->alias));
|
! my_strcasecmp(&my_charset_latin1, hash_tables->table_name,
|
||||||
/* Close all currently open handler tables with the same base table. */
|
tables->table_name))
|
||||||
table_ptr= &(thd->handler_tables);
|
break;
|
||||||
while (*table_ptr)
|
|
||||||
{
|
|
||||||
if ((!*tmp_tables->db ||
|
|
||||||
!my_strcasecmp(&my_charset_latin1, (*table_ptr)->s->db.str,
|
|
||||||
tmp_tables->db)) &&
|
|
||||||
! my_strcasecmp(&my_charset_latin1,
|
|
||||||
(*table_ptr)->s->table_name.str,
|
|
||||||
tmp_tables->table_name))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info",("*table_ptr '%s'.'%s' as '%s'",
|
|
||||||
(*table_ptr)->s->db.str,
|
|
||||||
(*table_ptr)->s->table_name.str,
|
|
||||||
(*table_ptr)->alias));
|
|
||||||
/* The first time it is required, lock for close_thread_table(). */
|
|
||||||
if (! did_lock && ! is_locked)
|
|
||||||
{
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
|
||||||
did_lock= TRUE;
|
|
||||||
}
|
|
||||||
mysql_ha_flush_table(thd, table_ptr, mode_flags);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
table_ptr= &(*table_ptr)->next;
|
|
||||||
}
|
|
||||||
/* end of handler_tables list */
|
|
||||||
}
|
}
|
||||||
/* end of flush tables list */
|
if (tables)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Close all currently open tables [which are marked for flush]. */
|
|
||||||
table_ptr= &(thd->handler_tables);
|
|
||||||
while (*table_ptr)
|
|
||||||
{
|
{
|
||||||
if ((mode_flags & MYSQL_HA_FLUSH_ALL) ||
|
hash_tables->next_local= head;
|
||||||
(*table_ptr)->needs_reopen_or_name_lock())
|
head= hash_tables;
|
||||||
{
|
|
||||||
/* The first time it is required, lock for close_thread_table(). */
|
|
||||||
if (! did_lock && ! is_locked)
|
|
||||||
{
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
|
||||||
did_lock= TRUE;
|
|
||||||
}
|
|
||||||
mysql_ha_flush_table(thd, table_ptr, mode_flags);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
table_ptr= &(*table_ptr)->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock if it was taken by this function. */
|
DBUG_RETURN(head);
|
||||||
if (did_lock)
|
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Flush (close) a table.
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
mysql_ha_flush_table()
|
Remove matching tables from the HANDLER's hash table.
|
||||||
thd Thread identifier.
|
|
||||||
table The table to close.
|
|
||||||
mode_flags MYSQL_HA_CLOSE_FINAL finally close the table.
|
|
||||||
MYSQL_HA_REOPEN_ON_USAGE mark for reopen.
|
|
||||||
|
|
||||||
DESCRIPTION
|
@param thd Thread identifier.
|
||||||
Broadcasts refresh if it closed the table.
|
@param tables The list of tables to remove.
|
||||||
The caller must lock LOCK_open.
|
|
||||||
|
|
||||||
RETURN
|
@note Broadcasts refresh if it closed a table with old version.
|
||||||
0 ok
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
|
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
TABLE_LIST *hash_tables;
|
TABLE_LIST *hash_tables, *next;
|
||||||
TABLE *table= *table_ptr;
|
DBUG_ENTER("mysql_ha_rm_tables");
|
||||||
DBUG_ENTER("mysql_ha_flush_table");
|
|
||||||
DBUG_PRINT("enter",("'%s'.'%s' as '%s' flags: 0x%02x",
|
|
||||||
table->s->db.str, table->s->table_name.str,
|
|
||||||
table->alias, mode_flags));
|
|
||||||
|
|
||||||
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
|
safe_mutex_assert_not_owner(&LOCK_open);
|
||||||
(uchar*) table->alias,
|
|
||||||
strlen(table->alias) + 1)))
|
DBUG_ASSERT(tables);
|
||||||
|
|
||||||
|
hash_tables= mysql_ha_find(thd, tables);
|
||||||
|
|
||||||
|
while (hash_tables)
|
||||||
{
|
{
|
||||||
if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE))
|
next= hash_tables->next_local;
|
||||||
{
|
if (hash_tables->table)
|
||||||
/* This is a final close. Remove from hash. */
|
mysql_ha_close_table(thd, hash_tables, FALSE);
|
||||||
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
|
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
|
||||||
}
|
hash_tables= next;
|
||||||
else
|
}
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush (close and mark for re-open) all tables that should be should
|
||||||
|
be reopen.
|
||||||
|
|
||||||
|
@param thd Thread identifier.
|
||||||
|
|
||||||
|
@note Broadcasts refresh if it closed a table with old version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_ha_flush(THD *thd)
|
||||||
|
{
|
||||||
|
TABLE_LIST *hash_tables;
|
||||||
|
DBUG_ENTER("mysql_ha_flush");
|
||||||
|
|
||||||
|
safe_mutex_assert_owner(&LOCK_open);
|
||||||
|
|
||||||
|
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
|
||||||
|
{
|
||||||
|
hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
|
||||||
|
if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock())
|
||||||
{
|
{
|
||||||
|
mysql_ha_close_table(thd, hash_tables, TRUE);
|
||||||
/* Mark table as closed, ready for re-open. */
|
/* Mark table as closed, ready for re-open. */
|
||||||
hash_tables->table= NULL;
|
hash_tables->table= NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_mutex_assert_owner(&LOCK_open);
|
DBUG_VOID_RETURN;
|
||||||
(*table_ptr)->file->ha_index_or_rnd_end();
|
|
||||||
safe_mutex_assert_owner(&LOCK_open);
|
|
||||||
if (close_thread_table(thd, table_ptr))
|
|
||||||
{
|
|
||||||
/* Tell threads waiting for refresh that something has happened */
|
|
||||||
broadcast_refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Close all HANDLER's tables.
|
||||||
|
|
||||||
|
@param thd Thread identifier.
|
||||||
|
|
||||||
|
@note Broadcasts refresh if it closed a table with old version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_ha_cleanup(THD *thd)
|
||||||
|
{
|
||||||
|
TABLE_LIST *hash_tables;
|
||||||
|
DBUG_ENTER("mysql_ha_cleanup");
|
||||||
|
|
||||||
|
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
|
||||||
|
{
|
||||||
|
hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
|
||||||
|
if (hash_tables->table)
|
||||||
|
mysql_ha_close_table(thd, hash_tables, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_free(&thd->handler_tables_hash);
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1834,11 +1834,11 @@ typedef struct st_lex : public Query_tables_list
|
|||||||
|
|
||||||
struct st_lex_local: public st_lex
|
struct st_lex_local: public st_lex
|
||||||
{
|
{
|
||||||
static void *operator new(size_t size)
|
static void *operator new(size_t size) throw()
|
||||||
{
|
{
|
||||||
return sql_alloc(size);
|
return sql_alloc(size);
|
||||||
}
|
}
|
||||||
static void *operator new(size_t size, MEM_ROOT *mem_root)
|
static void *operator new(size_t size, MEM_ROOT *mem_root) throw()
|
||||||
{
|
{
|
||||||
return (void*) alloc_root(mem_root, (uint) size);
|
return (void*) alloc_root(mem_root, (uint) size);
|
||||||
}
|
}
|
||||||
|
@@ -2700,7 +2700,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
|
|||||||
last_errno(0),
|
last_errno(0),
|
||||||
flags((uint) IS_IN_USE)
|
flags((uint) IS_IN_USE)
|
||||||
{
|
{
|
||||||
init_alloc_root(&main_mem_root, thd_arg->variables.query_alloc_block_size,
|
init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size,
|
||||||
thd_arg->variables.query_prealloc_size);
|
thd_arg->variables.query_prealloc_size);
|
||||||
*last_error= '\0';
|
*last_error= '\0';
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_ha_rm_tables(thd, table_list);
|
||||||
|
|
||||||
if (wait_if_global_read_lock(thd,0,1))
|
if (wait_if_global_read_lock(thd,0,1))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
@@ -1521,6 +1521,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
built_query.append("DROP TABLE ");
|
built_query.append("DROP TABLE ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_ha_rm_tables(thd, tables);
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1562,8 +1564,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
handlerton *table_type;
|
handlerton *table_type;
|
||||||
enum legacy_db_type frm_db_type;
|
enum legacy_db_type frm_db_type;
|
||||||
|
|
||||||
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, 1);
|
|
||||||
|
|
||||||
error= drop_temporary_table(thd, table);
|
error= drop_temporary_table(thd, table);
|
||||||
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
@@ -1572,13 +1572,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
tmp_table_deleted= 1;
|
tmp_table_deleted= 1;
|
||||||
continue;
|
continue;
|
||||||
case -1:
|
case -1:
|
||||||
// table already in use
|
DBUG_ASSERT(thd->in_sub_stmt);
|
||||||
/*
|
|
||||||
XXX: This branch should never be taken outside of SF, trigger or
|
|
||||||
prelocked mode.
|
|
||||||
|
|
||||||
DBUG_ASSERT(thd->in_sub_stmt);
|
|
||||||
*/
|
|
||||||
error= 1;
|
error= 1;
|
||||||
goto err_with_placeholders;
|
goto err_with_placeholders;
|
||||||
default:
|
default:
|
||||||
@@ -4025,7 +4019,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
|
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE);
|
mysql_ha_rm_tables(thd, tables);
|
||||||
|
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
char table_name[NAME_LEN*2+2];
|
char table_name[NAME_LEN*2+2];
|
||||||
@@ -5766,8 +5761,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0);
|
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0);
|
||||||
build_table_filename(path, sizeof(path), db, table_name, "", 0);
|
build_table_filename(path, sizeof(path), db, table_name, "", 0);
|
||||||
|
|
||||||
|
mysql_ha_rm_tables(thd, table_list);
|
||||||
mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE);
|
|
||||||
|
|
||||||
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
|
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
|
||||||
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
|
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
|
||||||
|
Reference in New Issue
Block a user