Merge of Bug#35996.
This commit is contained in:
commit
e6b1bade90
4
mysql-test/include/have_not_innodb_plugin.inc
Normal file
4
mysql-test/include/have_not_innodb_plugin.inc
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
disable_query_log;
|
||||||
|
--require r/not_true.require
|
||||||
|
select (PLUGIN_LIBRARY LIKE 'ha_innodb_plugin%') as `TRUE` from information_schema.plugins where PLUGIN_NAME='InnoDB';
|
||||||
|
enable_query_log;
|
@ -1268,4 +1268,66 @@ a b
|
|||||||
4 b
|
4 b
|
||||||
5 a
|
5 a
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#45567: Fast ALTER TABLE broken for enum and set
|
||||||
|
#
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (a ENUM('a1','a2'));
|
||||||
|
INSERT INTO t1 VALUES ('a1'),('a2');
|
||||||
|
# No copy: No modification
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2');
|
||||||
|
affected rows: 0
|
||||||
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
# No copy: Add new enumeration to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a3');
|
||||||
|
affected rows: 0
|
||||||
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Modify and add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx','a5');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Remove from the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Add new enumeration
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
# No copy: Add new enumerations to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx','a5','a6');
|
||||||
|
affected rows: 0
|
||||||
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a SET('a1','a2'));
|
||||||
|
INSERT INTO t1 VALUES ('a1'),('a2');
|
||||||
|
# No copy: No modification
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2');
|
||||||
|
affected rows: 0
|
||||||
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
# No copy: Add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a3');
|
||||||
|
affected rows: 0
|
||||||
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Modify and add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx','a5');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Remove from the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Add new member
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
# No copy: Add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6');
|
||||||
|
affected rows: 0
|
||||||
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
|
# Copy: Numerical incrase (pack lenght)
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9','a10');
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -279,3 +279,48 @@ ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
#
|
||||||
|
# Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
||||||
|
# merge table
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( a INT );
|
||||||
|
CREATE TABLE t2 ( a INT );
|
||||||
|
CREATE TABLE t3 ( a INT );
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
INSERT INTO t2 VALUES (1), (2);
|
||||||
|
INSERT INTO t3 VALUES (1), (2);
|
||||||
|
CREATE TRIGGER tr1 BEFORE DELETE ON t2
|
||||||
|
FOR EACH ROW INSERT INTO no_such_table VALUES (1);
|
||||||
|
DELETE t1, t2, t3 FROM t1, t2, t3;
|
||||||
|
ERROR 42S02: Table 'test.no_such_table' doesn't exist
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
SELECT * FROM t2;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
SELECT * FROM t3;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
CREATE TABLE t1 ( a INT );
|
||||||
|
CREATE TABLE t2 ( a INT );
|
||||||
|
CREATE TABLE t3 ( a INT );
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
INSERT INTO t2 VALUES (1), (2);
|
||||||
|
INSERT INTO t3 VALUES (1), (2);
|
||||||
|
CREATE TRIGGER tr1 AFTER DELETE ON t2
|
||||||
|
FOR EACH ROW INSERT INTO no_such_table VALUES (1);
|
||||||
|
DELETE t1, t2, t3 FROM t1, t2, t3;
|
||||||
|
ERROR 42S02: Table 'test.no_such_table' doesn't exist
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
SELECT * FROM t2;
|
||||||
|
a
|
||||||
|
2
|
||||||
|
SELECT * FROM t3;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
@ -1064,3 +1064,13 @@ a b c d
|
|||||||
128 NULL 128 NULL
|
128 NULL 128 NULL
|
||||||
DROP TABLE IF EXISTS t1,t2;
|
DROP TABLE IF EXISTS t1,t2;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
CREATE TABLE t1 (f1 int);
|
||||||
|
CREATE TABLE t2 (f1 int);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t2;
|
||||||
|
PREPARE stmt FROM 'UPDATE t2 AS A NATURAL JOIN v1 B SET B.f1 = 1';
|
||||||
|
EXECUTE stmt;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
2
mysql-test/r/not_true.require
Normal file
2
mysql-test/r/not_true.require
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
TRUE
|
||||||
|
NULL
|
39
mysql-test/r/partition_innodb_builtin.result
Normal file
39
mysql-test/r/partition_innodb_builtin.result
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
SET NAMES utf8;
|
||||||
|
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
|
||||||
|
ENGINE=InnoDB
|
||||||
|
PARTITION BY RANGE (a)
|
||||||
|
SUBPARTITION BY HASH (a)
|
||||||
|
(PARTITION `p0``\""e` VALUES LESS THAN (100)
|
||||||
|
(SUBPARTITION `sp0``\""e`,
|
||||||
|
SUBPARTITION `sp1``\""e`),
|
||||||
|
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
|
||||||
|
(SUBPARTITION `sp2``\""e`,
|
||||||
|
SUBPARTITION `sp3``\""e`));
|
||||||
|
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
|
||||||
|
START TRANSACTION;
|
||||||
|
# con1
|
||||||
|
SET NAMES utf8;
|
||||||
|
START TRANSACTION;
|
||||||
|
# default connection
|
||||||
|
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
|
||||||
|
# con1
|
||||||
|
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
|
||||||
|
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
|
||||||
|
# default connection
|
||||||
|
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
# First table reported in 'SHOW ENGINE InnoDB STATUS'
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
Type Name Status
|
||||||
|
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
|
||||||
|
set @old_sql_mode = @@sql_mode;
|
||||||
|
set sql_mode = 'ANSI_QUOTES';
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
Type Name Status
|
||||||
|
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
|
||||||
|
set @@sql_mode = @old_sql_mode;
|
||||||
|
# con1
|
||||||
|
ROLLBACK;
|
||||||
|
# default connection
|
||||||
|
DROP TABLE `t``\""e`;
|
||||||
|
SET NAMES DEFAULT;
|
50
mysql-test/r/partition_innodb_plugin.result
Normal file
50
mysql-test/r/partition_innodb_plugin.result
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
SET NAMES utf8;
|
||||||
|
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
|
||||||
|
ENGINE=InnoDB
|
||||||
|
PARTITION BY RANGE (a)
|
||||||
|
SUBPARTITION BY HASH (a)
|
||||||
|
(PARTITION `p0``\""e` VALUES LESS THAN (100)
|
||||||
|
(SUBPARTITION `sp0``\""e`,
|
||||||
|
SUBPARTITION `sp1``\""e`),
|
||||||
|
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
|
||||||
|
(SUBPARTITION `sp2``\""e`,
|
||||||
|
SUBPARTITION `sp3``\""e`));
|
||||||
|
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
|
||||||
|
START TRANSACTION;
|
||||||
|
# con1
|
||||||
|
SET NAMES utf8;
|
||||||
|
START TRANSACTION;
|
||||||
|
# default connection
|
||||||
|
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
|
||||||
|
# con1
|
||||||
|
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
|
||||||
|
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
|
||||||
|
# default connection
|
||||||
|
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
|
||||||
|
GROUP BY lock_table;
|
||||||
|
lock_table COUNT(*)
|
||||||
|
`test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */ 2
|
||||||
|
set @old_sql_mode = @@sql_mode;
|
||||||
|
set sql_mode = 'ANSI_QUOTES';
|
||||||
|
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
|
||||||
|
GROUP BY lock_table;
|
||||||
|
lock_table COUNT(*)
|
||||||
|
"test"."t`\""""e" /* Partition "p0`\""""e", Subpartition "sp0`\""""e" */ 2
|
||||||
|
set @@sql_mode = @old_sql_mode;
|
||||||
|
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
# First table reported in 'SHOW ENGINE InnoDB STATUS'
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
Type Name Status
|
||||||
|
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
|
||||||
|
set @old_sql_mode = @@sql_mode;
|
||||||
|
set sql_mode = 'ANSI_QUOTES';
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
Type Name Status
|
||||||
|
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
|
||||||
|
set @@sql_mode = @old_sql_mode;
|
||||||
|
# con1
|
||||||
|
ROLLBACK;
|
||||||
|
# default connection
|
||||||
|
DROP TABLE `t``\""e`;
|
||||||
|
SET NAMES DEFAULT;
|
@ -27,4 +27,35 @@ SELECT 1;
|
|||||||
1
|
1
|
||||||
1
|
1
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
#
|
||||||
|
# Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
|
||||||
|
# query
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a INT,
|
||||||
|
b INT,
|
||||||
|
PRIMARY KEY (a),
|
||||||
|
KEY b (b)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1, 1), (2, 1);
|
||||||
|
CREATE TABLE t2 LIKE t1;
|
||||||
|
INSERT INTO t2 SELECT * FROM t1;
|
||||||
|
CREATE TABLE t3 LIKE t1;
|
||||||
|
INSERT INTO t3 SELECT * FROM t1;
|
||||||
|
# Should not crash.
|
||||||
|
# Should have 1 impossible where and 2 dependent subqs.
|
||||||
|
EXPLAIN
|
||||||
|
SELECT
|
||||||
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||||
|
FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||||
|
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using index
|
||||||
|
2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer
|
||||||
|
# should return 0 rows
|
||||||
|
SELECT
|
||||||
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||||
|
FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||||
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -1000,4 +1000,50 @@ ALTER TABLE t1 MODIFY b ENUM('a', 'z', 'b', 'c') NOT NULL;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#45567: Fast ALTER TABLE broken for enum and set
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a ENUM('a1','a2'));
|
||||||
|
INSERT INTO t1 VALUES ('a1'),('a2');
|
||||||
|
--enable_info
|
||||||
|
--echo # No copy: No modification
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2');
|
||||||
|
--echo # No copy: Add new enumeration to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a3');
|
||||||
|
--echo # Copy: Modify and add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx','a5');
|
||||||
|
--echo # Copy: Remove from the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx');
|
||||||
|
--echo # Copy: Add new enumeration
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx');
|
||||||
|
--echo # No copy: Add new enumerations to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx','a5','a6');
|
||||||
|
--disable_info
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a SET('a1','a2'));
|
||||||
|
INSERT INTO t1 VALUES ('a1'),('a2');
|
||||||
|
--enable_info
|
||||||
|
--echo # No copy: No modification
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2');
|
||||||
|
--echo # No copy: Add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a3');
|
||||||
|
--echo # Copy: Modify and add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx','a5');
|
||||||
|
--echo # Copy: Remove from the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx');
|
||||||
|
--echo # Copy: Add new member
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx');
|
||||||
|
--echo # No copy: Add new to the end
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6');
|
||||||
|
--echo # Copy: Numerical incrase (pack lenght)
|
||||||
|
ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9','a10');
|
||||||
|
--disable_info
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -292,3 +292,47 @@ DROP TABLE t1;
|
|||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
||||||
|
--echo # merge table
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 ( a INT );
|
||||||
|
CREATE TABLE t2 ( a INT );
|
||||||
|
CREATE TABLE t3 ( a INT );
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
INSERT INTO t2 VALUES (1), (2);
|
||||||
|
INSERT INTO t3 VALUES (1), (2);
|
||||||
|
|
||||||
|
CREATE TRIGGER tr1 BEFORE DELETE ON t2
|
||||||
|
FOR EACH ROW INSERT INTO no_such_table VALUES (1);
|
||||||
|
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE t1, t2, t3 FROM t1, t2, t3;
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
|
||||||
|
CREATE TABLE t1 ( a INT );
|
||||||
|
CREATE TABLE t2 ( a INT );
|
||||||
|
CREATE TABLE t3 ( a INT );
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
INSERT INTO t2 VALUES (1), (2);
|
||||||
|
INSERT INTO t3 VALUES (1), (2);
|
||||||
|
|
||||||
|
CREATE TRIGGER tr1 AFTER DELETE ON t2
|
||||||
|
FOR EACH ROW INSERT INTO no_such_table VALUES (1);
|
||||||
|
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE t1, t2, t3 FROM t1, t2, t3;
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
@ -12,3 +12,5 @@
|
|||||||
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
|
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
|
||||||
innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently"
|
innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently"
|
||||||
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
|
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
|
||||||
|
partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
|
||||||
|
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
|
||||||
|
@ -729,4 +729,24 @@ SELECT * FROM t1 JOIN t2 ON b=c ORDER BY a;
|
|||||||
SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
|
SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t1,t2;
|
DROP TABLE IF EXISTS t1,t2;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#47150 Assertion in Field_long::val_int() on MERGE + TRIGGER + multi-table UPDATE
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f1 int);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (f1 int);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t2;
|
||||||
|
|
||||||
|
PREPARE stmt FROM 'UPDATE t2 AS A NATURAL JOIN v1 B SET B.f1 = 1';
|
||||||
|
EXECUTE stmt;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
67
mysql-test/t/partition_innodb_builtin.test
Normal file
67
mysql-test/t/partition_innodb_builtin.test
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
--source include/have_partition.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_not_innodb_plugin.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#32430 - show engine innodb status causes errors
|
||||||
|
#
|
||||||
|
SET NAMES utf8;
|
||||||
|
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
|
||||||
|
ENGINE=InnoDB
|
||||||
|
PARTITION BY RANGE (a)
|
||||||
|
SUBPARTITION BY HASH (a)
|
||||||
|
(PARTITION `p0``\""e` VALUES LESS THAN (100)
|
||||||
|
(SUBPARTITION `sp0``\""e`,
|
||||||
|
SUBPARTITION `sp1``\""e`),
|
||||||
|
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
|
||||||
|
(SUBPARTITION `sp2``\""e`,
|
||||||
|
SUBPARTITION `sp3``\""e`));
|
||||||
|
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
|
||||||
|
START TRANSACTION;
|
||||||
|
--echo # con1
|
||||||
|
connect(con1,localhost,root,,);
|
||||||
|
SET NAMES utf8;
|
||||||
|
START TRANSACTION;
|
||||||
|
--echo # default connection
|
||||||
|
connection default;
|
||||||
|
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
|
||||||
|
--echo # con1
|
||||||
|
connection con1;
|
||||||
|
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
|
||||||
|
let $id_1= `SELECT CONNECTION_ID()`;
|
||||||
|
SEND;
|
||||||
|
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
|
||||||
|
--echo # default connection
|
||||||
|
connection default;
|
||||||
|
let $wait_timeout= 2;
|
||||||
|
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||||
|
WHERE ID = $id_1 AND STATE = 'Searching rows for update';
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
#--echo # tested wait condition $wait_condition_reps times
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
|
||||||
|
--echo # First table reported in 'SHOW ENGINE InnoDB STATUS'
|
||||||
|
# RECORD LOCKS space id 0 page no 50 n bits 80 index `PRIMARY` in \
|
||||||
|
# Database `test`, Table `t1`, Partition `p0`, Subpartition `sp0` \
|
||||||
|
# trx id 0 775
|
||||||
|
# NOTE: replace_regex is very slow on match copy/past '(.*)' regex's
|
||||||
|
# on big texts, removing a lot of text before + after makes it much faster.
|
||||||
|
#/.*in (.*) trx.*/\1/
|
||||||
|
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
set @old_sql_mode = @@sql_mode;
|
||||||
|
set sql_mode = 'ANSI_QUOTES';
|
||||||
|
# INNODB_LOCKS only exists in innodb_plugin
|
||||||
|
#SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
|
||||||
|
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
set @@sql_mode = @old_sql_mode;
|
||||||
|
--echo # con1
|
||||||
|
connection con1;
|
||||||
|
REAP;
|
||||||
|
ROLLBACK;
|
||||||
|
disconnect con1;
|
||||||
|
--echo # default connection
|
||||||
|
connection default;
|
||||||
|
DROP TABLE `t``\""e`;
|
||||||
|
SET NAMES DEFAULT;
|
75
mysql-test/t/partition_innodb_plugin.test
Normal file
75
mysql-test/t/partition_innodb_plugin.test
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
--source include/have_partition.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source suite/innodb/include/have_innodb_plugin.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#32430 - show engine innodb status causes errors
|
||||||
|
#
|
||||||
|
SET NAMES utf8;
|
||||||
|
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
|
||||||
|
ENGINE=InnoDB
|
||||||
|
PARTITION BY RANGE (a)
|
||||||
|
SUBPARTITION BY HASH (a)
|
||||||
|
(PARTITION `p0``\""e` VALUES LESS THAN (100)
|
||||||
|
(SUBPARTITION `sp0``\""e`,
|
||||||
|
SUBPARTITION `sp1``\""e`),
|
||||||
|
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
|
||||||
|
(SUBPARTITION `sp2``\""e`,
|
||||||
|
SUBPARTITION `sp3``\""e`));
|
||||||
|
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
|
||||||
|
START TRANSACTION;
|
||||||
|
--echo # con1
|
||||||
|
connect(con1,localhost,root,,);
|
||||||
|
SET NAMES utf8;
|
||||||
|
START TRANSACTION;
|
||||||
|
--echo # default connection
|
||||||
|
connection default;
|
||||||
|
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
|
||||||
|
--echo # con1
|
||||||
|
connection con1;
|
||||||
|
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
|
||||||
|
let $id_1= `SELECT CONNECTION_ID()`;
|
||||||
|
SEND;
|
||||||
|
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
|
||||||
|
--echo # default connection
|
||||||
|
connection default;
|
||||||
|
let $wait_timeout= 2;
|
||||||
|
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||||
|
WHERE ID = $id_1 AND STATE = 'Searching rows for update';
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
#--echo # tested wait condition $wait_condition_reps times
|
||||||
|
# INNODB_LOCKS only exists in innodb_plugin
|
||||||
|
--sorted_result
|
||||||
|
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
|
||||||
|
GROUP BY lock_table;
|
||||||
|
set @old_sql_mode = @@sql_mode;
|
||||||
|
set sql_mode = 'ANSI_QUOTES';
|
||||||
|
--sorted_result
|
||||||
|
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
|
||||||
|
GROUP BY lock_table;
|
||||||
|
set @@sql_mode = @old_sql_mode;
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
|
||||||
|
--echo # First table reported in 'SHOW ENGINE InnoDB STATUS'
|
||||||
|
# RECORD LOCKS space id 0 page no 50 n bits 80 index `PRIMARY` in \
|
||||||
|
# Database `test`, Table `t1`, Partition `p0`, Subpartition `sp0` \
|
||||||
|
# trx id 0 775
|
||||||
|
# NOTE: replace_regex is very slow on match copy/past '(.*)' regex's
|
||||||
|
# on big texts, removing a lot of text before + after makes it much faster.
|
||||||
|
#/.*in (.*) trx.*/\1/
|
||||||
|
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
set @old_sql_mode = @@sql_mode;
|
||||||
|
set sql_mode = 'ANSI_QUOTES';
|
||||||
|
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
|
||||||
|
SHOW ENGINE InnoDB STATUS;
|
||||||
|
set @@sql_mode = @old_sql_mode;
|
||||||
|
--echo # con1
|
||||||
|
connection con1;
|
||||||
|
REAP;
|
||||||
|
ROLLBACK;
|
||||||
|
disconnect con1;
|
||||||
|
--echo # default connection
|
||||||
|
connection default;
|
||||||
|
DROP TABLE `t``\""e`;
|
||||||
|
SET NAMES DEFAULT;
|
@ -28,5 +28,37 @@ SELECT 1;
|
|||||||
|
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
|
||||||
|
--echo # query
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a INT,
|
||||||
|
b INT,
|
||||||
|
PRIMARY KEY (a),
|
||||||
|
KEY b (b)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1, 1), (2, 1);
|
||||||
|
|
||||||
|
CREATE TABLE t2 LIKE t1;
|
||||||
|
INSERT INTO t2 SELECT * FROM t1;
|
||||||
|
|
||||||
|
CREATE TABLE t3 LIKE t1;
|
||||||
|
INSERT INTO t3 SELECT * FROM t1;
|
||||||
|
|
||||||
|
--echo # Should not crash.
|
||||||
|
--echo # Should have 1 impossible where and 2 dependent subqs.
|
||||||
|
EXPLAIN
|
||||||
|
SELECT
|
||||||
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||||
|
FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||||
|
|
||||||
|
--echo # should return 0 rows
|
||||||
|
SELECT
|
||||||
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||||
|
FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
@ -108,10 +108,11 @@ my_bool my_thread_global_init(void)
|
|||||||
pthread_attr_t dummy_thread_attr;
|
pthread_attr_t dummy_thread_attr;
|
||||||
|
|
||||||
pthread_attr_init(&dummy_thread_attr);
|
pthread_attr_init(&dummy_thread_attr);
|
||||||
pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
|
||||||
pthread_create(&dummy_thread,&dummy_thread_attr,
|
if (pthread_create(&dummy_thread,&dummy_thread_attr,
|
||||||
nptl_pthread_exit_hack_handler, NULL);
|
nptl_pthread_exit_hack_handler, NULL) == 0)
|
||||||
|
(void)pthread_join(dummy_thread, NULL);
|
||||||
}
|
}
|
||||||
#endif /* TARGET_OS_LINUX */
|
#endif /* TARGET_OS_LINUX */
|
||||||
|
|
||||||
|
75
sql/field.cc
75
sql/field.cc
@ -8832,6 +8832,24 @@ bool Field::eq_def(Field *field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Compare the first t1::count type names.
|
||||||
|
|
||||||
|
@return TRUE if the type names of t1 match those of t2. FALSE otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool compare_type_names(CHARSET_INFO *charset, TYPELIB *t1, TYPELIB *t2)
|
||||||
|
{
|
||||||
|
for (uint i= 0; i < t1->count; i++)
|
||||||
|
if (my_strnncoll(charset,
|
||||||
|
(const uchar*) t1->type_names[i],
|
||||||
|
t1->type_lengths[i],
|
||||||
|
(const uchar*) t2->type_names[i],
|
||||||
|
t2->type_lengths[i]))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@return
|
@return
|
||||||
returns 1 if the fields are equally defined
|
returns 1 if the fields are equally defined
|
||||||
@ -8839,32 +8857,57 @@ bool Field::eq_def(Field *field)
|
|||||||
|
|
||||||
bool Field_enum::eq_def(Field *field)
|
bool Field_enum::eq_def(Field *field)
|
||||||
{
|
{
|
||||||
|
TYPELIB *values;
|
||||||
|
|
||||||
if (!Field::eq_def(field))
|
if (!Field::eq_def(field))
|
||||||
return 0;
|
return FALSE;
|
||||||
return compare_enum_values(((Field_enum*) field)->typelib);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
values= ((Field_enum*) field)->typelib;
|
||||||
|
|
||||||
bool Field_enum::compare_enum_values(TYPELIB *values)
|
/* Definition must be strictly equal. */
|
||||||
{
|
|
||||||
if (typelib->count != values->count)
|
if (typelib->count != values->count)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for (uint i= 0; i < typelib->count; i++)
|
|
||||||
if (my_strnncoll(field_charset,
|
return compare_type_names(field_charset, typelib, values);
|
||||||
(const uchar*) typelib->type_names[i],
|
|
||||||
typelib->type_lengths[i],
|
|
||||||
(const uchar*) values->type_names[i],
|
|
||||||
values->type_lengths[i]))
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether two fields can be considered 'equal' for table
|
||||||
|
alteration purposes. Fields are equal if they retain the same
|
||||||
|
pack length and if new members are added to the end of the list.
|
||||||
|
|
||||||
|
@return IS_EQUAL_YES if fields are compatible.
|
||||||
|
IS_EQUAL_NO otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
uint Field_enum::is_equal(Create_field *new_field)
|
uint Field_enum::is_equal(Create_field *new_field)
|
||||||
{
|
{
|
||||||
if (!Field_str::is_equal(new_field))
|
TYPELIB *values= new_field->interval;
|
||||||
return 0;
|
|
||||||
return compare_enum_values(new_field->interval);
|
/*
|
||||||
|
The fields are compatible if they have the same flags,
|
||||||
|
type, charset and have the same underlying length.
|
||||||
|
*/
|
||||||
|
if (compare_str_field_flags(new_field, flags) ||
|
||||||
|
new_field->sql_type != real_type() ||
|
||||||
|
new_field->charset != field_charset ||
|
||||||
|
new_field->pack_length != pack_length())
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changing the definition of an ENUM or SET column by adding a new
|
||||||
|
enumeration or set members to the end of the list of valid member
|
||||||
|
values only alters table metadata and not table data.
|
||||||
|
*/
|
||||||
|
if (typelib->count > values->count)
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
|
||||||
|
/* Check whether there are modification before the end. */
|
||||||
|
if (! compare_type_names(field_charset, typelib, new_field->interval))
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
|
||||||
|
return IS_EQUAL_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,6 +472,13 @@ public:
|
|||||||
/* maximum possible display length */
|
/* maximum possible display length */
|
||||||
virtual uint32 max_display_length()= 0;
|
virtual uint32 max_display_length()= 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Whether a field being created is compatible with a existing one.
|
||||||
|
|
||||||
|
Used by the ALTER TABLE code to evaluate whether the new definition
|
||||||
|
of a table is compatible with the old definition so that it can
|
||||||
|
determine if data needs to be copied over (table data change).
|
||||||
|
*/
|
||||||
virtual uint is_equal(Create_field *new_field);
|
virtual uint is_equal(Create_field *new_field);
|
||||||
/* convert decimal to longlong with overflow check */
|
/* convert decimal to longlong with overflow check */
|
||||||
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
|
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
|
||||||
@ -1862,7 +1869,6 @@ public:
|
|||||||
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
|
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
|
||||||
private:
|
private:
|
||||||
int do_save_field_metadata(uchar *first_byte);
|
int do_save_field_metadata(uchar *first_byte);
|
||||||
bool compare_enum_values(TYPELIB *values);
|
|
||||||
uint is_equal(Create_field *new_field);
|
uint is_equal(Create_field *new_field);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
21
sql/item.cc
21
sql/item.cc
@ -6331,9 +6331,26 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
/* view fild reference must be defined */
|
/* view fild reference must be defined */
|
||||||
DBUG_ASSERT(*ref);
|
DBUG_ASSERT(*ref);
|
||||||
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
|
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
|
||||||
if (!(*ref)->fixed &&
|
if ((*ref)->fixed)
|
||||||
((*ref)->fix_fields(thd, ref)))
|
{
|
||||||
|
Item *ref_item= (*ref)->real_item();
|
||||||
|
if (ref_item->type() == Item::FIELD_ITEM)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
In some cases we need to update table read set(see bug#47150).
|
||||||
|
If ref item is FIELD_ITEM and fixed then field and table
|
||||||
|
have proper values. So we can use them for update.
|
||||||
|
*/
|
||||||
|
Field *fld= ((Item_field*) ref_item)->field;
|
||||||
|
DBUG_ASSERT(fld && fld->table);
|
||||||
|
if (thd->mark_used_columns == MARK_COLUMNS_READ)
|
||||||
|
bitmap_set_bit(fld->table->read_set, fld->field_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(*ref)->fixed &&
|
||||||
|
((*ref)->fix_fields(thd, ref)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return Item_direct_ref::fix_fields(thd, reference);
|
return Item_direct_ref::fix_fields(thd, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,10 +2277,9 @@ enum enum_explain_filename_mode
|
|||||||
{
|
{
|
||||||
EXPLAIN_ALL_VERBOSE= 0,
|
EXPLAIN_ALL_VERBOSE= 0,
|
||||||
EXPLAIN_PARTITIONS_VERBOSE,
|
EXPLAIN_PARTITIONS_VERBOSE,
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT,
|
EXPLAIN_PARTITIONS_AS_COMMENT
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
|
|
||||||
};
|
};
|
||||||
uint explain_filename(const char *from, char *to, uint to_length,
|
uint explain_filename(THD* thd, const char *from, char *to, uint to_length,
|
||||||
enum_explain_filename_mode explain_mode);
|
enum_explain_filename_mode explain_mode);
|
||||||
uint filename_to_tablename(const char *from, char *to, uint to_length);
|
uint filename_to_tablename(const char *from, char *to, uint to_length);
|
||||||
uint tablename_to_filename(const char *from, char *to, uint to_length);
|
uint tablename_to_filename(const char *from, char *to, uint to_length);
|
||||||
|
@ -2907,7 +2907,8 @@ public:
|
|||||||
bool send_data(List<Item> &items);
|
bool send_data(List<Item> &items);
|
||||||
bool initialize_tables (JOIN *join);
|
bool initialize_tables (JOIN *join);
|
||||||
void send_error(uint errcode,const char *err);
|
void send_error(uint errcode,const char *err);
|
||||||
int do_deletes();
|
int do_deletes();
|
||||||
|
int do_table_deletes(TABLE *table, bool ignore);
|
||||||
bool send_eof();
|
bool send_eof();
|
||||||
virtual void abort();
|
virtual void abort();
|
||||||
};
|
};
|
||||||
|
@ -860,22 +860,19 @@ void multi_delete::abort()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Do delete from other tables.
|
Do delete from other tables.
|
||||||
Returns values:
|
|
||||||
0 ok
|
@retval 0 ok
|
||||||
1 error
|
@retval 1 error
|
||||||
|
|
||||||
|
@todo Is there any reason not use the normal nested-loops join? If not, and
|
||||||
|
there is no documentation supporting it, this method and callee should be
|
||||||
|
removed and there should be hooks within normal execution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int multi_delete::do_deletes()
|
int multi_delete::do_deletes()
|
||||||
{
|
{
|
||||||
int local_error= 0, counter= 0, tmp_error;
|
|
||||||
bool will_batch;
|
|
||||||
/*
|
|
||||||
If the IGNORE option is used all non fatal errors will be translated
|
|
||||||
to warnings and we should not break the row-by-row iteration
|
|
||||||
*/
|
|
||||||
bool ignore= thd->lex->current_select->no_error;
|
|
||||||
DBUG_ENTER("do_deletes");
|
DBUG_ENTER("do_deletes");
|
||||||
DBUG_ASSERT(do_delete);
|
DBUG_ASSERT(do_delete);
|
||||||
|
|
||||||
@ -886,79 +883,108 @@ int multi_delete::do_deletes()
|
|||||||
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
|
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
|
||||||
delete_tables);
|
delete_tables);
|
||||||
|
|
||||||
for (; table_being_deleted;
|
for (uint counter= 0; table_being_deleted;
|
||||||
table_being_deleted= table_being_deleted->next_local, counter++)
|
table_being_deleted= table_being_deleted->next_local, counter++)
|
||||||
{
|
{
|
||||||
ha_rows last_deleted= deleted;
|
|
||||||
TABLE *table = table_being_deleted->table;
|
TABLE *table = table_being_deleted->table;
|
||||||
if (tempfiles[counter]->get(table))
|
if (tempfiles[counter]->get(table))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
int local_error=
|
||||||
|
do_table_deletes(table, thd->lex->current_select->no_error);
|
||||||
|
|
||||||
|
if (thd->killed && !local_error)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
if (local_error == -1) // End of file
|
||||||
|
local_error = 0;
|
||||||
|
|
||||||
|
if (local_error)
|
||||||
|
DBUG_RETURN(local_error);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Implements the inner loop of nested-loops join within multi-DELETE
|
||||||
|
execution.
|
||||||
|
|
||||||
|
@param table The table from which to delete.
|
||||||
|
|
||||||
|
@param ignore If used, all non fatal errors will be translated
|
||||||
|
to warnings and we should not break the row-by-row iteration.
|
||||||
|
|
||||||
|
@return Status code
|
||||||
|
|
||||||
|
@retval 0 All ok.
|
||||||
|
@retval 1 Triggers or handler reported error.
|
||||||
|
@retval -1 End of file from handler.
|
||||||
|
*/
|
||||||
|
int multi_delete::do_table_deletes(TABLE *table, bool ignore)
|
||||||
|
{
|
||||||
|
int local_error= 0;
|
||||||
|
READ_RECORD info;
|
||||||
|
ha_rows last_deleted= deleted;
|
||||||
|
DBUG_ENTER("do_deletes_for_table");
|
||||||
|
init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
|
||||||
|
/*
|
||||||
|
Ignore any rows not found in reference tables as they may already have
|
||||||
|
been deleted by foreign key handling
|
||||||
|
*/
|
||||||
|
info.ignore_not_found_rows= 1;
|
||||||
|
bool will_batch= !table->file->start_bulk_delete();
|
||||||
|
while (!(local_error= info.read_record(&info)) && !thd->killed)
|
||||||
|
{
|
||||||
|
if (table->triggers &&
|
||||||
|
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
||||||
|
TRG_ACTION_BEFORE, FALSE))
|
||||||
{
|
{
|
||||||
local_error=1;
|
local_error= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_RECORD info;
|
local_error= table->file->ha_delete_row(table->record[0]);
|
||||||
init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
|
if (local_error && !ignore)
|
||||||
/*
|
|
||||||
Ignore any rows not found in reference tables as they may already have
|
|
||||||
been deleted by foreign key handling
|
|
||||||
*/
|
|
||||||
info.ignore_not_found_rows= 1;
|
|
||||||
will_batch= !table->file->start_bulk_delete();
|
|
||||||
while (!(local_error=info.read_record(&info)) && !thd->killed)
|
|
||||||
{
|
{
|
||||||
|
table->file->print_error(local_error, MYF(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Increase the reported number of deleted rows only if no error occurred
|
||||||
|
during ha_delete_row.
|
||||||
|
Also, don't execute the AFTER trigger if the row operation failed.
|
||||||
|
*/
|
||||||
|
if (!local_error)
|
||||||
|
{
|
||||||
|
deleted++;
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
||||||
TRG_ACTION_BEFORE, FALSE))
|
TRG_ACTION_AFTER, FALSE))
|
||||||
{
|
{
|
||||||
local_error= 1;
|
local_error= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_error= table->file->ha_delete_row(table->record[0]);
|
|
||||||
if (local_error && !ignore)
|
|
||||||
{
|
|
||||||
table->file->print_error(local_error,MYF(0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Increase the reported number of deleted rows only if no error occurred
|
|
||||||
during ha_delete_row.
|
|
||||||
Also, don't execute the AFTER trigger if the row operation failed.
|
|
||||||
*/
|
|
||||||
if (!local_error)
|
|
||||||
{
|
|
||||||
deleted++;
|
|
||||||
if (table->triggers &&
|
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
|
||||||
TRG_ACTION_AFTER, FALSE))
|
|
||||||
{
|
|
||||||
local_error= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
|
|
||||||
{
|
|
||||||
if (!local_error)
|
|
||||||
{
|
|
||||||
local_error= tmp_error;
|
|
||||||
table->file->print_error(local_error,MYF(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (last_deleted != deleted && !table->file->has_transactions())
|
|
||||||
thd->transaction.stmt.modified_non_trans_table= TRUE;
|
|
||||||
end_read_record(&info);
|
|
||||||
if (thd->killed && !local_error)
|
|
||||||
local_error= 1;
|
|
||||||
if (local_error == -1) // End of file
|
|
||||||
local_error = 0;
|
|
||||||
}
|
}
|
||||||
|
if (will_batch)
|
||||||
|
{
|
||||||
|
int tmp_error= table->file->end_bulk_delete();
|
||||||
|
if (tmp_error && !local_error)
|
||||||
|
{
|
||||||
|
local_error= tmp_error;
|
||||||
|
table->file->print_error(local_error, MYF(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last_deleted != deleted && !table->file->has_transactions())
|
||||||
|
thd->transaction.stmt.modified_non_trans_table= TRUE;
|
||||||
|
|
||||||
|
end_read_record(&info);
|
||||||
|
|
||||||
DBUG_RETURN(local_error);
|
DBUG_RETURN(local_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Send ok to the client
|
Send ok to the client
|
||||||
|
|
||||||
|
@ -3308,12 +3308,12 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
|||||||
@retval FALSE it's something else
|
@retval FALSE it's something else
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline static bool
|
static bool
|
||||||
is_local_field (Item *field)
|
is_local_field (Item *field)
|
||||||
{
|
{
|
||||||
field= field->real_item();
|
return field->real_item()->type() == Item::FIELD_ITEM
|
||||||
return field->type() == Item::FIELD_ITEM &&
|
&& !(field->used_tables() & OUTER_REF_TABLE_BIT)
|
||||||
!((Item_field *)field)->depended_from;
|
&& !((Item_field *)field->real_item())->depended_from;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,15 +70,21 @@ static void wait_for_kill_signal(THD *thd)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Helper function for explain_filename
|
@brief Helper function for explain_filename
|
||||||
|
@param thd Thread handle
|
||||||
|
@param to_p Explained name in system_charset_info
|
||||||
|
@param end_p End of the to_p buffer
|
||||||
|
@param name Name to be converted
|
||||||
|
@param name_len Length of the name, in bytes
|
||||||
*/
|
*/
|
||||||
static char* add_identifier(char *to_p, const char * end_p,
|
static char* add_identifier(THD* thd, char *to_p, const char * end_p,
|
||||||
const char* name, uint name_len, bool add_quotes)
|
const char* name, uint name_len)
|
||||||
{
|
{
|
||||||
uint res;
|
uint res;
|
||||||
uint errors;
|
uint errors;
|
||||||
const char *conv_name;
|
const char *conv_name;
|
||||||
char tmp_name[FN_REFLEN];
|
char tmp_name[FN_REFLEN];
|
||||||
char conv_string[FN_REFLEN];
|
char conv_string[FN_REFLEN];
|
||||||
|
int quote;
|
||||||
|
|
||||||
DBUG_ENTER("add_identifier");
|
DBUG_ENTER("add_identifier");
|
||||||
if (!name[name_len])
|
if (!name[name_len])
|
||||||
@ -102,19 +108,21 @@ static char* add_identifier(char *to_p, const char * end_p,
|
|||||||
conv_name= conv_string;
|
conv_name= conv_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_quotes && (end_p - to_p > 2))
|
quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '"';
|
||||||
|
|
||||||
|
if (quote != EOF && (end_p - to_p > 2))
|
||||||
{
|
{
|
||||||
*(to_p++)= '`';
|
*(to_p++)= (char) quote;
|
||||||
while (*conv_name && (end_p - to_p - 1) > 0)
|
while (*conv_name && (end_p - to_p - 1) > 0)
|
||||||
{
|
{
|
||||||
uint length= my_mbcharlen(system_charset_info, *conv_name);
|
uint length= my_mbcharlen(system_charset_info, *conv_name);
|
||||||
if (!length)
|
if (!length)
|
||||||
length= 1;
|
length= 1;
|
||||||
if (length == 1 && *conv_name == '`')
|
if (length == 1 && *conv_name == (char) quote)
|
||||||
{
|
{
|
||||||
if ((end_p - to_p) < 3)
|
if ((end_p - to_p) < 3)
|
||||||
break;
|
break;
|
||||||
*(to_p++)= '`';
|
*(to_p++)= (char) quote;
|
||||||
*(to_p++)= *(conv_name++);
|
*(to_p++)= *(conv_name++);
|
||||||
}
|
}
|
||||||
else if (((long) length) < (end_p - to_p))
|
else if (((long) length) < (end_p - to_p))
|
||||||
@ -125,7 +133,11 @@ static char* add_identifier(char *to_p, const char * end_p,
|
|||||||
else
|
else
|
||||||
break; /* string already filled */
|
break; /* string already filled */
|
||||||
}
|
}
|
||||||
to_p= strnmov(to_p, "`", end_p - to_p);
|
if (end_p > to_p) {
|
||||||
|
*(to_p++)= (char) quote;
|
||||||
|
if (end_p > to_p)
|
||||||
|
*to_p= 0; /* terminate by NUL, but do not include it in the count */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
to_p= strnmov(to_p, conv_name, end_p - to_p);
|
to_p= strnmov(to_p, conv_name, end_p - to_p);
|
||||||
@ -145,6 +157,7 @@ static char* add_identifier(char *to_p, const char * end_p,
|
|||||||
diagnostic, error etc. when it would be useful to know what a particular
|
diagnostic, error etc. when it would be useful to know what a particular
|
||||||
file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc.
|
file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc.
|
||||||
|
|
||||||
|
@param thd Thread handle
|
||||||
@param from Path name in my_charset_filename
|
@param from Path name in my_charset_filename
|
||||||
Null terminated in my_charset_filename, normalized
|
Null terminated in my_charset_filename, normalized
|
||||||
to use '/' as directory separation character.
|
to use '/' as directory separation character.
|
||||||
@ -161,13 +174,12 @@ static char* add_identifier(char *to_p, const char * end_p,
|
|||||||
[,[ Temporary| Renamed] Partition `p`
|
[,[ Temporary| Renamed] Partition `p`
|
||||||
[, Subpartition `sp`]] *|
|
[, Subpartition `sp`]] *|
|
||||||
(| is really a /, and it is all in one line)
|
(| is really a /, and it is all in one line)
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING ->
|
|
||||||
same as above but no quotes are added.
|
|
||||||
|
|
||||||
@retval Length of returned string
|
@retval Length of returned string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint explain_filename(const char *from,
|
uint explain_filename(THD* thd,
|
||||||
|
const char *from,
|
||||||
char *to,
|
char *to,
|
||||||
uint to_length,
|
uint to_length,
|
||||||
enum_explain_filename_mode explain_mode)
|
enum_explain_filename_mode explain_mode)
|
||||||
@ -281,14 +293,12 @@ uint explain_filename(const char *from,
|
|||||||
{
|
{
|
||||||
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
|
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
|
||||||
*(to_p++)= ' ';
|
*(to_p++)= ' ';
|
||||||
to_p= add_identifier(to_p, end_p, db_name, db_name_len, 1);
|
to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
|
||||||
to_p= strnmov(to_p, ", ", end_p - to_p);
|
to_p= strnmov(to_p, ", ", end_p - to_p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
to_p= add_identifier(to_p, end_p, db_name, db_name_len,
|
to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
|
||||||
(explain_mode !=
|
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
|
||||||
to_p= strnmov(to_p, ".", end_p - to_p);
|
to_p= strnmov(to_p, ".", end_p - to_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,16 +306,13 @@ uint explain_filename(const char *from,
|
|||||||
{
|
{
|
||||||
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
|
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
|
||||||
*(to_p++)= ' ';
|
*(to_p++)= ' ';
|
||||||
to_p= add_identifier(to_p, end_p, table_name, table_name_len, 1);
|
to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
to_p= add_identifier(to_p, end_p, table_name, table_name_len,
|
to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
|
||||||
(explain_mode !=
|
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
|
||||||
if (part_name)
|
if (part_name)
|
||||||
{
|
{
|
||||||
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
|
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
|
||||||
explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
|
|
||||||
to_p= strnmov(to_p, " /* ", end_p - to_p);
|
to_p= strnmov(to_p, " /* ", end_p - to_p);
|
||||||
else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
|
else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
|
||||||
to_p= strnmov(to_p, " ", end_p - to_p);
|
to_p= strnmov(to_p, " ", end_p - to_p);
|
||||||
@ -321,20 +328,15 @@ uint explain_filename(const char *from,
|
|||||||
}
|
}
|
||||||
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
|
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
|
||||||
*(to_p++)= ' ';
|
*(to_p++)= ' ';
|
||||||
to_p= add_identifier(to_p, end_p, part_name, part_name_len,
|
to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
|
||||||
(explain_mode !=
|
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
|
||||||
if (subpart_name)
|
if (subpart_name)
|
||||||
{
|
{
|
||||||
to_p= strnmov(to_p, ", ", end_p - to_p);
|
to_p= strnmov(to_p, ", ", end_p - to_p);
|
||||||
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
|
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
|
||||||
*(to_p++)= ' ';
|
*(to_p++)= ' ';
|
||||||
to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len,
|
to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
|
||||||
(explain_mode !=
|
|
||||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
|
||||||
}
|
}
|
||||||
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
|
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
|
||||||
explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
|
|
||||||
to_p= strnmov(to_p, " */", end_p - to_p);
|
to_p= strnmov(to_p, " */", end_p - to_p);
|
||||||
}
|
}
|
||||||
DBUG_PRINT("exit", ("to '%s'", to));
|
DBUG_PRINT("exit", ("to '%s'", to));
|
||||||
|
@ -801,7 +801,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
{
|
{
|
||||||
DBUG_DUMP("old",(uchar*) info->lastkey, info->lastkey_length);
|
DBUG_DUMP("old",(uchar*) info->lastkey, info->lastkey_length);
|
||||||
DBUG_DUMP("new",(uchar*) key, key_length);
|
DBUG_DUMP("new",(uchar*) key, key_length);
|
||||||
DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
|
DBUG_DUMP("new_in_page",(uchar*) old_keypos,(uint) (keypos-old_keypos));
|
||||||
|
|
||||||
if (comp_flag & SEARCH_FIND && flag == 0)
|
if (comp_flag & SEARCH_FIND && flag == 0)
|
||||||
mi_check_print_error(param,"Found duplicated key at page %s",llstr(page,llbuff));
|
mi_check_print_error(param,"Found duplicated key at page %s",llstr(page,llbuff));
|
||||||
@ -871,7 +871,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
llstr(page,llbuff),llstr(record,llbuff2),
|
llstr(page,llbuff),llstr(record,llbuff2),
|
||||||
llstr(info->state->data_file_length,llbuff3)));
|
llstr(info->state->data_file_length,llbuff3)));
|
||||||
DBUG_DUMP("key",(uchar*) key,key_length);
|
DBUG_DUMP("key",(uchar*) key,key_length);
|
||||||
DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
|
DBUG_DUMP("new_in_page",(uchar*) old_keypos,(uint) (keypos-old_keypos));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
param->record_checksum+=(ha_checksum) record;
|
param->record_checksum+=(ha_checksum) record;
|
||||||
@ -1545,6 +1545,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||||||
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
||||||
param->testflag|=T_CALC_CHECKSUM;
|
param->testflag|=T_CALC_CHECKSUM;
|
||||||
|
|
||||||
|
DBUG_ASSERT(param->use_buffers < SIZE_T_MAX);
|
||||||
|
|
||||||
if (!param->using_global_keycache)
|
if (!param->using_global_keycache)
|
||||||
VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
|
VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
|
||||||
(size_t) param->use_buffers, 0, 0));
|
(size_t) param->use_buffers, 0, 0));
|
||||||
|
@ -1,4 +1,28 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT_NAME="`basename $0`"
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
echo "Usage: ${SCRIPT_NAME} [--help|-h]"
|
||||||
|
echo ""
|
||||||
|
echo "This script creates the MySQL system tables and starts the server."
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg do
|
||||||
|
case "$arg" in
|
||||||
|
--help|-h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "${SCRIPT_NAME}: unknown option $arg"
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
if test ! -x ./scripts/mysql_install_db
|
if test ! -x ./scripts/mysql_install_db
|
||||||
then
|
then
|
||||||
echo "I didn't find the script './scripts/mysql_install_db'."
|
echo "I didn't find the script './scripts/mysql_install_db'."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user