1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merge rurik.mysql.com:/home/igor/mysql-5.0

into  rurik.mysql.com:/home/igor/dev/mysql-5.0-2
This commit is contained in:
igor@rurik.mysql.com
2005-11-16 20:09:35 -08:00
28 changed files with 683 additions and 153 deletions

View File

@ -536,9 +536,15 @@ void safe_mutex_end(FILE *file);
#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
#define pthread_mutex_trylock(A) pthread_mutex_lock(A) #define pthread_mutex_trylock(A) pthread_mutex_lock(A)
#define pthread_mutex_t safe_mutex_t #define pthread_mutex_t safe_mutex_t
#define safe_mutex_assert_owner(mp) DBUG_ASSERT((mp)->count > 0 && pthread_equal(pthread_self(),(mp)->thread)) #define safe_mutex_assert_owner(mp) \
DBUG_ASSERT((mp)->count > 0 && \
pthread_equal(pthread_self(), (mp)->thread))
#define safe_mutex_assert_not_owner(mp) \
DBUG_ASSERT(! (mp)->count || \
! pthread_equal(pthread_self(), (mp)->thread))
#else #else
#define safe_mutex_assert_owner(mp) #define safe_mutex_assert_owner(mp)
#define safe_mutex_assert_not_owner(mp)
#endif /* SAFE_MUTEX */ #endif /* SAFE_MUTEX */
/* READ-WRITE thread locking */ /* READ-WRITE thread locking */

View File

@ -445,3 +445,40 @@ drop table t2;
drop table t3; drop table t3;
drop table t4; drop table t4;
drop table t5; drop table t5;
create table t1 (c1 int);
insert into t1 values (1);
handler t1 open;
handler t1 read first;
c1
1
send the below to another connection, do not wait for the result
optimize table t1;
proceed with the normal connection
handler t1 read next;
c1
1
handler t1 close;
read the result from the other connection
Table Op Msg_type Msg_text
test.t1 optimize status OK
proceed with the normal connection
drop table t1;
create table t1 (c1 int);
insert into t1 values (14397);
flush tables with read lock;
drop table t1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
send the below to another connection, do not wait for the result
drop table t1;
proceed with the normal connection
select * from t1;
c1
14397
unlock tables;
read the result from the other connection
proceed with the normal connection
select * from t1;
ERROR 42S02: Table 'test.t1' doesn't exist
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'

View File

@ -505,6 +505,16 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary 1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary
1 SIMPLE t2 index NULL PRIMARY 4 NULL 2 Using index; Distinct 1 SIMPLE t2 index NULL PRIMARY 4 NULL 2 Using index; Distinct
drop table t1,t2; drop table t1,t2;
create table t1 (
c1 varchar(32),
key (c1)
) engine=myisam;
alter table t1 disable keys;
insert into t1 values ('a'), ('b');
select c1 from t1 order by c1 limit 1;
c1
a
drop table t1;
CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) ENGINE=MyISAM; CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) ENGINE=MyISAM;
Got one of the listed errors Got one of the listed errors
create table t1 (a int, b varchar(200), c text not null) checksum=1; create table t1 (a int, b varchar(200), c text not null) checksum=1;

View File

@ -306,11 +306,21 @@ count(*)
drop table t1; drop table t1;
create table t1 ( create table t1 (
a char(10) primary key a char(10) primary key
) engine=ndb; ) engine=ndbcluster default charset=latin1;
insert into t1 values ('jonas % '); insert into t1 values ('aaabb');
replace into t1 values ('jonas % ');
replace into t1 values ('jonas % ');
select * from t1; select * from t1;
a a
jonas % aaabb
replace into t1 set a = 'AAABB';
select * from t1;
a
AAABB
replace into t1 set a = 'aAaBb';
select * from t1;
a
aAaBb
replace into t1 set a = 'aaabb';
select * from t1;
a
aaabb
drop table t1; drop table t1;

View File

@ -375,3 +375,28 @@ drop procedure foo;
drop function fn1; drop function fn1;
drop database mysqltest1; drop database mysqltest1;
drop user "zedjzlcsjhd"@127.0.0.1; drop user "zedjzlcsjhd"@127.0.0.1;
use test;
use test;
drop function if exists f1;
create function f1() returns int reads sql data
begin
declare var integer;
declare c cursor for select a from v1;
open c;
fetch c into var;
close c;
return var;
end|
create view v1 as select 1 as a;
create table t1 (a int);
insert into t1 (a) values (f1());
select * from t1;
a
1
drop view v1;
drop function f1;
select * from t1;
a
1
drop table t1;
reset master;

View File

@ -872,6 +872,109 @@ names
foo4 foo4
drop procedure bug13510_3| drop procedure bug13510_3|
drop procedure bug13510_4| drop procedure bug13510_4|
drop function if exists bug_13627_f|
CREATE TABLE t1 (a int)|
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DROP TRIGGER test1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN DROP TRIGGER test1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN load table t1 from master; END |
ERROR 0A000: LOAD TABLE is not allowed in stored procedures
CREATE FUNCTION bug_13627_f() returns int BEGIN load table t1 from master; return 1; END |
ERROR 0A000: LOAD TABLE is not allowed in stored procedures
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create table t2 (a int); END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN create table t2 (a int); return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create index t1_i on t1 (a); END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN create index t1_i on t1 (a); return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter table t1 add column b int; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN alter table t1 add column b int; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN rename table t1 to t2; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN rename table t1 to t2; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN truncate table t1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN truncate table t1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop table t1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN drop table t1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop index t1_i on t1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN drop index t1_i on t1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN unlock tables; END |
ERROR 0A000: UNLOCK is not allowed in stored procedures
CREATE FUNCTION bug_13627_f() returns int BEGIN unlock tables; return 1; END |
ERROR 0A000: UNLOCK is not allowed in stored procedures
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN LOCK TABLE t1 READ; END |
ERROR 0A000: LOCK is not allowed in stored procedures
CREATE FUNCTION bug_13627_f() returns int BEGIN LOCK TABLE t1 READ; return 1; END |
ERROR 0A000: LOCK is not allowed in stored procedures
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create database mysqltest; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN create database mysqltest; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop database mysqltest; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN drop database mysqltest; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN rename user 'mysqltest_2' to 'mysqltest_1'; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN rename user 'mysqltest_2' to 'mysqltest_1'; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create view v1 as select 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN create view v1 as select 1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter view v1 as select 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN alter view v1 as select 1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop view v1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE FUNCTION bug_13627_f() returns int BEGIN drop view v1; return 1; END |
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create trigger tr2 before insert on t1 for each row do select 1; END |
ERROR 2F003: Can't create a TRIGGER from within another stored routine
CREATE FUNCTION bug_13627_f() returns int BEGIN create trigger tr2 before insert on t1 for each row do select 1; return 1; END |
ERROR 2F003: Can't create a TRIGGER from within another stored routine
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop function bug_13627_f; END |
ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
CREATE FUNCTION bug_13627_f() returns int BEGIN drop function bug_13627_f; return 1; END |
ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create function f2 () returns int return 1; END |
ERROR 2F003: Can't create a FUNCTION from within another stored routine
CREATE FUNCTION bug_13627_f() returns int BEGIN create function f2 () returns int return 1; return 1; END |
ERROR 2F003: Can't create a FUNCTION from within another stored routine
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
CREATE TEMPORARY TABLE t2 (a int);
DROP TEMPORARY TABLE t2;
END |
CREATE FUNCTION bug_13627_f() returns int
BEGIN
CREATE TEMPORARY TABLE t2 (a int);
DROP TEMPORARY TABLE t2;
return 1;
END |
drop table t1|
drop function bug_13627_f|
create database mysqltest1; create database mysqltest1;
use mysqltest1; use mysqltest1;
drop database mysqltest1; drop database mysqltest1;

View File

@ -15,4 +15,3 @@ rpl_relayrotate : Unstable test case, bug#12429
rpl_until : Unstable test case, bug#12429 rpl_until : Unstable test case, bug#12429
rpl_deadlock : Unstable test case, bug#12429 rpl_deadlock : Unstable test case, bug#12429
kill : Unstable test case, bug#9712 kill : Unstable test case, bug#9712
archive_gis : The test fails on 32bit Linux

View File

@ -2,8 +2,6 @@
# simple test of all group functions # simple test of all group functions
# #
--source include/have_innodb.inc
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2;
--enable_warnings --enable_warnings
@ -545,10 +543,12 @@ DROP TABLE t1;
# Bug #12882 min/max inconsistent on empty table # Bug #12882 min/max inconsistent on empty table
# #
--disable_warnings
create table t1m (a int) engine=myisam; create table t1m (a int) engine=myisam;
create table t1i (a int) engine=innodb; create table t1i (a int) engine=innodb;
create table t2m (a int) engine=myisam; create table t2m (a int) engine=myisam;
create table t2i (a int) engine=innodb; create table t2i (a int) engine=innodb;
--enable_warnings
insert into t2m values (5); insert into t2m values (5);
insert into t2i values (5); insert into t2i values (5);

View File

@ -347,4 +347,79 @@ drop table t3;
drop table t4; drop table t4;
drop table t5; drop table t5;
#
# Bug#14397 - OPTIMIZE TABLE with an open HANDLER causes a crash
#
create table t1 (c1 int);
insert into t1 values (1);
# client 1
handler t1 open;
handler t1 read first;
# client 2
connect (con2,localhost,root,,);
connection con2;
--exec echo send the below to another connection, do not wait for the result
send optimize table t1;
--sleep 1
# client 1
--exec echo proceed with the normal connection
connection default;
handler t1 read next;
handler t1 close;
# client 2
--exec echo read the result from the other connection
connection con2;
reap;
# client 1
--exec echo proceed with the normal connection
connection default;
drop table t1;
# End of 4.1 tests # End of 4.1 tests
#
# Addendum to Bug#14397 - OPTIMIZE TABLE with an open HANDLER causes a crash
# Show that DROP TABLE can no longer deadlock against
# FLUSH TABLES WITH READ LOCK. This is a 5.0 issue.
#
create table t1 (c1 int);
insert into t1 values (14397);
flush tables with read lock;
# The thread with the global read lock cannot drop the table itself:
--error 1223
drop table t1;
#
# client 2
# We need a second connection to try the drop.
# The drop waits for the global read lock to go away.
# Without the addendum fix it locked LOCK_open before entering the wait loop.
connection con2;
--exec echo send the below to another connection, do not wait for the result
send drop table t1;
--sleep 1
#
# client 1
# Now we need something that wants LOCK_open. A simple table access which
# opens the table does the trick.
--exec echo proceed with the normal connection
connection default;
# This would hang on LOCK_open without the 5.0 addendum fix.
select * from t1;
# Release the read lock. This should make the DROP go through.
unlock tables;
#
# client 2
# Read the result of the drop command.
connection con2;
--exec echo read the result from the other connection
reap;
#
# client 1
# Now back to normal operation. The table should not exist any more.
--exec echo proceed with the normal connection
connection default;
--error 1146
select * from t1;
# Just to be sure and not confuse the next test case writer.
drop table if exists t1;

View File

@ -476,6 +476,18 @@ explain select sql_big_result distinct t1.a from t1,t2 order by t2.a;
explain select distinct t1.a from t1,t2 order by t2.a; explain select distinct t1.a from t1,t2 order by t2.a;
drop table t1,t2; drop table t1,t2;
#
# Bug#14616 - Freshly imported table returns error 124 when using LIMIT
#
create table t1 (
c1 varchar(32),
key (c1)
) engine=myisam;
alter table t1 disable keys;
insert into t1 values ('a'), ('b');
select c1 from t1 order by c1 limit 1;
drop table t1;
# #
# Test RTREE index # Test RTREE index
# #

View File

@ -237,13 +237,18 @@ drop table t1;
#select a,b,length(a),length(b) from t1 where a='c' and b='c'; #select a,b,length(a),length(b) from t1 where a='c' and b='c';
#drop table t1; #drop table t1;
# bug # bug#14007
create table t1 ( create table t1 (
a char(10) primary key a char(10) primary key
) engine=ndb; ) engine=ndbcluster default charset=latin1;
insert into t1 values ('jonas % ');
replace into t1 values ('jonas % '); insert into t1 values ('aaabb');
replace into t1 values ('jonas % '); select * from t1;
replace into t1 set a = 'AAABB';
select * from t1;
replace into t1 set a = 'aAaBb';
select * from t1;
replace into t1 set a = 'aaabb';
select * from t1; select * from t1;
drop table t1; drop table t1;

View File

@ -360,4 +360,40 @@ connection master;
drop function fn1; drop function fn1;
drop database mysqltest1; drop database mysqltest1;
drop user "zedjzlcsjhd"@127.0.0.1; drop user "zedjzlcsjhd"@127.0.0.1;
use test;
sync_slave_with_master; sync_slave_with_master;
use test;
#
# Bug#14077 "Failure to replicate a stored function with a cursor":
# verify that stored routines with cursors work on slave.
#
connection master;
--disable_warnings
drop function if exists f1;
--enable_warnings
delimiter |;
create function f1() returns int reads sql data
begin
declare var integer;
declare c cursor for select a from v1;
open c;
fetch c into var;
close c;
return var;
end|
delimiter ;|
create view v1 as select 1 as a;
create table t1 (a int);
insert into t1 (a) values (f1());
select * from t1;
drop view v1;
drop function f1;
sync_slave_with_master;
connection slave;
select * from t1;
# cleanup
connection master;
drop table t1;
reset master;

View File

@ -1263,6 +1263,144 @@ call bug13510_4()|
drop procedure bug13510_3| drop procedure bug13510_3|
drop procedure bug13510_4| drop procedure bug13510_4|
#
# Test that statements which implicitly commit transaction are prohibited
# in stored function and triggers. Attempt to create function or trigger
# containing such statement should produce error (includes test for
# bug #13627).
#
--disable_warnings
drop function if exists bug_13627_f|
--enable_warnings
CREATE TABLE t1 (a int)|
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DROP TRIGGER test1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN DROP TRIGGER test1; return 1; END |
-- error ER_SP_BADSTATEMENT
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN load table t1 from master; END |
-- error ER_SP_BADSTATEMENT
CREATE FUNCTION bug_13627_f() returns int BEGIN load table t1 from master; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create table t2 (a int); END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN create table t2 (a int); return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create index t1_i on t1 (a); END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN create index t1_i on t1 (a); return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter table t1 add column b int; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN alter table t1 add column b int; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN rename table t1 to t2; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN rename table t1 to t2; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN truncate table t1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN truncate table t1; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop table t1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN drop table t1; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop index t1_i on t1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN drop index t1_i on t1; return 1; END |
-- error ER_SP_BADSTATEMENT
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN unlock tables; END |
-- error ER_SP_BADSTATEMENT
CREATE FUNCTION bug_13627_f() returns int BEGIN unlock tables; return 1; END |
-- error ER_SP_BADSTATEMENT
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN LOCK TABLE t1 READ; END |
-- error ER_SP_BADSTATEMENT
CREATE FUNCTION bug_13627_f() returns int BEGIN LOCK TABLE t1 READ; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create database mysqltest; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN create database mysqltest; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop database mysqltest; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN drop database mysqltest; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN rename user 'mysqltest_2' to 'mysqltest_1'; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN rename user 'mysqltest_2' to 'mysqltest_1'; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create view v1 as select 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN create view v1 as select 1; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter view v1 as select 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN alter view v1 as select 1; return 1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop view v1; END |
-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
CREATE FUNCTION bug_13627_f() returns int BEGIN drop view v1; return 1; END |
-- error ER_SP_NO_RECURSIVE_CREATE
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create trigger tr2 before insert on t1 for each row do select 1; END |
-- error ER_SP_NO_RECURSIVE_CREATE
CREATE FUNCTION bug_13627_f() returns int BEGIN create trigger tr2 before insert on t1 for each row do select 1; return 1; END |
-- error ER_SP_NO_DROP_SP
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop function bug_13627_f; END |
-- error ER_SP_NO_DROP_SP
CREATE FUNCTION bug_13627_f() returns int BEGIN drop function bug_13627_f; return 1; END |
-- error ER_SP_NO_RECURSIVE_CREATE
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create function f2 () returns int return 1; END |
-- error ER_SP_NO_RECURSIVE_CREATE
CREATE FUNCTION bug_13627_f() returns int BEGIN create function f2 () returns int return 1; return 1; END |
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
CREATE TEMPORARY TABLE t2 (a int);
DROP TEMPORARY TABLE t2;
END |
CREATE FUNCTION bug_13627_f() returns int
BEGIN
CREATE TEMPORARY TABLE t2 (a int);
DROP TEMPORARY TABLE t2;
return 1;
END |
drop table t1|
drop function bug_13627_f|
delimiter ;| delimiter ;|
# #

View File

@ -684,6 +684,21 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr)
Uint32 attrDescriptorIndex = regTabPtr->tabDescriptor + (attributeId << ZAD_LOG_SIZE); Uint32 attrDescriptorIndex = regTabPtr->tabDescriptor + (attributeId << ZAD_LOG_SIZE);
Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr; Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr;
Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr; Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr;
Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset);
if (charsetFlag) {
Uint32 csIndex = AttributeOffset::getCharsetPos(attributeOffset);
CHARSET_INFO* cs = regTabPtr->charsetArray[csIndex];
Uint32 srcPos = 0;
Uint32 dstPos = 0;
xfrm_attr(attrDescriptor, cs, &updateBuffer[1], srcPos,
&xfrmBuffer[1], dstPos, MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY);
ahIn.setDataSize(dstPos);
xfrmBuffer[0] = ahIn.m_value;
updateBuffer = xfrmBuffer;
}
ReadFunction f = regTabPtr->readFunctionArray[attributeId]; ReadFunction f = regTabPtr->readFunctionArray[attributeId];
AttributeHeader::init(&attributeHeader, attributeId, 0); AttributeHeader::init(&attributeHeader, attributeId, 0);
@ -691,7 +706,7 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr)
tMaxRead = MAX_KEY_SIZE_IN_WORDS; tMaxRead = MAX_KEY_SIZE_IN_WORDS;
bool tmp = tXfrmFlag; bool tmp = tXfrmFlag;
tXfrmFlag = false; tXfrmFlag = true;
ndbrequire((this->*f)(&keyReadBuffer[0], ahOut, attrDescriptor, attributeOffset)); ndbrequire((this->*f)(&keyReadBuffer[0], ahOut, attrDescriptor, attributeOffset));
tXfrmFlag = tmp; tXfrmFlag = tmp;
ndbrequire(tOutBufIndex == ahOut->getDataSize()); ndbrequire(tOutBufIndex == ahOut->getDataSize());

View File

@ -1868,55 +1868,61 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
while (i < noOfKeyAttr) while (i < noOfKeyAttr)
{ {
const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i]; const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i];
Uint32 dstWords =
Uint32 srcBytes = xfrm_attr(keyAttr.attributeDescriptor, keyAttr.charsetInfo,
AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); src, srcPos, dst, dstPos, dstSize);
Uint32 srcWords = (srcBytes + 3) / 4;
Uint32 dstWords = ~0;
uchar* dstPtr = (uchar*)&dst[dstPos];
const uchar* srcPtr = (const uchar*)&src[srcPos];
CHARSET_INFO* cs = keyAttr.charsetInfo;
if (cs == NULL)
{
jam();
memcpy(dstPtr, srcPtr, srcWords << 2);
dstWords = srcWords;
}
else
{
jam();
Uint32 typeId =
AttributeDescriptor::getType(keyAttr.attributeDescriptor);
Uint32 lb, len;
bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
ndbrequire(ok);
Uint32 xmul = cs->strxfrm_multiply;
if (xmul == 0)
xmul = 1;
/*
* Varchar is really Char. End spaces do not matter. To get
* same hash we blank-pad to maximum length via strnxfrm.
* TODO use MySQL charset-aware hash function instead
*/
Uint32 dstLen = xmul * (srcBytes - lb);
ndbrequire(dstLen <= ((dstSize - dstPos) << 2));
int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
ndbrequire(n != -1);
while ((n & 3) != 0)
{
dstPtr[n++] = 0;
}
dstWords = (n >> 2);
}
dstPos += dstWords;
srcPos += srcWords;
keyPartLen[i++] = dstWords; keyPartLen[i++] = dstWords;
} }
return dstPos; return dstPos;
} }
Uint32
SimulatedBlock::xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
const Uint32* src, Uint32 & srcPos,
Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const
{
Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDesc);
Uint32 srcWords = (srcBytes + 3) / 4;
Uint32 dstWords = ~0;
uchar* dstPtr = (uchar*)&dst[dstPos];
const uchar* srcPtr = (const uchar*)&src[srcPos];
if (cs == NULL)
{
jam();
memcpy(dstPtr, srcPtr, srcWords << 2);
dstWords = srcWords;
}
else
{
jam();
Uint32 typeId = AttributeDescriptor::getType(attrDesc);
Uint32 lb, len;
bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
ndbrequire(ok);
Uint32 xmul = cs->strxfrm_multiply;
if (xmul == 0)
xmul = 1;
/*
* Varchar end-spaces are ignored in comparisons. To get same hash
* we blank-pad to maximum length via strnxfrm.
*/
Uint32 dstLen = xmul * (srcBytes - lb);
ndbrequire(dstLen <= ((dstSize - dstPos) << 2));
int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
ndbrequire(n != -1);
while ((n & 3) != 0)
{
dstPtr[n++] = 0;
}
dstWords = (n >> 2);
}
dstPos += dstWords;
srcPos += srcWords;
return dstWords;
}
Uint32 Uint32
SimulatedBlock::create_distr_key(Uint32 tableId, SimulatedBlock::create_distr_key(Uint32 tableId,
Uint32 *data, Uint32 *data,

View File

@ -395,8 +395,12 @@ protected:
* @return length * @return length
*/ */
Uint32 xfrm_key(Uint32 tab, const Uint32* src, Uint32 xfrm_key(Uint32 tab, const Uint32* src,
Uint32 *dst, Uint32 dstLen, Uint32 *dst, Uint32 dstSize,
Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const; Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const;
Uint32 xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
const Uint32* src, Uint32 & srcPos,
Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const;
/** /**
* *

View File

@ -233,7 +233,8 @@ ha_archive::ha_archive(TABLE *table_arg)
buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info); buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
/* The size of the offset value we will use for position() */ /* The size of the offset value we will use for position() */
ref_length = sizeof(z_off_t); ref_length = 2 << ((zlibCompileFlags() >> 6) & 3);
DBUG_ASSERT(ref_length <= sizeof(z_off_t));
} }
/* /*

View File

@ -815,10 +815,13 @@ static void print_lock_error(int error, const char *table)
access to them is protected with a mutex LOCK_global_read_lock access to them is protected with a mutex LOCK_global_read_lock
(XXX: one should never take LOCK_open if LOCK_global_read_lock is taken, (XXX: one should never take LOCK_open if LOCK_global_read_lock is
otherwise a deadlock may occur - see mysql_rm_table. Other mutexes could taken, otherwise a deadlock may occur. Other mutexes could be a
be a problem too - grep the code for global_read_lock if you want to use problem too - grep the code for global_read_lock if you want to use
any other mutex here) any other mutex here) Also one must not hold LOCK_open when calling
wait_if_global_read_lock(). When the thread with the global read lock
tries to close its tables, it needs to take LOCK_open in
close_thread_table().
How blocking of threads by global read lock is achieved: that's How blocking of threads by global read lock is achieved: that's
advisory. Any piece of code which should be blocked by global read lock must advisory. Any piece of code which should be blocked by global read lock must
@ -937,6 +940,13 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
DBUG_ENTER("wait_if_global_read_lock"); DBUG_ENTER("wait_if_global_read_lock");
LINT_INIT(old_message); LINT_INIT(old_message);
/*
Assert that we do not own LOCK_open. If we would own it, other
threads could not close their tables. This would make a pretty
deadlock.
*/
safe_mutex_assert_not_owner(&LOCK_open);
(void) pthread_mutex_lock(&LOCK_global_read_lock); (void) pthread_mutex_lock(&LOCK_global_read_lock);
if ((need_exit_cond= must_wait)) if ((need_exit_cond= must_wait))
{ {

View File

@ -891,7 +891,8 @@ 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); int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
bool is_locked);
/* mysql_ha_flush mode_flags bits */ /* mysql_ha_flush mode_flags bits */
#define MYSQL_HA_CLOSE_FINAL 0x00 #define MYSQL_HA_CLOSE_FINAL 0x00
#define MYSQL_HA_REOPEN_ON_USAGE 0x01 #define MYSQL_HA_REOPEN_ON_USAGE 0x01

View File

@ -120,6 +120,45 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_DEALLOCATE_PREPARE: case SQLCOM_DEALLOCATE_PREPARE:
flags= sp_head::CONTAINS_DYNAMIC_SQL; flags= sp_head::CONTAINS_DYNAMIC_SQL;
break; break;
case SQLCOM_CREATE_TABLE:
if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
flags= 0;
else
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
break;
case SQLCOM_DROP_TABLE:
if (lex->drop_temporary)
flags= 0;
else
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
break;
case SQLCOM_CREATE_INDEX:
case SQLCOM_CREATE_DB:
case SQLCOM_CREATE_VIEW:
case SQLCOM_CREATE_TRIGGER:
case SQLCOM_CREATE_USER:
case SQLCOM_ALTER_TABLE:
case SQLCOM_BEGIN:
case SQLCOM_RENAME_TABLE:
case SQLCOM_RENAME_USER:
case SQLCOM_DROP_INDEX:
case SQLCOM_DROP_DB:
case SQLCOM_DROP_USER:
case SQLCOM_DROP_VIEW:
case SQLCOM_DROP_TRIGGER:
case SQLCOM_TRUNCATE:
case SQLCOM_COMMIT:
case SQLCOM_ROLLBACK:
case SQLCOM_LOAD_MASTER_DATA:
case SQLCOM_LOCK_TABLES:
case SQLCOM_CREATE_PROCEDURE:
case SQLCOM_CREATE_SPFUNCTION:
case SQLCOM_ALTER_PROCEDURE:
case SQLCOM_ALTER_FUNCTION:
case SQLCOM_DROP_PROCEDURE:
case SQLCOM_DROP_FUNCTION:
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
break;
default: default:
flags= 0; flags= 0;
break; break;

View File

@ -115,10 +115,13 @@ public:
MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s) MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
CONTAINS_DYNAMIC_SQL= 16, // Is set if a procedure with PREPARE/EXECUTE CONTAINS_DYNAMIC_SQL= 16, // Is set if a procedure with PREPARE/EXECUTE
IS_INVOKED= 32, // Is set if this sp_head is being used IS_INVOKED= 32, // Is set if this sp_head is being used
HAS_SET_AUTOCOMMIT_STMT = 64 // Is set if a procedure with 'set autocommit' HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit'
/* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */
HAS_COMMIT_OR_ROLLBACK= 128
}; };
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE /* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
int m_type;
uint m_flags; // Boolean attributes of a stored routine uint m_flags; // Boolean attributes of a stored routine
enum enum_field_types m_returns; // For FUNCTIONs only enum enum_field_types m_returns; // For FUNCTIONs only
Field::geometry_type m_geom_returns; Field::geometry_type m_geom_returns;
@ -292,6 +295,12 @@ public:
my_error(ER_SP_NO_RETSET, MYF(0), where); my_error(ER_SP_NO_RETSET, MYF(0), where);
else if (m_flags & HAS_SET_AUTOCOMMIT_STMT) else if (m_flags & HAS_SET_AUTOCOMMIT_STMT)
my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0)); my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0));
else if (m_type != TYPE_ENUM_PROCEDURE &&
(m_flags & sp_head::HAS_COMMIT_OR_ROLLBACK))
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
return TRUE;
}
return test(m_flags & return test(m_flags &
(CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT)); (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT));
} }

View File

@ -311,7 +311,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, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL,
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",
@ -1238,7 +1239,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
/* close handler tables which are marked for flush */ /* close handler tables which are marked for flush */
if (thd->handler_tables) if (thd->handler_tables)
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE); mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
table && table->in_use ; table && table->in_use ;
@ -1642,7 +1643,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); mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
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);

View File

@ -376,7 +376,7 @@ void THD::cleanup(void)
close_thread_tables(this); close_thread_tables(this);
} }
mysql_ha_flush(this, (TABLE_LIST*) 0, mysql_ha_flush(this, (TABLE_LIST*) 0,
MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL); MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL, FALSE);
hash_free(&handler_tables_hash); hash_free(&handler_tables_hash);
delete_dynamic(&user_var_events); delete_dynamic(&user_var_events);
hash_free(&user_vars); hash_free(&user_vars);

View File

@ -336,6 +336,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
ha_rows select_limit_cnt, ha_rows offset_limit_cnt) ha_rows select_limit_cnt, ha_rows offset_limit_cnt)
{ {
TABLE_LIST *hash_tables; TABLE_LIST *hash_tables;
TABLE **table_ptr;
TABLE *table; TABLE *table;
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
List<Item> list; List<Item> list;
@ -368,6 +369,28 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p", DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p",
hash_tables->db, hash_tables->table_name, hash_tables->db, hash_tables->table_name,
hash_tables->alias, table)); hash_tables->alias, table));
/* Table might have been flushed. */
if (table && (table->s->version != refresh_version))
{
/*
We must follow the thd->handler_tables chain, as we need the
address of the 'next' pointer referencing this table
for close_thread_table().
*/
for (table_ptr= &(thd->handler_tables);
*table_ptr && (*table_ptr != table);
table_ptr= &(*table_ptr)->next)
{}
(*table_ptr)->file->ha_index_or_rnd_end();
VOID(pthread_mutex_lock(&LOCK_open));
if (close_thread_table(thd, table_ptr))
{
/* Tell threads waiting for refresh that something has happened */
VOID(pthread_cond_broadcast(&COND_refresh));
}
VOID(pthread_mutex_unlock(&LOCK_open));
table= hash_tables->table= NULL;
}
if (!table) if (!table)
{ {
/* /*
@ -594,6 +617,7 @@ err0:
MYSQL_HA_REOPEN_ON_USAGE mark for reopen. MYSQL_HA_REOPEN_ON_USAGE mark for reopen.
MYSQL_HA_FLUSH_ALL flush all tables, not only MYSQL_HA_FLUSH_ALL flush all tables, not only
those marked for flush. those marked for flush.
is_locked If LOCK_open is locked.
DESCRIPTION DESCRIPTION
The list of HANDLER tables may be NULL, in which case all HANDLER The list of HANDLER tables may be NULL, in which case all HANDLER
@ -601,7 +625,6 @@ err0:
If 'tables' is NULL and MYSQL_HA_FLUSH_ALL is not set, If 'tables' is NULL and MYSQL_HA_FLUSH_ALL is not set,
all HANDLER tables marked for flush are closed. all HANDLER tables marked for flush are closed.
Broadcasts a COND_refresh condition, for every table closed. Broadcasts a COND_refresh condition, for every table closed.
The caller must lock LOCK_open.
NOTE NOTE
Since mysql_ha_flush() is called when the base table has to be closed, Since mysql_ha_flush() is called when the base table has to be closed,
@ -611,10 +634,12 @@ err0:
0 ok 0 ok
*/ */
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags) int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
bool is_locked)
{ {
TABLE_LIST *tmp_tables; TABLE_LIST *tmp_tables;
TABLE **table_ptr; TABLE **table_ptr;
bool did_lock= FALSE;
DBUG_ENTER("mysql_ha_flush"); DBUG_ENTER("mysql_ha_flush");
DBUG_PRINT("enter", ("tables: %p mode_flags: 0x%02x", tables, mode_flags)); DBUG_PRINT("enter", ("tables: %p mode_flags: 0x%02x", tables, mode_flags));
@ -640,6 +665,12 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags)
(*table_ptr)->s->db, (*table_ptr)->s->db,
(*table_ptr)->s->table_name, (*table_ptr)->s->table_name,
(*table_ptr)->alias)); (*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); mysql_ha_flush_table(thd, table_ptr, mode_flags);
continue; continue;
} }
@ -658,6 +689,12 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags)
if ((mode_flags & MYSQL_HA_FLUSH_ALL) || if ((mode_flags & MYSQL_HA_FLUSH_ALL) ||
((*table_ptr)->s->version != refresh_version)) ((*table_ptr)->s->version != refresh_version))
{ {
/* 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); mysql_ha_flush_table(thd, table_ptr, mode_flags);
continue; continue;
} }
@ -665,6 +702,10 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags)
} }
} }
/* Release the lock if it was taken by this function. */
if (did_lock)
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -696,8 +737,8 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
table->alias, mode_flags)); table->alias, mode_flags));
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
(byte*) (*table_ptr)->alias, (byte*) table->alias,
strlen((*table_ptr)->alias) + 1))) strlen(table->alias) + 1)))
{ {
if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE)) if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE))
{ {
@ -711,7 +752,9 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
} }
} }
safe_mutex_assert_owner(&LOCK_open);
(*table_ptr)->file->ha_index_or_rnd_end(); (*table_ptr)->file->ha_index_or_rnd_end();
safe_mutex_assert_owner(&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 */

View File

@ -2403,18 +2403,6 @@ mysql_execute_command(THD *thd)
reset_one_shot_variables(thd); reset_one_shot_variables(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#ifndef TO_BE_DELETED
/*
This is a workaround to deal with the shortcoming in 3.23.44-3.23.46
masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK()
as DO RELEASE_LOCK()
*/
if (lex->sql_command == SQLCOM_SELECT)
{
lex->sql_command = SQLCOM_DO;
lex->insert_list = &select_lex->item_list;
}
#endif
} }
else else
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */

View File

@ -11142,8 +11142,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
DBUG_ENTER("test_if_skip_sort_order"); DBUG_ENTER("test_if_skip_sort_order");
LINT_INIT(ref_key_parts); LINT_INIT(ref_key_parts);
/* Check which keys can be used to resolve ORDER BY */ /*
usable_keys.set_all(); Check which keys can be used to resolve ORDER BY.
We must not try to use disabled keys.
*/
usable_keys= table->s->keys_in_use;
for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next) for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
{ {
Item *item= (*tmp_order->item)->real_item(); Item *item= (*tmp_order->item)->real_item();

View File

@ -103,23 +103,28 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
/* mark for close and remove all cached entries */ /* mark for close and remove all cached entries */
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
VOID(pthread_mutex_lock(&LOCK_open));
if (!drop_temporary) if (!drop_temporary)
{ {
if ((error= wait_if_global_read_lock(thd, 0, 1))) if ((error= wait_if_global_read_lock(thd, 0, 1)))
{ {
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name); my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name);
goto err; DBUG_RETURN(TRUE);
} }
else else
need_start_waiters= TRUE; need_start_waiters= TRUE;
} }
/*
Acquire LOCK_open after wait_if_global_read_lock(). If we would hold
LOCK_open during wait_if_global_read_lock(), other threads could not
close their tables. This would make a pretty deadlock.
*/
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
VOID(pthread_mutex_lock(&LOCK_open));
error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
err:
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
@ -232,7 +237,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
char *db=table->db; char *db=table->db;
db_type table_type= DB_TYPE_UNKNOWN; db_type table_type= DB_TYPE_UNKNOWN;
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL); mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, TRUE);
if (!close_temporary_table(thd, db, table->table_name)) if (!close_temporary_table(thd, db, table->table_name))
{ {
tmp_table_deleted=1; tmp_table_deleted=1;
@ -2171,7 +2176,7 @@ 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); mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE);
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];
@ -3127,8 +3132,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
new_db= db; new_db= db;
used_fields=create_info->used_fields; used_fields=create_info->used_fields;
mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE);
mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL);
/* 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)
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,

View File

@ -1159,11 +1159,6 @@ create:
| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_CREATE_INDEX; lex->sql_command= SQLCOM_CREATE_INDEX;
if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
TL_OPTION_UPDATING)) TL_OPTION_UPDATING))
@ -3299,11 +3294,6 @@ alter:
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_ALTER_TABLE; lex->sql_command= SQLCOM_ALTER_TABLE;
lex->name= 0; lex->name= 0;
lex->duplicates= DUP_ERROR; lex->duplicates= DUP_ERROR;
@ -3614,11 +3604,6 @@ start:
START_SYM TRANSACTION_SYM start_transaction_opts START_SYM TRANSACTION_SYM start_transaction_opts
{ {
LEX *lex= Lex; LEX *lex= Lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_BEGIN; lex->sql_command= SQLCOM_BEGIN;
lex->start_transaction_opt= $3; lex->start_transaction_opt= $3;
} }
@ -3803,13 +3788,7 @@ opt_no_write_to_binlog:
rename: rename:
RENAME table_or_tables RENAME table_or_tables
{ {
LEX *lex= Lex; Lex->sql_command= SQLCOM_RENAME_TABLE;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command=SQLCOM_RENAME_TABLE;
} }
table_to_table_list table_to_table_list
{} {}
@ -5946,21 +5925,10 @@ drop:
lex->sql_command = SQLCOM_DROP_TABLE; lex->sql_command = SQLCOM_DROP_TABLE;
lex->drop_temporary= $2; lex->drop_temporary= $2;
lex->drop_if_exists= $4; lex->drop_if_exists= $4;
if (!lex->drop_temporary && lex->sphead &&
lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
} }
| DROP INDEX_SYM ident ON table_ident {} | DROP INDEX_SYM ident ON table_ident {}
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_DROP_INDEX; lex->sql_command= SQLCOM_DROP_INDEX;
lex->alter_info.drop_list.empty(); lex->alter_info.drop_list.empty();
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
@ -6006,13 +5974,7 @@ drop:
} }
| DROP VIEW_SYM if_exists table_list opt_restrict | DROP VIEW_SYM if_exists table_list opt_restrict
{ {
THD *thd= YYTHD; LEX *lex= Lex;
LEX *lex= thd->lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_DROP_VIEW; lex->sql_command= SQLCOM_DROP_VIEW;
lex->drop_if_exists= $3; lex->drop_if_exists= $3;
} }
@ -8652,11 +8614,6 @@ begin:
BEGIN_SYM BEGIN_SYM
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command = SQLCOM_BEGIN; lex->sql_command = SQLCOM_BEGIN;
lex->start_transaction_opt= 0; lex->start_transaction_opt= 0;
} }
@ -8689,11 +8646,6 @@ commit:
COMMIT_SYM opt_work opt_chain opt_release COMMIT_SYM opt_work opt_chain opt_release
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_COMMIT; lex->sql_command= SQLCOM_COMMIT;
lex->tx_chain= $3; lex->tx_chain= $3;
lex->tx_release= $4; lex->tx_release= $4;
@ -8704,11 +8656,6 @@ rollback:
ROLLBACK_SYM opt_work opt_chain opt_release ROLLBACK_SYM opt_work opt_chain opt_release
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
{
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
YYABORT;
}
lex->sql_command= SQLCOM_ROLLBACK; lex->sql_command= SQLCOM_ROLLBACK;
lex->tx_chain= $3; lex->tx_chain= $3;
lex->tx_release= $4; lex->tx_release= $4;