Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.

This commit is contained in:
Alexey Kopytov 2009-12-11 19:40:58 +03:00
commit ebdef570e5
56 changed files with 1925 additions and 344 deletions

View File

@ -783,6 +783,10 @@ static int run_sql_fix_privilege_tables(void)
found_real_errors++;
print_line(line);
}
else if (strncmp(line, "WARNING", 7) == 0)
{
print_line(line);
}
} while ((line= get_line(line)) && *line);
}

View File

@ -2113,7 +2113,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
sighold sigset sigthreadmask port_create sleep \
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd)
posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack)
#
#

View File

@ -23,7 +23,7 @@
(defined(__alpha__) && defined(__GNUC__))
#define HAVE_STACKTRACE 1
#endif
#elif defined(__WIN__)
#elif defined(__WIN__) || defined(__sun)
#define HAVE_STACKTRACE 1
#endif

View File

@ -14,7 +14,6 @@ main.log_tables # Bug#47924 2009-10-08 alik main.log_ta
main.plugin # Bug#47146 Linking problem with example plugin when dtrace enabled
main.plugin_load # Bug#47146
rpl.rpl_cross_version* # Bug#48340 2009-12-01 Daogang rpl_cross_version: Found warnings/errors in server log file!
rpl.rpl_get_master_version_and_clock* # Bug#49191 2009-12-01 Daogang rpl_get_master_version_and_clock failed on PB2: COM_REGISTER_SLAVE failed
rpl.rpl_heartbeat_basic # BUG#43828 2009-10-22 luis fails sporadically
rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically

View File

@ -52,7 +52,7 @@ if (`SELECT '$debug_lock' != ''`)
# reap the result of the waiting query
connection $connection_name;
error 0, 1317, 1307, 1306, 1334, 1305;
error 0, 1317, 1307, 1306, 1334, 1305, 1034;
reap;
connection master;

View File

@ -1848,6 +1848,24 @@ select hex(_utf8 B'001111111111');
ERROR HY000: Invalid utf8 character string: 'FF'
select (_utf8 X'616263FF');
ERROR HY000: Invalid utf8 character string: 'FF'
#
# Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings
#
CREATE TABLE t1 (id int not null primary key, name varchar(10)) character set utf8;
INSERT INTO t1 VALUES
(2,'一二三01'),(3,'一二三09'),(4,'一二三02'),(5,'一二三08'),
(6,'一二三11'),(7,'一二三91'),(8,'一二三21'),(9,'一二三81');
SELECT * FROM t1 ORDER BY BINARY(name);
id name
2 一二三01
4 一二三02
5 一二三08
3 一二三09
6 一二三11
8 一二三21
9 一二三81
7 一二三91
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL);
INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065);
SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b;

View File

@ -2561,6 +2561,35 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer
2 DERIVED t1 ALL NULL NULL NULL NULL 2
drop table t1;
#
# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
#
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (a VARCHAR(20), b INT);
CREATE TABLE t2 (a VARCHAR(20), b INT);
INSERT INTO t1 VALUES ('ABC', 1);
INSERT INTO t2 VALUES ('ABC', 1);
SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
secret
SELECT DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
secret
SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC')
FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC')
secret
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
INSERT INTO t1 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
INSERT INTO t2 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
FROM t2 WHERE t2.b = 1 GROUP BY t2.b;
DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
secret
DROP TABLE t1, t2;
Start of 5.4 tests
SELECT format(12345678901234567890.123, 3);
format(12345678901234567890.123, 3)

View File

@ -127,4 +127,46 @@ mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
set GLOBAL sql_mode=default;
#
# Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table
# but does not set values.
#
CREATE PROCEDURE testproc() BEGIN END;
UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc';
mtr.global_suppressions OK
mtr.test_suppressions OK
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
mysql.general_log
Error : You can't use locks with log tables.
status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.host OK
mysql.ndb_binlog_index OK
mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
mysql.slow_log
Error : You can't use locks with log tables.
status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
CALL testproc();
DROP PROCEDURE testproc;
WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary.
WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary.
WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary.
The --upgrade-system-tables option was used, databases won't be touched.

View File

@ -1463,6 +1463,15 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
col
1
# Must use ref-or-null on the a_c index
EXPLAIN
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
id select_type table type possible_keys key key_len ref rows Extra
x x x ref_or_null a_c,a x x x x x
# Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
col
1
DROP TABLE t1;
End of 5.0 tests
CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,

View File

@ -1917,6 +1917,31 @@ execute stmt using @arg;
?
-12345.5432100000
deallocate prepare stmt;
#
# Bug#48508: Crash on prepared statement re-execution.
#
create table t1(b int);
insert into t1 values (0);
create view v1 AS select 1 as a from t1 where b;
prepare stmt from "select * from v1 where a";
execute stmt;
a
execute stmt;
a
deallocate prepare stmt;
drop table t1;
drop view v1;
create table t1(a bigint);
create table t2(b tinyint);
insert into t2 values (null);
prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1";
execute stmt;
1
execute stmt;
1
deallocate prepare stmt;
drop table t1,t2;
#
End of 5.0 tests.
create procedure proc_1() reset query cache;
call proc_1();
@ -2926,6 +2951,25 @@ execute stmt;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
drop table t1;
deallocate prepare stmt;
#
# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
#
prepare encode from "select encode(?, ?) into @ciphertext";
prepare decode from "select decode(?, ?) into @plaintext";
set @str="abc", @key="cba";
execute encode using @str, @key;
execute decode using @ciphertext, @key;
select @plaintext;
@plaintext
abc
set @str="bcd", @key="dcb";
execute encode using @str, @key;
execute decode using @ciphertext, @key;
select @plaintext;
@plaintext
bcd
deallocate prepare encode;
deallocate prepare decode;
End of 5.1 tests.

View File

@ -4441,6 +4441,91 @@ SELECT 1 FROM t2 JOIN t1 ON 1=1
WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a);
1
DROP TABLE t1,t2;
#
# Bug #49199: Optimizer handles incorrectly:
# field='const1' AND field='const2' in some cases
CREATE TABLE t1(a DATETIME NOT NULL);
INSERT INTO t1 VALUES('2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
a
2001-01-01 00:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
DROP TABLE t1;
CREATE TABLE t1(a DATE NOT NULL);
INSERT INTO t1 VALUES('2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
a
2001-01-01
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select '2001-01-01' AS `a` from `test`.`t1` where 1
DROP TABLE t1;
CREATE TABLE t1(a TIMESTAMP NOT NULL);
INSERT INTO t1 VALUES('2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
a
2001-01-01 00:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
DROP TABLE t1;
CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
a b
2001-01-01 00:00:00 2001-01-01
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
DROP TABLE t1;
CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL);
INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
a b
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 0
SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
a b
2001-01-01 00:00:00 2001-01-01
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
DROP TABLE t1;
CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
SELECT x.a, y.a, z.a FROM t1 x
JOIN t1 y ON x.a=y.a
JOIN t1 z ON y.a=z.a
WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
a a a
2001-01-01 00:00:00 2001-01-01 00:00:00 2001-01-01 00:00:00
EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
JOIN t1 y ON x.a=y.a
JOIN t1 z ON y.a=z.a
WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE x system NULL NULL NULL NULL 1 100.00
1 SIMPLE y system NULL NULL NULL NULL 1 100.00
1 SIMPLE z system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1
DROP TABLE t1;
End of 5.0 tests
create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
@ -4609,4 +4694,14 @@ HAVING v <= 't'
ORDER BY pk;
v
DROP TABLE t1;
#
# Bug#49489 Uninitialized cache led to a wrong result.
#
CREATE TABLE t1(c1 DOUBLE(5,4));
INSERT INTO t1 VALUES (9.1234);
SELECT * FROM t1 WHERE c1 < 9.12345;
c1
9.1234
DROP TABLE t1;
# End of test for bug#49489.
End of 5.1 tests

View File

@ -1453,4 +1453,10 @@ GRANT PROCESS ON *.* TO test_u@localhost;
SHOW ENGINE MYISAM MUTEX;
SHOW ENGINE MYISAM STATUS;
DROP USER test_u@localhost;
#
# Bug #48985: show create table crashes if previous access to the table
# was killed
#
SHOW CREATE TABLE non_existent;
ERROR 70100: Query execution was interrupted
End of 5.1 tests

View File

@ -12,3 +12,29 @@ a
foo string
drop function bug17615|
drop table t3|
SET NAMES utf8;
DROP FUNCTION IF EXISTS bug48766;
CREATE FUNCTION bug48766 ()
RETURNS ENUM( 'w' ) CHARACTER SET ucs2
RETURN 0;
SHOW CREATE FUNCTION bug48766;
Function sql_mode Create Function character_set_client collation_connection Database Collation
bug48766 CREATE DEFINER=`root`@`localhost` FUNCTION `bug48766`() RETURNS enum('w') CHARSET ucs2
RETURN 0 utf8 utf8_general_ci latin1_swedish_ci
SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME='bug48766';
DTD_IDENTIFIER
enum('w') CHARSET ucs2
DROP FUNCTION bug48766;
CREATE FUNCTION bug48766 ()
RETURNS ENUM('а','б','в','г') CHARACTER SET ucs2
RETURN 0;
SHOW CREATE FUNCTION bug48766;
Function sql_mode Create Function character_set_client collation_connection Database Collation
bug48766 CREATE DEFINER=`root`@`localhost` FUNCTION `bug48766`() RETURNS enum('а','б','в','г') CHARSET ucs2
RETURN 0 utf8 utf8_general_ci latin1_swedish_ci
SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME='bug48766';
DTD_IDENTIFIER
enum('а','б','в','г') CHARSET ucs2
DROP FUNCTION bug48766;

View File

@ -46,3 +46,267 @@ a
2001
drop table t1;
End of 5.0 tests
#
# Bug #49480: WHERE using YEAR columns returns unexpected results
#
CREATE TABLE t2(yy YEAR(2), c2 CHAR(4));
CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4));
INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069);
INSERT INTO t4 (c4) SELECT c2 FROM t2;
UPDATE t2 SET yy = c2;
UPDATE t4 SET yyyy = c4;
SELECT * FROM t2;
yy c2
NULL NULL
70 1970
99 1999
00 2000
01 2001
69 2069
SELECT * FROM t4;
yyyy c4
NULL NULL
1970 1970
1999 1999
2000 2000
2001 2001
2069 2069
# Comparison of YEAR(2) with YEAR(4)
SELECT * FROM t2, t4 WHERE yy = yyyy;
yy c2 yyyy c4
70 1970 1970 1970
99 1999 1999 1999
00 2000 2000 2000
01 2001 2001 2001
69 2069 2069 2069
SELECT * FROM t2, t4 WHERE yy <=> yyyy;
yy c2 yyyy c4
NULL NULL NULL NULL
70 1970 1970 1970
99 1999 1999 1999
00 2000 2000 2000
01 2001 2001 2001
69 2069 2069 2069
SELECT * FROM t2, t4 WHERE yy < yyyy;
yy c2 yyyy c4
70 1970 1999 1999
70 1970 2000 2000
99 1999 2000 2000
70 1970 2001 2001
99 1999 2001 2001
00 2000 2001 2001
70 1970 2069 2069
99 1999 2069 2069
00 2000 2069 2069
01 2001 2069 2069
SELECT * FROM t2, t4 WHERE yy > yyyy;
yy c2 yyyy c4
99 1999 1970 1970
00 2000 1970 1970
01 2001 1970 1970
69 2069 1970 1970
00 2000 1999 1999
01 2001 1999 1999
69 2069 1999 1999
01 2001 2000 2000
69 2069 2000 2000
69 2069 2001 2001
# Comparison of YEAR(2) with YEAR(2)
SELECT * FROM t2 a, t2 b WHERE a.yy = b.yy;
yy c2 yy c2
70 1970 70 1970
99 1999 99 1999
00 2000 00 2000
01 2001 01 2001
69 2069 69 2069
SELECT * FROM t2 a, t2 b WHERE a.yy <=> b.yy;
yy c2 yy c2
NULL NULL NULL NULL
70 1970 70 1970
99 1999 99 1999
00 2000 00 2000
01 2001 01 2001
69 2069 69 2069
SELECT * FROM t2 a, t2 b WHERE a.yy < b.yy;
yy c2 yy c2
70 1970 99 1999
70 1970 00 2000
99 1999 00 2000
70 1970 01 2001
99 1999 01 2001
00 2000 01 2001
70 1970 69 2069
99 1999 69 2069
00 2000 69 2069
01 2001 69 2069
# Comparison of YEAR(4) with YEAR(4)
SELECT * FROM t4 a, t4 b WHERE a.yyyy = b.yyyy;
yyyy c4 yyyy c4
1970 1970 1970 1970
1999 1999 1999 1999
2000 2000 2000 2000
2001 2001 2001 2001
2069 2069 2069 2069
SELECT * FROM t4 a, t4 b WHERE a.yyyy <=> b.yyyy;
yyyy c4 yyyy c4
NULL NULL NULL NULL
1970 1970 1970 1970
1999 1999 1999 1999
2000 2000 2000 2000
2001 2001 2001 2001
2069 2069 2069 2069
SELECT * FROM t4 a, t4 b WHERE a.yyyy < b.yyyy;
yyyy c4 yyyy c4
1970 1970 1999 1999
1970 1970 2000 2000
1999 1999 2000 2000
1970 1970 2001 2001
1999 1999 2001 2001
2000 2000 2001 2001
1970 1970 2069 2069
1999 1999 2069 2069
2000 2000 2069 2069
2001 2001 2069 2069
# Comparison with constants:
SELECT * FROM t2 WHERE yy = NULL;
yy c2
SELECT * FROM t4 WHERE yyyy = NULL;
yyyy c4
SELECT * FROM t2 WHERE yy <=> NULL;
yy c2
NULL NULL
SELECT * FROM t4 WHERE yyyy <=> NULL;
yyyy c4
NULL NULL
SELECT * FROM t2 WHERE yy < NULL;
yy c2
SELECT * FROM t2 WHERE yy > NULL;
yy c2
SELECT * FROM t2 WHERE yy = NOW();
yy c2
SELECT * FROM t4 WHERE yyyy = NOW();
yyyy c4
SELECT * FROM t2 WHERE yy = 99;
yy c2
99 1999
SELECT * FROM t2 WHERE 99 = yy;
yy c2
99 1999
SELECT * FROM t4 WHERE yyyy = 99;
yyyy c4
1999 1999
SELECT * FROM t2 WHERE yy = 'test';
yy c2
00 2000
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'test'
SELECT * FROM t4 WHERE yyyy = 'test';
yyyy c4
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'test'
SELECT * FROM t2 WHERE yy = '1999';
yy c2
99 1999
SELECT * FROM t4 WHERE yyyy = '1999';
yyyy c4
1999 1999
SELECT * FROM t2 WHERE yy = 1999;
yy c2
99 1999
SELECT * FROM t4 WHERE yyyy = 1999;
yyyy c4
1999 1999
SELECT * FROM t2 WHERE yy = 1999.1;
yy c2
99 1999
SELECT * FROM t4 WHERE yyyy = 1999.1;
yyyy c4
1999 1999
SELECT * FROM t2 WHERE yy = 1998.9;
yy c2
99 1999
SELECT * FROM t4 WHERE yyyy = 1998.9;
yyyy c4
1999 1999
# Coverage tests for YEAR with zero/2000 constants:
SELECT * FROM t2 WHERE yy = 0;
yy c2
00 2000
SELECT * FROM t2 WHERE yy = '0';
yy c2
00 2000
SELECT * FROM t2 WHERE yy = '0000';
yy c2
00 2000
SELECT * FROM t2 WHERE yy = '2000';
yy c2
00 2000
SELECT * FROM t2 WHERE yy = 2000;
yy c2
00 2000
SELECT * FROM t4 WHERE yyyy = 0;
yyyy c4
SELECT * FROM t4 WHERE yyyy = '0';
yyyy c4
2000 2000
SELECT * FROM t4 WHERE yyyy = '0000';
yyyy c4
SELECT * FROM t4 WHERE yyyy = '2000';
yyyy c4
2000 2000
SELECT * FROM t4 WHERE yyyy = 2000;
yyyy c4
2000 2000
# Comparison with constants those are out of YEAR range
# (coverage test for backward compatibility)
SELECT COUNT(yy) FROM t2;
COUNT(yy)
5
SELECT COUNT(yyyy) FROM t4;
COUNT(yyyy)
5
SELECT COUNT(*) FROM t2 WHERE yy = -1;
COUNT(*)
0
SELECT COUNT(*) FROM t4 WHERE yyyy > -1;
COUNT(*)
5
SELECT COUNT(*) FROM t2 WHERE yy > -1000000000000000000;
COUNT(*)
5
SELECT COUNT(*) FROM t4 WHERE yyyy > -1000000000000000000;
COUNT(*)
5
SELECT COUNT(*) FROM t2 WHERE yy < 2156;
COUNT(*)
5
SELECT COUNT(*) FROM t4 WHERE yyyy < 2156;
COUNT(*)
5
SELECT COUNT(*) FROM t2 WHERE yy < 1000000000000000000;
COUNT(*)
5
SELECT COUNT(*) FROM t4 WHERE yyyy < 1000000000000000000;
COUNT(*)
5
SELECT * FROM t2 WHERE yy < 123;
yy c2
70 1970
99 1999
00 2000
01 2001
69 2069
SELECT * FROM t2 WHERE yy > 123;
yy c2
SELECT * FROM t4 WHERE yyyy < 123;
yyyy c4
SELECT * FROM t4 WHERE yyyy > 123;
yyyy c4
1970 1970
1999 1999
2000 2000
2001 2001
2069 2069
DROP TABLE t2, t4;
#
End of 5.1 tests

View File

@ -1,3 +1,8 @@
call mtr.add_suppression('Attempting backtrace');
call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.');
call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.');
call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.');
flush logs;
flush logs;
flush logs;
@ -21,7 +26,6 @@ flush logs;
*** must be a warning master-bin.000001 was not found ***
Warnings:
Warning 1612 Being purged log master-bin.000001 was not found
Warning 1612 Being purged log master-bin.000001 was not found
*** must show one record, of the active binlog, left in the index file after PURGE ***
show binary logs;
Log_name File_size
@ -37,4 +41,111 @@ Level Code Message
Warning 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files
Error 1377 Fatal error during log purge
reset master;
# crash_purge_before_update_index
flush logs;
SET SESSION debug="+d,crash_purge_before_update_index";
purge binary logs TO 'master-bin.000002';
ERROR HY000: Lost connection to MySQL server during query
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000001
master-bin.000002
master-bin.000003
# crash_purge_non_critical_after_update_index
flush logs;
SET SESSION debug="+d,crash_purge_non_critical_after_update_index";
purge binary logs TO 'master-bin.000004';
ERROR HY000: Lost connection to MySQL server during query
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000004
master-bin.000005
# crash_purge_critical_after_update_index
flush logs;
SET SESSION debug="+d,crash_purge_critical_after_update_index";
purge binary logs TO 'master-bin.000006';
ERROR HY000: Lost connection to MySQL server during query
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000006
master-bin.000007
# crash_create_non_critical_before_update_index
SET SESSION debug="+d,crash_create_non_critical_before_update_index";
flush logs;
ERROR HY000: Lost connection to MySQL server during query
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000006
master-bin.000007
master-bin.000008
# crash_create_critical_before_update_index
SET SESSION debug="+d,crash_create_critical_before_update_index";
flush logs;
ERROR HY000: Lost connection to MySQL server during query
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000006
master-bin.000007
master-bin.000008
master-bin.000009
# crash_create_after_update_index
SET SESSION debug="+d,crash_create_after_update_index";
flush logs;
ERROR HY000: Lost connection to MySQL server during query
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000006
master-bin.000007
master-bin.000008
master-bin.000009
master-bin.000010
master-bin.000011
#
# This should put the server in unsafe state and stop
# accepting any command. If we inject a fault at this
# point and continue the execution the server crashes.
# Besides the flush command does not report an error.
#
# fault_injection_registering_index
SET SESSION debug="+d,fault_injection_registering_index";
flush logs;
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000006
master-bin.000007
master-bin.000008
master-bin.000009
master-bin.000010
master-bin.000011
master-bin.000012
# fault_injection_updating_index
SET SESSION debug="+d,fault_injection_updating_index";
flush logs;
SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
SELECT @index;
@index
master-bin.000006
master-bin.000007
master-bin.000008
master-bin.000009
master-bin.000010
master-bin.000011
master-bin.000012
master-bin.000013
SET SESSION debug="";
End of tests

View File

@ -3,6 +3,18 @@
#
source include/have_log_bin.inc;
source include/not_embedded.inc;
# Don't test this under valgrind, memory leaks will occur
--source include/not_valgrind.inc
source include/have_debug.inc;
call mtr.add_suppression('Attempting backtrace');
call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.');
call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.');
call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.');
let $old=`select @@debug`;
let $MYSQLD_DATADIR= `select @@datadir`;
let $INDEX=$MYSQLD_DATADIR/master-bin.index;
#
# testing purge binary logs TO
@ -13,7 +25,6 @@ flush logs;
flush logs;
source include/show_binary_logs.inc;
let $MYSQLD_DATADIR= `select @@datadir`;
remove_file $MYSQLD_DATADIR/master-bin.000001;
# there must be a warning with file names
@ -66,4 +77,159 @@ rmdir $MYSQLD_DATADIR/master-bin.000001;
--disable_warnings
reset master;
--enable_warnings
--echo # crash_purge_before_update_index
flush logs;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug="+d,crash_purge_before_update_index";
--error 2013
purge binary logs TO 'master-bin.000002';
--enable_reconnect
--source include/wait_until_connected_again.inc
file_exists $MYSQLD_DATADIR/master-bin.000001;
file_exists $MYSQLD_DATADIR/master-bin.000002;
file_exists $MYSQLD_DATADIR/master-bin.000003;
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo # crash_purge_non_critical_after_update_index
flush logs;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug="+d,crash_purge_non_critical_after_update_index";
--error 2013
purge binary logs TO 'master-bin.000004';
--enable_reconnect
--source include/wait_until_connected_again.inc
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000001;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000002;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000003;
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo # crash_purge_critical_after_update_index
flush logs;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug="+d,crash_purge_critical_after_update_index";
--error 2013
purge binary logs TO 'master-bin.000006';
--enable_reconnect
--source include/wait_until_connected_again.inc
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000004;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000005;
file_exists $MYSQLD_DATADIR/master-bin.000006;
file_exists $MYSQLD_DATADIR/master-bin.000007;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000008;
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo # crash_create_non_critical_before_update_index
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug="+d,crash_create_non_critical_before_update_index";
--error 2013
flush logs;
--enable_reconnect
--source include/wait_until_connected_again.inc
file_exists $MYSQLD_DATADIR/master-bin.000008;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000009;
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo # crash_create_critical_before_update_index
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug="+d,crash_create_critical_before_update_index";
--error 2013
flush logs;
--enable_reconnect
--source include/wait_until_connected_again.inc
file_exists $MYSQLD_DATADIR/master-bin.000009;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000010;
--error 1
file_exists $MYSQLD_DATADIR/master-bin.000011;
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo # crash_create_after_update_index
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug="+d,crash_create_after_update_index";
--error 2013
flush logs;
--enable_reconnect
--source include/wait_until_connected_again.inc
file_exists $MYSQLD_DATADIR/master-bin.000010;
file_exists $MYSQLD_DATADIR/master-bin.000011;
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo #
--echo # This should put the server in unsafe state and stop
--echo # accepting any command. If we inject a fault at this
--echo # point and continue the execution the server crashes.
--echo # Besides the flush command does not report an error.
--echo #
--echo # fault_injection_registering_index
SET SESSION debug="+d,fault_injection_registering_index";
flush logs;
--source include/restart_mysqld.inc
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
--echo # fault_injection_updating_index
SET SESSION debug="+d,fault_injection_updating_index";
flush logs;
--source include/restart_mysqld.inc
--chmod 0644 $INDEX
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval SET @index=LOAD_FILE('$index')
-- replace_regex /\.[\\\/]master/master/
SELECT @index;
eval SET SESSION debug="$old";
--echo End of tests

View File

@ -0,0 +1,9 @@
create table ABC (i int) engine=ibmdb2i;
insert into ABC values(1);
create table abc (i int) engine=ibmdb2i;
insert into abc values (2);
select * from ABC;
i
1
drop table ABC;
drop table abc;

View File

@ -0,0 +1,10 @@
source suite/ibmdb2i/include/have_ibmdb2i.inc;
source include/have_case_sensitive_file_system.inc;
create table ABC (i int) engine=ibmdb2i;
insert into ABC values(1);
create table abc (i int) engine=ibmdb2i;
insert into abc values (2);
select * from ABC;
drop table ABC;
drop table abc;

View File

@ -169,4 +169,77 @@ DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
######## BUG#49119 #######
### i) test case from the 'how to repeat section'
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TABLE t1(c1 INT);
CREATE PROCEDURE p1() SELECT * FROM t1 |
REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost';
ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1'
DROP TABLE t1;
DROP PROCEDURE p1;
### ii) Test case in which REVOKE partially succeeds
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TABLE t1(c1 INT);
CREATE PROCEDURE p1() SELECT * FROM t1 |
CREATE USER 'user49119'@'localhost';
GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost';
##############################################################
### Showing grants for both users: root and user49119 (master)
SHOW GRANTS FOR 'user49119'@'localhost';
Grants for user49119@localhost
GRANT USAGE ON *.* TO 'user49119'@'localhost'
GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'user49119'@'localhost'
SHOW GRANTS FOR CURRENT_USER;
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
##############################################################
##############################################################
### Showing grants for both users: root and user49119 (master)
SHOW GRANTS FOR 'user49119'@'localhost';
Grants for user49119@localhost
GRANT USAGE ON *.* TO 'user49119'@'localhost'
GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'user49119'@'localhost'
SHOW GRANTS FOR CURRENT_USER;
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
##############################################################
## This statement will make the revoke fail because root has no
## execute grant. However, it will still revoke the grant for
## user49119.
REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost';
ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1'
##############################################################
### Showing grants for both users: root and user49119 (master)
### after revoke statement failure
SHOW GRANTS FOR 'user49119'@'localhost';
Grants for user49119@localhost
GRANT USAGE ON *.* TO 'user49119'@'localhost'
SHOW GRANTS FOR CURRENT_USER;
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
##############################################################
#############################################################
### Showing grants for both users: root and user49119 (slave)
### after revoke statement failure (should match
SHOW GRANTS FOR 'user49119'@'localhost';
Grants for user49119@localhost
GRANT USAGE ON *.* TO 'user49119'@'localhost'
SHOW GRANTS FOR CURRENT_USER;
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
##############################################################
DROP TABLE t1;
DROP PROCEDURE p1;
DROP USER 'user49119'@'localhost';
"End of test"

View File

@ -63,7 +63,7 @@ source include/diff_master_slave.inc;
DROP DATABASE d1;
source include/kill_query.inc;
source include/diff_master_slave.inc;
DROP DATABASE d2;
DROP DATABASE IF EXISTS d2;
source include/kill_query.inc;
source include/diff_master_slave.inc;
CREATE EVENT e2
@ -115,6 +115,7 @@ source include/diff_master_slave.inc;
DROP INDEX i1 on t1;
source include/kill_query.inc;
source include/diff_master_slave.inc;
CREATE TABLE IF NOT EXISTS t4 (a int);
CREATE TRIGGER tr2 BEFORE INSERT ON t4
FOR EACH ROW BEGIN
DELETE FROM t1 WHERE a=NEW.a;

View File

@ -216,4 +216,104 @@ connection slave;
USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
# BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...'
#
# The tests are divided into two test cases:
#
# i) a test case that mimics the one in the bug report.
#
# - We show that, despite the fact, that a revoke command fails
# when binlogging is active, the master will not hit an
# assertion.
#
# ii) a test case that partially succeeds on the master will also
# partially succeed on the slave.
#
# - The revoke statement that partially succeeds tries to revoke
# an EXECUTE grant for two users, and only one of the user has
# the specific grant. This will cause mysql to drop one of the
# grants and report error for the statement. The slave should
# also drop the grants that the master succeed and the SQL
# thread should not stop on statement failure.
-- echo ######## BUG#49119 #######
-- echo ### i) test case from the 'how to repeat section'
-- source include/master-slave-reset.inc
-- connection master
CREATE TABLE t1(c1 INT);
DELIMITER |;
CREATE PROCEDURE p1() SELECT * FROM t1 |
DELIMITER ;|
-- error ER_NONEXISTING_PROC_GRANT
REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost';
-- sync_slave_with_master
-- connection master
DROP TABLE t1;
DROP PROCEDURE p1;
-- sync_slave_with_master
-- echo ### ii) Test case in which REVOKE partially succeeds
-- connection master
-- source include/master-slave-reset.inc
-- connection master
CREATE TABLE t1(c1 INT);
DELIMITER |;
CREATE PROCEDURE p1() SELECT * FROM t1 |
DELIMITER ;|
CREATE USER 'user49119'@'localhost';
GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost';
-- echo ##############################################################
-- echo ### Showing grants for both users: root and user49119 (master)
SHOW GRANTS FOR 'user49119'@'localhost';
SHOW GRANTS FOR CURRENT_USER;
-- echo ##############################################################
-- sync_slave_with_master
-- echo ##############################################################
-- echo ### Showing grants for both users: root and user49119 (master)
SHOW GRANTS FOR 'user49119'@'localhost';
SHOW GRANTS FOR CURRENT_USER;
-- echo ##############################################################
-- connection master
-- echo ## This statement will make the revoke fail because root has no
-- echo ## execute grant. However, it will still revoke the grant for
-- echo ## user49119.
-- error ER_NONEXISTING_PROC_GRANT
REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost';
-- echo ##############################################################
-- echo ### Showing grants for both users: root and user49119 (master)
-- echo ### after revoke statement failure
SHOW GRANTS FOR 'user49119'@'localhost';
SHOW GRANTS FOR CURRENT_USER;
-- echo ##############################################################
-- sync_slave_with_master
-- echo #############################################################
-- echo ### Showing grants for both users: root and user49119 (slave)
-- echo ### after revoke statement failure (should match
SHOW GRANTS FOR 'user49119'@'localhost';
SHOW GRANTS FOR CURRENT_USER;
-- echo ##############################################################
-- connection master
DROP TABLE t1;
DROP PROCEDURE p1;
DROP USER 'user49119'@'localhost';
-- sync_slave_with_master
--echo "End of test"

View File

@ -153,7 +153,7 @@ source include/kill_query_and_diff_master_slave.inc;
send DROP DATABASE d1;
source include/kill_query_and_diff_master_slave.inc;
send DROP DATABASE d2;
send DROP DATABASE IF EXISTS d2;
source include/kill_query_and_diff_master_slave.inc;
######## EVENT ########
@ -226,7 +226,7 @@ source include/kill_query_and_diff_master_slave.inc;
send DROP PROCEDURE p1;
source include/kill_query_and_diff_master_slave.inc;
# Temporarily disabled, see comment above for DROP FUNCTION IF EXISTS
# Temporarily disabled because of bug#43353, see comment above for DROP FUNCTION IF EXISTS
#send DROP PROCEDURE IF EXISTS p2;
#source include/kill_query_and_diff_master_slave.inc;
@ -277,6 +277,11 @@ source include/kill_query_and_diff_master_slave.inc;
######## TRIGGER ########
# Make sure table t4 exists
connection master;
CREATE TABLE IF NOT EXISTS t4 (a int);
connection master1;
let $diff_statement= SHOW TRIGGERS LIKE 'v%';
DELIMITER //;

View File

@ -1411,6 +1411,16 @@ select hex(_utf8 B'001111111111');
--error ER_INVALID_CHARACTER_STRING
select (_utf8 X'616263FF');
--echo #
--echo # Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings
--echo #
CREATE TABLE t1 (id int not null primary key, name varchar(10)) character set utf8;
INSERT INTO t1 VALUES
(2,'一二三01'),(3,'一二三09'),(4,'一二三02'),(5,'一二三08'),
(6,'一二三11'),(7,'一二三91'),(8,'一二三21'),(9,'一二三81');
SELECT * FROM t1 ORDER BY BINARY(name);
DROP TABLE t1;
#
# Bug #36772: When using UTF8, CONVERT with GROUP BY returns truncated results
#

View File

@ -10,7 +10,6 @@
#
##############################################################################
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadicallyr
innodb-autoinc : Bug#49267 2009-12-02 test fails on windows because of different case mode
innodb : Bug#49396 2009-12-03 test fails in embedded mode

View File

@ -1320,6 +1320,39 @@ explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
drop table t1;
--echo #
--echo # Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (a VARCHAR(20), b INT);
CREATE TABLE t2 (a VARCHAR(20), b INT);
INSERT INTO t1 VALUES ('ABC', 1);
INSERT INTO t2 VALUES ('ABC', 1);
SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
SELECT DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC')
FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
INSERT INTO t1 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
INSERT INTO t2 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
FROM t2 WHERE t2.b = 1 GROUP BY t2.b;
DROP TABLE t1, t2;
--echo Start of 5.4 tests
#

View File

@ -90,6 +90,24 @@ set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
eval set GLOBAL sql_mode=default;
--echo #
--echo # Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table
--echo # but does not set values.
--echo #
# Create a stored procedure and set the fields in question to null.
# When running mysql_upgrade, a warning should be written.
CREATE PROCEDURE testproc() BEGIN END;
UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc';
--exec $MYSQL_UPGRADE --skip-verbose --force 2> $MYSQLTEST_VARDIR/tmp/41569.txt
CALL testproc();
DROP PROCEDURE testproc;
--cat_file $MYSQLTEST_VARDIR/tmp/41569.txt
--remove_file $MYSQLTEST_VARDIR/tmp/41569.txt
#
# Test the --upgrade-system-tables option
#

View File

@ -886,6 +886,15 @@ SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
--echo # Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
# part 2 of the problem : DESC test cases
--echo # Must use ref-or-null on the a_c index
--replace_column 1 x 2 x 3 x 6 x 7 x 8 x 9 x 10 x
EXPLAIN
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
--echo # Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
DROP TABLE t1;

View File

@ -1991,6 +1991,29 @@ select @arg;
execute stmt using @arg;
deallocate prepare stmt;
--echo #
--echo # Bug#48508: Crash on prepared statement re-execution.
--echo #
create table t1(b int);
insert into t1 values (0);
create view v1 AS select 1 as a from t1 where b;
prepare stmt from "select * from v1 where a";
execute stmt;
execute stmt;
deallocate prepare stmt;
drop table t1;
drop view v1;
create table t1(a bigint);
create table t2(b tinyint);
insert into t2 values (null);
prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1";
execute stmt;
execute stmt;
deallocate prepare stmt;
drop table t1,t2;
--echo #
--echo End of 5.0 tests.
#
@ -3009,6 +3032,23 @@ execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
--echo #
prepare encode from "select encode(?, ?) into @ciphertext";
prepare decode from "select decode(?, ?) into @plaintext";
set @str="abc", @key="cba";
execute encode using @str, @key;
execute decode using @ciphertext, @key;
select @plaintext;
set @str="bcd", @key="dcb";
execute encode using @str, @key;
execute decode using @ciphertext, @key;
select @plaintext;
deallocate prepare encode;
deallocate prepare decode;
###########################################################################
--echo

View File

@ -3786,6 +3786,56 @@ SELECT 1 FROM t2 JOIN t1 ON 1=1
DROP TABLE t1,t2;
--echo #
--echo # Bug #49199: Optimizer handles incorrectly:
--echo # field='const1' AND field='const2' in some cases
--echo
CREATE TABLE t1(a DATETIME NOT NULL);
INSERT INTO t1 VALUES('2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
DROP TABLE t1;
CREATE TABLE t1(a DATE NOT NULL);
INSERT INTO t1 VALUES('2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
DROP TABLE t1;
CREATE TABLE t1(a TIMESTAMP NOT NULL);
INSERT INTO t1 VALUES('2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
DROP TABLE t1;
CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
DROP TABLE t1;
CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL);
INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
DROP TABLE t1;
CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
SELECT x.a, y.a, z.a FROM t1 x
JOIN t1 y ON x.a=y.a
JOIN t1 z ON y.a=z.a
WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
JOIN t1 y ON x.a=y.a
JOIN t1 z ON y.a=z.a
WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
DROP TABLE t1;
--echo End of 5.0 tests
#
@ -3964,4 +4014,13 @@ ORDER BY pk;
DROP TABLE t1;
--echo #
--echo # Bug#49489 Uninitialized cache led to a wrong result.
--echo #
CREATE TABLE t1(c1 DOUBLE(5,4));
INSERT INTO t1 VALUES (9.1234);
SELECT * FROM t1 WHERE c1 < 9.12345;
DROP TABLE t1;
--echo # End of test for bug#49489.
--echo End of 5.1 tests

View File

@ -1206,6 +1206,28 @@ connection default;
DROP USER test_u@localhost;
--echo #
--echo # Bug #48985: show create table crashes if previous access to the table
--echo # was killed
--echo #
connect(con1,localhost,root,,);
CONNECTION con1;
LET $ID= `SELECT connection_id()`;
CONNECTION default;
--disable_query_log
eval KILL QUERY $ID;
--enable_query_log
CONNECTION con1;
--error ER_QUERY_INTERRUPTED
SHOW CREATE TABLE non_existent;
CONNECTION default;
DISCONNECT con1;
--echo End of 5.1 tests
# Wait till all disconnects are completed

View File

@ -26,3 +26,32 @@ drop table t3|
delimiter ;|
#
# Bug#48766 SHOW CREATE FUNCTION returns extra data in return clause
#
SET NAMES utf8;
--disable_warnings
DROP FUNCTION IF EXISTS bug48766;
--enable_warnings
#
# Test that Latin letters are not prepended with extra '\0'.
#
CREATE FUNCTION bug48766 ()
RETURNS ENUM( 'w' ) CHARACTER SET ucs2
RETURN 0;
SHOW CREATE FUNCTION bug48766;
SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME='bug48766';
DROP FUNCTION bug48766;
#
# Test non-Latin characters
#
CREATE FUNCTION bug48766 ()
RETURNS ENUM('а','б','в','г') CHARACTER SET ucs2
RETURN 0;
SHOW CREATE FUNCTION bug48766;
SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME='bug48766';
DROP FUNCTION bug48766;

View File

@ -30,3 +30,109 @@ select * from t1;
drop table t1;
--echo End of 5.0 tests
--echo #
--echo # Bug #49480: WHERE using YEAR columns returns unexpected results
--echo #
CREATE TABLE t2(yy YEAR(2), c2 CHAR(4));
CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4));
INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069);
INSERT INTO t4 (c4) SELECT c2 FROM t2;
UPDATE t2 SET yy = c2;
UPDATE t4 SET yyyy = c4;
SELECT * FROM t2;
SELECT * FROM t4;
--echo # Comparison of YEAR(2) with YEAR(4)
SELECT * FROM t2, t4 WHERE yy = yyyy;
SELECT * FROM t2, t4 WHERE yy <=> yyyy;
SELECT * FROM t2, t4 WHERE yy < yyyy;
SELECT * FROM t2, t4 WHERE yy > yyyy;
--echo # Comparison of YEAR(2) with YEAR(2)
SELECT * FROM t2 a, t2 b WHERE a.yy = b.yy;
SELECT * FROM t2 a, t2 b WHERE a.yy <=> b.yy;
SELECT * FROM t2 a, t2 b WHERE a.yy < b.yy;
--echo # Comparison of YEAR(4) with YEAR(4)
SELECT * FROM t4 a, t4 b WHERE a.yyyy = b.yyyy;
SELECT * FROM t4 a, t4 b WHERE a.yyyy <=> b.yyyy;
SELECT * FROM t4 a, t4 b WHERE a.yyyy < b.yyyy;
--echo # Comparison with constants:
SELECT * FROM t2 WHERE yy = NULL;
SELECT * FROM t4 WHERE yyyy = NULL;
SELECT * FROM t2 WHERE yy <=> NULL;
SELECT * FROM t4 WHERE yyyy <=> NULL;
SELECT * FROM t2 WHERE yy < NULL;
SELECT * FROM t2 WHERE yy > NULL;
SELECT * FROM t2 WHERE yy = NOW();
SELECT * FROM t4 WHERE yyyy = NOW();
SELECT * FROM t2 WHERE yy = 99;
SELECT * FROM t2 WHERE 99 = yy;
SELECT * FROM t4 WHERE yyyy = 99;
SELECT * FROM t2 WHERE yy = 'test';
SELECT * FROM t4 WHERE yyyy = 'test';
SELECT * FROM t2 WHERE yy = '1999';
SELECT * FROM t4 WHERE yyyy = '1999';
SELECT * FROM t2 WHERE yy = 1999;
SELECT * FROM t4 WHERE yyyy = 1999;
SELECT * FROM t2 WHERE yy = 1999.1;
SELECT * FROM t4 WHERE yyyy = 1999.1;
SELECT * FROM t2 WHERE yy = 1998.9;
SELECT * FROM t4 WHERE yyyy = 1998.9;
--echo # Coverage tests for YEAR with zero/2000 constants:
SELECT * FROM t2 WHERE yy = 0;
SELECT * FROM t2 WHERE yy = '0';
SELECT * FROM t2 WHERE yy = '0000';
SELECT * FROM t2 WHERE yy = '2000';
SELECT * FROM t2 WHERE yy = 2000;
SELECT * FROM t4 WHERE yyyy = 0;
SELECT * FROM t4 WHERE yyyy = '0';
SELECT * FROM t4 WHERE yyyy = '0000';
SELECT * FROM t4 WHERE yyyy = '2000';
SELECT * FROM t4 WHERE yyyy = 2000;
--echo # Comparison with constants those are out of YEAR range
--echo # (coverage test for backward compatibility)
SELECT COUNT(yy) FROM t2;
SELECT COUNT(yyyy) FROM t4;
SELECT COUNT(*) FROM t2 WHERE yy = -1;
SELECT COUNT(*) FROM t4 WHERE yyyy > -1;
SELECT COUNT(*) FROM t2 WHERE yy > -1000000000000000000;
SELECT COUNT(*) FROM t4 WHERE yyyy > -1000000000000000000;
SELECT COUNT(*) FROM t2 WHERE yy < 2156;
SELECT COUNT(*) FROM t4 WHERE yyyy < 2156;
SELECT COUNT(*) FROM t2 WHERE yy < 1000000000000000000;
SELECT COUNT(*) FROM t4 WHERE yyyy < 1000000000000000000;
SELECT * FROM t2 WHERE yy < 123;
SELECT * FROM t2 WHERE yy > 123;
SELECT * FROM t4 WHERE yyyy < 123;
SELECT * FROM t4 WHERE yyyy > 123;
DROP TABLE t2, t4;
--echo #
--echo End of 5.1 tests

View File

@ -63,7 +63,26 @@ void my_safe_print_str(const char* name, const char* val, int max_len)
fputc('\n', stderr);
}
#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#if defined(HAVE_PRINTSTACK)
/* Use Solaris' symbolic stack trace routine. */
#include <ucontext.h>
void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
ulong thread_stack __attribute__((unused)))
{
if (printstack(fileno(stderr)) == -1)
fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n");
else
fprintf(stderr,
"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"
"Resolved stack trace is much more helpful in diagnosing the\n"
"problem, so please do resolve it\n");
}
#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#if BACKTRACE_DEMANGLE

View File

@ -420,18 +420,48 @@ ALTER TABLE proc ADD character_set_client
ALTER TABLE proc MODIFY character_set_client
char(32) collate utf8_bin DEFAULT NULL;
SELECT CASE WHEN COUNT(*) > 0 THEN
CONCAT ("WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (", @@character_set_client, "). Please verify if necessary.")
ELSE NULL
END
AS value FROM proc WHERE character_set_client IS NULL;
UPDATE proc SET character_set_client = @@character_set_client
WHERE character_set_client IS NULL;
ALTER TABLE proc ADD collation_connection
char(32) collate utf8_bin DEFAULT NULL
AFTER character_set_client;
ALTER TABLE proc MODIFY collation_connection
char(32) collate utf8_bin DEFAULT NULL;
SELECT CASE WHEN COUNT(*) > 0 THEN
CONCAT ("WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (", @@collation_connection, "). Please verify if necessary.")
ELSE NULL
END
AS value FROM proc WHERE collation_connection IS NULL;
UPDATE proc SET collation_connection = @@collation_connection
WHERE collation_connection IS NULL;
ALTER TABLE proc ADD db_collation
char(32) collate utf8_bin DEFAULT NULL
AFTER collation_connection;
ALTER TABLE proc MODIFY db_collation
char(32) collate utf8_bin DEFAULT NULL;
SELECT CASE WHEN COUNT(*) > 0 THEN
CONCAT ("WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary.")
ELSE NULL
END
AS value FROM proc WHERE db_collation IS NULL;
UPDATE proc AS p SET db_collation =
( SELECT DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = p.db)
WHERE db_collation IS NULL;
ALTER TABLE proc ADD body_utf8 longblob DEFAULT NULL
AFTER db_collation;
ALTER TABLE proc MODIFY body_utf8 longblob DEFAULT NULL;

View File

@ -956,40 +956,9 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
if (agg_item_set_converter(coll, owner->func_name(),
b, 1, MY_COLL_CMP_CONV, 1))
return 1;
} else if (type != ROW_RESULT && ((*a)->field_type() == MYSQL_TYPE_YEAR ||
(*b)->field_type() == MYSQL_TYPE_YEAR))
{
is_nulls_eq= is_owner_equal_func();
year_as_datetime= FALSE;
if ((*a)->is_datetime())
{
year_as_datetime= TRUE;
get_value_a_func= &get_datetime_value;
} else if ((*a)->field_type() == MYSQL_TYPE_YEAR)
get_value_a_func= &get_year_value;
else
{
/*
Because convert_constant_item is called only for EXECUTE in PS mode
the value of get_value_x_func set in PREPARE might be not
valid for EXECUTE.
*/
get_value_a_func= NULL;
}
if ((*b)->is_datetime())
{
year_as_datetime= TRUE;
get_value_b_func= &get_datetime_value;
} else if ((*b)->field_type() == MYSQL_TYPE_YEAR)
get_value_b_func= &get_year_value;
else
get_value_b_func= NULL;
func= &Arg_comparator::compare_year;
return 0;
}
else if (try_year_cmp_func(type))
return 0;
a= cache_converted_constant(thd, a, &a_cache, type);
b= cache_converted_constant(thd, b, &b_cache, type);
@ -997,6 +966,45 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
}
/*
Helper function to call from Arg_comparator::set_cmp_func()
*/
bool Arg_comparator::try_year_cmp_func(Item_result type)
{
if (type == ROW_RESULT)
return FALSE;
bool a_is_year= (*a)->field_type() == MYSQL_TYPE_YEAR;
bool b_is_year= (*b)->field_type() == MYSQL_TYPE_YEAR;
if (!a_is_year && !b_is_year)
return FALSE;
if (a_is_year && b_is_year)
{
get_value_a_func= &get_year_value;
get_value_b_func= &get_year_value;
}
else if (a_is_year && (*b)->is_datetime())
{
get_value_a_func= &get_year_value;
get_value_b_func= &get_datetime_value;
}
else if (b_is_year && (*a)->is_datetime())
{
get_value_b_func= &get_year_value;
get_value_a_func= &get_datetime_value;
}
else
return FALSE;
is_nulls_eq= is_owner_equal_func();
func= &Arg_comparator::compare_datetime;
return TRUE;
}
/**
Convert and cache a constant.
@ -1023,7 +1031,7 @@ Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value,
(*value)->const_item() && type != (*value)->result_type())
{
Item_cache *cache= Item_cache::get_cache(*value, type);
cache->store(*value);
cache->setup(*value);
*cache_item= cache;
return cache_item;
}
@ -1147,7 +1155,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
/*
Retrieves YEAR value of 19XX form from given item.
Retrieves YEAR value of 19XX-00-00 00:00:00 form from given item.
SYNOPSIS
get_year_value()
@ -1159,7 +1167,9 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
DESCRIPTION
Retrieves the YEAR value of 19XX form from given item for comparison by the
compare_year() function.
compare_datetime() function.
Converts year to DATETIME of form YYYY-00-00 00:00:00 for the compatibility
with the get_datetime_value function result.
RETURN
obtained value
@ -1186,6 +1196,9 @@ get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
if (value <= 1900)
value+= 1900;
/* Convert year to DATETIME of form YYYY-00-00 00:00:00 (YYYY0000000000). */
value*= 10000000000LL;
return value;
}
@ -1615,67 +1628,6 @@ int Arg_comparator::compare_e_row()
}
/**
Compare values as YEAR.
@details
Compare items as YEAR for EQUAL_FUNC and for other comparison functions.
The YEAR values of form 19XX are obtained with help of the get_year_value()
function.
If one of arguments is of DATE/DATETIME type its value is obtained
with help of the get_datetime_value function. In this case YEAR values
prior to comparison are converted to the ulonglong YYYY-00-00 00:00:00
DATETIME form.
If an argument type neither YEAR nor DATE/DATEIME then val_int function
is used to obtain value for comparison.
RETURN
If is_nulls_eq is TRUE:
1 if items are equal or both are null
0 otherwise
If is_nulls_eq is FALSE:
-1 a < b
0 a == b or at least one of items is null
1 a > b
See the table:
is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
a_is_null | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
b_is_null | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
result | 1 | 0 | 0 |0/1| 0 | 0 | 0 |-1/0/1|
*/
int Arg_comparator::compare_year()
{
bool a_is_null, b_is_null;
ulonglong val1= get_value_a_func ?
(*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null) :
(*a)->val_int();
ulonglong val2= get_value_b_func ?
(*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null) :
(*b)->val_int();
if (!(*a)->null_value)
{
if (!(*b)->null_value)
{
if (set_null)
owner->null_value= 0;
/* Convert year to DATETIME of form YYYY-00-00 00:00:00 when necessary. */
if((*a)->field_type() == MYSQL_TYPE_YEAR && year_as_datetime)
val1*= 10000000000LL;
if((*b)->field_type() == MYSQL_TYPE_YEAR && year_as_datetime)
val2*= 10000000000LL;
if (val1 < val2) return is_nulls_eq ? 0 : -1;
if (val1 == val2) return is_nulls_eq ? 1 : 0;
return is_nulls_eq ? 0 : 1;
}
}
if (set_null)
owner->null_value= is_nulls_eq ? 0 : 1;
return (is_nulls_eq && (*a)->null_value == (*b)->null_value) ? 1 : 0;
}
void Item_func_truth::fix_length_and_dec()
{
maybe_null= 0;
@ -4291,7 +4243,7 @@ Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
uchar *arg_v= *arg_p;
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
if (new_item && new_item != item)
li.replace(new_item);
current_thd->change_item_tree(li.ref(), new_item);
}
return Item_func::transform(transformer, arg_t);
}
@ -5292,7 +5244,8 @@ Item *Item_bool_rowready_func2::negated_item()
}
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0),
compare_as_dates(FALSE)
{
const_item_cache= 0;
fields.push_back(f1);
@ -5305,6 +5258,7 @@ Item_equal::Item_equal(Item *c, Item_field *f)
const_item_cache= 0;
fields.push_back(f);
const_item= c;
compare_as_dates= f->is_datetime();
}
@ -5319,9 +5273,45 @@ Item_equal::Item_equal(Item_equal *item_equal)
fields.push_back(item);
}
const_item= item_equal->const_item;
compare_as_dates= item_equal->compare_as_dates;
cond_false= item_equal->cond_false;
}
void Item_equal::compare_const(Item *c)
{
if (compare_as_dates)
{
cmp.set_datetime_cmp_func(this, &c, &const_item);
cond_false= cmp.compare();
}
else
{
Item_func_eq *func= new Item_func_eq(c, const_item);
func->set_cmp_func();
func->quick_fix_field();
cond_false= !func->val_int();
}
if (cond_false)
const_item_cache= 1;
}
void Item_equal::add(Item *c, Item_field *f)
{
if (cond_false)
return;
if (!const_item)
{
DBUG_ASSERT(f);
const_item= c;
compare_as_dates= f->is_datetime();
return;
}
compare_const(c);
}
void Item_equal::add(Item *c)
{
if (cond_false)
@ -5331,11 +5321,7 @@ void Item_equal::add(Item *c)
const_item= c;
return;
}
Item_func_eq *func= new Item_func_eq(c, const_item);
func->set_cmp_func();
func->quick_fix_field();
if ((cond_false= !func->val_int()))
const_item_cache= 1;
compare_const(c);
}
void Item_equal::add(Item_field *f)

View File

@ -45,24 +45,22 @@ class Arg_comparator: public Sql_alloc
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
bool set_null; // TRUE <=> set owner->null_value
// when one of arguments is NULL.
bool year_as_datetime; // TRUE <=> convert YEAR value to
// the YYYY-00-00 00:00:00 DATETIME
// format. See compare_year.
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
bool try_year_cmp_func(Item_result type);
public:
DTCollation cmp_collation;
/* Allow owner function to use string buffers. */
String value1, value2;
Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(0),
year_as_datetime(0), get_value_a_func(0), get_value_b_func(0) {};
get_value_a_func(0), get_value_b_func(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
a_cache(0), b_cache(0), set_null(0), year_as_datetime(0),
a_cache(0), b_cache(0), set_null(0),
get_value_a_func(0), get_value_b_func(0) {};
int set_compare_func(Item_result_field *owner, Item_result type);
@ -104,7 +102,6 @@ public:
int compare_real_fixed();
int compare_e_real_fixed();
int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
int compare_year();
static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
ulonglong *const_val_arg);
@ -1586,7 +1583,9 @@ class Item_equal: public Item_bool_func
List<Item_field> fields; /* list of equal field items */
Item *const_item; /* optional constant item equal to fields items */
cmp_item *eval_item;
Arg_comparator cmp;
bool cond_false;
bool compare_as_dates;
public:
inline Item_equal()
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
@ -1595,6 +1594,8 @@ public:
Item_equal(Item *c, Item_field *f);
Item_equal(Item_equal *item_equal);
inline Item* get_const() { return const_item; }
void compare_const(Item *c);
void add(Item *c, Item_field *f);
void add(Item *c);
void add(Item_field *f);
uint members();

View File

@ -1720,68 +1720,65 @@ String *Item_func_encrypt::val_str(String *str)
#endif /* HAVE_CRYPT */
}
bool Item_func_encode::seed()
{
char buf[80];
ulong rand_nr[2];
String *key, tmp(buf, sizeof(buf), system_charset_info);
if (!(key= args[1]->val_str(&tmp)))
return TRUE;
hash_password(rand_nr, key->ptr(), key->length());
sql_crypt.init(rand_nr);
return FALSE;
}
void Item_func_encode::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null=args[0]->maybe_null || args[1]->maybe_null;
collation.set(&my_charset_bin);
/* Precompute the seed state if the item is constant. */
seeded= args[1]->const_item() &&
(args[1]->result_type() == STRING_RESULT) && !seed();
}
String *Item_func_encode::val_str(String *str)
{
String *res;
char pw_buff[80];
String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
String *password;
DBUG_ASSERT(fixed == 1);
if (!(res=args[0]->val_str(str)))
{
null_value=1; /* purecov: inspected */
return 0; /* purecov: inspected */
null_value= 1;
return NULL;
}
if (!(password=args[1]->val_str(& tmp_pw_value)))
if (!seeded && seed())
{
null_value=1;
return 0;
null_value= 1;
return NULL;
}
null_value=0;
res=copy_if_not_alloced(str,res,res->length());
SQL_CRYPT sql_crypt(password->ptr(), password->length());
sql_crypt.init();
sql_crypt.encode((char*) res->ptr(),res->length());
res->set_charset(&my_charset_bin);
null_value= 0;
res= copy_if_not_alloced(str, res, res->length());
transform(res);
sql_crypt.reinit();
return res;
}
String *Item_func_decode::val_str(String *str)
void Item_func_encode::transform(String *res)
{
String *res;
char pw_buff[80];
String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
String *password;
DBUG_ASSERT(fixed == 1);
sql_crypt.encode((char*) res->ptr(),res->length());
res->set_charset(&my_charset_bin);
}
if (!(res=args[0]->val_str(str)))
{
null_value=1; /* purecov: inspected */
return 0; /* purecov: inspected */
}
if (!(password=args[1]->val_str(& tmp_pw_value)))
{
null_value=1;
return 0;
}
null_value=0;
res=copy_if_not_alloced(str,res,res->length());
SQL_CRYPT sql_crypt(password->ptr(), password->length());
sql_crypt.init();
void Item_func_decode::transform(String *res)
{
sql_crypt.decode((char*) res->ptr(),res->length());
return res;
}

View File

@ -354,12 +354,22 @@ public:
class Item_func_encode :public Item_str_func
{
private:
/** Whether the PRNG has already been seeded. */
bool seeded;
protected:
SQL_CRYPT sql_crypt;
public:
Item_func_encode(Item *a, Item *seed):
Item_str_func(a, seed) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "encode"; }
protected:
virtual void transform(String *);
private:
/** Provide a seed for the PRNG sequence. */
bool seed();
};
@ -367,8 +377,9 @@ class Item_func_decode :public Item_func_encode
{
public:
Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {}
String *val_str(String *);
const char *func_name() const { return "decode"; }
protected:
void transform(String *);
};

View File

@ -2608,9 +2608,9 @@ void Item_char_typecast::fix_length_and_dec()
from_cs != &my_charset_bin &&
cast_cs != &my_charset_bin);
collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ?
cast_length :
args[0]->max_length / args[0]->collation.collation->mbmaxlen;
char_length= (cast_length >= 0) ? cast_length :
args[0]->max_length /
(cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen);
max_length= char_length * cast_cs->mbmaxlen;
}

View File

@ -1910,6 +1910,22 @@ void MYSQL_LOG::init(enum_log_type log_type_arg,
}
bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name,
const char *new_name,
enum_log_type log_type_arg,
enum cache_type io_cache_type_arg)
{
init(log_type_arg, io_cache_type_arg);
if (new_name && !strmov(log_file_name, new_name))
return TRUE;
else if (!new_name && generate_new_name(log_file_name, log_name))
return TRUE;
return FALSE;
}
/*
Open a (new) log file.
@ -1942,17 +1958,14 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
write_error= 0;
init(log_type_arg, io_cache_type_arg);
if (!(name= my_strdup(log_name, MYF(MY_WME))))
{
name= (char *)log_name; // for the error message
goto err;
}
if (new_name)
strmov(log_file_name, new_name);
else if (generate_new_name(log_file_name, name))
if (init_and_set_log_file_name(name, new_name,
log_type_arg, io_cache_type_arg))
goto err;
if (io_cache_type == SEQ_READ_APPEND)
@ -2443,7 +2456,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
*/
index_file_name[0] = 0;
bzero((char*) &index_file, sizeof(index_file));
bzero((char*) &purge_temp, sizeof(purge_temp));
bzero((char*) &purge_index_file, sizeof(purge_index_file));
}
/* this is called only once */
@ -2487,7 +2500,7 @@ void MYSQL_BIN_LOG::init_pthread_objects()
bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
const char *log_name)
const char *log_name, bool need_mutex)
{
File index_file_nr= -1;
DBUG_ASSERT(!my_b_inited(&index_file));
@ -2512,7 +2525,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
init_io_cache(&index_file, index_file_nr,
IO_SIZE, WRITE_CACHE,
my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
0, MYF(MY_WME | MY_WAIT_IF_FULL)))
0, MYF(MY_WME | MY_WAIT_IF_FULL)) ||
DBUG_EVALUATE_IF("fault_injection_openning_index", 1, 0))
{
/*
TODO: all operations creating/deleting the index file or a log, should
@ -2523,6 +2537,28 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
my_close(index_file_nr,MYF(0));
return TRUE;
}
#ifdef HAVE_REPLICATION
/*
Sync the index by purging any binary log file that is not registered.
In other words, either purge binary log files that were removed from
the index but not purged from the file system due to a crash or purge
any binary log file that was created but not register in the index
due to a crash.
*/
if (set_purge_index_file_name(index_file_name_arg) ||
open_purge_index_file(FALSE) ||
purge_index_entry(NULL, NULL, need_mutex) ||
close_purge_index_file() ||
DBUG_EVALUATE_IF("fault_injection_recovering_index", 1, 0))
{
sql_print_error("MYSQL_BIN_LOG::open_index_file failed to sync the index "
"file.");
return TRUE;
}
#endif
return FALSE;
}
@ -2547,17 +2583,44 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
enum cache_type io_cache_type_arg,
bool no_auto_events_arg,
ulong max_size_arg,
bool null_created_arg)
bool null_created_arg,
bool need_mutex)
{
File file= -1;
DBUG_ENTER("MYSQL_BIN_LOG::open");
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
write_error=0;
if (init_and_set_log_file_name(log_name, new_name, log_type_arg,
io_cache_type_arg))
{
sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name.");
DBUG_RETURN(1);
}
#ifdef HAVE_REPLICATION
if (open_purge_index_file(TRUE) ||
register_create_index_entry(log_file_name) ||
sync_purge_index_file() ||
DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0))
{
sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
DBUG_RETURN(1);
}
DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort(););
#endif
write_error= 0;
/* open the main log file */
if (MYSQL_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
if (MYSQL_LOG::open(log_name, log_type_arg, new_name,
io_cache_type_arg))
{
#ifdef HAVE_REPLICATION
close_purge_index_file();
#endif
DBUG_RETURN(1); /* all warnings issued */
}
init(no_auto_events_arg, max_size_arg);
@ -2583,9 +2646,6 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
write_file_name_to_index_file= 1;
}
DBUG_ASSERT(my_b_inited(&index_file) != 0);
reinit_io_cache(&index_file, WRITE_CACHE,
my_b_filelength(&index_file), 0, 0);
if (need_start_event && !no_auto_events)
{
/*
@ -2643,23 +2703,44 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
if (write_file_name_to_index_file)
{
#ifdef HAVE_REPLICATION
DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort(););
#endif
DBUG_ASSERT(my_b_inited(&index_file) != 0);
reinit_io_cache(&index_file, WRITE_CACHE,
my_b_filelength(&index_file), 0, 0);
/*
As this is a new log file, we write the file name to the index
file. As every time we write to the index file, we sync it.
*/
if (my_b_write(&index_file, (uchar*) log_file_name,
strlen(log_file_name)) ||
my_b_write(&index_file, (uchar*) "\n", 1) ||
flush_io_cache(&index_file) ||
if (DBUG_EVALUATE_IF("fault_injection_updating_index", 1, 0) ||
my_b_write(&index_file, (uchar*) log_file_name,
strlen(log_file_name)) ||
my_b_write(&index_file, (uchar*) "\n", 1) ||
flush_io_cache(&index_file) ||
my_sync(index_file.file, MYF(MY_WME)))
goto err;
goto err;
#ifdef HAVE_REPLICATION
DBUG_EXECUTE_IF("crash_create_after_update_index", abort(););
#endif
}
}
log_state= LOG_OPENED;
#ifdef HAVE_REPLICATION
close_purge_index_file();
#endif
DBUG_RETURN(0);
err:
#ifdef HAVE_REPLICATION
if (is_inited_purge_index_file())
purge_index_entry(NULL, NULL, need_mutex);
close_purge_index_file();
#endif
sql_print_error("Could not use %s for logging (error %d). \
Turning logging off for the whole duration of the MySQL server process. \
To turn it on again: fix the cause, \
@ -2916,8 +2997,15 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
name=0; // Protect against free
close(LOG_CLOSE_TO_BE_OPENED);
/* First delete all old log files */
/*
First delete all old log files and then update the index file.
As we first delete the log files and do not use sort of logging,
a crash may lead to an inconsistent state where the index has
references to non-existent files.
We need to invert the steps and use the purge_index_file methods
in order to make the operation safe.
*/
if (find_log_pos(&linfo, NullS, 0))
{
error=1;
@ -2984,8 +3072,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
}
if (!thd->slave_thread)
need_start_event=1;
if (!open_index_file(index_file_name, 0))
open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0);
if (!open_index_file(index_file_name, 0, FALSE))
open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE);
my_free((uchar*) save_name, MYF(0));
err:
@ -3172,7 +3260,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
bool need_update_threads,
ulonglong *decrease_log_space)
{
int error;
int error= 0;
bool exit_loop= 0;
LOG_INFO log_info;
THD *thd= current_thd;
@ -3183,33 +3271,15 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
pthread_mutex_lock(&LOCK_index);
if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
{
sql_print_error("MYSQL_LOG::purge_logs was called with file %s not "
sql_print_error("MYSQL_BIN_LOG::purge_logs was called with file %s not "
"listed in the index.", to_log);
goto err;
}
/*
For crash recovery reasons the index needs to be updated before
any files are deleted. Move files to be deleted into a temp file
to be processed after the index is updated.
*/
if (!my_b_inited(&purge_temp))
if ((error= open_purge_index_file(TRUE)))
{
if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME))))
{
sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp");
goto err;
}
}
else
{
if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)))
{
sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp "
"for write");
goto err;
}
sql_print_error("MYSQL_BIN_LOG::purge_logs failed to sync the index file.");
goto err;
}
/*
@ -3219,51 +3289,177 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
!is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
if ((error=my_b_write(&purge_temp, (const uchar*)log_info.log_file_name,
strlen(log_info.log_file_name))) ||
(error=my_b_write(&purge_temp, (const uchar*)"\n", 1)))
if ((error= register_purge_index_entry(log_info.log_file_name)))
{
sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to purge_temp",
sql_print_error("MYSQL_BIN_LOG::purge_logs failed to copy %s to register file.",
log_info.log_file_name);
goto err;
}
if (find_next_log(&log_info, 0) || exit_loop)
break;
}
}
DBUG_EXECUTE_IF("crash_purge_before_update_index", abort(););
if ((error= sync_purge_index_file()))
{
sql_print_error("MSYQL_BIN_LOG::purge_logs failed to flush register file.");
goto err;
}
/* We know how many files to delete. Update index file. */
if ((error=update_log_index(&log_info, need_update_threads)))
{
sql_print_error("MSYQL_LOG::purge_logs failed to update the index file");
sql_print_error("MSYQL_BIN_LOG::purge_logs failed to update the index file");
goto err;
}
DBUG_EXECUTE_IF("crash_after_update_index", abort(););
DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort(););
/* Switch purge_temp for read. */
if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)))
err:
/* Read each entry from purge_index_file and delete the file. */
if (is_inited_purge_index_file() &&
(error= purge_index_entry(thd, decrease_log_space, FALSE)))
sql_print_error("MSYQL_BIN_LOG::purge_logs failed to process registered files"
" that would be purged.");
close_purge_index_file();
DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort(););
if (need_mutex)
pthread_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
int MYSQL_BIN_LOG::set_purge_index_file_name(const char *base_file_name)
{
int error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::set_purge_index_file_name");
if (fn_format(purge_index_file_name, base_file_name, mysql_data_home,
".~rec~", MYF(MY_UNPACK_FILENAME | MY_SAFE_PATH |
MY_REPLACE_EXT)) == NULL)
{
sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp "
error= 1;
sql_print_error("MYSQL_BIN_LOG::set_purge_index_file_name failed to set "
"file name.");
}
DBUG_RETURN(error);
}
int MYSQL_BIN_LOG::open_purge_index_file(bool destroy)
{
int error= 0;
File file= -1;
DBUG_ENTER("MYSQL_BIN_LOG::open_purge_index_file");
if (destroy)
close_purge_index_file();
if (!my_b_inited(&purge_index_file))
{
if ((file= my_open(purge_index_file_name, O_RDWR | O_CREAT | O_BINARY,
MYF(MY_WME | ME_WAITTANG))) < 0 ||
init_io_cache(&purge_index_file, file, IO_SIZE,
(destroy ? WRITE_CACHE : READ_CACHE),
0, 0, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
{
error= 1;
sql_print_error("MYSQL_BIN_LOG::open_purge_index_file failed to open register "
" file.");
}
}
DBUG_RETURN(error);
}
int MYSQL_BIN_LOG::close_purge_index_file()
{
int error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::close_purge_index_file");
if (my_b_inited(&purge_index_file))
{
end_io_cache(&purge_index_file);
error= my_close(purge_index_file.file, MYF(0));
}
my_delete(purge_index_file_name, MYF(0));
bzero((char*) &purge_index_file, sizeof(purge_index_file));
DBUG_RETURN(error);
}
bool MYSQL_BIN_LOG::is_inited_purge_index_file()
{
DBUG_ENTER("MYSQL_BIN_LOG::is_inited_purge_index_file");
DBUG_RETURN (my_b_inited(&purge_index_file));
}
int MYSQL_BIN_LOG::sync_purge_index_file()
{
int error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file");
if ((error= flush_io_cache(&purge_index_file)) ||
(error= my_sync(purge_index_file.file, MYF(MY_WME))))
DBUG_RETURN(error);
DBUG_RETURN(error);
}
int MYSQL_BIN_LOG::register_purge_index_entry(const char *entry)
{
int error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::register_purge_index_entry");
if ((error=my_b_write(&purge_index_file, (const uchar*)entry, strlen(entry))) ||
(error=my_b_write(&purge_index_file, (const uchar*)"\n", 1)))
DBUG_RETURN (error);
DBUG_RETURN(error);
}
int MYSQL_BIN_LOG::register_create_index_entry(const char *entry)
{
DBUG_ENTER("MYSQL_BIN_LOG::register_create_index_entry");
DBUG_RETURN(register_purge_index_entry(entry));
}
int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
bool need_mutex)
{
MY_STAT s;
int error= 0;
LOG_INFO log_info;
LOG_INFO check_log_info;
DBUG_ENTER("MYSQL_BIN_LOG:purge_index_entry");
DBUG_ASSERT(my_b_inited(&purge_index_file));
if ((error=reinit_io_cache(&purge_index_file, READ_CACHE, 0, 0, 0)))
{
sql_print_error("MSYQL_BIN_LOG::purge_index_entry failed to reinit register file "
"for read");
goto err;
}
/* Read each entry from purge_temp and delete the file. */
for (;;)
{
uint length;
if ((length=my_b_gets(&purge_temp, log_info.log_file_name,
if ((length=my_b_gets(&purge_index_file, log_info.log_file_name,
FN_REFLEN)) <= 1)
{
if (purge_temp.error)
if (purge_index_file.error)
{
error= purge_temp.error;
sql_print_error("MSYQL_LOG::purge_logs error %d reading from "
"purge_temp", error);
error= purge_index_file.error;
sql_print_error("MSYQL_BIN_LOG::purge_index_entry error %d reading from "
"register file.", error);
goto err;
}
@ -3274,9 +3470,6 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
/* Get rid of the trailing '\n' */
log_info.log_file_name[length-1]= 0;
ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
MY_STAT s;
if (!my_stat(log_info.log_file_name, &s, MYF(0)))
{
if (my_errno == ENOENT)
@ -3324,64 +3517,92 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
}
else
{
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
if (!my_delete(log_info.log_file_name, MYF(0)))
if ((error= find_log_pos(&check_log_info, log_info.log_file_name, need_mutex)))
{
if (decrease_log_space)
*decrease_log_space-= s.st_size;
}
else
{
if (my_errno == ENOENT)
{
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to delete file '%s'",
log_info.log_file_name);
my_errno= 0;
}
else
if (error != LOG_INFO_EOF)
{
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
"a problem with deleting %s and "
"reading the binlog index file",
log_info.log_file_name);
}
else
{
sql_print_information("Failed to delete file '%s'; "
sql_print_information("Failed to delete file '%s' and "
"read the binlog index file",
log_info.log_file_name);
}
goto err;
}
error= 0;
if (!need_mutex)
{
/*
This is to avoid triggering an error in NDB.
*/
ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
}
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
if (!my_delete(log_info.log_file_name, MYF(0)))
{
if (decrease_log_space)
*decrease_log_space-= s.st_size;
}
else
{
if (my_errno == ENOENT)
{
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to delete file '%s'",
log_info.log_file_name);
my_errno= 0;
}
else
{
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
if (my_errno == EMFILE)
{
DBUG_PRINT("info",
("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
error= LOG_INFO_EMFILE;
}
else
{
sql_print_information("Failed to delete file '%s'; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
}
if (my_errno == EMFILE)
{
DBUG_PRINT("info",
("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
error= LOG_INFO_EMFILE;
goto err;
}
error= LOG_INFO_FATAL;
goto err;
}
error= LOG_INFO_FATAL;
goto err;
}
}
}
}
err:
close_cached_file(&purge_temp);
if (need_mutex)
pthread_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
@ -3421,7 +3642,8 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
goto err;
while (strcmp(log_file_name, log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
!is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
if (!my_stat(log_info.log_file_name, &stat_area, MYF(0)))
{
@ -3430,14 +3652,6 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
/*
It's not fatal if we can't stat a log file that does not exist.
*/
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
log_info.log_file_name);
}
sql_print_information("Failed to execute my_stat on file '%s'",
log_info.log_file_name);
my_errno= 0;
}
else
@ -3632,9 +3846,9 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
*/
/* reopen index binlog file, BUG#34582 */
if (!open_index_file(index_file_name, 0))
open(old_name, log_type, new_name_ptr,
io_cache_type, no_auto_events, max_size, 1);
if (!open_index_file(index_file_name, 0, FALSE))
open(old_name, log_type, new_name_ptr,
io_cache_type, no_auto_events, max_size, 1, FALSE);
my_free(old_name,MYF(0));
end:
@ -5591,7 +5805,7 @@ int TC_LOG_BINLOG::open(const char *opt_name)
if (using_heuristic_recover())
{
/* generate a new binlog to mask a corrupted one */
open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0);
open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0, TRUE);
cleanup();
return 1;
}

View File

@ -172,6 +172,10 @@ public:
enum_log_type log_type,
const char *new_name,
enum cache_type io_cache_type_arg);
bool init_and_set_log_file_name(const char *log_name,
const char *new_name,
enum_log_type log_type_arg,
enum cache_type io_cache_type_arg);
void init(enum_log_type log_type_arg,
enum cache_type io_cache_type_arg);
void close(uint exiting);
@ -233,14 +237,15 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
pthread_cond_t update_cond;
ulonglong bytes_written;
IO_CACHE index_file;
char index_file_name[FN_REFLEN];
/*
purge_temp is a temp file used in purge_logs so that the index file
purge_file is a temp file used in purge_logs so that the index file
can be updated before deleting files from disk, yielding better crash
recovery. It is created on demand the first time purge_logs is called
and then reused for subsequent calls. It is cleaned up in cleanup().
*/
IO_CACHE purge_temp;
char index_file_name[FN_REFLEN];
IO_CACHE purge_index_file;
char purge_index_file_name[FN_REFLEN];
/*
The max size before rotation (usable only if log_type == LOG_BIN: binary
logs and relay logs).
@ -362,9 +367,10 @@ public:
const char *new_name,
enum cache_type io_cache_type_arg,
bool no_auto_events_arg, ulong max_size,
bool null_created);
bool null_created,
bool need_mutex);
bool open_index_file(const char *index_file_name_arg,
const char *log_name);
const char *log_name, bool need_mutex);
/* Use this to start writing a new log file */
void new_file();
@ -410,6 +416,16 @@ public:
ulonglong *decrease_log_space);
int purge_logs_before_date(time_t purge_time);
int purge_first_log(Relay_log_info* rli, bool included);
int set_purge_index_file_name(const char *base_file_name);
int open_purge_index_file(bool destroy);
bool is_inited_purge_index_file();
int close_purge_index_file();
int clean_purge_index_file();
int sync_purge_index_file();
int register_purge_index_entry(const char* entry);
int register_create_index_entry(const char* entry);
int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
bool need_mutex);
bool reset_logs(THD* thd);
void close(uint exiting);

View File

@ -2139,8 +2139,8 @@ void Query_log_event::pack_info(Protocol *protocol)
/**
Utility function for the next method (Query_log_event::write()) .
*/
static void write_str_with_code_and_len(char **dst, const char *src,
int len, uint code)
static void write_str_with_code_and_len(uchar **dst, const char *src,
uint len, uint code)
{
/*
only 1 byte to store the length of catalog, so it should not
@ -2235,7 +2235,7 @@ bool Query_log_event::write(IO_CACHE* file)
}
if (catalog_len) // i.e. this var is inited (false for 4.0 events)
{
write_str_with_code_and_len((char **)(&start),
write_str_with_code_and_len(&start,
catalog, catalog_len, Q_CATALOG_NZ_CODE);
/*
In 5.0.x where x<4 masters we used to store the end zero here. This was
@ -2273,7 +2273,7 @@ bool Query_log_event::write(IO_CACHE* file)
{
/* In the TZ sys table, column Name is of length 64 so this should be ok */
DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
write_str_with_code_and_len((char **)(&start),
write_str_with_code_and_len(&start,
time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
}
if (lc_time_names_number)
@ -4543,6 +4543,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
as the present method does not call mysql_parse().
*/
lex_start(thd);
thd->lex->local_file= local_fname;
mysql_reset_thd_for_next_command(thd);
if (!use_rli_only_for_errors)

View File

@ -3970,7 +3970,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
opt_bin_logname=my_strdup(buf, MYF(0));
}
if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln))
if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
{
unireg_abort(1);
}
@ -4134,7 +4134,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
}
if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
WRITE_CACHE, 0, max_binlog_size, 0))
WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
unireg_abort(1);
#ifdef HAVE_REPLICATION
@ -5983,7 +5983,8 @@ Disable with --skip-super-large-pages.",
#endif
{"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
{"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \
each time the SQL thread starts.",
(uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"language", 'L',

View File

@ -183,10 +183,10 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
*/
if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE) ||
rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
(max_relay_log_size ? max_relay_log_size :
max_binlog_size), 1))
max_binlog_size), 1, TRUE))
{
pthread_mutex_unlock(&rli->data_lock);
sql_print_error("Failed in open_log() called from init_relay_log_info()");

View File

@ -908,6 +908,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
sp->m_name.str));
String retstr(64);
retstr.set_charset(system_charset_info);
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
type == TYPE_ENUM_FUNCTION);
@ -1411,6 +1412,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
64 -- size of "returns" column of mysql.proc.
*/
String retstr(64);
retstr.set_charset(sp->get_creation_ctx()->get_client_cs());
DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));
if (sp->m_first_free_instance)

View File

@ -3381,7 +3381,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if (write_to_binlog)
{
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);

View File

@ -5693,7 +5693,8 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
{
// in PS use own arena or data will be freed after prepare
if (register_tree_change && thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
if (register_tree_change &&
thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute())
arena= thd->activate_stmt_arena_if_needed(&backup);
/*
create_item() may, or may not create a new Item, depending on

View File

@ -581,6 +581,8 @@ public:
{ return state == INITIALIZED_FOR_SP; }
inline bool is_stmt_prepare_or_first_sp_execute() const
{ return (int)state < (int)PREPARED; }
inline bool is_stmt_prepare_or_first_stmt_execute() const
{ return (int)state <= (int)PREPARED; }
inline bool is_first_stmt_execute() const { return state == PREPARED; }
inline bool is_stmt_execute() const
{ return state == PREPARED || state == EXECUTED; }

View File

@ -28,14 +28,7 @@
#include "mysql_priv.h"
SQL_CRYPT::SQL_CRYPT(const char *password, uint length)
{
ulong rand_nr[2];
hash_password(rand_nr,password, length);
crypt_init(rand_nr);
}
void SQL_CRYPT::crypt_init(ulong *rand_nr)
void SQL_CRYPT::init(ulong *rand_nr)
{
uint i;
randominit(&rand,rand_nr[0],rand_nr[1]);

View File

@ -26,15 +26,15 @@ class SQL_CRYPT :public Sql_alloc
struct rand_struct rand,org_rand;
char decode_buff[256],encode_buff[256];
uint shift;
void crypt_init(ulong *seed);
public:
SQL_CRYPT(const char *seed, uint length);
SQL_CRYPT() {}
SQL_CRYPT(ulong *seed)
{
crypt_init(seed);
init(seed);
}
~SQL_CRYPT() {}
void init() { shift=0; rand=org_rand; }
void init(ulong *seed);
void reinit() { shift=0; rand=org_rand; }
void encode(char *str, uint length);
void decode(char *str, uint length);
};

View File

@ -696,6 +696,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
file. In this case it's best to just continue as if nothing has
happened. (This is a very unlikely senario)
*/
thd->clear_error();
}
not_silent:
@ -811,9 +812,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
thd->clear_error();
Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0,
/* suppress_use */ TRUE, errcode);
/* suppress_use */ TRUE, 0);
/*
Write should use the database being created as the "current
@ -823,7 +824,6 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
qinfo.db = db;
qinfo.db_len = strlen(db);
thd->clear_error();
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
@ -963,9 +963,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
thd->clear_error();
Query_log_event qinfo(thd, query, query_length, 0,
/* suppress_use */ TRUE, errcode);
/* suppress_use */ TRUE, 0);
/*
Write should use the database being created as the "current
database" and not the threads current database, which is the
@ -974,7 +974,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
qinfo.db = db;
qinfo.db_len = strlen(db);
thd->clear_error();
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}

View File

@ -5967,6 +5967,7 @@ inline void add_cond_and_fix(Item **e1, Item *e2)
{
*e1= res;
res->quick_fix_field();
res->update_used_tables();
}
}
else
@ -7633,7 +7634,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
already contains a constant and its value is not equal to
the value of const_item.
*/
item_equal->add(const_item);
item_equal->add(const_item, field_item);
}
else
{
@ -13600,7 +13601,7 @@ check_reverse_order:
select->quick=tmp;
}
}
else if (tab->type != JT_NEXT &&
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
{
/*

View File

@ -641,7 +641,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
thd->push_internal_handler(&view_error_suppressor);
bool error= open_normal_and_derived_tables(thd, table_list, 0);
thd->pop_internal_handler();
if (error && thd->is_error())
if (error && (thd->killed || thd->is_error()))
DBUG_RETURN(TRUE);
}

View File

@ -329,7 +329,7 @@ char* ha_ibmdb2i::get_foreign_key_create_info(void)
/* Process the constraint name. */
info.strncat(STRING_WITH_LEN(" CONSTRAINT "));
info.strncat(STRING_WITH_LEN(",\n CONSTRAINT "));
convNameForCreateInfo(thd, info,
FKCstDef->CstName.Name, FKCstDef->CstName.Len);
@ -398,7 +398,6 @@ char* ha_ibmdb2i::get_foreign_key_create_info(void)
if ((i+1) < cstCnt)
{
info.strcat(',');
tempPtr = (char*)cstHdr + cstHdr->CstLen;
cstHdr = (constraint_hdr_t*)(tempPtr);
}
@ -671,28 +670,3 @@ uint ha_ibmdb2i::referenced_by_foreign_key(void)
}
DBUG_RETURN(count);
}
bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes)
{
DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data");
uint i;
/* Check that auto_increment value and field definitions were
not changed. */
if ((info->used_fields & HA_CREATE_USED_AUTO &&
info->auto_increment_value != 0) ||
table_changes != IS_EQUAL_YES)
DBUG_RETURN(COMPATIBLE_DATA_NO);
/* Check if any fields were renamed. */
for (i= 0; i < table->s->fields; i++)
{
Field *field= table->field[i];
if (field->flags & FIELD_IS_RENAMED)
{
DBUG_PRINT("info", ("Field has been renamed, copy table"));
DBUG_RETURN(COMPATIBLE_DATA_NO);
}
}
DBUG_RETURN(COMPATIBLE_DATA_YES);
}

View File

@ -284,7 +284,7 @@ static int ibmdb2i_init_func(void *p)
was_ILE_inited = false;
ibmdb2i_hton= (handlerton *)p;
VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST));
(void) hash_init(&ibmdb2i_open_tables,system_charset_info,32,0,0,
(void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0,
(hash_get_key) ibmdb2i_get_key,0,0);
ibmdb2i_hton->state= SHOW_OPTION_YES;

View File

@ -110,9 +110,6 @@ extern "C" {
# ifndef MYSQL_PLUGIN_IMPORT
# define MYSQL_PLUGIN_IMPORT /* nothing */
# endif /* MYSQL_PLUGIN_IMPORT */
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
#if MYSQL_VERSION_ID < 50124
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER