1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge branch '10.11' into 11.2

This commit is contained in:
Oleksandr Byelkin
2024-08-21 07:58:46 +02:00
85 changed files with 2875 additions and 292 deletions

63
CREDITS
View File

@@ -1,20 +1,48 @@
MariaDB is brought to you by the MariaDB Foundation, a non profit MariaDB is brought to you by the MariaDB Foundation, a non profit
organization registered in the USA. organization registered in the USA.
The current main sponsors of the MariaDB Foundation are: As of August 2024, the main sponsors of the MariaDB Foundation are:
Alibaba Cloud https://www.alibabacloud.com/ (2017) Amazon https://amazon.com
Intel https://www.intel.com (2022) Acronis https://www.acronis.com
MariaDB Corporation https://www.mariadb.com (2013) Alibaba Cloud https://www.alibabacloud.com
Microsoft https://microsoft.com/ (2017) C>onstructor https://constructor.org
ServiceNow https://servicenow.com (2019) Development Bank of Singapore https://www.dbs.com
SIT https://sit.org (2022) Intel https://www.intel.com
Tencent Cloud https://cloud.tencent.com (2017) MariaDB plc https://www.mariadb.com
Development Bank of Singapore https://dbs.com (2016) ServiceNow https://servicenow.com
IBM https://www.ibm.com (2017) WebPros https://webpros.com
Automattic https://automattic.com (2019) IBM https://www.ibm.com
Galera Cluster https://galeracluster.com (2020) IONOS https://www.ionos.com
Percona https://www.percona.com (2018) Automattic https://automattic.com
SkySQL https://skysql.com
team.blue https://team.blue
Tencent Cloud https://cloud.tencent.com
Wikimedia Foundation https://www.wikimediafoundation.org
Cyber Leo https://cyberleo.com
Hetzner https://www.hetzner.com
Rumahweb https://www.rumahweb.com
Tasjeel.ae https://www.tasjeel.ae
Galera Cluster https://galeracluster.com
Percona https://www.percona.com
Vettabase https://vettabase.com
Previous sponsors include:
Booking.com
Jelastic.com
Microsoft
Nexedi
Open Query
Planeetta Web Hosting
SpringbokSQL
Tencent Games
Tencent Game DBA
Tencent TDSQL
Verkkokauppa
Virtuozzo
Visma
Webyog
For a full list of sponsors, see For a full list of sponsors, see
https://mariadb.org/about/#sponsors https://mariadb.org/about/#sponsors
@@ -27,7 +55,7 @@ For all corporate sponsorships please contact the
MariaDB Foundation Board via foundation@mariadb.org. MariaDB Foundation Board via foundation@mariadb.org.
The MariaDB Foundation is responsible for the MariaDB source The MariaDB Foundation is responsible for the MariaDB source
repository, the official MariaDB binaries and http://mariadb.org. repository, the official MariaDB binaries and https://mariadb.org.
The MariaDB Foundation also provides, among other things, the The MariaDB Foundation also provides, among other things, the
following services to the MariaDB community: following services to the MariaDB community:
@@ -37,8 +65,8 @@ following services to the MariaDB community:
- Merging MySQL patches into MariaDB - Merging MySQL patches into MariaDB
- Bug fixing in MariaDB (for bugs that affects a large part of the community) - Bug fixing in MariaDB (for bugs that affects a large part of the community)
- Building the official MariaDB binaries - Building the official MariaDB binaries
- Maintaining http://mariadb.org - Maintaining https://mariadb.org
- Documenting MariaDB in the MariaDB Knowledge Base http://mariadb.com/kb - Documenting MariaDB in the MariaDB Knowledge Base https://mariadb.com/kb
To be able to do the above we need help from corporations and individuals! To be able to do the above we need help from corporations and individuals!
@@ -49,8 +77,5 @@ go to https://mariadb.org/donate/
You can get a list of all the main authors of MariaDB / MySQL by running You can get a list of all the main authors of MariaDB / MySQL by running
SHOW AUTHORS; SHOW AUTHORS;
You can get a list sponsors and contributors by running
SHOW CONTRIBUTORS;
You can read more about the MariaDB Foundation at: You can read more about the MariaDB Foundation at:
https://mariadb.org/about/ https://mariadb.org/about/

View File

@@ -243,7 +243,6 @@ get_one_option(const struct my_option *opt, const char *argument,
#ifdef _WIN32 #ifdef _WIN32
case 'W': case 'W':
opt_protocol = MYSQL_PROTOCOL_PIPE; opt_protocol = MYSQL_PROTOCOL_PIPE;
opt_local_file=1;
break; break;
#endif #endif
case OPT_MYSQL_PROTOCOL: case OPT_MYSQL_PROTOCOL:

View File

@@ -247,9 +247,9 @@ SETA(CPACK_RPM_server_PACKAGE_REQUIRES
IF(WITH_WSREP) IF(WITH_WSREP)
SETA(CPACK_RPM_server_PACKAGE_REQUIRES SETA(CPACK_RPM_server_PACKAGE_REQUIRES
"galera-4" "rsync" "lsof" "grep" "gawk" "iproute" "galera-4" "rsync" "grep" "gawk" "iproute"
"coreutils" "findutils" "tar") "coreutils" "findutils" "tar")
SETA(CPACK_RPM_server_PACKAGE_RECOMMENDS "pv") SETA(CPACK_RPM_server_PACKAGE_RECOMMENDS "lsof" "pv")
ENDIF() ENDIF()
SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh) SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh)

View File

@@ -8,15 +8,17 @@ SET(CONC_WITH_SIGNCODE ${SIGNCODE})
SET(SIGN_OPTIONS ${SIGNTOOL_PARAMETERS}) SET(SIGN_OPTIONS ${SIGNTOOL_PARAMETERS})
SET(CONC_WITH_EXTERNAL_ZLIB ON) SET(CONC_WITH_EXTERNAL_ZLIB ON)
IF(SSL_DEFINES MATCHES "WOLFSSL") IF(NOT CONC_WITH_SSL)
IF(WIN32) IF(SSL_DEFINES MATCHES "WOLFSSL")
SET(CONC_WITH_SSL "SCHANNEL") IF(WIN32)
SET(CONC_WITH_SSL "SCHANNEL")
ELSE()
SET(CONC_WITH_SSL "GNUTLS") # that's what debian wants, right?
ENDIF()
ELSE() ELSE()
SET(CONC_WITH_SSL "GNUTLS") # that's what debian wants, right? SET(CONC_WITH_SSL "OPENSSL")
SET(OPENSSL_FOUND TRUE)
ENDIF() ENDIF()
ELSE()
SET(CONC_WITH_SSL "OPENSSL")
SET(OPENSSL_FOUND TRUE)
ENDIF() ENDIF()
SET(CONC_WITH_CURL OFF) SET(CONC_WITH_CURL OFF)

View File

@@ -2013,7 +2013,7 @@ struct my_option xb_server_options[] =
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
{"check-privileges", OPT_XTRA_CHECK_PRIVILEGES, "Check database user " {"check-privileges", OPT_XTRA_CHECK_PRIVILEGES, "Check database user "
"privileges fro the backup user", "privileges for the backup user",
&opt_check_privileges, &opt_check_privileges, &opt_check_privileges, &opt_check_privileges,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },

View File

@@ -199,7 +199,8 @@ static my_bool print_win_error_msg(DWORD error, my_bool verbose)
char *s; char *s;
if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, (char *)&s, 0, NULL, error, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(char *) &s, 0,
NULL)) NULL))
{ {
char* end = s + strlen(s) - 1; char* end = s + strlen(s) - 1;

View File

@@ -255,9 +255,20 @@ static inline void safe_strcpy(char *dst, size_t dst_size, const char *src)
* *
* 2) IF there is no 0 byte in the first dst_size bytes of src, strncpy will * 2) IF there is no 0 byte in the first dst_size bytes of src, strncpy will
* copy dst_size bytes, and the final byte won't be 0. * copy dst_size bytes, and the final byte won't be 0.
*
* In GCC 8+, the `-Wstringop-truncation` warning may object to strncpy()
* being used in this way, so we need to disable this warning for this
* single statement.
*/ */
#if defined __GNUC__ && __GNUC__ >= 8
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
strncpy(dst, src, dst_size); strncpy(dst, src, dst_size);
#if defined __GNUC__ && __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
dst[dst_size - 1]= 0; dst[dst_size - 1]= 0;
} }

View File

@@ -0,0 +1,4 @@
if (`select version() like '%valgrind%' || version() like '%asan%'`)
{
skip Does not run with binaries built with valgrind or asan;
}

View File

@@ -1,18 +1,42 @@
SHOW CONTRIBUTORS; SHOW CONTRIBUTORS;
Name Location Comment Name Location Comment
Amazon https://www.amazon.com/ Diamond Sponsor of the MariaDB Foundation
Acronis https://www.acronis.com/ Platinum Sponsor of the MariaDB Foundation
Alibaba Cloud https://www.alibabacloud.com/ Platinum Sponsor of the MariaDB Foundation Alibaba Cloud https://www.alibabacloud.com/ Platinum Sponsor of the MariaDB Foundation
Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundation C<onstructor https://www.constructor.org/ Platinum Sponsor of the MariaDB Foundation
Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation Development Bank of Singapore https://www.dbs.com/ Platinum Sponsor of the MariaDB Foundation
MariaDB Corporation https://mariadb.com Founding member, Platinum Sponsor of the MariaDB Foundation Intel https://www.intel.com/ Platinum Sponsor of the MariaDB Foundation
ServiceNow https://servicenow.com Platinum Sponsor of the MariaDB Foundation MariaDB plc https://mariadb.com/ Founding member, Platinum Sponsor of the MariaDB Foundation
Intel https://www.intel.com Platinum Sponsor of the MariaDB Foundation ServiceNow https://servicenow.com/ Platinum Sponsor of the MariaDB Foundation
SIT https://sit.org Platinum Sponsor of the MariaDB Foundation WebPros https://webpros.com/ Platinum Sponsor of the MariaDB Foundation
Visma https://visma.com Gold Sponsor of the MariaDB Foundation IBM https://www.ibm.com/ Gold Sponsor of the MariaDB Foundation
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation IONOS https://www.ionos.com/ Gold Sponsor of the MariaDB Foundation
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation Automattic https://automattic.com/ Silver Sponsor of the MariaDB Foundation
Automattic https://automattic.com Silver Sponsor of the MariaDB Foundation SkySQL https://skysql.com/ Silver Sponsor of the MariaDB Foundation
team.blue https://team.blue/ Silver Sponsor of the MariaDB Foundation
Tencent Cloud https://cloud.tencent.com/ Silver Sponsor of the MariaDB Foundation
Wikimedia Foundation https://www.wikimediafoundation.org/ Silver Sponsor of the MariaDB Foundation
Cyber Leo https://cyberleo.com/ Bronze Sponsor of the MariaDB Foundation
Hetzner https://www.hetzner.com/ Bronze Sponsor of the MariaDB Foundation
Rumahweb https://rumahweb.com/ Bronze Sponsor of the MariaDB Foundation
Tasjeel.ae https://tasjeel.ae/ Bronze Sponsor of the MariaDB Foundation
Galera Cluster https://galeracluster.com/ Sponsor of the MariaDB Foundation
Percona https://www.percona.com/ Sponsor of the MariaDB Foundation Percona https://www.percona.com/ Sponsor of the MariaDB Foundation
Galera Cluster https://galeracluster.com Sponsor of the MariaDB Foundation Vettabase https://vettabase.com/ Technology partner of the MariaDB Foundation
Booking.com Previous Sponsor of the MariaDB Foundation
Jelastic.com Previous Sponsor of the MariaDB Foundation
Microsoft Previous Sponsor of the MariaDB Foundation
Nexedi Previous Sponsor of the MariaDB Foundation
Open Query Previous Sponsor of the MariaDB Foundation
Planeetta Web Hosting Previous Sponsor of the MariaDB Foundation
SpringbokSQL Previous Sponsor of the MariaDB Foundation
Tencent Games Previous Sponsor of the MariaDB Foundation
Tencent Game DBA Previous Sponsor of the MariaDB Foundation
Tencent TDSQL Previous Sponsor of the MariaDB Foundation
Verkkokauppa Previous Sponsor of the MariaDB Foundation
Virtuozzo Previous Sponsor of the MariaDB Foundation
Visma Previous Sponsor of the MariaDB Foundation
Webyog Previous Sponsor of the MariaDB Foundation
Google USA Sponsoring encryption, parallel replication and GTID Google USA Sponsoring encryption, parallel replication and GTID
Facebook USA Sponsoring non-blocking API, LIMIT ROWS EXAMINED etc Facebook USA Sponsoring non-blocking API, LIMIT ROWS EXAMINED etc
Ronald Bradford Brisbane, Australia EFF contribution for UC2006 Auction Ronald Bradford Brisbane, Australia EFF contribution for UC2006 Auction

View File

@@ -4225,6 +4225,129 @@ SELECT 1 COLLATE utf8mb4_bin;
1 1
SELECT 1 COLLATE latin1_swedish_ci; SELECT 1 COLLATE latin1_swedish_ci;
ERROR 42000: COLLATION 'latin1_swedish_ci' is not valid for CHARACTER SET 'utf8mb4' ERROR 42000: COLLATION 'latin1_swedish_ci' is not valid for CHARACTER SET 'utf8mb4'
# MDEV-34376 Wrong data types when mixing an utf8 *TEXT column and a short binary
#
CREATE TABLE t1 (
c_tinytext tinytext,
c_text text,
c_mediumtext mediumtext,
c_longtext longtext
) CHARACTER SET utf8mb4;
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM v1;
# Using table fields
CREATE TABLE t2 AS SELECT
COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary,
COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary,
COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary,
COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`mix_tinytext_binary` tinyblob DEFAULT NULL,
`mix_text_binary` blob DEFAULT NULL,
`mix_mediumtext_binary` mediumblob DEFAULT NULL,
`mix_longtext_binary` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
c_tinytext AS mix_tinytext_binary,
c_text AS mix_text_binary,
c_mediumtext AS mix_mediumtext_binary,
c_longtext AS mix_longtext_binary
FROM t1
UNION SELECT
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY);
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`mix_tinytext_binary` tinyblob DEFAULT NULL,
`mix_text_binary` blob DEFAULT NULL,
`mix_mediumtext_binary` mediumblob DEFAULT NULL,
`mix_longtext_binary` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2;
# Using view fields
CREATE TABLE t2 AS SELECT
COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary,
COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary,
COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary,
COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary
FROM v1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`mix_tinytext_binary` tinyblob DEFAULT NULL,
`mix_text_binary` blob DEFAULT NULL,
`mix_mediumtext_binary` mediumblob DEFAULT NULL,
`mix_longtext_binary` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
c_tinytext AS mix_tinytext_binary,
c_text AS mix_text_binary,
c_mediumtext AS mix_mediumtext_binary,
c_longtext AS mix_longtext_binary
FROM v1
UNION SELECT
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY);
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`mix_tinytext_binary` tinyblob DEFAULT NULL,
`mix_text_binary` blob DEFAULT NULL,
`mix_mediumtext_binary` mediumblob DEFAULT NULL,
`mix_longtext_binary` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2;
# Using view on view fields
CREATE TABLE t2 AS SELECT
COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary,
COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary,
COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary,
COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary
FROM v2;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`mix_tinytext_binary` tinyblob DEFAULT NULL,
`mix_text_binary` blob DEFAULT NULL,
`mix_mediumtext_binary` mediumblob DEFAULT NULL,
`mix_longtext_binary` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
c_tinytext AS mix_tinytext_binary,
c_text AS mix_text_binary,
c_mediumtext AS mix_mediumtext_binary,
c_longtext AS mix_longtext_binary
FROM v2
UNION SELECT
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY);
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`mix_tinytext_binary` tinyblob DEFAULT NULL,
`mix_text_binary` blob DEFAULT NULL,
`mix_mediumtext_binary` mediumblob DEFAULT NULL,
`mix_longtext_binary` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t2;
DROP VIEW v2, v1;
DROP TABLE t1;
#
# End of 10.5 tests
#
# #
# MDEV-10865 COLLATE keyword doesn't work in PREPARE query # MDEV-10865 COLLATE keyword doesn't work in PREPARE query
# #

View File

@@ -2109,6 +2109,102 @@ SELECT 1 COLLATE utf8mb4_bin;
--error ER_COLLATION_CHARSET_MISMATCH --error ER_COLLATION_CHARSET_MISMATCH
SELECT 1 COLLATE latin1_swedish_ci; SELECT 1 COLLATE latin1_swedish_ci;
--echo # MDEV-34376 Wrong data types when mixing an utf8 *TEXT column and a short binary
--echo #
CREATE TABLE t1 (
c_tinytext tinytext,
c_text text,
c_mediumtext mediumtext,
c_longtext longtext
) CHARACTER SET utf8mb4;
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM v1;
--echo # Using table fields
CREATE TABLE t2 AS SELECT
COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary,
COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary,
COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary,
COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
c_tinytext AS mix_tinytext_binary,
c_text AS mix_text_binary,
c_mediumtext AS mix_mediumtext_binary,
c_longtext AS mix_longtext_binary
FROM t1
UNION SELECT
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY);
SHOW CREATE TABLE t2;
DROP TABLE t2;
--echo # Using view fields
CREATE TABLE t2 AS SELECT
COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary,
COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary,
COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary,
COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary
FROM v1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
c_tinytext AS mix_tinytext_binary,
c_text AS mix_text_binary,
c_mediumtext AS mix_mediumtext_binary,
c_longtext AS mix_longtext_binary
FROM v1
UNION SELECT
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY);
SHOW CREATE TABLE t2;
DROP TABLE t2;
--echo # Using view on view fields
CREATE TABLE t2 AS SELECT
COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary,
COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary,
COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary,
COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary
FROM v2;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
c_tinytext AS mix_tinytext_binary,
c_text AS mix_text_binary,
c_mediumtext AS mix_mediumtext_binary,
c_longtext AS mix_longtext_binary
FROM v2
UNION SELECT
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY),
CAST('binary data' AS BINARY);
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP VIEW v2, v1;
DROP TABLE t1;
--echo #
--echo # End of 10.5 tests
--echo #
--echo # --echo #
--echo # MDEV-10865 COLLATE keyword doesn't work in PREPARE query --echo # MDEV-10865 COLLATE keyword doesn't work in PREPARE query
--echo # --echo #

View File

@@ -957,3 +957,47 @@ DROP TABLE t;
# #
# End of 10.4 tests # End of 10.4 tests
# #
#
# MDEV-23983: Crash caused by query containing constant having clause
#
CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b TEXT, c INT);
INSERT INTO t1 VALUES (3, 7, 'b', 1), (4, 7, 'b', 1);
SELECT * FROM t1
WHERE t1.id = 3
GROUP BY t1.a
HAVING t1.b = 'b' and t1.c = 1;
id a b c
3 7 b 1
SELECT * FROM t1
WHERE t1.id = 3
GROUP BY t1.a
HAVING t1.b = 'b' and t1.c = 2;
id a b c
explain SELECT * FROM t1
WHERE t1.id = 3
GROUP BY t1.a
HAVING t1.b = 'b' and t1.c = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
CREATE TABLE t2 (id INT, b TEXT, c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3, 'b', 1);
SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a
GROUP BY t2.id
HAVING t2.b = 'b' and t2.c = 1;
id b c
3 b 1
SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a
GROUP BY t2.id
HAVING t2.b = 'b' and t2.c = 2;
id b c
explain SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a
GROUP BY t2.id
HAVING t2.b = 'b' and t2.c = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
DROP TABLE t1,t2;
#
# End of 10.5 tests
#

View File

@@ -1011,3 +1011,48 @@ DROP TABLE t;
--echo # --echo #
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #
--echo #
--echo # MDEV-23983: Crash caused by query containing constant having clause
--echo #
CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b TEXT, c INT);
INSERT INTO t1 VALUES (3, 7, 'b', 1), (4, 7, 'b', 1);
SELECT * FROM t1
WHERE t1.id = 3
GROUP BY t1.a
HAVING t1.b = 'b' and t1.c = 1;
let $q=
SELECT * FROM t1
WHERE t1.id = 3
GROUP BY t1.a
HAVING t1.b = 'b' and t1.c = 2;
eval $q;
eval explain $q;
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
CREATE TABLE t2 (id INT, b TEXT, c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3, 'b', 1);
SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a
GROUP BY t2.id
HAVING t2.b = 'b' and t2.c = 1;
let $q=
SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a
GROUP BY t2.id
HAVING t2.b = 'b' and t2.c = 2;
eval $q;
eval explain $q;
DROP TABLE t1,t2;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@@ -14,3 +14,33 @@ SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5;
c c c c
DROP TABLE t1, t2; DROP TABLE t1, t2;
SET optimizer_switch=default; SET optimizer_switch=default;
#
# MDEV-34683 Types mismatch when cloning items causes debug assertion
#
CREATE TABLE t1 (a date);
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
SELECT a FROM v1 WHERE a IN ('a', 'b', 'c');
a
CREATE VIEW v2 AS SELECT '' as a;
SELECT * FROM v2 WHERE a='' AND CASE '' WHEN '' THEN '' ELSE a END='';
a
DROP TABLE t1;
DROP VIEW v1, v2;
#
# MDEV-34771: Types mismatch when cloning items causes debug assertion
#
CREATE VIEW t AS SELECT 1 AS a;
SELECT * FROM t WHERE a=b'';
a
drop view t;
#
# MDEV-34776: Assertion failure in Item_string::do_build_clone
#
CREATE VIEW v AS SELECT version() AS f;
SELECT * FROM v WHERE f = '10.5.20';
f
drop view v;
#
# End of 10.5 tests
#

View File

@@ -13,3 +13,39 @@ SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5;
DROP TABLE t1, t2; DROP TABLE t1, t2;
SET optimizer_switch=default; SET optimizer_switch=default;
--echo #
--echo # MDEV-34683 Types mismatch when cloning items causes debug assertion
--echo #
CREATE TABLE t1 (a date);
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
--disable_warnings
SELECT a FROM v1 WHERE a IN ('a', 'b', 'c');
--enable_warnings
CREATE VIEW v2 AS SELECT '' as a;
SELECT * FROM v2 WHERE a='' AND CASE '' WHEN '' THEN '' ELSE a END='';
DROP TABLE t1;
DROP VIEW v1, v2;
--echo #
--echo # MDEV-34771: Types mismatch when cloning items causes debug assertion
--echo #
CREATE VIEW t AS SELECT 1 AS a;
SELECT * FROM t WHERE a=b'';
drop view t;
--echo #
--echo # MDEV-34776: Assertion failure in Item_string::do_build_clone
--echo #
CREATE VIEW v AS SELECT version() AS f;
SELECT * FROM v WHERE f = '10.5.20';
drop view v;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@@ -1,5 +1,5 @@
--source include/not_msan.inc --source include/not_msan.inc
--source include/not_valgrind.inc --source include/not_valgrind_build.inc
--echo # MDEV-20699 do not cache SP in SHOW CREATE --echo # MDEV-20699 do not cache SP in SHOW CREATE
--echo # Warmup round, this might allocate some memory for session variable --echo # Warmup round, this might allocate some memory for session variable

View File

@@ -5952,7 +5952,9 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
--enable_ps2_protocol --enable_ps2_protocol
--echo # The following shows that t2 was indeed scanned with a full scan. --echo # The following shows that t2 was indeed scanned with a full scan.
--sorted_result
show table_statistics; show table_statistics;
--sorted_result
show index_statistics; show index_statistics;
set global userstat=@tmp_mdev410; set global userstat=@tmp_mdev410;

View File

@@ -20,5 +20,3 @@ galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATIN
galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert()
galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback()
galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback()
galera_sst_mysqldump_with_key : MDEV-32782 galera_sst_mysqldump_with_key test failed
galera_var_ignore_apply_errors : MENT-1997 galera_var_ignore_apply_errors test freezes

View File

@@ -0,0 +1,88 @@
connection node_2;
connection node_1;
#
# Case 1: test with binlog_format ROW
#
connection node_1;
SET @@binlog_format=ROW;
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
connection node_2;
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
DROP TABLE t1,t2;
#
# Case 2: test with binlog_format MIXED
#
connection node_1;
SET @@binlog_format=MIXED;
Warnings:
Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
Warnings:
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
Warnings:
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
connection node_2;
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
DROP TABLE t1,t2;
#
# Case 3: test with binlog_format STATEMENT
#
connection node_1;
SET @@binlog_format=STATEMENT;
Warnings:
Warning 1105 MariaDB Galera and flashback do not support binlog format: STATEMENT
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
Warnings:
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
Warnings:
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
connection node_2;
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
DROP TABLE t1,t2;
connection node_1;

View File

@@ -0,0 +1,100 @@
connection node_2;
connection node_1;
create table t1(id serial, val varchar(100)) engine=myisam;
insert into t1 values(null, 'a');
insert into t1 values(null, 'b');
insert into t1 select null, 'c';
insert into t1 select null, 'd' from t1;
select * from t1;
id val
1 a
3 b
5 c
7 d
9 d
11 d
create table t2(id serial, val varchar(100)) engine=aria;
insert into t2 values(null, 'a');
insert into t2 values(null, 'b');
insert into t2 select null, 'c';
insert into t2 select null, 'd' from t2;
select * from t2;
id val
1 a
3 b
5 c
7 d
9 d
11 d
create table t3(id serial, val varchar(100)) engine=innodb;
insert into t3 values(null, 'a');
insert into t3 values(null, 'b');
insert into t3 select null, 'c';
insert into t3 select null, 'd' from t3;
select * from t3;
id val
1 a
3 b
5 c
7 d
9 d
11 d
set global wsrep_mode=REPLICATE_MYISAM;
create table t4(id serial, val varchar(100)) engine=myisam;
insert into t4 values(null, 'a');
insert into t4 values(null, 'b');
insert into t4 select null, 'c';
insert into t4 select null, 'd' from t4;
select * from t4;
id val
1 a
2 b
3 c
4 d
5 d
6 d
create table t5(id serial, val varchar(100)) engine=myisam;
insert into t5 values(null, 'a');
insert into t5 values(null, 'b');
insert into t5 select null, 'c';
insert into t5 select null, 'd' from t5;
select * from t2;
id val
1 a
3 b
5 c
7 d
9 d
11 d
connection node_2;
select * from t1;
id val
select * from t2;
id val
select * from t3;
id val
1 a
3 b
5 c
7 d
9 d
11 d
select * from t4;
id val
1 a
2 b
3 c
4 d
5 d
6 d
select * from t5;
id val
1 a
2 b
3 c
4 d
5 d
6 d
connection node_1;
drop table t1,t2,t3,t4,t5;
set global wsrep_mode=default;

View File

@@ -7,27 +7,61 @@ SET GLOBAL wsrep_on = OFF;
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
DROP TABLE t1; DROP TABLE t1;
connection node_2;
SHOW TABLES;
Tables_in_test
connection node_1;
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE SCHEMA s1; CREATE SCHEMA s1;
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
DROP SCHEMA s1; DROP SCHEMA s1;
connection node_2;
SHOW SCHEMAS;
Database
information_schema
mtr
mysql
performance_schema
sys
test
connection node_1;
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE INDEX idx1 ON t1 (f1); CREATE INDEX idx1 ON t1 (f1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
DROP INDEX idx1 ON t1; DROP INDEX idx1 ON t1;
connection node_2;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1; DROP TABLE t1;
connection node_1;
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE INDEX idx1 ON t1 (f1); CREATE INDEX idx1 ON t1 (f1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
ALTER TABLE t1 DROP INDEX idx1; ALTER TABLE t1 DROP INDEX idx1;
connection node_2;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1; DROP TABLE t1;
connection node_1;
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
ALTER TABLE t1 ADD COLUMN f2 INTEGER; ALTER TABLE t1 ADD COLUMN f2 INTEGER;
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
ALTER TABLE t1 DROP COLUMN f2; ALTER TABLE t1 DROP COLUMN f2;
connection node_2;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1; DROP TABLE t1;
connection node_2; connection node_2;
SET GLOBAL wsrep_ignore_apply_errors = 2; SET GLOBAL wsrep_ignore_apply_errors = 2;
@@ -37,12 +71,11 @@ SET GLOBAL wsrep_on = OFF;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 1;
connection node_1; SELECT COUNT(*) AS expect_0 FROM t1;
SELECT COUNT(*) as expect_0 FROM t1;
expect_0 expect_0
0 0
connection node_2; connection node_2;
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) AS expect_0 FROM t1;
expect_0 expect_0
0 0
DROP TABLE t1; DROP TABLE t1;
@@ -57,12 +90,11 @@ INSERT INTO t1 VALUES (3);
DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 1;
DELETE FROM t1 WHERE f1 = 2; DELETE FROM t1 WHERE f1 = 2;
COMMIT; COMMIT;
connection node_1; SELECT COUNT(*) AS expect_1 FROM t1;
SELECT COUNT(*) as expect_1 FROM t1;
expect_1 expect_1
1 1
connection node_2; connection node_2;
SELECT COUNT(*) as expect_1 FROM t1; SELECT COUNT(*) AS expect_1 FROM t1;
expect_1 expect_1
1 1
DROP TABLE t1; DROP TABLE t1;
@@ -75,14 +107,14 @@ DELETE FROM t1 WHERE f1 = 3;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
connection node_1; connection node_1;
DELETE FROM t1; DELETE FROM t1;
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) AS expect_0 FROM t1;
expect_0 expect_0
0 0
connection node_2; connection node_2;
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
VARIABLE_VALUE = 'Primary' expect_Primary
1 Primary
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) AS expect_0 FROM t1;
expect_0 expect_0
0 0
DROP TABLE t1; DROP TABLE t1;
@@ -103,14 +135,14 @@ DELETE FROM t1 WHERE f1 = 4;
DELETE FROM t1 WHERE f1 = 5; DELETE FROM t1 WHERE f1 = 5;
COMMIT; COMMIT;
SET AUTOCOMMIT=ON; SET AUTOCOMMIT=ON;
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) AS expect_0 FROM t1;
expect_0 expect_0
0 0
connection node_2; connection node_2;
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
VARIABLE_VALUE = 'Primary' expect_Primary
1 Primary
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) AS expect_0 FROM t1;
expect_0 expect_0
0 0
DROP TABLE t1; DROP TABLE t1;
@@ -126,14 +158,14 @@ DELETE FROM t1 WHERE f1 = 3;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
connection node_1; connection node_1;
DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1;
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) expect_0 FROM t1;
expect_0 expect_0
0 0
connection node_2; connection node_2;
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
VARIABLE_VALUE = 'Primary' VARIABLE_VALUE = 'Primary'
1 1
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) expect_0 FROM t1;
expect_0 expect_0
0 0
DROP TABLE t1,t2; DROP TABLE t1,t2;
@@ -148,20 +180,20 @@ DELETE FROM child WHERE parent_id = 2;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
connection node_1; connection node_1;
DELETE FROM parent; DELETE FROM parent;
SELECT COUNT(*) as expect_0 FROM parent; SELECT COUNT(*) AS expect_0 FROM parent;
expect_0 expect_0
0 0
SELECT COUNT(*) as expect_0 FROM child; SELECT COUNT(*) AS expect_0 FROM child;
expect_0 expect_0
0 0
connection node_2; connection node_2;
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
VARIABLE_VALUE = 'Primary' VARIABLE_VALUE = 'Primary'
1 1
SELECT COUNT(*) as expect_0 FROM parent; SELECT COUNT(*) AS expect_0 FROM parent;
expect_0 expect_0
0 0
SELECT COUNT(*) as expect_0 FROM child; SELECT COUNT(*) AS expect_0 FROM child;
expect_0 expect_0
0 0
DROP TABLE child, parent; DROP TABLE child, parent;
@@ -175,8 +207,10 @@ connection node_1;
CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); CREATE TABLE t1 (f1 INTEGER, f2 INTEGER);
DROP TABLE t1; DROP TABLE t1;
connection node_2; connection node_2;
SELECT * FROM t1;
ERROR 42S02: Table 'test.t1' doesn't exist
SET GLOBAL wsrep_ignore_apply_errors = 7; SET GLOBAL wsrep_ignore_apply_errors = 7;
CALL mtr.add_suppression("Can't find record in 't.*'"); CALL mtr.add_suppression("Can't find record in ");
CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event"); CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event");
CALL mtr.add_suppression("Slave SQL: Error 'Unknown table 'test\\.t1'' on query\\. Default database: 'test'\\. Query: 'DROP TABLE t1', Error_code: 1051"); CALL mtr.add_suppression("Slave SQL: Error 'Unknown table 'test\\.t1'' on query\\. Default database: 'test'\\. Query: 'DROP TABLE t1', Error_code: 1051");
CALL mtr.add_suppression("Slave SQL: Error 'Can't drop database 's1'; database doesn't exist' on query\\. Default database: 'test'\\. Query: 'DROP SCHEMA s1', Error_code: 1008"); CALL mtr.add_suppression("Slave SQL: Error 'Can't drop database 's1'; database doesn't exist' on query\\. Default database: 'test'\\. Query: 'DROP SCHEMA s1', Error_code: 1008");

View File

@@ -64,6 +64,7 @@ id a
connection node_1; connection node_1;
DROP TABLE t,t2,t3; DROP TABLE t,t2,t3;
# Bigger REPLACE ... AS SELECT test # Bigger REPLACE ... AS SELECT test
SET GLOBAL wsrep_mode=REPLICATE_MYISAM;
CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB; CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB;
CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM; CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM;
CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria; CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria;
@@ -113,7 +114,7 @@ EXPECT_1000
1000 1000
SELECT COUNT(*) AS EXPECT_1000 FROM t3; SELECT COUNT(*) AS EXPECT_1000 FROM t3;
EXPECT_1000 EXPECT_1000
1000 0
SELECT COUNT(*) AS EXPECT_1000 FROM t4; SELECT COUNT(*) AS EXPECT_1000 FROM t4;
EXPECT_1000 EXPECT_1000
1000 1000
@@ -126,9 +127,9 @@ EXPECT_1000
SELECT COUNT(*) AS EXPECT_1000 FROM t7; SELECT COUNT(*) AS EXPECT_1000 FROM t7;
EXPECT_1000 EXPECT_1000
1000 1000
SELECT COUNT(*) AS EXPECT_1000 FROM t8; SELECT COUNT(*) AS EXPECT_0 FROM t8;
EXPECT_1000 EXPECT_0
1000 0
connection node_1; connection node_1;
DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8;
# Bigger INSERT INTO ... SELECT test # Bigger INSERT INTO ... SELECT test
@@ -181,7 +182,7 @@ EXPECT_1000
1000 1000
SELECT COUNT(*) AS EXPECT_1000 FROM t3; SELECT COUNT(*) AS EXPECT_1000 FROM t3;
EXPECT_1000 EXPECT_1000
1000 0
SELECT COUNT(*) AS EXPECT_1000 FROM t4; SELECT COUNT(*) AS EXPECT_1000 FROM t4;
EXPECT_1000 EXPECT_1000
1000 1000
@@ -194,9 +195,9 @@ EXPECT_1000
SELECT COUNT(*) AS EXPECT_1000 FROM t7; SELECT COUNT(*) AS EXPECT_1000 FROM t7;
EXPECT_1000 EXPECT_1000
1000 1000
SELECT COUNT(*) AS EXPECT_1000 FROM t8; SELECT COUNT(*) AS EXPECT_0 FROM t8;
EXPECT_1000 EXPECT_0
1000 0
connection node_1; connection node_1;
DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8;
CREATE TABLE t1(pk int not null primary key) engine=innodb; CREATE TABLE t1(pk int not null primary key) engine=innodb;

View File

@@ -0,0 +1,68 @@
--source include/galera_cluster.inc
--source include/log_bin.inc
--echo #
--echo # Case 1: test with binlog_format ROW
--echo #
--connection node_1
SET @@binlog_format=ROW;
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
#
# Note that this has two rows (1,2) and (1,3) where (1,3) contains duplicate key
# but we requested REPLACE --> ::update_row() is called to update (1,2) --> (1,3)
#
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
SELECT * FROM t1;
SELECT * FROM t2;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
--source include/wait_condition.inc
SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1,t2;
--echo #
--echo # Case 2: test with binlog_format MIXED
--echo #
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
--source include/wait_condition.inc
SET @@binlog_format=MIXED;
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
SELECT * FROM t1;
SELECT * FROM t2;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
--source include/wait_condition.inc
SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1,t2;
--echo #
--echo # Case 3: test with binlog_format STATEMENT
--echo #
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
--source include/wait_condition.inc
SET @@binlog_format=STATEMENT;
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
SELECT * FROM t1;
SELECT * FROM t2;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' OR TABLE_NAME = 't1'
--source include/wait_condition.inc
SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1,t2;
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
--source include/wait_condition.inc

View File

@@ -0,0 +1,53 @@
--source include/galera_cluster.inc
--source include/have_aria.inc
create table t1(id serial, val varchar(100)) engine=myisam;
insert into t1 values(null, 'a');
insert into t1 values(null, 'b');
insert into t1 select null, 'c';
insert into t1 select null, 'd' from t1;
select * from t1;
create table t2(id serial, val varchar(100)) engine=aria;
insert into t2 values(null, 'a');
insert into t2 values(null, 'b');
insert into t2 select null, 'c';
insert into t2 select null, 'd' from t2;
select * from t2;
create table t3(id serial, val varchar(100)) engine=innodb;
insert into t3 values(null, 'a');
insert into t3 values(null, 'b');
insert into t3 select null, 'c';
insert into t3 select null, 'd' from t3;
select * from t3;
set global wsrep_mode=REPLICATE_MYISAM;
create table t4(id serial, val varchar(100)) engine=myisam;
insert into t4 values(null, 'a');
insert into t4 values(null, 'b');
insert into t4 select null, 'c';
insert into t4 select null, 'd' from t4;
select * from t4;
create table t5(id serial, val varchar(100)) engine=myisam;
insert into t5 values(null, 'a');
insert into t5 values(null, 'b');
insert into t5 select null, 'c';
insert into t5 select null, 'd' from t5;
select * from t2;
--connection node_2
select * from t1;
select * from t2;
select * from t3;
select * from t4;
select * from t5;
--connection node_1
drop table t1,t2,t3,t4,t5;
set global wsrep_mode=default;

View File

@@ -3,6 +3,11 @@
# We do not set mysqldump-related SST options here because doing so on startup # We do not set mysqldump-related SST options here because doing so on startup
# causes the first MTR connection to be forefully dropped by Galera, which in turn confuses MTR # causes the first MTR connection to be forefully dropped by Galera, which in turn confuses MTR
[mysqld]
wsrep-debug=1
wsrep-sync_wait=15
loose-galera_sst_mysqldump_with_key=1
[mysqld.1] [mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true'

View File

@@ -6,6 +6,7 @@
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_ssl_communication.inc --source include/have_ssl_communication.inc
--source include/force_restart.inc
--source suite/galera/include/galera_sst_set_mysqldump.inc --source suite/galera/include/galera_sst_set_mysqldump.inc
--let $node_1=node_1 --let $node_1=node_1

View File

@@ -1,7 +1,6 @@
!include ../galera_2nodes.cnf !include ../galera_2nodes.cnf
[mysqld.1] [mysqld]
wsrep_debug=1
[mysqld.2]
wsrep_debug=1 wsrep_debug=1
wsrep_sync_wait=15
loose-galera-var-ignore-apply-errors=1

View File

@@ -2,8 +2,9 @@
# Test option wsrep_ignore_apply_errors # Test option wsrep_ignore_apply_errors
# #
--source include/have_perfschema.inc
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/force_restart.inc
# #
# Ignore reconciling DDL errors on node_2 # Ignore reconciling DDL errors on node_2
@@ -17,41 +18,55 @@ SET GLOBAL wsrep_ignore_apply_errors = 1;
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
DROP TABLE t1; DROP TABLE t1;
--connection node_2
SHOW TABLES;
# Drop schema that does not exist # Drop schema that does not exist
--connection node_1
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE SCHEMA s1; CREATE SCHEMA s1;
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
DROP SCHEMA s1; DROP SCHEMA s1;
--connection node_2
SHOW SCHEMAS;
# Drop index that does not exist using DROP INDEX # Drop index that does not exist using DROP INDEX
--connection node_1
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE INDEX idx1 ON t1 (f1); CREATE INDEX idx1 ON t1 (f1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
DROP INDEX idx1 ON t1; DROP INDEX idx1 ON t1;
--connection node_2
SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
# Drop index that does not exist using ALTER TABLE # Drop index that does not exist using ALTER TABLE
--connection node_1
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE INDEX idx1 ON t1 (f1); CREATE INDEX idx1 ON t1 (f1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
ALTER TABLE t1 DROP INDEX idx1; ALTER TABLE t1 DROP INDEX idx1;
--connection node_2
SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
# Drop column that does not exist # Drop column that does not exist
--connection node_1
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
ALTER TABLE t1 ADD COLUMN f2 INTEGER; ALTER TABLE t1 ADD COLUMN f2 INTEGER;
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
ALTER TABLE t1 DROP COLUMN f2; ALTER TABLE t1 DROP COLUMN f2;
--connection node_2
SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
@@ -68,21 +83,11 @@ CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 1;
SELECT COUNT(*) AS expect_0 FROM t1;
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) as expect_0 FROM t1;
--connection node_2 --connection node_2
--source include/galera_wait_ready.inc SELECT COUNT(*) AS expect_0 FROM t1;
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) as expect_0 FROM t1;
DROP TABLE t1; DROP TABLE t1;
# Delete row that does not exist in a multi statement transaction # Delete row that does not exist in a multi statement transaction
@@ -92,25 +97,15 @@ INSERT INTO t1 VALUES (2);
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
START TRANSACTION; START TRANSACTION;
INSERT INTO t1 VALUES (3); INSERT INTO t1 VALUES (3);
DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 1;
DELETE FROM t1 WHERE f1 = 2; DELETE FROM t1 WHERE f1 = 2;
COMMIT; COMMIT;
SELECT COUNT(*) AS expect_1 FROM t1;
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) as expect_1 FROM t1;
--connection node_2 --connection node_2
--source include/galera_wait_ready.inc SELECT COUNT(*) AS expect_1 FROM t1;
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) as expect_1 FROM t1;
DROP TABLE t1; DROP TABLE t1;
# #
@@ -127,21 +122,16 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
SET SESSION wsrep_on = OFF; SET SESSION wsrep_on = OFF;
DELETE FROM t1 WHERE f1 = 3; DELETE FROM t1 WHERE f1 = 3;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
--source include/galera_wait_ready.inc
--connection node_1 --connection node_1
DELETE FROM t1; DELETE FROM t1;
SELECT COUNT(*) AS expect_0 FROM t1;
SELECT COUNT(*) as expect_0 FROM t1;
--connection node_2 --connection node_2
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--source include/wait_condition.inc
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; --let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT COUNT(*) as expect_0 FROM t1; SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
SELECT COUNT(*) AS expect_0 FROM t1;
DROP TABLE t1; DROP TABLE t1;
# #
@@ -158,10 +148,8 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
SET SESSION wsrep_on = OFF; SET SESSION wsrep_on = OFF;
DELETE FROM t1 WHERE f1 = 3; DELETE FROM t1 WHERE f1 = 3;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
--source include/galera_wait_ready.inc
--connection node_1 --connection node_1
SET AUTOCOMMIT=OFF; SET AUTOCOMMIT=OFF;
START TRANSACTION; START TRANSACTION;
DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 1;
@@ -171,18 +159,13 @@ DELETE FROM t1 WHERE f1 = 4;
DELETE FROM t1 WHERE f1 = 5; DELETE FROM t1 WHERE f1 = 5;
COMMIT; COMMIT;
SET AUTOCOMMIT=ON; SET AUTOCOMMIT=ON;
SELECT COUNT(*) AS expect_0 FROM t1;
SELECT COUNT(*) as expect_0 FROM t1;
--connection node_2 --connection node_2
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--source include/wait_condition.inc
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; --let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT COUNT(*) as expect_0 FROM t1; SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
SELECT COUNT(*) AS expect_0 FROM t1;
DROP TABLE t1; DROP TABLE t1;
# #
@@ -203,22 +186,16 @@ SET SESSION wsrep_on = OFF;
DELETE FROM t2 WHERE f1 = 2; DELETE FROM t2 WHERE f1 = 2;
DELETE FROM t1 WHERE f1 = 3; DELETE FROM t1 WHERE f1 = 3;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
--source include/galera_wait_ready.inc
--connection node_1 --connection node_1
DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1;
SELECT COUNT(*) as expect_0 FROM t1; SELECT COUNT(*) expect_0 FROM t1;
--connection node_2 --connection node_2
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--source include/wait_condition.inc
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; --let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT COUNT(*) as expect_0 FROM t1; SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
SELECT COUNT(*) expect_0 FROM t1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
# #
@@ -238,26 +215,18 @@ INSERT INTO child VALUES (1,1),(2,2),(3,3);
SET SESSION wsrep_on = OFF; SET SESSION wsrep_on = OFF;
DELETE FROM child WHERE parent_id = 2; DELETE FROM child WHERE parent_id = 2;
SET SESSION wsrep_on = ON; SET SESSION wsrep_on = ON;
--source include/galera_wait_ready.inc
--connection node_1 --connection node_1
DELETE FROM parent; DELETE FROM parent;
SELECT COUNT(*) as expect_0 FROM parent; SELECT COUNT(*) AS expect_0 FROM parent;
SELECT COUNT(*) as expect_0 FROM child; SELECT COUNT(*) AS expect_0 FROM child;
--connection node_2 --connection node_2
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--source include/wait_condition.inc
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
--let $wait_condition = SELECT COUNT(*) = 0 FROM parent;
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM child; --let $wait_condition = SELECT COUNT(*) = 0 FROM child;
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT COUNT(*) as expect_0 FROM parent; SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
SELECT COUNT(*) as expect_0 FROM child; SELECT COUNT(*) AS expect_0 FROM parent;
SELECT COUNT(*) AS expect_0 FROM child;
DROP TABLE child, parent; DROP TABLE child, parent;
# #
@@ -272,15 +241,17 @@ SET GLOBAL wsrep_ignore_apply_errors = 4;
SET GLOBAL wsrep_on = OFF; SET GLOBAL wsrep_on = OFF;
CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t1 (f1 INTEGER);
SET GLOBAL wsrep_on = ON; SET GLOBAL wsrep_on = ON;
--source include/galera_wait_ready.inc
--connection node_1 --connection node_1
CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); CREATE TABLE t1 (f1 INTEGER, f2 INTEGER);
DROP TABLE t1; DROP TABLE t1;
--connection node_2 --connection node_2
--error ER_NO_SUCH_TABLE
SELECT * FROM t1;
SET GLOBAL wsrep_ignore_apply_errors = 7; SET GLOBAL wsrep_ignore_apply_errors = 7;
CALL mtr.add_suppression("Can't find record in 't.*'"); CALL mtr.add_suppression("Can't find record in ");
CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event"); CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event");
CALL mtr.add_suppression("Slave SQL: Error 'Unknown table 'test\\.t1'' on query\\. Default database: 'test'\\. Query: 'DROP TABLE t1', Error_code: 1051"); CALL mtr.add_suppression("Slave SQL: Error 'Unknown table 'test\\.t1'' on query\\. Default database: 'test'\\. Query: 'DROP TABLE t1', Error_code: 1051");
CALL mtr.add_suppression("Slave SQL: Error 'Can't drop database 's1'; database doesn't exist' on query\\. Default database: 'test'\\. Query: 'DROP SCHEMA s1', Error_code: 1008"); CALL mtr.add_suppression("Slave SQL: Error 'Can't drop database 's1'; database doesn't exist' on query\\. Default database: 'test'\\. Query: 'DROP SCHEMA s1', Error_code: 1008");

View File

@@ -64,6 +64,7 @@ DROP TABLE t,t2,t3;
--echo # Bigger REPLACE ... AS SELECT test --echo # Bigger REPLACE ... AS SELECT test
SET GLOBAL wsrep_mode=REPLICATE_MYISAM;
CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB; CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB;
CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM; CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM;
CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria; CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria;
@@ -95,7 +96,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t8;
--connection node_2 --connection node_2
--let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_' --let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_'
--source include/wait_condition.inc --source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t8; --let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t7;
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_1000 FROM t1; SELECT COUNT(*) AS EXPECT_1000 FROM t1;
@@ -105,7 +106,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t4;
SELECT COUNT(*) AS EXPECT_1000 FROM t5; SELECT COUNT(*) AS EXPECT_1000 FROM t5;
SELECT COUNT(*) AS EXPECT_1000 FROM t6; SELECT COUNT(*) AS EXPECT_1000 FROM t6;
SELECT COUNT(*) AS EXPECT_1000 FROM t7; SELECT COUNT(*) AS EXPECT_1000 FROM t7;
SELECT COUNT(*) AS EXPECT_1000 FROM t8; SELECT COUNT(*) AS EXPECT_0 FROM t8;
--connection node_1 --connection node_1
DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8;
@@ -143,7 +144,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t8;
--connection node_2 --connection node_2
--let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_' --let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_'
--source include/wait_condition.inc --source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t8; --let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t7;
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_1000 FROM t1; SELECT COUNT(*) AS EXPECT_1000 FROM t1;
@@ -153,7 +154,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t4;
SELECT COUNT(*) AS EXPECT_1000 FROM t5; SELECT COUNT(*) AS EXPECT_1000 FROM t5;
SELECT COUNT(*) AS EXPECT_1000 FROM t6; SELECT COUNT(*) AS EXPECT_1000 FROM t6;
SELECT COUNT(*) AS EXPECT_1000 FROM t7; SELECT COUNT(*) AS EXPECT_1000 FROM t7;
SELECT COUNT(*) AS EXPECT_1000 FROM t8; SELECT COUNT(*) AS EXPECT_0 FROM t8;
--connection node_1 --connection node_1
DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8;

View File

@@ -1,17 +1,20 @@
connection node_2; connection node_2;
connection node_1; connection node_1;
connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
connection node_1; connection node_1;
connection node_2; connection node_2;
connection node_3; connection node_3;
connection node_2; connection node_2;
SET SESSION wsrep_on=OFF; SET wsrep_on=OFF;
DROP SCHEMA test; DROP SCHEMA test;
connection node_3; connection node_3;
SET SESSION wsrep_on=OFF; SET wsrep_on=OFF;
CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb;
connection node_1; connection node_1;
CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb;
INSERT INTO test.t1 values (1); SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
VARIABLE_VALUE
1
SHOW STATUS LIKE 'wsrep_cluster_status'; SHOW STATUS LIKE 'wsrep_cluster_status';
Variable_name Value Variable_name Value
wsrep_cluster_status Primary wsrep_cluster_status Primary

View File

@@ -14,3 +14,9 @@ connection node_3;
# restart: with restart_parameters # restart: with restart_parameters
connection node_2; connection node_2;
FLUSH SSL; FLUSH SSL;
connection node_3;
call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading");
connection node_2;
call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading");
connection node_1;
call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading");

View File

@@ -3,3 +3,14 @@
[mysqld] [mysqld]
wsrep-ignore-apply-errors=0 wsrep-ignore-apply-errors=0
wsrep_sync_wait=0 wsrep_sync_wait=0
loose-gcf-354=0
wsrep-debug=1
[mysqld.1]
wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=1G;pc.weight=4'
[mysqld.2]
wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=1G'
[mysqld.3]
wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=1G'

View File

@@ -2,9 +2,7 @@
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/force_restart.inc --source include/force_restart.inc
--let $galera_connection_name = node_3 --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
--let $galera_server_number = 3
--source include/galera_connect.inc
# Save original auto_increment_offset values. # Save original auto_increment_offset values.
--let $node_1=node_1 --let $node_1=node_1
@@ -16,11 +14,11 @@
# 1. Create different inconsistencies on nodes 2 and 3 # 1. Create different inconsistencies on nodes 2 and 3
# #
--connection node_2 --connection node_2
SET SESSION wsrep_on=OFF; SET wsrep_on=OFF;
DROP SCHEMA test; DROP SCHEMA test;
--connection node_3 --connection node_3
SET SESSION wsrep_on=OFF; SET wsrep_on=OFF;
CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb;
# #
# 2. The following should generate different errors on nodes 2 and 3 and # 2. The following should generate different errors on nodes 2 and 3 and
@@ -29,10 +27,10 @@ CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb;
# #
--connection node_1 --connection node_1
CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb;
INSERT INTO test.t1 values (1);
--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
--source include/wait_condition.inc --source include/wait_condition.inc
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status' --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'
--source include/wait_condition.inc --source include/wait_condition.inc
SHOW STATUS LIKE 'wsrep_cluster_status'; SHOW STATUS LIKE 'wsrep_cluster_status';

View File

@@ -1,10 +1,14 @@
!include ../galera_3nodes.cnf !include ../galera_3nodes.cnf
[mysqld]
wsrep-debug=1
loose-galera-ssl-reload=1
[mysqld.1] [mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.crt;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.key' wsrep_provider_options='base_port=@mysqld.1.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem'
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.crt;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.key' wsrep_provider_options='base_port=@mysqld.2.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem'
[mysqld.3] [mysqld.3]
wsrep_provider_options='base_port=@mysqld.3.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.crt;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.key' wsrep_provider_options='base_port=@mysqld.3.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem'

View File

@@ -5,6 +5,7 @@
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/have_openssl.inc --source include/have_openssl.inc
--source include/have_ssl_communication.inc --source include/have_ssl_communication.inc
--source include/force_restart.inc
--let $galera_version=26.4.8 --let $galera_version=26.4.8
source ../../wsrep/include/check_galera_version.inc; source ../../wsrep/include/check_galera_version.inc;
@@ -31,22 +32,22 @@ let $ssl_cert = $MYSQLTEST_VARDIR/tmp/ssl_cert.pem;
let $ssl_key = $MYSQLTEST_VARDIR/tmp/ssl_key.pem; let $ssl_key = $MYSQLTEST_VARDIR/tmp/ssl_key.pem;
let $ssl_ca = $MYSQLTEST_VARDIR/tmp/ssl_ca.pem; let $ssl_ca = $MYSQLTEST_VARDIR/tmp/ssl_ca.pem;
copy_file std_data/galera_certs/galera.root.crt $ssl_ca; copy_file std_data/cacert.pem $ssl_ca;
copy_file std_data/galera_certs/galera.1.crt $ssl_cert; copy_file std_data/client-cert.pem $ssl_cert;
copy_file std_data/galera_certs/galera.1.key $ssl_key; copy_file std_data/client-key.pem $ssl_key;
--connection node_2 --connection node_2
--source include/shutdown_mysqld.inc --source include/shutdown_mysqld.inc
--let $restart_noprint=1 --let $restart_noprint=1
--let $restart_parameters = --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1 --wsrep_provider_options=base_port=$NODE_GALERAPORT_2;socket.ssl=yes;socket.ssl_ca=$MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=$MYSQLTEST_VARDIR/tmp/ssl_cert.pem;socket.ssl_key=$MYSQLTEST_VARDIR/tmp/ssl_key.pem --let $restart_parameters = --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1 --wsrep_provider_options=base_port=$NODE_GALERAPORT_2;socket.ssl=yes;socket.ssl_ca=$MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=$MYSQLTEST_VARDIR/tmp/ssl_cert.pem;socket.ssl_key=$MYSQLTEST_VARDIR/tmp/ssl_key.pem
--source include/start_mysqld.inc --source include/start_mysqld.inc
--source include/galera_wait_ready.inc --source include/galera_wait_ready.inc
# Set certificate and key and reload by setting directly `wsrep_provider_options` # Set certificate and key and reload by setting directly `wsrep_provider_options`
remove_file $ssl_cert; remove_file $ssl_cert;
remove_file $ssl_key; remove_file $ssl_key;
copy_file std_data/galera_certs/galera.2.crt $ssl_cert; copy_file std_data/client-cert.pem $ssl_cert;
copy_file std_data/galera_certs/galera.2.key $ssl_key; copy_file std_data/client-key.pem $ssl_key;
SET GLOBAL wsrep_provider_options = 'socket.ssl_reload=1'; SET GLOBAL wsrep_provider_options = 'socket.ssl_reload=1';
--connection node_3 --connection node_3
@@ -67,5 +68,12 @@ remove_file $ssl_ca;
remove_file $ssl_cert; remove_file $ssl_cert;
remove_file $ssl_key; remove_file $ssl_key;
--connection node_3
call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading");
--connection node_2
call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading");
--connection node_1
call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading");
# Restore original auto_increment_offset values. # Restore original auto_increment_offset values.
--source ../galera/include/auto_increment_offset_restore.inc --source ../galera/include/auto_increment_offset_restore.inc

View File

@@ -518,5 +518,14 @@ COUNT(*)
1 1
DROP TABLE t1; DROP TABLE t1;
# End of 10.4 tests # End of 10.4 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent; #
# MDEV-29010 Table cannot be loaded after instant ALTER
#
CREATE TABLE t1 (a CHAR(255), b INT,
c INT as (b) VIRTUAL)ENGINE=InnoDB CHARACTER SET utf32;
ALTER TABLE t1 DROP COLUMN a;
ALTER TABLE t1 DROP COLUMN c;
DROP TABLE t1;
# End of 10.5 tests
# End of 10.6 tests # End of 10.6 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;

View File

@@ -556,6 +556,17 @@ DROP TABLE t1;
--echo # End of 10.4 tests --echo # End of 10.4 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent; --echo #
--echo # MDEV-29010 Table cannot be loaded after instant ALTER
--echo #
CREATE TABLE t1 (a CHAR(255), b INT,
c INT as (b) VIRTUAL)ENGINE=InnoDB CHARACTER SET utf32;
ALTER TABLE t1 DROP COLUMN a;
ALTER TABLE t1 DROP COLUMN c;
DROP TABLE t1;
--echo # End of 10.5 tests
--echo # End of 10.6 tests --echo # End of 10.6 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;

View File

@@ -0,0 +1,210 @@
CREATE TABLE t1 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
a VARCHAR(200),
b TEXT
) ENGINE = InnoDB STATS_PERSISTENT=0;
INSERT INTO t1 (a,b) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...') ,
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...');
ALTER TABLE t1 ADD FULLTEXT INDEX idx_1 (a);
ALTER TABLE t1 ADD FULLTEXT INDEX idx_2 (b);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`a` varchar(200) DEFAULT NULL,
`b` text DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `idx_1` (`a`),
FULLTEXT KEY `idx_2` (`b`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0
START TRANSACTION;
INSERT INTO t1 (a,b) VALUES
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
ROLLBACK;
SELECT * FROM t1 WHERE MATCH (a)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(a) AGAINST("+mysql +Tutorial" IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(b) AGAINST("+Tutorial" IN BOOLEAN MODE);
id a b
3 Optimizing MySQL In this tutorial we will show ...
select * from t1 where MATCH(b) AGAINST("+stands +(DataBase)" IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(b) AGAINST("+DataBase -(comparison)" IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select *, MATCH(a) AGAINST("Optimizing MySQL" IN BOOLEAN MODE) as x from t1;
id a b x
1 MySQL Tutorial DBMS stands for DataBase ... 0.000000001885928302414186
2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186
3 Optimizing MySQL In this tutorial we will show ... 0.22764469683170319
select *, MATCH(b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
id a b x
1 MySQL Tutorial DBMS stands for DataBase ... 0
2 How To Use MySQL Well After you went through a ... 0
3 Optimizing MySQL In this tutorial we will show ... 0
select * from t1 where MATCH a AGAINST ("+Optimiz* +Optimiz*" IN BOOLEAN MODE);
id a b
3 Optimizing MySQL In this tutorial we will show ...
select * from t1 where MATCH b AGAINST ('"DBMS stands"' IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH b AGAINST ('"DBMS STANDS"' IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(b) AGAINST ("DataBase" WITH QUERY EXPANSION);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(a) AGAINST ("Security" WITH QUERY EXPANSION);
id a b
ALTER TABLE t1 DROP INDEX idx_1;
ALTER TABLE t1 DROP INDEX idx_2;
ALTER TABLE t1 ADD FULLTEXT INDEX idx_1 (a);
ALTER TABLE t1 ADD FULLTEXT INDEX idx_2 (b);
SELECT * FROM t1 WHERE MATCH (a)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(a) AGAINST("+mysql +Tutorial" IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(b) AGAINST("+Tutorial" IN BOOLEAN MODE);
id a b
3 Optimizing MySQL In this tutorial we will show ...
select * from t1 where MATCH(b) AGAINST("+stands +(DataBase)" IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(b) AGAINST("+DataBase -(comparison)" IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select *, MATCH(a) AGAINST("Optimizing MySQL" IN BOOLEAN MODE) as x from t1;
id a b x
1 MySQL Tutorial DBMS stands for DataBase ... 0.000000001885928302414186
2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186
3 Optimizing MySQL In this tutorial we will show ... 0.22764469683170319
select *, MATCH(b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
id a b x
1 MySQL Tutorial DBMS stands for DataBase ... 0
2 How To Use MySQL Well After you went through a ... 0
3 Optimizing MySQL In this tutorial we will show ... 0
select * from t1 where MATCH a AGAINST ("+Optimiz* +Optimiz*" IN BOOLEAN MODE);
id a b
3 Optimizing MySQL In this tutorial we will show ...
select * from t1 where MATCH b AGAINST ('"DBMS stands"' IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH b AGAINST ('"DBMS STANDS"' IN BOOLEAN MODE);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(b) AGAINST ("DataBase" WITH QUERY EXPANSION);
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
select * from t1 where MATCH(a) AGAINST ("Security" WITH QUERY EXPANSION);
id a b
INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...');
INSERT INTO t1 (a,b) VALUES
('test proximity search, test, proximity and phrase',
'search, with proximity innodb');
INSERT INTO t1 (a,b) VALUES
('test proximity fts search, test, proximity and phrase',
'search, with proximity innodb');
INSERT INTO t1 (a,b) VALUES
('test more of proximity for fts search, test, more proximity and phrase',
'search, with proximity innodb');
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"proximity search"@3' IN BOOLEAN MODE);
id a b
8 test proximity search, test, proximity and phrase search, with proximity innodb
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"proximity search"@2' IN BOOLEAN MODE);
id a b
8 test proximity search, test, proximity and phrase search, with proximity innodb
SELECT * FROM t1
WHERE MATCH (b)
AGAINST ('"proximity innodb"@4' IN BOOLEAN MODE);
id a b
8 test proximity search, test, proximity and phrase search, with proximity innodb
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"test proximity"@3' IN BOOLEAN MODE);
id a b
8 test proximity search, test, proximity and phrase search, with proximity innodb
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"more test proximity"@3' IN BOOLEAN MODE);
id a b
10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"more test proximity"@2' IN BOOLEAN MODE);
id a b
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"more fts proximity"@02' IN BOOLEAN MODE);
id a b
SELECT * FROM t1 WHERE CONCAT(t1.a,t1.b) IN (
SELECT CONCAT(a,b) FROM t1 AS t2 WHERE
MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
) OR t1.id = 3 ;
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
3 Optimizing MySQL In this tutorial we will show ...
SELECT * FROM t1 WHERE CONCAT(t1.a,t1.b) IN (
SELECT CONCAT(a,b) FROM t1 AS t2
WHERE MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
AND t2.id != 3) ;
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
SELECT * FROM t1 WHERE id IN (SELECT MIN(id) FROM t1 WHERE
MATCH (b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ;
id a b
3 Optimizing MySQL In this tutorial we will show ...
SELECT * FROM t1 WHERE id NOT IN (SELECT MIN(id) FROM t1
WHERE MATCH (b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) ;
id a b
1 MySQL Tutorial DBMS stands for DataBase ...
2 How To Use MySQL Well After you went through a ...
7 test query expansion for database ...
8 test proximity search, test, proximity and phrase search, with proximity innodb
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb
SELECT * FROM t1 WHERE EXISTS (SELECT t2.id FROM t1 AS t2 WHERE
MATCH (t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
AND t1.id = t2.id) ;
id a b
3 Optimizing MySQL In this tutorial we will show ...
SELECT * FROM t1 WHERE NOT EXISTS (SELECT t2.id FROM t1 AS t2 WHERE
MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
AND t1.id = t2.id) ;
id a b
2 How To Use MySQL Well After you went through a ...
3 Optimizing MySQL In this tutorial we will show ...
7 test query expansion for database ...
8 test proximity search, test, proximity and phrase search, with proximity innodb
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb
SELECT * FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE
MATCH(t2.a) AGAINST ('"proximity search"@3' IN BOOLEAN MODE));
id a b
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
SELECT * FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE
MATCH(t2.b) AGAINST ('"proximity innodb"@3' IN BOOLEAN MODE));
id a b
9 test proximity fts search, test, proximity and phrase search, with proximity innodb
10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb
DROP TABLE t1;

View File

@@ -0,0 +1,318 @@
INSTALL PLUGIN simple_parser SONAME 'mypluglib';
# Test Part 2: Create Index Test(CREATE TABLE WITH FULLTEXT INDEX)
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 How To Use MySQL Well After you went through a ...
3 Optimizing MySQL In this tutorial we will show ...
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
id title body
# Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
id title body
4 1001 MySQL Tricks How to use full-text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
id title body
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
id title body
DROP TABLE articles;
# Test Part 3: Row Merge Create Index Test(ALTER TABLE ADD FULLTEXT INDEX)
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser;
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 How To Use MySQL Well After you went through a ...
3 Optimizing MySQL In this tutorial we will show ...
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
id title body
# Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
id title body
4 1001 MySQL Tricks How to use full-text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
id title body
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text' WITH QUERY EXPANSION);
id title body
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
2 How To Use MySQL Well After you went through a ...
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
3 Optimizing MySQL In this tutorial we will show ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text' WITH QUERY EXPANSION);
id title body
5 Go MySQL Tricks How to use full text search engine
4 1001 MySQL Tricks How to use full-text search engine
2 How To Use MySQL Well After you went through a ...
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
3 Optimizing MySQL In this tutorial we will show ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
id title body
DROP TABLE articles;
# Test Part 3 END
SET SESSION debug="+d,fts_instrument_use_default_parser";
# Test Part 4: Create Index Test with Default/Internal Parser
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 How To Use MySQL Well After you went through a ...
3 Optimizing MySQL In this tutorial we will show ...
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
id title body
# Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
id title body
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
id title body
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
# simple parser st_mysql_ftparser_boolean_info doesn't
# store position of every word in boolean metadata.
# This leads to empty result
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
id title body
DROP TABLE articles;
# Test Part 5: Row Merge Create Index Test with Default/Internal Parser
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser;
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 How To Use MySQL Well After you went through a ...
3 Optimizing MySQL In this tutorial we will show ...
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
id title body
# Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
id title body
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
id title body
4 1001 MySQL Tricks How to use full-text search engine
5 Go MySQL Tricks How to use full text search engine
# simple parser st_mysql_ftparser_boolean_info doesn't
# store position of every word in boolean metadata.
# This leads to empty result
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
id title body
DROP TABLE articles;
# Test Part 6: Test Query Parser with Default/Internal Parser
SET GLOBAL innodb_ft_enable_diag_print = 1;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('MySQL Tutorial','DBMS stands for MySQL good one DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+mysql -database' IN BOOLEAN MODE);
id title body
3 How To Use MySQL Well After you went through a ...
4 Optimizing MySQL In this tutorial we will show ...
5 1001 MySQL Tricks How to use full-text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('>mysql <database ~search' IN BOOLEAN MODE);
id title body
3 How To Use MySQL Well After you went through a ...
4 Optimizing MySQL In this tutorial we will show ...
5 1001 MySQL Tricks How to use full-text search engine
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 MySQL Tutorial DBMS stands for MySQL good one DataBase ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+(mysql database) -engine' IN BOOLEAN MODE);
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 MySQL Tutorial DBMS stands for MySQL good one DataBase ...
3 How To Use MySQL Well After you went through a ...
4 Optimizing MySQL In this tutorial we will show ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+(mysql database -engine' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql"' IN BOOLEAN MODE);
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 MySQL Tutorial DBMS stands for MySQL good one DataBase ...
3 How To Use MySQL Well After you went through a ...
4 Optimizing MySQL In this tutorial we will show ...
5 1001 MySQL Tricks How to use full-text search engine
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"for mysql"' IN BOOLEAN MODE);
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
2 MySQL Tutorial DBMS stands for MySQL good one DataBase ...
3 How To Use MySQL Well After you went through a ...
4 Optimizing MySQL In this tutorial we will show ...
5 1001 MySQL Tricks How to use full-text search engine
# simple parser st_mysql_ftparser_boolean_info doesn't
# store position of every word in boolean metadata.
# This leads to empty result for the next 3 queries
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"full text search"' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"full text search engine"' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+"dbms stands" -good' IN BOOLEAN MODE);
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+("dbms stands") -good' IN BOOLEAN MODE);
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+("dbms stands" search) -good' IN BOOLEAN MODE);
id title body
5 1001 MySQL Tricks How to use full-text search engine
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+("dbms stands" "full text") -good' IN BOOLEAN MODE);
id title body
1 MySQL Tutorial DBMS stands for MySQL DataBase ...
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('("msyql database")@3' IN BOOLEAN MODE);
id title body
DROP TABLE articles;
SET NAMES utf8;
# Test Part 7: Test Different Charset
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB DEFAULT CHARACTER SET gb2312 COLLATE gb2312_chinese_ci;
INSERT INTO articles (title, body) VALUES
('数据库 是 数据 的 结构化 集合','它 可以 是 任何 东西'),
('从 简单 的 购物清单 到 画展','或 企业网络 中 的 海量信息'),
('要 想 将 数据 添加 到 数据库','或 访问、处理 计算机 数据库 中 保存 的 数据'),
('需要 使用 数据库 管理系统','计算机 是 处理 大量 数据 的 理想 工具');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('数据库');
id title body
3 要 想 将 数据 添加 到 数据库 或 访问、处理 计算机 数据库 中 保存 的 数据
1 数据库 是 数据 的 结构化 集合 它 可以 是 任何 东西
4 需要 使用 数据库 管理系统 计算机 是 处理 大量 数据 的 理想 工具
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('数据');
id title body
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('数据*');
id title body
3 要 想 将 数据 添加 到 数据库 或 访问、处理 计算机 数据库 中 保存 的 数据
1 数据库 是 数据 的 结构化 集合 它 可以 是 任何 东西
4 需要 使用 数据库 管理系统 计算机 是 处理 大量 数据 的 理想 工具
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+数据库 -计算机');
id title body
1 数据库 是 数据 的 结构化 集合 它 可以 是 任何 东西
# simple parser st_mysql_ftparser_boolean_info doesn't
# store position of every word in boolean metadata.
# This leads to empty result
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"计算机 数据库"' IN BOOLEAN MODE);
id title body
DROP TABLE articles;
SET GLOBAL innodb_ft_enable_diag_print = 0;
SET SESSION debug="-d,fts_instrument_use_default_parser";
# Test Part 9:# Abort the operation in dict_create_index_step
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
SET SESSION debug="+d,ib_dict_create_index_tree_fail";
CREATE FULLTEXT INDEX idx ON articles(body);
ERROR HY000: Out of memory.
SET SESSION debug="-d,ib_dict_create_index_tree_fail";
DROP TABLE articles;
UNINSTALL PLUGIN simple_parser;

View File

@@ -0,0 +1,169 @@
--source include/have_innodb.inc
#------------------------------------------------------------------------------
# Test With two FTS index on same table + alter/create/drop index + tnx
#------------------------------------------------------------------------------
# Create FTS table
CREATE TABLE t1 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
a VARCHAR(200),
b TEXT
) ENGINE = InnoDB STATS_PERSISTENT=0;
# Insert rows
INSERT INTO t1 (a,b) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...') ,
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...');
# Create the 2 FTS index Using Alter on same table
ALTER TABLE t1 ADD FULLTEXT INDEX idx_1 (a);
ALTER TABLE t1 ADD FULLTEXT INDEX idx_2 (b);
EVAL SHOW CREATE TABLE t1;
# check mutiple index with transaction
START TRANSACTION;
# Insert rows
INSERT INTO t1 (a,b) VALUES
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
ROLLBACK;
# Select word "tutorial" in the table
SELECT * FROM t1 WHERE MATCH (a)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE);
# boolean mode
select * from t1 where MATCH(a) AGAINST("+mysql +Tutorial" IN BOOLEAN MODE);
select * from t1 where MATCH(b) AGAINST("+Tutorial" IN BOOLEAN MODE);
select * from t1 where MATCH(b) AGAINST("+stands +(DataBase)" IN BOOLEAN MODE);
select * from t1 where MATCH(b) AGAINST("+DataBase -(comparison)" IN BOOLEAN MODE);
select *, MATCH(a) AGAINST("Optimizing MySQL" IN BOOLEAN MODE) as x from t1;
select *, MATCH(b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
select * from t1 where MATCH a AGAINST ("+Optimiz* +Optimiz*" IN BOOLEAN MODE);
select * from t1 where MATCH b AGAINST ('"DBMS stands"' IN BOOLEAN MODE);
select * from t1 where MATCH b AGAINST ('"DBMS STANDS"' IN BOOLEAN MODE);
# query expansion
select * from t1 where MATCH(b) AGAINST ("DataBase" WITH QUERY EXPANSION);
select * from t1 where MATCH(a) AGAINST ("Security" WITH QUERY EXPANSION);
# Drop index
ALTER TABLE t1 DROP INDEX idx_1;
ALTER TABLE t1 DROP INDEX idx_2;
# Create the FTS index again
ALTER TABLE t1 ADD FULLTEXT INDEX idx_1 (a);
ALTER TABLE t1 ADD FULLTEXT INDEX idx_2 (b);
# Select word "tutorial" in the table
SELECT * FROM t1 WHERE MATCH (a)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE);
# boolean mode
select * from t1 where MATCH(a) AGAINST("+mysql +Tutorial" IN BOOLEAN MODE);
select * from t1 where MATCH(b) AGAINST("+Tutorial" IN BOOLEAN MODE);
select * from t1 where MATCH(b) AGAINST("+stands +(DataBase)" IN BOOLEAN MODE);
select * from t1 where MATCH(b) AGAINST("+DataBase -(comparison)" IN BOOLEAN MODE);
select *, MATCH(a) AGAINST("Optimizing MySQL" IN BOOLEAN MODE) as x from t1;
select *, MATCH(b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
select * from t1 where MATCH a AGAINST ("+Optimiz* +Optimiz*" IN BOOLEAN MODE);
select * from t1 where MATCH b AGAINST ('"DBMS stands"' IN BOOLEAN MODE);
select * from t1 where MATCH b AGAINST ('"DBMS STANDS"' IN BOOLEAN MODE);
# query expansion
select * from t1 where MATCH(b) AGAINST ("DataBase" WITH QUERY EXPANSION);
select * from t1 where MATCH(a) AGAINST ("Security" WITH QUERY EXPANSION);
# insert for proximity search
INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...');
# Insert into table with similar word of different distances
INSERT INTO t1 (a,b) VALUES
('test proximity search, test, proximity and phrase',
'search, with proximity innodb');
INSERT INTO t1 (a,b) VALUES
('test proximity fts search, test, proximity and phrase',
'search, with proximity innodb');
INSERT INTO t1 (a,b) VALUES
('test more of proximity for fts search, test, more proximity and phrase',
'search, with proximity innodb');
# This should only return the first document
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"proximity search"@3' IN BOOLEAN MODE);
# This would return no document
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"proximity search"@2' IN BOOLEAN MODE);
# This give you all three documents
SELECT * FROM t1
WHERE MATCH (b)
AGAINST ('"proximity innodb"@4' IN BOOLEAN MODE);
# Similar boundary testing for the words
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"test proximity"@3' IN BOOLEAN MODE);
# Test with more word The last document will return, please notice there
# is no ordering requirement for proximity search.
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"more test proximity"@3' IN BOOLEAN MODE);
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"more test proximity"@2' IN BOOLEAN MODE);
# The phrase search will not require exact word ordering
SELECT * FROM t1
WHERE MATCH (a)
AGAINST ('"more fts proximity"@02' IN BOOLEAN MODE);
# Select word "tutorial" in the table - innodb crash
SELECT * FROM t1 WHERE CONCAT(t1.a,t1.b) IN (
SELECT CONCAT(a,b) FROM t1 AS t2 WHERE
MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
) OR t1.id = 3 ;
# Select word "tutorial" in the table - innodb crash
SELECT * FROM t1 WHERE CONCAT(t1.a,t1.b) IN (
SELECT CONCAT(a,b) FROM t1 AS t2
WHERE MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
AND t2.id != 3) ;
# Select word "tutorial" in the table
SELECT * FROM t1 WHERE id IN (SELECT MIN(id) FROM t1 WHERE
MATCH (b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ;
# Select word except "tutorial" in the table
SELECT * FROM t1 WHERE id NOT IN (SELECT MIN(id) FROM t1
WHERE MATCH (b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) ;
# Select word "tutorial" in the table
SELECT * FROM t1 WHERE EXISTS (SELECT t2.id FROM t1 AS t2 WHERE
MATCH (t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
AND t1.id = t2.id) ;
# Select not word like "tutorial" using subquery
SELECT * FROM t1 WHERE NOT EXISTS (SELECT t2.id FROM t1 AS t2 WHERE
MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)
AND t1.id = t2.id) ;
SELECT * FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE
MATCH(t2.a) AGAINST ('"proximity search"@3' IN BOOLEAN MODE));
SELECT * FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE
MATCH(t2.b) AGAINST ('"proximity innodb"@3' IN BOOLEAN MODE));
DROP TABLE t1;

View File

@@ -0,0 +1,308 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_simple_parser.inc
# Install fts parser plugin
INSTALL PLUGIN simple_parser SONAME 'mypluglib';
-- echo # Test Part 2: Create Index Test(CREATE TABLE WITH FULLTEXT INDEX)
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
# Simple term search
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
# Test stopword and word len less than fts_min_token_size
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
-- echo # Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
# No result here, we get '"mysql' 'database"' by simple parser
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
DROP TABLE articles;
-- echo # Test Part 3: Row Merge Create Index Test(ALTER TABLE ADD FULLTEXT INDEX)
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
# Create fulltext index
ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser;
# Simple term search
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
# Test stopword and word len less than fts_min_token_size
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
-- echo # Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
# Test query expansion
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text' WITH QUERY EXPANSION);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text' WITH QUERY EXPANSION);
# No result here, we get '"mysql' 'database"' by simple parser
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
DROP TABLE articles;
-- echo # Test Part 3 END
# Use default parser
SET SESSION debug="+d,fts_instrument_use_default_parser";
-- echo # Test Part 4: Create Index Test with Default/Internal Parser
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
# Simple term search
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
# Test stopword and word len less than fts_min_token_size
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
-- echo # Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
# Phrase search
--echo # simple parser st_mysql_ftparser_boolean_info doesn't
--echo # store position of every word in boolean metadata.
--echo # This leads to empty result
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
DROP TABLE articles;
# Disable query parse using plugin parser
-- echo # Test Part 5: Row Merge Create Index Test with Default/Internal Parser
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine'),
('Go MySQL Tricks','How to use full text search engine');
# Create fulltext index
ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser;
# Simple term search
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('mysql');
# Test stopword and word len less than fts_min_token_size
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('will go');
-- echo # Test plugin parser tokenizer difference
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full-text');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('full text');
# Phrase search
--echo # simple parser st_mysql_ftparser_boolean_info doesn't
--echo # store position of every word in boolean metadata.
--echo # This leads to empty result
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
DROP TABLE articles;
-- echo # Test Part 6: Test Query Parser with Default/Internal Parser
let $innodb_ft_enable_diag_print_orig = `SELECT @@innodb_ft_enable_diag_print`;
# Enable diag print to print query parse tree
SET GLOBAL innodb_ft_enable_diag_print = 1;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
INSERT INTO articles (title, body) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),
('MySQL Tutorial','DBMS stands for MySQL good one DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','How to use full-text search engine');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+mysql -database' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('>mysql <database ~search' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+(mysql database) -engine' IN BOOLEAN MODE);
# The will be no result because of parsing error.
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+(mysql database -engine' IN BOOLEAN MODE);
# Test phrase match
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql"' IN BOOLEAN MODE);
# Test stopword or word less than fts_min_token_size
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"for mysql"' IN BOOLEAN MODE);
--echo # simple parser st_mysql_ftparser_boolean_info doesn't
--echo # store position of every word in boolean metadata.
--echo # This leads to empty result for the next 3 queries
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"full text search"' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"full text search engine"' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+"dbms stands" -good' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+("dbms stands") -good' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+("dbms stands" search) -good' IN BOOLEAN MODE);
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+("dbms stands" "full text") -good' IN BOOLEAN MODE);
# Test proximity match
# It will be treated as phrase match
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('("msyql database")@3' IN BOOLEAN MODE);
DROP TABLE articles;
SET NAMES utf8;
-- echo # Test Part 7: Test Different Charset
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB DEFAULT CHARACTER SET gb2312 COLLATE gb2312_chinese_ci;
INSERT INTO articles (title, body) VALUES
('数据库 是 数据 的 结构化 集合','它 可以 是 任何 东西'),
('从 简单 的 购物清单 到 画展','或 企业网络 中 的 海量信息'),
('要 想 将 数据 添加 到 数据库','或 访问、处理 计算机 数据库 中 保存 的 数据'),
('需要 使用 数据库 管理系统','计算机 是 处理 大量 数据 的 理想 工具');
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('数据库');
# Test word len less than fts_min_token_size
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('数据');
# Test wildcard
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('数据*');
# Test operator
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('+数据库 -计算机');
# Test phrase search
--echo # simple parser st_mysql_ftparser_boolean_info doesn't
--echo # store position of every word in boolean metadata.
--echo # This leads to empty result
SELECT * FROM articles WHERE
MATCH(title, body) AGAINST('"计算机 数据库"' IN BOOLEAN MODE);
DROP TABLE articles;
eval SET GLOBAL innodb_ft_enable_diag_print = $innodb_ft_enable_diag_print_orig;
# Disable use default parser
SET SESSION debug="-d,fts_instrument_use_default_parser";
-- echo # Test Part 9:# Abort the operation in dict_create_index_step
# by setting return status of dict_create_index_tree_step() to DB_OUT_OF_MEMORY
# # The newly create dict_index_t should be removed from fts cache
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body) WITH PARSER simple_parser
) ENGINE=InnoDB;
#
SET SESSION debug="+d,ib_dict_create_index_tree_fail";
--error ER_OUT_OF_RESOURCES
CREATE FULLTEXT INDEX idx ON articles(body);
SET SESSION debug="-d,ib_dict_create_index_tree_fail";
#
DROP TABLE articles;
UNINSTALL PLUGIN simple_parser;

View File

@@ -15,6 +15,8 @@
################################################################################ ################################################################################
--source include/have_sequence.inc
--echo # - UNIQUE KEY --echo # - UNIQUE KEY
--echo # - INDEX --echo # - INDEX
--echo # - FULLTEXT INDEX --echo # - FULLTEXT INDEX
@@ -231,3 +233,18 @@ CREATE TABLE t1 (
DELETE FROM t1 WHERE vc IS NULL ORDER BY pk; DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-34632 Assertion `table->field[0]->ptr >= table->record[0] &&
# table->field[0]->ptr <= table->record[0] + table->s->reclength' failed in
# void handler::assert_icp_limitations(uchar*)
#
SET sql_mode='';
CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 SELECT 1 FROM seq_1_to_2 ;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 SELECT 1 UNION SELECT 1;
SELECT * FROM t1;
DROP TABLE t1;

View File

@@ -215,6 +215,25 @@ INDEX(vc(32))
); );
DELETE FROM t1 WHERE vc IS NULL ORDER BY pk; DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
DROP TABLE t1; DROP TABLE t1;
SET sql_mode='';
CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 SELECT 1 FROM seq_1_to_2 ;
Warnings:
Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
SELECT * FROM t1;
a
1
1
DROP TABLE t1;
CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 SELECT 1 UNION SELECT 1;
Warnings:
Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
SELECT * FROM t1;
a
1
DROP TABLE t1;
# #
# MDEV-11737 Failing assertion: block->magic_n == MEM_BLOCK_MAGIC_N # MDEV-11737 Failing assertion: block->magic_n == MEM_BLOCK_MAGIC_N
# #

View File

@@ -209,6 +209,25 @@ INDEX(vc(32))
); );
DELETE FROM t1 WHERE vc IS NULL ORDER BY pk; DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
DROP TABLE t1; DROP TABLE t1;
SET sql_mode='';
CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 SELECT 1 FROM seq_1_to_2 ;
Warnings:
Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
SELECT * FROM t1;
a
1
1
DROP TABLE t1;
CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 SELECT 1 UNION SELECT 1;
Warnings:
Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
SELECT * FROM t1;
a
1
DROP TABLE t1;
# #
# Original test # Original test
# #

View File

@@ -16,6 +16,9 @@ SHOW VARIABLES LIKE 'binlog_format';
Variable_name Value Variable_name Value
binlog_format STATEMENT binlog_format STATEMENT
CREATE TABLE IF NOT EXISTS test.t1 AS SELECT * FROM information_schema.routines WHERE 1 = 0; CREATE TABLE IF NOT EXISTS test.t1 AS SELECT * FROM information_schema.routines WHERE 1 = 0;
Warnings:
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
SET binlog_format=MIXED; SET binlog_format=MIXED;
Warnings: Warnings:
Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED
@@ -26,9 +29,14 @@ SHOW VARIABLES LIKE 'binlog_format';
Variable_name Value Variable_name Value
binlog_format MIXED binlog_format MIXED
CREATE TABLE IF NOT EXISTS test.t2 AS SELECT * FROM information_schema.routines WHERE 1 = 0; CREATE TABLE IF NOT EXISTS test.t2 AS SELECT * FROM information_schema.routines WHERE 1 = 0;
Warnings:
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
SET binlog_format=ROW; SET binlog_format=ROW;
SHOW WARNINGS; SHOW WARNINGS;
Level Code Message Level Code Message
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
SHOW VARIABLES LIKE 'binlog_format'; SHOW VARIABLES LIKE 'binlog_format';
Variable_name Value Variable_name Value
binlog_format ROW binlog_format ROW

View File

@@ -47,12 +47,25 @@ static void *coc_malloc(size_t size, const char *f __attribute__((unused)),
return malloc(size); return malloc(size);
} }
static void *coc_realloc(void *addr, size_t num,
const char *file __attribute__((unused)),
int line __attribute__((unused)))
{
return realloc(addr, num);
}
static void coc_free(void *addr, const char *file __attribute__((unused)),
int line __attribute__((unused)))
{
free(addr);
}
int check_openssl_compatibility() int check_openssl_compatibility()
{ {
EVP_CIPHER_CTX *evp_ctx; EVP_CIPHER_CTX *evp_ctx;
EVP_MD_CTX *md5_ctx; EVP_MD_CTX *md5_ctx;
if (!CRYPTO_set_mem_functions(coc_malloc, NULL, NULL)) if (!CRYPTO_set_mem_functions(coc_malloc, coc_realloc, coc_free))
return 0; return 0;
testing= 1; testing= 1;

View File

@@ -100,10 +100,9 @@ check_pid_and_port()
local busy=0 local busy=0
if [ $lsof_available -ne 0 ]; then if [ $lsof_available -ne 0 ]; then
port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \ port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | grep -F '(LISTEN)')
grep -F '(LISTEN)')
echo "$port_info" | \ echo "$port_info" | \
grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 grep -q -E "[[:space:]]\\[?(\\*|[[:xdigit:]]*(:[[:xdigit:]]*)+)(\\](%[^:]+)?)?:$port[[:space:]]" && busy=1
else else
local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+' local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+'
if [ $sockstat_available -ne 0 ]; then if [ $sockstat_available -ne 0 ]; then
@@ -122,7 +121,7 @@ check_pid_and_port()
grep -F 'users:(' | grep -o -E "$filter") grep -F 'users:(' | grep -o -E "$filter")
fi fi
echo "$port_info" | \ echo "$port_info" | \
grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port\$" && busy=1 grep -q -E "[[:space:]]\\[?(\\*|[[:xdigit:]]*(:[[:xdigit:]]*)+)(\\](%[^:]+)?)?:$port\$" && busy=1
fi fi
if [ $busy -eq 0 ]; then if [ $busy -eq 0 ]; then

View File

@@ -36,20 +36,44 @@ struct show_table_contributors_st {
*/ */
struct show_table_contributors_st show_table_contributors[]= { struct show_table_contributors_st show_table_contributors[]= {
/* MariaDB foundation sponsors, in contribution, size , time order */ /* MariaDB Foundation sponsors, alphabetical by tier */
{"Amazon", "https://www.amazon.com/", "Diamond Sponsor of the MariaDB Foundation"},
{"Acronis", "https://www.acronis.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"Alibaba Cloud", "https://www.alibabacloud.com/", "Platinum Sponsor of the MariaDB Foundation"}, {"Alibaba Cloud", "https://www.alibabacloud.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"Tencent Cloud", "https://cloud.tencent.com", "Platinum Sponsor of the MariaDB Foundation"}, {"C<onstructor", "https://www.constructor.org/", "Platinum Sponsor of the MariaDB Foundation"},
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"}, {"Development Bank of Singapore", "https://www.dbs.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"}, {"Intel", "https://www.intel.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"ServiceNow", "https://servicenow.com", "Platinum Sponsor of the MariaDB Foundation"}, {"MariaDB plc", "https://mariadb.com/", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
{"Intel", "https://www.intel.com", "Platinum Sponsor of the MariaDB Foundation"}, {"ServiceNow", "https://servicenow.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"SIT", "https://sit.org", "Platinum Sponsor of the MariaDB Foundation"}, {"WebPros", "https://webpros.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"}, {"IBM", "https://www.ibm.com/", "Gold Sponsor of the MariaDB Foundation"},
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"}, {"IONOS", "https://www.ionos.com/", "Gold Sponsor of the MariaDB Foundation"},
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"}, {"Automattic", "https://automattic.com/", "Silver Sponsor of the MariaDB Foundation"},
{"Automattic", "https://automattic.com", "Silver Sponsor of the MariaDB Foundation"}, {"SkySQL", "https://skysql.com/", "Silver Sponsor of the MariaDB Foundation"},
{"team.blue", "https://team.blue/", "Silver Sponsor of the MariaDB Foundation"},
{"Tencent Cloud", "https://cloud.tencent.com/", "Silver Sponsor of the MariaDB Foundation"},
{"Wikimedia Foundation", "https://www.wikimediafoundation.org/", "Silver Sponsor of the MariaDB Foundation"},
{"Cyber Leo", "https://cyberleo.com/", "Bronze Sponsor of the MariaDB Foundation"},
{"Hetzner", "https://www.hetzner.com/", "Bronze Sponsor of the MariaDB Foundation"},
{"Rumahweb", "https://rumahweb.com/", "Bronze Sponsor of the MariaDB Foundation"},
{"Tasjeel.ae", "https://tasjeel.ae/", "Bronze Sponsor of the MariaDB Foundation"},
{"Galera Cluster", "https://galeracluster.com/", "Sponsor of the MariaDB Foundation"},
{"Percona", "https://www.percona.com/", "Sponsor of the MariaDB Foundation"}, {"Percona", "https://www.percona.com/", "Sponsor of the MariaDB Foundation"},
{"Galera Cluster", "https://galeracluster.com", "Sponsor of the MariaDB Foundation"}, {"Vettabase", "https://vettabase.com/", "Technology partner of the MariaDB Foundation"},
{"Booking.com", "", "Previous Sponsor of the MariaDB Foundation"},
{"Jelastic.com", "", "Previous Sponsor of the MariaDB Foundation"},
{"Microsoft", "", "Previous Sponsor of the MariaDB Foundation"},
{"Nexedi", "", "Previous Sponsor of the MariaDB Foundation"},
{"Open Query", "", "Previous Sponsor of the MariaDB Foundation"},
{"Planeetta Web Hosting", "", "Previous Sponsor of the MariaDB Foundation"},
{"SpringbokSQL", "", "Previous Sponsor of the MariaDB Foundation"},
{"Tencent Games", "", "Previous Sponsor of the MariaDB Foundation"},
{"Tencent Game DBA", "", "Previous Sponsor of the MariaDB Foundation"},
{"Tencent TDSQL", "", "Previous Sponsor of the MariaDB Foundation"},
{"Verkkokauppa", "", "Previous Sponsor of the MariaDB Foundation"},
{"Virtuozzo", "", "Previous Sponsor of the MariaDB Foundation"},
{"Visma", "", "Previous Sponsor of the MariaDB Foundation"},
{"Webyog", "", "Previous Sponsor of the MariaDB Foundation"},
/* Sponsors of important features */ /* Sponsors of important features */
{"Google", "USA", "Sponsoring encryption, parallel replication and GTID"}, {"Google", "USA", "Sponsoring encryption, parallel replication and GTID"},

View File

@@ -815,7 +815,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
update_discovery_counters(hton, 1); update_discovery_counters(hton, 1);
if (ddl_recovery_done && hton->signal_ddl_recovery_done) if (ddl_recovery_done && hton->signal_ddl_recovery_done)
hton->signal_ddl_recovery_done(hton); ret= hton->signal_ddl_recovery_done(hton);
DBUG_RETURN(ret); DBUG_RETURN(ret);

View File

@@ -3768,6 +3768,10 @@ public:
return &type_handler_null; return &type_handler_null;
return field->type_handler(); return field->type_handler();
} }
uint32 character_octet_length() const override
{
return field->character_octet_length();
}
Field *create_tmp_field_from_item_field(MEM_ROOT *root, TABLE *new_table, Field *create_tmp_field_from_item_field(MEM_ROOT *root, TABLE *new_table,
Item_ref *orig_item, Item_ref *orig_item,
const Tmp_field_param *param); const Tmp_field_param *param);
@@ -4926,6 +4930,9 @@ public:
Item_string_sys(THD *thd, const char *str): Item_string_sys(THD *thd, const char *str):
Item_string(thd, str, (uint) strlen(str), system_charset_info) Item_string(thd, str, (uint) strlen(str), system_charset_info)
{ } { }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_string_sys>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
}; };
@@ -4940,6 +4947,9 @@ public:
Item_string(thd, str, (uint) strlen(str), &my_charset_latin1, Item_string(thd, str, (uint) strlen(str), &my_charset_latin1,
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII) DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII)
{ } { }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_string_ascii>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
}; };
@@ -4976,6 +4986,9 @@ public:
// require fix_fields() to be re-run for every statement. // require fix_fields() to be re-run for every statement.
return mark_unsupported_function(func_name.str, arg, VCOL_TIME_FUNC); return mark_unsupported_function(func_name.str, arg, VCOL_TIME_FUNC);
} }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_static_string_func>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
}; };
@@ -4993,6 +5006,9 @@ public:
{ {
return mark_unsupported_function("safe_string", arg, VCOL_IMPOSSIBLE); return mark_unsupported_function("safe_string", arg, VCOL_IMPOSSIBLE);
} }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_partition_func_safe_string>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
}; };
@@ -5154,6 +5170,9 @@ class Item_bin_string: public Item_hex_hybrid
public: public:
Item_bin_string(THD *thd, const char *str, size_t str_length); Item_bin_string(THD *thd, const char *str, size_t str_length);
void print(String *str, enum_query_type query_type) override; void print(String *str, enum_query_type query_type) override;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_bin_string>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
}; };
@@ -5441,6 +5460,9 @@ public:
cached_time.copy_to_mysql_time(ltime); cached_time.copy_to_mysql_time(ltime);
return (null_value= false); return (null_value= false);
} }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_date_literal_for_invalid_dates>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
}; };
@@ -5814,6 +5836,10 @@ public:
{ return (*ref)->type_handler(); } { return (*ref)->type_handler(); }
const Type_handler *real_type_handler() const override const Type_handler *real_type_handler() const override
{ return (*ref)->real_type_handler(); } { return (*ref)->real_type_handler(); }
uint32 character_octet_length() const override
{
return Item_ref::real_item()->character_octet_length();
}
Field *get_tmp_table_field() override Field *get_tmp_table_field() override
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); } { return result_field ? result_field : (*ref)->get_tmp_table_field(); }
Item *get_tmp_table_item(THD *thd) override; Item *get_tmp_table_item(THD *thd) override;
@@ -5854,9 +5880,10 @@ public:
{ {
(*ref)->save_in_field(result_field, no_conversions); (*ref)->save_in_field(result_field, no_conversions);
} }
Item *real_item() override Item *real_item() override { return ref ? (*ref)->real_item() : this; }
const Item *real_item() const
{ {
return ref ? (*ref)->real_item() : this; return const_cast<Item_ref*>(this)->Item_ref::real_item();
} }
const TYPELIB *get_typelib() const override const TYPELIB *get_typelib() const override
{ {
@@ -6940,7 +6967,9 @@ public:
description description
*/ */
bool associate_with_target_field(THD *thd, Item_field *field) override; bool associate_with_target_field(THD *thd, Item_field *field) override;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_default_value>(thd, this); }
Item* do_build_clone(THD *thd) const override { return get_copy(thd); }
private: private:
bool tie_field(THD *thd); bool tie_field(THD *thd);
}; };

View File

@@ -1853,6 +1853,16 @@ longlong Item_func_eq::val_int()
} }
Item *Item_func_eq::do_build_clone(THD *thd) const
{
/*
Clone the parent and cast to the child class since there is nothing
specific for Item_func_eq
*/
return (Item_func_eq*) Item_bool_rowready_func2::do_build_clone(thd);
}
/** Same as Item_func_eq, but NULL = NULL. */ /** Same as Item_func_eq, but NULL = NULL. */
bool Item_func_equal::fix_length_and_dec(THD *thd) bool Item_func_equal::fix_length_and_dec(THD *thd)

View File

@@ -810,10 +810,11 @@ public:
uint in_equality_no; uint in_equality_no;
uint exists2in_reserved_items() override { return 1; }; uint exists2in_reserved_items() override { return 1; };
friend class Arg_comparator; friend class Arg_comparator;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_eq>(thd, this); }
Item* date_conds_transformer(THD *thd, uchar *arg) override Item* date_conds_transformer(THD *thd, uchar *arg) override
{ return do_date_conds_transformation(thd, this); } { return do_date_conds_transformation(thd, this); }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_eq>(thd, this); }
Item *do_build_clone(THD *thd) const override;
}; };
class Item_func_equal final :public Item_bool_rowready_func2 class Item_func_equal final :public Item_bool_rowready_func2
@@ -2456,7 +2457,7 @@ public:
Item *do_build_clone(THD *thd) const override Item *do_build_clone(THD *thd) const override
{ {
Item_func_case_simple *clone= (Item_func_case_simple *) Item_func_case_simple *clone= (Item_func_case_simple *)
Item_func_case::build_clone(thd); Item_func_case::do_build_clone(thd);
uint ncases= when_count(); uint ncases= when_count();
if (clone && clone->Predicant_to_list_comparator::init_clone(thd, ncases)) if (clone && clone->Predicant_to_list_comparator::init_clone(thd, ncases))
return NULL; return NULL;

View File

@@ -9303,6 +9303,25 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
#ifndef _WIN32
#define fprintf_stderr(format, ...) fprintf(stderr, format, __VA_ARGS__)
#else
/*
On Windows, if FILE* is unbuffered, fprintf() writes output byte by byte.
This is suboptimal for printing to error log, we want full message at once.
*/
#define fprintf_stderr(format, ...) \
do \
{ \
char buf[256]; \
size_t len= snprintf(buf, sizeof(buf), format, __VA_ARGS__); \
if (len >= sizeof(buf)) \
fprintf(stderr, format, __VA_ARGS__); \
else \
fwrite(buf, len, 1, stderr); \
} while (0)
#endif
static void print_buffer_to_file(enum loglevel level, const char *buffer, static void print_buffer_to_file(enum loglevel level, const char *buffer,
size_t length) size_t length)
{ {
@@ -9336,7 +9355,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer,
localtime_r(&skr, &tm_tmp); localtime_r(&skr, &tm_tmp);
start=&tm_tmp; start=&tm_tmp;
fprintf(stderr, "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n", fprintf_stderr( "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n",
start->tm_year + 1900, start->tm_year + 1900,
start->tm_mon+1, start->tm_mon+1,
start->tm_mday, start->tm_mday,

View File

@@ -9260,10 +9260,22 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
if (!result && triggers) if (!result && triggers)
{ {
void *save_bulk_param= thd->bulk_param;
/*
Reset the sentinel thd->bulk_param in order not to consume the next
values of a bound array in case one of statement executed by
the trigger's body is INSERT statement.
*/
thd->bulk_param= nullptr;
if (triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, if (triggers->process_triggers(thd, event, TRG_ACTION_BEFORE,
TRUE) || TRUE) ||
not_null_fields_have_null_values(table)) not_null_fields_have_null_values(table))
{
thd->bulk_param= save_bulk_param;
return TRUE; return TRUE;
}
thd->bulk_param= save_bulk_param;
/* /*
Re-calculate virtual fields to cater for cases when base columns are Re-calculate virtual fields to cater for cases when base columns are

View File

@@ -6493,6 +6493,24 @@ int THD::decide_logging_format(TABLE_LIST *tables)
} }
set_current_stmt_binlog_format_row(); set_current_stmt_binlog_format_row();
} }
/* If user has requested binlog_format STMT OR MIXED
in CREATE TABLE [SELECT|REPLACE] we will fall back
to ROW.
Note that we can't use local binlog_format variable
here because wsrep_binlog_format sets it to ROW.
*/
if (wsrep_ctas && variables.binlog_format != BINLOG_FORMAT_ROW)
{
push_warning_printf(this, Sql_condition::WARN_LEVEL_WARN,
ER_UNKNOWN_ERROR,
"Galera does not support binlog_format = %s "
"in CREATE TABLE [SELECT|REPLACE] forcing ROW",
binlog_format == BINLOG_FORMAT_STMT ?
"STMT" : "MIXED");
set_current_stmt_binlog_format_row();
}
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (WSREP_EMULATE_BINLOG_NNULL(this) || if (WSREP_EMULATE_BINLOG_NNULL(this) ||

View File

@@ -808,13 +808,17 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd)
delete_history); delete_history);
if (delete_record) if (delete_record)
{ {
void *save_bulk_param= thd->bulk_param;
thd->bulk_param= nullptr;
if (!delete_history && table->triggers && if (!delete_history && table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE, table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE)) TRG_ACTION_BEFORE, FALSE))
{ {
error= 1; error= 1;
thd->bulk_param= save_bulk_param;
break; break;
} }
thd->bulk_param= save_bulk_param;
// no LIMIT / OFFSET // no LIMIT / OFFSET
if (returning && result->send_data(returning->item_list) < 0) if (returning && result->send_data(returning->item_list) < 0)
@@ -845,13 +849,16 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd)
if (likely(!error)) if (likely(!error))
{ {
deleted++; deleted++;
thd->bulk_param= nullptr;
if (!delete_history && table->triggers && if (!delete_history && table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE, table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE)) TRG_ACTION_AFTER, FALSE))
{ {
error= 1; error= 1;
thd->bulk_param= save_bulk_param;
break; break;
} }
thd->bulk_param= save_bulk_param;
if (!--limit && using_limit) if (!--limit && using_limit)
{ {
error= -1; error= -1;

View File

@@ -309,14 +309,27 @@ Diagnostics_area::reset_diagnostics_area()
m_message[0]= '\0'; m_message[0]= '\0';
Sql_state_errno::clear(); Sql_state_errno::clear();
Sql_user_condition_identity::clear(); Sql_user_condition_identity::clear();
m_affected_rows= 0;
m_last_insert_id= 0; m_last_insert_id= 0;
m_statement_warn_count= 0; if (!is_bulk_op())
{
m_affected_rows= 0;
m_statement_warn_count= 0;
}
#endif #endif
get_warning_info()->clear_error_condition(); get_warning_info()->clear_error_condition();
set_is_sent(false); set_is_sent(false);
/** Tiny reset in debug mode to see garbage right away */ /** Tiny reset in debug mode to see garbage right away */
m_status= DA_EMPTY; if (!is_bulk_op())
/*
For BULK DML operations (e.g. UPDATE) the data member m_status
has the value DA_OK_BULK. Keep this value in order to handle
m_affected_rows, m_statement_warn_count in correct way. Else,
the number of rows and the number of warnings affected by
the last statement executed as part of a trigger fired by the dml
(e.g. UPDATE statement fires a trigger on AFTER UPDATE) would counts
rows modified by trigger's statement.
*/
m_status= DA_EMPTY;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@@ -1078,6 +1078,11 @@ public:
return m_affected_rows; return m_affected_rows;
} }
void set_message(const char *msg)
{
strmake_buf(m_message, msg);
}
ulonglong last_insert_id() const ulonglong last_insert_id() const
{ {
DBUG_ASSERT(m_status == DA_OK || m_status == DA_OK_BULK); DBUG_ASSERT(m_status == DA_OK || m_status == DA_OK_BULK);

View File

@@ -1053,19 +1053,11 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
*/ */
restore_record(table,s->default_values); // Get empty record restore_record(table,s->default_values); // Get empty record
table->reset_default_fields(); table->reset_default_fields();
/*
Reset the sentinel thd->bulk_param in order not to consume the next
values of a bound array in case one of statement executed by
the trigger's body is INSERT statement.
*/
void *save_bulk_param= thd->bulk_param;
thd->bulk_param= nullptr;
if (unlikely(fill_record_n_invoke_before_triggers(thd, table, fields, if (unlikely(fill_record_n_invoke_before_triggers(thd, table, fields,
*values, 0, *values, 0,
TRG_EVENT_INSERT))) TRG_EVENT_INSERT)))
{ {
thd->bulk_param= save_bulk_param;
if (values_list.elements != 1 && ! thd->is_error()) if (values_list.elements != 1 && ! thd->is_error())
{ {
info.records++; info.records++;
@@ -1079,7 +1071,6 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
error=1; error=1;
break; break;
} }
thd->bulk_param= save_bulk_param;
} }
else else
{ {
@@ -1372,7 +1363,18 @@ values_loop_end:
*/ */
if (returning) if (returning)
result->send_eof(); result->send_eof();
else else if (!(thd->in_sub_stmt & SUB_STMT_TRIGGER))
/*
Set the status and the number of affected rows in Diagnostics_area
only in case the INSERT statement is not processed as part of a trigger
invoked by some other DML statement. Else we would result in incorrect
number of affected rows for bulk DML operations, e.g. the UPDATE
statement (called via PS protocol). It would happen since the data
member Diagnostics_area::m_affected_rows modified twice per DML
statement - first time at the end of handling the INSERT statement
invoking by a trigger fired on handling the original DML statement,
and the second time at the end of handling the original DML statement.
*/
my_ok(thd, info.copied + info.deleted + my_ok(thd, info.copied + info.deleted +
((thd->client_capabilities & CLIENT_FOUND_ROWS) ? ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
info.touched : info.updated), id); info.touched : info.updated), id);
@@ -1394,7 +1396,18 @@ values_loop_end:
(long) thd->get_stmt_da()->current_statement_warn_count()); (long) thd->get_stmt_da()->current_statement_warn_count());
if (returning) if (returning)
result->send_eof(); result->send_eof();
else else if (!(thd->in_sub_stmt & SUB_STMT_TRIGGER))
/*
Set the status and the number of affected rows in Diagnostics_area
only in case the INSERT statement is not processed as part of a trigger
invoked by some other DML statement. Else we would result in incorrect
number of affected rows for bulk DML operations, e.g. the UPDATE
statement (called via PS protocol). It would happen since the data
member Diagnostics_area::m_affected_rows modified twice per DML
statement - first time at the end of handling the INSERT statement
invoking by a trigger fired on handling the original DML statement,
and the second time at the end of handling the original DML statement.
*/
::my_ok(thd, info.copied + info.deleted + updated, id, buff); ::my_ok(thd, info.copied + info.deleted + updated, id, buff);
} }
thd->abort_on_warning= 0; thd->abort_on_warning= 0;

View File

@@ -4599,7 +4599,14 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
// For !InnoDB we start TOI if it is not yet started and hope for the best // For !InnoDB we start TOI if it is not yet started and hope for the best
if (!is_innodb && !wsrep_toi) if (!is_innodb && !wsrep_toi)
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL); {
const legacy_db_type db_type= first_table->table->file->partition_ht()->db_type;
/* Currently we support TOI for MyISAM only. */
if (db_type == DB_TYPE_MYISAM &&
wsrep_check_mode(WSREP_MODE_REPLICATE_MYISAM))
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
}
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
/* /*

View File

@@ -3282,19 +3282,22 @@ int JOIN::optimize_stage2()
which do not use aggregate functions. In such case which do not use aggregate functions. In such case
temporary table may not be used and const condition temporary table may not be used and const condition
elements may be lost during further having elements may be lost during further having
condition transformation in JOIN::exec. condition transformation.
*/ */
if (having && const_table_map && !having->with_sum_func()) if (having && const_table_map && !having->with_sum_func())
{ {
having->update_used_tables(); having->update_used_tables();
having= having->remove_eq_conds(thd, &select_lex->having_value, true); if (having->const_item() && !having->is_expensive())
if (select_lex->having_value == Item::COND_FALSE)
{ {
having= (Item*) Item_false; if (!having->val_int())
zero_result_cause= "Impossible HAVING noticed after reading const tables"; {
error= 0; having= Item_false;
select_lex->mark_const_derived(zero_result_cause); zero_result_cause= "Impossible HAVING noticed after reading const tables";
goto setup_subq_exit; error= 0;
select_lex->mark_const_derived(zero_result_cause);
goto setup_subq_exit;
}
having= Item_true;
} }
} }

View File

@@ -1300,7 +1300,7 @@ uint32 Type_numeric_attributes::find_max_octet_length(Item **item, uint nitems)
{ {
uint32 octet_length= 0; uint32 octet_length= 0;
for (uint i= 0; i < nitems ; i++) for (uint i= 0; i < nitems ; i++)
set_if_bigger(octet_length, item[i]->max_length); set_if_bigger(octet_length, item[i]->character_octet_length());
return octet_length; return octet_length;
} }

View File

@@ -3388,6 +3388,7 @@ public:
Type_all_attributes(const Type_all_attributes &) = default; Type_all_attributes(const Type_all_attributes &) = default;
virtual ~Type_all_attributes() = default; virtual ~Type_all_attributes() = default;
virtual void set_type_maybe_null(bool maybe_null_arg)= 0; virtual void set_type_maybe_null(bool maybe_null_arg)= 0;
virtual uint32 character_octet_length() const { return max_length; }
// Returns total number of decimal digits // Returns total number of decimal digits
virtual decimal_digits_t decimal_precision() const= 0; virtual decimal_digits_t decimal_precision() const= 0;
virtual const TYPELIB *get_typelib() const= 0; virtual const TYPELIB *get_typelib() const= 0;

View File

@@ -1057,13 +1057,19 @@ error:
rows_inserted++; rows_inserted++;
} }
void *save_bulk_param= thd->bulk_param;
thd->bulk_param= nullptr;
if (table->triggers && if (table->triggers &&
unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))) TRG_ACTION_AFTER, TRUE)))
{ {
error= 1; error= 1;
thd->bulk_param= save_bulk_param;
break; break;
} }
thd->bulk_param= save_bulk_param;
if (!--limit && using_limit) if (!--limit && using_limit)
{ {
@@ -1253,6 +1259,20 @@ update_end:
(ulong) thd->get_stmt_da()->current_statement_warn_count()); (ulong) thd->get_stmt_da()->current_statement_warn_count());
my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
id, buff); id, buff);
if (thd->get_stmt_da()->is_bulk_op())
{
/*
Update the diagnostics message sent to a client with number of actual
rows update by the statement. For bulk UPDATE operation it should be
done after returning from my_ok() since the final number of updated
rows be knows on finishing the entire bulk update statement.
*/
my_snprintf(buff, sizeof(buff), ER_THD(thd, ER_UPDATE_INFO),
(ulong) thd->get_stmt_da()->affected_rows(),
(ulong) thd->get_stmt_da()->affected_rows(),
(ulong) thd->get_stmt_da()->current_statement_warn_count());
thd->get_stmt_da()->set_message(buff);
}
DBUG_PRINT("info",("%ld records updated", (long) updated)); DBUG_PRINT("info",("%ld records updated", (long) updated));
} }
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */

View File

@@ -1030,6 +1030,7 @@ buf_block_init(buf_block_t* block, byte* frame)
MEM_MAKE_DEFINED(&block->modify_clock, sizeof block->modify_clock); MEM_MAKE_DEFINED(&block->modify_clock, sizeof block->modify_clock);
ut_ad(!block->modify_clock); ut_ad(!block->modify_clock);
MEM_MAKE_DEFINED(&block->page.lock, sizeof block->page.lock); MEM_MAKE_DEFINED(&block->page.lock, sizeof block->page.lock);
block->page.lock.init();
block->page.init(buf_page_t::NOT_USED, page_id_t(~0ULL)); block->page.init(buf_page_t::NOT_USED, page_id_t(~0ULL));
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
MEM_MAKE_DEFINED(&block->index, sizeof block->index); MEM_MAKE_DEFINED(&block->index, sizeof block->index);

View File

@@ -814,7 +814,7 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
break; break;
case 1: case 1:
mysql_mutex_lock(&buf_pool.flush_list_mutex); mysql_mutex_lock(&buf_pool.flush_list_mutex);
if (const lsn_t om = bpage->oldest_modification()) { if (ut_d(const lsn_t om =) bpage->oldest_modification()) {
ut_ad(om == 1); ut_ad(om == 1);
buf_pool.delete_from_flush_list(bpage); buf_pool.delete_from_flush_list(bpage);
} }

View File

@@ -173,6 +173,7 @@ page_exists:
page_zip_set_size(&bpage->zip, zip_size); page_zip_set_size(&bpage->zip, zip_size);
bpage->zip.data = (page_zip_t*) data; bpage->zip.data = (page_zip_t*) data;
bpage->lock.init();
bpage->init(buf_page_t::READ_FIX, page_id); bpage->init(buf_page_t::READ_FIX, page_id);
bpage->lock.x_lock(true); bpage->lock.x_lock(true);

View File

@@ -7955,7 +7955,10 @@ set_max_autoinc:
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE, if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
record, record,
NULL)) { NULL)) {
DBUG_PRINT("wsrep", ("row key failed")); WSREP_DEBUG("::write_rows::wsrep_append_keys failed THD %ld for %s.%s",
thd_get_thread_id(m_user_thd),
table->s->db.str,
table->s->table_name.str);
error_result = HA_ERR_INTERNAL_ERROR; error_result = HA_ERR_INTERNAL_ERROR;
goto func_exit; goto func_exit;
} }
@@ -8665,8 +8668,10 @@ func_exit:
Check THD-level wsrep state in that case. */ Check THD-level wsrep state in that case. */
(trx->is_wsrep() || (!trx_is_started(trx) && wsrep_on(m_user_thd))) (trx->is_wsrep() || (!trx_is_started(trx) && wsrep_on(m_user_thd)))
&& wsrep_thd_is_local(m_user_thd) && wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) { && !wsrep_thd_ignore_table(m_user_thd)
DBUG_PRINT("wsrep", ("update row key")); && (thd_sql_command(m_user_thd) != SQLCOM_CREATE_TABLE)
&& (thd_sql_command(m_user_thd) != SQLCOM_LOAD ||
thd_binlog_format(m_user_thd) == BINLOG_FORMAT_ROW)) {
/* We use table-level exclusive key for SEQUENCES /* We use table-level exclusive key for SEQUENCES
and normal key append for others. */ and normal key append for others. */
@@ -8678,8 +8683,10 @@ func_exit:
? WSREP_SERVICE_KEY_UPDATE ? WSREP_SERVICE_KEY_UPDATE
: WSREP_SERVICE_KEY_EXCLUSIVE, : WSREP_SERVICE_KEY_EXCLUSIVE,
old_row, new_row)) { old_row, new_row)) {
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED"); WSREP_DEBUG("::update_rows::wsrep_append_keys failed THD %ld for %s.%s",
DBUG_PRINT("wsrep", ("row key failed")); thd_get_thread_id(m_user_thd),
table->s->db.str,
table->s->table_name.str);
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} }
} }
@@ -8731,7 +8738,10 @@ ha_innobase::delete_row(
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE, if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
record, record,
NULL)) { NULL)) {
DBUG_PRINT("wsrep", ("delete fail")); WSREP_DEBUG("::delete_rows::wsrep_append_keys failed THD %ld for %s.%s",
thd_get_thread_id(m_user_thd),
table->s->db.str,
table->s->table_name.str);
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} }
} }

View File

@@ -181,6 +181,13 @@ inline void dict_table_t::init_instant(const dict_table_t& table)
auto fixed_len = dict_col_get_fixed_size( auto fixed_len = dict_col_get_fixed_size(
f.col, not_redundant()); f.col, not_redundant());
/* Long fixed length can be treated as variable
length fields that needs external storage */
if (fixed_len > DICT_MAX_FIXED_COL_LEN) {
fixed_len = 0;
}
field_map_it->set_dropped(); field_map_it->set_dropped();
if (!f.col->is_nullable()) { if (!f.col->is_nullable()) {
field_map_it->set_not_null(); field_map_it->set_not_null();

View File

@@ -602,10 +602,10 @@ public:
void init(uint32_t state, page_id_t id) void init(uint32_t state, page_id_t id)
{ {
ut_ad(state < REMOVE_HASH || state >= UNFIXED); ut_ad(state < REMOVE_HASH || state >= UNFIXED);
ut_ad(!lock.is_locked_or_waiting());
id_= id; id_= id;
zip.fix= state; zip.fix= state;
oldest_modification_= 0; oldest_modification_= 0;
lock.init();
ut_d(in_zip_hash= false); ut_d(in_zip_hash= false);
ut_d(in_free_list= false); ut_d(in_free_list= false);
ut_d(in_LRU_list= false); ut_d(in_LRU_list= false);

View File

@@ -421,8 +421,7 @@ inline void page_rec_set_n_owned(buf_block_t *block, rec_t *rec, ulint n_owned,
ut_ad(block->page.frame == page_align(rec)); ut_ad(block->page.frame == page_align(rec));
ut_ad(comp == (page_is_comp(block->page.frame) != 0)); ut_ad(comp == (page_is_comp(block->page.frame) != 0));
if (page_zip_des_t *page_zip= compressed if (compressed && is_buf_block_get_page_zip(block))
? buf_block_get_page_zip(block) : nullptr)
{ {
ut_ad(comp); ut_ad(comp);
rec_set_bit_field_1(rec, n_owned, REC_NEW_N_OWNED, rec_set_bit_field_1(rec, n_owned, REC_NEW_N_OWNED,

View File

@@ -39,32 +39,45 @@ template<bool spinloop>
class pthread_mutex_wrapper final class pthread_mutex_wrapper final
{ {
pthread_mutex_t lock; pthread_mutex_t lock;
#ifdef UNIV_DEBUG
/** whether the mutex is usable; set by init(); cleared by destroy() */
bool initialized{false};
public:
~pthread_mutex_wrapper() { ut_ad(!initialized); }
#endif
public: public:
void init() void init()
{ {
ut_ad(!initialized);
ut_d(initialized= true);
if (spinloop) if (spinloop)
pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
else else
pthread_mutex_init(&lock, nullptr); pthread_mutex_init(&lock, nullptr);
} }
void destroy() { pthread_mutex_destroy(&lock); } void destroy()
{
ut_ad(initialized); ut_d(initialized=false);
pthread_mutex_destroy(&lock);
}
# ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP # ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void wr_lock() { pthread_mutex_lock(&lock); } void wr_lock() { ut_ad(initialized); pthread_mutex_lock(&lock); }
# else # else
private: private:
void wr_wait(); void wr_wait();
public: public:
inline void wr_lock(); inline void wr_lock();
# endif # endif
void wr_unlock() { pthread_mutex_unlock(&lock); } void wr_unlock() { ut_ad(initialized); pthread_mutex_unlock(&lock); }
bool wr_lock_try() { return !pthread_mutex_trylock(&lock); } bool wr_lock_try()
{ ut_ad(initialized); return !pthread_mutex_trylock(&lock); }
}; };
# ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP # ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
template<> void pthread_mutex_wrapper<true>::wr_wait(); template<> void pthread_mutex_wrapper<true>::wr_wait();
template<> template<>
inline void pthread_mutex_wrapper<false>::wr_lock() inline void pthread_mutex_wrapper<false>::wr_lock()
{ pthread_mutex_lock(&lock); } { ut_ad(initialized); pthread_mutex_lock(&lock); }
template<> template<>
inline void pthread_mutex_wrapper<true>::wr_lock() inline void pthread_mutex_wrapper<true>::wr_lock()
{ if (!wr_lock_try()) wr_wait(); } { if (!wr_lock_try()) wr_wait(); }

View File

@@ -1044,13 +1044,19 @@ std::pair<lsn_t,byte*> log_t::append_prepare(size_t size, bool ex) noexcept
size_t b{spin ? lock_lsn() : buf_free.load(std::memory_order_relaxed)}; size_t b{spin ? lock_lsn() : buf_free.load(std::memory_order_relaxed)};
write_to_buf++; write_to_buf++;
const lsn_t l{lsn.load(std::memory_order_relaxed)}, end_lsn{l + size}; lsn_t l{lsn.load(std::memory_order_relaxed)}, end_lsn{l + size};
if (UNIV_UNLIKELY(pmem if (UNIV_UNLIKELY(pmem
? (end_lsn - ? (end_lsn -
get_flushed_lsn(std::memory_order_relaxed)) > capacity() get_flushed_lsn(std::memory_order_relaxed)) > capacity()
: b + size >= buf_size)) : b + size >= buf_size))
{
b= append_prepare_wait<spin>(b, ex, l); b= append_prepare_wait<spin>(b, ex, l);
/* While flushing log, we had released the lsn lock and LSN could have
progressed in the meantime. */
l= lsn.load(std::memory_order_relaxed);
end_lsn= l + size;
}
size_t new_buf_free= b + size; size_t new_buf_free= b + size;
if (pmem && new_buf_free >= file_size) if (pmem && new_buf_free >= file_size)

View File

@@ -3207,6 +3207,7 @@ static void add_fts_index(dict_table_t *table)
{ {
dict_index_t *fts_index= dict_mem_index_create( dict_index_t *fts_index= dict_mem_index_create(
table, FTS_DOC_ID_INDEX_NAME, DICT_UNIQUE, 2); table, FTS_DOC_ID_INDEX_NAME, DICT_UNIQUE, 2);
fts_index->lock.SRW_LOCK_INIT(index_tree_rw_lock_key);
fts_index->page= FIL_NULL; fts_index->page= FIL_NULL;
fts_index->cached= 1; fts_index->cached= 1;
fts_index->n_uniq= 1; fts_index->n_uniq= 1;
@@ -3288,6 +3289,7 @@ static dict_table_t *build_fts_hidden_table(
new_table, old_index->name, old_index->type, new_table, old_index->name, old_index->type,
old_index->n_fields + is_clustered); old_index->n_fields + is_clustered);
new_index->lock.SRW_LOCK_INIT(index_tree_rw_lock_key);
new_index->id= old_index->id; new_index->id= old_index->id;
new_index->n_uniq= old_index->n_uniq; new_index->n_uniq= old_index->n_uniq;
new_index->type= old_index->type; new_index->type= old_index->type;

View File

@@ -661,6 +661,7 @@ void srw_lock_debug::destroy()
ut_ad(r->empty()); ut_ad(r->empty());
delete r; delete r;
} }
readers_lock.destroy();
srw_lock::destroy(); srw_lock::destroy();
} }

View File

@@ -660,6 +660,7 @@ dberr_t trx_rseg_array_init()
break; break;
} }
rseg.destroy();
rseg.init(rseg_space, page_no); rseg.init(rseg_space, page_no);
ut_ad(rseg.is_persistent()); ut_ad(rseg.is_persistent());
err = trx_rseg_mem_restore(&rseg, &mtr); err = trx_rseg_mem_restore(&rseg, &mtr);
@@ -741,6 +742,7 @@ dberr_t trx_temp_rseg_create(mtr_t *mtr)
mtr->commit(); mtr->commit();
return err; return err;
} }
trx_sys.temp_rsegs[i].destroy();
trx_sys.temp_rsegs[i].init(fil_system.temp_space, trx_sys.temp_rsegs[i].init(fil_system.temp_space,
rblock->page.id().page_no()); rblock->page.id().page_no());
mtr->commit(); mtr->commit();

View File

@@ -146,6 +146,10 @@ void trx_sys_t::create()
m_initialised= true; m_initialised= true;
trx_list.create(); trx_list.create();
rw_trx_hash.init(); rw_trx_hash.init();
for (auto &rseg : temp_rsegs)
rseg.init(nullptr, FIL_NULL);
for (auto &rseg : rseg_array)
rseg.init(nullptr, FIL_NULL);
} }
size_t trx_sys_t::history_size() size_t trx_sys_t::history_size()
@@ -224,6 +228,7 @@ static trx_rseg_t *trx_rseg_create(uint32_t space_id)
? nullptr : trx_rseg_header_create(space, rseg_id, 0, &mtr, &err)) ? nullptr : trx_rseg_header_create(space, rseg_id, 0, &mtr, &err))
{ {
rseg= &trx_sys.rseg_array[rseg_id]; rseg= &trx_sys.rseg_array[rseg_id];
rseg->destroy();
rseg->init(space, rblock->page.id().page_no()); rseg->init(space, rblock->page.id().page_no());
ut_ad(rseg->is_persistent()); ut_ad(rseg->is_persistent());
mtr.write<4,mtr_t::MAYBE_NOP> mtr.write<4,mtr_t::MAYBE_NOP>
@@ -322,13 +327,8 @@ trx_sys_t::close()
rw_trx_hash.destroy(); rw_trx_hash.destroy();
/* There can't be any active transactions. */ /* There can't be any active transactions. */
for (auto& rseg : temp_rsegs) rseg.destroy();
for (ulint i = 0; i < array_elements(temp_rsegs); ++i) { for (auto& rseg : rseg_array) rseg.destroy();
temp_rsegs[i].destroy();
}
for (ulint i = 0; i < array_elements(rseg_array); ++i) {
rseg_array[i].destroy();
}
ut_a(trx_list.empty()); ut_a(trx_list.empty());
trx_list.close(); trx_list.close();

View File

@@ -1822,7 +1822,7 @@ trx_print_low(
/*!< in: mem_heap_get_size(trx->lock.lock_heap) */ /*!< in: mem_heap_get_size(trx->lock.lock_heap) */
{ {
if (const trx_id_t id = trx->id) { if (const trx_id_t id = trx->id) {
fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id); fprintf(f, "TRANSACTION " TRX_ID_FMT, id);
} else { } else {
fprintf(f, "TRANSACTION (%p)", trx); fprintf(f, "TRANSACTION (%p)", trx);
} }

View File

@@ -722,29 +722,32 @@ static void init_compute_vcols(void *table)
static int compute_vcols(MI_INFO *info, uchar *record, int keynum) static int compute_vcols(MI_INFO *info, uchar *record, int keynum)
{ {
int error= 0;
/* This mutex is needed for parallel repair */ /* This mutex is needed for parallel repair */
mysql_mutex_lock(&info->s->intern_lock); mysql_mutex_lock(&info->s->intern_lock);
TABLE *table= (TABLE*)(info->external_ref); TABLE *table= (TABLE*)(info->external_ref);
table->move_fields(table->field, record, table->field[0]->record_ptr()); table->move_fields(table->field, record, table->record[0]);
if (keynum == -1) // update all vcols if (keynum == -1) // update all vcols
{ {
int error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ); error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ);
if (table->update_virtual_fields(table->file, VCOL_UPDATE_INDEXED)) if (table->update_virtual_fields(table->file, VCOL_UPDATE_INDEXED))
error= 1; error= 1;
mysql_mutex_unlock(&info->s->intern_lock);
return error;
} }
// update only one key else
KEY *key= table->key_info + keynum;
KEY_PART_INFO *kp= key->key_part, *end= kp + key->ext_key_parts;
for (; kp < end; kp++)
{ {
Field *f= table->field[kp->fieldnr - 1]; // update only one key
if (f->vcol_info && !f->vcol_info->is_stored()) KEY *key= table->key_info + keynum;
table->update_virtual_field(f, false); KEY_PART_INFO *kp= key->key_part, *end= kp + key->ext_key_parts;
for (; kp < end; kp++)
{
Field *f= table->field[kp->fieldnr - 1];
if (f->vcol_info && !f->vcol_info->is_stored())
table->update_virtual_field(f, false);
}
} }
table->move_fields(table->field, table->record[0], record);
mysql_mutex_unlock(&info->s->intern_lock); mysql_mutex_unlock(&info->s->intern_lock);
return 0; return error;
} }
} }
@@ -1037,16 +1040,6 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param)
table->use_all_columns(); table->use_all_columns();
} }
void ha_myisam::restore_vcos_after_repair()
{
if (file->s->base.reclength < file->s->vreclength)
{
table->move_fields(table->field, table->record[0],
table->field[0]->record_ptr());
table->default_column_bitmaps();
}
}
int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
{ {
if (!file) return HA_ADMIN_INTERNAL_ERROR; if (!file) return HA_ADMIN_INTERNAL_ERROR;
@@ -1143,8 +1136,6 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
} }
restore_vcos_after_repair();
thd_proc_info(thd, old_proc_info); thd_proc_info(thd, old_proc_info);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
} }
@@ -1190,8 +1181,6 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
else if (!mi_is_crashed(file) && !thd->killed) else if (!mi_is_crashed(file) && !thd->killed)
mi_mark_crashed(file); mi_mark_crashed(file);
restore_vcos_after_repair();
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
} }
@@ -1241,8 +1230,6 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
break; break;
} }
restore_vcos_after_repair();
if (!error && start_records != file->state->records && if (!error && start_records != file->state->records &&
!(check_opt->flags & T_VERY_SILENT)) !(check_opt->flags & T_VERY_SILENT))
{ {
@@ -1280,8 +1267,6 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
error= repair(thd,*param,1); error= repair(thd,*param,1);
} }
restore_vcos_after_repair();
return error; return error;
} }
@@ -1719,8 +1704,6 @@ int ha_myisam::enable_indexes(key_map map, bool persist)
} }
info(HA_STATUS_CONST); info(HA_STATUS_CONST);
thd_proc_info(thd, save_proc_info); thd_proc_info(thd, save_proc_info);
restore_vcos_after_repair();
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }

View File

@@ -49,7 +49,6 @@ class ha_myisam final : public handler
bool can_enable_indexes; bool can_enable_indexes;
int repair(THD *thd, HA_CHECK &param, bool optimize); int repair(THD *thd, HA_CHECK &param, bool optimize);
void setup_vcols_for_repair(HA_CHECK *param); void setup_vcols_for_repair(HA_CHECK *param);
void restore_vcos_after_repair();
public: public:
ha_myisam(handlerton *hton, TABLE_SHARE *table_arg); ha_myisam(handlerton *hton, TABLE_SHARE *table_arg);

View File

@@ -0,0 +1,19 @@
set @old_aria_encrypt_tables=@@global.aria_encrypt_tables;
set global aria_encrypt_tables=ON;
CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so';
call mtr.add_suppression(".*\\[ERROR\\] SPIDER plugin initialization failed at.* by 'Initialization of encryption failed for");
call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER' registration as a STORAGE ENGINE failed.");
INSTALL PLUGIN spider SONAME 'ha_spider.so';
ERROR HY000: Can't initialize function 'spider'; Plugin initialization function failed.
SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"');
ERROR HY000: Can't initialize function 'spider_direct_sql'; Plugin 'SPIDER' is not loaded
Warnings:
Note 1305 FUNCTION test.spider_flush_table_mon_cache does not exist
Warnings:
Note 1305 FUNCTION test.spider_copy_tables does not exist
Warnings:
Note 1305 FUNCTION test.spider_ping_table does not exist
Warnings:
Note 1305 FUNCTION test.spider_bg_direct_sql does not exist
Warnings:
Note 1305 SONAME ha_spider.so does not exist

View File

@@ -0,0 +1,14 @@
set @old_aria_encrypt_tables=@@global.aria_encrypt_tables;
set global aria_encrypt_tables=ON;
CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so';
call mtr.add_suppression(".*\\[ERROR\\] SPIDER plugin initialization failed at.* by 'Initialization of encryption failed for");
call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER' registration as a STORAGE ENGINE failed.");
--error ER_CANT_INITIALIZE_UDF
INSTALL PLUGIN spider SONAME 'ha_spider.so';
--error ER_CANT_INITIALIZE_UDF
SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"');
--disable_query_log
--source ../../include/clean_up_spider.inc
set global aria_encrypt_tables=@old_aria_encrypt_tables;

View File

@@ -1,8 +1,8 @@
DROP FUNCTION spider_flush_table_mon_cache; DROP FUNCTION IF EXISTS spider_flush_table_mon_cache;
DROP FUNCTION spider_copy_tables; DROP FUNCTION IF EXISTS spider_copy_tables;
DROP FUNCTION spider_ping_table; DROP FUNCTION IF EXISTS spider_ping_table;
DROP FUNCTION spider_bg_direct_sql; DROP FUNCTION IF EXISTS spider_bg_direct_sql;
DROP FUNCTION spider_direct_sql; DROP FUNCTION IF EXISTS spider_direct_sql;
UNINSTALL SONAME IF EXISTS 'ha_spider'; UNINSTALL SONAME IF EXISTS 'ha_spider';
DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa;
DROP TABLE IF EXISTS mysql.spider_xa_member; DROP TABLE IF EXISTS mysql.spider_xa_member;

View File

@@ -5963,8 +5963,10 @@ bool spider_init_system_tables()
/* /*
Spider is typically loaded before ddl_recovery, but DDL statements Spider may be loaded before ddl_recovery (e.g. with
cannot be executed before ddl_recovery, so we delay system table creation. --plugin-load-add), but DDL statements in spider init queries cannot
be executed before ddl_recovery, so we execute these queries only
after ddl recovery.
*/ */
static int spider_after_ddl_recovery(handlerton *) static int spider_after_ddl_recovery(handlerton *)
{ {
@@ -6381,6 +6383,7 @@ error_pt_attr_setstate:
*/ */
pthread_attr_destroy(&spider_pt_attr); pthread_attr_destroy(&spider_pt_attr);
error_pt_attr_init: error_pt_attr_init:
spider_hton_ptr= NULL;
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
} }

View File

@@ -22062,6 +22062,452 @@ static void test_mdev_30159()
myquery(rc); myquery(rc);
} }
#ifndef EMBEDDED_LIBRARY
/**
Test case for bulk UPDATE against a table with an active AFTER UPDATE
trigger.
*/
static void test_mdev_34718_au()
{
int rc;
MYSQL_STMT *stmt_update;
MYSQL_BIND bind[2];
unsigned int vals[]= { 1, 2, 3};
unsigned int new_vals[]= { 5, 6, 7};
unsigned int vals_array_len= 3;
my_ulonglong row_count;
MYSQL_RES *result;
MYSQL_ROW row;
const char *update_stmt= "UPDATE t1 SET a = ? WHERE a = ?";
const char *update_stmt_state_info;
myheader("test_mdev_34718_au");
/* Set up test's environment */
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TRIGGER t1_au AFTER UPDATE ON t1 "
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (NEW.a); END;");
stmt_update= mysql_stmt_init(mysql);
check_stmt(stmt_update);
rc= mysql_stmt_prepare(stmt_update, update_stmt, strlen(update_stmt));
check_execute(stmt_update, rc);
memset(&bind[0], 0, sizeof(MYSQL_BIND));
memset(&bind[1], 0, sizeof(MYSQL_BIND));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= new_vals;
bind[1].buffer_type= MYSQL_TYPE_LONG;
bind[1].buffer= vals;
/*
Every input positional parameter is bound with array of 3 elements
containing actual values for positional parameters
*/
rc= mysql_stmt_attr_set(stmt_update, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
check_execute(stmt_update, rc);
rc= mysql_stmt_bind_param(stmt_update, bind);
check_execute(stmt_update, rc);
/*
Execution of this prepared statement replaces the table rows (1), (2), (3)
with values (5), (6), (7)
*/
rc= mysql_stmt_execute(stmt_update);
check_execute(stmt_update, rc);
/*
Check that the BULK UPDATE statement affects exactly 3 rows
*/
row_count = mysql_stmt_affected_rows(stmt_update);
DIE_UNLESS(row_count == 3);
update_stmt_state_info= mysql_info(mysql);
/*
Check that information about executed operation is matched with
the expected result
*/
DIE_UNLESS(!strcmp("Rows matched: 3 Changed: 3 Warnings: 0",
update_stmt_state_info));
/*
* Check that the AFTER UPDATE trigger of the table t1 does work correctly
* and inserts the rows (5), (6), (7) into the table t2.
*/
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
myquery(rc);
result= mysql_store_result(mysql);
row = mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 5);
row = mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 6);
row = mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 7);
row = mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 5);
row = mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 6);
row = mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 7);
row= mysql_fetch_row(result);
DIE_UNLESS(row == NULL);
mysql_free_result(result);
mysql_stmt_close(stmt_update);
/* Clean up */
rc= mysql_query(mysql, "DROP TABLE t1, t2");
myquery(rc);
}
/**
Test case for bulk UPDATE against a table with an active BEFORE UPDATE
trigger.
*/
static void test_mdev_34718_bu()
{
int rc;
MYSQL_STMT *stmt_update;
MYSQL_BIND bind[2];
unsigned int vals[]= { 1, 2, 3};
unsigned int new_vals[]= { 5, 6, 7};
unsigned int vals_array_len= 3;
my_ulonglong row_count;
MYSQL_RES *result;
MYSQL_ROW row;
const char *update_stmt= "UPDATE t1 SET a = ? WHERE a = ?";
const char *update_stmt_state_info;
myheader("test_mdev_34718_bu");
/* Set up test's environment */
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TRIGGER t1_au BEFORE UPDATE ON t1 "
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (NEW.a); END;");
/* Initialize the prepared statement and set it up for bulk operations */
stmt_update= mysql_stmt_init(mysql);
check_stmt(stmt_update);
rc= mysql_stmt_prepare(stmt_update, update_stmt, strlen(update_stmt));
check_execute(stmt_update, rc);
memset(&bind[0], 0, sizeof(MYSQL_BIND));
memset(&bind[1], 0, sizeof(MYSQL_BIND));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= new_vals;
bind[1].buffer_type= MYSQL_TYPE_LONG;
bind[1].buffer= vals;
/*
Every input positional parameter is bound with array of 3 elements
containing actual values for positional parameters
*/
rc= mysql_stmt_attr_set(stmt_update, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
check_execute(stmt_update, rc);
rc= mysql_stmt_bind_param(stmt_update, bind);
check_execute(stmt_update, rc);
/*
Execution of this prepared statement replaces the table rows (1), (2), (3)
with values (5), (6), (7)
*/
rc= mysql_stmt_execute(stmt_update);
check_execute(stmt_update, rc);
/*
Check that the BULK UPDATE statement affects exactly 3 rows
*/
row_count= mysql_stmt_affected_rows(stmt_update);
DIE_UNLESS(row_count == 3);
update_stmt_state_info= mysql_info(mysql);
/*
Check that information about executed operation is matched with
the expected result
*/
DIE_UNLESS(!strcmp("Rows matched: 3 Changed: 3 Warnings: 0",
update_stmt_state_info));
/*
* Check that the BEFORE UPDATE trigger of the table t1 does work correctly
* and inserts the rows (5), (6), (7) into the table t2.
*/
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
myquery(rc);
result= mysql_store_result(mysql);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 5);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 6);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 7);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 5);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 6);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 7);
row= mysql_fetch_row(result);
DIE_UNLESS(row == NULL);
mysql_free_result(result);
mysql_stmt_close(stmt_update);
/* Clean up */
rc= mysql_query(mysql, "DROP TABLE t1, t2");
myquery(rc);
}
/**
Test case for bulk DELETE against a table with an active BEFORE DELETE
trigger.
*/
static void test_mdev_34718_bd()
{
int rc;
MYSQL_STMT *stmt_delete;
MYSQL_BIND bind[1];
unsigned int vals[]= { 1, 2, 3};
unsigned int vals_array_len= 3;
my_ulonglong row_count;
MYSQL_RES *result;
MYSQL_ROW row;
const char *delete_stmt= "DELETE FROM t1 WHERE a = ?";
myheader("test_mdev_34718_bd");
/* Set up test's environment */
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TRIGGER t1_bd BEFORE DELETE ON t1 "
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (OLD.a); END;");
/* Initialize the prepared statement and set it up for bulk operations */
stmt_delete= mysql_stmt_init(mysql);
check_stmt(stmt_delete);
rc= mysql_stmt_prepare(stmt_delete, delete_stmt, strlen(delete_stmt));
check_execute(stmt_delete, rc);
memset(&bind[0], 0, sizeof(MYSQL_BIND));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= vals;
/*
Input positional parameter is bound with array of 3 elements
containing actual values for the positional parameter
*/
rc= mysql_stmt_attr_set(stmt_delete, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
check_execute(stmt_delete, rc);
rc= mysql_stmt_bind_param(stmt_delete, bind);
check_execute(stmt_delete, rc);
/*
Execution of this prepared statement deletes the rows (1), (2), (3)
from the table t1 and inserts the rows (1), (2), (3) into the table t2
in result of firing the BEFORE DELETE trigger
*/
rc= mysql_stmt_execute(stmt_delete);
check_execute(stmt_delete, rc);
/*
Check that the BULK DELETE statement affects exactly 3 rows
*/
row_count= mysql_stmt_affected_rows(stmt_delete);
DIE_UNLESS(row_count == 3);
/*
* Check that the BEFORE DELETE trigger of the table t1 does work correctly
* and inserts the rows (1), (2), (3) into the table t2.
*/
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
myquery(rc);
result= mysql_store_result(mysql);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 1);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 2);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 3);
row= mysql_fetch_row(result);
DIE_UNLESS(row == NULL);
mysql_free_result(result);
mysql_stmt_close(stmt_delete);
/* Clean up */
rc= mysql_query(mysql, "DROP TABLE t1, t2");
myquery(rc);
}
/**
Test case for bulk DELETE against a table with an active AFTER DELETE
trigger.
*/
static void test_mdev_34718_ad()
{
int rc;
MYSQL_STMT *stmt_delete;
MYSQL_BIND bind[1];
unsigned int vals[]= { 1, 2, 3};
unsigned int vals_array_len= 3;
my_ulonglong row_count;
MYSQL_RES *result;
MYSQL_ROW row;
const char *delete_stmt= "DELETE FROM t1 WHERE a = ?";
myheader("test_mdev_34718_bd");
/* Set up test's environment */
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
myquery(rc);
rc= mysql_query(mysql, "CREATE TRIGGER t1_bd AFTER DELETE ON t1 "
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (OLD.a); END;");
/* Initialize the prepared statement and set it up for bulk operations */
stmt_delete= mysql_stmt_init(mysql);
check_stmt(stmt_delete);
rc= mysql_stmt_prepare(stmt_delete, delete_stmt, strlen(delete_stmt));
check_execute(stmt_delete, rc);
memset(&bind[0], 0, sizeof(MYSQL_BIND));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= vals;
/*
Input positional parameter is bound with array of 3 elements
containing actual values for the positional parameter
*/
rc= mysql_stmt_attr_set(stmt_delete, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
check_execute(stmt_delete, rc);
rc= mysql_stmt_bind_param(stmt_delete, bind);
check_execute(stmt_delete, rc);
/*
Execution of this prepared statement deletes the rows (1), (2), (3)
from the table t1 and inserts the rows (1), (2), (3) into the table t2
in result of firing the BEFORE DELETE trigger
*/
rc= mysql_stmt_execute(stmt_delete);
check_execute(stmt_delete, rc);
/*
Check that the BULK DELETE statement affects exactly 3 rows
*/
row_count= mysql_stmt_affected_rows(stmt_delete);
DIE_UNLESS(row_count == 3);
/*
* Check that the AFTER DELETE trigger of the table t1 does work correctly
* and inserts the rows (1), (2), (3) into the table t2.
*/
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
myquery(rc);
result= mysql_store_result(mysql);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 1);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 2);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 3);
row= mysql_fetch_row(result);
DIE_UNLESS(row == NULL);
mysql_free_result(result);
mysql_stmt_close(stmt_delete);
/* Clean up */
rc= mysql_query(mysql, "DROP TABLE t1, t2");
myquery(rc);
}
#endif // EMBEDDED_LIBRARY
/* /*
Check that server_status returned after connecting to server Check that server_status returned after connecting to server
is consistent with the value of autocommit variable. is consistent with the value of autocommit variable.
@@ -22630,6 +23076,10 @@ static struct my_tests_st my_tests[]= {
{ "test_cache_metadata", test_cache_metadata}, { "test_cache_metadata", test_cache_metadata},
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
{ "test_mdev_24411", test_mdev_24411}, { "test_mdev_24411", test_mdev_24411},
{ "test_mdev_34718_bu", test_mdev_34718_bu },
{ "test_mdev_34718_au", test_mdev_34718_au },
{ "test_mdev_34718_bd", test_mdev_34718_bd },
{ "test_mdev_34718_ad", test_mdev_34718_ad },
#endif #endif
{ "test_mdev_10075", test_mdev_10075}, { "test_mdev_10075", test_mdev_10075},
{ 0, 0 } { 0, 0 }