merge mysql-5.1->mysql-5.1-security

This commit is contained in:
Georgi Kodinov 2012-03-08 17:16:53 +02:00
commit 4b5306fd6e
38 changed files with 1112 additions and 163 deletions

View file

@ -4,6 +4,9 @@
# $engine_type -- storage engine to be tested
# $test_foreign_keys -- 0, skip foreign key tests
# -- 1, do not skip foreign key tests
# $partitions_a -- partition by column 'a'
# $partitions_id -- partition by column 'id'
# $partitions_s1 -- partition by column 's1'
# have to be set before sourcing this script.
#
# Last update:
@ -19,47 +22,61 @@ eval SET SESSION STORAGE_ENGINE = $engine_type;
drop table if exists t1,t2,t3;
--enable_warnings
set @save_query_cache_size = @@global.query_cache_size;
set GLOBAL query_cache_size = 1355776;
#
# Without auto_commit.
#
flush status;
set autocommit=0;
create table t1 (a int not null);
eval create table t1 (a int not null)$partitions_a;
insert into t1 values (1),(2),(3);
--sorted_result
select * from t1;
show status like "Qcache_queries_in_cache";
drop table t1;
commit;
set autocommit=1;
begin;
create table t1 (a int not null);
eval create table t1 (a int not null)$partitions_a;
insert into t1 values (1),(2),(3);
--sorted_result
select * from t1;
show status like "Qcache_queries_in_cache";
drop table t1;
commit;
create table t1 (a int not null);
create table t2 (a int not null);
create table t3 (a int not null);
eval create table t1 (a int not null)$partitions_a;
eval create table t2 (a int not null)$partitions_a;
eval create table t3 (a int not null)$partitions_a;
insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1),(2);
--sorted_result
select * from t1;
--sorted_result
select * from t2;
--sorted_result
select * from t3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
begin;
--sorted_result
select * from t1;
--sorted_result
select * from t2;
--sorted_result
select * from t3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
insert into t1 values (3);
insert into t2 values (3);
insert into t1 values (4);
--sorted_result
select * from t1;
--sorted_result
select * from t2;
--sorted_result
select * from t3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
@ -67,7 +84,7 @@ commit;
show status like "Qcache_queries_in_cache";
drop table t3,t2,t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
eval CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id))$partitions_id;
select count(*) from t1;
insert into t1 (id) values (0);
select count(*) from t1;
@ -78,8 +95,6 @@ if ($test_foreign_keys)
#
# one statement roll back inside transation
#
let $save_query_cache_size=`select @@global.query_cache_size`;
set GLOBAL query_cache_size=1355776;
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a));
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b));
CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`));
@ -95,9 +110,6 @@ insert into t3 VALUES ( NULL, 1, 1, 2 );
commit;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
drop table t3,t2,t1;
--disable_query_log
eval set GLOBAL query_cache_size=$save_query_cache_size;
--enable_query_log
}
#
@ -118,7 +130,7 @@ SET GLOBAL query_cache_size = 200000;
flush status;
SET @@autocommit=1;
eval SET SESSION STORAGE_ENGINE = $engine_type;
CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1));
eval CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1))$partitions_s1;
INSERT INTO t2 VALUES (1,repeat('a',10)),(2,repeat('a',10)),(3,repeat('a',10)),(4,repeat('a',10));
COMMIT;
START TRANSACTION;
@ -176,8 +188,8 @@ show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
# Final cleanup
eval set GLOBAL query_cache_size=$save_query_cache_size;
disconnect connection1;
--source include/wait_until_disconnected.inc
connection default;
set @@global.query_cache_size = @save_query_cache_size;
drop table t2;

View file

@ -1,5 +1,7 @@
SET SESSION STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2,t3;
set @save_query_cache_size = @@global.query_cache_size;
set GLOBAL query_cache_size = 1355776;
flush status;
set autocommit=0;
create table t1 (a int not null);
@ -100,7 +102,7 @@ show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
drop table t3,t2,t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
select count(*) from t1;
count(*)
0
@ -109,7 +111,6 @@ select count(*) from t1;
count(*)
1
drop table t1;
set GLOBAL query_cache_size=1355776;
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a));
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b));
CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`));
@ -218,5 +219,5 @@ Qcache_queries_in_cache 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
set GLOBAL query_cache_size=1048576;
set @@global.query_cache_size = @save_query_cache_size;
drop table t2;

View file

@ -776,4 +776,14 @@ SELECT 1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1);
1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1)
1
#
#
# Bug#13012483: EXPLAIN EXTENDED, PREPARED STATEMENT, CRASH IN CHECK_SIMPLE_EQUALITY
#
CREATE TABLE t1 (a INT);
PREPARE s FROM "SELECT 1 FROM t1 WHERE 1 < ALL (SELECT @:= (1 IN (SELECT 1 FROM t1)) FROM t1)";
EXECUTE s;
1
DROP TABLE t1;
# End of test BUG#13012483
#
End of 5.1 tests

View file

@ -0,0 +1,205 @@
SET SESSION STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2,t3;
set @save_query_cache_size = @@global.query_cache_size;
set GLOBAL query_cache_size = 1355776;
flush status;
set autocommit=0;
create table t1 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t1;
commit;
set autocommit=1;
begin;
create table t1 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t1;
commit;
create table t1 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
create table t2 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
create table t3 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1),(2);
select * from t1;
a
1
2
select * from t2;
a
1
2
select * from t3;
a
1
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
begin;
select * from t1;
a
1
2
select * from t2;
a
1
2
select * from t3;
a
1
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
insert into t1 values (3);
insert into t2 values (3);
insert into t1 values (4);
select * from t1;
a
1
2
3
4
select * from t2;
a
1
2
3
select * from t3;
a
1
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
commit;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t3,t2,t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) PARTITION BY HASH (id) PARTITIONS 3;
select count(*) from t1;
count(*)
0
insert into t1 (id) values (0);
select count(*) from t1;
count(*)
1
drop table t1;
SET SESSION STORAGE_ENGINE = InnoDB;
SET @@autocommit=1;
connection default
SHOW VARIABLES LIKE 'have_query_cache';
Variable_name Value
have_query_cache YES
SET GLOBAL query_cache_size = 200000;
flush status;
SET @@autocommit=1;
SET SESSION STORAGE_ENGINE = InnoDB;
CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1)) PARTITION BY KEY (s1) PARTITIONS 3;
INSERT INTO t2 VALUES (1,repeat('a',10)),(2,repeat('a',10)),(3,repeat('a',10)),(4,repeat('a',10));
COMMIT;
START TRANSACTION;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
0
UPDATE t2 SET s2 = 'w' WHERE s1 = 3;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
1
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
connection connection1
START TRANSACTION;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
0
INSERT INTO t2 VALUES (5,'w');
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
1
COMMIT;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
1
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
connection default
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
1
COMMIT;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
connection connection1
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
2
START TRANSACTION;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
2
INSERT INTO t2 VALUES (6,'w');
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
3
connection default
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
2
START TRANSACTION;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
2
DELETE from t2 WHERE s1=3;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
1
COMMIT;
connection connection1
COMMIT;
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
count(*)
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
set @@global.query_cache_size = @save_query_cache_size;
drop table t2;

View file

@ -527,3 +527,207 @@ SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%P
Host Db User Table_name Column_name Timestamp Column_priv
DROP TABLE t1;
DROP TABLE t2;
#
# Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
# IGNORED AND BREAKS REPLICATION
#
DROP TABLE IF EXISTS test_table;
DROP FUNCTION IF EXISTS test_function;
CREATE TABLE test_table (c1 CHAR(50));
SET @org_mode=@@sql_mode;
SET @@sql_mode='';
PREPARE insert_stmt FROM 'INSERT INTO test_table VALUES (?)';
PREPARE update_stmt FROM 'UPDATE test_table SET c1= ? WHERE c1= ?';
CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
BEGIN
DECLARE char_val CHAR(50);
SELECT c1 INTO char_val FROM test_table WHERE c1=var;
RETURN char_val;
END
$
SET @var1='abcd\'ef';
SET @var2='abcd\"ef';
SET @var3='abcd\bef';
SET @var4='abcd\nef';
SET @var5='abcd\ref';
SET @var6='abcd\tef';
SET @var7='abcd\\ef';
SET @var8='abcd\%ef';
SET @var9='abcd\_ef';
SET @to_var1='wxyz\'ef';
SET @to_var2='wxyz\"ef';
SET @to_var3='wxyz\bef';
SET @to_var4='wxyz\nef';
SET @to_var5='wxyz\ref';
SET @to_var6='wxyz\tef';
SET @to_var7='wxyz\\ef';
SET @to_var8='wxyz\%ef';
SET @to_var9='wxyz\_ef';
# STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
EXECUTE insert_stmt USING @var1;
EXECUTE insert_stmt USING @var2;
EXECUTE insert_stmt USING @var3;
EXECUTE insert_stmt USING @var4;
EXECUTE insert_stmt USING @var5;
EXECUTE insert_stmt USING @var6;
EXECUTE insert_stmt USING @var7;
EXECUTE insert_stmt USING @var8;
EXECUTE insert_stmt USING @var9;
SELECT * FROM test_table;
c1
abcd'ef
abcd"ef
abcdef
abcd
ef
abcd ef
abcd ef
abcd\ef
abcd\%ef
abcd\_ef
EXECUTE update_stmt USING @to_var1, @var1;
EXECUTE update_stmt USING @to_var2, @var2;
EXECUTE update_stmt USING @to_var3, @var3;
EXECUTE update_stmt USING @to_var4, @var4;
EXECUTE update_stmt USING @to_var5, @var5;
EXECUTE update_stmt USING @to_var6, @var6;
EXECUTE update_stmt USING @to_var7, @var7;
EXECUTE update_stmt USING @to_var8, @var8;
EXECUTE update_stmt USING @to_var9, @var9;
SELECT * FROM test_table;
c1
wxyz'ef
wxyz"ef
wxyzef
wxyz
ef
wxyz ef
wxyz ef
wxyz\ef
wxyz\%ef
wxyz\_ef
# END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
# STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
select test_function(@to_var1);
test_function(@to_var1)
wxyz'ef
SELECT test_function(@to_var2);
test_function(@to_var2)
wxyz"ef
SELECT test_function(@to_var3);
test_function(@to_var3)
wxyzef
SELECT test_function(@to_var4);
test_function(@to_var4)
wxyz
ef
SELECT test_function(@to_var5);
test_function(@to_var5)
wxyz ef
SELECT test_function(@to_var6);
test_function(@to_var6)
wxyz ef
SELECT test_function(@to_var7);
test_function(@to_var7)
wxyz\ef
SELECT test_function(@to_var8);
test_function(@to_var8)
wxyz\%ef
SELECT test_function(@to_var9);
test_function(@to_var9)
wxyz\_ef
# END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
DELETE FROM test_table;
DROP FUNCTION test_function;
SET @@sql_mode='NO_BACKSLASH_ESCAPES';
CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
BEGIN
DECLARE char_val CHAR(50);
SELECT c1 INTO char_val FROM test_table WHERE c1=var;
RETURN char_val;
END
$
# STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
EXECUTE insert_stmt USING @var1;
EXECUTE insert_stmt USING @var2;
EXECUTE insert_stmt USING @var3;
EXECUTE insert_stmt USING @var4;
EXECUTE insert_stmt USING @var5;
EXECUTE insert_stmt USING @var6;
EXECUTE insert_stmt USING @var7;
EXECUTE insert_stmt USING @var8;
EXECUTE insert_stmt USING @var9;
SELECT * FROM test_table;
c1
abcd'ef
abcd"ef
abcdef
abcd
ef
abcd ef
abcd ef
abcd\ef
abcd\%ef
abcd\_ef
EXECUTE update_stmt USING @to_var1, @var1;
EXECUTE update_stmt USING @to_var2, @var2;
EXECUTE update_stmt USING @to_var3, @var3;
EXECUTE update_stmt USING @to_var4, @var4;
EXECUTE update_stmt USING @to_var5, @var5;
EXECUTE update_stmt USING @to_var6, @var6;
EXECUTE update_stmt USING @to_var7, @var7;
EXECUTE update_stmt USING @to_var8, @var8;
EXECUTE update_stmt USING @to_var9, @var9;
SELECT * FROM test_table;
c1
wxyz'ef
wxyz"ef
wxyzef
wxyz
ef
wxyz ef
wxyz ef
wxyz\ef
wxyz\%ef
wxyz\_ef
# END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
# STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
select test_function(@to_var1);
test_function(@to_var1)
wxyz'ef
SELECT test_function(@to_var2);
test_function(@to_var2)
wxyz"ef
SELECT test_function(@to_var3);
test_function(@to_var3)
wxyzef
SELECT test_function(@to_var4);
test_function(@to_var4)
wxyz
ef
SELECT test_function(@to_var5);
test_function(@to_var5)
wxyz ef
SELECT test_function(@to_var6);
test_function(@to_var6)
wxyz ef
SELECT test_function(@to_var7);
test_function(@to_var7)
wxyz\ef
SELECT test_function(@to_var8);
test_function(@to_var8)
wxyz\%ef
SELECT test_function(@to_var9);
test_function(@to_var9)
wxyz\_ef
# END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
DROP TABLE test_table;
DROP FUNCTION test_function;
SET @@sql_mode= @org_mode;
#End of Test for Bug#12601974

View file

@ -38,3 +38,114 @@ DROP VIEW testView;
DROP TABLE t1;
SET @@global.sql_mode= @old_sql_mode;
SET @@session.binlog_format=@old_binlog_format;
#
# Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
# IGNORED AND BREAKS REPLICATION
#
DROP DATABASE IF EXISTS mysqltest_db;
DROP TABLE IF EXISTS test_table;
CREATE DATABASE mysqltest_db;
USE mysqltest_db;
CREATE TABLE test_table (c1 CHAR(50));
SET @org_mode=@@sql_mode;
SET @@sql_mode='';
CREATE PROCEDURE proc_without_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
BEGIN
DECLARE var1 CHAR(50) DEFAULT param1;
DECLARE var2 CHAR(50) DEFAULT param2;
DECLARE var3 CHAR(50) DEFAULT 'abcd\bef';
DECLARE var4 CHAR(50) DEFAULT 'abcd\nef';
DECLARE var5 CHAR(50) DEFAULT 'abcd\ref';
DECLARE var6 CHAR(50) DEFAULT 'abcd\tef';
DECLARE var7 CHAR(50) DEFAULT 'abcd\\ef';
DECLARE var8 CHAR(50) DEFAULT 'abcd\%ef';
DECLARE var9 CHAR(50) DEFAULT 'abcd\_ef';
INSERT INTO test_table VALUES (var1);
INSERT INTO test_table VALUES (var2);
INSERT INTO test_table VALUES (var3);
INSERT INTO test_table VALUES (var4);
INSERT INTO test_table VALUES (var5);
INSERT INTO test_table VALUES (var6);
INSERT INTO test_table VALUES (var7);
INSERT INTO test_table VALUES (var8);
INSERT INTO test_table VALUES (var9);
END
$
SET @@sql_mode='NO_BACKSLASH_ESCAPES'$
CREATE PROCEDURE proc_with_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
BEGIN
DECLARE var1 CHAR(50) DEFAULT param1;
DECLARE var2 CHAR(50) DEFAULT param2;
DECLARE var3 CHAR(50) DEFAULT 'wxyz\bef';
DECLARE var4 CHAR(50) DEFAULT 'wxyz\nef';
DECLARE var5 CHAR(50) DEFAULT 'wxyz\ref';
DECLARE var6 CHAR(50) DEFAULT 'wxyz\tef';
DECLARE var7 CHAR(50) DEFAULT 'wxyz\\ef';
DECLARE var8 CHAR(50) DEFAULT 'wxyz\%ef';
DECLARE var9 CHAR(50) DEFAULT 'wxyz\_ef';
INSERT INTO test_table VALUES (var1);
INSERT INTO test_table VALUES (var2);
INSERT INTO test_table VALUES (var3);
INSERT INTO test_table VALUES (var4);
INSERT INTO test_table VALUES (var5);
INSERT INTO test_table VALUES (var6);
INSERT INTO test_table VALUES (var7);
INSERT INTO test_table VALUES (var8);
INSERT INTO test_table VALUES (var9);
END
$
SET @@sql_mode='';
CALL proc_without_sql_mode('abcd\'ef', 'abcd\"ef');
CALL proc_with_sql_mode('wxyz\'ef', 'wxyz\"ef');
SELECT * FROM test_table;
c1
abcd'ef
abcd"ef
abcdef
abcd
ef
abcd ef
abcd ef
abcd\ef
abcd\%ef
abcd\_ef
wxyz'ef
wxyz"ef
wxyz\bef
wxyz\nef
wxyz\ref
wxyz\tef
wxyz\\ef
wxyz\%ef
wxyz\_ef
"Dropping table test_table"
DROP TABLE test_table;
#"test_table" content after replaying the binlog
SELECT * FROM test_table;
c1
abcd'ef
abcd"ef
abcdef
abcd
ef
abcd ef
abcd ef
abcd\ef
abcd\%ef
abcd\_ef
wxyz'ef
wxyz"ef
wxyz\bef
wxyz\nef
wxyz\ref
wxyz\tef
wxyz\\ef
wxyz\%ef
wxyz\_ef
#Clean up
DROP DATABASE mysqltest_db;
SET @@sql_mode= @org_mode;
use test;
#End of Test for Bug#12601974

View file

@ -73,3 +73,99 @@ DROP TABLE t1;
SET @@global.sql_mode= @old_sql_mode;
SET @@session.binlog_format=@old_binlog_format;
--echo
--echo #
--echo # Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
--echo # IGNORED AND BREAKS REPLICATION
--echo #
--disable_warnings
DROP DATABASE IF EXISTS mysqltest_db;
DROP TABLE IF EXISTS test_table;
--enable_warnings
CREATE DATABASE mysqltest_db;
USE mysqltest_db;
CREATE TABLE test_table (c1 CHAR(50));
SET @org_mode=@@sql_mode;
SET @@sql_mode='';
DELIMITER $;
CREATE PROCEDURE proc_without_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
BEGIN
DECLARE var1 CHAR(50) DEFAULT param1;
DECLARE var2 CHAR(50) DEFAULT param2;
DECLARE var3 CHAR(50) DEFAULT 'abcd\bef';
DECLARE var4 CHAR(50) DEFAULT 'abcd\nef';
DECLARE var5 CHAR(50) DEFAULT 'abcd\ref';
DECLARE var6 CHAR(50) DEFAULT 'abcd\tef';
DECLARE var7 CHAR(50) DEFAULT 'abcd\\ef';
DECLARE var8 CHAR(50) DEFAULT 'abcd\%ef';
DECLARE var9 CHAR(50) DEFAULT 'abcd\_ef';
INSERT INTO test_table VALUES (var1);
INSERT INTO test_table VALUES (var2);
INSERT INTO test_table VALUES (var3);
INSERT INTO test_table VALUES (var4);
INSERT INTO test_table VALUES (var5);
INSERT INTO test_table VALUES (var6);
INSERT INTO test_table VALUES (var7);
INSERT INTO test_table VALUES (var8);
INSERT INTO test_table VALUES (var9);
END
$
SET @@sql_mode='NO_BACKSLASH_ESCAPES'$
CREATE PROCEDURE proc_with_sql_mode (IN param1 CHAR(50), IN param2 CHAR(50))
BEGIN
DECLARE var1 CHAR(50) DEFAULT param1;
DECLARE var2 CHAR(50) DEFAULT param2;
DECLARE var3 CHAR(50) DEFAULT 'wxyz\bef';
DECLARE var4 CHAR(50) DEFAULT 'wxyz\nef';
DECLARE var5 CHAR(50) DEFAULT 'wxyz\ref';
DECLARE var6 CHAR(50) DEFAULT 'wxyz\tef';
DECLARE var7 CHAR(50) DEFAULT 'wxyz\\ef';
DECLARE var8 CHAR(50) DEFAULT 'wxyz\%ef';
DECLARE var9 CHAR(50) DEFAULT 'wxyz\_ef';
INSERT INTO test_table VALUES (var1);
INSERT INTO test_table VALUES (var2);
INSERT INTO test_table VALUES (var3);
INSERT INTO test_table VALUES (var4);
INSERT INTO test_table VALUES (var5);
INSERT INTO test_table VALUES (var6);
INSERT INTO test_table VALUES (var7);
INSERT INTO test_table VALUES (var8);
INSERT INTO test_table VALUES (var9);
END
$
DELIMITER ;$
SET @@sql_mode='';
CALL proc_without_sql_mode('abcd\'ef', 'abcd\"ef');
CALL proc_with_sql_mode('wxyz\'ef', 'wxyz\"ef');
SELECT * FROM test_table;
let $MYSQLD_DATADIR= `select @@datadir`;
--exec $MYSQL_BINLOG --force-if-open -d mysqltest_db $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug12601974.binlog
--echo "Dropping table test_table"
DROP TABLE test_table;
--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug12601974.binlog"
--echo #"test_table" content after replaying the binlog
SELECT * FROM test_table;
--echo #Clean up
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug12601974.binlog
DROP DATABASE mysqltest_db;
SET @@sql_mode= @org_mode;
use test;
--echo
--echo #End of Test for Bug#12601974

View file

@ -8,6 +8,7 @@
-- disable_query_log
-- disable_result_log
call mtr.add_suppression("InnoDB: Warning: a long semaphore wait:");
call mtr.add_suppression("the age of the last checkpoint is");
# set packet size and reconnect
SET @@global.max_allowed_packet=16777216;

View file

@ -8,6 +8,7 @@
-- disable_query_log
-- disable_result_log
call mtr.add_suppression("InnoDB: Warning: a long semaphore wait:");
call mtr.add_suppression("the age of the last checkpoint is");
# set packet size and reconnect
let $max_packet=`select @@global.max_allowed_packet`;

View file

@ -1 +0,0 @@
--set-variable=query_cache_size=1M

View file

@ -562,4 +562,17 @@ SELECT 1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1);
--echo #
--echo #
--echo # Bug#13012483: EXPLAIN EXTENDED, PREPARED STATEMENT, CRASH IN CHECK_SIMPLE_EQUALITY
--echo #
CREATE TABLE t1 (a INT);
PREPARE s FROM "SELECT 1 FROM t1 WHERE 1 < ALL (SELECT @:= (1 IN (SELECT 1 FROM t1)) FROM t1)";
EXECUTE s;
DROP TABLE t1;
--echo # End of test BUG#13012483
--echo #
--echo End of 5.1 tests

View file

@ -0,0 +1,21 @@
# t/cache_innodb.test
#
# Last update:
# 2006-07-26 ML test refactored (MySQL 5.1)
# main code t/innodb_cache.test --> include/query_cache.inc
# new wrapper t/cache_innodb.test
#
--source include/have_query_cache.inc
--source include/have_innodb.inc
--source include/have_partition.inc
let $engine_type= InnoDB;
# Using SELECT to get a space as first character.
let $partitions_a= `SELECT ' PARTITION BY KEY (a) PARTITIONS 3'`;
let $partitions_id= `SELECT ' PARTITION BY HASH (id) PARTITIONS 3'`;
let $partitions_s1= `SELECT ' PARTITION BY KEY (s1) PARTITIONS 3'`;
# partitioning does not support FOREIGN KEYs
let $test_foreign_keys= 0;
--source include/query_cache.inc

View file

@ -344,3 +344,157 @@ SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%P
# Cleanup
DROP TABLE t1;
DROP TABLE t2;
--echo
--echo #
--echo # Test for Bug#12601974 - STORED PROCEDURE SQL_MODE=NO_BACKSLASH_ESCAPES
--echo # IGNORED AND BREAKS REPLICATION
--echo #
--disable_warnings
DROP TABLE IF EXISTS test_table;
DROP FUNCTION IF EXISTS test_function;
--enable_warnings
CREATE TABLE test_table (c1 CHAR(50));
SET @org_mode=@@sql_mode;
SET @@sql_mode='';
PREPARE insert_stmt FROM 'INSERT INTO test_table VALUES (?)';
PREPARE update_stmt FROM 'UPDATE test_table SET c1= ? WHERE c1= ?';
DELIMITER $;
CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
BEGIN
DECLARE char_val CHAR(50);
SELECT c1 INTO char_val FROM test_table WHERE c1=var;
RETURN char_val;
END
$
DELIMITER ;$
SET @var1='abcd\'ef';
SET @var2='abcd\"ef';
SET @var3='abcd\bef';
SET @var4='abcd\nef';
SET @var5='abcd\ref';
SET @var6='abcd\tef';
SET @var7='abcd\\ef';
SET @var8='abcd\%ef';
SET @var9='abcd\_ef';
SET @to_var1='wxyz\'ef';
SET @to_var2='wxyz\"ef';
SET @to_var3='wxyz\bef';
SET @to_var4='wxyz\nef';
SET @to_var5='wxyz\ref';
SET @to_var6='wxyz\tef';
SET @to_var7='wxyz\\ef';
SET @to_var8='wxyz\%ef';
SET @to_var9='wxyz\_ef';
--echo # STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
EXECUTE insert_stmt USING @var1;
EXECUTE insert_stmt USING @var2;
EXECUTE insert_stmt USING @var3;
EXECUTE insert_stmt USING @var4;
EXECUTE insert_stmt USING @var5;
EXECUTE insert_stmt USING @var6;
EXECUTE insert_stmt USING @var7;
EXECUTE insert_stmt USING @var8;
EXECUTE insert_stmt USING @var9;
SELECT * FROM test_table;
EXECUTE update_stmt USING @to_var1, @var1;
EXECUTE update_stmt USING @to_var2, @var2;
EXECUTE update_stmt USING @to_var3, @var3;
EXECUTE update_stmt USING @to_var4, @var4;
EXECUTE update_stmt USING @to_var5, @var5;
EXECUTE update_stmt USING @to_var6, @var6;
EXECUTE update_stmt USING @to_var7, @var7;
EXECUTE update_stmt USING @to_var8, @var8;
EXECUTE update_stmt USING @to_var9, @var9;
SELECT * FROM test_table;
--echo
--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
--echo # STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
select test_function(@to_var1);
SELECT test_function(@to_var2);
SELECT test_function(@to_var3);
SELECT test_function(@to_var4);
SELECT test_function(@to_var5);
SELECT test_function(@to_var6);
SELECT test_function(@to_var7);
SELECT test_function(@to_var8);
SELECT test_function(@to_var9);
--echo
--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
DELETE FROM test_table;
DROP FUNCTION test_function;
SET @@sql_mode='NO_BACKSLASH_ESCAPES';
DELIMITER $;
CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50)
BEGIN
DECLARE char_val CHAR(50);
SELECT c1 INTO char_val FROM test_table WHERE c1=var;
RETURN char_val;
END
$
DELIMITER ;$
--echo # STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
EXECUTE insert_stmt USING @var1;
EXECUTE insert_stmt USING @var2;
EXECUTE insert_stmt USING @var3;
EXECUTE insert_stmt USING @var4;
EXECUTE insert_stmt USING @var5;
EXECUTE insert_stmt USING @var6;
EXECUTE insert_stmt USING @var7;
EXECUTE insert_stmt USING @var8;
EXECUTE insert_stmt USING @var9;
SELECT * FROM test_table;
EXECUTE update_stmt USING @to_var1, @var1;
EXECUTE update_stmt USING @to_var2, @var2;
EXECUTE update_stmt USING @to_var3, @var3;
EXECUTE update_stmt USING @to_var4, @var4;
EXECUTE update_stmt USING @to_var5, @var5;
EXECUTE update_stmt USING @to_var6, @var6;
EXECUTE update_stmt USING @to_var7, @var7;
EXECUTE update_stmt USING @to_var8, @var8;
EXECUTE update_stmt USING @to_var9, @var9;
SELECT * FROM test_table;
--echo
--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN PREPARE STATEMENT
--echo # STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
select test_function(@to_var1);
SELECT test_function(@to_var2);
SELECT test_function(@to_var3);
SELECT test_function(@to_var4);
SELECT test_function(@to_var5);
SELECT test_function(@to_var6);
SELECT test_function(@to_var7);
SELECT test_function(@to_var8);
SELECT test_function(@to_var9);
--echo
--echo # END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
DROP TABLE test_table;
DROP FUNCTION test_function;
SET @@sql_mode= @org_mode;
--echo
--echo #End of Test for Bug#12601974

View file

@ -170,7 +170,7 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
my_safe_printf_stderr("%s",
"Error when traversing the stack, stack appears corrupt.\n");
else
my_safe_printf_stderr("%s"
my_safe_printf_stderr("%s",
"Please read "
"http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
"and follow instructions on how to resolve the stack trace.\n"

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -6494,20 +6494,20 @@ int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
return ret;
err:
if (file > m_file)
{
uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
KEY *old_key_info= table_arg->key_info;
uint i;
/* Use the newly added key_info as table->key_info to remove them. */
for (i= 0; i < num_of_keys; i++)
key_numbers[i]= i;
table_arg->key_info= key_info;
while (--file >= m_file)
{
(void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys);
(void) (*file)->final_drop_index(table_arg);
}
table_arg->key_info= old_key_info;
{
uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
KEY *old_key_info= table_arg->key_info;
uint i;
/* Use the newly added key_info as table->key_info to remove them. */
for (i= 0; i < num_of_keys; i++)
key_numbers[i]= i;
table_arg->key_info= key_info;
while (--file >= m_file)
{
(void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys);
(void) (*file)->final_drop_index(table_arg);
}
table_arg->key_info= old_key_info;
}
return ret;
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -219,9 +219,9 @@ public:
*/
ha_partition(handlerton *hton, TABLE_SHARE * table);
ha_partition(handlerton *hton, partition_info * part_info);
ha_partition(handlerton *hton, TABLE_SHARE *share,
partition_info *part_info_arg,
ha_partition *clone_arg,
ha_partition(handlerton *hton, TABLE_SHARE *share,
partition_info *part_info_arg,
ha_partition *clone_arg,
MEM_ROOT *clone_mem_root_arg);
~ha_partition();
/*
@ -553,6 +553,20 @@ public:
virtual int extra(enum ha_extra_function operation);
virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
virtual int reset(void);
/*
Do not allow caching of partitioned tables, since we cannot return
a callback or engine_data that would work for a generic engine.
*/
virtual my_bool register_query_cache_table(THD *thd, char *table_key,
uint key_length,
qc_engine_callback
*engine_callback,
ulonglong *engine_data)
{
*engine_callback= NULL;
*engine_data= 0;
return FALSE;
}
private:
static const uint NO_CURRENT_PART_ID;

View file

@ -3085,7 +3085,7 @@ String *Item_param::val_str(String* str)
that binary log contains wrong statement
*/
const String *Item_param::query_val_str(String* str) const
const String *Item_param::query_val_str(THD *thd, String* str) const
{
switch (state) {
case INT_VALUE:
@ -3123,7 +3123,8 @@ const String *Item_param::query_val_str(String* str) const
case LONG_DATA_VALUE:
{
str->length(0);
append_query_string(value.cs_info.character_set_client, &str_value, str);
append_query_string(thd, value.cs_info.character_set_client, &str_value,
str);
break;
}
case NULL_VALUE:
@ -3256,7 +3257,7 @@ void Item_param::print(String *str, enum_query_type query_type)
char buffer[STRING_BUFFER_USUAL_SIZE];
String tmp(buffer, sizeof(buffer), &my_charset_bin);
const String *res;
res= query_val_str(&tmp);
res= query_val_str(current_thd, &tmp);
str->append(*res);
}
}

View file

@ -1703,7 +1703,7 @@ public:
*/
void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
const String *query_val_str(String *str) const;
const String *query_val_str(THD *thd, String *str) const;
bool convert_str_value(THD *thd);

View file

@ -254,7 +254,7 @@ public:
Item_in_optimizer(Item *a, Item_in_subselect *b):
Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
save_cache(0), result_for_null_param(UNKNOWN)
{}
{ with_subselect= true; }
bool fix_fields(THD *, Item **);
bool fix_left(THD *thd, Item **ref);
bool is_null();

View file

@ -572,7 +572,7 @@ char *str_to_hex(char *to, const char *from, uint len)
*/
int
append_query_string(CHARSET_INFO *csinfo,
append_query_string(THD *thd, CHARSET_INFO *csinfo,
String const *from, String *to)
{
char *beg, *ptr;
@ -587,9 +587,26 @@ append_query_string(CHARSET_INFO *csinfo,
else
{
*ptr++= '\'';
ptr+= escape_string_for_mysql(csinfo, ptr, 0,
from->ptr(), from->length());
*ptr++='\'';
if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
{
ptr+= escape_string_for_mysql(csinfo, ptr, 0,
from->ptr(), from->length());
}
else
{
const char *frm_str= from->ptr();
for (; frm_str < (from->ptr() + from->length()); frm_str++)
{
/* Using '' way to represent "'" */
if (*frm_str == '\'')
*ptr++= *frm_str;
*ptr++= *frm_str;
}
}
*ptr++= '\'';
}
to->length(orig_len + ptr - beg);
return 0;

View file

@ -799,7 +799,7 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table);
int append_query_string(CHARSET_INFO *csinfo,
int append_query_string(THD *thd, CHARSET_INFO *csinfo,
String const *from, String *to);
void get_default_definer(THD *thd, LEX_USER *definer);

View file

@ -2468,10 +2468,6 @@ static void check_data_home(const char *path)
#endif /*__WIN__ || __NETWARE */
#ifdef HAVE_LINUXTHREADS
#define UNSAFE_DEFAULT_LINUX_THREADS 200
#endif
#if BACKTRACE_DEMANGLE
#include <cxxabi.h>

View file

@ -131,6 +131,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
"Hope that's ok; if not, decrease some variables in the equation.\n\n");
#if defined(HAVE_LINUXTHREADS)
#define UNSAFE_DEFAULT_LINUX_THREADS 200
if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
{
my_safe_printf_stderr(

View file

@ -157,7 +157,7 @@ sp_get_item_value(THD *thd, Item *item, String *str)
buf.append(result->charset()->csname);
if (cs->escape_with_backslash_is_dangerous)
buf.append(' ');
append_query_string(cs, result, &buf);
append_query_string(thd, cs, result, &buf);
buf.append(" COLLATE '");
buf.append(item->collation.collation->name);
buf.append('\'');

View file

@ -1734,8 +1734,9 @@ void log_slow_statement(THD *thd)
ulonglong end_utime_of_query= thd->current_utime();
thd_proc_info(thd, "logging slow query");
if (((end_utime_of_query - thd->utime_after_lock) >
thd->variables.long_query_time ||
if ((((end_utime_of_query > thd->utime_after_lock) &&
((end_utime_of_query - thd->utime_after_lock) >
thd->variables.long_query_time)) ||
((thd->server_status &
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
opt_log_queries_not_using_indexes &&

View file

@ -795,7 +795,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
*/
else if (! is_param_long_data_type(param))
DBUG_RETURN(1);
res= param->query_val_str(&str);
res= param->query_val_str(thd, &str);
if (param->convert_str_value(thd))
DBUG_RETURN(1); /* out of memory */
@ -969,7 +969,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt,
DBUG_RETURN(1);
}
}
res= param->query_val_str(&str);
res= param->query_val_str(thd, &str);
if (param->convert_str_value(thd))
DBUG_RETURN(1); /* out of memory */
@ -1115,7 +1115,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
setup_one_conversion_function(thd, param, param->param_type);
if (param->set_from_user_var(thd, entry))
DBUG_RETURN(1);
val= param->query_val_str(&buf);
val= param->query_val_str(thd, &buf);
if (param->convert_str_value(thd))
DBUG_RETURN(1); /* out of memory */

View file

@ -291,13 +291,20 @@ btr_pcur_restore_position(
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
switch (cursor->rel_pos) {
case BTR_PCUR_ON:
mode = PAGE_CUR_LE;
} else if (cursor->rel_pos == BTR_PCUR_AFTER) {
break;
case BTR_PCUR_AFTER:
mode = PAGE_CUR_G;
} else {
ut_ad(cursor->rel_pos == BTR_PCUR_BEFORE);
break;
case BTR_PCUR_BEFORE:
mode = PAGE_CUR_L;
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
}
btr_pcur_open_with_no_init(index, tuple, mode, latch_mode,
@ -306,26 +313,45 @@ btr_pcur_restore_position(
/* Restore the old search mode */
cursor->search_mode = old_mode;
if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor, mtr)
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(
btr_pcur_get_rec(cursor), index,
NULL, ULINT_UNDEFINED, &heap))) {
if (btr_pcur_is_on_user_rec(cursor, mtr)) {
switch (cursor->rel_pos) {
case BTR_PCUR_ON:
if (!cmp_dtuple_rec(
tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
index, NULL,
ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! But we can retain
the value of old_rec */
/* We have to store the NEW value for
the modify clock, since the cursor can
now be on a different page! But we can
retain the value of old_rec */
cursor->block_when_stored = buf_block_align(
btr_pcur_get_page(cursor));
cursor->modify_clock = buf_block_get_modify_clock(
cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
cursor->block_when_stored =
buf_block_align(
btr_pcur_get_page(cursor));
cursor->modify_clock =
buf_block_get_modify_clock(
cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
mem_heap_free(heap);
mem_heap_free(heap);
return(TRUE);
return(TRUE);
}
break;
case BTR_PCUR_BEFORE:
page_cur_move_to_next(btr_pcur_get_page_cur(cursor));
break;
case BTR_PCUR_AFTER:
page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
}
}
mem_heap_free(heap);

View file

@ -1,3 +1,16 @@
2012-03-08 The InnoDB Team
* btr/btr0pcur.c:
Fix Bug#13807811 BTR_PCUR_RESTORE_POSITION() CAN SKIP A RECORD
2012-02-28 The InnoDB Team
* btr/btr0btr.c, dict/dict0dict.c, include/btr0btr.h,
include/dict0dict.h, include/dict0dict.ic, include/dict0mem.h,
handler/handler0alter.cc, row/row0mysql.c:
Fix Bug#12861864 RACE CONDITION IN BTR_GET_SIZE() AND
DROP INDEX/TABLE/DATABASE
2012-02-15 The InnoDB Team
* btr/btr0btr.c, btr/btr0cur.c, fsp/fsp0fsp.c, ibuf/ibuf0ibuf.c,

View file

@ -991,45 +991,49 @@ btr_page_alloc(
/**************************************************************//**
Gets the number of pages in a B-tree.
@return number of pages */
@return number of pages, or ULINT_UNDEFINED if the index is unavailable */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
dict_index_t* index, /*!< in: index */
ulint flag) /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
mtr_t* mtr) /*!< in/out: mini-transaction where index
is s-latched */
{
fseg_header_t* seg_header;
page_t* root;
ulint n;
ulint dummy;
mtr_t mtr;
mtr_start(&mtr);
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_S_LOCK));
mtr_s_lock(dict_index_get_lock(index), &mtr);
if (index->page == FIL_NULL
|| index->to_be_dropped
|| *index->name == TEMP_INDEX_PREFIX) {
return(ULINT_UNDEFINED);
}
root = btr_root_get(index, &mtr);
root = btr_root_get(index, mtr);
if (flag == BTR_N_LEAF_PAGES) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
fseg_n_reserved_pages(seg_header, &n, &mtr);
fseg_n_reserved_pages(seg_header, &n, mtr);
} else if (flag == BTR_TOTAL_SIZE) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
n = fseg_n_reserved_pages(seg_header, &dummy, &mtr);
n = fseg_n_reserved_pages(seg_header, &dummy, mtr);
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
n += fseg_n_reserved_pages(seg_header, &dummy, &mtr);
n += fseg_n_reserved_pages(seg_header, &dummy, mtr);
} else {
ut_error;
}
mtr_commit(&mtr);
return(n);
}

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -121,6 +121,8 @@ btr_pcur_store_position(
ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(page_is_leaf(page));
ut_ad(page_get_page_no(page) == index->page);
cursor->old_stored = BTR_PCUR_OLD_STORED;
@ -313,13 +315,20 @@ btr_pcur_restore_position_func(
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
switch (cursor->rel_pos) {
case BTR_PCUR_ON:
mode = PAGE_CUR_LE;
} else if (cursor->rel_pos == BTR_PCUR_AFTER) {
break;
case BTR_PCUR_AFTER:
mode = PAGE_CUR_G;
} else {
ut_ad(cursor->rel_pos == BTR_PCUR_BEFORE);
break;
case BTR_PCUR_BEFORE:
mode = PAGE_CUR_L;
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
}
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
@ -328,25 +337,44 @@ btr_pcur_restore_position_func(
/* Restore the old search mode */
cursor->search_mode = old_mode;
if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor)
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(
btr_pcur_get_rec(cursor), index,
NULL, ULINT_UNDEFINED, &heap))) {
if (btr_pcur_is_on_user_rec(cursor)) {
switch (cursor->rel_pos) {
case BTR_PCUR_ON:
if (!cmp_dtuple_rec(
tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
index, NULL,
ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! But we can retain
the value of old_rec */
/* We have to store the NEW value for
the modify clock, since the cursor can
now be on a different page! But we can
retain the value of old_rec */
cursor->block_when_stored = btr_pcur_get_block(cursor);
cursor->modify_clock = buf_block_get_modify_clock(
cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
cursor->block_when_stored =
btr_pcur_get_block(cursor);
cursor->modify_clock =
buf_block_get_modify_clock(
cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
mem_heap_free(heap);
mem_heap_free(heap);
return(TRUE);
return(TRUE);
}
break;
case BTR_PCUR_BEFORE:
page_cur_move_to_next(btr_pcur_get_page_cur(cursor));
break;
case BTR_PCUR_AFTER:
page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
}
}
mem_heap_free(heap);

View file

@ -4271,16 +4271,27 @@ dict_update_statistics(
(srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
|| (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
&& dict_index_is_clust(index)))) {
mtr_t mtr;
ulint size;
size = btr_get_size(index, BTR_TOTAL_SIZE);
index->stat_index_size = size;
mtr_start(&mtr);
mtr_s_lock(dict_index_get_lock(index), &mtr);
sum_of_index_sizes += size;
size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr);
size = btr_get_size(index, BTR_N_LEAF_PAGES);
if (size != ULINT_UNDEFINED) {
sum_of_index_sizes += size;
index->stat_index_size = size;
size = btr_get_size(
index, BTR_N_LEAF_PAGES, &mtr);
}
if (size == 0) {
mtr_commit(&mtr);
switch (size) {
case ULINT_UNDEFINED:
goto fake_statistics;
case 0:
/* The root node of the tree is a leaf */
size = 1;
}
@ -4297,6 +4308,7 @@ dict_update_statistics(
various means, also via secondary indexes. */
ulint i;
fake_statistics:
sum_of_index_sizes++;
index->stat_index_size = index->stat_n_leaf_pages = 1;

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@ -1010,7 +1010,9 @@ ha_innobase::prepare_drop_index(
goto func_exit;
}
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = TRUE;
rw_lock_x_unlock(dict_index_get_lock(index));
}
/* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined
@ -1129,7 +1131,9 @@ func_exit:
= dict_table_get_first_index(prebuilt->table);
do {
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = FALSE;
rw_lock_x_unlock(dict_index_get_lock(index));
index = dict_table_get_next_index(index);
} while (index);
}
@ -1189,7 +1193,9 @@ ha_innobase::final_drop_index(
for (index = dict_table_get_first_index(prebuilt->table);
index; index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = FALSE;
rw_lock_x_unlock(dict_index_get_lock(index));
}
goto func_exit;

View file

@ -536,13 +536,16 @@ btr_parse_page_reorganize(
#ifndef UNIV_HOTBACKUP
/**************************************************************//**
Gets the number of pages in a B-tree.
@return number of pages */
@return number of pages, or ULINT_UNDEFINED if the index is unavailable */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
dict_index_t* index, /*!< in: index */
ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
mtr_t* mtr) /*!< in/out: mini-transaction where index
is s-latched */
__attribute__((nonnull, warn_unused_result));
/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
that the caller has made the reservation for free extents!

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@ -1018,14 +1018,6 @@ dict_index_get_page(
/*================*/
const dict_index_t* tree); /*!< in: index */
/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
dict_index_t* index, /*!< in/out: index */
ulint page); /*!< in: page number */
/*********************************************************************//**
Gets the read-write lock of the index tree.
@return read-write lock */
UNIV_INLINE

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@ -722,21 +722,6 @@ dict_index_get_page(
return(index->page);
}
/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
dict_index_t* index, /*!< in/out: index */
ulint page) /*!< in: page number */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
index->page = page;
}
/*********************************************************************//**
Gets the read-write lock of the index tree.
@return read-write lock */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@ -305,7 +305,9 @@ struct dict_index_struct{
unsigned to_be_dropped:1;
/*!< TRUE if this index is marked to be
dropped in ha_innobase::prepare_drop_index(),
otherwise FALSE */
otherwise FALSE. Protected by
dict_sys->mutex, dict_operation_lock and
index->lock.*/
dict_field_t* fields; /*!< array of field descriptions */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@ -3023,6 +3023,7 @@ row_drop_table_for_mysql(
{
dict_foreign_t* foreign;
dict_table_t* table;
dict_index_t* index;
ulint space_id;
ulint err;
const char* table_name;
@ -3229,6 +3230,18 @@ check_next_foreign:
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
trx->table_id = table->id;
/* Mark all indexes unavailable in the data dictionary cache
before starting to drop the table. */
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
ut_ad(!index->to_be_dropped);
index->to_be_dropped = TRUE;
rw_lock_x_unlock(dict_index_get_lock(index));
}
/* We use the private SQL parser of Innobase to generate the
query graphs needed in deleting the dictionary data from system
tables in Innobase. Deleting a row from SYS_INDEXES table also
@ -3394,6 +3407,17 @@ check_next_foreign:
the undo log. We can directly exit here
and return the DB_TOO_MANY_CONCURRENT_TRXS
error. */
/* Mark all indexes available in the data dictionary
cache again. */
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = FALSE;
rw_lock_x_unlock(dict_index_get_lock(index));
}
break;
case DB_OUT_OF_FILE_SPACE:

View file

@ -245,15 +245,11 @@ row_build(
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
if (rec_offs_any_null_extern(rec, offsets)) {
/* This condition can occur during crash recovery
before trx_rollback_active() has completed execution.
This condition is possible if the server crashed
during an insert or update-by-delete-and-insert before
btr_store_big_rec_extern_fields() did mtr_commit() all
BLOB pointers to the freshly inserted clustered index
record. */
ut_a(trx_assert_recovered(
row_get_rec_trx_id(rec, index, offsets)));
before trx_rollback_active() has completed execution,
or when a concurrently executing
row_ins_index_entry_low() has committed the B-tree
mini-transaction but has not yet managed to restore
the cursor position for writing the big_rec. */
ut_a(trx_undo_roll_ptr_is_insert(
row_get_rec_roll_ptr(rec, index, offsets)));
}