From 53c4e4d054cb5ac895535abc9815e70378dbf1b5 Mon Sep 17 00:00:00 2001 From: Mike Griffin Date: Fri, 29 Jul 2022 16:07:42 +1000 Subject: [PATCH 01/14] MDEV-18702 mysqldump: add variable 'max-statement-time' With a global non-default max-statement-time of a time interval that exceed the query time mysqldump queries when doing a backup. To solve both, add a max-statement-time option, defaulting to 0 (unlimited time). Also like mariabackup, set the session wait_timeout=DEFAULT (28800). The time/processing between mysqldump times isn't expected to get that close ever, but let's adopt the standard of mariabackup as no-one has challenged it has having a detrimental effect. Reviewer and test case author Daniel Black --- client/mysqldump.c | 14 +++++ man/mysqldump.1 | 30 +++++++++++ mysql-test/main/mysqldump-timing.result | 71 +++++++++++++++++++++++++ mysql-test/main/mysqldump-timing.test | 26 +++++++++ 4 files changed, 141 insertions(+) create mode 100644 mysql-test/main/mysqldump-timing.result create mode 100644 mysql-test/main/mysqldump-timing.test diff --git a/client/mysqldump.c b/client/mysqldump.c index 6cdc3db3c08..0d9b48e585e 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -146,6 +146,7 @@ static ulonglong opt_system= 0ULL; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0, select_field_names_inited= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; +static double opt_max_statement_time= 0.0; static MYSQL mysql_connection,*mysql=0; static DYNAMIC_STRING insert_pat, select_field_names; static char *opt_password=0,*current_user=0, @@ -162,6 +163,7 @@ static my_bool server_supports_switching_charsets= TRUE; static ulong opt_compatible_mode= 0; #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 +#define MYSQL_OPT_MAX_STATEMENT_TIME 0 #define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2 static uint opt_mysql_port= 0, opt_master_data; @@ -464,6 +466,10 @@ static struct my_option my_long_options[] = &opt_max_allowed_packet, &opt_max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, + {"max-statement-time", MYSQL_OPT_MAX_STATEMENT_TIME, + "Max statement execution time. If unset, overrides server default with 0.", + &opt_max_statement_time, &opt_max_statement_time, 0, GET_DOUBLE, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "The buffer size for TCP/IP and socket communication.", &opt_net_buffer_length, &opt_net_buffer_length, 0, @@ -6816,6 +6822,7 @@ static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size) int main(int argc, char **argv) { + char query[48]; char bin_log_name[FN_REFLEN]; int exit_code; int consistent_binlog_pos= 0; @@ -6857,6 +6864,13 @@ int main(int argc, char **argv) if (!path) write_header(md_result_file, *argv); + /* Set MAX_STATEMENT_TIME to 0 unless set in client */ + my_snprintf(query, sizeof(query), "/*!100100 SET @@MAX_STATEMENT_TIME=%f */", opt_max_statement_time); + mysql_query(mysql, query); + + /* Set server side timeout between client commands to server compiled-in default */ + mysql_query(mysql, "/*!100100 SET WAIT_TIMEOUT=DEFAULT */"); + /* Check if the server support multi source */ if (mysql_get_server_version(mysql) >= 100000) { diff --git a/man/mysqldump.1 b/man/mysqldump.1 index ae6d76f24c3..140bc45c7c6 100644 --- a/man/mysqldump.1 +++ b/man/mysqldump.1 @@ -1361,6 +1361,21 @@ Sets the maximum packet length to send to or receive from server\&. .sp -1 .IP \(bu 2.3 .\} +.\" mysqldump: max-statement-time option +.\" max-statement-time option: mysqldump +\fB\-\-max\-statement\-time=\fR\fB\fIseconds\fR\fR +.sp +Sets the maximum time any statement can run before being timed out by the server. (Default value is 0 (no limit))\& +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} .\" mysqldump: net-buffer-length option .\" net-buffer-length option: mysqldump \fB\-\-net\-buffer\-length=\fR\fB\fIlength\fR\fR @@ -2619,6 +2634,21 @@ The maximum size of the buffer for client/server communication\&. The maximum is .sp -1 .IP \(bu 2.3 .\} +max_statement_time +.sp +A query that has taken more than max_statement_time seconds will be aborted and the backup will +fail\&. The argument will be treated as a decimal value with microsecond precision\&. A value +of 0 (default) means no timeout\&. The maximum timeout is 31536000 seconds\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} net_buffer_length .sp The initial size of the buffer for client/server communication\&. When creating multiple\-row diff --git a/mysql-test/main/mysqldump-timing.result b/mysql-test/main/mysqldump-timing.result new file mode 100644 index 00000000000..71120ebf2d5 --- /dev/null +++ b/mysql-test/main/mysqldump-timing.result @@ -0,0 +1,71 @@ +# +# MDEV-18702 mysqldump should use max_statement_time=0 and/or allow setting one +# +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (0); +LOCK TABLE t1 WRITE; +timeout without t1 contents expected + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @save_max_statement_time=@@max_statement_time; +SET GLOBAL max_statement_time=0.1; +UNLOCK TABLES;; +This would be a race condition otherwise, but default max_statement_time=0 makes it succeed + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (0); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +SET GLOBAL max_statement_time=@save_max_statement_time; +DROP DATABASE test1; +# +# End of 10.3 test +# diff --git a/mysql-test/main/mysqldump-timing.test b/mysql-test/main/mysqldump-timing.test new file mode 100644 index 00000000000..25921fdd0cd --- /dev/null +++ b/mysql-test/main/mysqldump-timing.test @@ -0,0 +1,26 @@ + + +--echo # +--echo # MDEV-18702 mysqldump should use max_statement_time=0 and/or allow setting one +--echo # + +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (0); +LOCK TABLE t1 WRITE; +--echo timeout without t1 contents expected +--error 2 +--exec $MYSQL_DUMP --max-statement-time=1 --skip-lock-tables --skip-comments test1 t1 +SET @save_max_statement_time=@@max_statement_time; +SET GLOBAL max_statement_time=0.1; +--send UNLOCK TABLES; +--echo This would be a race condition otherwise, but default max_statement_time=0 makes it succeed +--exec $MYSQL_DUMP --skip-lock-tables --skip-comments test1 t1 +--reap +SET GLOBAL max_statement_time=@save_max_statement_time; +DROP DATABASE test1; + +--echo # +--echo # End of 10.3 test +--echo # From 92b0a367aa9f4602f99d28eae5776c679984ac88 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 30 Jul 2022 13:29:17 +1000 Subject: [PATCH 02/14] MDEV-26447: mysqldump to use temporary view instead of tables. This is particularly important for Azure where there is no MyISAM support in their MariaDB cloud product. Like mysqldumper does, a view can satisfy the requirement like a table, without constraints. The views in frm files are text form and don't have column limits. Thanks Thomas Casteleyn for the suggestion. --- client/mysqldump.c | 51 +++-------- mysql-test/main/lock_view.result | 49 +++++------ mysql-test/main/mysqldump-nl.result | 11 ++- mysql-test/main/mysqldump.result | 117 ++++++++++---------------- mysql-test/suite/roles/definer.result | 47 +++++------ 5 files changed, 103 insertions(+), 172 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 0d9b48e585e..437677f3638 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3072,9 +3072,8 @@ static uint get_table_structure(const char *table, const char *db, char *table_t if (strcmp(field->name, "View") == 0) { char *scv_buff= NULL; - my_ulonglong n_cols; - verbose_msg("-- It's a view, create dummy table for view\n"); + verbose_msg("-- It's a view, create dummy view for view\n"); /* save "show create" statement for later */ if ((row= mysql_fetch_row(result)) && (scv_buff=row[1])) @@ -3083,9 +3082,9 @@ static uint get_table_structure(const char *table, const char *db, char *table_t mysql_free_result(result); /* - Create a table with the same name as the view and with columns of + Create a view with the same name as the view and with columns of the same name in order to satisfy views that depend on this view. - The table will be removed when the actual view is created. + The view will be removed when the actual view is created. The properties of each column, are not preserved in this temporary table, because they are not necessary. @@ -3117,23 +3116,9 @@ static uint get_table_structure(const char *table, const char *db, char *table_t else my_free(scv_buff); - n_cols= mysql_num_rows(result); - if (0 != n_cols) + if (mysql_num_rows(result) != 0) { - /* - The actual formula is based on the column names and how the .FRM - files are stored and is too volatile to be repeated here. - Thus we simply warn the user if the columns exceed a limit we - know works most of the time. - */ - if (n_cols >= 1000) - fprintf(stderr, - "-- Warning: Creating a stand-in table for view %s may" - " fail when replaying the dump file produced because " - "of the number of columns exceeding 1000. Exercise " - "caution when replaying the produced dump file.\n", - table); if (opt_drop) { /* @@ -3149,7 +3134,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t fprintf(sql_file, "SET @saved_cs_client = @@character_set_client;\n" "SET character_set_client = utf8;\n" - "/*!50001 CREATE TABLE %s (\n", + "/*!50001 CREATE VIEW %s AS SELECT\n", result_table); /* @@ -3161,28 +3146,21 @@ static uint get_table_structure(const char *table, const char *db, char *table_t row= mysql_fetch_row(result); /* - The actual column type doesn't matter anyway, since the table will + The actual column value doesn't matter anyway, since the view will be dropped at run time. - We do tinyint to avoid hitting the row size limit. */ - fprintf(sql_file, " %s tinyint NOT NULL", + fprintf(sql_file, " 1 AS %s", quote_name(row[0], name_buff, 0)); while((row= mysql_fetch_row(result))) { /* col name, col type */ - fprintf(sql_file, ",\n %s tinyint NOT NULL", + fprintf(sql_file, ",\n 1 AS %s", quote_name(row[0], name_buff, 0)); } - /* - Stand-in tables are always MyISAM tables as the default - engine might have a column-limit that's lower than the - number of columns in the view, and MyISAM support is - guaranteed to be in the server anyway. - */ fprintf(sql_file, - "\n) ENGINE=MyISAM */;\n" + " */;\n" "SET character_set_client = @saved_cs_client;\n"); check_io(sql_file); @@ -6642,15 +6620,8 @@ static my_bool get_view_structure(char *table, char* db) "\n--\n-- Final view structure for view %s\n--\n\n", fix_for_comment(result_table)); - /* Table might not exist if this view was dumped with --tab. */ - fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table); - if (opt_drop) - { - fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n", - opt_quoted_table); - check_io(sql_file); - } - + /* View might not exist if this view was dumped with --tab. */ + fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n", opt_quoted_table); my_snprintf(query, sizeof(query), "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE, " diff --git a/mysql-test/main/lock_view.result b/mysql-test/main/lock_view.result index 48c45dcf23d..6cc788f86f1 100644 --- a/mysql-test/main/lock_view.result +++ b/mysql-test/main/lock_view.result @@ -32,9 +32,8 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER USE `mysqltest2`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin1 */; @@ -42,39 +41,34 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest3` /*!40100 DEFAULT CHARACTER USE `mysqltest3`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3i` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3i` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3is` ( - `schema_name` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3is` AS SELECT + 1 AS `schema_name` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3nt` ( - `1` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3nt` AS SELECT + 1 AS `1` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3ps` ( - `user` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3ps` AS SELECT + 1 AS `user` */; SET character_set_client = @saved_cs_client; USE `mysqltest1`; USE `mysqltest2`; -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -89,7 +83,7 @@ USE `mysqltest2`; /*!50001 SET collation_connection = @saved_col_connection */; USE `mysqltest3`; -/*!50001 DROP TABLE IF EXISTS `v3`*/; +/*!50001 DROP VIEW IF EXISTS `v3`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -102,7 +96,7 @@ USE `mysqltest3`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3i`*/; +/*!50001 DROP VIEW IF EXISTS `v3i`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -115,7 +109,7 @@ USE `mysqltest3`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3is`*/; +/*!50001 DROP VIEW IF EXISTS `v3is`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -128,7 +122,7 @@ USE `mysqltest3`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3nt`*/; +/*!50001 DROP VIEW IF EXISTS `v3nt`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -141,7 +135,7 @@ USE `mysqltest3`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3ps`*/; +/*!50001 DROP VIEW IF EXISTS `v3ps`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -243,11 +237,10 @@ disconnect con1; connection default; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `id` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `id` */; SET character_set_client = @saved_cs_client; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; diff --git a/mysql-test/main/mysqldump-nl.result b/mysql-test/main/mysqldump-nl.result index 89fb3144867..bac1ccb6ea0 100644 --- a/mysql-test/main/mysqldump-nl.result +++ b/mysql-test/main/mysqldump-nl.result @@ -53,11 +53,10 @@ raboof` int(11) DEFAULT NULL SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1 -1v` ( - `foobar -raboof` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1 +1v` AS SELECT + 1 AS `foobar +raboof` */; SET character_set_client = @saved_cs_client; -- @@ -95,7 +94,7 @@ USE `mysqltest1 -- 1v` -- -/*!50001 DROP TABLE IF EXISTS `v1 +/*!50001 DROP VIEW IF EXISTS `v1 1v`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 1ddda58e368..8babe0239b8 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -2068,11 +2068,9 @@ DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; -/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2162,11 +2160,9 @@ DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; -/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2236,11 +2232,9 @@ DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; -/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2350,31 +2344,27 @@ DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `a` tinyint NOT NULL, - `b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `a`, + 1 AS `b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `a` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a` */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v3`; /*!50001 DROP VIEW IF EXISTS `v3`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3` ( - `a` tinyint NOT NULL, - `b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3` AS SELECT + 1 AS `a`, + 1 AS `b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; -/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2388,7 +2378,6 @@ SET character_set_client = @saved_cs_client; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2402,7 +2391,6 @@ SET character_set_client = @saved_cs_client; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3`*/; /*!50001 DROP VIEW IF EXISTS `v3`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3107,35 +3095,31 @@ DROP TABLE IF EXISTS `v0`; /*!50001 DROP VIEW IF EXISTS `v0`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v0` ( - `a` tinyint NOT NULL, - `b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v0` AS SELECT + 1 AS `a`, + 1 AS `b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `a` tinyint NOT NULL, - `b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `a`, + 1 AS `b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `a` tinyint NOT NULL, - `b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a`, + 1 AS `b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; USE `test`; -/*!50001 DROP TABLE IF EXISTS `v0`*/; /*!50001 DROP VIEW IF EXISTS `v0`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3149,7 +3133,6 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3163,7 +3146,6 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3401,7 +3383,7 @@ insert into t values(5, 51); create view v1 as select qty, price, qty*price as value from t; create view v2 as select qty from v1; mysqldump { -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -3416,7 +3398,7 @@ mysqldump { /*!50001 SET collation_connection = @saved_col_connection */; } mysqldump { -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -3509,13 +3491,11 @@ DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `id` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `id` */; SET character_set_client = @saved_cs_client; USE `mysqldump_test_db`; -/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3569,15 +3549,14 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_views` /*!40100 DEFAULT CHAR USE `mysqldump_views`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `nasishnasifu` ( - `id` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `nasishnasifu` AS SELECT + 1 AS `id` */; SET character_set_client = @saved_cs_client; USE `mysqldump_tables`; USE `mysqldump_views`; -/*!50001 DROP TABLE IF EXISTS `nasishnasifu`*/; +/*!50001 DROP VIEW IF EXISTS `nasishnasifu`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -3978,11 +3957,9 @@ DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `c` */; SET character_set_client = @saved_cs_client; -/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -4400,13 +4377,11 @@ DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `id` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `id` */; SET character_set_client = @saved_cs_client; USE `mysqldump_test_db`; -/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -5494,9 +5469,8 @@ CREATE TABLE `nonunique_table_name` ( /*!40101 SET character_set_client = @saved_cs_client */; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `nonunique_table_view_name` ( - `1` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `nonunique_table_view_name` AS SELECT + 1 AS `1` */; SET character_set_client = @saved_cs_client; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db2` /*!40100 DEFAULT CHARACTER SET utf8 */; @@ -5519,7 +5493,7 @@ CREATE TABLE `nonunique_table_view_name` ( INSERT INTO `nonunique_table_view_name` VALUES (3),(4); USE `db1`; -/*!50001 DROP TABLE IF EXISTS `nonunique_table_view_name`*/; +/*!50001 DROP VIEW IF EXISTS `nonunique_table_view_name`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -5595,15 +5569,14 @@ CREATE TABLE `nonunique_table_name` ( INSERT INTO `nonunique_table_name` VALUES (5),(6); SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `nonunique_table_view_name` ( - `1` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `nonunique_table_view_name` AS SELECT + 1 AS `1` */; SET character_set_client = @saved_cs_client; USE `db2`; USE `db1`; -/*!50001 DROP TABLE IF EXISTS `nonunique_table_view_name`*/; +/*!50001 DROP VIEW IF EXISTS `nonunique_table_view_name`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result index a5551e7dede..bc79ad8a98c 100644 --- a/mysql-test/suite/roles/definer.result +++ b/mysql-test/suite/roles/definer.result @@ -280,39 +280,34 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v1` ( - `a+b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v2` ( - `a+b` tinyint NOT NULL, - `c` tinyint NOT NULL, - `current_role()` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a+b`, + 1 AS `c`, + 1 AS `current_role()` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v3` ( - `a+b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v3` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v4` ( - `a+b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v4` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; -/*!50001 CREATE TABLE `v5` ( - `a+b` tinyint NOT NULL, - `c` tinyint NOT NULL -) ENGINE=MyISAM */; +/*!50001 CREATE VIEW `v5` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; SET character_set_client = @saved_cs_client; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 */; @@ -536,7 +531,7 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; USE `test`; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -547,7 +542,7 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -558,7 +553,7 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3`*/; +/*!50001 DROP VIEW IF EXISTS `v3`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -571,7 +566,7 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v4`*/; +/*!50001 DROP VIEW IF EXISTS `v4`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -584,7 +579,7 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v5`*/; +/*!50001 DROP VIEW IF EXISTS `v5`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; From 07a670b8848e00672b2274a30f44e79cdba20376 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 2 Aug 2022 11:42:20 +0200 Subject: [PATCH 03/14] MDEV-23097 heap-use-after-free in mysqlimport mysqlimport starts many worker threads. when one of the worker encounters an error, it frees global memory and calls exit(). it suppresses memory leak detector, because, as the comment says "dirty exit, some threads are still running", indeed, it cannot free the memory from other threads. but precisely because some threads are still running, they might use this global memory, so it cannot be freed. fix: if we know that some threads are still running and accept that we cannot free all memory anyway, let's not free global allocations either --- client/mysqlimport.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 880d3ff07cf..9d83e65535d 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -524,16 +524,18 @@ static void safe_exit(int error, MYSQL *mysql) if (mysql) mysql_close(mysql); - mysql_library_end(); -#ifdef HAVE_SMEM - my_free(shared_memory_base_name); -#endif - free_defaults(argv_to_free); - my_free(opt_password); if (error) sf_leaking_memory= 1; /* dirty exit, some threads are still running */ else + { + mysql_library_end(); +#ifdef HAVE_SMEM + my_free(shared_memory_base_name); +#endif + free_defaults(argv_to_free); + my_free(opt_password); my_end(my_end_arg); /* clean exit */ + } exit(error); } From c2300d06f7845f51db6318c2fdcbadd6becc0e89 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 1 Aug 2022 20:52:10 -0700 Subject: [PATCH 04/14] MDEV-28617 Crash with INSERT...SELECT using derived table in GROUP BY clause This bug manifested itself for INSERT...SELECT and DELETE statements whose WHERE condition used an IN/ANY/ALL predicand or a EXISTS predicate with such grouping subquery that: - its GROUP BY clause could be eliminated, - the GROUP clause contained a subquery over a mergeable derived table referencing the updated table. The bug ultimately caused a server crash when the prepare phase of the statement processing was executed. This happened after removal redundant subqueries used in the eliminated GROUP BY clause from the statement tree. The function that excluded the subqueries from the did not do it properly. As a result the specification of any derived table contained in a removed subquery was not marked as excluded. Approved by Oleksandr Byelkin --- mysql-test/main/insert_select.result | 89 ++++++++++++++++++++++++++++ mysql-test/main/insert_select.test | 82 +++++++++++++++++++++++++ sql/sql_lex.cc | 7 ++- 3 files changed, 175 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/insert_select.result b/mysql-test/main/insert_select.result index ea770535e8f..3f9ac8c6322 100644 --- a/mysql-test/main/insert_select.result +++ b/mysql-test/main/insert_select.result @@ -954,3 +954,92 @@ ERROR 23000: Duplicate entry '-128' for key 'a' DROP TABLE t1, t2; DROP PROCEDURE p1; # End of 10.2 test +# +# MDEV-28617: INSERT ... SELECT with redundant IN subquery in GROUP BY +# list that uses mergeable derived table containing +# reference to target table +# +create table t1 (a int); +create table t2 (b int); +create table t3 (c int); +insert into t1 values (3), (1); +insert into t2 values (3), (2); +insert into t3 values (4), (2); +insert into t1 +select b from t2 +where b in (select c from t3 +group by (select * from (select a from t1) dt where a = 1)); +select * from t1; +a +3 +1 +2 +delete from t1; +insert into t1 values (3), (1); +insert into t1 +select b from t2 +where b >= any (select c from t3 +group by (select * from (select a from t1) dt where a = 1)); +select * from t1; +a +3 +1 +3 +2 +delete from t1; +insert into t1 values (3), (1); +insert into t1 +select b from t2 +where b <= all (select c from t3 +group by (select * from (select a from t1) dt where a = 1)); +select * from t1; +a +3 +1 +2 +delete from t1; +insert into t1 values (3), (1); +insert into t1 +select b from t2 +where exists (select c from t3 +group by (select * from (select a from t1) dt where a = 1)); +select * from t1; +a +3 +1 +3 +2 +delete from t1; +insert into t1 values (3), (1); +prepare stmt from " +insert into t1 +select b from t2 + where b in (select c from t3 + group by (select * from (select a from t1) dt where a = 1)); +"; +execute stmt; +select * from t1; +a +3 +1 +2 +delete from t1; +insert into t1 values (3), (1); +execute stmt; +select * from t1; +a +3 +1 +2 +delete from t1; +insert into t1 values (3), (1); +delete from t1 +where exists (select b from t2 +where b in (select c from t3 +group by (select * from (select a from t1) dt +where a = 1))); +select * from t1; +a +deallocate prepare stmt; +drop table t1,t2,t3; +# End of 10.3 test diff --git a/mysql-test/main/insert_select.test b/mysql-test/main/insert_select.test index 1f672acc203..6baa7e43c34 100644 --- a/mysql-test/main/insert_select.test +++ b/mysql-test/main/insert_select.test @@ -514,3 +514,85 @@ DROP TABLE t1, t2; DROP PROCEDURE p1; --echo # End of 10.2 test + +--echo # +--echo # MDEV-28617: INSERT ... SELECT with redundant IN subquery in GROUP BY +--echo # list that uses mergeable derived table containing +--echo # reference to target table +--echo # + +create table t1 (a int); +create table t2 (b int); +create table t3 (c int); + +insert into t1 values (3), (1); +insert into t2 values (3), (2); +insert into t3 values (4), (2); + +insert into t1 +select b from t2 + where b in (select c from t3 + group by (select * from (select a from t1) dt where a = 1)); +select * from t1; + +delete from t1; +insert into t1 values (3), (1); + +insert into t1 +select b from t2 + where b >= any (select c from t3 + group by (select * from (select a from t1) dt where a = 1)); +select * from t1; + +delete from t1; +insert into t1 values (3), (1); + +insert into t1 +select b from t2 + where b <= all (select c from t3 + group by (select * from (select a from t1) dt where a = 1)); +select * from t1; + +delete from t1; +insert into t1 values (3), (1); + +insert into t1 +select b from t2 + where exists (select c from t3 + group by (select * from (select a from t1) dt where a = 1)); +select * from t1; + +delete from t1; +insert into t1 values (3), (1); + +prepare stmt from " +insert into t1 +select b from t2 + where b in (select c from t3 + group by (select * from (select a from t1) dt where a = 1)); +"; + +execute stmt; +select * from t1; + +delete from t1; +insert into t1 values (3), (1); + +execute stmt; +select * from t1; + +delete from t1; +insert into t1 values (3), (1); + +delete from t1 + where exists (select b from t2 + where b in (select c from t3 + group by (select * from (select a from t1) dt + where a = 1))); +select * from t1; + +deallocate prepare stmt; + +drop table t1,t2,t3; + +--echo # End of 10.3 test diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e4c5b7cbd75..3400e31fd5c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2530,6 +2530,7 @@ void st_select_lex_node::fast_exclude() for (; slave; slave= slave->next) slave->fast_exclude(); + prev= NULL; // to ensure correct behavior of st_select_lex_unit::is_excluded() } @@ -2604,9 +2605,7 @@ void st_select_lex_node::exclude_from_tree() */ void st_select_lex_node::exclude() { - /* exclude from global list */ - fast_exclude(); - /* exclude from other structures */ + /* exclude the node from the tree */ exclude_from_tree(); /* We do not need following statements, because prev pointer of first @@ -2614,6 +2613,8 @@ void st_select_lex_node::exclude() if (master->slave == this) master->slave= next; */ + /* exclude all nodes under this excluded node */ + fast_exclude(); } From 8fd8a81a9933e6a5b8afe2e7a2655652bd7c7190 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 3 Aug 2022 12:49:49 +0200 Subject: [PATCH 05/14] Fix Oracle parser. --- sql/sql_yacc_ora.yy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index c079598a169..f49efa8c262 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -2330,6 +2330,7 @@ create: { if (Lex->main_select_push()) MYSQL_YYABORT; + Lex->inc_select_stack_outer_barrier(); if (Lex->add_create_view(thd, $1 | $5, DTYPE_ALGORITHM_UNDEFINED, $3, $6)) MYSQL_YYABORT; @@ -2345,6 +2346,7 @@ create: MYSQL_YYABORT; if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7)) MYSQL_YYABORT; + Lex->inc_select_stack_outer_barrier(); } view_list_opt AS view_select { From d7649968d9d80c35b6fd382f89e6b73d7c41ddb4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Aug 2022 00:11:34 +0200 Subject: [PATCH 06/14] MDEV-29220 Missing RHEL-9-specific logic in cpack_rpm.cmake --- cmake/cpack_rpm.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index e8419682f64..cb717e3b708 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -264,7 +264,7 @@ ELSEIF(RPM MATCHES "fedora" OR RPM MATCHES "(rhel|centos)7") ALTERNATIVE_NAME("server" "mariadb-server") ALTERNATIVE_NAME("server" "mysql-compat-server") ALTERNATIVE_NAME("test" "mariadb-test") -ELSEIF(RPM MATCHES "(rhel|centos)8") +ELSEIF(RPM MATCHES "(rhel|centos|rocky)[89]") SET(epoch 3:) ALTERNATIVE_NAME("backup" "mariadb-backup") ALTERNATIVE_NAME("client" "mariadb") From cd51854d7a69f6518a84403fa428af5035e946a8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Aug 2022 13:31:48 +0200 Subject: [PATCH 07/14] RHEL9 disables SHA1 signatures in openssl with its 0049-Selectively-disallow-SHA1-signatures.patch in the openssl source rpm. let's allow them for now, this fixes tls_version and tls_version1 tests. --- mysql-test/include/default_my.cnf | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/include/default_my.cnf b/mysql-test/include/default_my.cnf index d102c9020cc..a1c427fe12c 100644 --- a/mysql-test/include/default_my.cnf +++ b/mysql-test/include/default_my.cnf @@ -33,3 +33,4 @@ disable-force-if-open [ENV] MASTER_MYPORT= @mysqld.1.port MASTER_MYSOCK= @mysqld.1.socket +OPENSSL_ENABLE_SHA1_SIGNATURES= 1 From f9ec9b6abbce8c88b0cfd1888135b9701415162a Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 20 Jul 2022 14:14:43 +0530 Subject: [PATCH 08/14] MDEV-27282 InnoDB: Failing assertion: !query->intersection - query->intersection fails to get freed if the query exceeds innodb_ft_result_cache_limit - errors from init_ftfuncs were not propogated by delete command This is taken from percona/percona-server@ef2c0bcb9a34aeb06de0058d7c2a2969416b35a7 --- .../innodb_fts/r/ft_result_cache_limit.result | 39 +++++++++++++ .../innodb_fts/t/ft_result_cache_limit.test | 57 +++++++++++++++++++ sql/item_func.cc | 2 + sql/sql_delete.cc | 4 +- storage/innobase/fts/fts0que.cc | 15 +++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result create mode 100644 mysql-test/suite/innodb_fts/t/ft_result_cache_limit.test diff --git a/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result b/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result new file mode 100644 index 00000000000..2dbdd5a04bc --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result @@ -0,0 +1,39 @@ +# +# Bug 1634932: Assertion failure in thread x in +# file fts0que.cc +# +SET @saved_innodb_ft_result_cache_limit= @@global.innodb_ft_result_cache_limit; +CREATE TABLE `t1` ( +`FTS_DOC_ID` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, +`text_content` MEDIUMTEXT, PRIMARY KEY (`FTS_DOC_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +CREATE UNIQUE INDEX FTS_DOC_ID_INDEX ON t1(FTS_DOC_ID); +SET autocommit=0; +CREATE PROCEDURE populate_t1() +BEGIN +DECLARE i INT DEFAULT 1; +WHILE (i <= 250) DO +INSERT INTO t1 (text_content) VALUES ("some_text_1234 aaa"); +SET i = i + 1; +END WHILE; +END// +CALL populate_t1; +SET autocommit=1; +SET SESSION debug="+d,fts_instrument_result_cache_limit"; +Warnings: +Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +ALTER TABLE t1 ADD FULLTEXT INDEX `text_content_idx` (`text_content`); +SELECT FTS_DOC_ID, text_content +FROM t1 +WHERE MATCH text_content AGAINST ('+some_text_1234' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +UPDATE t1 +SET text_content='some_text_12345' +where MATCH text_content AGAINST ('+some_text_1234' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +DELETE FROM t1 +WHERE MATCH text_content AGAINST ('+some_text_1234' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SET GLOBAL innodb_ft_result_cache_limit = @saved_innodb_ft_result_cache_limit; +DROP TABLE t1; +DROP PROCEDURE populate_t1; diff --git a/mysql-test/suite/innodb_fts/t/ft_result_cache_limit.test b/mysql-test/suite/innodb_fts/t/ft_result_cache_limit.test new file mode 100644 index 00000000000..84254a182d7 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/ft_result_cache_limit.test @@ -0,0 +1,57 @@ +--echo # +--echo # Bug 1634932: Assertion failure in thread x in +--echo # file fts0que.cc +--echo # + +--source include/have_innodb.inc +--source include/have_debug.inc + +SET @saved_innodb_ft_result_cache_limit= @@global.innodb_ft_result_cache_limit; + +CREATE TABLE `t1` ( + `FTS_DOC_ID` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `text_content` MEDIUMTEXT, PRIMARY KEY (`FTS_DOC_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE UNIQUE INDEX FTS_DOC_ID_INDEX ON t1(FTS_DOC_ID); + +SET autocommit=0; + +DELIMITER //; +CREATE PROCEDURE populate_t1() +BEGIN + DECLARE i INT DEFAULT 1; + WHILE (i <= 250) DO + INSERT INTO t1 (text_content) VALUES ("some_text_1234 aaa"); + SET i = i + 1; + END WHILE; +END// + +DELIMITER ;// + +CALL populate_t1; +SET autocommit=1; + +SET SESSION debug="+d,fts_instrument_result_cache_limit"; + +ALTER TABLE t1 ADD FULLTEXT INDEX `text_content_idx` (`text_content`); + +# HA_ERR_FTS_EXCEED_RESULT_CACHE_LIMIT = 188 +--error 128 +SELECT FTS_DOC_ID, text_content +FROM t1 +WHERE MATCH text_content AGAINST ('+some_text_1234' IN BOOLEAN MODE); + +--error 128 +UPDATE t1 +SET text_content='some_text_12345' +where MATCH text_content AGAINST ('+some_text_1234' IN BOOLEAN MODE); + +--error 128 +DELETE FROM t1 +WHERE MATCH text_content AGAINST ('+some_text_1234' IN BOOLEAN MODE); + +SET GLOBAL innodb_ft_result_cache_limit = @saved_innodb_ft_result_cache_limit; + +DROP TABLE t1; +DROP PROCEDURE populate_t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 3fd69405456..2c79ca531d3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6012,6 +6012,8 @@ bool Item_func_match::init_search(THD *thd, bool no_order) ft_handler= table->file->ft_init_ext(flags, key, ft_tmp); + if (!ft_handler) + DBUG_RETURN(1); if (join_key) table->file->ft_handler=ft_handler; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index a0d8feb61e8..95de5d6ad61 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1184,7 +1184,9 @@ multi_delete::initialize_tables(JOIN *join) table->file->ref_length, MEM_STRIP_BUF_SIZE); } - init_ftfuncs(thd, thd->lex->current_select, 1); + if (init_ftfuncs(thd, thd->lex->current_select, 1)) + DBUG_RETURN(true); + DBUG_RETURN(thd->is_fatal_error); } diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 01227a8df58..f7fc543e211 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1202,6 +1202,14 @@ fts_query_difference( return(query->error); } +/* Free the query intersection +@param query query instance */ +static void fts_query_free_intersection(fts_query_t* query) +{ + fts_query_free_doc_ids(query, query->intersection); + query->intersection = NULL; +} + /*****************************************************************//** Intersect the token doc ids with the current set. @return DB_SUCCESS if all go well */ @@ -1300,6 +1308,7 @@ fts_query_intersect( /* error is passed by 'query->error' */ if (query->error != DB_SUCCESS) { ut_ad(query->error == DB_FTS_EXCEED_RESULT_CACHE_LIMIT); + fts_query_free_intersection(query); return(query->error); } @@ -1328,6 +1337,8 @@ fts_query_intersect( ut_a(!query->multi_exist || (query->multi_exist && rbt_size(query->doc_ids) <= n_doc_ids)); + } else if (query->intersection) { + fts_query_free_intersection(query); } } @@ -1546,6 +1557,10 @@ fts_merge_doc_ids( query, ranking->doc_id, ranking->rank); if (query->error != DB_SUCCESS) { + if (query->intersection) { + ut_a(query->oper == FTS_EXIST); + fts_query_free_intersection(query); + } DBUG_RETURN(query->error); } From 2cd98c95dee7ae77e6280b4e047a2ebec00b5442 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 3 Aug 2022 16:07:16 +0300 Subject: [PATCH 09/14] MDEV-23809: Server crash in JOIN_CACHE::free or ... The problem was caused by use of COLLATION(AVG('x')). This is an item whose value is a constant. Name Resolution code called convert_const_to_int() which removed AVG('x'). However, the item representing COLLATION(...) still had with_sum_func=1. This inconsistent state confused the code that handles grouping and DISTINCT: JOIN::get_best_combination() decided to use one temporary table and allocated one JOIN_TAB for it, but then JOIN::make_aggr_tables_info() attempted to use two and made writes beyond the end of the JOIN::join_tab array. The fix: - Do not replace constant expressions which contain aggregate functions. - Add JOIN::dbug_join_tab_array_size to catch attempts to use more JOIN_TAB objects than we've allocated. --- mysql-test/main/func_group.result | 25 +++++++++++++++++++++++++ mysql-test/main/func_group.test | 19 +++++++++++++++++++ sql/item_cmpfunc.cc | 13 ++++++++++++- sql/sql_select.cc | 12 ++++++++++++ sql/sql_select.h | 1 + 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index 37d8e15e52d..d5ac57d5443 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -2523,5 +2523,30 @@ DROP TABLE t2; DROP VIEW v1; DROP TABLE t1; # +# MDEV-23809: Server crash in JOIN_CACHE::free or ... +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +SELECT DISTINCT CASE CONVERT(EXPORT_SET(0, COLLATION(BENCHMARK(1, BIT_OR(0))),0),TIME) WHEN a THEN 1 END AS f FROM t1; +f +NULL +Warnings: +Warning 1292 Truncated incorrect time value: '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(8) NULL, b BIGINT); +INSERT INTO t1 (a,b) VALUES (NULL,NULL),('foo',NULL); +SELECT DISTINCT STRCMP((b > COLLATION(STDDEV_SAMP(15750))), a) AS f FROM t1; +f +NULL +DROP TABLE t1; +CREATE TABLE t1 (a BIGINT) AS SELECT 1 AS v3 UNION SELECT FALSE ; +SELECT DISTINCT a IN ( COLLATION (AVG ('x'))) FROM t1 ; +a IN ( COLLATION (AVG ('x'))) +NULL +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +DROP TABLE t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test index fb2106ac3ae..f91aee3e577 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -1756,6 +1756,25 @@ DROP TABLE t2; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-23809: Server crash in JOIN_CACHE::free or ... +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +SELECT DISTINCT CASE CONVERT(EXPORT_SET(0, COLLATION(BENCHMARK(1, BIT_OR(0))),0),TIME) WHEN a THEN 1 END AS f FROM t1; +DROP TABLE t1; + + +CREATE TABLE t1 (a VARCHAR(8) NULL, b BIGINT); +INSERT INTO t1 (a,b) VALUES (NULL,NULL),('foo',NULL); +SELECT DISTINCT STRCMP((b > COLLATION(STDDEV_SAMP(15750))), a) AS f FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a BIGINT) AS SELECT 1 AS v3 UNION SELECT FALSE ; +SELECT DISTINCT a IN ( COLLATION (AVG ('x'))) FROM t1 ; +DROP TABLE t1; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a3c0d4d95df..fe6b8feb4de 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -340,7 +340,18 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, field_item->field_type() != MYSQL_TYPE_YEAR) return 1; - if ((*item)->const_item() && !(*item)->is_expensive()) + /* + Replace (*item) with its value if the item can be computed. + + Do not replace items that contain aggregate functions: + There can be such items that are constants, e.g. COLLATION(AVG(123)), + but this function is called at Name Resolution phase. + Removing aggregate functions may confuse query plan generation code, e.g. + the optimizer might conclude that the query doesn't need to do grouping + at all. + */ + if ((*item)->const_item() && !(*item)->is_expensive() && + !(*item)->with_sum_func) { TABLE *table= field->table; Sql_mode_save sql_mode(thd); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 33fb19966b2..a865c75184f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1596,6 +1596,9 @@ JOIN::optimize_inner() DEBUG_SYNC(thd, "before_join_optimize"); THD_STAGE_INFO(thd, stage_optimizing); +#ifndef DBUG_OFF + dbug_join_tab_array_size= 0; +#endif set_allowed_join_cache_types(); need_distinct= TRUE; @@ -2740,6 +2743,9 @@ setup_subq_exit: { if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) DBUG_RETURN(1); +#ifndef DBUG_OFF + dbug_join_tab_array_size= 1; +#endif need_tmp= 1; } if (make_aggr_tables_info()) @@ -3044,6 +3050,7 @@ bool JOIN::make_aggr_tables_info() { aggr_tables++; curr_tab= join_tab + exec_join_tab_cnt(); + DBUG_ASSERT(curr_tab - join_tab < dbug_join_tab_array_size); bzero((void*)curr_tab, sizeof(JOIN_TAB)); curr_tab->ref.key= -1; if (only_const_tables()) @@ -3172,6 +3179,7 @@ bool JOIN::make_aggr_tables_info() curr_tab++; aggr_tables++; + DBUG_ASSERT(curr_tab - join_tab < dbug_join_tab_array_size); bzero((void*)curr_tab, sizeof(JOIN_TAB)); curr_tab->ref.key= -1; @@ -9781,6 +9789,10 @@ bool JOIN::get_best_combination() fix_semijoin_strategies_for_picked_join_order(this); +#ifndef DBUG_OFF + dbug_join_tab_array_size= top_join_tab_count + aggr_tables; +#endif + if (inject_splitting_cond_for_all_tables_with_split_opt()) DBUG_RETURN(TRUE); diff --git a/sql/sql_select.h b/sql/sql_select.h index c8ff8b24385..fe6a640003f 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1265,6 +1265,7 @@ public: #ifndef DBUG_OFF void dbug_verify_sj_inner_tables(uint n_positions) const; + uint dbug_join_tab_array_size; #endif /* We also maintain a stack of join optimization states in * join->positions[] */ From 37a3d4467e3115f4d4dfcad0a6ee3c23e785f524 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 3 Aug 2022 17:55:45 +0300 Subject: [PATCH 10/14] MDEV-23809: Server crash in JOIN_CACHE::free ...: part #2 Part #2: make sure we allocate space for two JOIN_TABs that use temporary tables. The dbug_join_tab_array_size is still set to catch cases where we try to access more JOIN_TAB object than we thought we would have. --- sql/sql_select.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a865c75184f..70c0a80ba2a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9780,6 +9780,23 @@ bool JOIN::get_best_combination() if (aggr_tables > 2) aggr_tables= 2; + +#ifndef DBUG_OFF + dbug_join_tab_array_size= top_join_tab_count + aggr_tables; +#endif + /* + NOTE: The above computation of aggr_tables can produce wrong result because some + of the variables it uses may change their values after we leave this function. + Known examples: + - Dangerous: using_outer_summary_function=false at this point. Added + DBUG_ASSERT below to demonstrate. Can this cause us to allocate less + space than we would need? + - Not dangerous: select_distinct can be true here but be assigned false + afterwards. + */ + aggr_tables= 2; + DBUG_ASSERT(!tmp_table_param.using_outer_summary_function); + if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)* (top_join_tab_count + aggr_tables)))) DBUG_RETURN(TRUE); @@ -9789,10 +9806,6 @@ bool JOIN::get_best_combination() fix_semijoin_strategies_for_picked_join_order(this); -#ifndef DBUG_OFF - dbug_join_tab_array_size= top_join_tab_count + aggr_tables; -#endif - if (inject_splitting_cond_for_all_tables_with_split_opt()) DBUG_RETURN(TRUE); From c6406643cdba6f38d2c820169a36dbf4921bfeca Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 4 Aug 2022 10:01:24 +0200 Subject: [PATCH 11/14] Fix compile errors. --- sql/sql_select.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.h b/sql/sql_select.h index 9051b7fd2b8..ecfa4c6fd11 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1289,7 +1289,7 @@ public: #ifndef DBUG_OFF void dbug_verify_sj_inner_tables(uint n_positions) const; - uint dbug_join_tab_array_size; + int dbug_join_tab_array_size; #endif /* We also maintain a stack of join optimization states in * join->positions[] */ From 992b510b2ff8877091d5c36b31d1882e8c4a233f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 4 Aug 2022 10:01:24 +0200 Subject: [PATCH 12/14] Fix compile errors. --- sql/sql_select.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.h b/sql/sql_select.h index fe6a640003f..a953354abb0 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1265,7 +1265,7 @@ public: #ifndef DBUG_OFF void dbug_verify_sj_inner_tables(uint n_positions) const; - uint dbug_join_tab_array_size; + int dbug_join_tab_array_size; #endif /* We also maintain a stack of join optimization states in * join->positions[] */ From 43c7f6a0f3d2d636fea0decfc9b5818e4a7c885a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 4 Aug 2022 19:41:09 +1000 Subject: [PATCH 13/14] MDEV-18702: mysqldump: add variable 'max-statement-time' (mtr fix) Disable for embedded as mysqldump cannot connect to embedded server. --- mysql-test/main/mysqldump-timing.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/main/mysqldump-timing.test b/mysql-test/main/mysqldump-timing.test index 25921fdd0cd..07305b73a72 100644 --- a/mysql-test/main/mysqldump-timing.test +++ b/mysql-test/main/mysqldump-timing.test @@ -1,4 +1,4 @@ - +--source include/not_embedded.inc --echo # --echo # MDEV-18702 mysqldump should use max_statement_time=0 and/or allow setting one From 3b071bad1981a12e76769cbfc31b62fbd7362372 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 4 Aug 2022 12:51:32 +0300 Subject: [PATCH 14/14] MDEV-29242: Assertion `computed_weight == weight' failed SEL_ARG::verify_weight Make SEL_ARG::make_root() maintain SEL_ARG::weight. Also, an unrelated change: fix dbug_print_sel_arg() to correctly print SQL NULL for the right endpoint. --- mysql-test/main/range_notembedded.result | 9 +++++++++ mysql-test/main/range_notembedded.test | 9 +++++++++ sql/opt_range.cc | 5 ++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/range_notembedded.result b/mysql-test/main/range_notembedded.result index eeab230e72f..6d2f73cd3f9 100644 --- a/mysql-test/main/range_notembedded.result +++ b/mysql-test/main/range_notembedded.result @@ -248,3 +248,12 @@ WHERE (help_topic_id < '2' OR help_topic_id != 8 OR help_topic_id < 1) AND help_keyword_id = help_topic_id; help_topic_id help_keyword_id +# +# MDEV-29242: Assertion `computed_weight == weight' failed SEL_ARG::verify_weight +# +CREATE TABLE t1 (id INT, KEY (id)); +INSERT INTO t1 VALUES (1),(5); +SELECT id FROM t1 WHERE id IS NULL OR id NOT BETWEEN 1 AND 4; +id +5 +DROP TABLE t1; diff --git a/mysql-test/main/range_notembedded.test b/mysql-test/main/range_notembedded.test index 4e77d6a4810..00d16a5d564 100644 --- a/mysql-test/main/range_notembedded.test +++ b/mysql-test/main/range_notembedded.test @@ -150,3 +150,12 @@ FROM mysql.help_relation WHERE (help_topic_id < '2' OR help_topic_id != 8 OR help_topic_id < 1) AND help_keyword_id = help_topic_id; + +--echo # +--echo # MDEV-29242: Assertion `computed_weight == weight' failed SEL_ARG::verify_weight +--echo # +CREATE TABLE t1 (id INT, KEY (id)); +INSERT INTO t1 VALUES (1),(5); +SELECT id FROM t1 WHERE id IS NULL OR id NOT BETWEEN 1 AND 4; +DROP TABLE t1; + diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 1cc573f90f2..ee2ac81abeb 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1901,7 +1901,9 @@ inline void SEL_ARG::make_root() left=right= &null_element; color=BLACK; next=prev=0; - use_count=0; elements=1; + use_count=0; + elements=1; + weight= 1 + (next_key_part? next_key_part->weight : 0); } SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg, @@ -16153,6 +16155,7 @@ const char *dbug_print_sel_arg(SEL_ARG *sel_arg) out.append("+inf"); else { + buf.length(0); print_sel_arg_key(sel_arg->field, sel_arg->max_value, &buf); out.append(buf); }