1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

merge mysql-5.5->mysql-5.5-security

This commit is contained in:
Georgi Kodinov
2012-04-10 14:23:17 +03:00
51 changed files with 1677 additions and 326 deletions

View File

@@ -1,7 +1,7 @@
You can find information about how to install from a source distributions at
http://dev.mysql.com/doc/refman/5.1/en/installing-source.html
http://dev.mysql.com/doc/refman/5.5/en/source-installation.html
The MySQL Reference Manual is also available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML

View File

@@ -2,7 +2,7 @@
You can find information about how to install from a Windows source
distributions at
http://dev.mysql.com/doc/refman/5.1/en/windows-source-build.html
http://dev.mysql.com/doc/refman/5.5/en/source-installation.html
The MySQL Reference Manual is also available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML

View File

@@ -141,7 +141,8 @@ static my_bool opt_compress= FALSE, tty_password= FALSE,
const char *auto_generate_sql_type= "mixed";
static unsigned long connect_flags= CLIENT_MULTI_RESULTS |
CLIENT_MULTI_STATEMENTS;
CLIENT_MULTI_STATEMENTS |
CLIENT_REMEMBER_OPTIONS;
static int verbose, delimiter_length;
static uint commit_rate;

View File

@@ -120,8 +120,13 @@ CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.cc
${PACKAGE_DIR}/sql/sql_yacc.cc COPYONLY)
# Copy spec files
CONFIGURE_FILE(${CMAKE_BINARY_DIR}/support-files/mysql.${VERSION}.spec
${PACKAGE_DIR}/support-files/mysql.${VERSION}.spec COPYONLY)
SET(SPECFILENAME "mysql.${VERSION}.spec")
IF("${VERSION}" MATCHES "-ndb-")
STRING(REGEX REPLACE "^.*-ndb-" "" NDBVERSION "${VERSION}")
SET(SPECFILENAME "mysql-cluster-${NDBVERSION}.spec")
ENDIF()
CONFIGURE_FILE(${CMAKE_BINARY_DIR}/support-files/${SPECFILENAME}
${PACKAGE_DIR}/support-files/${SPECFILENAME} COPYONLY)
# Add documentation, if user has specified where to find them
IF(MYSQL_DOCS_LOCATION)

View File

@@ -57,7 +57,10 @@ MACRO(GET_MYSQL_VERSION)
MESSAGE("-- MySQL ${VERSION}")
SET(MYSQL_BASE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" CACHE INTERNAL "MySQL Base version")
SET(MYSQL_NO_DASH_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
STRING(REPLACE "-" "_" MYSQL_RPM_VERSION "${VERSION}")
# Use NDBVERSION irregardless of whether this is Cluster or not, if not
# then the regex will be ignored anyway.
STRING(REGEX REPLACE "^.*-ndb-" "" NDBVERSION "${VERSION}")
STRING(REPLACE "-" "_" MYSQL_RPM_VERSION "${NDBVERSION}")
MATH(EXPR MYSQL_VERSION_ID "10000*${MAJOR_VERSION} + 100*${MINOR_VERSION} + ${PATCH_VERSION}")
MARK_AS_ADVANCED(VERSION MYSQL_VERSION_ID MYSQL_BASE_VERSION)
SET(CPACK_PACKAGE_VERSION_MAJOR ${MAJOR_VERSION})
@@ -93,6 +96,10 @@ ENDIF()
IF(NOT CPACK_SOURCE_PACKAGE_FILE_NAME)
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mysql-${VERSION}")
IF("${VERSION}" MATCHES "-ndb-")
STRING(REGEX REPLACE "^.*-ndb-" "" NDBVERSION "${VERSION}")
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mysql-cluster-gpl-${NDBVERSION}")
ENDIF()
ENDIF()
SET(CPACK_PACKAGE_CONTACT "MySQL Release Engineering <mysql-build@oss.oracle.com>")
SET(CPACK_PACKAGE_VENDOR "Oracle Corporation")

View File

@@ -116,8 +116,15 @@ IF(NOT VERSION)
SET(PRODUCT_TAG)
ENDIF()
SET(package_name "mysql${PRODUCT_TAG}-${VERSION}-${SYSTEM_NAME_AND_PROCESSOR}")
IF("${VERSION}" MATCHES "-ndb-")
STRING(REGEX REPLACE "^.*-ndb-" "" NDBVERSION "${VERSION}")
SET(package_name "mysql-cluster${PRODUCT_TAG}-${NDBVERSION}-${SYSTEM_NAME_AND_PROCESSOR}")
ELSE()
SET(package_name "mysql${PRODUCT_TAG}-${VERSION}-${SYSTEM_NAME_AND_PROCESSOR}")
ENDIF()
MESSAGE("-- Packaging as: ${package_name}")
# Sometimes package suffix is added (something like "-icc-glibc23")
IF(PACKAGE_SUFFIX)
SET(package_name "${package_name}${PACKAGE_SUFFIX}")

View File

@@ -343,6 +343,8 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
set_stmt_errmsg(stmt, net);
DBUG_RETURN(1);
}
else if (stmt->mysql->status == MYSQL_STATUS_GET_RESULT)
stmt->mysql->status= MYSQL_STATUS_STATEMENT_GET_RESULT;
DBUG_RETURN(0);
}

View File

@@ -247,3 +247,13 @@ mysql
performance_schema
test
DROP DATABASE bug58090;
#
# Bug #11766072 - 59107: MYSQLSLAP CRASHES IF STARTED WITH NO ARGUMENTS ON WINDOWS
#
Benchmark
Average number of seconds to run all queries: TIME seconds
Minimum number of seconds to run all queries: TIME seconds
Maximum number of seconds to run all queries: TIME seconds
Number of clients running queries: 1
Average number of queries per client: 0

View File

@@ -3746,5 +3746,108 @@ FROM (SELECT 1 UNION SELECT 2) t;
1
1
2
# Bug#13805127: Stored program cache produces wrong result in same THD
PREPARE s1 FROM
"
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2
";
SET @x = 1;
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2;
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
EXECUTE s1;
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
SET @x = 2;
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2;
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
EXECUTE s1;
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
SET @x = 1;
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2;
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
EXECUTE s1;
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
DEALLOCATE PREPARE s1;
#
# End of 5.5 tests.

View File

@@ -111,6 +111,7 @@ DROP FUNCTION db1.f1;
DROP TABLE db1.t1;
DROP DATABASE db1;
DROP DATABASE db2;
USE test;
#
# Bug#13105873:valgrind warning:possible crash in foreign
# key handling on subsequent create table if not exists
@@ -132,3 +133,92 @@ Note 1050 Table 't2' already exists
DROP DATABASE testdb;
USE test;
End of 5.1 tests
#
# Bug#11763507 - 56224: FUNCTION NAME IS CASE-SENSITIVE
#
SET @@SQL_MODE = '';
CREATE FUNCTION testf_bug11763507() RETURNS INT
BEGIN
RETURN 0;
END
$
CREATE PROCEDURE testp_bug11763507()
BEGIN
SELECT "PROCEDURE testp_bug11763507";
END
$
SELECT testf_bug11763507();
testf_bug11763507()
0
SELECT TESTF_bug11763507();
TESTF_bug11763507()
0
SHOW FUNCTION STATUS LIKE 'testf_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testf_bug11763507 FUNCTION root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW FUNCTION STATUS WHERE NAME='testf_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testf_bug11763507 FUNCTION root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW FUNCTION STATUS LIKE 'TESTF_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testf_bug11763507 FUNCTION root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW FUNCTION STATUS WHERE NAME='TESTF_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testf_bug11763507 FUNCTION root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW CREATE FUNCTION testf_bug11763507;
Function sql_mode Create Function character_set_client collation_connection Database Collation
testf_bug11763507 CREATE DEFINER=`root`@`localhost` FUNCTION `testf_bug11763507`() RETURNS int(11)
BEGIN
RETURN 0;
END latin1 latin1_swedish_ci latin1_swedish_ci
SHOW CREATE FUNCTION TESTF_bug11763507;
Function sql_mode Create Function character_set_client collation_connection Database Collation
testf_bug11763507 CREATE DEFINER=`root`@`localhost` FUNCTION `testf_bug11763507`() RETURNS int(11)
BEGIN
RETURN 0;
END latin1 latin1_swedish_ci latin1_swedish_ci
CALL testp_bug11763507();
PROCEDURE testp_bug11763507
PROCEDURE testp_bug11763507
CALL TESTP_bug11763507();
PROCEDURE testp_bug11763507
PROCEDURE testp_bug11763507
SHOW PROCEDURE STATUS LIKE 'testp_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testp_bug11763507 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW PROCEDURE STATUS WHERE NAME='testp_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testp_bug11763507 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW PROCEDURE STATUS LIKE 'TESTP_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testp_bug11763507 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW PROCEDURE STATUS WHERE NAME='TESTP_bug11763507';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test testp_bug11763507 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
SHOW CREATE PROCEDURE testp_bug11763507;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
testp_bug11763507 CREATE DEFINER=`root`@`localhost` PROCEDURE `testp_bug11763507`()
BEGIN
SELECT "PROCEDURE testp_bug11763507";
END latin1 latin1_swedish_ci latin1_swedish_ci
SHOW CREATE PROCEDURE TESTP_bug11763507;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
testp_bug11763507 CREATE DEFINER=`root`@`localhost` PROCEDURE `testp_bug11763507`()
BEGIN
SELECT "PROCEDURE testp_bug11763507";
END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name LIKE 'testf_bug11763507';
specific_name
testf_bug11763507
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name LIKE 'TESTF_bug11763507';
specific_name
testf_bug11763507
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name='testf_bug11763507';
specific_name
testf_bug11763507
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name='TESTF_bug11763507';
specific_name
testf_bug11763507
DROP PROCEDURE testp_bug11763507;
DROP FUNCTION testf_bug11763507;
#END OF BUG#11763507 test.

View File

@@ -945,3 +945,32 @@ Error 1329 No data - zero rows fetched, selected, or processed
SET SESSION debug="-d,bug23032_emit_warning";
DROP PROCEDURE p1;
DROP TABLE t1;
#
# Bug#11763507 - 56224: FUNCTION NAME IS CASE-SENSITIVE
#
SET @@SQL_MODE = '';
CREATE FUNCTION testf_bug11763507() RETURNS INT
BEGIN
RETURN 0;
END
$
CREATE PROCEDURE testp_bug11763507()
BEGIN
SELECT "PROCEDURE testp_bug11763507";
END
$
SHOW FUNCTION CODE testf_bug11763507;
Pos Instruction
0 freturn 3 0
SHOW FUNCTION CODE TESTF_bug11763507;
Pos Instruction
0 freturn 3 0
SHOW PROCEDURE CODE testp_bug11763507;
Pos Instruction
0 stmt 0 "SELECT "PROCEDURE testp_bug11763507""
SHOW PROCEDURE CODE TESTP_bug11763507;
Pos Instruction
0 stmt 0 "SELECT "PROCEDURE testp_bug11763507""
DROP PROCEDURE testp_bug11763507;
DROP FUNCTION testf_bug11763507;
#END OF BUG#11763507 test.

View File

@@ -7747,6 +7747,44 @@ CALL p2();
DROP PROCEDURE p1;
DROP PROCEDURE p2;
DROP TABLE t1;
# Bug#13805127: Stored program cache produces wrong result in same THD
CREATE PROCEDURE p1(x INT UNSIGNED)
BEGIN
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE x = 1
UNION
SELECT 2 FROM dual WHERE x = 1 OR x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2
;
END|
CALL p1(1);
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
CALL p1(2);
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
CALL p1(1);
c1 c2 count(c3)
2012-03-01 01:00:00 2 1
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
DROP PROCEDURE p1;
# End of 5.5 test
#
# Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS

View File

@@ -308,4 +308,25 @@ SELECT `my.db`.f1(2);
2
# Switching to default connection.
DROP DATABASE `my.db`;
USE test;
set @@global.concurrent_insert= @old_concurrent_insert;
#
# Bug#11763507 - 56224: FUNCTION NAME IS CASE-SENSITIVE
#
SET @@SQL_MODE = '';
CREATE EVENT teste_bug11763507 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO SELECT 1 $
SHOW EVENTS LIKE 'teste_bug11763507';
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
test teste_bug11763507 root@localhost SYSTEM ONE TIME # # # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
SHOW EVENTS LIKE 'TESTE_bug11763507';
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
test teste_bug11763507 root@localhost SYSTEM ONE TIME # # # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
SHOW CREATE EVENT teste_bug11763507;
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
teste_bug11763507 SYSTEM # latin1 latin1_swedish_ci latin1_swedish_ci
SHOW CREATE EVENT TESTE_bug11763507;
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
teste_bug11763507 SYSTEM # latin1 latin1_swedish_ci latin1_swedish_ci
DROP EVENT teste_bug11763507;
#END OF BUG#11763507 test.

View File

@@ -4468,6 +4468,55 @@ ERROR 21000: Subquery returns more than 1 row
SET SESSION sql_mode=@old_sql_mode;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
CREATE TABLE t1(a1 int);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2(a1 int);
INSERT INTO t2 VALUES (3);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
1
1
1
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
1
1
1
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
1
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
1
1
1
SET SESSION sql_mode=@old_sql_mode;
DROP TABLE t1, t2;
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
create table t2(i int);
insert into t2 values(0);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
CREATE VIEW v1 AS
SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
;
CREATE TABLE t1 (
pk int NOT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_varchar_key (col_varchar_key)
);
SELECT t1.pk
FROM t1
WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
;
pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
End of 5.0 tests.
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);

View File

@@ -2679,6 +2679,8 @@ CREATE TABLE replace_table (a INT, b INT, PRIMARY KEY(a));
INSERT INTO replace_table values (1,1),(2,2);
CREATE TABLE update_table (a INT, b INT, PRIMARY KEY(a));
INSERT INTO update_table values (1,1),(2,2);
CREATE TABLE insert_2_keys (a INT UNIQUE KEY, b INT UNIQUE KEY) ENGINE = InnoDB;
INSERT INTO insert_2_keys values (1, 1);
INSERT IGNORE INTO insert_table SELECT * FROM filler_table;
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT IGNORE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave.
@@ -2702,10 +2704,15 @@ Note 1592 Unsafe statement written to the binary log using statement format sinc
CREATE TEMPORARY TABLE temp1 (a INT, b INT, PRIMARY KEY(b)) REPLACE SELECT * FROM filler_table;
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave.
INSERT INTO insert_2_keys VALUES (1, 2)
ON DUPLICATE KEY UPDATE a=VALUES(a)+10, b=VALUES(b)+10;
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
DROP TABLE filler_table;
DROP TABLE insert_table;
DROP TABLE update_table;
DROP TABLE replace_table;
DROP TABLE create_ignore_test;
DROP TABLE create_replace_test;
DROP TABLE insert_2_keys;
"End of tests"

View File

@@ -17,6 +17,7 @@
# - CREATE TABLE [IGNORE/REPLACE] SELECT
# - INSERT IGNORE...SELECT
# - UPDATE IGNORE
# - INSERT... ON DUPLICATE KEY UPDATE on a table with two UNIQUE KEYS
#
# Note that statements that use stored functions, stored procedures,
# triggers, views, or prepared statements that invoke unsafe
@@ -714,6 +715,9 @@ DROP TABLE t1;
#UPDATE IGNORE
#CREATE TABLE... IGNORE SELECT
#CREATE TABLE... REPLACE SELECT
#
###BUG 11765650 - 58637: MARK UPDATES THAT DEPEND ON ORDER OF TWO KEYS UNSAFE
#INSERT.... ON DUP KEY UPDATE on a table with more than one UNIQUE KEY
#setup tables
CREATE TABLE filler_table (a INT, b INT);
@@ -723,6 +727,8 @@ CREATE TABLE replace_table (a INT, b INT, PRIMARY KEY(a));
INSERT INTO replace_table values (1,1),(2,2);
CREATE TABLE update_table (a INT, b INT, PRIMARY KEY(a));
INSERT INTO update_table values (1,1),(2,2);
CREATE TABLE insert_2_keys (a INT UNIQUE KEY, b INT UNIQUE KEY) ENGINE = InnoDB;
INSERT INTO insert_2_keys values (1, 1);
#INSERT IGNORE... SELECT
INSERT IGNORE INTO insert_table SELECT * FROM filler_table;
@@ -740,6 +746,10 @@ CREATE TABLE create_replace_test (a INT, b INT, PRIMARY KEY(b)) REPLACE SELECT *
#temporary tables should not throw the warning.
CREATE TEMPORARY TABLE temp1 (a INT, b INT, PRIMARY KEY(b)) REPLACE SELECT * FROM filler_table;
#INSERT.... ON DUP KEY UPDATE on a table with more than one UNIQUE KEY
INSERT INTO insert_2_keys VALUES (1, 2)
ON DUPLICATE KEY UPDATE a=VALUES(a)+10, b=VALUES(b)+10;
###clean up
DROP TABLE filler_table;
DROP TABLE insert_table;
@@ -747,5 +757,6 @@ DROP TABLE update_table;
DROP TABLE replace_table;
DROP TABLE create_ignore_test;
DROP TABLE create_replace_test;
DROP TABLE insert_2_keys;
--echo "End of tests"

View File

@@ -648,7 +648,7 @@ t2 CREATE TABLE `t2` (
`n` int(10) unsigned NOT NULL,
`o` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`m`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1;
Table Create Table
@@ -657,7 +657,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SELECT * FROM t1;
a b c
@@ -671,16 +671,16 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -688,7 +688,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -702,21 +702,21 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
23 1 FALSE
24 2 FALSE
25 3 FALSE
26 4 FALSE
27 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
31 1 FALSE
32 2 FALSE
33 3 FALSE
34 4 FALSE
35 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -724,7 +724,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -738,26 +738,26 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
23 1 FALSE
24 2 FALSE
25 3 FALSE
26 4 FALSE
27 5 FALSE
30 1 FALSE
31 2 FALSE
32 3 FALSE
33 4 FALSE
34 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
31 1 FALSE
32 2 FALSE
33 3 FALSE
34 4 FALSE
35 5 FALSE
38 1 FALSE
39 2 FALSE
40 3 FALSE
41 4 FALSE
42 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -765,7 +765,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@@ -774,7 +774,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@@ -783,7 +783,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -797,41 +797,41 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
23 1 FALSE
24 2 FALSE
25 3 FALSE
26 4 FALSE
27 5 FALSE
30 1 FALSE
31 2 FALSE
32 3 FALSE
33 4 FALSE
34 5 FALSE
37 1 FALSE
38 2 FALSE
39 3 FALSE
40 4 FALSE
41 5 FALSE
44 1 FALSE
45 2 FALSE
46 3 FALSE
47 4 FALSE
48 5 FALSE
51 1 FALSE
52 2 FALSE
53 3 FALSE
54 4 FALSE
55 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
31 1 FALSE
32 2 FALSE
33 3 FALSE
34 4 FALSE
35 5 FALSE
38 1 FALSE
39 2 FALSE
40 3 FALSE
41 4 FALSE
42 5 FALSE
45 1 FALSE
46 2 FALSE
47 3 FALSE
48 4 FALSE
49 5 FALSE
52 1 FALSE
53 2 FALSE
54 3 FALSE
55 4 FALSE
56 5 FALSE
59 1 FALSE
60 2 FALSE
61 3 FALSE
62 4 FALSE
63 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -839,7 +839,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE IF EXISTS t1;
@@ -1251,3 +1251,21 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=256;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 256
CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, NULL);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` tinyint(4) NOT NULL AUTO_INCREMENT,
`c2` varchar(10) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
SELECT * FROM t1;
c1 c2
1 NULL
DROP TABLE t1;

View File

@@ -637,3 +637,14 @@ INSERT INTO t1 VALUES (18446744073709551615);
-- source include/restart_mysqld.inc
SHOW CREATE TABLE t1;
DROP TABLE t1;
# Check if we handl offset > column max value properly
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=256;
SHOW VARIABLES LIKE "%auto_inc%";
# TINYINT
CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, NULL);
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;

View File

@@ -4,6 +4,8 @@ call mtr.add_suppression("Unsafe statement written to the binary log using state
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
UNIQUE(b));
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
SELECT * FROM t1;
a b
1 10

View File

@@ -1,8 +1,11 @@
include/master-slave.inc
[connection master]
include/assert.inc [The default value shown for the slave's port number is the actual port number of the slave.]
include/rpl_restart_server.inc [server_number=2 parameters: --report-port=9000]
include/start_slave.inc
[Slave restarted with the report-port set to some value]
include/assert.inc [The value shown for the slave's port number is 9000 which is the value set for report-port.]
include/rpl_restart_server.inc [server_number=2 parameters: --report-port=]
include/start_slave.inc
[Slave restarted with the report-port set to the value of slave's port number]
include/assert.inc [The default value shown for the slave's port number is the actual port number of the slave.]
include/rpl_end.inc

View File

@@ -1 +0,0 @@
--report-port=

View File

@@ -10,22 +10,18 @@
#
#====Method====
#
# Start replication with report port not set.This will give the actual port
# number of the slave (ie. SLAVE_PORT) for the on doing SHOW SLAVE HOSTS on
# the master.
# Restart the slave server with report port set to 9000 and start the slave.
# Start replication with report port set to 9000 and restart the slave.
# In this case on doing SHOW SLAVE HOSTS on the master, we get the port number
# of the slave to be 9000.
# In the second case restart the slave server with report port not set. In this
# case on doing SHOW SLAVE HOSTS on the master, we get the actual port number
# of the slave (ie. SLAVE_PORT).
source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
connection master;
--let $report_port= query_get_value(SHOW SLAVE HOSTS, Port, 1)
--let assert_text= The default value shown for the slave's port number is the actual port number of the slave.
--let assert_cond= $report_port = "$SLAVE_MYPORT"
--source include/assert.inc
# Start the server with some value being passed to the report_port= <option>
# this will be used incase we have to mask the value of the slave's port
# number in certain situations.
@@ -46,4 +42,25 @@ connection master;
--let assert_cond= $report_port = "9000"
--source include/assert.inc
# Start the server with the report-port being passed with no value. So on SHOW SLAVE HOSTS
# on the master the value of slave's port should be the actual value of the slave port.
--let $rpl_server_number= 2
--let $rpl_server_parameters= --report-port=
--source include/rpl_restart_server.inc
connection slave;
--source include/start_slave.inc
--echo [Slave restarted with the report-port set to the value of slave's port number]
connection master;
# The value reported is the actual value of the slave's port.
--let $report_port= query_get_value(SHOW SLAVE HOSTS, Port, 1)
--let assert_text= The default value shown for the slave's port number is the actual port number of the slave.
--let assert_cond= $report_port = "$SLAVE_MYPORT"
--source include/assert.inc
--source include/rpl_end.inc

View File

@@ -1,6 +1,5 @@
# Can't run test of external client with embedded server
--source include/not_embedded.inc
--source include/not_windows.inc
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=20 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql
@@ -37,7 +36,7 @@
--exec $MYSQL_SLAP --only-print --delimiter=";" --query="select * from t1;select * from t2" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32)); INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')" --engine="heap,myisam" --post-query="SHOW TABLES" --pre-query="SHOW TABLES";
--exec $MYSQL_SLAP --only-print --delimiter=";" --query="select * from t1;select * from t2" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32)); INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')" --engine="heap,myisam" --post-query="SHOW TABLES" --pre-query="SHOW TABLES" --number-of-queries=6 --commit=1;
--exec $MYSQL_SLAP --only-print --delimiter=";" --query="select * from t1;select * from t2" --create="CREATE TABLE t1 (id int, name varchar(64)); create table t2(foo1 varchar(32), foo2 varchar(32)); INSERT INTO t1 VALUES (1, 'This is a test'); insert into t2 values ('test', 'test2')" --engine="heap,myisam" --post-query="SHOW TABLES" --pre-query="SHOW TABLES" --number-of-queries=6 --commit=1
--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=write --detach=2
@@ -68,3 +67,9 @@ SHOW DATABASES;
SHOW DATABASES;
DROP DATABASE bug58090;
--echo #
--echo # Bug #11766072 - 59107: MYSQLSLAP CRASHES IF STARTED WITH NO ARGUMENTS ON WINDOWS
--echo #
--replace_regex /queries: [0-9]+.[0-9]+/queries: TIME/
--exec $MYSQL_SLAP

View File

@@ -3364,6 +3364,94 @@ disconnect con1;
SELECT *
FROM (SELECT 1 UNION SELECT 2) t;
--echo
--echo # Bug#13805127: Stored program cache produces wrong result in same THD
--echo
PREPARE s1 FROM
"
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2
";
--echo
SET @x = 1;
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2;
--echo
EXECUTE s1;
--echo
SET @x = 2;
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2;
--echo
EXECUTE s1;
--echo
SET @x = 1;
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE @x = 1
UNION
SELECT 2 FROM dual WHERE @x = 1 OR @x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2;
--echo
EXECUTE s1;
DEALLOCATE PREPARE s1;
--echo #
--echo # End of 5.5 tests.

View File

@@ -138,6 +138,7 @@ DROP FUNCTION db1.f1;
DROP TABLE db1.t1;
DROP DATABASE db1;
DROP DATABASE db2;
USE test;
--echo #
--echo # Bug#13105873:valgrind warning:possible crash in foreign
@@ -164,3 +165,66 @@ DROP DATABASE testdb;
USE test;
--echo End of 5.1 tests
--echo #
--echo # Bug#11763507 - 56224: FUNCTION NAME IS CASE-SENSITIVE
--echo #
SET @@SQL_MODE = '';
DELIMITER $;
CREATE FUNCTION testf_bug11763507() RETURNS INT
BEGIN
RETURN 0;
END
$
CREATE PROCEDURE testp_bug11763507()
BEGIN
SELECT "PROCEDURE testp_bug11763507";
END
$
DELIMITER ;$
# STORED FUNCTIONS
SELECT testf_bug11763507();
SELECT TESTF_bug11763507();
--replace_column 5 # 6 #
SHOW FUNCTION STATUS LIKE 'testf_bug11763507';
--replace_column 5 # 6 #
SHOW FUNCTION STATUS WHERE NAME='testf_bug11763507';
--replace_column 5 # 6 #
SHOW FUNCTION STATUS LIKE 'TESTF_bug11763507';
--replace_column 5 # 6 #
SHOW FUNCTION STATUS WHERE NAME='TESTF_bug11763507';
SHOW CREATE FUNCTION testf_bug11763507;
SHOW CREATE FUNCTION TESTF_bug11763507;
# STORED PROCEDURE
CALL testp_bug11763507();
CALL TESTP_bug11763507();
--replace_column 5 # 6 #
SHOW PROCEDURE STATUS LIKE 'testp_bug11763507';
--replace_column 5 # 6 #
SHOW PROCEDURE STATUS WHERE NAME='testp_bug11763507';
--replace_column 5 # 6 #
SHOW PROCEDURE STATUS LIKE 'TESTP_bug11763507';
--replace_column 5 # 6 #
SHOW PROCEDURE STATUS WHERE NAME='TESTP_bug11763507';
SHOW CREATE PROCEDURE testp_bug11763507;
SHOW CREATE PROCEDURE TESTP_bug11763507;
# INFORMATION SCHEMA
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name LIKE 'testf_bug11763507';
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name LIKE 'TESTF_bug11763507';
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name='testf_bug11763507';
SELECT specific_name FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name='TESTF_bug11763507';
DROP PROCEDURE testp_bug11763507;
DROP FUNCTION testf_bug11763507;
--echo #END OF BUG#11763507 test.

View File

@@ -702,3 +702,35 @@ SET SESSION debug="-d,bug23032_emit_warning";
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # Bug#11763507 - 56224: FUNCTION NAME IS CASE-SENSITIVE
--echo #
SET @@SQL_MODE = '';
DELIMITER $;
CREATE FUNCTION testf_bug11763507() RETURNS INT
BEGIN
RETURN 0;
END
$
CREATE PROCEDURE testp_bug11763507()
BEGIN
SELECT "PROCEDURE testp_bug11763507";
END
$
DELIMITER ;$
# STORED FUNCTIONS
SHOW FUNCTION CODE testf_bug11763507;
SHOW FUNCTION CODE TESTF_bug11763507;
# STORED PROCEDURE
SHOW PROCEDURE CODE testp_bug11763507;
SHOW PROCEDURE CODE TESTP_bug11763507;
DROP PROCEDURE testp_bug11763507;
DROP FUNCTION testf_bug11763507;
--echo #END OF BUG#11763507 test.

View File

@@ -9027,6 +9027,42 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2;
DROP TABLE t1;
--echo
--echo # Bug#13805127: Stored program cache produces wrong result in same THD
--echo
delimiter |;
CREATE PROCEDURE p1(x INT UNSIGNED)
BEGIN
SELECT c1, t2.c2, count(c3)
FROM
(
SELECT 3 as c2 FROM dual WHERE x = 1
UNION
SELECT 2 FROM dual WHERE x = 1 OR x = 2
) AS t1,
(
SELECT '2012-03-01 01:00:00' AS c1, 3 as c2, 1 as c3 FROM dual
UNION
SELECT '2012-03-01 02:00:00', 3, 2 FROM dual
UNION
SELECT '2012-03-01 01:00:00', 2, 1 FROM dual
) AS t2
WHERE t2.c2 = t1.c2
GROUP BY c1, c2
;
END|
delimiter ;|
--echo
CALL p1(1);
CALL p1(2);
CALL p1(1);
DROP PROCEDURE p1;
--echo # End of 5.5 test

View File

@@ -473,6 +473,7 @@ SELECT `my.db`.f1(2);
connection default;
disconnect addcon;
DROP DATABASE `my.db`;
USE test;
#
# Restore global concurrent_insert value. Keep in the end of the test file.
@@ -483,3 +484,26 @@ set @@global.concurrent_insert= @old_concurrent_insert;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
--echo #
--echo # Bug#11763507 - 56224: FUNCTION NAME IS CASE-SENSITIVE
--echo #
SET @@SQL_MODE = '';
DELIMITER $;
CREATE EVENT teste_bug11763507 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO SELECT 1 $
DELIMITER ;$
# EVENTS
--replace_column 6 # 7 # 8 # 9 #
SHOW EVENTS LIKE 'teste_bug11763507';
--replace_column 6 # 7 # 8 # 9 #
SHOW EVENTS LIKE 'TESTE_bug11763507';
--replace_column 4 #
SHOW CREATE EVENT teste_bug11763507;
--replace_column 4 #
SHOW CREATE EVENT TESTE_bug11763507;
DROP EVENT teste_bug11763507;
--echo #END OF BUG#11763507 test.

View File

@@ -3421,6 +3421,61 @@ SET SESSION sql_mode=@old_sql_mode;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo #
--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
--echo #
CREATE TABLE t1(a1 int);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2(a1 int);
INSERT INTO t2 VALUES (3);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
## All these are subject to the transformation
## '1 < some (...)' => '1 < max(...)'
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
SET SESSION sql_mode=@old_sql_mode;
DROP TABLE t1, t2;
--echo #
--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
--echo #
create table t2(i int);
insert into t2 values(0);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
CREATE VIEW v1 AS
SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
;
CREATE TABLE t1 (
pk int NOT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_varchar_key (col_varchar_key)
);
SELECT t1.pk
FROM t1
WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
;
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
--echo End of 5.0 tests.
#

View File

@@ -211,13 +211,16 @@ void _lf_pinbox_put_pins(LF_PINS *pins)
LF_PINBOX *pinbox= pins->pinbox;
uint32 top_ver, nr;
nr= pins->link;
#ifdef MY_LF_EXTRA_DEBUG
#ifndef DBUG_OFF
{
/* This thread should not hold any pin. */
int i;
for (i= 0; i < LF_PINBOX_PINS; i++)
DBUG_ASSERT(pins->pin[i] == 0);
}
#endif
#endif /* DBUG_OFF */
/*
XXX this will deadlock if other threads will wait for
the caller to do something after _lf_pinbox_put_pins(),

View File

@@ -1031,7 +1031,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
{
DBUG_ASSERT(select_lex->non_agg_field_used());
/*
If the argument is a field, we assume that fix_fields() has
tagged the select_lex with non_agg_field_used.
We reverse that decision after this rewrite with MIN/MAX.
*/
if (item->get_arg(0)->type() == Item::FIELD_ITEM)
DBUG_ASSERT(select_lex->non_agg_field_used());
select_lex->set_non_agg_field_used(false);
}

175
sql/mem_root_array.h Normal file
View File

@@ -0,0 +1,175 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef MEM_ROOT_ARRAY_INCLUDED
#define MEM_ROOT_ARRAY_INCLUDED
#include <my_alloc.h>
/**
A typesafe replacement for DYNAMIC_ARRAY.
We use MEM_ROOT for allocating storage, rather than the C++ heap.
The interface is chosen to be similar to std::vector.
@remark
Unlike DYNAMIC_ARRAY, elements are properly copied
(rather than memcpy()d) if the underlying array needs to be expanded.
@remark
Depending on has_trivial_destructor, we destroy objects which are
removed from the array (including when the array object itself is destroyed).
@remark
Note that MEM_ROOT has no facility for reusing free space,
so don't use this if multiple re-expansions are likely to happen.
@param Element_type The type of the elements of the container.
Elements must be copyable.
@param has_trivial_destructor If true, we don't destroy elements.
We could have used type traits to determine this.
__has_trivial_destructor is supported by some (but not all)
compilers we use.
*/
template<typename Element_type, bool has_trivial_destructor>
class Mem_root_array
{
public:
Mem_root_array(MEM_ROOT *root)
: m_root(root), m_array(NULL), m_size(0), m_capacity(0)
{
DBUG_ASSERT(m_root != NULL);
}
~Mem_root_array()
{
clear();
}
Element_type &at(size_t n)
{
DBUG_ASSERT(n < size());
return m_array[n];
}
const Element_type &at(size_t n) const
{
DBUG_ASSERT(n < size());
return m_array[n];
}
// Returns a pointer to the first element in the array.
Element_type *begin() { return &m_array[0]; }
// Returns a pointer to the past-the-end element in the array.
Element_type *end() { return &m_array[size()]; }
// Erases all of the elements.
void clear()
{
if (!empty())
chop(0);
}
/*
Chops the tail off the array, erasing all tail elements.
@param pos Index of first element to erase.
*/
void chop(const size_t pos)
{
DBUG_ASSERT(pos < m_size);
if (!has_trivial_destructor)
{
for (size_t ix= pos; ix < m_size; ++ix)
{
Element_type *p= &m_array[ix];
p->~Element_type(); // Destroy discarded element.
}
}
m_size= pos;
}
/*
Reserves space for array elements.
Copies over existing elements, in case we are re-expanding the array.
@param n number of elements.
@retval true if out-of-memory, false otherwise.
*/
bool reserve(size_t n)
{
if (n <= m_capacity)
return false;
void *mem= alloc_root(m_root, n * element_size());
if (!mem)
return true;
Element_type *array= static_cast<Element_type*>(mem);
// Copy all the existing elements into the new array.
for (size_t ix= 0; ix < m_size; ++ix)
{
Element_type *new_p= &array[ix];
Element_type *old_p= &m_array[ix];
new (new_p) Element_type(*old_p); // Copy into new location.
if (!has_trivial_destructor)
old_p->~Element_type(); // Destroy the old element.
}
// Forget the old array.
m_array= array;
m_capacity= n;
return false;
}
/*
Adds a new element at the end of the array, after its current last
element. The content of this new element is initialized to a copy of
the input argument.
@param element Object to copy.
@retval true if out-of-memory, false otherwise.
*/
bool push_back(const Element_type &element)
{
const size_t min_capacity= 20;
const size_t expansion_factor= 2;
if (0 == m_capacity && reserve(min_capacity))
return true;
if (m_size == m_capacity && reserve(m_capacity * expansion_factor))
return true;
Element_type *p= &m_array[m_size++];
new (p) Element_type(element);
return false;
}
size_t capacity() const { return m_capacity; }
size_t element_size() const { return sizeof(Element_type); }
bool empty() const { return size() == 0; }
size_t size() const { return m_size; }
private:
MEM_ROOT *const m_root;
Element_type *m_array;
size_t m_size;
size_t m_capacity;
// Not (yet) implemented.
Mem_root_array(const Mem_root_array&);
Mem_root_array &operator=(const Mem_root_array&);
};
#endif // MEM_ROOT_ARRAY_INCLUDED

View File

@@ -1765,6 +1765,48 @@ static void set_root(const char *path)
}
static my_socket create_socket(const struct addrinfo *addrinfo_list,
int addr_family,
struct addrinfo **use_addrinfo)
{
my_socket sock= INVALID_SOCKET;
for (const struct addrinfo *cur_ai= addrinfo_list; cur_ai != NULL;
cur_ai= cur_ai->ai_next)
{
if (cur_ai->ai_family != addr_family)
continue;
sock= socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
char ip_addr[INET6_ADDRSTRLEN];
if (vio_get_normalized_ip_string(cur_ai->ai_addr, cur_ai->ai_addrlen,
ip_addr, sizeof (ip_addr)))
{
ip_addr[0]= 0;
}
if (sock == INVALID_SOCKET)
{
sql_print_error("Failed to create a socket for %s '%s': errno: %d.",
(addr_family == AF_INET) ? "IPv4" : "IPv6",
(const char *) ip_addr,
(int) socket_errno);
continue;
}
sql_print_information("Server socket created on IP: '%s'.",
(const char *) ip_addr);
*use_addrinfo= (struct addrinfo *)cur_ai;
return sock;
}
return INVALID_SOCKET;
}
static void network_init(void)
{
#ifdef HAVE_SYS_UN_H
@@ -1793,37 +1835,60 @@ static void network_init(void)
{
struct addrinfo *ai, *a;
struct addrinfo hints;
int error;
DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
sql_print_information("Server hostname (bind-address): '%s'; port: %d",
my_bind_addr_str, mysqld_port);
// Get list of IP-addresses associated with the server hostname.
bzero(&hints, sizeof (hints));
hints.ai_flags= AI_PASSIVE;
hints.ai_socktype= SOCK_STREAM;
hints.ai_family= AF_UNSPEC;
my_snprintf(port_buf, NI_MAXSERV, "%d", mysqld_port);
error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
if (error != 0)
if (getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai))
{
DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */
sql_print_error("Can't start server: cannot resolve hostname!");
unireg_abort(1); /* purecov: tested */
}
for (a= ai; a != NULL; a= a->ai_next)
// Log all the IP-addresses.
for (struct addrinfo *cur_ai= ai; cur_ai != NULL; cur_ai= cur_ai->ai_next)
{
ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol);
if (ip_sock != INVALID_SOCKET)
break;
char ip_addr[INET6_ADDRSTRLEN];
if (vio_get_normalized_ip_string(cur_ai->ai_addr, cur_ai->ai_addrlen,
ip_addr, sizeof (ip_addr)))
{
sql_print_error("Fails to print out IP-address.");
continue;
}
sql_print_information(" - '%s' resolves to '%s';",
my_bind_addr_str, ip_addr);
}
/*
If the 'bind-address' option specifies the hostname, which resolves to
multiple IP-address, use the following rule:
- if there are IPv4-addresses, use the first IPv4-address
returned by getaddrinfo();
- if there are IPv6-addresses, use the first IPv6-address
returned by getaddrinfo();
*/
ip_sock= create_socket(ai, AF_INET, &a);
if (ip_sock == INVALID_SOCKET)
{
DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */
unireg_abort(1); /* purecov: tested */
}
ip_sock= create_socket(ai, AF_INET6, &a);
// Report user-error if we failed to create a socket.
if (ip_sock == INVALID_SOCKET)
{
sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */
unireg_abort(1); /* purecov: tested */
}
#ifndef __WIN__
/*
We should not use SO_REUSEADDR on windows as this would enable a
@@ -7027,28 +7092,6 @@ mysqld_get_one_option(int optid,
case (int) OPT_SKIP_STACK_TRACE:
test_flags|=TEST_NO_STACKTRACE;
break;
case (int) OPT_BIND_ADDRESS:
{
struct addrinfo *res_lst, hints;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_socktype= SOCK_STREAM;
hints.ai_protocol= IPPROTO_TCP;
if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
{
sql_print_error("Can't start server: cannot resolve hostname!");
return 1;
}
if (res_lst->ai_next)
{
sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
return 1;
}
freeaddrinfo(res_lst);
}
break;
case OPT_CONSOLE:
if (opt_console)
opt_error_log= 0; // Force logs to stdout

View File

@@ -6494,6 +6494,9 @@ ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT
ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC
eng "CREATE TABLE... SELECT... on a table with an auto-increment column is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are inserted. This order cannot be predicted and may differ on master and the slave."
ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
eng "INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe"
ER_TABLE_IN_FK_CHECK
eng "Table is being used in foreign key check."

View File

@@ -5691,6 +5691,32 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
has_write_table_with_auto_increment_and_select(tables))
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT);
/*
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
can be unsafe.
*/
uint unique_keys= 0;
for (TABLE_LIST *query_table= tables; query_table && unique_keys <= 1;
query_table= query_table->next_global)
if(query_table->table)
{
uint keys= query_table->table->s->keys, i= 0;
unique_keys= 0;
for (KEY* keyinfo= query_table->table->s->key_info;
i < keys && unique_keys <= 1; i++, keyinfo++)
{
if (keyinfo->flags & HA_NOSAME)
unique_keys++;
}
if (!query_table->placeholder() &&
query_table->lock_type >= TL_WRITE_ALLOW_WRITE &&
unique_keys > 1 && thd->lex->sql_command == SQLCOM_INSERT &&
/* Duplicate key update is not supported by INSERT DELAYED */
thd->command != COM_DELAYED_INSERT &&
thd->lex->duplicates == DUP_UPDATE)
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
}
/* We have to emulate LOCK TABLES if we are statement needs prelocking. */
if (thd->lex->requires_prelocking())
{

View File

@@ -66,7 +66,8 @@ Query_tables_list::binlog_stmt_unsafe_errcode[BINLOG_STMT_UNSAFE_COUNT] =
ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT,
ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT,
ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC,
ER_BINLOG_UNSAFE_UPDATE_IGNORE
ER_BINLOG_UNSAFE_UPDATE_IGNORE,
ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
};
@@ -389,6 +390,8 @@ void lex_start(THD *thd)
lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
lex->select_lex.init_order();
lex->select_lex.group_list.empty();
if (lex->select_lex.group_list_ptrs)
lex->select_lex.group_list_ptrs->clear();
lex->describe= 0;
lex->subqueries= FALSE;
lex->context_analysis_only= 0;
@@ -1773,6 +1776,8 @@ void st_select_lex::init_select()
{
st_select_lex_node::init_select();
group_list.empty();
if (group_list_ptrs)
group_list_ptrs->clear();
type= db= 0;
having= 0;
table_join_options= 0;
@@ -3100,6 +3105,8 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
The passed WHERE and HAVING are to be saved for the future executions.
This function saves it, and returns a copy which can be thrashed during
this execution of the statement. By saving/thrashing here we mean only
We also save the chain of ORDER::next in group_list, in case
the list is modified by remove_const().
AND/OR trees.
The function also calls fix_prepare_info_in_table_list that saves all
ON expressions.
@@ -3111,6 +3118,19 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
if (!thd->stmt_arena->is_conventional() && first_execution)
{
first_execution= 0;
if (group_list.first)
{
if (!group_list_ptrs)
{
void *mem= thd->stmt_arena->alloc(sizeof(Group_list_ptrs));
group_list_ptrs= new (mem) Group_list_ptrs(thd->stmt_arena->mem_root);
}
group_list_ptrs->reserve(group_list.elements);
for (ORDER *order= group_list.first; order; order= order->next)
{
group_list_ptrs->push_back(order);
}
}
if (*conds)
{
prep_where= *conds;
@@ -3362,3 +3382,7 @@ void binlog_unsafe_map_init()
BINLOG_DIRECT_OFF & TRX_CACHE_NOT_EMPTY);
}
#endif
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
template class Mem_root_array<ORDER*, true>;
#endif

View File

@@ -24,6 +24,7 @@
#include "sql_trigger.h"
#include "item.h" /* From item_subselect.h: subselect_union_engine */
#include "thr_lock.h" /* thr_lock_type, TL_UNLOCK */
#include "mem_root_array.h"
/* YACC and LEX Definitions */
@@ -258,6 +259,7 @@ enum enum_drop_mode
#define TL_OPTION_ALIAS 8
typedef List<Item> List_item;
typedef Mem_root_array<ORDER*, true> Group_list_ptrs;
/* SERVERS CACHE CHANGES */
typedef struct st_lex_server_options
@@ -693,7 +695,16 @@ public:
enum olap_type olap;
/* FROM clause - points to the beginning of the TABLE_LIST::next_local list. */
SQL_I_List<TABLE_LIST> table_list;
SQL_I_List<ORDER> group_list; /* GROUP BY clause. */
/*
GROUP BY clause.
This list may be mutated during optimization (by remove_const()),
so for prepared statements, we keep a copy of the ORDER.next pointers in
group_list_ptrs, and re-establish the original list before each execution.
*/
SQL_I_List<ORDER> group_list;
Group_list_ptrs *group_list_ptrs;
List<Item> item_list; /* list of fields & expressions */
List<String> interval_list;
bool is_item_list_lookup;
@@ -870,7 +881,8 @@ public:
bool test_limit();
friend void lex_start(THD *thd);
st_select_lex() : n_sum_items(0), n_child_sum_items(0) {}
st_select_lex() : group_list_ptrs(NULL), n_sum_items(0), n_child_sum_items(0)
{}
void make_empty_select()
{
init_query();
@@ -1311,6 +1323,12 @@ public:
*/
BINLOG_STMT_UNSAFE_UPDATE_IGNORE,
/**
INSERT... ON DUPLICATE KEY UPDATE on a table with more than one
UNIQUE KEYS is unsafe.
*/
BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS,
/* The last element of this enumeration type. */
BINLOG_STMT_UNSAFE_COUNT
};

View File

@@ -2422,6 +2422,14 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
DBUG_ASSERT(sl->join == 0);
ORDER *order;
/* Fix GROUP list */
if (sl->group_list_ptrs && sl->group_list_ptrs->size() > 0)
{
for (uint ix= 0; ix < sl->group_list_ptrs->size() - 1; ++ix)
{
order= sl->group_list_ptrs->at(ix);
order->next= sl->group_list_ptrs->at(ix+1);
}
}
for (order= sl->group_list.first; order; order= order->next)
order->item= &order->item_ptr;
/* Fix ORDER list */

View File

@@ -4787,7 +4787,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
{
restore_record(table, s->default_values);
if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0))
if (!wild || !wild[0] || !wild_case_compare(system_charset_info,
sp_name.c_ptr_safe(), wild))
{
int enum_idx= (int) proc_table->field[MYSQL_PROC_FIELD_ACCESS]->val_int();
table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
@@ -5947,7 +5948,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
DBUG_RETURN(1);
}
if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
if (!(!wild || !wild[0] || !wild_case_compare(scs, et.name.str, wild)))
DBUG_RETURN(0);
/*

View File

@@ -4409,6 +4409,7 @@ Item *Field_iterator_table::create_item(THD *thd)
{
select->non_agg_fields.push_back(item);
item->marker= select->cur_pos_in_select_list;
select->set_non_agg_field_used(true);
}
return item;
}

View File

@@ -334,40 +334,276 @@ next_page:
ut_free(page_arr);
}
/******************************************************************//**
While flushing (or removing dirty) pages from a tablespace we don't
want to hog the CPU and resources. Release the buffer pool and block
mutex and try to force a context switch. Then reacquire the same mutexes.
The current page is "fixed" before the release of the mutexes and then
"unfixed" again once we have reacquired the mutexes. */
static
void
buf_flush_yield(
/*============*/
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_page_t* bpage) /*!< in/out: current page */
{
mutex_t* block_mutex;
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(buf_page_in_file(bpage));
block_mutex = buf_page_get_mutex(bpage);
mutex_enter(block_mutex);
/* "Fix" the block so that the position cannot be
changed after we release the buffer pool and
block mutexes. */
buf_page_set_sticky(bpage);
/* Now it is safe to release the buf_pool->mutex. */
buf_pool_mutex_exit(buf_pool);
mutex_exit(block_mutex);
/* Try and force a context switch. */
os_thread_yield();
buf_pool_mutex_enter(buf_pool);
mutex_enter(block_mutex);
/* "Unfix" the block now that we have both the
buffer pool and block mutex again. */
buf_page_unset_sticky(bpage);
mutex_exit(block_mutex);
}
/******************************************************************//**
If we have hogged the resources for too long then release the buffer
pool and flush list mutex and do a thread yield. Set the current page
to "sticky" so that it is not relocated during the yield.
@return TRUE if yielded */
static
ibool
buf_flush_try_yield(
/*================*/
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_page_t* bpage, /*!< in/out: bpage to remove */
ulint processed) /*!< in: number of pages processed */
{
/* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
loop we release buf_pool->mutex to let other threads
do their job but only if the block is not IO fixed. This
ensures that the block stays in its position in the
flush_list. */
if (bpage != NULL
&& processed >= BUF_LRU_DROP_SEARCH_SIZE
&& buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
buf_flush_list_mutex_exit(buf_pool);
/* Release the buffer pool and block mutex
to give the other threads a go. */
buf_flush_yield(buf_pool, bpage);
buf_flush_list_mutex_enter(buf_pool);
/* Should not have been removed from the flush
list during the yield. However, this check is
not sufficient to catch a remove -> add. */
ut_ad(bpage->in_flush_list);
return(TRUE);
}
return(FALSE);
}
/******************************************************************//**
Removes a single page from a given tablespace inside a specific
buffer pool instance.
@return TRUE if page was removed. */
static
ibool
buf_flush_or_remove_page(
/*=====================*/
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_page_t* bpage) /*!< in/out: bpage to remove */
{
mutex_t* block_mutex;
ibool processed = FALSE;
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(buf_flush_list_mutex_own(buf_pool));
block_mutex = buf_page_get_mutex(bpage);
/* bpage->space and bpage->io_fix are protected by
buf_pool->mutex and block_mutex. It is safe to check
them while holding buf_pool->mutex only. */
if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* We cannot remove this page during this scan
yet; maybe the system is currently reading it
in, or flushing the modifications to the file */
} else {
/* We have to release the flush_list_mutex to obey the
latching order. We are however guaranteed that the page
will stay in the flush_list because buf_flush_remove()
needs buf_pool->mutex as well (for the non-flush case). */
buf_flush_list_mutex_exit(buf_pool);
mutex_enter(block_mutex);
ut_ad(bpage->oldest_modification != 0);
if (bpage->buf_fix_count == 0) {
buf_flush_remove(bpage);
processed = TRUE;
}
mutex_exit(block_mutex);
buf_flush_list_mutex_enter(buf_pool);
}
ut_ad(!mutex_own(block_mutex));
return(processed);
}
/******************************************************************//**
Remove all dirty pages belonging to a given tablespace inside a specific
buffer pool instance when we are deleting the data file(s) of that
tablespace. The pages still remain a part of LRU and are evicted from
the list as they age towards the tail of the LRU. */
the list as they age towards the tail of the LRU.
@return TRUE if all freed. */
static
ibool
buf_flush_or_remove_pages(
/*======================*/
buf_pool_t* buf_pool, /*!< buffer pool instance */
ulint id) /*!< in: target space id for which
to remove or flush pages */
{
buf_page_t* prev;
buf_page_t* bpage;
ulint processed = 0;
ibool all_freed = TRUE;
buf_flush_list_mutex_enter(buf_pool);
for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
bpage != NULL;
bpage = prev) {
ut_a(buf_page_in_file(bpage));
ut_ad(bpage->in_flush_list);
/* Save the previous link because once we free the
page we can't rely on the links. */
prev = UT_LIST_GET_PREV(list, bpage);
if (buf_page_get_space(bpage) != id) {
/* Skip this block, as it does not belong to
the target space. */
} else if (!buf_flush_or_remove_page(buf_pool, bpage)) {
/* Remove was unsuccessful, we have to try again
by scanning the entire list from the end. */
all_freed = FALSE;
}
++processed;
/* Yield if we have hogged the CPU and mutexes for too long. */
if (buf_flush_try_yield(buf_pool, prev, processed)) {
/* Reset the batch size counter if we had to yield. */
processed = 0;
}
}
buf_flush_list_mutex_exit(buf_pool);
return(all_freed);
}
/******************************************************************//**
Remove or flush all the dirty pages that belong to a given tablespace
inside a specific buffer pool instance. The pages will remain in the LRU
list and will be evicted from the LRU list as they age and move towards
the tail of the LRU list. */
static
void
buf_LRU_remove_dirty_pages_for_tablespace(
/*======================================*/
buf_flush_dirty_pages(
/*==================*/
buf_pool_t* buf_pool, /*!< buffer pool instance */
ulint id) /*!< in: space id */
{
ibool all_freed;
do {
buf_pool_mutex_enter(buf_pool);
all_freed = buf_flush_or_remove_pages(buf_pool, id);
buf_pool_mutex_exit(buf_pool);
ut_ad(buf_flush_validate(buf_pool));
if (!all_freed) {
os_thread_sleep(20000);
}
} while (!all_freed);
}
/******************************************************************//**
Remove all pages that belong to a given tablespace inside a specific
buffer pool instance when we are DISCARDing the tablespace. */
static
void
buf_LRU_remove_all_pages(
/*=====================*/
buf_pool_t* buf_pool, /*!< buffer pool instance */
ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ibool all_freed;
ulint i;
scan_again:
buf_pool_mutex_enter(buf_pool);
buf_flush_list_mutex_enter(buf_pool);
all_freed = TRUE;
for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list), i = 0;
bpage != NULL; ++i) {
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
bpage != NULL;
/* No op */) {
buf_page_t* prev_bpage;
mutex_t* block_mutex = NULL;
ut_a(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
prev_bpage = UT_LIST_GET_PREV(list, bpage);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
/* bpage->space and bpage->io_fix are protected by
buf_pool->mutex and block_mutex. It is safe to check
buf_pool->mutex and the block_mutex. It is safe to check
them while holding buf_pool->mutex only. */
if (buf_page_get_space(bpage) != id) {
@@ -381,83 +617,87 @@ scan_again:
all_freed = FALSE;
goto next_page;
} else {
block_mutex = buf_page_get_mutex(bpage);
mutex_enter(block_mutex);
if (bpage->buf_fix_count > 0) {
mutex_exit(block_mutex);
/* We cannot remove this page during
this scan yet; maybe the system is
currently reading it in, or flushing
the modifications to the file */
all_freed = FALSE;
goto next_page;
}
}
/* We have to release the flush_list_mutex to obey the
latching order. We are however guaranteed that the page
will stay in the flush_list because buf_flush_remove()
needs buf_pool->mutex as well. */
buf_flush_list_mutex_exit(buf_pool);
block_mutex = buf_page_get_mutex(bpage);
mutex_enter(block_mutex);
ut_ad(mutex_own(block_mutex));
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Dropping space %lu page %lu\n",
(ulong) buf_page_get_space(bpage),
(ulong) buf_page_get_page_no(bpage));
}
#endif
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
/* Do nothing, because the adaptive hash index
covers uncompressed pages only. */
} else if (((buf_block_t*) bpage)->index) {
ulint page_no;
ulint zip_size;
buf_pool_mutex_exit(buf_pool);
zip_size = buf_page_get_zip_size(bpage);
page_no = buf_page_get_page_no(bpage);
if (bpage->buf_fix_count > 0) {
mutex_exit(block_mutex);
buf_flush_list_mutex_enter(buf_pool);
/* We cannot remove this page during
this scan yet; maybe the system is
currently reading it in, or flushing
the modifications to the file */
/* Note that the following call will acquire
and release block->lock X-latch. */
all_freed = FALSE;
goto next_page;
btr_search_drop_page_hash_when_freed(
id, zip_size, page_no);
goto scan_again;
}
ut_ad(bpage->oldest_modification != 0);
if (bpage->oldest_modification != 0) {
buf_flush_remove(bpage);
}
buf_flush_remove(bpage);
ut_ad(!bpage->in_flush_list);
/* Remove from the LRU list. */
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
mutex_exit(block_mutex);
} else {
/* The block_mutex should have been released
by buf_LRU_block_remove_hashed_page() when it
returns BUF_BLOCK_ZIP_FREE. */
ut_ad(block_mutex == &buf_pool->zip_mutex);
}
ut_ad(!mutex_own(block_mutex));
mutex_exit(block_mutex);
buf_flush_list_mutex_enter(buf_pool);
next_page:
bpage = prev_bpage;
if (!bpage) {
break;
}
/* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
loop we release buf_pool->mutex to let other threads
do their job. */
if (i < BUF_LRU_DROP_SEARCH_SIZE) {
continue;
}
/* We IO-fix the block to make sure that the block
stays in its position in the flush_list. */
if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* Block is already IO-fixed. We don't
want to change the value. Lets leave
this block alone. */
continue;
}
buf_flush_list_mutex_exit(buf_pool);
block_mutex = buf_page_get_mutex(bpage);
mutex_enter(block_mutex);
buf_page_set_sticky(bpage);
mutex_exit(block_mutex);
/* Now it is safe to release the buf_pool->mutex. */
buf_pool_mutex_exit(buf_pool);
os_thread_yield();
buf_pool_mutex_enter(buf_pool);
mutex_enter(block_mutex);
buf_page_unset_sticky(bpage);
mutex_exit(block_mutex);
buf_flush_list_mutex_enter(buf_pool);
ut_ad(bpage->in_flush_list);
i = 0;
}
buf_pool_mutex_exit(buf_pool);
buf_flush_list_mutex_exit(buf_pool);
ut_ad(buf_flush_validate(buf_pool));
if (!all_freed) {
os_thread_sleep(20000);
@@ -467,28 +707,46 @@ next_page:
}
/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. */
Removes all pages belonging to a given tablespace. */
UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
buf_LRU_flush_or_remove_pages(
/*==========================*/
ulint id) /*!< in: space id */
ulint id, /*!< in: space id */
enum buf_remove_t buf_remove)/*!< in: remove or flush
strategy */
{
ulint i;
ulint i;
/* Before we attempt to drop pages one by one we first
attempt to drop page hash index entries in batches to make
it more efficient. The batching attempt is a best effort
attempt and does not guarantee that all pages hash entries
will be dropped. We get rid of remaining page hash entries
one by one below. */
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool;
buf_pool = buf_pool_from_array(i);
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
buf_LRU_remove_dirty_pages_for_tablespace(buf_pool, id);
switch (buf_remove) {
case BUF_REMOVE_ALL_NO_WRITE:
/* A DISCARD tablespace case. Remove AHI entries
and evict all pages from LRU. */
/* Before we attempt to drop pages hash entries
one by one we first attempt to drop page hash
index entries in batches to make it more
efficient. The batching attempt is a best effort
attempt and does not guarantee that all pages
hash entries will be dropped. We get rid of
remaining page hash entries one by one below. */
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
buf_LRU_remove_all_pages(buf_pool, id);
break;
case BUF_REMOVE_FLUSH_NO_WRITE:
/* A DROP table case. AHI entries are already
removed. No need to evict all pages from LRU
list. Just evict pages from flush list without
writing. */
buf_flush_dirty_pages(buf_pool, id);
break;
}
}
}

View File

@@ -2159,7 +2159,7 @@ fil_op_log_parse_or_replay(
switch (type) {
case MLOG_FILE_DELETE:
if (fil_tablespace_exists_in_mem(space_id)) {
ut_a(fil_delete_tablespace(space_id));
ut_a(fil_delete_tablespace(space_id, TRUE));
}
break;
@@ -2229,7 +2229,9 @@ UNIV_INTERN
ibool
fil_delete_tablespace(
/*==================*/
ulint id) /*!< in: space id */
ulint id, /*!< in: space id */
ibool evict_all) /*!< in: TRUE if we want all pages
evicted from LRU. */
{
ibool success;
fil_space_t* space;
@@ -2351,7 +2353,10 @@ try_again:
completely and permanently. The flag is_being_deleted also prevents
fil_flush() from being applied to this tablespace. */
buf_LRU_invalidate_tablespace(id);
buf_LRU_flush_or_remove_pages(
id, evict_all
? BUF_REMOVE_ALL_NO_WRITE
: BUF_REMOVE_FLUSH_NO_WRITE);
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
@@ -2439,7 +2444,7 @@ fil_discard_tablespace(
{
ibool success;
success = fil_delete_tablespace(id);
success = fil_delete_tablespace(id, TRUE);
if (!success) {
fprintf(stderr,

View File

@@ -1450,70 +1450,87 @@ values we want to reserve for multi-value inserts e.g.,
INSERT INTO T VALUES(), (), ();
innobase_next_autoinc() will be called with increment set to
n * 3 where autoinc_lock_mode != TRADITIONAL because we want
to reserve 3 values for the multi-value INSERT above.
innobase_next_autoinc() will be called with increment set to 3 where
autoinc_lock_mode != TRADITIONAL because we want to reserve 3 values for
the multi-value INSERT above.
@return the next value */
static
ulonglong
innobase_next_autoinc(
/*==================*/
ulonglong current, /*!< in: Current value */
ulonglong increment, /*!< in: increment current by */
ulonglong need, /*!< in: count of values needed */
ulonglong step, /*!< in: AUTOINC increment step */
ulonglong offset, /*!< in: AUTOINC offset */
ulonglong max_value) /*!< in: max value for type */
{
ulonglong next_value;
ulonglong block = need * step;
/* Should never be 0. */
ut_a(increment > 0);
ut_a(need > 0);
ut_a(block > 0);
ut_a(max_value > 0);
/* Current value should never be greater than the maximum. */
ut_a(current <= max_value);
/* According to MySQL documentation, if the offset is greater than
the increment then the offset is ignored. */
if (offset > increment) {
the step then the offset is ignored. */
if (offset > block) {
offset = 0;
}
if (max_value <= current) {
/* Check for overflow. */
if (block >= max_value
|| offset > max_value
|| current == max_value
|| max_value - offset <= offset) {
next_value = max_value;
} else if (offset <= 1) {
/* Offset 0 and 1 are the same, because there must be at
least one node in the system. */
if (max_value - current <= increment) {
next_value = max_value;
} else {
next_value = current + increment;
}
} else if (max_value > current) {
if (current > offset) {
next_value = ((current - offset) / increment) + 1;
} else {
next_value = ((offset - current) / increment) + 1;
}
ut_a(increment > 0);
ut_a(next_value > 0);
/* Check for multiplication overflow. */
if (increment > (max_value / next_value)) {
next_value = max_value;
} else {
next_value *= increment;
ut_a(max_value >= next_value);
/* Check for overflow. */
if (max_value - next_value <= offset) {
next_value = max_value;
} else {
next_value += offset;
}
}
} else {
next_value = max_value;
ut_a(max_value > current);
ulonglong free = max_value - current;
if (free < offset || free - offset <= block) {
next_value = max_value;
} else {
next_value = 0;
}
}
if (next_value == 0) {
ulonglong next;
if (current > offset) {
next = (current - offset) / step;
} else {
next = (offset - current) / step;
}
ut_a(max_value > next);
next_value = next * step;
/* Check for multiplication overflow. */
ut_a(next_value >= next);
ut_a(max_value > next_value);
/* Check for overflow */
if (max_value - next_value >= block) {
next_value += block;
if (max_value - next_value >= offset) {
next_value += offset;
} else {
next_value = max_value;
}
} else {
next_value = max_value;
}
}
ut_a(next_value != 0);
ut_a(next_value <= max_value);
return(next_value);
@@ -3749,7 +3766,7 @@ ha_innobase::innobase_initialize_autoinc()
nor the offset, so use a default increment of 1. */
auto_inc = innobase_next_autoinc(
read_auto_inc, 1, 1, col_max_value);
read_auto_inc, 1, 1, 0, col_max_value);
break;
}
@@ -5249,15 +5266,16 @@ set_max_autoinc:
if (auto_inc <= col_max_value) {
ut_a(prebuilt->autoinc_increment > 0);
ulonglong need;
ulonglong offset;
ulonglong increment;
offset = prebuilt->autoinc_offset;
need = prebuilt->autoinc_increment;
increment = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
auto_inc,
need, offset, col_max_value);
1, increment, offset,
col_max_value);
err = innobase_set_max_autoinc(
auto_inc);
@@ -5525,14 +5543,14 @@ ha_innobase::update_row(
if (auto_inc <= col_max_value && auto_inc != 0) {
ulonglong need;
ulonglong offset;
ulonglong increment;
offset = prebuilt->autoinc_offset;
need = prebuilt->autoinc_increment;
increment = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
auto_inc, need, offset, col_max_value);
auto_inc, 1, increment, offset, col_max_value);
error = innobase_set_max_autoinc(auto_inc);
}
@@ -10145,16 +10163,15 @@ ha_innobase::get_auto_increment(
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
ulonglong current;
ulonglong next_value;
current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
current, need, offset, col_max_value);
current, *nb_reserved_values, increment, offset,
col_max_value);
prebuilt->autoinc_last_value = next_value;

View File

@@ -64,15 +64,14 @@ These are low-level functions
#define BUF_LRU_FREE_SEARCH_LEN(b) (5 + 2 * BUF_READ_AHEAD_AREA(b))
/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. A PROBLEM: if readahead is being started,
what guarantees that it will not try to read in pages after this operation has
completed? */
Removes all pages belonging to a given tablespace. */
UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
buf_LRU_flush_or_remove_pages(
/*==========================*/
ulint id); /*!< in: space id */
ulint id, /*!< in: space id */
enum buf_remove_t buf_remove);/*!< in: remove or flush
strategy */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */

View File

@@ -63,6 +63,15 @@ enum buf_io_fix {
the flush_list */
};
/** Algorithm to remove the pages for a tablespace from the buffer pool.
@See buf_LRU_flush_or_remove_pages(). */
enum buf_remove_t {
BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
pool, don't write or sync to disk */
BUF_REMOVE_FLUSH_NO_WRITE /*!< Remove only, from the flush list,
don't write or sync to disk */
};
/** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
/* @{ */
#define BUF_BUDDY_LOW_SHIFT PAGE_ZIP_MIN_SIZE_SHIFT

View File

@@ -397,7 +397,9 @@ UNIV_INTERN
ibool
fil_delete_tablespace(
/*==================*/
ulint id); /*!< in: space id */
ulint id, /*!< in: space id */
ibool evict_all); /*!< in: TRUE if we want all pages
evicted from LRU. */
#ifndef UNIV_HOTBACKUP
/*******************************************************************//**
Discards a single-table tablespace. The tablespace must be cached in the

View File

@@ -143,9 +143,9 @@ struct trx_purge_struct{
obtaining an s-latch here. */
read_view_t* view; /*!< The purge will not remove undo logs
which are >= this view (purge view) */
ulint n_pages_handled;/*!< Approximate number of undo log
ulonglong n_pages_handled;/*!< Approximate number of undo log
pages processed in purge */
ulint handle_limit; /*!< Target of how many pages to get
ulonglong handle_limit; /*!< Target of how many pages to get
processed in the current purge */
/*------------------------------*/
/* The following two fields form the 'purge pointer' which advances

View File

@@ -1999,7 +1999,8 @@ err_exit:
case DB_TOO_MANY_CONCURRENT_TRXS:
/* We already have .ibd file here. it should be deleted. */
if (table->space && !fil_delete_tablespace(table->space)) {
if (table->space && !fil_delete_tablespace(table->space,
FALSE)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: not able to"
@@ -3438,7 +3439,7 @@ check_next_foreign:
"InnoDB: of table ");
ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, ".\n");
} else if (!fil_delete_tablespace(space_id)) {
} else if (!fil_delete_tablespace(space_id, FALSE)) {
fprintf(stderr,
"InnoDB: We removed now the InnoDB"
" internal data dictionary entry\n"

View File

@@ -1202,7 +1202,7 @@ trx_purge(
(ulong) purge_sys->n_pages_handled);
}
return(purge_sys->n_pages_handled - old_pages_handled);
return((ulint) (purge_sys->n_pages_handled - old_pages_handled));
}
/******************************************************************//**

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -801,6 +801,22 @@ void destroy_thread(PFS_thread *pfs)
pfs->m_lock.allocated_to_free();
}
/**
Get the hash pins for @filename_hash.
@param thread The running thread.
@returns The LF_HASH pins for the thread.
*/
LF_PINS* get_filename_hash_pins(PFS_thread *thread)
{
if (unlikely(thread->m_filename_hash_pins == NULL))
{
if (! filename_hash_inited)
return NULL;
thread->m_filename_hash_pins= lf_hash_get_pins(&filename_hash);
}
return thread->m_filename_hash_pins;
}
/**
Find or create instrumentation for a file instance by file name.
@param thread the executing instrumented thread
@@ -816,23 +832,13 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
PFS_file *pfs;
PFS_scan scan;
if (! filename_hash_inited)
LF_PINS *pins= get_filename_hash_pins(thread);
if (unlikely(pins == NULL))
{
/* File instrumentation can be turned off. */
file_lost++;
return NULL;
}
if (unlikely(thread->m_filename_hash_pins == NULL))
{
thread->m_filename_hash_pins= lf_hash_get_pins(&filename_hash);
if (unlikely(thread->m_filename_hash_pins == NULL))
{
file_lost++;
return NULL;
}
}
char safe_buffer[FN_REFLEN];
const char *safe_filename;
@@ -904,7 +910,7 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
/* Append the unresolved file name to the resolved path */
char *ptr= buffer + strlen(buffer);
char *buf_end= &buffer[sizeof(buffer)-1];
if (buf_end > ptr)
if ((buf_end > ptr) && (*(ptr-1) != FN_LIBCHAR))
*ptr++= FN_LIBCHAR;
if (buf_end > ptr)
strncpy(ptr, safe_filename + dirlen, buf_end - ptr);
@@ -918,16 +924,18 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
const uint retry_max= 3;
search:
entry= reinterpret_cast<PFS_file**>
(lf_hash_search(&filename_hash, thread->m_filename_hash_pins,
(lf_hash_search(&filename_hash, pins,
normalized_filename, normalized_length));
if (entry && (entry != MY_ERRPTR))
{
pfs= *entry;
pfs->m_file_stat.m_open_count++;
lf_hash_search_unpin(thread->m_filename_hash_pins);
lf_hash_search_unpin(pins);
return pfs;
}
lf_hash_search_unpin(pins);
/* filename is not constant, just using it for noise on create */
uint random= randomized_index(filename, file_max);
@@ -954,7 +962,7 @@ search:
reset_single_stat_link(&pfs->m_wait_stat);
int res;
res= lf_hash_insert(&filename_hash, thread->m_filename_hash_pins,
res= lf_hash_insert(&filename_hash, pins,
&pfs);
if (likely(res == 0))
{
@@ -1006,9 +1014,12 @@ void release_file(PFS_file *pfs)
void destroy_file(PFS_thread *thread, PFS_file *pfs)
{
DBUG_ASSERT(thread != NULL);
DBUG_ASSERT(thread->m_filename_hash_pins != NULL);
DBUG_ASSERT(pfs != NULL);
lf_hash_delete(&filename_hash, thread->m_filename_hash_pins,
LF_PINS *pins= get_filename_hash_pins(thread);
DBUG_ASSERT(pins != NULL);
lf_hash_delete(&filename_hash, pins,
pfs->m_filename, pfs->m_filename_length);
pfs->m_lock.allocated_to_free();
}

View File

@@ -70,7 +70,14 @@ IF(UNIX)
INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
CONFIGURE_FILE(MySQL-shared-compat.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/MySQL-shared-compat.spec @ONLY)
CONFIGURE_FILE(mysql.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/mysql.spec @ONLY)
CONFIGURE_FILE(mysql.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/mysql.${VERSION}.spec @ONLY)
SET(SPECFILENAME "mysql.${VERSION}.spec")
IF("${VERSION}" MATCHES "-ndb-")
STRING(REGEX REPLACE "^.*-ndb-" "" NDBVERSION "${VERSION}")
SET(SPECFILENAME "mysql-cluster-${NDBVERSION}.spec")
ENDIF()
CONFIGURE_FILE(mysql.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/${SPECFILENAME} @ONLY)
CONFIGURE_FILE(MySQL-shared-compat.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/MySQL-shared-compat.spec @ONLY)
SET(bindir ${prefix}/${INSTALL_BINDIR})