From 178d32f03b84004af3611aab7c6fb9ce0b1388f4 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 1 Dec 2020 14:13:05 +0400 Subject: [PATCH 01/72] MDEV-24318 server_audit doesn't respect filters for PROXY_CONNECT events. The log line should be added behind the filters. --- mysql-test/suite/plugins/r/server_audit.result | 2 +- plugin/server_audit/server_audit.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 7c287b369b1..f309b6c95a3 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -440,8 +440,8 @@ TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,,,0 TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,user, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT PROXY ON plug_dest TO plug',0 -TIME,HOSTNAME,plug,localhost,ID,0,PROXY_CONNECT,test,`plug_dest`@`%`,0 TIME,HOSTNAME,plug,localhost,ID,0,CONNECT,test,,0 +TIME,HOSTNAME,plug,localhost,ID,0,PROXY_CONNECT,test,`plug_dest`@`%`,0 TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,test,,0 TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,user, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db, diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index a4884f17c75..fe8bf4478fc 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -2067,13 +2067,9 @@ static void update_connection_info(struct connection_info *cn, { case MYSQL_AUDIT_CONNECTION_CONNECT: setup_connection_connect(cn, event); - if (event->status == 0 && event->proxy_user && event->proxy_user[0]) - log_proxy(cn, event); break; case MYSQL_AUDIT_CONNECTION_CHANGE_USER: *after_action= AA_CHANGE_USER; - if (event->proxy_user && event->proxy_user[0]) - log_proxy(cn, event); break; default:; } @@ -2191,6 +2187,8 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) { case MYSQL_AUDIT_CONNECTION_CONNECT: log_connection(cn, event, event->status ? "FAILED_CONNECT": "CONNECT"); + if (event->status == 0 && event->proxy_user && event->proxy_user[0]) + log_proxy(cn, event); break; case MYSQL_AUDIT_CONNECTION_DISCONNECT: if (use_event_data_for_disconnect) @@ -2200,6 +2198,8 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) break; case MYSQL_AUDIT_CONNECTION_CHANGE_USER: log_connection(cn, event, "CHANGEUSER"); + if (event->proxy_user && event->proxy_user[0]) + log_proxy(cn, event); break; default:; } From b6ce493d53fe2a825fb5fe548ff128cdb11e0fab Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 2 Dec 2020 12:58:51 +0530 Subject: [PATCH 02/72] Fixing compile failure on kvm full-text --- sql/sql_type.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 0bae1e55145..32862be371a 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -5999,11 +5999,18 @@ LEX_CSTRING Charset::collation_specific_name() const for character sets and collations, so a collation name not necessarily starts with the character set name. */ + LEX_CSTRING retval; size_t csname_length= strlen(m_charset->csname); if (strncmp(m_charset->name, m_charset->csname, csname_length)) - return {NULL, 0}; + { + retval.str= NULL; + retval.length= 0; + return retval; + } const char *ptr= m_charset->name + csname_length; - return {ptr, strlen(ptr) }; + retval.str= ptr; + retval.length= strlen(ptr); + return retval; } From a50cb4867a7f63bfc03b33bfb5be8d47d15ba64d Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 2 Dec 2020 11:34:37 +0300 Subject: [PATCH 03/72] MDEV-24334 make monitor_set_tbl global variable thread-safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atomic_relaxed: add fetch_or() and fetch_and() innodb_init(): rely on a zero-initialization of a global variable monitor_set_tbl: make Atomic_relaxed array and use proper operations for setting bit, unsetting bit and reading bit Reviewed by: Marko Mäkelä --- include/my_atomic_wrapper.h | 5 +++++ storage/innobase/handler/ha_innodb.cc | 3 --- storage/innobase/include/srv0mon.h | 22 +++++++++++----------- storage/innobase/srv/srv0mon.cc | 4 ++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/my_atomic_wrapper.h b/include/my_atomic_wrapper.h index 64835e30ca7..c574fba4a8e 100644 --- a/include/my_atomic_wrapper.h +++ b/include/my_atomic_wrapper.h @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ +#pragma once #ifdef __cplusplus #include /** @@ -50,6 +51,10 @@ public: { return m.fetch_sub(i, o); } Type fetch_xor(const Type i, std::memory_order o= std::memory_order_relaxed) { return m.fetch_xor(i, o); } + Type fetch_and(const Type i, std::memory_order o= std::memory_order_relaxed) + { return m.fetch_and(i, o); } + Type fetch_or(const Type i, std::memory_order o= std::memory_order_relaxed) + { return m.fetch_or(i, o); } bool compare_exchange_strong(Type& i1, const Type i2, std::memory_order o1= std::memory_order_relaxed, std::memory_order o2= std::memory_order_relaxed) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a9206df377c..345f2a37d5d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4245,9 +4245,6 @@ static int innodb_init(void* p) } #endif /* MYSQL_DYNAMIC_PLUGIN */ - /* Currently, monitor counter information are not persistent. */ - memset(monitor_set_tbl, 0, sizeof monitor_set_tbl); - memset(innodb_counter_value, 0, sizeof innodb_counter_value); /* Do this as late as possible so server is fully starts up, diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 45f9ae3d5e9..58e36676398 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -498,23 +498,23 @@ enum mon_option_t { /** This "monitor_set_tbl" is a bitmap records whether a particular monitor counter has been turned on or off */ -extern ulint monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) / - NUM_BITS_ULINT]; +extern Atomic_relaxed + monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) / NUM_BITS_ULINT]; /** Macros to turn on/off the control bit in monitor_set_tbl for a monitor counter option. */ -#define MONITOR_ON(monitor) \ - (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] |= \ - (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))) +#define MONITOR_ON(monitor) \ + (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT].fetch_or( \ + (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT)))) -#define MONITOR_OFF(monitor) \ - (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] &= \ - ~(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))) +#define MONITOR_OFF(monitor) \ + (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT].fetch_and( \ + ~(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT)))) /** Check whether the requested monitor is turned on/off */ -#define MONITOR_IS_ON(monitor) \ - (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] & \ - (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))) +#define MONITOR_IS_ON(monitor) \ + (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] & \ + (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))) /** The actual monitor counter array that records each monintor counter value */ diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index c759a5b75fe..e64d3b9f426 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -1424,8 +1424,8 @@ monitor_value_t innodb_counter_value[NUM_MONITOR]; /* monitor_set_tbl is used to record and determine whether a monitor has been turned on/off. */ -ulint monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - - 1) / NUM_BITS_ULINT]; +Atomic_relaxed + monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) / NUM_BITS_ULINT]; /****************************************************************//** Get a monitor's "monitor_info" by its monitor id (index into the From 1eb59c307de163b507efade1fc372d8ff2bb94b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 4 Dec 2020 11:46:47 +0200 Subject: [PATCH 04/72] MDEV-24340 Unique final message of InnoDB during shutdown innobase_space_shutdown(): Remove. We want this step to be executed before the message "InnoDB: Shutdown completed; log sequence number " is output by innodb_shutdown(). It used to be executed after that step. innodb_shutdown(): Duplicate the code that used to live in innobase_space_shutdown(). innobase_init_abort(): Merge with innobase_space_shutdown(). --- extra/mariabackup/xtrabackup.cc | 5 +---- storage/innobase/handler/ha_innodb.cc | 24 +++++------------------- storage/innobase/handler/ha_innodb.h | 3 --- storage/innobase/srv/srv0start.cc | 11 +++++++++++ 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 20a8a562fa5..241d7aeb198 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -6073,12 +6073,9 @@ static bool xtrabackup_prepare_func(char** argv) srv_shutdown_bg_undo_sources(); srv_purge_shutdown(); buf_flush_sync_all_buf_pools(); - innodb_shutdown(); - innobase_space_shutdown(); } - else - innodb_shutdown(); + innodb_shutdown(); innodb_free_param(); /* output to metadata file */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 04683a6843b..d7ccbd7f883 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3544,11 +3544,12 @@ ha_innobase::init_table_handle_for_HANDLER(void) reset_template(); } -/** Free tablespace resources allocated. */ -void innobase_space_shutdown() +/*********************************************************************//** +Free any resources that were allocated and return failure. +@return always return 1 */ +static int innobase_init_abort() { - DBUG_ENTER("innobase_space_shutdown"); - + DBUG_ENTER("innobase_init_abort"); srv_sys_space.shutdown(); if (srv_tmp_space.get_sanity_check_status()) { fil_space_close(srv_tmp_space.name()); @@ -3559,20 +3560,6 @@ void innobase_space_shutdown() #ifdef WITH_INNODB_DISALLOW_WRITES os_event_destroy(srv_allow_writes_event); #endif /* WITH_INNODB_DISALLOW_WRITES */ - - DBUG_VOID_RETURN; -} - -/*********************************************************************//** -Free any resources that were allocated and return failure. -@return always return 1 */ -static -int -innobase_init_abort() -/*=================*/ -{ - DBUG_ENTER("innobase_init_abort"); - innobase_space_shutdown(); DBUG_RETURN(1); } @@ -4417,7 +4404,6 @@ innobase_end(handlerton*, ha_panic_function) } innodb_shutdown(); - innobase_space_shutdown(); mysql_mutex_destroy(&commit_cond_m); mysql_cond_destroy(&commit_cond); diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index a02c897f7ae..b1c34f64326 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -976,6 +976,3 @@ which is in the prepared state @return 0 or error number */ int innobase_rollback_by_xid(handlerton* hton, XID* xid); - -/** Free tablespace resources allocated. */ -void innobase_space_shutdown(); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 0d8ebbe98cd..a7be1cdbf21 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2913,6 +2913,17 @@ innodb_shutdown() fclose(dict_foreign_err_file); } + srv_sys_space.shutdown(); + if (srv_tmp_space.get_sanity_check_status()) { + fil_space_close(srv_tmp_space.name()); + srv_tmp_space.delete_files(); + } + srv_tmp_space.shutdown(); + +#ifdef WITH_INNODB_DISALLOW_WRITES + os_event_destroy(srv_allow_writes_event); +#endif /* WITH_INNODB_DISALLOW_WRITES */ + if (srv_was_started && srv_print_verbose_log) { ib::info() << "Shutdown completed; log sequence number " << srv_shutdown_lsn; From 50d7eddc3d21b9bad66db6961900e3222a6fa356 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 4 Dec 2020 08:50:20 -0800 Subject: [PATCH 05/72] MDEV-24314 Unexpected error message when selecting from view that uses mergeable derived table Do not check privileges for derived tables/CTEs and their fields. Approved by Oleksandr Byelkin --- mysql-test/r/view.result | 35 +++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 30 ++++++++++++++++++++++++++++++ sql/sql_base.cc | 1 + sql/sql_parse.cc | 3 +++ 4 files changed, 69 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 994d5949460..0da11c7c355 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -6767,5 +6767,40 @@ DROP PROCEDURE sp; DROP VIEW v1; DROP TABLE t1; # +# MDEV-24314: create view with derived table without default database +# +drop database test; +create database db1; +create table db1.t1 (a int); +insert into db1.t1 values (3),(7),(1); +create view db1.v1 as select * from (select * from db1.t1) t; +show create view db1.v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db1`.`v1` AS select `t`.`a` AS `a` from (select `db1`.`t1`.`a` AS `a` from `db1`.`t1`) `t` latin1 latin1_swedish_ci +select * from db1.v1; +a +3 +7 +1 +drop view db1.v1; +prepare stmt from " +create view db1.v1 as select * from (select * from db1.t1) t; +"; +execute stmt; +deallocate prepare stmt; +show create view db1.v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db1`.`v1` AS select `t`.`a` AS `a` from (select `db1`.`t1`.`a` AS `a` from `db1`.`t1`) `t` latin1 latin1_swedish_ci +select * from db1.v1; +a +3 +7 +1 +drop view db1.v1; +drop table db1.t1; +drop database db1; +create database test; +use test; +# # End of 10.2 tests # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index cd5cc6efade..2486887600b 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -6491,6 +6491,36 @@ DROP PROCEDURE sp; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-24314: create view with derived table without default database +--echo # + +drop database test; + +create database db1; +create table db1.t1 (a int); +insert into db1.t1 values (3),(7),(1); + +create view db1.v1 as select * from (select * from db1.t1) t; +show create view db1.v1; +select * from db1.v1; +drop view db1.v1; + +prepare stmt from " +create view db1.v1 as select * from (select * from db1.t1) t; +"; +execute stmt; +deallocate prepare stmt; +show create view db1.v1; +select * from db1.v1; +drop view db1.v1; + +drop table db1.t1; +drop database db1; + +create database test; +use test; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 590073bbed7..622273648a1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5795,6 +5795,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ if (check_privileges && + !table_list->is_derived() && check_column_grant_in_table_ref(thd, *actual_table, name, length)) fld= WRONG_GRANT; else diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0166c4554e7..6e1d36b79a4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6639,6 +6639,9 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool check_single_table_access(THD *thd, ulong privilege, TABLE_LIST *tables, bool no_errors) { + if (tables->is_derived()) + return 0; + Switch_to_definer_security_ctx backup_sctx(thd, tables); const char *db_name; From a82209ca31684a5fd30eb2341a7b0a78eaa6d149 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 23 Nov 2020 21:33:03 +0100 Subject: [PATCH 06/72] MDEV-24177 && MDEV-24178 - MDEV-24177: main.sp2 test fails: Result length mismatch - MDEV-24178: main.upgrade_MDEV-19650 test fails: Result length mismatch Reviewed by: serg@mariadb.com --- mysql-test/mysql-test-run.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 8093e7ecb6f..7b73782eedc 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3365,6 +3365,7 @@ sub mysql_install_db { mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/"); mtr_add_arg($args, "--core-file"); mtr_add_arg($args, "--console"); + mtr_add_arg($args, "--character-set-server=latin1"); if ( $opt_debug ) { From eb7b14ec9a4e0eabaa073e10f3b42f656ed7c421 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Thu, 5 Mar 2020 16:40:29 +0100 Subject: [PATCH 07/72] MDEV-21367: mysqld_safe log don't log to err.log Introduced with 6b7918d524d5 in `10.2` just check for helper and handle it if exist. Reviewed by: cvicentiu@mariadb.org --- scripts/mysqld_safe.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 0110653be90..dc2c0db8e40 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -155,7 +155,7 @@ log_generic () { case $logging in init) ;; # Just echo the message, don't save it anywhere file) - if [ -n "$helper" ]; then + if [ "$helper_exist" -eq "0" ]; then echo "$msg" | "$helper" "$user" log "$err_log" fi ;; @@ -179,7 +179,7 @@ eval_log_error () { local cmd="$1" case $logging in file) - if [ -n "$helper" ]; then + if [ "$helper_exist" -eq "0" ]; then cmd="$cmd 2>&1 | "`shell_quote_string "$helper"`" $user log "`shell_quote_string "$err_log"` fi ;; @@ -551,10 +551,9 @@ fi helper=`find_in_bin mysqld_safe_helper` print_defaults=`find_in_bin my_print_defaults` - # Check if helper exists -$helper --help >/dev/null 2>&1 || helper="" - +command -v $helper --help >/dev/null 2>&1 +helper_exist=$? # # Second, try to find the data directory # @@ -962,7 +961,6 @@ fi # Avoid 'nohup: ignoring input' warning test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null" - log_notice "Starting $MYSQLD daemon with databases from $DATADIR" # variable to track the current number of "fast" (a.k.a. subsecond) restarts From f924a3bd6cd70c140f00d162ad18da003cc87a89 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Tue, 1 Dec 2020 15:40:44 +0100 Subject: [PATCH 08/72] MDEV-24139: CHECK_CLAUSE field in INFORMATION_SCHEMA.CHECK_CONSTRAINTS truncate check constraints expressions - Reviewed by: daniel@mariadb.org --- mysql-test/r/information_schema.result | 1 + mysql-test/suite/funcs_1/r/is_check_constraints.result | 5 ++++- mysql-test/suite/funcs_1/r/is_columns_is.result | 4 ++-- mysql-test/suite/funcs_1/r/is_columns_is_embedded.result | 4 ++-- mysql-test/suite/funcs_1/r/is_tables_is.result | 8 ++++---- mysql-test/suite/funcs_1/r/is_tables_is_embedded.result | 8 ++++---- mysql-test/suite/funcs_1/t/is_check_constraints.test | 4 +++- sql/sql_show.cc | 2 +- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 7644ff4e7a2..dc772eecc62 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -843,6 +843,7 @@ information_schema.columns where data_type = 'longtext' and table_schema != 'performance_schema'; table_schema table_name column_name information_schema ALL_PLUGINS PLUGIN_DESCRIPTION +information_schema CHECK_CONSTRAINTS CHECK_CLAUSE information_schema COLUMNS COLUMN_DEFAULT information_schema COLUMNS COLUMN_TYPE information_schema COLUMNS GENERATION_EXPRESSION diff --git a/mysql-test/suite/funcs_1/r/is_check_constraints.result b/mysql-test/suite/funcs_1/r/is_check_constraints.result index 4d7c7b446e6..fa2bf2d9201 100644 --- a/mysql-test/suite/funcs_1/r/is_check_constraints.result +++ b/mysql-test/suite/funcs_1/r/is_check_constraints.result @@ -90,7 +90,9 @@ CREATE TABLE t3 ( a int, b int check (b>0), # field constraint named 'b' -CONSTRAINT b check (b>10) # table constraint +CONSTRAINT b check (b>10), # table constraint +# `CHECK_CLAUSE` should allow more then `var(64)` constraints +CONSTRAINT b1 check (b<123456789012345678901234567890123456789012345678901234567890123456789) ) ENGINE=InnoDB; SELECT * from information_schema.check_constraints; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE @@ -104,6 +106,7 @@ def foo t2 CHK_dates `start_date` is null def foo t2 name char_length(`name`) > 2 def foo t3 b `b` > 0 def foo t3 b `b` > 10 +def foo t3 b1 `b` < 123456789012345678901234567890123456789012345678901234567890123456789 disconnect con1; CONNECT con2, localhost, boo2,, test; SELECT * from information_schema.check_constraints; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index a34668daff3..672c8e0810a 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -24,7 +24,7 @@ def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 '' NO varchar 32 96 N def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 '' NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NEVER NULL def information_schema CHARACTER_SETS DESCRIPTION 3 '' NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) select NEVER NULL def information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3) select NEVER NULL -def information_schema CHECK_CONSTRAINTS CHECK_CLAUSE 5 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL +def information_schema CHECK_CONSTRAINTS CHECK_CLAUSE 5 '' NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select NEVER NULL def information_schema CHECK_CONSTRAINTS CONSTRAINT_CATALOG 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select NEVER NULL def information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME 4 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL def information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL @@ -563,7 +563,7 @@ NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint( 3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHECK_CONSTRAINTS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) -3.0000 information_schema CHECK_CONSTRAINTS CHECK_CLAUSE varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema CHECK_CONSTRAINTS CHECK_CLAUSE longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index ac3130d58b0..85026160b41 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -24,7 +24,7 @@ def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 '' NO varchar 32 96 N def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 '' NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) NEVER NULL def information_schema CHARACTER_SETS DESCRIPTION 3 '' NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) NEVER NULL def information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3) NEVER NULL -def information_schema CHECK_CONSTRAINTS CHECK_CLAUSE 5 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL +def information_schema CHECK_CONSTRAINTS CHECK_CLAUSE 5 '' NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext NEVER NULL def information_schema CHECK_CONSTRAINTS CONSTRAINT_CATALOG 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) NEVER NULL def information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME 4 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL def information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL @@ -563,7 +563,7 @@ NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint( 3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHECK_CONSTRAINTS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) -3.0000 information_schema CHECK_CONSTRAINTS CHECK_CLAUSE varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema CHECK_CONSTRAINTS CHECK_CLAUSE longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index 9022e057ae5..502b165cde3 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -85,9 +85,9 @@ TABLE_CATALOG def TABLE_SCHEMA information_schema TABLE_NAME CHECK_CONSTRAINTS TABLE_TYPE SYSTEM VIEW -ENGINE MEMORY +ENGINE MYISAM_OR_MARIA VERSION 11 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# @@ -1044,9 +1044,9 @@ TABLE_CATALOG def TABLE_SCHEMA information_schema TABLE_NAME CHECK_CONSTRAINTS TABLE_TYPE SYSTEM VIEW -ENGINE MEMORY +ENGINE MYISAM_OR_MARIA VERSION 11 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result index 9022e057ae5..502b165cde3 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result @@ -85,9 +85,9 @@ TABLE_CATALOG def TABLE_SCHEMA information_schema TABLE_NAME CHECK_CONSTRAINTS TABLE_TYPE SYSTEM VIEW -ENGINE MEMORY +ENGINE MYISAM_OR_MARIA VERSION 11 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# @@ -1044,9 +1044,9 @@ TABLE_CATALOG def TABLE_SCHEMA information_schema TABLE_NAME CHECK_CONSTRAINTS TABLE_TYPE SYSTEM VIEW -ENGINE MEMORY +ENGINE MYISAM_OR_MARIA VERSION 11 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# diff --git a/mysql-test/suite/funcs_1/t/is_check_constraints.test b/mysql-test/suite/funcs_1/t/is_check_constraints.test index eadfd817832..f66ba875024 100644 --- a/mysql-test/suite/funcs_1/t/is_check_constraints.test +++ b/mysql-test/suite/funcs_1/t/is_check_constraints.test @@ -68,7 +68,9 @@ CREATE TABLE t3 ( a int, b int check (b>0), # field constraint named 'b' -CONSTRAINT b check (b>10) # table constraint +CONSTRAINT b check (b>10), # table constraint +# `CHECK_CLAUSE` should allow more then `var(64)` constraints +CONSTRAINT b1 check (b<123456789012345678901234567890123456789012345678901234567890123456789) ) ENGINE=InnoDB; --sorted_result SELECT * from information_schema.check_constraints; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5544c765775..3babaabb37d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -9410,7 +9410,7 @@ ST_FIELD_INFO check_constraints_fields_info[]= {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"CHECK_CLAUSE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + {"CHECK_CLAUSE", MAX_FIELD_VARCHARLENGTH , MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; From 47c4caf1bfe1a2edc475aad6bba945a60e9cc754 Mon Sep 17 00:00:00 2001 From: Dan Solodko Date: Tue, 11 Aug 2020 18:02:39 +0300 Subject: [PATCH 09/72] mdev-22485 mysqlslap does not use current user as default --- client/mysqlslap.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 8c53cbb421e..19544384670 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1193,9 +1193,6 @@ get_options(int *argc,char ***argv) if (debug_check_flag) my_end_arg= MY_CHECK_ERROR; - if (!user) - user= (char *)"root"; - /* If something is created and --no-drop is not specified, we drop the schema. From bc2dc83cb56851144a8c15e73a83c7817dc705a2 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Tue, 1 Dec 2020 21:38:22 +0100 Subject: [PATCH 10/72] MDEV-22485: add the test case Closes PR #1649 --- mysql-test/main/mysqlslap.opt | 1 + mysql-test/main/mysqlslap.result | 100 +++++++++++++++++++++++++++++++ mysql-test/main/mysqlslap.test | 51 ++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/mysql-test/main/mysqlslap.opt b/mysql-test/main/mysqlslap.opt index 632f5b4c069..da7672849bb 100644 --- a/mysql-test/main/mysqlslap.opt +++ b/mysql-test/main/mysqlslap.opt @@ -1 +1,2 @@ --sql_mode='NO_ENGINE_SUBSTITUTION' +--log-output=TABLE,FILE --general-log=0 --slow-query-log=0 diff --git a/mysql-test/main/mysqlslap.result b/mysql-test/main/mysqlslap.result index 791cb5ac6b3..a83d4d38a16 100644 --- a/mysql-test/main/mysqlslap.result +++ b/mysql-test/main/mysqlslap.result @@ -258,3 +258,103 @@ DROP TABLE t1; # # Bug MDEV-15789 (Upstream: #80329): MYSQLSLAP OPTIONS --AUTO-GENERATE-SQL-GUID-PRIMARY and --AUTO-GENERATE-SQL-SECONDARY-INDEXES DONT WORK # +# +# MDEV-22485: mysqlslap does not use current user as default for connecting to server +# +set @old_general_log=@@global.general_log; +set @old_general_log_file=@@global.general_log_file; +select @old_general_log; +@old_general_log +0 +show global variables +where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; +Variable_name Value +general_log OFF +slow_query_log OFF +truncate table mysql.general_log; +select * from mysql.general_log; +event_time user_host thread_id server_id command_type argument +set global general_log=ON; +current_user.log; +@@current_user.log +current_user.log +SET GLOBAL general_log_file=general_log.log; +show global variables +where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; +Variable_name Value +general_log ON +slow_query_log OFF +flush logs; +create user anel@localhost; +grant all on *.* to anel@localhost; +connect con1,localhost,anel,,; +connection con1; +create table t(t int); +# Run mysqlslap user anel +Benchmark + Average number of seconds to run all queries: X seconds + Minimum number of seconds to run all queries: X seconds + Maximum number of seconds to run all queries: X seconds + Number of clients running queries: 1 + Average number of queries per client: 1 + +flush tables; +select user_host, command_type, argument from mysql.general_log; +user_host command_type argument +root[root] @ localhost [] Query select @@general_log_file +root[root] @ localhost [] Query SET GLOBAL general_log_file=current_user.log +root[root] @ localhost [] Query show global variables +where Variable_name = 'general_log' or Variable_name = 'slow_query_log' +root[root] @ localhost [] Query flush logs +root[root] @ localhost [] Query create user anel@localhost +root[root] @ localhost [] Query grant all on *.* to anel@localhost +[anel] @ localhost [] Connect anel@localhost as anonymous on test +anel[anel] @ localhost [] Query create table t(t int) +[root] @ localhost [] Connect root@localhost as anonymous on +[root] @ localhost [] Connect root@localhost as anonymous on test +root[root] @ localhost [] Query SELECT current_user() +root[root] @ localhost [] Quit +root[root] @ localhost [] Quit +anel[anel] @ localhost [] Query flush tables +anel[anel] @ localhost [] Query select user_host, command_type, argument from mysql.general_log +disconnect con1; +connection default; +# Run mysqlslap user root +Benchmark + Average number of seconds to run all queries: X seconds + Minimum number of seconds to run all queries: X seconds + Maximum number of seconds to run all queries: X seconds + Number of clients running queries: 1 + Average number of queries per client: 1 + +flush tables; +select user_host, command_type, argument from mysql.general_log; +user_host command_type argument +root[root] @ localhost [] Query select @@general_log_file +root[root] @ localhost [] Query SET GLOBAL general_log_file=current_user.log +root[root] @ localhost [] Query show global variables +where Variable_name = 'general_log' or Variable_name = 'slow_query_log' +root[root] @ localhost [] Query flush logs +root[root] @ localhost [] Query create user anel@localhost +root[root] @ localhost [] Query grant all on *.* to anel@localhost +[anel] @ localhost [] Connect anel@localhost as anonymous on test +anel[anel] @ localhost [] Query create table t(t int) +[root] @ localhost [] Connect root@localhost as anonymous on +[root] @ localhost [] Connect root@localhost as anonymous on test +root[root] @ localhost [] Query SELECT current_user() +root[root] @ localhost [] Quit +root[root] @ localhost [] Quit +anel[anel] @ localhost [] Query flush tables +anel[anel] @ localhost [] Query select user_host, command_type, argument from mysql.general_log +anel[anel] @ localhost [] Quit +[root] @ localhost [] Connect root@localhost as anonymous on +[root] @ localhost [] Connect root@localhost as anonymous on test +root[root] @ localhost [] Query SELECT current_user() +root[root] @ localhost [] Quit +root[root] @ localhost [] Quit +root[root] @ localhost [] Query flush tables +root[root] @ localhost [] Query select user_host, command_type, argument from mysql.general_log +drop user anel@localhost; +drop table t; +set global general_log= @old_general_log; +set global general_log_file= @old_general_log_file; diff --git a/mysql-test/main/mysqlslap.test b/mysql-test/main/mysqlslap.test index 81115d59d09..4e99b8f2cd2 100644 --- a/mysql-test/main/mysqlslap.test +++ b/mysql-test/main/mysqlslap.test @@ -88,3 +88,54 @@ DROP TABLE t1; --exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --create-schema=slap --exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-secondary-indexes=1 --create-schema=slap + +--echo # +--echo # MDEV-22485: mysqlslap does not use current user as default for connecting to server +--echo # +--disable_ps_protocol +set @old_general_log=@@global.general_log; +set @old_general_log_file=@@global.general_log_file; +select @old_general_log; + +show global variables +where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; +truncate table mysql.general_log; +# empty log at the beginning +select * from mysql.general_log; + +set global general_log=ON; +--replace_regex /[\/\w:](?!.log).*/current_user.log/ +select @@general_log_file; +--replace_regex /=.+"/=general_log.log/ +--let $gen_log_file=$MYSQLTEST_VARDIR/tmp/general_log.log +--replace_regex /".+"/general_log.log/ +--eval SET GLOBAL general_log_file="$gen_log_file" +show global variables +where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; +flush logs; +create user anel@localhost; +grant all on *.* to anel@localhost; +connect con1,localhost,anel,,; +connection con1; +create table t(t int); +--echo # Run mysqlslap user anel +--replace_regex /\d[.]\d+/X/ +--exec $MYSQL_SLAP --create-schema=test --query="SELECT current_user()" --concurrency=1 --iterations=1 +flush tables; +--replace_regex /".+/current_user.log/ /[::1]// +select user_host, command_type, argument from mysql.general_log; +disconnect con1; + +connection default; +--echo # Run mysqlslap user root +--replace_regex /\d[.]\d+/X/ +--exec $MYSQL_SLAP --create-schema=test --query="SELECT current_user()" --concurrency=1 --iterations=1 +flush tables; +#--exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --create-schema=slap +--replace_regex /".+/current_user.log/ /[::1]// +select user_host, command_type, argument from mysql.general_log; +drop user anel@localhost; +drop table t; +set global general_log= @old_general_log; +set global general_log_file= @old_general_log_file; +--enable_ps_protocol From 2db6eb142956cd1744cf5c452bca66b20067d73e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 4 Dec 2020 14:20:52 -0800 Subject: [PATCH 11/72] MDEV-22781 CREATE VIEW containing WITH clause Signal 11 For table references to CTEs the field TABLE_LIST::db must be set to an empty string as it's done for table references to derived tables in order CTEs to be processed similar to how derived tables are processed. Approved by Oleksandr Byelkin --- mysql-test/r/cte_nonrecursive.result | 43 +++++++++++++++++++++++++--- mysql-test/r/cte_recursive.result | 4 +-- mysql-test/t/cte_nonrecursive.test | 29 +++++++++++++++++++ sql/sql_cte.cc | 1 + sql/sql_view.cc | 2 ++ 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result index 746fcbcf051..a47fdcd6e57 100644 --- a/mysql-test/r/cte_nonrecursive.result +++ b/mysql-test/r/cte_nonrecursive.result @@ -571,7 +571,7 @@ with t as (select a from t1 where b >= 'c') select * from t2,t where t2.c=t.a; show create view v1; View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS with t as (select `t1`.`a` AS `a` from `t1` where `t1`.`b` >= 'c')select `t2`.`c` AS `c`,`t`.`a` AS `a` from (`t2` join `t`) where `t2`.`c` = `t`.`a` latin1 latin1_swedish_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS with t as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`b` >= 'c')select `test`.`t2`.`c` AS `c`,`t`.`a` AS `a` from (`test`.`t2` join `t`) where `test`.`t2`.`c` = `t`.`a` latin1 latin1_swedish_ci select * from v1; c a 4 4 @@ -588,7 +588,7 @@ with t as (select a, count(*) from t1 where b >= 'c' group by a) select * from t2,t where t2.c=t.a; show create view v2; View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS with t as (select `t1`.`a` AS `a`,count(0) AS `count(*)` from `t1` where `t1`.`b` >= 'c' group by `t1`.`a`)select `t2`.`c` AS `c`,`t`.`a` AS `a`,`t`.`count(*)` AS `count(*)` from (`t2` join `t`) where `t2`.`c` = `t`.`a` latin1 latin1_swedish_ci +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS with t as (select `test`.`t1`.`a` AS `a`,count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` >= 'c' group by `test`.`t1`.`a`)select `test`.`t2`.`c` AS `c`,`t`.`a` AS `a`,`t`.`count(*)` AS `count(*)` from (`test`.`t2` join `t`) where `test`.`t2`.`c` = `t`.`a` latin1 latin1_swedish_ci select * from v2; c a count(*) 4 4 2 @@ -606,7 +606,7 @@ with t(c) as (select a from t1 where b >= 'c') select * from t r1 where r1.c=4; show create view v3; View Create View character_set_client collation_connection -v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS with t as (select `t1`.`a` AS `c` from `t1` where `t1`.`b` >= 'c')select `r1`.`c` AS `c` from `t` `r1` where `r1`.`c` = 4 latin1 latin1_swedish_ci +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS with t as (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c')select `r1`.`c` AS `c` from `t` `r1` where `r1`.`c` = 4 latin1 latin1_swedish_ci select * from v3; c 4 @@ -1349,7 +1349,7 @@ r.r_regionkey in select r_regionkey from t where r_name <> "ASIA"); show create view v; View Create View character_set_client collation_connection -v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `n`.`n_nationkey` AS `n_nationkey`,`n`.`n_name` AS `n_name`,`n`.`n_regionkey` AS `n_regionkey`,`r`.`r_regionkey` AS `r_regionkey`,`r`.`r_name` AS `r_name` from (`nation` `n` join `region` `r`) where `n`.`n_regionkey` = `r`.`r_regionkey` and `r`.`r_regionkey` in (with t as (select `region`.`r_regionkey` AS `r_regionkey`,`region`.`r_name` AS `r_name` from `region` where `region`.`r_regionkey` <= 3)select `t`.`r_regionkey` from `t` where `t`.`r_name` <> 'ASIA') latin1 latin1_swedish_ci +v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `n`.`n_nationkey` AS `n_nationkey`,`n`.`n_name` AS `n_name`,`n`.`n_regionkey` AS `n_regionkey`,`r`.`r_regionkey` AS `r_regionkey`,`r`.`r_name` AS `r_name` from (`test`.`nation` `n` join `test`.`region` `r`) where `n`.`n_regionkey` = `r`.`r_regionkey` and `r`.`r_regionkey` in (with t as (select `test`.`region`.`r_regionkey` AS `r_regionkey`,`test`.`region`.`r_name` AS `r_name` from `test`.`region` where `test`.`region`.`r_regionkey` <= 3)select `t`.`r_regionkey` from `t` where `t`.`r_name` <> 'ASIA') latin1 latin1_swedish_ci select * from v; n_nationkey n_name n_regionkey r_regionkey r_name 0 ALGERIA 0 0 AFRICA @@ -1690,4 +1690,39 @@ ERROR 3D000: No database selected DROP TABLE test.t; connection default; disconnect con1; +# +# MDEV-22781: create view with CTE without default database +# +drop database test; +create database db1; +create table db1.t1 (a int); +insert into db1.t1 values (3),(7),(1); +create view db1.v1 as with t as (select * from db1.t1) select * from t; +show create view db1.v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db1`.`v1` AS with t as (select `db1`.`t1`.`a` AS `a` from `db1`.`t1`)select `t`.`a` AS `a` from `t` latin1 latin1_swedish_ci +select * from db1.v1; +a +3 +7 +1 +drop view db1.v1; +prepare stmt from " +create view db1.v1 as with t as (select * from db1.t1) select * from t; +"; +execute stmt; +deallocate prepare stmt; +show create view db1.v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db1`.`v1` AS with t as (select `db1`.`t1`.`a` AS `a` from `db1`.`t1`)select `t`.`a` AS `a` from `t` latin1 latin1_swedish_ci +select * from db1.v1; +a +3 +7 +1 +drop view db1.v1; +drop table db1.t1; +drop database db1; +create database test; +use test; # End of 10.2 tests diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index 85883d3e6f1..405bfbbb621 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -818,7 +818,7 @@ where p.id = a.father or p.id = a.mother select * from ancestors; show create view v1; View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS with recursive ancestors as (select `folks`.`id` AS `id`,`folks`.`name` AS `name`,`folks`.`dob` AS `dob`,`folks`.`father` AS `father`,`folks`.`mother` AS `mother` from `folks` where `folks`.`name` = 'Me' and `folks`.`dob` = '2000-01-01' union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`folks` `p` join `ancestors` `a`) where `p`.`id` = `a`.`father` or `p`.`id` = `a`.`mother`)select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors` latin1 latin1_swedish_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS with recursive ancestors as (select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' and `test`.`folks`.`dob` = '2000-01-01' union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`test`.`folks` `p` join `ancestors` `a`) where `p`.`id` = `a`.`father` or `p`.`id` = `a`.`mother`)select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors` latin1 latin1_swedish_ci select * from v1; id name dob father mother 100 Me 2000-01-01 20 30 @@ -849,7 +849,7 @@ where p.id = ma.mother select * from ancestors; show create view v2; View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS with recursive ancestors as (select `folks`.`id` AS `id`,`folks`.`name` AS `name`,`folks`.`dob` AS `dob`,`folks`.`father` AS `father`,`folks`.`mother` AS `mother` from `folks` where `folks`.`name` = 'Me' union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`folks` `p` join `ancestors` `fa`) where `p`.`id` = `fa`.`father` union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`folks` `p` join `ancestors` `ma`) where `p`.`id` = `ma`.`mother`)select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors` latin1 latin1_swedish_ci +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS with recursive ancestors as (select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`test`.`folks` `p` join `ancestors` `fa`) where `p`.`id` = `fa`.`father` union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`test`.`folks` `p` join `ancestors` `ma`) where `p`.`id` = `ma`.`mother`)select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors` latin1 latin1_swedish_ci select * from v2; id name dob father mother 100 Me 2000-01-01 20 30 diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test index 41a5b815bc7..0174ddbaad0 100644 --- a/mysql-test/t/cte_nonrecursive.test +++ b/mysql-test/t/cte_nonrecursive.test @@ -1201,4 +1201,33 @@ DROP TABLE test.t; --connection default --disconnect con1 +--echo # +--echo # MDEV-22781: create view with CTE without default database +--echo # + +drop database test; +create database db1; +create table db1.t1 (a int); +insert into db1.t1 values (3),(7),(1); + +create view db1.v1 as with t as (select * from db1.t1) select * from t; +show create view db1.v1; +select * from db1.v1; +drop view db1.v1; + +prepare stmt from " +create view db1.v1 as with t as (select * from db1.t1) select * from t; +"; +execute stmt; +deallocate prepare stmt; +show create view db1.v1; +select * from db1.v1; +drop view db1.v1; + +drop table db1.t1; +drop database db1; + +create database test; +use test; + --echo # End of 10.2 tests diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index fe8e0de71b4..a8bccf0c1dd 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -227,6 +227,7 @@ With_element *With_clause::find_table_def(TABLE_LIST *table, !table->is_fqtn) { table->set_derived(); + table->db= empty_c_string; return with_elem; } } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 8bfe6896ea2..0701c5233ac 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -291,6 +291,8 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, { for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local) { + if (!tbl->with && tbl->select_lex) + tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl); /* Ensure that we have some privileges on this table, more strict check will be done on column level after preparation, From e007fcf59dd02407277b130dbd3984a7b5352c5e Mon Sep 17 00:00:00 2001 From: Sujatha Date: Tue, 8 Dec 2020 11:59:58 +0530 Subject: [PATCH 12/72] MDEV-19716: ASAN use-after-poison in Query_log_event::Query_log_event / THD::log_events_and_free_tmp_shares Post push fix to address test failure. Problem: ======= rpl.rpl_drop_temp_table_invaid_lex added as part bug fix has occasional failures in build bot. MTR's internal check of the test case 'rpl.rpl_drop_temp_table_invaid_lex' failed. Variable_name Value -Slave_open_temp_tables 0 +Slave_open_temp_tables 1 Analysis: ========= The reason for the failure is that the DROP TEMPORARY TABLE command which gets generated on connection disconnect might not have reached the slave and hence the temp table remains on the slave. Fix: === On master, upon disconnect, wait till connection is completely gone. Then ensure that DROP TEMPORARY table statement is available in the binary log. Sync the slave with master and check that temporary table count is zero on slave. Fixed a typo in test name. --- ...sult => rpl_drop_temp_table_invalid_lex.result} | 5 ++++- ...x.test => rpl_drop_temp_table_invalid_lex.test} | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) rename mysql-test/suite/rpl/r/{rpl_drop_temp_table_invaid_lex.result => rpl_drop_temp_table_invalid_lex.result} (62%) rename mysql-test/suite/rpl/t/{rpl_drop_temp_table_invaid_lex.test => rpl_drop_temp_table_invalid_lex.test} (64%) diff --git a/mysql-test/suite/rpl/r/rpl_drop_temp_table_invaid_lex.result b/mysql-test/suite/rpl/r/rpl_drop_temp_table_invalid_lex.result similarity index 62% rename from mysql-test/suite/rpl/r/rpl_drop_temp_table_invaid_lex.result rename to mysql-test/suite/rpl/r/rpl_drop_temp_table_invalid_lex.result index 49e9195ed35..f3c4cb4def2 100644 --- a/mysql-test/suite/rpl/r/rpl_drop_temp_table_invaid_lex.result +++ b/mysql-test/suite/rpl/r/rpl_drop_temp_table_invalid_lex.result @@ -4,5 +4,8 @@ connect con1,localhost,root,,; CREATE TEMPORARY TABLE tmp (a INT); CREATE TABLE non_existing_db.t SELECT 1 AS b; disconnect con1; -connection default; +connection master; +connection slave; +connection slave; +include/assert.inc ["Slave_open_temp_tables count should be 0"] include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop_temp_table_invaid_lex.test b/mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test similarity index 64% rename from mysql-test/suite/rpl/t/rpl_drop_temp_table_invaid_lex.test rename to mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test index 2d3031da544..475afef12fc 100644 --- a/mysql-test/suite/rpl/t/rpl_drop_temp_table_invaid_lex.test +++ b/mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test @@ -17,15 +17,25 @@ # MDEV-19716: ASAN use-after-poison in Query_log_event::Query_log_event / # THD::log_events_and_free_tmp_shares +--source include/have_binlog_format_mixed_or_statement.inc --source include/master-slave.inc --connect (con1,localhost,root,,) - CREATE TEMPORARY TABLE tmp (a INT); --send CREATE TABLE non_existing_db.t SELECT 1 AS b --disconnect con1 +--source include/wait_until_disconnected.inc ---connection default +--connection master +--let $wait_binlog_event= DROP +--source include/wait_for_binlog_event.inc +sync_slave_with_master; + +--connection slave +--let $open_temp_tbl_count=query_get_value(show status like 'Slave_open_temp_tables', Value, 1) +--let $assert_cond= "open_temp_tbl_count" = 0 +--let $assert_text= "Slave_open_temp_tables count should be 0" +--source include/assert.inc --source include/rpl_end.inc From a3f7f2334a267ec4e120f70e84a8551fb502860f Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 8 Dec 2020 11:13:36 -0800 Subject: [PATCH 13/72] MDEV-24019 Assertion is hit for query using recursive CTE with no default DB When the query using a recursive CTE whose definition contained wildcard symbols in the recursive part was processed at the prepare stage an assertion was hit if the query was executed without any default database set. The failure happened when the function insert_fields() tried to check column privileges for the temporary table created for a recursive reference to the CTE. No acl checks are needed for any CTE. That's why this check should be blocked as well. The patch formulates a stricter condition at which this check is to be blocked that covers the case when a query using recursive CTEs is executed with no default database set. Approved by Oleksandr Byelkin --- mysql-test/r/cte_recursive.result | 44 +++++++++++++++++++++++++++++++ mysql-test/t/cte_recursive.test | 35 ++++++++++++++++++++++++ sql/sql_base.cc | 35 ++++++++---------------- 3 files changed, 90 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index 405bfbbb621..5090a0ffef9 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -4191,5 +4191,49 @@ a b c deallocate prepare stmt; drop table t1; # +# MDEV-24019: query with recursive CTE when no default database is set +# +drop database test; +with recursive a as +(select 1 from dual union select * from a as r) +select * from a; +1 +1 +create database db1; +create table db1.t1 (a int); +insert into db1.t1 values (3), (7), (1); +with recursive cte as +(select * from db1.t1 union select * from (select * from cte) as t) +select * from cte; +a +3 +7 +1 +explain with recursive cte as +(select * from db1.t1 union select * from (select * from cte) as t) +select * from cte; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 3 +3 RECURSIVE UNION ALL NULL NULL NULL NULL 3 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +prepare stmt from "with recursive cte as +(select * from db1.t1 union select * from (select * from cte) as t) +select * from cte"; +execute stmt; +a +3 +7 +1 +execute stmt; +a +3 +7 +1 +deallocate prepare stmt; +drop database db1; +create database test; +use test; +# # End of 10.2 tests # diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index 082e9be7a7a..f902ac25253 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -2690,6 +2690,41 @@ deallocate prepare stmt; drop table t1; +--echo # +--echo # MDEV-24019: query with recursive CTE when no default database is set +--echo # + +drop database test; + +let $q= +with recursive a as + (select 1 from dual union select * from a as r) +select * from a; + +eval $q; + +create database db1; +create table db1.t1 (a int); +insert into db1.t1 values (3), (7), (1); + +let $q= +with recursive cte as + (select * from db1.t1 union select * from (select * from cte) as t) +select * from cte; + +eval $q; +eval explain $q; + +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +drop database db1; + +create database test; +use test; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 622273648a1..8e57ea437b6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7648,36 +7648,23 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* - Ensure that we have access rights to all fields to be inserted. Under - some circumstances, this check may be skipped. + Ensure that we have access rights to all fields to be inserted + the table 'tables'. Under some circumstances, this check may be skipped. - - If any_privileges is true, skip the check. + The check is skipped in the following cases: - - If the SELECT privilege has been found as fulfilled already for both - the TABLE and TABLE_LIST objects (and both of these exist, of - course), the check is skipped. + - any_privileges is true - - If the SELECT privilege has been found fulfilled for the TABLE object - and the TABLE_LIST represents a derived table other than a view (see - below), the check is skipped. + - the table is a derived table - - If the TABLE_LIST object represents a view, we may skip checking if - the SELECT privilege has been found fulfilled for it, regardless of - the TABLE object. + - the table is a view with SELECT privilege - - If there is no TABLE object, the test is skipped if either - * the TABLE_LIST does not represent a view, or - * the SELECT privilege has been found fulfilled. - - A TABLE_LIST that is not a view may be a subquery, an - information_schema table, or a nested table reference. See the comment - for TABLE_LIST. + - the table is a base table with SELECT privilege */ - if (!((table && tables->is_non_derived() && - (table->grant.privilege & SELECT_ACL)) || - ((!tables->is_non_derived() && - (tables->grant.privilege & SELECT_ACL)))) && - !any_privileges) + if (!any_privileges && + !tables->is_derived() && + !(tables->is_view() && (tables->grant.privilege & SELECT_ACL)) && + !(table && (table->grant.privilege & SELECT_ACL))) { field_iterator.set(tables); if (check_grant_all_columns(thd, SELECT_ACL, &field_iterator)) From 86fc37b66877e45c38593e7af15159c32f81eb7c Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Sun, 22 Mar 2020 11:33:53 +0100 Subject: [PATCH 14/72] MDEV-19273: Server crash in MDL_ticket::has_stronger_or_equal_type or Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str, table->table_name.str, MDL_SHARED)' failed in mysql_rm_table_no_locks Early report error in case of DROP SEQUENCE Do not use error variable for other purposes except error. --- mysql-test/suite/sql_sequence/create.result | 2 +- mysql-test/suite/sql_sequence/create.test | 2 +- mysql-test/suite/sql_sequence/other.result | 59 +++++++++++++++++++ mysql-test/suite/sql_sequence/other.test | 64 +++++++++++++++++++++ sql/sql_table.cc | 56 ++++++++++++++---- 5 files changed, 169 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result index 14464c60e99..5a53a66c9a8 100644 --- a/mysql-test/suite/sql_sequence/create.result +++ b/mysql-test/suite/sql_sequence/create.result @@ -666,7 +666,7 @@ create temporary sequence s; drop temporary table s; create temporary table s (i int); drop temporary sequence s; -ERROR 42S02: Unknown SEQUENCE: 'test.s' +ERROR 42S02: 'test.s' is not a SEQUENCE drop table s; # # MDEV-15115 Assertion failure in CREATE SEQUENCE...ROW_FORMAT=REDUNDANT diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test index 2c41fb3658b..ac3aae845cd 100644 --- a/mysql-test/suite/sql_sequence/create.test +++ b/mysql-test/suite/sql_sequence/create.test @@ -489,7 +489,7 @@ drop table s; create temporary sequence s; drop temporary table s; create temporary table s (i int); ---error ER_UNKNOWN_SEQUENCES +--error ER_NOT_SEQUENCE2 drop temporary sequence s; drop table s; diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result index abc101b3c00..643233149d2 100644 --- a/mysql-test/suite/sql_sequence/other.result +++ b/mysql-test/suite/sql_sequence/other.result @@ -300,4 +300,63 @@ update t1 set p_first_name='Yunxi' where p_id=1; drop view v2; drop table t1,t2; drop sequence s1; +# +# MDEV-19273:Server crash in MDL_ticket::has_stronger_or_equal_type or +# Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE, +# table->db.str, table->table_name.str, MDL_SHARED)' failed +# in mysql_rm_table_no_locks +# +CREATE TABLE t1 (a INT); +CREATE TEMPORARY TABLE tmp (b INT); +LOCK TABLE t1 READ; +DROP SEQUENCE tmp; +ERROR 42S02: 'test.tmp' is not a SEQUENCE +DROP TEMPORARY SEQUENCE tmp; +ERROR 42S02: 'test.tmp' is not a SEQUENCE +DROP SEQUENCE t1; +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +DROP TEMPORARY SEQUENCE t1; +ERROR 42S02: Unknown SEQUENCE: 'test.t1' +UNLOCK TABLES; +DROP SEQUENCE t1; +ERROR 42S02: 'test.t1' is not a SEQUENCE +DROP TEMPORARY SEQUENCE t1; +ERROR 42S02: Unknown SEQUENCE: 'test.t1' +DROP TABLE t1; +CREATE TABLE t (a INT); +CREATE TEMPORARY TABLE s (f INT); +CREATE SEQUENCE s; +LOCK TABLE t WRITE; +DROP SEQUENCE s; +ERROR 42S02: 'test.s' is not a SEQUENCE +DROP TEMPORARY SEQUENCE s; +ERROR 42S02: 'test.s' is not a SEQUENCE +UNLOCK TABLES; +CREATE TEMPORARY SEQUENCE s; +LOCK TABLE t WRITE; +DROP TEMPORARY SEQUENCE s; +UNLOCK TABLES; +DROP TEMPORARY TABLE s; +DROP SEQUENCE s; +create table s(a INT); +CREATE TEMPORARY TABLE s (f INT); +LOCK TABLE t WRITE; +DROP TEMPORARY TABLE s; +CREATE TEMPORARY TABLE s (f INT); +DROP TABLE s; +DROP TABLE s; +ERROR HY000: Table 's' was not locked with LOCK TABLES +UNLOCK TABLES; +DROP TABLE s; +CREATE VIEW v1 as SELECT * FROM t; +CREATE SEQUENCE s; +DROP SEQUENCE IF EXISTS v1; +Warnings: +Note 4091 Unknown SEQUENCE: 'test.v1' +DROP VIEW IF EXISTS s; +Warnings: +Note 4092 Unknown VIEW: 'test.s' +DROP VIEW v1; +DROP SEQUENCE s; +DROP TABLE t; # End of 10.3 tests diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test index 70c4efa40e5..0fbb2d0e2f9 100644 --- a/mysql-test/suite/sql_sequence/other.test +++ b/mysql-test/suite/sql_sequence/other.test @@ -315,4 +315,68 @@ drop view v2; drop table t1,t2; drop sequence s1; +--echo # +--echo # MDEV-19273:Server crash in MDL_ticket::has_stronger_or_equal_type or +--echo # Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE, +--echo # table->db.str, table->table_name.str, MDL_SHARED)' failed +--echo # in mysql_rm_table_no_locks +--echo # + +CREATE TABLE t1 (a INT); +CREATE TEMPORARY TABLE tmp (b INT); +LOCK TABLE t1 READ; +--error ER_NOT_SEQUENCE2 +DROP SEQUENCE tmp; +--error ER_NOT_SEQUENCE2 +DROP TEMPORARY SEQUENCE tmp; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +DROP SEQUENCE t1; +--error ER_UNKNOWN_SEQUENCES +DROP TEMPORARY SEQUENCE t1; +UNLOCK TABLES; +--error ER_NOT_SEQUENCE2 +DROP SEQUENCE t1; +--error ER_UNKNOWN_SEQUENCES +DROP TEMPORARY SEQUENCE t1; + +# Cleanup +DROP TABLE t1; + + +CREATE TABLE t (a INT); +CREATE TEMPORARY TABLE s (f INT); +CREATE SEQUENCE s; +LOCK TABLE t WRITE; +--error ER_NOT_SEQUENCE2 +DROP SEQUENCE s; +--error ER_NOT_SEQUENCE2 +DROP TEMPORARY SEQUENCE s; +UNLOCK TABLES; +CREATE TEMPORARY SEQUENCE s; +LOCK TABLE t WRITE; +DROP TEMPORARY SEQUENCE s; +UNLOCK TABLES; +DROP TEMPORARY TABLE s; +DROP SEQUENCE s; + +create table s(a INT); +CREATE TEMPORARY TABLE s (f INT); +LOCK TABLE t WRITE; +DROP TEMPORARY TABLE s; +CREATE TEMPORARY TABLE s (f INT); +DROP TABLE s; +--error ER_TABLE_NOT_LOCKED +DROP TABLE s; +UNLOCK TABLES; +DROP TABLE s; + +CREATE VIEW v1 as SELECT * FROM t; +CREATE SEQUENCE s; + +DROP SEQUENCE IF EXISTS v1; +DROP VIEW IF EXISTS s; + +DROP VIEW v1; +DROP SEQUENCE s; +DROP TABLE t; --echo # End of 10.3 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 96d270b25ff..55cc33b4680 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2314,8 +2314,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { bool is_trans= 0; bool table_creation_was_logged= 0; + bool real_table= FALSE; LEX_CSTRING db= table->db; handlerton *table_type= 0; + // reset error state for this table + error= 0; DBUG_PRINT("table", ("table_l: '%s'.'%s' table: %p s: %p", table->db.str, table->table_name.str, table->table, @@ -2331,9 +2334,35 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, thd->find_temporary_table(table) && table->mdl_request.ticket != NULL)); - if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table) || - (drop_sequence && table->table->s->table_type != TABLE_TYPE_SEQUENCE)) + if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table)) + real_table= TRUE; + else if (drop_sequence && + table->table->s->table_type != TABLE_TYPE_SEQUENCE) + { + was_table= (table->table->s->table_type == TABLE_TYPE_NORMAL); + was_view= (table->table->s->table_type == TABLE_TYPE_VIEW); + if (if_exists) + { + char buff[FN_REFLEN]; + String tbl_name(buff, sizeof(buff), system_charset_info); + tbl_name.length(0); + tbl_name.append(&db); + tbl_name.append('.'); + tbl_name.append(&table->table_name); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_NOT_SEQUENCE2, ER_THD(thd, ER_NOT_SEQUENCE2), + tbl_name.c_ptr_safe()); + + /* + Our job is done here. This statement was added to avoid executing + unnecessary code farther below which in some strange corner cases + caused the server to crash (see MDEV-17896). + */ + goto log_query; + } error= 1; + goto non_critical_err; + } else { table_creation_was_logged= table->table->s->table_creation_was_logged; @@ -2342,29 +2371,28 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, error= 1; goto err; } - error= 0; table->table= 0; } - if ((drop_temporary && if_exists) || !error) + if ((drop_temporary && if_exists) || !real_table) { /* This handles the case of temporary tables. We have the following cases: . "DROP TEMPORARY" was executed and a temporary table was affected - (i.e. drop_temporary && !error) or the if_exists was specified (i.e. - drop_temporary && if_exists). + (i.e. drop_temporary && !real_table) or the + if_exists was specified (i.e. drop_temporary && if_exists). . "DROP" was executed but a temporary table was affected (.i.e - !error). + !real_table). */ if (!dont_log_query && table_creation_was_logged) { /* - If there is an error, we don't know the type of the engine + If there is an real_table, we don't know the type of the engine at this point. So, we keep it in the trx-cache. */ - is_trans= error ? TRUE : is_trans; + is_trans= real_table ? TRUE : is_trans; if (is_trans) trans_tmp_table_deleted= TRUE; else @@ -2391,7 +2419,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, is no need to proceed with the code that tries to drop a regular table. */ - if (!error) continue; + if (!real_table) continue; } else if (!drop_temporary) { @@ -2407,7 +2435,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, reg_ext, 0); } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); - error= 0; if (drop_temporary || (ha_table_exists(thd, &db, &alias, &table_type, &is_sequence) == 0 && table_type == 0) || @@ -2447,6 +2474,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { non_tmp_error = (drop_temporary ? non_tmp_error : TRUE); error= 1; + /* + non critical error (only for this table), so we continue. + Next we write it to wrong_tables and continue this loop + The same as "goto non_critical_err". + */ } } else @@ -2540,7 +2572,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } non_tmp_error|= MY_TEST(error); } - +non_critical_err: if (error) { if (wrong_tables.length()) From f99abb45c586e618fbbf573e1990209ab7f26968 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 9 Dec 2020 20:15:29 +0300 Subject: [PATCH 15/72] MDEV-17573 Assertion in federatedx on multi-update Cause: shared federatedx_io cannot store table-specific data. Fix: move current row reference `federatedx_io_mysql::current` to ha_federatedx. FederatedX connection (represented by federatedx_io) is stored into federatedx_txn::txn_list of per-server connections (see federatedx_txn::acquire()). federatedx_txn object is stored into THD (see ha_federatedx::external_lock()). When multiple handlers acquire FederatedX connection they get single federatedx_io instance. Multiple handlers do their operation via federatedx_io_mysql::mark_position() and federatedx_io_mysql::fetch_row() in arbitrarty manner. They access the same federatedx_io_mysql instance and same MYSQL_ROWS *current pointer, so one handler disrupts the work of the other. Related to "MDEV-14551 Can't find record in table on multi-table update with ORDER BY". --- mysql-test/suite/federated/federatedx.result | 26 ++++++++++++++++++ mysql-test/suite/federated/federatedx.test | 29 ++++++++++++++++++++ storage/federatedx/federatedx_io_mysql.cc | 16 ++++++----- storage/federatedx/federatedx_io_null.cc | 10 ++++--- storage/federatedx/ha_federatedx.cc | 4 +-- storage/federatedx/ha_federatedx.h | 7 +++-- 6 files changed, 77 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/federated/federatedx.result b/mysql-test/suite/federated/federatedx.result index 84dcb0d0a8c..af01bb3d90f 100644 --- a/mysql-test/suite/federated/federatedx.result +++ b/mysql-test/suite/federated/federatedx.result @@ -2283,6 +2283,32 @@ connection default; connection master; CREATE TABLE t1 (a INT) ENGINE=FEDERATED CONNECTION='mysql://@127.0.0.1:SLAVE_PORT/federated/t1'; ERROR HY000: Can't create federated table. Foreign data src error: database: 'federated' username: '' hostname: '127.0.0.1' +# +# MDEV-17573 Assertion in federatedx on multi-update +# +create table t1 ( +x int, +d datetime); +create table t1f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t1'; +create table t2 ( +x int, y int, +d datetime); +create table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t2'; +create table t3 ( +x int, y int, z int, +d datetime); +create table t3f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t3'; +insert into t1 values (1, "1990-01-01 00:00"); +insert into t1 values (1, "1991-01-01 11:11"); +insert into t2 values (2, 2, "1992-02-02 22:22"); +insert into t3 values (3, 3, 3, "1993-03-03 23:33"); +update t1f, t2f, t3f set t1f.x= 11, t2f.y= 22, t3f.z= 33; +drop table t1f; +drop table t2f; +drop table t3f; +drop table t1; +drop table t2; +drop table t3; connection master; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/federatedx.test b/mysql-test/suite/federated/federatedx.test index 29d1eaddc26..bd03f744639 100644 --- a/mysql-test/suite/federated/federatedx.test +++ b/mysql-test/suite/federated/federatedx.test @@ -2010,4 +2010,33 @@ connection master; --error ER_CANT_CREATE_FEDERATED_TABLE eval CREATE TABLE t1 (a INT) ENGINE=FEDERATED CONNECTION='mysql://@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +--echo # +--echo # MDEV-17573 Assertion in federatedx on multi-update +--echo # +create table t1 ( + x int, + d datetime); +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval create table t1f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t1'; + +create table t2 ( + x int, y int, + d datetime); +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval create table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t2'; + +create table t3 ( + x int, y int, z int, + d datetime); +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval create table t3f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t3'; + +insert into t1 values (1, "1990-01-01 00:00"); +insert into t1 values (1, "1991-01-01 11:11"); +insert into t2 values (2, 2, "1992-02-02 22:22"); +insert into t3 values (3, 3, 3, "1993-03-03 23:33"); +update t1f, t2f, t3f set t1f.x= 11, t2f.y= 22, t3f.z= 33; + +drop table t1f; drop table t2f; drop table t3f; drop table t1; drop table t2; drop table t3; + source include/federated_cleanup.inc; diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc index 2068716eeba..4a2588a6af4 100644 --- a/storage/federatedx/federatedx_io_mysql.cc +++ b/storage/federatedx/federatedx_io_mysql.cc @@ -64,7 +64,6 @@ struct mysql_position class federatedx_io_mysql :public federatedx_io { MYSQL mysql; /* MySQL connection */ - MYSQL_ROWS *current; DYNAMIC_ARRAY savepoints; bool requested_autocommit; bool actual_autocommit; @@ -108,7 +107,8 @@ public: virtual void free_result(FEDERATEDX_IO_RESULT *io_result); virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result); virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result); - virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result); + virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result, + FEDERATEDX_IO_ROWS **current= NULL); virtual ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result); virtual const char *get_column_data(FEDERATEDX_IO_ROW *row, unsigned int column); @@ -117,7 +117,7 @@ public: virtual size_t get_ref_length() const; virtual void mark_position(FEDERATEDX_IO_RESULT *io_result, - void *ref); + void *ref, FEDERATEDX_IO_ROWS *current); virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, const void *ref); virtual void set_thd(void *thd); @@ -515,10 +515,12 @@ my_ulonglong federatedx_io_mysql::get_num_rows(FEDERATEDX_IO_RESULT *io_result) } -FEDERATEDX_IO_ROW *federatedx_io_mysql::fetch_row(FEDERATEDX_IO_RESULT *io_result) +FEDERATEDX_IO_ROW *federatedx_io_mysql::fetch_row(FEDERATEDX_IO_RESULT *io_result, + FEDERATEDX_IO_ROWS **current) { MYSQL_RES *result= (MYSQL_RES*)io_result; - current= result->data_cursor; + if (current) + *current= (FEDERATEDX_IO_ROWS *) result->data_cursor; return (FEDERATEDX_IO_ROW *) mysql_fetch_row(result); } @@ -626,11 +628,11 @@ size_t federatedx_io_mysql::get_ref_length() const void federatedx_io_mysql::mark_position(FEDERATEDX_IO_RESULT *io_result, - void *ref) + void *ref, FEDERATEDX_IO_ROWS *current) { mysql_position& pos= *reinterpret_cast(ref); pos.result= (MYSQL_RES *) io_result; - pos.offset= current; + pos.offset= (MYSQL_ROW_OFFSET) current; } int federatedx_io_mysql::seek_position(FEDERATEDX_IO_RESULT **io_result, diff --git a/storage/federatedx/federatedx_io_null.cc b/storage/federatedx/federatedx_io_null.cc index aa35d4bdecc..d945db528c7 100644 --- a/storage/federatedx/federatedx_io_null.cc +++ b/storage/federatedx/federatedx_io_null.cc @@ -90,7 +90,8 @@ public: virtual void free_result(FEDERATEDX_IO_RESULT *io_result); virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result); virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result); - virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result); + virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result, + FEDERATEDX_IO_ROWS **current= NULL); virtual ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result); virtual const char *get_column_data(FEDERATEDX_IO_ROW *row, unsigned int column); @@ -98,7 +99,7 @@ public: unsigned int column) const; virtual size_t get_ref_length() const; virtual void mark_position(FEDERATEDX_IO_RESULT *io_result, - void *ref); + void *ref, FEDERATEDX_IO_ROWS *current); virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, const void *ref); }; @@ -242,7 +243,8 @@ my_ulonglong federatedx_io_null::get_num_rows(FEDERATEDX_IO_RESULT *) } -FEDERATEDX_IO_ROW *federatedx_io_null::fetch_row(FEDERATEDX_IO_RESULT *) +FEDERATEDX_IO_ROW *federatedx_io_null::fetch_row(FEDERATEDX_IO_RESULT *, + FEDERATEDX_IO_ROWS **current) { return NULL; } @@ -288,7 +290,7 @@ size_t federatedx_io_null::get_ref_length() const void federatedx_io_null::mark_position(FEDERATEDX_IO_RESULT *io_result, - void *ref) + void *ref, FEDERATEDX_IO_ROWS *current) { } diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 840a5a68885..5d2ddc1fb3b 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -2908,7 +2908,7 @@ int ha_federatedx::read_next(uchar *buf, FEDERATEDX_IO_RESULT *result) DBUG_RETURN(retval); /* Fetch a row, insert it back in a row format. */ - if (!(row= io->fetch_row(result))) + if (!(row= io->fetch_row(result, ¤t))) DBUG_RETURN(HA_ERR_END_OF_FILE); if (!(retval= convert_row_to_internal_format(buf, row, result))) @@ -2952,7 +2952,7 @@ void ha_federatedx::position(const uchar *record __attribute__ ((unused))) if (txn->acquire(share, ha_thd(), TRUE, &io)) DBUG_VOID_RETURN; - io->mark_position(stored_result, ref); + io->mark_position(stored_result, ref, current); position_called= TRUE; diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 56c34d9ef37..3d208d89074 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -129,6 +129,7 @@ typedef struct st_federatedx_share { typedef struct st_federatedx_result FEDERATEDX_IO_RESULT; typedef struct st_federatedx_row FEDERATEDX_IO_ROW; +typedef struct st_federatedx_rows FEDERATEDX_IO_ROWS; typedef ptrdiff_t FEDERATEDX_IO_OFFSET; class federatedx_io @@ -203,7 +204,8 @@ public: virtual void free_result(FEDERATEDX_IO_RESULT *io_result)=0; virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result)=0; virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result)=0; - virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result)=0; + virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result, + FEDERATEDX_IO_ROWS **current= NULL)=0; virtual ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result)=0; virtual const char *get_column_data(FEDERATEDX_IO_ROW *row, unsigned int column)=0; @@ -212,7 +214,7 @@ public: virtual size_t get_ref_length() const=0; virtual void mark_position(FEDERATEDX_IO_RESULT *io_result, - void *ref)=0; + void *ref, FEDERATEDX_IO_ROWS *current)=0; virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, const void *ref)=0; virtual void set_thd(void *thd) { } @@ -265,6 +267,7 @@ class ha_federatedx: public handler federatedx_txn *txn; federatedx_io *io; FEDERATEDX_IO_RESULT *stored_result; + FEDERATEDX_IO_ROWS *current; /** Array of all stored results we get during a query execution. */ From 59bbe873d48b13eb3b8a912c2187ea94ee165ae9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 3 Nov 2020 19:07:16 +0100 Subject: [PATCH 16/72] Revert "MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare" This reverts commit 5a0c34e4c2fd951119efb432eedcaa65a1d36606. but keeps the test case --- sql/field.h | 3 --- sql/filesort.cc | 14 +------------- sql/sql_class.h | 2 -- sql/sql_type.h | 2 -- 4 files changed, 1 insertion(+), 20 deletions(-) diff --git a/sql/field.h b/sql/field.h index fea40251587..18e44f1d9d4 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1339,8 +1339,6 @@ public: virtual uint max_packed_col_length(uint max_length) { return max_length;} - virtual bool is_packable() const { return false; } - uint offset(uchar *record) const { return (uint) (ptr - record); @@ -1829,7 +1827,6 @@ public: bool can_optimize_range(const Item_bool_func *cond, const Item *item, bool is_eq_func) const; - bool is_packable() const { return true; } }; /* base class for float and double and decimal (old one) */ diff --git a/sql/filesort.cc b/sql/filesort.cc index 96f9aa874da..d76c39c3bd4 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1971,14 +1971,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, if (sortorder->field) { CHARSET_INFO *cs= sortorder->field->sort_charset(); - sortorder->type= sortorder->field->is_packable() ? - SORT_FIELD_ATTR::VARIABLE_SIZE : - SORT_FIELD_ATTR::FIXED_SIZE; - sortorder->length= sortorder->field->sort_length(); - if (sortorder->is_variable_sized()) - set_if_smaller(sortorder->length, thd->variables.max_sort_length); - if (use_strnxfrm((cs=sortorder->field->sort_charset()))) { *multi_byte_charset= true; @@ -1989,10 +1982,6 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, } else { - sortorder->type= sortorder->item->type_handler()->is_packable() ? - SORT_FIELD_ATTR::VARIABLE_SIZE : - SORT_FIELD_ATTR::FIXED_SIZE; - sortorder->item->sortlength(thd, sortorder->item, sortorder); if (use_strnxfrm(sortorder->item->collation.collation)) { @@ -2001,8 +1990,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, if (sortorder->item->maybe_null) length++; // Place for NULL marker } - if (sortorder->is_variable_sized()) - set_if_smaller(sortorder->length, thd->variables.max_sort_length); + set_if_smaller(sortorder->length, thd->variables.max_sort_length); length+=sortorder->length; } sortorder->field= (Field*) 0; // end marker diff --git a/sql/sql_class.h b/sql/sql_class.h index 84f188b7803..d2b0b40846b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5456,8 +5456,6 @@ struct SORT_FIELD_ATTR { uint length; /* Length of sort field */ uint suffix_length; /* Length suffix (0-4) */ - enum Type { FIXED_SIZE, VARIABLE_SIZE } type; - bool is_variable_sized() { return type == VARIABLE_SIZE; } }; diff --git a/sql/sql_type.h b/sql/sql_type.h index 046b42e4a83..42090037ead 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -92,7 +92,6 @@ public: virtual void sortlength(THD *thd, const Type_std_attributes *item, SORT_FIELD_ATTR *attr) const= 0; - virtual bool is_packable() const { return false; } }; @@ -170,7 +169,6 @@ public: void sortlength(THD *thd, const Type_std_attributes *item, SORT_FIELD_ATTR *attr) const; - bool is_packable()const { return true; } }; From b31912fd3525be526cd2852e376bd7d1e7ec4d31 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 3 Nov 2020 23:38:31 +0100 Subject: [PATCH 17/72] MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare don't allow too small max_sort_length values --- mysql-test/include/ctype_utf8mb4.inc | 2 +- mysql-test/r/ctype_utf16.result | 2 + mysql-test/r/ctype_utf16le.result | 2 + mysql-test/r/ctype_utf32.result | 2 + mysql-test/r/ctype_utf8.result | 4 +- mysql-test/r/ctype_utf8mb4.result | 4 +- mysql-test/r/ctype_utf8mb4_heap.result | 4 +- mysql-test/r/ctype_utf8mb4_innodb.result | 4 +- mysql-test/r/ctype_utf8mb4_myisam.result | 4 +- mysql-test/r/order_by.result | 22 +- mysql-test/r/query_cache.result | 28 +- .../sys_vars/r/max_sort_length_basic.result | 199 -------- .../sys_vars/r/max_sort_length_func.result | 442 +++++++++--------- .../sys_vars/r/sysvars_server_embedded.result | 2 +- .../r/sysvars_server_notembedded.result | 2 +- .../sys_vars/t/max_sort_length_basic.test | 225 --------- .../sys_vars/t/max_sort_length_func.test | 157 +++---- mysql-test/t/ctype_utf8mb4.test | 2 +- mysql-test/t/order_by.test | 8 +- mysql-test/t/query_cache.test | 10 +- sql/sys_vars.cc | 2 +- 21 files changed, 328 insertions(+), 799 deletions(-) delete mode 100644 mysql-test/suite/sys_vars/r/max_sort_length_basic.result delete mode 100644 mysql-test/suite/sys_vars/t/max_sort_length_basic.test diff --git a/mysql-test/include/ctype_utf8mb4.inc b/mysql-test/include/ctype_utf8mb4.inc index 862afe96f6c..2e924d6ddde 100644 --- a/mysql-test/include/ctype_utf8mb4.inc +++ b/mysql-test/include/ctype_utf8mb4.inc @@ -1585,7 +1585,7 @@ drop table t1; --echo # --echo # Check strnxfrm() with odd length --echo # -set max_sort_length=9; +set max_sort_length=65; select @@max_sort_length; eval create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine $engine; insert into t1 values ('a'),('b'),('c'); diff --git a/mysql-test/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result index 491e01b7361..9fa055b9526 100644 --- a/mysql-test/r/ctype_utf16.result +++ b/mysql-test/r/ctype_utf16.result @@ -1492,6 +1492,8 @@ ab AE AE SET max_sort_length=8; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '8' SELECT * FROM t1 ORDER BY s1; s1 ab diff --git a/mysql-test/r/ctype_utf16le.result b/mysql-test/r/ctype_utf16le.result index d98c113840b..a43ed6ee538 100644 --- a/mysql-test/r/ctype_utf16le.result +++ b/mysql-test/r/ctype_utf16le.result @@ -1765,6 +1765,8 @@ ab AE AE SET max_sort_length=8; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '8' SELECT * FROM t1 ORDER BY s1; s1 ab diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result index 8f40a90859b..7598474e493 100644 --- a/mysql-test/r/ctype_utf32.result +++ b/mysql-test/r/ctype_utf32.result @@ -1505,6 +1505,8 @@ ab AE AE SET max_sort_length=8; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '8' SELECT * FROM t1 ORDER BY s1; s1 ab diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index d7f13b4053f..7189629b570 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -6755,9 +6755,11 @@ DFFFDFFF9CFF9DFF9EFF # Checking strnxfrm() with odd length # set max_sort_length=9; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '9' select @@max_sort_length; @@max_sort_length -9 +64 create table t1 (a varchar(128) character set utf8 collate utf8_general_ci); insert into t1 values ('a'),('b'),('c'); select * from t1 order by a; diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index 691ac51e241..bdcc07d590e 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -2371,10 +2371,10 @@ drop table t1; # # Check strnxfrm() with odd length # -set max_sort_length=9; +set max_sort_length=65; select @@max_sort_length; @@max_sort_length -9 +65 create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci); insert into t1 values ('a'),('b'),('c'); select * from t1 order by a; diff --git a/mysql-test/r/ctype_utf8mb4_heap.result b/mysql-test/r/ctype_utf8mb4_heap.result index 4aef2d8cb66..9eb7d48370f 100644 --- a/mysql-test/r/ctype_utf8mb4_heap.result +++ b/mysql-test/r/ctype_utf8mb4_heap.result @@ -2203,10 +2203,10 @@ drop table t1; # # Check strnxfrm() with odd length # -set max_sort_length=9; +set max_sort_length=65; select @@max_sort_length; @@max_sort_length -9 +65 create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine heap; insert into t1 values ('a'),('b'),('c'); select * from t1 order by a; diff --git a/mysql-test/r/ctype_utf8mb4_innodb.result b/mysql-test/r/ctype_utf8mb4_innodb.result index 7c95906a742..c8fe1233b55 100644 --- a/mysql-test/r/ctype_utf8mb4_innodb.result +++ b/mysql-test/r/ctype_utf8mb4_innodb.result @@ -2331,10 +2331,10 @@ drop table t1; # # Check strnxfrm() with odd length # -set max_sort_length=9; +set max_sort_length=65; select @@max_sort_length; @@max_sort_length -9 +65 create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine InnoDB; insert into t1 values ('a'),('b'),('c'); select * from t1 order by a; diff --git a/mysql-test/r/ctype_utf8mb4_myisam.result b/mysql-test/r/ctype_utf8mb4_myisam.result index f06a1fc53f3..c975d805dfa 100644 --- a/mysql-test/r/ctype_utf8mb4_myisam.result +++ b/mysql-test/r/ctype_utf8mb4_myisam.result @@ -2331,10 +2331,10 @@ drop table t1; # # Check strnxfrm() with odd length # -set max_sort_length=9; +set max_sort_length=65; select @@max_sort_length; @@max_sort_length -9 +65 create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine MyISAM; insert into t1 values ('a'),('b'),('c'); select * from t1 order by a; diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 7bc8f562f1b..b1441013bc8 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -763,18 +763,20 @@ col2 col col 2 2 2 1 3 3 drop table t1, t2; -create table t1 (a char(25)); +create table t1 (a char(70)); insert into t1 set a = repeat('x', 20); -insert into t1 set a = concat(repeat('x', 19), 'z'); -insert into t1 set a = concat(repeat('x', 19), 'ab'); -insert into t1 set a = concat(repeat('x', 19), 'aa'); +insert into t1 set a = concat(repeat('x', 63), 'z'); +insert into t1 set a = concat(repeat('x', 63), 'ab'); +insert into t1 set a = concat(repeat('x', 63), 'aa'); set max_sort_length=20; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '20' select a from t1 order by a; a -xxxxxxxxxxxxxxxxxxxab -xxxxxxxxxxxxxxxxxxxaa xxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxz +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxab +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaa +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz drop table t1; create table t1 ( `sid` decimal(8,0) default null, @@ -3241,6 +3243,8 @@ drop table t1; SET @save_sort_buffer_size= @@sort_buffer_size; SET @save_max_sort_length= @@max_sort_length; SET max_sort_length=8; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '8' SET sort_buffer_size=1024; CREATE TABLE t1(a INT, b DECIMAL(65), c BLOB); INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_25; @@ -3308,6 +3312,8 @@ SET @save_max_sort_length= @@max_sort_length; SET @save_sort_buffer_size= @@sort_buffer_size; SET @save_max_length_for_sort_data= @@max_length_for_sort_data; SET max_sort_length=8; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '8' SET sort_buffer_size=1024; SET max_length_for_sort_data=7000; CREATE TABLE t1(a VARCHAR(64), b VARCHAR(2048))DEFAULT CHARSET=utf8; @@ -3443,6 +3449,8 @@ INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); SET max_length_for_sort_data= 30; SET sql_select_limit = 3; SET max_sort_length=8; +Warnings: +Warning 1292 Truncated incorrect max_sort_length value: '8' SELECT * FROM t1 ORDER BY a+1; a b 1 1 diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index d872735e507..11d9cead143 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -814,33 +814,33 @@ select @@character_set_results; NULL set character_set_results=default; set GLOBAL query_cache_size=1355776; -create table t1 (id int auto_increment primary key, c char(25)); +create table t1 (id int auto_increment primary key, c char(65)); insert into t1 set c = repeat('x',24); -insert into t1 set c = concat(repeat('x',24),'x'); -insert into t1 set c = concat(repeat('x',24),'w'); -insert into t1 set c = concat(repeat('x',24),'y'); +insert into t1 set c = concat(repeat('x',64),'x'); +insert into t1 set c = concat(repeat('x',64),'w'); +insert into t1 set c = concat(repeat('x',64),'y'); set max_sort_length=200; select c from t1 order by c, id; c xxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxw -xxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy reset query cache; -set max_sort_length=20; +set max_sort_length=64; select c from t1 order by c, id; c xxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxw -xxxxxxxxxxxxxxxxxxxxxxxxy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy set max_sort_length=200; select c from t1 order by c, id; c xxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxw -xxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy set max_sort_length=default; select '1' || '3' from t1; '1' || '3' diff --git a/mysql-test/suite/sys_vars/r/max_sort_length_basic.result b/mysql-test/suite/sys_vars/r/max_sort_length_basic.result deleted file mode 100644 index b48b045897c..00000000000 --- a/mysql-test/suite/sys_vars/r/max_sort_length_basic.result +++ /dev/null @@ -1,199 +0,0 @@ -SET @start_global_value = @@global.max_sort_length; -SELECT @start_global_value; -@start_global_value -1024 -SET @start_session_value = @@session.max_sort_length; -SELECT @start_session_value; -@start_session_value -1024 -'#--------------------FN_DYNVARS_084_01-------------------------#' -SET @@global.max_sort_length = 1000; -SET @@global.max_sort_length = DEFAULT; -SELECT @@global.max_sort_length; -@@global.max_sort_length -1024 -SET @@session.max_sort_length = 1000; -SET @@session.max_sort_length = DEFAULT; -SELECT @@session.max_sort_length; -@@session.max_sort_length -1024 -'#--------------------FN_DYNVARS_084_02-------------------------#' -SET @@global.max_sort_length = DEFAULT; -SELECT @@global.max_sort_length = 1024; -@@global.max_sort_length = 1024 -1 -SET @@session.max_sort_length = DEFAULT; -SELECT @@session.max_sort_length = 1024; -@@session.max_sort_length = 1024 -1 -'#--------------------FN_DYNVARS_084_03-------------------------#' -SET @@global.max_sort_length = 8; -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@global.max_sort_length = 9; -SELECT @@global.max_sort_length; -@@global.max_sort_length -9 -SET @@global.max_sort_length = 8388608; -SELECT @@global.max_sort_length; -@@global.max_sort_length -8388608 -SET @@global.max_sort_length = 8388607; -SELECT @@global.max_sort_length; -@@global.max_sort_length -8388607 -SET @@global.max_sort_length = 65536; -SELECT @@global.max_sort_length; -@@global.max_sort_length -65536 -'#--------------------FN_DYNVARS_084_04-------------------------#' -SET @@session.max_sort_length = 8; -SELECT @@session.max_sort_length; -@@session.max_sort_length -8 -SET @@session.max_sort_length = 9; -SELECT @@session.max_sort_length; -@@session.max_sort_length -9 -SET @@session.max_sort_length = 8388608; -SELECT @@session.max_sort_length; -@@session.max_sort_length -8388608 -SET @@session.max_sort_length = 8388607; -SELECT @@session.max_sort_length; -@@session.max_sort_length -8388607 -SET @@session.max_sort_length = 65536; -SELECT @@session.max_sort_length; -@@session.max_sort_length -65536 -'#------------------FN_DYNVARS_084_05-----------------------#' -SET @@global.max_sort_length = -1024; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '-1024' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@global.max_sort_length = 3; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '3' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@global.max_sort_length = 8388609; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '8388609' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8388608 -SET @@global.max_sort_length = 0; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '0' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@global.max_sort_length = 65530.34; -ERROR 42000: Incorrect argument type to variable 'max_sort_length' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@global.max_sort_length = test; -ERROR 42000: Incorrect argument type to variable 'max_sort_length' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@session.max_sort_length = 8388610; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '8388610' -SELECT @@session.max_sort_length; -@@session.max_sort_length -8388608 -SET @@session.max_sort_length = -1; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '-1' -SELECT @@session.max_sort_length; -@@session.max_sort_length -8 -SET @@session.max_sort_length = 3; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '3' -SELECT @@session.max_sort_length; -@@session.max_sort_length -8 -SET @@session.max_sort_length = 0; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '0' -SELECT @@session.max_sort_length; -@@session.max_sort_length -8 -SET @@session.max_sort_length = 65530.34; -ERROR 42000: Incorrect argument type to variable 'max_sort_length' -SET @@session.max_sort_length = 10737418241; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '10737418241' -SELECT @@session.max_sort_length; -@@session.max_sort_length -8388608 -SET @@session.max_sort_length = test; -ERROR 42000: Incorrect argument type to variable 'max_sort_length' -SELECT @@session.max_sort_length; -@@session.max_sort_length -8388608 -'#------------------FN_DYNVARS_084_06-----------------------#' -SELECT @@global.max_sort_length = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='max_sort_length'; -@@global.max_sort_length = VARIABLE_VALUE -1 -'#------------------FN_DYNVARS_084_07-----------------------#' -SELECT @@session.max_sort_length = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.SESSION_VARIABLES -WHERE VARIABLE_NAME='max_sort_length'; -@@session.max_sort_length = VARIABLE_VALUE -1 -'#------------------FN_DYNVARS_084_08-----------------------#' -SET @@global.max_sort_length = TRUE; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '1' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -SET @@global.max_sort_length = FALSE; -Warnings: -Warning 1292 Truncated incorrect max_sort_length value: '0' -SELECT @@global.max_sort_length; -@@global.max_sort_length -8 -'#---------------------FN_DYNVARS_084_09----------------------#' -SET @@global.max_sort_length = 2048; -SELECT @@max_sort_length = @@global.max_sort_length; -@@max_sort_length = @@global.max_sort_length -0 -'#---------------------FN_DYNVARS_084_10----------------------#' -SET @@max_sort_length = 100000; -SELECT @@max_sort_length = @@local.max_sort_length; -@@max_sort_length = @@local.max_sort_length -1 -SELECT @@local.max_sort_length = @@session.max_sort_length; -@@local.max_sort_length = @@session.max_sort_length -1 -'#---------------------FN_DYNVARS_084_11----------------------#' -SET max_sort_length = 1024; -SELECT @@max_sort_length; -@@max_sort_length -1024 -SELECT local.max_sort_length; -ERROR 42S02: Unknown table 'local' in field list -SELECT session.max_sort_length; -ERROR 42S02: Unknown table 'session' in field list -SELECT max_sort_length = @@session.max_sort_length; -ERROR 42S22: Unknown column 'max_sort_length' in 'field list' -SET @@global.max_sort_length = @start_global_value; -SELECT @@global.max_sort_length; -@@global.max_sort_length -1024 -SET @@session.max_sort_length = @start_session_value; -SELECT @@session.max_sort_length; -@@session.max_sort_length -1024 diff --git a/mysql-test/suite/sys_vars/r/max_sort_length_func.result b/mysql-test/suite/sys_vars/r/max_sort_length_func.result index 36f5518287a..3ec8faf1b7e 100644 --- a/mysql-test/suite/sys_vars/r/max_sort_length_func.result +++ b/mysql-test/suite/sys_vars/r/max_sort_length_func.result @@ -1,301 +1,279 @@ SET @start_value= @@global.max_sort_length; -SET @session_max_sort_length = @@Session.max_sort_length; -DROP TABLE IF EXISTS t; ** creating tables ** -CREATE TABLE t -( -id INT AUTO_INCREMENT PRIMARY KEY, -c TEXT(30) -); -CREATE TABLE t1 -( -id INT AUTO_INCREMENT PRIMARY KEY, -c BLOB(30) -); -CREATE TABLE t2 -( -id INT AUTO_INCREMENT PRIMARY KEY, -c TEXT(30) -); +CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, c TEXT); +CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, c BLOB); +CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY, c TEXT); '#--------------------FN_DYNVARS_098_01-------------------------#' connect test_con1,localhost,root,,; -connection test_con1; -SELECT @@global.max_sort_length = 10; -@@global.max_sort_length = 10 -0 -SELECT @@session.max_sort_length = 10; -@@session.max_sort_length = 10 -0 -** Setting value to 30 and inserting data ** -SET @@global.max_sort_length = 30; +** Setting value to 70 and inserting data ** +SET @@global.max_sort_length = 70; SELECT @@global.max_sort_length; @@global.max_sort_length -30 -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +70 +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ** Results should be sorted ** -SET @@session.max_sort_length = 29; +SET @@session.max_sort_length = 69; SELECT @@session.max_sort_length; @@session.max_sort_length -29 -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +69 +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ** Results should be sorted ** '#--------------------FN_DYNVARS_098_02-------------------------#' connect test_con2,localhost,root,,; -connection test_con2; -SET @@global.max_sort_length = 30; +SET @@global.max_sort_length = 70; SELECT @@global.max_sort_length; @@global.max_sort_length -30 -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +70 +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ** Results should be sorted ** -SET @@session.max_sort_length = 20; +SET @@session.max_sort_length = 64; SELECT @@session.max_sort_length; @@session.max_sort_length -20 -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +64 +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw ** Results should not be sorted ** '#--------------------FN_DYNVARS_098_03-------------------------#' -SET max_sort_length=20; -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +SET max_sort_length=64; +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw ** Results should not be sorted ** RESET QUERY CACHE; '#--------------------FN_DYNVARS_098_04-------------------------#' -SET max_sort_length=29; +SET max_sort_length=69; SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ** Results should be sorted ** '#--------------------FN_DYNVARS_098_05-------------------------#' -SET max_sort_length=30; +SET max_sort_length=70; SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ** Results should be sorted ** '#--------------------FN_DYNVARS_098_06-------------------------#' SET max_sort_length=default; +SELECT @@max_sort_length; +@@max_sort_length +70 SELECT c from t ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ** Results should be sorted ** '#--------------------FN_DYNVARS_098_07-------------------------#' Testing type BLOB -SET @@global.max_sort_length = 30; -SELECT @@global.max_sort_length; -@@global.max_sort_length -30 -INSERT INTO t1 set c = repeat('x',29); -INSERT INTO t1 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t1 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t1 set c = concat(repeat('x',28),'g','w'); -SELECT c from t1 ORDER BY c, id; +SET @@max_sort_length = 70; +SELECT @@max_sort_length; +@@max_sort_length +70 +INSERT INTO t1 set c = repeat('x',69); +INSERT INTO t1 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t1 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t1 set c = concat(repeat('x',68),'g','w'); +SELECT c from t1 ORDER BY c, id DESC; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx ** Results should be sorted ** -SET @@session.max_sort_length = 20; +SET @@session.max_sort_length = 64; SELECT @@session.max_sort_length; @@session.max_sort_length -20 -INSERT INTO t1 set c = repeat('x',29); -INSERT INTO t1 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t1 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t1 set c = concat(repeat('x',28),'g','w'); +64 +INSERT INTO t1 set c = repeat('x',69); +INSERT INTO t1 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t1 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t1 set c = concat(repeat('x',68),'g','w'); SELECT c from t1 ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw ** Results should not be sorted ** '#--------------------FN_DYNVARS_098_08-------------------------#' Testing type CHAR -SET @@global.max_sort_length = 30; +SET @@global.max_sort_length = 70; SELECT @@global.max_sort_length; @@global.max_sort_length -30 -INSERT INTO t2 set c = repeat('x',29); -INSERT INTO t2 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t2 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t2 set c = concat(repeat('x',28),'g','w'); +70 +INSERT INTO t2 set c = repeat('x',69); +INSERT INTO t2 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t2 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t2 set c = concat(repeat('x',68),'g','w'); SELECT c from t2 ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw ** Results should not be sorted ** -SET @@session.max_sort_length = 20; +SET @@session.max_sort_length = 64; SELECT @@session.max_sort_length; @@session.max_sort_length -20 -INSERT INTO t2 set c = repeat('x',29); -INSERT INTO t2 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t2 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t2 set c = concat(repeat('x',28),'g','w'); +64 +INSERT INTO t2 set c = repeat('x',69); +INSERT INTO t2 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t2 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t2 set c = concat(repeat('x',68),'g','w'); SELECT c from t2 ORDER BY c, id; c -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw -xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxrx -xxxxxxxxxxxxxxxxxxxxxxxxxxxxsy -xxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsy +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgw ** Results should not be sorted ** connection default; disconnect test_con1; disconnect test_con2; -SET @@SESSION.max_sort_length = @session_max_sort_length; -DROP TABLE IF EXISTS t; -DROP TABLE IF EXISTS t1; -DROP TABLE IF EXISTS t2; +DROP TABLE t, t1, t2; SET @@global.max_sort_length= @start_value; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 87795f802e2..06886ff05c4 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -1766,7 +1766,7 @@ VARIABLE_NAME MAX_SORT_LENGTH VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored) -NUMERIC_MIN_VALUE 8 +NUMERIC_MIN_VALUE 64 NUMERIC_MAX_VALUE 8388608 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index aaaf1afb8b7..4808997a87a 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -1906,7 +1906,7 @@ VARIABLE_NAME MAX_SORT_LENGTH VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored) -NUMERIC_MIN_VALUE 8 +NUMERIC_MIN_VALUE 64 NUMERIC_MAX_VALUE 8388608 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL diff --git a/mysql-test/suite/sys_vars/t/max_sort_length_basic.test b/mysql-test/suite/sys_vars/t/max_sort_length_basic.test deleted file mode 100644 index fcd6db017f1..00000000000 --- a/mysql-test/suite/sys_vars/t/max_sort_length_basic.test +++ /dev/null @@ -1,225 +0,0 @@ -############## mysql-test\t\max_sort_length_basic.test ############### -# # -# Variable Name: max_sort_length # -# Scope: GLOBAL | SESSION # -# Access Type: Dynamic # -# Data Type: numeric # -# Default Value: 1024 # -# Range: 4-8388608 # -# # -# # -# Creation Date: 2008-02-07 # -# Author: Salman # -# # -# Description: Test Cases of Dynamic System Variable max_sort_length # -# that checks the behavior of this variable in the following ways# -# * Default Value # -# * Valid & Invalid values # -# * Scope & Access method # -# * Data Integrity # -# # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/ # -# server-system-variables.html # -# # -############################################################################### - ---source include/load_sysvars.inc - - -############################################ -# START OF max_sort_length TESTS # -############################################ - - -############################################################# -# Save initial value # -############################################################# - -SET @start_global_value = @@global.max_sort_length; -SELECT @start_global_value; -SET @start_session_value = @@session.max_sort_length; -SELECT @start_session_value; - - ---echo '#--------------------FN_DYNVARS_084_01-------------------------#' -####################################################### -# Display the DEFAULT value of max_sort_length # -####################################################### - -SET @@global.max_sort_length = 1000; -SET @@global.max_sort_length = DEFAULT; -SELECT @@global.max_sort_length; - - -SET @@session.max_sort_length = 1000; -SET @@session.max_sort_length = DEFAULT; -SELECT @@session.max_sort_length; - - ---echo '#--------------------FN_DYNVARS_084_02-------------------------#' -####################################################### -# Check the DEFAULT value of max_sort_length # -####################################################### - -SET @@global.max_sort_length = DEFAULT; -SELECT @@global.max_sort_length = 1024; - -SET @@session.max_sort_length = DEFAULT; -SELECT @@session.max_sort_length = 1024; - - - ---echo '#--------------------FN_DYNVARS_084_03-------------------------#' -######################################################################### -# Change the value of max_sort_length to a valid value for GLOBAL Scope # -######################################################################### - -SET @@global.max_sort_length = 8; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 9; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 8388608; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 8388607; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 65536; -SELECT @@global.max_sort_length; - ---echo '#--------------------FN_DYNVARS_084_04-------------------------#' -########################################################################## -# Change the value of max_sort_length to a valid value for SESSION Scope # -########################################################################## - -SET @@session.max_sort_length = 8; -SELECT @@session.max_sort_length; - -SET @@session.max_sort_length = 9; -SELECT @@session.max_sort_length; - -SET @@session.max_sort_length = 8388608; -SELECT @@session.max_sort_length; - -SET @@session.max_sort_length = 8388607; -SELECT @@session.max_sort_length; - -SET @@session.max_sort_length = 65536; -SELECT @@session.max_sort_length; - - ---echo '#------------------FN_DYNVARS_084_05-----------------------#' -########################################################### -# Change the value of max_sort_length to an invalid value # -########################################################### - -SET @@global.max_sort_length = -1024; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 3; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 8388609; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = 0; -SELECT @@global.max_sort_length; ---Error ER_WRONG_TYPE_FOR_VAR -SET @@global.max_sort_length = 65530.34; -SELECT @@global.max_sort_length; ---Error ER_WRONG_TYPE_FOR_VAR -SET @@global.max_sort_length = test; -SELECT @@global.max_sort_length; - -SET @@session.max_sort_length = 8388610; -SELECT @@session.max_sort_length; -SET @@session.max_sort_length = -1; -SELECT @@session.max_sort_length; -SET @@session.max_sort_length = 3; -SELECT @@session.max_sort_length; -SET @@session.max_sort_length = 0; -SELECT @@session.max_sort_length; ---Error ER_WRONG_TYPE_FOR_VAR -SET @@session.max_sort_length = 65530.34; -SET @@session.max_sort_length = 10737418241; -SELECT @@session.max_sort_length; ---Error ER_WRONG_TYPE_FOR_VAR -SET @@session.max_sort_length = test; -SELECT @@session.max_sort_length; - - ---echo '#------------------FN_DYNVARS_084_06-----------------------#' -#################################################################### -# Check if the value in GLOBAL Table matches value in variable # -#################################################################### - - -SELECT @@global.max_sort_length = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='max_sort_length'; - ---echo '#------------------FN_DYNVARS_084_07-----------------------#' -#################################################################### -# Check if the value in SESSION Table matches value in variable # -#################################################################### - -SELECT @@session.max_sort_length = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.SESSION_VARIABLES -WHERE VARIABLE_NAME='max_sort_length'; - - ---echo '#------------------FN_DYNVARS_084_08-----------------------#' -#################################################################### -# Check if TRUE and FALSE values can be used on variable # -#################################################################### - -SET @@global.max_sort_length = TRUE; -SELECT @@global.max_sort_length; -SET @@global.max_sort_length = FALSE; -SELECT @@global.max_sort_length; - - ---echo '#---------------------FN_DYNVARS_084_09----------------------#' -################################################################################# -# Check if accessing variable with and without GLOBAL point to same variable # -################################################################################# - -SET @@global.max_sort_length = 2048; -SELECT @@max_sort_length = @@global.max_sort_length; - - ---echo '#---------------------FN_DYNVARS_084_10----------------------#' -######################################################################################################## -# Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable # -######################################################################################################## - -SET @@max_sort_length = 100000; -SELECT @@max_sort_length = @@local.max_sort_length; -SELECT @@local.max_sort_length = @@session.max_sort_length; - - ---echo '#---------------------FN_DYNVARS_084_11----------------------#' -########################################################################## -# Check if max_sort_length can be accessed with and without @@ sign # -########################################################################## - - -SET max_sort_length = 1024; -SELECT @@max_sort_length; ---Error ER_UNKNOWN_TABLE -SELECT local.max_sort_length; ---Error ER_UNKNOWN_TABLE -SELECT session.max_sort_length; ---Error ER_BAD_FIELD_ERROR -SELECT max_sort_length = @@session.max_sort_length; - - -#################################### -# Restore initial value # -#################################### - -SET @@global.max_sort_length = @start_global_value; -SELECT @@global.max_sort_length; -SET @@session.max_sort_length = @start_session_value; -SELECT @@session.max_sort_length; - - -#################################################### -# END OF max_sort_length TESTS # -#################################################### - diff --git a/mysql-test/suite/sys_vars/t/max_sort_length_func.test b/mysql-test/suite/sys_vars/t/max_sort_length_func.test index fd0b87750a1..d54453a57b6 100644 --- a/mysql-test/suite/sys_vars/t/max_sort_length_func.test +++ b/mysql-test/suite/sys_vars/t/max_sort_length_func.test @@ -26,70 +26,40 @@ SET @start_value= @@global.max_sort_length; -SET @session_max_sort_length = @@Session.max_sort_length; - - ---disable_warnings -DROP TABLE IF EXISTS t; ---enable_warnings - ######################### # Creating new table # ######################### - --echo ** creating tables ** -CREATE TABLE t -( -id INT AUTO_INCREMENT PRIMARY KEY, -c TEXT(30) -); - -CREATE TABLE t1 -( -id INT AUTO_INCREMENT PRIMARY KEY, -c BLOB(30) -); - -CREATE TABLE t2 -( -id INT AUTO_INCREMENT PRIMARY KEY, -c TEXT(30) -); - - +CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, c TEXT); +CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, c BLOB); +CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY, c TEXT); --echo '#--------------------FN_DYNVARS_098_01-------------------------#' ########################################################## # Test behavior of variable on new connection # 01 # ########################################################## - connect (test_con1,localhost,root,,); -connection test_con1; - -# Value of session & global vairable here should be 10 -SELECT @@global.max_sort_length = 10; -SELECT @@session.max_sort_length = 10; # Setting global value of variable and inserting data in table ---echo ** Setting value to 30 and inserting data ** -SET @@global.max_sort_length = 30; +--echo ** Setting value to 70 and inserting data ** +SET @@global.max_sort_length = 70; SELECT @@global.max_sort_length; -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; --echo ** Results should be sorted ** # Setting session value of variable and inserting data in table -SET @@session.max_sort_length = 29; +SET @@session.max_sort_length = 69; SELECT @@session.max_sort_length; -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; --echo ** Results should be sorted ** @@ -99,72 +69,69 @@ SELECT c from t ORDER BY c, id; ########################################################## connect (test_con2,localhost,root,,); -connection test_con2; - ## Setting global value of variable and inserting data in table -SET @@global.max_sort_length = 30; +SET @@global.max_sort_length = 70; SELECT @@global.max_sort_length; -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; --echo ** Results should be sorted ** # Setting session value of variable and inserting data in table -SET @@session.max_sort_length = 20; +SET @@session.max_sort_length = 64; SELECT @@session.max_sort_length; -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; --echo ** Results should not be sorted ** --echo '#--------------------FN_DYNVARS_098_03-------------------------#' ######################################################### -#Check if sorting is applied with the max_sort_length=20# +#Check if sorting is applied with the max_sort_length=64# ######################################################### ########################################### # Setting new value for max_sort_length # ########################################### -SET max_sort_length=20; +SET max_sort_length=64; ################################### # Inserting values in table t # ################################### -INSERT INTO t set c = repeat('x',29); -INSERT INTO t set c = concat(repeat('x',28),'r','x'); -INSERT INTO t set c = concat(repeat('x',28),'s','y'); -INSERT INTO t set c = concat(repeat('x',28),'g','w'); +INSERT INTO t set c = repeat('x',69); +INSERT INTO t set c = concat(repeat('x',68),'r','x'); +INSERT INTO t set c = concat(repeat('x',68),'s','y'); +INSERT INTO t set c = concat(repeat('x',68),'g','w'); SELECT c from t ORDER BY c, id; --echo ** Results should not be sorted ** RESET QUERY CACHE; - --echo '#--------------------FN_DYNVARS_098_04-------------------------#' ######################################################### -#Check if sorting is applied with the max_sort_length=29# +#Check if sorting is applied with the max_sort_length=69# ######################################################### -SET max_sort_length=29; +SET max_sort_length=69; SELECT c from t ORDER BY c, id; --echo ** Results should be sorted ** --echo '#--------------------FN_DYNVARS_098_05-------------------------#' ######################################################### -#Check if sorting is applied with the max_sort_length=30# +#Check if sorting is applied with the max_sort_length=70# ######################################################### -SET max_sort_length=30; +SET max_sort_length=70; SELECT c from t ORDER BY c, id; --echo ** Results should be sorted ** @@ -173,34 +140,33 @@ SELECT c from t ORDER BY c, id; #Check if sorting is applied with the max_sort_length=Default# ############################################################## - SET max_sort_length=default; +SELECT @@max_sort_length; SELECT c from t ORDER BY c, id; --echo ** Results should be sorted ** - --echo '#--------------------FN_DYNVARS_098_07-------------------------#' ########################################### #Check if sorting is applied on BLOB type # ########################################### --echo Testing type BLOB # Setting global value of variable and inserting data in table -SET @@global.max_sort_length = 30; -SELECT @@global.max_sort_length; -INSERT INTO t1 set c = repeat('x',29); -INSERT INTO t1 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t1 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t1 set c = concat(repeat('x',28),'g','w'); -SELECT c from t1 ORDER BY c, id; +SET @@max_sort_length = 70; +SELECT @@max_sort_length; +INSERT INTO t1 set c = repeat('x',69); +INSERT INTO t1 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t1 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t1 set c = concat(repeat('x',68),'g','w'); +SELECT c from t1 ORDER BY c, id DESC; --echo ** Results should be sorted ** # Setting session value of variable and inserting data in table -SET @@session.max_sort_length = 20; +SET @@session.max_sort_length = 64; SELECT @@session.max_sort_length; -INSERT INTO t1 set c = repeat('x',29); -INSERT INTO t1 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t1 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t1 set c = concat(repeat('x',28),'g','w'); +INSERT INTO t1 set c = repeat('x',69); +INSERT INTO t1 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t1 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t1 set c = concat(repeat('x',68),'g','w'); SELECT c from t1 ORDER BY c, id; --echo ** Results should not be sorted ** @@ -210,26 +176,25 @@ SELECT c from t1 ORDER BY c, id; ########################################### --echo Testing type CHAR # Setting global value of variable and inserting data in table -SET @@global.max_sort_length = 30; +SET @@global.max_sort_length = 70; SELECT @@global.max_sort_length; -INSERT INTO t2 set c = repeat('x',29); -INSERT INTO t2 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t2 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t2 set c = concat(repeat('x',28),'g','w'); +INSERT INTO t2 set c = repeat('x',69); +INSERT INTO t2 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t2 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t2 set c = concat(repeat('x',68),'g','w'); SELECT c from t2 ORDER BY c, id; --echo ** Results should not be sorted ** # Setting session value of variable and inserting data in table -SET @@session.max_sort_length = 20; +SET @@session.max_sort_length = 64; SELECT @@session.max_sort_length; -INSERT INTO t2 set c = repeat('x',29); -INSERT INTO t2 set c = concat(repeat('x',28),'r','x'); -INSERT INTO t2 set c = concat(repeat('x',28),'s','y'); -INSERT INTO t2 set c = concat(repeat('x',28),'g','w'); +INSERT INTO t2 set c = repeat('x',69); +INSERT INTO t2 set c = concat(repeat('x',68),'r','x'); +INSERT INTO t2 set c = concat(repeat('x',68),'s','y'); +INSERT INTO t2 set c = concat(repeat('x',68),'g','w'); SELECT c from t2 ORDER BY c, id; --echo ** Results should not be sorted ** - # # Cleanup # @@ -239,12 +204,6 @@ connection default; disconnect test_con1; disconnect test_con2; -SET @@SESSION.max_sort_length = @session_max_sort_length; - ---disable_warnings -DROP TABLE IF EXISTS t; -DROP TABLE IF EXISTS t1; -DROP TABLE IF EXISTS t2; ---enable_warnings +DROP TABLE t, t1, t2; SET @@global.max_sort_length= @start_value; diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test index 532729dafde..8fbbee872ce 100644 --- a/mysql-test/t/ctype_utf8mb4.test +++ b/mysql-test/t/ctype_utf8mb4.test @@ -1520,7 +1520,7 @@ drop table t1; --echo # --echo # Check strnxfrm() with odd length --echo # -set max_sort_length=9; +set max_sort_length=65; select @@max_sort_length; create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci); insert into t1 values ('a'),('b'),('c'); diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index e9802f95721..36c25ed37fb 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -531,11 +531,11 @@ drop table t1, t2; # Bug #5428: a problem with small max_sort_length value # -create table t1 (a char(25)); +create table t1 (a char(70)); insert into t1 set a = repeat('x', 20); -insert into t1 set a = concat(repeat('x', 19), 'z'); -insert into t1 set a = concat(repeat('x', 19), 'ab'); -insert into t1 set a = concat(repeat('x', 19), 'aa'); +insert into t1 set a = concat(repeat('x', 63), 'z'); +insert into t1 set a = concat(repeat('x', 63), 'ab'); +insert into t1 set a = concat(repeat('x', 63), 'aa'); set max_sort_length=20; select a from t1 order by a; drop table t1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 7235c6af3b3..d518d7a3956 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -606,15 +606,15 @@ set character_set_results=default; # # max_sort_length set GLOBAL query_cache_size=1355776; -create table t1 (id int auto_increment primary key, c char(25)); +create table t1 (id int auto_increment primary key, c char(65)); insert into t1 set c = repeat('x',24); -insert into t1 set c = concat(repeat('x',24),'x'); -insert into t1 set c = concat(repeat('x',24),'w'); -insert into t1 set c = concat(repeat('x',24),'y'); +insert into t1 set c = concat(repeat('x',64),'x'); +insert into t1 set c = concat(repeat('x',64),'w'); +insert into t1 set c = concat(repeat('x',64),'y'); set max_sort_length=200; select c from t1 order by c, id; reset query cache; -set max_sort_length=20; +set max_sort_length=64; select c from t1 order by c, id; set max_sort_length=200; select c from t1 order by c, id; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 7b74689a7f0..e1252acefcc 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2224,7 +2224,7 @@ static Sys_var_ulong Sys_max_sort_length( "the first max_sort_length bytes of each value are used; the rest " "are ignored)", SESSION_VAR(max_sort_length), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(8, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1)); + VALID_RANGE(64, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1)); static Sys_var_ulong Sys_max_sp_recursion_depth( "max_sp_recursion_depth", From 589479b3ecd3ed4df5d03a844173830a30f70d83 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 10 Nov 2020 20:30:50 +0100 Subject: [PATCH 18/72] MDEV-14836 Assertion `m_status == DA_ERROR' failed in Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED Make the test case more robust. We only care that the query returns no rows and that the server doesn't crash. --- mysql-test/r/information_schema.result | 2 +- mysql-test/t/information_schema.test | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index dc772eecc62..db416f983e3 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -2194,7 +2194,7 @@ SCHEMA_NAME SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT IS_GENERATED GENERATION_EXPRESSION Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 666 rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete +Warning 1931 Query execution was interrupted. The query examined at least ### rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete # # End of 10.2 Test # diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index df00ff26908..cd30c2103a0 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1914,6 +1914,7 @@ SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a' --echo # Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED --echo # +replace_regex /at least \d+ rows/at least ### rows/; SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; --echo # From ba33d4753e7be37f35e15f6b44b934e9a3720b4c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 11 Nov 2020 12:19:20 +0100 Subject: [PATCH 19/72] cleanup: type_year test formatting --- mysql-test/r/type_year.result | 17 +++++++++++------ mysql-test/t/type_year.test | 27 ++++++++++++--------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 99c3c50ea8c..65d6d72f25b 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -1,4 +1,3 @@ -drop table if exists t1; create table t1 (y year,y2 year(2)); Warnings: Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead @@ -28,6 +27,9 @@ y y2 2001 01 2069 69 drop table t1; +# +# Bug 2335 +# create table t1 (y year); insert ignore into t1 values (now()); Warnings: @@ -36,6 +38,9 @@ select if(y = now(), 1, 0) from t1; if(y = now(), 1, 0) 1 drop table t1; +# +# Bug #27176: Assigning a string to an year column has unexpected results +# create table t1(a year); insert into t1 values (2000.5), ('2000.5'), ('2001a'), ('2.001E3'); Warnings: @@ -47,7 +52,9 @@ a 2001 2001 drop table t1; -End of 5.0 tests +# +# End of 5.0 tests +# # # Bug #49480: WHERE using YEAR columns returns unexpected results # @@ -373,7 +380,8 @@ Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Pleas Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead DROP TABLE t1; # -End of 5.1 tests +# End of 5.1 tests +# create function y2k() returns int deterministic return 2000; create table t1 (a year(2), b int); Warnings: @@ -456,9 +464,6 @@ DROP TABLE t1; # End of 10.1 tests # # -# Start of 10.2 tests -# -# # MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings # CREATE TABLE t1 (a YEAR); diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index af26a69c581..ba77f8f5a62 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -1,9 +1,6 @@ # # Test year # ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (y year,y2 year(2)); insert into t1 values (0,0),(1999,1999),(2000,2000),(2001,2001),(70,70),(69,69); @@ -12,24 +9,27 @@ select * from t1 order by y; select * from t1 order by y2; drop table t1; -# -# Bug 2335 -# +--echo # +--echo # Bug 2335 +--echo # create table t1 (y year); insert ignore into t1 values (now()); select if(y = now(), 1, 0) from t1; drop table t1; -# -# Bug #27176: Assigning a string to an year column has unexpected results -# +--echo # +--echo # Bug #27176: Assigning a string to an year column has unexpected results +--echo # + create table t1(a year); insert into t1 values (2000.5), ('2000.5'), ('2001a'), ('2.001E3'); select * from t1; drop table t1; ---echo End of 5.0 tests +--echo # +--echo # End of 5.0 tests +--echo # --echo # --echo # Bug #49480: WHERE using YEAR columns returns unexpected results @@ -168,9 +168,10 @@ CREATE TABLE t1 (c1 YEAR(2), c2 YEAR(4)); ALTER TABLE t1 MODIFY COLUMN c2 YEAR(2); DROP TABLE t1; +--echo # +--echo # End of 5.1 tests --echo # ---echo End of 5.1 tests # # fun with convert_const_to_int # in some cases 00 is equal to 2000, in others it is not. @@ -229,10 +230,6 @@ DROP TABLE t1; --echo # End of 10.1 tests --echo # ---echo # ---echo # Start of 10.2 tests ---echo # - --echo # --echo # MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings --echo # From aeb561cf3e87539ba76b631b493e211f8c71f7f8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 11 Nov 2020 12:30:17 +0100 Subject: [PATCH 20/72] tests for YEAR(N) --- mysql-test/r/type_year.result | 58 +++++++++++++++++++++++++++++++++++ mysql-test/t/type_year.test | 11 +++++++ 2 files changed, 69 insertions(+) diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 65d6d72f25b..75876d2efad 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -505,5 +505,63 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 DROP TABLE t1; # +# Various widths of the YEAR +# +create or replace table t1 (a YEAR(0)); +Warnings: +Note 1287 'YEAR(0)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create or replace table t1 (a YEAR(1)); +Warnings: +Note 1287 'YEAR(1)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create or replace table t1 (a YEAR(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create or replace table t1 (a YEAR(3)); +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create or replace table t1 (a YEAR(4)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create or replace table t1 (a YEAR(5)); +Warnings: +Note 1287 'YEAR(5)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create or replace table t1 (a YEAR(100)); +Warnings: +Note 1287 'YEAR(100)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index ba77f8f5a62..34c417d9026 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -265,6 +265,17 @@ SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR ALTER TABLE t1 MODIFY a YEAR; DROP TABLE t1; +--echo # +--echo # Various widths of the YEAR +--echo # +create or replace table t1 (a YEAR(0)); SHOW CREATE TABLE t1; +create or replace table t1 (a YEAR(1)); SHOW CREATE TABLE t1; +create or replace table t1 (a YEAR(2)); SHOW CREATE TABLE t1; +create or replace table t1 (a YEAR(3)); SHOW CREATE TABLE t1; +create or replace table t1 (a YEAR(4)); SHOW CREATE TABLE t1; +create or replace table t1 (a YEAR(5)); SHOW CREATE TABLE t1; +create or replace table t1 (a YEAR(100)); SHOW CREATE TABLE t1; +drop table t1; --echo # --echo # End of 10.2 tests From e189faf0b3f28465a7bfb8dbb87958cb64a38be6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 11 Nov 2020 13:23:39 +0100 Subject: [PATCH 21/72] document that a fulltext parser plugin can replace mysql_add_word callback --- include/mysql/plugin_ftparser.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/mysql/plugin_ftparser.h b/include/mysql/plugin_ftparser.h index 99bb6b24f3f..8db8712926f 100644 --- a/include/mysql/plugin_ftparser.h +++ b/include/mysql/plugin_ftparser.h @@ -158,7 +158,9 @@ typedef struct st_mysql_ftparser_boolean_info the word to MySQL full-text index. When parsing a search query, this function will add the new word to the list of words to search for. The boolean_info argument can be NULL for all cases except - when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO. + when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO. A plugin can replace this + callback to post-process every parsed word before passing it to the original + mysql_add_word function. ftparser_state: A generic pointer. The plugin can set it to point to information to be used internally for its own purposes. From f6e91552f00daf7f87bffd3a64082dc5673af95c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 11 Nov 2020 15:51:18 +0100 Subject: [PATCH 22/72] MDEV-4677 GROUP_CONCAT not showing any output with group_concat_max_len >= 4Gb don't allow group_concat_max_len values >= 4Gb (they never worked anyway) --- mysql-test/r/func_gconcat.result | 12 ++++++++++++ .../sys_vars/r/sysvars_server_embedded.result | 4 ++-- .../sys_vars/r/sysvars_server_notembedded.result | 4 ++-- mysql-test/t/func_gconcat.test | 10 ++++++++++ sql/field.cc | 2 +- sql/item_sum.cc | 14 +++++++------- sql/sql_cache.cc | 4 ++-- sql/sql_cache.h | 2 +- sql/sql_class.h | 3 ++- sql/sys_vars.cc | 4 ++-- 10 files changed, 41 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 992f935b14e..da33e7bbc2c 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -1280,5 +1280,17 @@ Name_exp_1 DROP VIEW v1; DROP TABLE t1; # +# MDEV-4677 GROUP_CONCAT not showing any output with group_concat_max_len >= 4Gb +# +set group_concat_max_len=1024*1024*1024*4; +Warnings: +Warning 1292 Truncated incorrect group_concat_max_len value: '4294967296' +create table t1 (i int, j int); +insert into t1 values (1,1),(1,2); +select i, group_concat(j) from t1 group by i; +i group_concat(j) +1 1,2 +drop table t1; +# # End of 10.2 tests # diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 06886ff05c4..5ccabeecf2d 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -944,10 +944,10 @@ READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME GROUP_CONCAT_MAX_LEN VARIABLE_SCOPE SESSION -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED VARIABLE_COMMENT The maximum length of the result of function GROUP_CONCAT() NUMERIC_MIN_VALUE 4 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 4808997a87a..42c236bf54a 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -964,10 +964,10 @@ READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME GROUP_CONCAT_MAX_LEN VARIABLE_SCOPE SESSION -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED VARIABLE_COMMENT The maximum length of the result of function GROUP_CONCAT() NUMERIC_MIN_VALUE 4 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e752d9fcd50..b699d39e953 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -939,6 +939,16 @@ DROP VIEW v1; DROP TABLE t1; + +--echo # +--echo # MDEV-4677 GROUP_CONCAT not showing any output with group_concat_max_len >= 4Gb +--echo # +set group_concat_max_len=1024*1024*1024*4; +create table t1 (i int, j int); +insert into t1 values (1,1),(1,2); +select i, group_concat(j) from t1 group by i; +drop table t1; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/field.cc b/sql/field.cc index fbce8b9041d..9ea1eac9db9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8255,7 +8255,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) DBUG_ASSERT(length <= max_data_length()); new_length= length; - copy_length= (uint)MY_MIN(UINT_MAX,table->in_use->variables.group_concat_max_len); + copy_length= table->in_use->variables.group_concat_max_len; if (new_length > copy_length) { new_length= Well_formed_prefix(cs, diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 9490c71c19e..dd65f04a652 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3171,7 +3171,7 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), { Item_func_group_concat *item= (Item_func_group_concat *) item_arg; TABLE *table= item->table; - uint max_length= (uint)table->in_use->variables.group_concat_max_len; + uint max_length= table->in_use->variables.group_concat_max_len; String tmp((char *)table->record[1], table->s->reclength, default_charset_info); String tmp2; @@ -3499,7 +3499,7 @@ bool Item_func_group_concat::repack_tree(THD *thd) DBUG_ASSERT(tree->size_of_element == st.tree.size_of_element); st.table= table; st.len= 0; - st.maxlen= (size_t)thd->variables.group_concat_max_len; + st.maxlen= thd->variables.group_concat_max_len; tree_walk(tree, ©_to_tree, &st, left_root_right); if (st.len <= st.maxlen) // Copying aborted. Must be OOM { @@ -3520,7 +3520,7 @@ bool Item_func_group_concat::repack_tree(THD *thd) decreases up to N=10 (that is, factor=1024) and then starts to increase, again, very slowly. */ -#define GCONCAT_REPACK_FACTOR (1 << 10) +#define GCONCAT_REPACK_FACTOR 10 bool Item_func_group_concat::add() { @@ -3566,7 +3566,7 @@ bool Item_func_group_concat::add() { THD *thd= table->in_use; table->field[0]->store(row_str_len, FALSE); - if (tree_len > thd->variables.group_concat_max_len * GCONCAT_REPACK_FACTOR + if ((tree_len >> GCONCAT_REPACK_FACTOR) > thd->variables.group_concat_max_len && tree->elements_in_tree > 1) if (repack_tree(thd)) return 1; @@ -3624,9 +3624,9 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) result.set_charset(collation.collation); result_field= 0; null_value= 1; - max_length= (uint32)(thd->variables.group_concat_max_len - / collation.collation->mbminlen - * collation.collation->mbmaxlen); + max_length= (uint32)MY_MIN(thd->variables.group_concat_max_len + / collation.collation->mbminlen + * collation.collation->mbmaxlen, UINT_MAX32); uint32 offset; if (separator->needs_conversion(separator->length(), separator->charset(), diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8555ae6ee3e..0de153a5e7d 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1451,7 +1451,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) DBUG_PRINT("qcache", ("\ long %d, 4.1: %d, eof: %d, bin_proto: %d, more results %d, pkt_nr: %d, \ CS client: %u, CS result: %u, CS conn: %u, limit: %llu, TZ: %p, \ -sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %lu, \ +sql mode: 0x%llx, sort len: %llu, concat len: %u, div_precision: %lu, \ def_week_frmt: %lu, in_trans: %d, autocommit: %d", (int)flags.client_long_flag, (int)flags.client_protocol_41, @@ -1951,7 +1951,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) DBUG_PRINT("qcache", ("\ long %d, 4.1: %d, eof: %d, bin_proto: %d, more results %d, pkt_nr: %d, \ CS client: %u, CS result: %u, CS conn: %u, limit: %llu, TZ: %p, \ -sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %lu, \ +sql mode: 0x%llx, sort len: %llu, concat len: %u, div_precision: %lu, \ def_week_frmt: %lu, in_trans: %d, autocommit: %d", (int)flags.client_long_flag, (int)flags.client_protocol_41, diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 6ad73bbb0a2..d428c7fdb80 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -554,11 +554,11 @@ struct Query_cache_query_flags uint character_set_client_num; uint character_set_results_num; uint collation_connection_num; + uint group_concat_max_len; ha_rows limit; Time_zone *time_zone; sql_mode_t sql_mode; ulonglong max_sort_length; - ulonglong group_concat_max_len; ulong default_week_format; ulong div_precision_increment; MY_LOCALE *lc_time_names; diff --git a/sql/sql_class.h b/sql/sql_class.h index d2b0b40846b..35068245830 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -555,7 +555,6 @@ typedef struct system_variables ulonglong bulk_insert_buff_size; ulonglong join_buff_size; ulonglong sortbuff_size; - ulonglong group_concat_max_len; ulonglong default_regex_flags; ulonglong max_mem_used; @@ -645,6 +644,8 @@ typedef struct system_variables uint32 gtid_domain_id; uint64 gtid_seq_no; + uint group_concat_max_len; + /** Default transaction access mode. READ ONLY (true) or READ WRITE (false). */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e1252acefcc..baf27a7d0af 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4157,11 +4157,11 @@ static Sys_var_ulong Sys_default_week_format( SESSION_VAR(default_week_format), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 7), DEFAULT(0), BLOCK_SIZE(1)); -static Sys_var_ulonglong Sys_group_concat_max_len( +static Sys_var_uint Sys_group_concat_max_len( "group_concat_max_len", "The maximum length of the result of function GROUP_CONCAT()", SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(4, SIZE_T_MAX), DEFAULT(1024*1024), BLOCK_SIZE(1)); + VALID_RANGE(4, UINT_MAX32), DEFAULT(1024*1024), BLOCK_SIZE(1)); static char *glob_hostname_ptr; static Sys_var_charptr Sys_hostname( From 493c7d34cb2c5c0bc8c495d1dd7b2394c62036ad Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 23 Nov 2020 14:10:44 +0100 Subject: [PATCH 23/72] MDEV-24194 View definition corruption fix parsing of "1 IS NULL = 2" --- mysql-test/r/precedence.result | 4 ++++ mysql-test/t/precedence.test | 3 +++ sql/sql_yacc.yy | 16 ++++++---------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/precedence.result b/mysql-test/r/precedence.result index 986af631346..65c32ba2b04 100644 --- a/mysql-test/r/precedence.result +++ b/mysql-test/r/precedence.result @@ -8017,4 +8017,8 @@ create or replace view v1 as select 1 IS TRUE IS FALSE, 2 IS FALSE IS UNKNOWN, 3 Select view_definition from information_schema.views where table_schema='test' and table_name='v1'; view_definition select 1 is true is false AS `1 IS TRUE IS FALSE`,/*always not null*/ 1 is null AS `2 IS FALSE IS UNKNOWN`,/*always not null*/ 1 is null AS `3 IS UNKNOWN IS NULL`,/*always not null*/ 1 is null is true AS `4 IS NULL IS TRUE` +create or replace view v1 as select 2 IS TRUE = 3, 2 IS FALSE = 3, 2 IS UNKNOWN = 3, 2 IS NULL = 3, ISNULL(2) = 1; +Select view_definition from information_schema.views where table_schema='test' and table_name='v1'; +view_definition +select 2 is true = 3 AS `2 IS TRUE = 3`,2 is false = 3 AS `2 IS FALSE = 3`,/*always not null*/ 1 is null = 3 AS `2 IS UNKNOWN = 3`,/*always not null*/ 1 is null = 3 AS `2 IS NULL = 3`,/*always not null*/ 1 is null = 1 AS `ISNULL(2) = 1` drop view v1; diff --git a/mysql-test/t/precedence.test b/mysql-test/t/precedence.test index ad367c23603..cd7cee4f911 100644 --- a/mysql-test/t/precedence.test +++ b/mysql-test/t/precedence.test @@ -4785,4 +4785,7 @@ Select view_definition from information_schema.views where table_schema='test' a create or replace view v1 as select 1 IS TRUE IS FALSE, 2 IS FALSE IS UNKNOWN, 3 IS UNKNOWN IS NULL, 4 IS NULL IS TRUE; Select view_definition from information_schema.views where table_schema='test' and table_name='v1'; +create or replace view v1 as select 2 IS TRUE = 3, 2 IS FALSE = 3, 2 IS UNKNOWN = 3, 2 IS NULL = 3, ISNULL(2) = 1; +Select view_definition from information_schema.views where table_schema='test' and table_name='v1'; + drop view v1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2eabc4f0a6d..1f37296842c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1030,10 +1030,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 105 shift/reduce conflicts. + Currently there are 98 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 105 +%expect 98 /* Comments for TOKENS. @@ -1836,7 +1836,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type literal text_literal insert_ident order_ident temporal_literal simple_ident expr opt_expr opt_else sum_expr in_sum_expr - variable variable_aux bool_pri + variable variable_aux predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr expr_or_default set_expr_or_default @@ -8972,23 +8972,19 @@ expr: if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri - ; - -bool_pri: - bool_pri EQUAL_SYM predicate %prec EQUAL_SYM + | expr EQUAL_SYM predicate %prec EQUAL_SYM { $$= new (thd->mem_root) Item_func_equal(thd, $1, $3); if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri comp_op predicate %prec '=' + | expr comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri comp_op all_or_any '(' subselect ')' %prec '=' + | expr comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); if ($$ == NULL) From 79fd338e6ca6df8d4c8cf3f326fc6ae0a256bdd2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 10 Dec 2020 09:19:03 +0100 Subject: [PATCH 24/72] MDEV-23942 mariadb-10.5.6/storage/connect/plugutil.cpp:380: bad width ? cppcheck warnings --- storage/connect/plugutil.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index 0ab594f5533..baeac32066b 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -378,9 +378,9 @@ char *PlugReadMessage(PGLOBAL g, int mid, char *m) if (atoi(buff) == mid) break; - if (sscanf(buff, " %*d %s \"%[^\"]", msgid, stmsg) < 2) { + if (sscanf(buff, " %*d %.31s \"%.255[^\"]", msgid, stmsg) < 2) { // Old message file - if (!sscanf(buff, " %*d \"%[^\"]", stmsg)) { + if (!sscanf(buff, " %*d \"%.255[^\"]", stmsg)) { sprintf(stmsg, "Bad message file for %d %s", mid, SVP(m)); goto fin; } else From 0adbf27f00e19801a8e244292000e85e6889b9aa Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 11 Dec 2020 17:33:44 +0300 Subject: [PATCH 25/72] Run innodb.innodb_stats test with EITS disabled. - There is no reason to collect EITS statistics - The test is sporadically failing on some platforms. I believe the issue is in InnoDB. Let's rule out EITS code as a possible source of the issue. --- mysql-test/suite/innodb/r/innodb_stats.result | 10 ---------- mysql-test/suite/innodb/t/innodb_stats.test | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_stats.result b/mysql-test/suite/innodb/r/innodb_stats.result index eadce75318b..d2c3bd0127e 100644 --- a/mysql-test/suite/innodb/r/innodb_stats.result +++ b/mysql-test/suite/innodb/r/innodb_stats.result @@ -4,7 +4,6 @@ dummy INSERT, the table should be empty dummy INSERT, the table should be empty ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -57,7 +56,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -110,7 +108,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (1); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -163,7 +160,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (1), (1); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -216,7 +212,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -269,7 +264,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (2); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -322,7 +316,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (1), (2); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -375,7 +368,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (2), (3); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -428,7 +420,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (1), (2), (3), (3); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, @@ -481,7 +472,6 @@ TRUNCATE TABLE test_innodb_stats; INSERT INTO test_innodb_stats (a) VALUES (1), (2), (3), (4), (5), (1), (2), (3), (4), (5); ANALYZE TABLE test_innodb_stats; Table Op Msg_type Msg_text -test.test_innodb_stats analyze status Engine-independent statistics collected test.test_innodb_stats analyze status OK SELECT stat_name, diff --git a/mysql-test/suite/innodb/t/innodb_stats.test b/mysql-test/suite/innodb/t/innodb_stats.test index 09515ec9720..1a962e3568e 100644 --- a/mysql-test/suite/innodb/t/innodb_stats.test +++ b/mysql-test/suite/innodb/t/innodb_stats.test @@ -10,7 +10,7 @@ DROP TABLE IF EXISTS test_innodb_stats; set @save_use_stat_tables= @@use_stat_tables; -set @@use_stat_tables= COMPLEMENTARY; +set @@use_stat_tables= NEVER; CREATE TABLE test_innodb_stats ( a INT, From 4addd31531f722438b8b702c9cd00c28b61efce3 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 11 Dec 2020 18:54:21 +0300 Subject: [PATCH 26/72] MDEV-21958: Query having many NOT-IN clauses running forever Basic variant of the fix: do not consider conditions in form unique_key NOT IN (c1,c2...) to be sargable. If there are only a few constants, the condition is not selective. If there are a lot constants, the overhead of processing such a huge range list is not worth it. --- mysql-test/main/range.result | 30 ++++++++++++++++++++++++++++ mysql-test/main/range.test | 24 ++++++++++++++++++++++ mysql-test/main/range_mrr_icp.result | 30 ++++++++++++++++++++++++++++ sql/opt_range.cc | 24 ++++++++++++++++++++++ 4 files changed, 108 insertions(+) diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index c10ddf9d9fd..132ca019a61 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -3241,6 +3241,36 @@ analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE t1 index a a 5 NULL 2000 2000.00 10.05 60.05 Using where; Using index drop table t1,ten,t2; +# +# MDEV-21958: Query having many NOT-IN clauses running forever +# +create table t2 ( +pk int primary key, +key1 int, +col1 int, +key (key1, pk) +); +insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); +set @tmp_21958=@@optimizer_trace; +set optimizer_trace=1; +explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY,key1 NULL NULL NULL 5 Using where +# This should show only ranges in form "(1) <= (key1) <= (1)" +# ranges over "pk" should not be constructed. +select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +from information_schema.optimizer_trace; +json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +[ + + [ + "(1) <= (key1) <= (1)", + "(2) <= (key1) <= (2)", + "(3) <= (key1) <= (3)" + ] +] +set optimizer_trace=@tmp_21958; +drop table t2; # End of 10.4 tests set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index 65f580698c5..fab6c8530c2 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -2207,6 +2207,30 @@ let $a= `select group_concat(a) from t2`; eval analyze SELECT * FROM t1 where a in ($a); drop table t1,ten,t2; +--echo # +--echo # MDEV-21958: Query having many NOT-IN clauses running forever +--echo # +create table t2 ( + pk int primary key, + key1 int, + col1 int, + key (key1, pk) +); + +insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); + +set @tmp_21958=@@optimizer_trace; +set optimizer_trace=1; +explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); + +--echo # This should show only ranges in form "(1) <= (key1) <= (1)" +--echo # ranges over "pk" should not be constructed. +select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +from information_schema.optimizer_trace; +set optimizer_trace=@tmp_21958; + +drop table t2; + --echo # End of 10.4 tests set global innodb_stats_persistent= @innodb_stats_persistent_save; diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index 826ac621064..ebefc21a58d 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -3238,6 +3238,36 @@ analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE t1 index a a 5 NULL 2000 2000.00 10.05 60.05 Using where; Using index drop table t1,ten,t2; +# +# MDEV-21958: Query having many NOT-IN clauses running forever +# +create table t2 ( +pk int primary key, +key1 int, +col1 int, +key (key1, pk) +); +insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); +set @tmp_21958=@@optimizer_trace; +set optimizer_trace=1; +explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY,key1 NULL NULL NULL 5 Using where +# This should show only ranges in form "(1) <= (key1) <= (1)" +# ranges over "pk" should not be constructed. +select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +from information_schema.optimizer_trace; +json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +[ + + [ + "(1) <= (key1) <= (1)", + "(2) <= (key1) <= (2)", + "(3) <= (key1) <= (3)" + ] +] +set optimizer_trace=@tmp_21958; +drop table t2; # End of 10.4 tests set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 043a1e70f61..1a7ac1044c3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7787,6 +7787,30 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, if (array->count > NOT_IN_IGNORE_THRESHOLD || !value_item) DBUG_RETURN(0); + /* + If this is "unique_key NOT IN (...)", do not consider it sargable (for + any index, not just the unique one). The logic is as follows: + - if there are only a few constants, this condition is not selective + (unless the table is also very small in which case we won't gain + anything) + - If there are a lot of constants, the overhead of building and + processing enormous range list is not worth it. + */ + if (param->using_real_indexes) + { + key_map::Iterator it(field->key_start); + uint key_no; + while ((key_no= it.next_bit()) != key_map::Iterator::BITMAP_END) + { + KEY *key_info= ¶m->table->key_info[key_no]; + if (key_info->user_defined_key_parts == 1 && + (key_info->flags & HA_NOSAME)) + { + DBUG_RETURN(0); + } + } + } + /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */ uint i=0; do From 4fa44c584cf14c72fdbb15b88d406fd4e9e42c18 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 11 Dec 2020 19:35:38 +0100 Subject: [PATCH 27/72] MDEV-24331 mysqldump fails with "Got error: 1356" if the database contains a view with a subquery detect derived tables differently. TABLE_LIST::is_derived() only works after mysql_derived_init() --- mysql-test/r/lock_view.result | 34 ++++++++++++++++++++++++++++++++++ mysql-test/t/lock_view.test | 17 +++++++++++++++++ sql/sql_parse.cc | 2 +- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/lock_view.result b/mysql-test/r/lock_view.result index 4d375bace42..364c2cddf60 100644 --- a/mysql-test/r/lock_view.result +++ b/mysql-test/r/lock_view.result @@ -229,3 +229,37 @@ drop user definer@localhost; drop database mysqltest1; drop database mysqltest2; drop database mysqltest3; +# +# MDEV-24331 mysqldump fails with "Got error: 1356" if the database contains a view with a subquery +# +create user u1@localhost; +grant all privileges on test.* to u1@localhost; +connect con1,localhost,u1; +use test; +create table t1 (id int not null); +create view v1 as select * from (select * from t1) dt; +lock table v1 read; +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 */; +SET character_set_client = @saved_cs_client; +/*!50001 DROP TABLE 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 */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`u1`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v1` AS select `dt`.`id` AS `id` from (select `test`.`t1`.`id` AS `id` from `test`.`t1`) `dt` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +drop view v1; +drop table t1; +drop user u1@localhost; diff --git a/mysql-test/t/lock_view.test b/mysql-test/t/lock_view.test index 4b1adac5be1..abb8d317946 100644 --- a/mysql-test/t/lock_view.test +++ b/mysql-test/t/lock_view.test @@ -75,3 +75,20 @@ drop user definer@localhost; drop database mysqltest1; drop database mysqltest2; drop database mysqltest3; + +--echo # +--echo # MDEV-24331 mysqldump fails with "Got error: 1356" if the database contains a view with a subquery +--echo # +create user u1@localhost; +grant all privileges on test.* to u1@localhost; +connect con1,localhost,u1; +use test; +create table t1 (id int not null); +create view v1 as select * from (select * from t1) dt; +lock table v1 read; +disconnect con1; +connection default; +exec $MYSQL_DUMP test v1 -uu1 --compact; +drop view v1; +drop table t1; +drop user u1@localhost; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6e1d36b79a4..54937116383 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6639,7 +6639,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool check_single_table_access(THD *thd, ulong privilege, TABLE_LIST *tables, bool no_errors) { - if (tables->is_derived()) + if (tables->derived) return 0; Switch_to_definer_security_ctx backup_sctx(thd, tables); From 121582647ce999a5418cf705646744f2f7fe4065 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 11 Dec 2020 20:35:25 +0100 Subject: [PATCH 28/72] MDEV-24279 Segfault after 1 day and 5 minutes uptime feedback plugin now fakes a SHOW command to force create_schema_table() to instantiate the table at once, not lazily. The test from plugins.feedback_plugin_send applies. Caused by e64084d5a3a7 --- plugin/feedback/sender_thread.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 8e2e9dd5ed6..943443f60fe 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -117,6 +117,7 @@ static int prepare_for_fill(TABLE_LIST *tables) tables->init_one_table(&INFORMATION_SCHEMA_NAME, &tbl_name, 0, TL_READ); tables->schema_table= i_s_feedback; + tables->schema_table_reformed= 1; tables->table= create_schema_table(thd, tables); if (!tables->table) return 1; From 502bc77f23715f84a049fe6c28a861e9af271016 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 11 Dec 2020 22:44:13 +0300 Subject: [PATCH 29/72] MDEV-21958: Query having many NOT-IN clauses running forever, part 2 Move the testcase into a separate file: embedded server doesn't have optimizer trace. --- mysql-test/main/range.result | 30 ---------------------------- mysql-test/main/range.test | 24 ---------------------- mysql-test/main/range_mrr_icp.result | 30 ---------------------------- 3 files changed, 84 deletions(-) diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 132ca019a61..c10ddf9d9fd 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -3241,36 +3241,6 @@ analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE t1 index a a 5 NULL 2000 2000.00 10.05 60.05 Using where; Using index drop table t1,ten,t2; -# -# MDEV-21958: Query having many NOT-IN clauses running forever -# -create table t2 ( -pk int primary key, -key1 int, -col1 int, -key (key1, pk) -); -insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); -set @tmp_21958=@@optimizer_trace; -set optimizer_trace=1; -explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL PRIMARY,key1 NULL NULL NULL 5 Using where -# This should show only ranges in form "(1) <= (key1) <= (1)" -# ranges over "pk" should not be constructed. -select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) -from information_schema.optimizer_trace; -json_detailed(JSON_EXTRACT(trace, '$**.ranges')) -[ - - [ - "(1) <= (key1) <= (1)", - "(2) <= (key1) <= (2)", - "(3) <= (key1) <= (3)" - ] -] -set optimizer_trace=@tmp_21958; -drop table t2; # End of 10.4 tests set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index fab6c8530c2..65f580698c5 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -2207,30 +2207,6 @@ let $a= `select group_concat(a) from t2`; eval analyze SELECT * FROM t1 where a in ($a); drop table t1,ten,t2; ---echo # ---echo # MDEV-21958: Query having many NOT-IN clauses running forever ---echo # -create table t2 ( - pk int primary key, - key1 int, - col1 int, - key (key1, pk) -); - -insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); - -set @tmp_21958=@@optimizer_trace; -set optimizer_trace=1; -explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); - ---echo # This should show only ranges in form "(1) <= (key1) <= (1)" ---echo # ranges over "pk" should not be constructed. -select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) -from information_schema.optimizer_trace; -set optimizer_trace=@tmp_21958; - -drop table t2; - --echo # End of 10.4 tests set global innodb_stats_persistent= @innodb_stats_persistent_save; diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index ebefc21a58d..826ac621064 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -3238,36 +3238,6 @@ analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE t1 index a a 5 NULL 2000 2000.00 10.05 60.05 Using where; Using index drop table t1,ten,t2; -# -# MDEV-21958: Query having many NOT-IN clauses running forever -# -create table t2 ( -pk int primary key, -key1 int, -col1 int, -key (key1, pk) -); -insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); -set @tmp_21958=@@optimizer_trace; -set optimizer_trace=1; -explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL PRIMARY,key1 NULL NULL NULL 5 Using where -# This should show only ranges in form "(1) <= (key1) <= (1)" -# ranges over "pk" should not be constructed. -select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) -from information_schema.optimizer_trace; -json_detailed(JSON_EXTRACT(trace, '$**.ranges')) -[ - - [ - "(1) <= (key1) <= (1)", - "(2) <= (key1) <= (2)", - "(3) <= (key1) <= (3)" - ] -] -set optimizer_trace=@tmp_21958; -drop table t2; # End of 10.4 tests set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= From dcc7f93965f7fb534f29c5c682b2abf22e808fe2 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 11 Dec 2020 22:45:54 +0300 Subject: [PATCH 30/72] MDEV-21958: Query having many NOT-IN clauses running forever, part 3 Add the new file --- mysql-test/main/range_notembedded.result | 31 ++++++++++++++++++++++ mysql-test/main/range_notembedded.test | 33 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 mysql-test/main/range_notembedded.result create mode 100644 mysql-test/main/range_notembedded.test diff --git a/mysql-test/main/range_notembedded.result b/mysql-test/main/range_notembedded.result new file mode 100644 index 00000000000..7084e0ca7a0 --- /dev/null +++ b/mysql-test/main/range_notembedded.result @@ -0,0 +1,31 @@ +drop table if exists t1,t2; +# +# MDEV-21958: Query having many NOT-IN clauses running forever +# +create table t2 ( +pk int primary key, +key1 int, +col1 int, +key (key1, pk) +); +insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); +set @tmp_21958=@@optimizer_trace; +set optimizer_trace=1; +explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY,key1 NULL NULL NULL 5 Using where +# This should show only ranges in form "(1) <= (key1) <= (1)" +# ranges over "pk" should not be constructed. +select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +from information_schema.optimizer_trace; +json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +[ + + [ + "(1) <= (key1) <= (1)", + "(2) <= (key1) <= (2)", + "(3) <= (key1) <= (3)" + ] +] +set optimizer_trace=@tmp_21958; +drop table t2; diff --git a/mysql-test/main/range_notembedded.test b/mysql-test/main/range_notembedded.test new file mode 100644 index 00000000000..4dc49429ff1 --- /dev/null +++ b/mysql-test/main/range_notembedded.test @@ -0,0 +1,33 @@ +# +# Range tests without embedded server. +# The first reason to have them is that embedded server doesn't have +# optimizer trace. +# +--source include/not_embedded.inc +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +--echo # +--echo # MDEV-21958: Query having many NOT-IN clauses running forever +--echo # +create table t2 ( + pk int primary key, + key1 int, + col1 int, + key (key1, pk) +); + +insert into t2 (pk, key1) values (1,1),(2,2),(3,3),(4,4),(5,5); + +set @tmp_21958=@@optimizer_trace; +set optimizer_trace=1; +explain select * from t2 where key1 in (1,2,3) and pk not in (1,2,3); + +--echo # This should show only ranges in form "(1) <= (key1) <= (1)" +--echo # ranges over "pk" should not be constructed. +select json_detailed(JSON_EXTRACT(trace, '$**.ranges')) +from information_schema.optimizer_trace; +set optimizer_trace=@tmp_21958; + +drop table t2; From 18256bce23a5e219a8f4424b56a4380cf8be330a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 12 Dec 2020 12:10:37 +0100 Subject: [PATCH 31/72] remove the test for MDEV-22485 that doesn't test MDEV-22485 This reverts commit bc2dc83cb56851144a8c15e73a83c7817dc705a2. --- mysql-test/main/mysqlslap.opt | 1 - mysql-test/main/mysqlslap.result | 100 ------------------------------- mysql-test/main/mysqlslap.test | 51 ---------------- 3 files changed, 152 deletions(-) diff --git a/mysql-test/main/mysqlslap.opt b/mysql-test/main/mysqlslap.opt index da7672849bb..632f5b4c069 100644 --- a/mysql-test/main/mysqlslap.opt +++ b/mysql-test/main/mysqlslap.opt @@ -1,2 +1 @@ --sql_mode='NO_ENGINE_SUBSTITUTION' ---log-output=TABLE,FILE --general-log=0 --slow-query-log=0 diff --git a/mysql-test/main/mysqlslap.result b/mysql-test/main/mysqlslap.result index a83d4d38a16..791cb5ac6b3 100644 --- a/mysql-test/main/mysqlslap.result +++ b/mysql-test/main/mysqlslap.result @@ -258,103 +258,3 @@ DROP TABLE t1; # # Bug MDEV-15789 (Upstream: #80329): MYSQLSLAP OPTIONS --AUTO-GENERATE-SQL-GUID-PRIMARY and --AUTO-GENERATE-SQL-SECONDARY-INDEXES DONT WORK # -# -# MDEV-22485: mysqlslap does not use current user as default for connecting to server -# -set @old_general_log=@@global.general_log; -set @old_general_log_file=@@global.general_log_file; -select @old_general_log; -@old_general_log -0 -show global variables -where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; -Variable_name Value -general_log OFF -slow_query_log OFF -truncate table mysql.general_log; -select * from mysql.general_log; -event_time user_host thread_id server_id command_type argument -set global general_log=ON; -current_user.log; -@@current_user.log -current_user.log -SET GLOBAL general_log_file=general_log.log; -show global variables -where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; -Variable_name Value -general_log ON -slow_query_log OFF -flush logs; -create user anel@localhost; -grant all on *.* to anel@localhost; -connect con1,localhost,anel,,; -connection con1; -create table t(t int); -# Run mysqlslap user anel -Benchmark - Average number of seconds to run all queries: X seconds - Minimum number of seconds to run all queries: X seconds - Maximum number of seconds to run all queries: X seconds - Number of clients running queries: 1 - Average number of queries per client: 1 - -flush tables; -select user_host, command_type, argument from mysql.general_log; -user_host command_type argument -root[root] @ localhost [] Query select @@general_log_file -root[root] @ localhost [] Query SET GLOBAL general_log_file=current_user.log -root[root] @ localhost [] Query show global variables -where Variable_name = 'general_log' or Variable_name = 'slow_query_log' -root[root] @ localhost [] Query flush logs -root[root] @ localhost [] Query create user anel@localhost -root[root] @ localhost [] Query grant all on *.* to anel@localhost -[anel] @ localhost [] Connect anel@localhost as anonymous on test -anel[anel] @ localhost [] Query create table t(t int) -[root] @ localhost [] Connect root@localhost as anonymous on -[root] @ localhost [] Connect root@localhost as anonymous on test -root[root] @ localhost [] Query SELECT current_user() -root[root] @ localhost [] Quit -root[root] @ localhost [] Quit -anel[anel] @ localhost [] Query flush tables -anel[anel] @ localhost [] Query select user_host, command_type, argument from mysql.general_log -disconnect con1; -connection default; -# Run mysqlslap user root -Benchmark - Average number of seconds to run all queries: X seconds - Minimum number of seconds to run all queries: X seconds - Maximum number of seconds to run all queries: X seconds - Number of clients running queries: 1 - Average number of queries per client: 1 - -flush tables; -select user_host, command_type, argument from mysql.general_log; -user_host command_type argument -root[root] @ localhost [] Query select @@general_log_file -root[root] @ localhost [] Query SET GLOBAL general_log_file=current_user.log -root[root] @ localhost [] Query show global variables -where Variable_name = 'general_log' or Variable_name = 'slow_query_log' -root[root] @ localhost [] Query flush logs -root[root] @ localhost [] Query create user anel@localhost -root[root] @ localhost [] Query grant all on *.* to anel@localhost -[anel] @ localhost [] Connect anel@localhost as anonymous on test -anel[anel] @ localhost [] Query create table t(t int) -[root] @ localhost [] Connect root@localhost as anonymous on -[root] @ localhost [] Connect root@localhost as anonymous on test -root[root] @ localhost [] Query SELECT current_user() -root[root] @ localhost [] Quit -root[root] @ localhost [] Quit -anel[anel] @ localhost [] Query flush tables -anel[anel] @ localhost [] Query select user_host, command_type, argument from mysql.general_log -anel[anel] @ localhost [] Quit -[root] @ localhost [] Connect root@localhost as anonymous on -[root] @ localhost [] Connect root@localhost as anonymous on test -root[root] @ localhost [] Query SELECT current_user() -root[root] @ localhost [] Quit -root[root] @ localhost [] Quit -root[root] @ localhost [] Query flush tables -root[root] @ localhost [] Query select user_host, command_type, argument from mysql.general_log -drop user anel@localhost; -drop table t; -set global general_log= @old_general_log; -set global general_log_file= @old_general_log_file; diff --git a/mysql-test/main/mysqlslap.test b/mysql-test/main/mysqlslap.test index 4e99b8f2cd2..81115d59d09 100644 --- a/mysql-test/main/mysqlslap.test +++ b/mysql-test/main/mysqlslap.test @@ -88,54 +88,3 @@ DROP TABLE t1; --exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --create-schema=slap --exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-secondary-indexes=1 --create-schema=slap - ---echo # ---echo # MDEV-22485: mysqlslap does not use current user as default for connecting to server ---echo # ---disable_ps_protocol -set @old_general_log=@@global.general_log; -set @old_general_log_file=@@global.general_log_file; -select @old_general_log; - -show global variables -where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; -truncate table mysql.general_log; -# empty log at the beginning -select * from mysql.general_log; - -set global general_log=ON; ---replace_regex /[\/\w:](?!.log).*/current_user.log/ -select @@general_log_file; ---replace_regex /=.+"/=general_log.log/ ---let $gen_log_file=$MYSQLTEST_VARDIR/tmp/general_log.log ---replace_regex /".+"/general_log.log/ ---eval SET GLOBAL general_log_file="$gen_log_file" -show global variables -where Variable_name = 'general_log' or Variable_name = 'slow_query_log'; -flush logs; -create user anel@localhost; -grant all on *.* to anel@localhost; -connect con1,localhost,anel,,; -connection con1; -create table t(t int); ---echo # Run mysqlslap user anel ---replace_regex /\d[.]\d+/X/ ---exec $MYSQL_SLAP --create-schema=test --query="SELECT current_user()" --concurrency=1 --iterations=1 -flush tables; ---replace_regex /".+/current_user.log/ /[::1]// -select user_host, command_type, argument from mysql.general_log; -disconnect con1; - -connection default; ---echo # Run mysqlslap user root ---replace_regex /\d[.]\d+/X/ ---exec $MYSQL_SLAP --create-schema=test --query="SELECT current_user()" --concurrency=1 --iterations=1 -flush tables; -#--exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --create-schema=slap ---replace_regex /".+/current_user.log/ /[::1]// -select user_host, command_type, argument from mysql.general_log; -drop user anel@localhost; -drop table t; -set global general_log= @old_general_log; -set global general_log_file= @old_general_log_file; ---enable_ps_protocol From e9d86d80bef50e29a1f7cf7e7bb689cadad11600 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 11 Dec 2020 14:32:08 +0100 Subject: [PATCH 32/72] issue ER_USER_IS_BLOCKED also for non-existent users following the same masquerading logic --- sql/sql_acl.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0769e1eb395..08d747b9743 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -12828,15 +12828,6 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) ACL_USER *user= find_user_or_anon(sctx->host, sctx->user, sctx->ip); - if (user && user->password_errors >= max_password_errors && !ignore_max_password_errors(user)) - { - mysql_mutex_unlock(&acl_cache->lock); - my_error(ER_USER_IS_BLOCKED, MYF(0)); - general_log_print(mpvio->auth_info.thd, COM_CONNECT, - ER_THD(mpvio->auth_info.thd, ER_USER_IS_BLOCKED)); - DBUG_RETURN(1); - } - if (user) mpvio->acl_user= user->copy(mpvio->auth_info.thd->mem_root); @@ -12873,6 +12864,15 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) mpvio->make_it_fail= true; } + if (mpvio->acl_user->password_errors >= max_password_errors && + !ignore_max_password_errors(mpvio->acl_user)) + { + my_error(ER_USER_IS_BLOCKED, MYF(0)); + general_log_print(mpvio->auth_info.thd, COM_CONNECT, + ER_THD(mpvio->auth_info.thd, ER_USER_IS_BLOCKED)); + DBUG_RETURN(1); + } + /* user account requires non-default plugin and the client is too old */ if (mpvio->acl_user->auth->plugin.str != native_password_plugin_name.str && mpvio->acl_user->auth->plugin.str != old_password_plugin_name.str && From e5d88e03beec38973539f5d290fa70f81be645ef Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Mon, 14 Dec 2020 16:51:30 +0530 Subject: [PATCH 33/72] MDEV-22740: UBSAN: sql/opt_split.cc:1150:28: runtime error: shift exponent 61 is too large for 32-bit type 'int' (on optimized builds) Use a ulonglong instead of uint when left shifting to calculate the table map for all the tables in a query --- sql/opt_split.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 6807a623b73..fd7836f55cc 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -1149,7 +1149,7 @@ bool JOIN_TAB::fix_splitting(SplM_plan_info *spl_plan, bool JOIN::fix_all_splittings_in_plan() { table_map prev_tables= 0; - table_map all_tables= (1 << table_count) - 1; + table_map all_tables= (table_map(1) << table_count) - 1; for (uint tablenr= 0; tablenr < table_count; tablenr++) { POSITION *cur_pos= &best_positions[tablenr]; From 0ea650022dab58fe0b888fae1b816937f98521b6 Mon Sep 17 00:00:00 2001 From: Stepan Patryshev Date: Mon, 14 Dec 2020 19:50:48 +0200 Subject: [PATCH 34/72] MDEV-23659 Update Galera disabled.def file --- mysql-test/suite/galera_3nodes/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index 5e3804b9844..0e2706f2dc3 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -14,4 +14,3 @@ galera_gtid_2_cluster : MDEV-23775 Galera test failure on galera_3nodes.galera_g galera_ist_gcache_rollover : MDEV-23578 WSREP: exception caused by message: {v=0,t=1,ut=255,o=4,s=0,sr=0,as=1,f=6,src=50524cfe,srcvid=view_id(REG,50524cfe,4),insvid=view_id(UNKNOWN,00000000,0),ru=00000000,r=[-1,-1],fs=75,nl=(} galera_slave_options_do :MDEV-8798 galera_slave_options_ignore : MDEV-8798 -galera_ipv6_mysqldump : MDEV-23576 From 384f107ae586a9b4949ec9fd5393959a26d866cd Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 14 Dec 2020 15:06:42 +1100 Subject: [PATCH 35/72] MDEV-21646: postfix - my_addr_resolve: static Dl_info info Encountered the linker failure on Debug build in 10.4: [53/585] Linking CXX executable unittest/sql/mf_iocache-t FAILED: unittest/sql/mf_iocache-t : && /usr/bin/c++ -pie -fPIC -fstack-protector --param=ssp-buffer-size=4 -fPIC -g -DENABLED_DEBUG_SYNC -ggdb3 -DSAFE_MUTEX -DSAFEMALLOC -DTRASH_FREED_MEMORY -Wall -Wextra -Wno-format-truncation -Wno-init-self -Wno-nonnull-compare -Wno-unused-parameter -Woverloaded-virtual -Wnon-virtual-dtor -Wvla -Wwrite-strings -Werror -Wl,-z,relro,-z,now unittest/sql/CMakeFiles/mf_iocache-t.dir/mf_iocache-t.cc.o unittest/sql/CMakeFiles/mf_iocache-t.dir/__/__/sql/mf_iocache_encr.cc.o -o unittest/sql/mf_iocache-t -lpthread mysys/libmysys.a unittest/mytap/libmytap.a mysys_ssl/libmysys_ssl.a mysys/libmysys.a dbug/libdbug.a mysys/libmysys.a dbug/libdbug.a -lz -lm strings/libstrings.a -lpthread -lssl -lcrypto -ldl && : /usr/bin/ld: mysys/libmysys.a(my_addr_resolve.c.o):/home/dan/repos/mariadb-server-10.4/mysys/my_addr_resolve.c:173: multiple definition of `info'; unittest/sql/CMakeFiles/mf_iocache-t.dir/mf_iocache-t.cc.o:/home/dan/repos/mariadb-server-10.4/unittest/sql/mf_iocache-t.cc:99: first defined here We make Dl_info static as in MDEV-21646 moving it out of the function was the main goal and having it scope limited by static doesn't affect the function. --- mysys/my_addr_resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 3a49c749010..f0c0d214171 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -170,7 +170,7 @@ static pid_t pid; static char addr2line_binary[1024]; static char output[1024]; static struct pollfd poll_fds; -Dl_info info; +static Dl_info info; int start_addr2line_fork(const char *binary_path) { From d4c35fb21b11f05b317d2e98de42f9a2cab46c27 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 24 Oct 2020 21:01:07 +1100 Subject: [PATCH 36/72] MDEV-24207: recognise mysql forms of invalid password for mysql_native_password The main goal of this patch is to prevent MariaDB's native_password_plugin from "parsing" the hex (or non hex) authentication_string. Due to how the current code is written, we convert any string (within native_password_get_salt) that has the appropriate length to a "binary" representation, that can potentially match a real password. More specifically, "*THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE" produces the same results as "*d13c3c78dafa52d9bce09bdd1adcb7befced1ebe". The length indicator is the main indicator of an invalid password. We use use same trick with "invalid" to change its internal representation. The "parsing" mentioned is by get_salt_from_password down to char_val() and because if where it is, its effectively a static plugin API that cannot change. In supporting these, we support the SHOW CREATE USER from MySQL may have the hashed password string: *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE. Obviously this isn't a hash because it contains non-hex characters. After this patch we do however recognise the pattern; [any char, notionally *]{40 chars not all are hex} as a pattern for an invalid password. This was determined to be the general pattern that MySQL used. Reviewers: Sergei G, Vicentiu --- mysql-test/main/set_password.result | 8 +++++++- mysql-test/main/set_password.test | 7 ++++++- sql/sql_acl.cc | 18 ++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/set_password.result b/mysql-test/main/set_password.result index 6a4e0da937e..a3d8683ee64 100644 --- a/mysql-test/main/set_password.result +++ b/mysql-test/main/set_password.result @@ -11,9 +11,11 @@ create user oldauth@localhost identified with 'mysql_old_password' using '378b24 create user oldpass@localhost identified by password '378b243e220ca493'; create user oldpassold@localhost identified with 'mysql_old_password'; set password for oldpassold@localhost = '378b243e220ca493'; +create user invalidmysql57auth@localhost identified via 'mysql_native_password' using '*THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE'; select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; User Host Password plugin authentication_string invalidauth localhost invalid mysql_native_password invalid +invalidmysql57auth localhost *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE mysql_native_password *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE invalidpass localhost invalid mysql_native_password invalid invalidpassnat localhost invalid mysql_native_password invalid mariadb.sys localhost mysql_native_password @@ -95,6 +97,7 @@ set password for oldpassold@localhost = PASSWORD('test2'); select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; User Host Password plugin authentication_string invalidauth localhost invalid mysql_native_password invalid +invalidmysql57auth localhost *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE mysql_native_password *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE invalidpass localhost invalid mysql_native_password invalid invalidpassnat localhost invalid mysql_native_password invalid mariadb.sys localhost mysql_native_password @@ -160,6 +163,9 @@ ERROR 28000: Access denied for user 'invalidpass'@'localhost' (using password: Y connect(localhost,invalidpassnat,invalid,test,MASTER_PORT,MASTER_SOCKET); connect con,localhost,invalidpassnat,invalid,; ERROR 28000: Access denied for user 'invalidpassnat'@'localhost' (using password: YES) +connect(localhost,invalidmysql57auth,invalid,test,MASTER_PORT,MASTER_SOCKET); +connect con,localhost,invalidmysql57auth,invalid,; +ERROR 28000: Access denied for user 'invalidmysql57auth'@'localhost' (using password: YES) connect con,localhost,oldauth,test2,; select current_user(); current_user() @@ -177,7 +183,7 @@ oldpassold@localhost disconnect con; connection default; drop user natauth@localhost, newpass@localhost, newpassnat@localhost; -drop user invalidauth@localhost, invalidpass@localhost, invalidpassnat@localhost; +drop user invalidauth@localhost, invalidpass@localhost, invalidpassnat@localhost,invalidmysql57auth@localhost; drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; set global secure_auth=default; # switching from mysql.global_priv to mysql.user diff --git a/mysql-test/main/set_password.test b/mysql-test/main/set_password.test index dd5e261346b..ec652a09274 100644 --- a/mysql-test/main/set_password.test +++ b/mysql-test/main/set_password.test @@ -31,6 +31,8 @@ create user oldpass@localhost identified by password '378b243e220ca493'; create user oldpassold@localhost identified with 'mysql_old_password'; set password for oldpassold@localhost = '378b243e220ca493'; +create user invalidmysql57auth@localhost identified via 'mysql_native_password' using '*THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE'; + --sorted_result select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; @@ -131,6 +133,9 @@ select current_user(); --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCESS_DENIED_ERROR --connect(con,localhost,invalidpassnat,invalid,) +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +--connect(con,localhost,invalidmysql57auth,invalid,) --connect(con,localhost,oldauth,test2,) select current_user(); @@ -144,7 +149,7 @@ select current_user(); --connection default drop user natauth@localhost, newpass@localhost, newpassnat@localhost; -drop user invalidauth@localhost, invalidpass@localhost, invalidpassnat@localhost; +drop user invalidauth@localhost, invalidpass@localhost, invalidpassnat@localhost,invalidmysql57auth@localhost; drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; set global secure_auth=default; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 08d747b9743..cb2757ba48f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -14203,6 +14203,7 @@ static int native_password_get_salt(const char *hash, size_t hash_length, { DBUG_ASSERT(sizeof(invalid_password) > SCRAMBLE_LENGTH); DBUG_ASSERT(*out_length >= SCRAMBLE_LENGTH); + DBUG_ASSERT(*out_length >= sizeof(invalid_password)); if (hash_length == 0) { *out_length= 0; @@ -14213,14 +14214,27 @@ static int native_password_get_salt(const char *hash, size_t hash_length, { if (hash_length == 7 && strcmp(hash, "invalid") == 0) { - memcpy(out, invalid_password, SCRAMBLED_PASSWORD_CHAR_LENGTH); - *out_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; + memcpy(out, invalid_password, sizeof(invalid_password)); + *out_length= sizeof(invalid_password); return 0; } my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); return 1; } + for (const char *c= hash + 1; c < (hash + hash_length); c++) + { + /* If any non-hex characters are found, mark the password as invalid. */ + if (!(*c >= '0' && *c <= '9') && + !(*c >= 'A' && *c <= 'F') && + !(*c >= 'a' && *c <= 'f')) + { + memcpy(out, invalid_password, sizeof(invalid_password)); + *out_length= sizeof(invalid_password); + return 0; + } + } + *out_length= SCRAMBLE_LENGTH; get_salt_from_password(out, hash); return 0; From 5f4d351d7fe3dcae9f5d76d8027d54fa8392e66a Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Thu, 17 Sep 2020 19:05:08 +0530 Subject: [PATCH 37/72] MDEV-22422: Assertion `! is_set()' failed in Diagnostics_area::set_eof_status Analysis: The error is not returned when the statement can't be used. And so we still go on to search for keywords. Fix: Return the error state. --- sql/sql_help.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_help.cc b/sql/sql_help.cc index c05c9a7d229..5ae9d3beb8b 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -741,6 +741,9 @@ static bool mysqld_help_internal(THD *thd, const char *mask) &name, &description, &example); delete select; + if (thd->is_error()) + goto error; + if (count_topics == 0) { int UNINIT_VAR(key_id); From 74223c33d1aeffac28b155c59646dc3df58e33fb Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Tue, 4 Aug 2020 13:21:54 +0530 Subject: [PATCH 38/72] MDEV-23209: Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed in Diagnostics_area::set_ok_status on INSERT Analysis: Error is not returned when strict mode is enabled and value is truncated because double is outside range. Fix: Return HA_ERR_AUTOINC_ERANGE if the error was reported when double is outside range. --- sql/handler.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/handler.cc b/sql/handler.cc index d2408767530..c38c604347a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3118,6 +3118,13 @@ int handler::update_auto_increment() (table->auto_increment_field_not_null && thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) { + + /* + There could be an error reported because value was truncated + when strict mode is enabled. + */ + if (thd->is_error()) + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); /* Update next_insert_id if we had already generated a value in this statement (case of INSERT VALUES(null),(3763),(null): From ac9c6f53a5e1d0637fb390f1cd7b44bd8c38d72e Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 27 Oct 2020 11:49:17 +0100 Subject: [PATCH 39/72] MDEV-24034 Policy CMP0075 is not set during compile The policy is not set for 10.2 If it is set, CMake would complain about bundled zlib for which the policy is not set. Fix: - Set policy for 10.2 for the top level project. For 10.3+ it was already set - Cleanup zlib to remove unneeded stuff. It is an internal static library, it needs none of PROJECT, library versioning, RC file on Windows. The name of the library on Unix does not make any difference, since it is static and compiled in. --- CMakeLists.txt | 3 +++ zlib/CMakeLists.txt | 39 --------------------------------------- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4734c6f7d5f..466b2a5bc3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,9 @@ ENDIF() IF(POLICY CMP0054) CMAKE_POLICY(SET CMP0054 NEW) ENDIF() +IF(POLICY CMP0075) + CMAKE_POLICY(SET CMP0075 NEW) +ENDIF() MESSAGE(STATUS "Running cmake version ${CMAKE_VERSION}") diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index 810ec8ae0cb..ee79bc0bd5f 100644 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -13,12 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA -cmake_minimum_required(VERSION 2.4.4) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - -project(zlib C) - -set(VERSION "1.2.11") include(CheckTypeSize) include(CheckFunctionExists) @@ -110,40 +104,7 @@ set(ZLIB_SRCS zutil.c ) -if(NOT MINGW) - set(ZLIB_DLL_SRCS - win32/zlib1.rc # If present will override custom build rule below. - ) -endif() - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - ADD_CONVENIENCE_LIBRARY(zlib STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) RESTRICT_SYMBOL_EXPORTS(zlib) - -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(CMAKE_SYSTEM_NAME MATCHES "SunOS") - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib PROPERTIES OUTPUT_NAME z) -elseif(UNIX) - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib PROPERTIES OUTPUT_NAME z) -endif() - - -RESTRICT_SYMBOL_EXPORTS(zlib) From 066212d16cc2b3995e2c53de9e2f799fdab557bd Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 15 Dec 2020 14:38:30 +0300 Subject: [PATCH 40/72] MDEV-21958: Query having many NOT-IN clauses running forever Basic variant of the fix: do not consider conditions in form unique_key NOT IN (c1,c2...) to be sargable. If there are only a few constants, the condition is not selective. If there are a lot constants, the overhead of processing such a huge range list is not worth it. (Backport to 10.2) --- mysql-test/r/range.result | 15 +++++++++++++++ mysql-test/t/range.test | 21 +++++++++++++++++++++ sql/opt_range.cc | 24 ++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 9ea0dc12a0b..49bce9a316d 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -3158,6 +3158,21 @@ pk a b 1 5 50 65 5 50 drop table t1; +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 ( +pk int primary key, +key1 int, +col1 varchar(255), +key (key1, pk) +); +insert into t2 (pk, key1) +select A.a+10 *B.a + 100*C.a, A.a+10 *B.a +100*C.a from t1 A, t1 B, t1 C; +# This must use ALL, not range: +explain select * from t2 force index (primary) where pk not in (1,2,3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1000 Using where +drop table t1,t2; # # End of 10.2 tests # diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 264f7c784ce..4088aa2990e 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -2183,6 +2183,27 @@ eval $q4; drop table t1; +# +# MDEV-21958: Query having many NOT-IN clauses running forever (testcase 2) +# +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t2 ( + pk int primary key, + key1 int, + col1 varchar(255), + key (key1, pk) +); + +insert into t2 (pk, key1) +select A.a+10 *B.a + 100*C.a, A.a+10 *B.a +100*C.a from t1 A, t1 B, t1 C; + +--echo # This must use ALL, not range: +explain select * from t2 force index (primary) where pk not in (1,2,3); + +drop table t1,t2; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/opt_range.cc b/sql/opt_range.cc index cbf82a20f4a..3a6579b0471 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7158,6 +7158,30 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, if (array->count > NOT_IN_IGNORE_THRESHOLD || !value_item) DBUG_RETURN(0); + /* + If this is "unique_key NOT IN (...)", do not consider it sargable (for + any index, not just the unique one). The logic is as follows: + - if there are only a few constants, this condition is not selective + (unless the table is also very small in which case we won't gain + anything) + - If there are a lot of constants, the overhead of building and + processing enormous range list is not worth it. + */ + if (param->using_real_indexes) + { + key_map::Iterator it(field->key_start); + uint key_no; + while ((key_no= it.next_bit()) != key_map::Iterator::BITMAP_END) + { + KEY *key_info= ¶m->table->key_info[key_no]; + if (key_info->user_defined_key_parts == 1 && + (key_info->flags & HA_NOSAME)) + { + DBUG_RETURN(0); + } + } + } + /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */ uint i=0; do From 71806bf37c45d5490d8382cba6a5cca6879fa0db Mon Sep 17 00:00:00 2001 From: Stepan Patryshev Date: Tue, 15 Dec 2020 18:05:56 +0200 Subject: [PATCH 41/72] MDEV-24414 Update and enable galera.galera_defaults --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/t/galera_defaults.test | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index dd1721839e0..0692a02c7b0 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -14,7 +14,6 @@ MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-328B : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-329 : MDEV-19962 Galera test failure on MW-329 -galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event() galera_binlog_stmt_autoinc : MDEV-19959 Galera test failure on galera_binlog_stmt_autoinc galera_gcache_recover_manytrx : MDEV-18834 Galera test failure diff --git a/mysql-test/suite/galera/t/galera_defaults.test b/mysql-test/suite/galera/t/galera_defaults.test index 3d4a7da7b54..a9e10de0176 100644 --- a/mysql-test/suite/galera/t/galera_defaults.test +++ b/mysql-test/suite/galera/t/galera_defaults.test @@ -13,7 +13,7 @@ # Make sure that the test is operating on the right version of galera library. --disable_query_log ---let $galera_version=25.3.20 +--let $galera_version=25.3.31 source ../wsrep/include/check_galera_version.inc; --enable_query_log From dc62a67ed3e7d5dcfb125f3e718adff40c17f764 Mon Sep 17 00:00:00 2001 From: Stepan Patryshev Date: Tue, 15 Dec 2020 18:05:59 +0200 Subject: [PATCH 42/72] MDEV-24414 Update and enable galera.galera_defaults --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/t/galera_defaults.test | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 4d911c60a5e..f53fbd2b08c 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -14,7 +14,6 @@ MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-328B : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-329 : MDEV-19962 Galera test failure on MW-329 -galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event() galera_binlog_stmt_autoinc : MDEV-19959 Galera test failure on galera_binlog_stmt_autoinc galera_gcache_recover_manytrx : MDEV-18834 Galera test failure diff --git a/mysql-test/suite/galera/t/galera_defaults.test b/mysql-test/suite/galera/t/galera_defaults.test index 3d4a7da7b54..a9e10de0176 100644 --- a/mysql-test/suite/galera/t/galera_defaults.test +++ b/mysql-test/suite/galera/t/galera_defaults.test @@ -13,7 +13,7 @@ # Make sure that the test is operating on the right version of galera library. --disable_query_log ---let $galera_version=25.3.20 +--let $galera_version=25.3.31 source ../wsrep/include/check_galera_version.inc; --enable_query_log From 2c4761ccc1980421103ed1c82aff8cf2907d962b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 9 Nov 2020 19:21:07 +1100 Subject: [PATCH 43/72] MDEV-24172: innodb stats table last_update is TIMESTAMP The last_updated column of innodb_table_stats and innodb_index_stats hasn't been DATA_FIXBINARY for many years. Innodb represents TIMESTAMP as INT of length 4. Let's test it with this and stop hiding the result in mysql_upgrade test. Reviewer: Marko --- mysql-test/r/mysql_upgrade.result | 2 -- mysql-test/t/mysql_upgrade.test | 2 -- storage/innobase/dict/dict0stats.cc | 8 ++++---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index b6fb56a63e0..a3e88765554 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -476,8 +476,6 @@ even_longer_user_name_number_3_to_test_the_grantor_and_definer_field_length@loca DROP USER very_long_user_name_number_1, very_long_user_name_number_2, even_longer_user_name_number_3_to_test_the_grantor_and_definer_field_length@localhost; DROP PROCEDURE test.pr; use test; -call mtr.add_suppression('Column last_update in table `mysql`.`innodb_table_stats` is INT NOT NULL but should be'); -alter table mysql.innodb_table_stats modify last_update int not null; create table extralongname_extralongname_extralongname_extralongname_ext ( id int(10) unsigned not null, created_date date not null, diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index 5dad8702fc5..a6702f91aa6 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -173,8 +173,6 @@ DROP PROCEDURE test.pr; # MDEV-13274 mysql_upgrade fails if dbname+tablename+partioname > 64 chars # use test; -call mtr.add_suppression('Column last_update in table `mysql`.`innodb_table_stats` is INT NOT NULL but should be'); -alter table mysql.innodb_table_stats modify last_update int not null; create table extralongname_extralongname_extralongname_extralongname_ext ( id int(10) unsigned not null, diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index e72a86500a6..1611703c2e9 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -178,8 +178,8 @@ dict_stats_persistent_storage_check( {"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597}, - {"last_update", DATA_FIXBINARY, - DATA_NOT_NULL, 4}, + {"last_update", DATA_INT, + DATA_NOT_NULL | DATA_UNSIGNED, 4}, {"n_rows", DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, @@ -209,8 +209,8 @@ dict_stats_persistent_storage_check( {"index_name", DATA_VARMYSQL, DATA_NOT_NULL, 192}, - {"last_update", DATA_FIXBINARY, - DATA_NOT_NULL, 4}, + {"last_update", DATA_INT, + DATA_NOT_NULL | DATA_UNSIGNED, 4}, {"stat_name", DATA_VARMYSQL, DATA_NOT_NULL, 64*3}, From 8de323f81acd830035a11058d5b76127d71616a4 Mon Sep 17 00:00:00 2001 From: Etienne Guesnet Date: Wed, 16 Dec 2020 08:44:58 +1100 Subject: [PATCH 44/72] MDEV-24099: sql/sql_insert ip_len issue on AIX ip_len has a different meaning on AIX so we use a different variable name here not to conflict. Backport from MDEV-20178 2f5d372444cff53914cfcd118e92a91f575cec35 --- sql/sql_insert.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b203fffaa72..8115b3c6397 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2690,7 +2690,7 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, delayed_row *row= 0; Delayed_insert *di=thd->di; const Discrete_interval *forced_auto_inc; - size_t user_len, host_len, ip_len; + size_t user_len, host_len, ip_length; DBUG_ENTER("write_delayed"); DBUG_PRINT("enter", ("query = '%s' length %lu", query.str, (ulong) query.length)); @@ -2724,7 +2724,7 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, goto err; } - user_len= host_len= ip_len= 0; + user_len= host_len= ip_length= 0; row->user= row->host= row->ip= NULL; if (thd->security_ctx) { @@ -2733,11 +2733,11 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, if (thd->security_ctx->host) host_len= strlen(thd->security_ctx->host) + 1; if (thd->security_ctx->ip) - ip_len= strlen(thd->security_ctx->ip) + 1; + ip_length= strlen(thd->security_ctx->ip) + 1; } /* This can't be THREAD_SPECIFIC as it's freed in delayed thread */ if (!(row->record= (char*) my_malloc(table->s->reclength + - user_len + host_len + ip_len, + user_len + host_len + ip_length, MYF(MY_WME)))) goto err; memcpy(row->record, table->record[0], table->s->reclength); @@ -2757,7 +2757,7 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, if (thd->security_ctx->ip) { row->ip= row->record + table->s->reclength + user_len + host_len; - memcpy(row->ip, thd->security_ctx->ip, ip_len); + memcpy(row->ip, thd->security_ctx->ip, ip_length); } } row->query_id= thd->query_id; From aebb1112693ebfa33e8e446668292a6124636ad7 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 16 Dec 2020 10:26:29 +1100 Subject: [PATCH 45/72] MDEV-21958: postfix - result of range_mrr_icp --- mysql-test/r/range_mrr_icp.result | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result index 55613261ce9..3561283044a 100644 --- a/mysql-test/r/range_mrr_icp.result +++ b/mysql-test/r/range_mrr_icp.result @@ -3170,6 +3170,21 @@ pk a b 70 4 40 71 2 20 drop table t1; +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 ( +pk int primary key, +key1 int, +col1 varchar(255), +key (key1, pk) +); +insert into t2 (pk, key1) +select A.a+10 *B.a + 100*C.a, A.a+10 *B.a +100*C.a from t1 A, t1 B, t1 C; +# This must use ALL, not range: +explain select * from t2 force index (primary) where pk not in (1,2,3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1000 Using where +drop table t1,t2; # # End of 10.2 tests # From 719da2c4cc988760049ef4eefe04081594763149 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Tue, 15 Dec 2020 16:46:58 +0300 Subject: [PATCH 46/72] MDEV-22810 mariabackup does not honor open_files_limit from option during backup prepare open_files_limit option was processed only for --backup, but not for --prepare. --- extra/mariabackup/xtrabackup.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 241d7aeb198..53301fd8e75 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -5811,6 +5811,10 @@ static bool xtrabackup_prepare_func(char** argv) ut_ad(inc_dir_tables_hash); } + msg("open files limit requested %u, set to %u", + (uint) xb_open_files_limit, + xb_set_max_open_files(xb_open_files_limit)); + /* Fix DDL for prepare. Process .del,.ren, and .new files. The order in which files are processed, is important (see MDEV-18185, MDEV-18201) From c742346e5041d85caaf30d2d6c10369603ad09ad Mon Sep 17 00:00:00 2001 From: Stepan Patryshev Date: Wed, 16 Dec 2020 18:29:06 +0200 Subject: [PATCH 47/72] TODO-2697 Enable galera.lp1376747-4 on 10.3 CS --- mysql-test/suite/galera/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 0692a02c7b0..87dbb7a6487 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -23,7 +23,6 @@ galera_ssl_upgrade : MDEV-19950 Galera test failure on galera_ssl_upgrade galera_sst_mariabackup_encrypt_with_key : MDEV-21484 galera_sst_mariabackup_encrypt_with_key galera_var_node_address : MDEV-20485 Galera test failure galera_wan : MDEV-17259 Test failure on galera.galera_wan -lp1376747-4 : MDEV-21911 Galera test failure on lp1376747-4 partition : MDEV-19958 Galera test failure on galera.partition query_cache: MDEV-15805 Test failure on galera.query_cache sql_log_bin : MDEV-21491 galera.sql_log_bin From a244be7044534a59199a0f11e856be37ba6f02c8 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 16 Dec 2020 09:11:11 -0800 Subject: [PATCH 48/72] MDEV-23406 Signal 8 in maria_create after recursive cte query This bug could cause a crash when executing queries that used mutually recursive CTEs with system variable big_tables set to 1. It happened due to several bugs in the code that handled recursive table references referred mutually recursive CTEs. For each recursive table reference a temporary table is created that contains all rows generated for the corresponding recursive CTE table on the previous step of recursion. This temporary table should be created in the same way as the temporary table created for a regular materialized derived table using the method select_union::create_result_table(). In this case when the temporary table is created it uses the select_union::TMP_TABLE_PARAM structure as the parameter for the table construction. However the code created the temporary table using just the function create_tmp_table() and passed pointers to certain fields of the TMP_TABLE_PARAM structure used for accumulation of rows of the recursive CTE table as parameters for update. This was a mistake because now different temporary tables cannot share some TMP_TABLE_PARAM fields in a general case. Besides, depending on how mutually recursive CTE tables were defined and which of them were referred in the executed query the select_union object allocated for a recursive table reference could be allocated again after the the temporary table had been created. In this case the TMP_TABLE_PARAM object associated with the temporary table created for the recursive table reference contained unassigned fields needed for execution when Aria engine is employed as the engine for temporary tables. This patch ensures that - select_union object is created only once for any recursive table reference - any temporary table created for recursive CTEs uses its own TMP_TABLE_PARAM structure The patch also fixes a problem caused by incomplete cleanup of join tables associated with recursive table references. Approved by Oleksandr Byelkin --- mysql-test/r/cte_recursive.result | 219 ++++++++++++++++++++++++++++++ mysql-test/t/cte_recursive.test | 94 +++++++++++++ sql/sql_class.h | 12 +- sql/sql_cte.cc | 7 +- sql/sql_derived.cc | 9 +- sql/sql_select.cc | 4 - sql/sql_union.cc | 64 +++++---- 7 files changed, 370 insertions(+), 39 deletions(-) diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index 5090a0ffef9..b6b4ed7fb37 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -4235,5 +4235,224 @@ drop database db1; create database test; use test; # +# MDEV-23406: query with mutually recursive CTEs when big_tables=1 +# +set @save_big_tables=@@big_tables; +set big_tables=1; +create table folks(id int, name char(32), dob date, father int, mother int); +insert into folks values +(100, 'Me', '2000-01-01', 20, 30), +(20, 'Dad', '1970-02-02', 10, 9), +(30, 'Mom', '1975-03-03', 8, 7), +(10, 'Grandpa Bill', '1940-04-05', null, null), +(9, 'Grandma Ann', '1941-10-15', null, null), +(25, 'Uncle Jim', '1968-11-18', 8, 7), +(98, 'Sister Amy', '2001-06-20', 20, 30), +(7, 'Grandma Sally', '1943-08-23', null, 6), +(8, 'Grandpa Ben', '1940-10-21', null, null), +(6, 'Grandgrandma Martha', '1923-05-17', null, null), +(67, 'Cousin Eddie', '1992-02-28', 25, 27), +(27, 'Auntie Melinda', '1971-03-29', null, null); +with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +w_id, w_name, w_dob, w_father, w_mother) +as +( +select h.*, w.* +from folks h, folks w, coupled_ancestors a +where a.father = h.id AND a.mother = w.id +union +select h.*, w.* +from folks v, folks h, folks w +where v.name = 'Me' and +(v.father = h.id AND v.mother= w.id) +), +coupled_ancestors (id, name, dob, father, mother) +as +( +select h_id, h_name, h_dob, h_father, h_mother +from ancestor_couples +union +select w_id, w_name, w_dob, w_father, w_mother +from ancestor_couples +) +select h_name, h_dob, w_name, w_dob +from ancestor_couples; +h_name h_dob w_name w_dob +Dad 1970-02-02 Mom 1975-03-03 +Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15 +Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23 +explain with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +w_id, w_name, w_dob, w_father, w_mother) +as +( +select h.*, w.* +from folks h, folks w, coupled_ancestors a +where a.father = h.id AND a.mother = w.id +union +select h.*, w.* +from folks v, folks h, folks w +where v.name = 'Me' and +(v.father = h.id AND v.mother= w.id) +), +coupled_ancestors (id, name, dob, father, mother) +as +( +select h_id, h_name, h_dob, h_father, h_mother +from ancestor_couples +union +select w_id, w_name, w_dob, w_father, w_mother +from ancestor_couples +) +select h_name, h_dob, w_name, w_dob +from ancestor_couples; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 1728 +4 DERIVED ALL NULL NULL NULL NULL 1728 +5 RECURSIVE UNION ALL NULL NULL NULL NULL 1728 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +3 DERIVED v ALL NULL NULL NULL NULL 12 Using where +3 DERIVED h ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +3 DERIVED w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join) +2 RECURSIVE UNION ALL NULL NULL NULL NULL 2 +2 RECURSIVE UNION h ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +2 RECURSIVE UNION w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join) +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +prepare stmt from "with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +w_id, w_name, w_dob, w_father, w_mother) +as +( +select h.*, w.* +from folks h, folks w, coupled_ancestors a +where a.father = h.id AND a.mother = w.id +union +select h.*, w.* +from folks v, folks h, folks w +where v.name = 'Me' and +(v.father = h.id AND v.mother= w.id) +), +coupled_ancestors (id, name, dob, father, mother) +as +( +select h_id, h_name, h_dob, h_father, h_mother +from ancestor_couples +union +select w_id, w_name, w_dob, w_father, w_mother +from ancestor_couples +) +select h_name, h_dob, w_name, w_dob +from ancestor_couples"; +execute stmt; +h_name h_dob w_name w_dob +Dad 1970-02-02 Mom 1975-03-03 +Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15 +Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23 +execute stmt; +h_name h_dob w_name w_dob +Dad 1970-02-02 Mom 1975-03-03 +Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15 +Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23 +deallocate prepare stmt; +with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +w_id, w_name, w_dob, w_father, w_mother) +as +( +select h.*, w.* +from folks h, folks w, coupled_ancestors a +where a.father = h.id AND a.mother = w.id +), +coupled_ancestors (id, name, dob, father, mother) +as +( +select * +from folks +where name = 'Me' + union all +select h_id, h_name, h_dob, h_father, h_mother +from ancestor_couples +union all +select w_id, w_name, w_dob, w_father, w_mother +from ancestor_couples +) +select h_name, h_dob, w_name, w_dob +from ancestor_couples; +h_name h_dob w_name w_dob +Dad 1970-02-02 Mom 1975-03-03 +Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15 +Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23 +explain with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +w_id, w_name, w_dob, w_father, w_mother) +as +( +select h.*, w.* +from folks h, folks w, coupled_ancestors a +where a.father = h.id AND a.mother = w.id +), +coupled_ancestors (id, name, dob, father, mother) +as +( +select * +from folks +where name = 'Me' + union all +select h_id, h_name, h_dob, h_father, h_mother +from ancestor_couples +union all +select w_id, w_name, w_dob, w_father, w_mother +from ancestor_couples +) +select h_name, h_dob, w_name, w_dob +from ancestor_couples; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +3 DERIVED folks ALL NULL NULL NULL NULL 12 Using where +4 RECURSIVE UNION ALL NULL NULL NULL NULL 2 +5 RECURSIVE UNION ALL NULL NULL NULL NULL 2 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +2 DERIVED h ALL NULL NULL NULL NULL 12 +2 DERIVED ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +2 DERIVED w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join) +prepare stmt from "with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +w_id, w_name, w_dob, w_father, w_mother) +as +( +select h.*, w.* +from folks h, folks w, coupled_ancestors a +where a.father = h.id AND a.mother = w.id +), +coupled_ancestors (id, name, dob, father, mother) +as +( +select * +from folks +where name = 'Me' + union all +select h_id, h_name, h_dob, h_father, h_mother +from ancestor_couples +union all +select w_id, w_name, w_dob, w_father, w_mother +from ancestor_couples +) +select h_name, h_dob, w_name, w_dob +from ancestor_couples"; +execute stmt; +h_name h_dob w_name w_dob +Dad 1970-02-02 Mom 1975-03-03 +Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15 +Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23 +execute stmt; +h_name h_dob w_name w_dob +Dad 1970-02-02 Mom 1975-03-03 +Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15 +Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23 +deallocate prepare stmt; +drop table folks; +set big_tables=@save_big_tables; +# # End of 10.2 tests # diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index f902ac25253..849e76b0436 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -2725,6 +2725,100 @@ drop database db1; create database test; use test; +--echo # +--echo # MDEV-23406: query with mutually recursive CTEs when big_tables=1 +--echo # + +set @save_big_tables=@@big_tables; +set big_tables=1; + +create table folks(id int, name char(32), dob date, father int, mother int); + +insert into folks values +(100, 'Me', '2000-01-01', 20, 30), +(20, 'Dad', '1970-02-02', 10, 9), +(30, 'Mom', '1975-03-03', 8, 7), +(10, 'Grandpa Bill', '1940-04-05', null, null), +(9, 'Grandma Ann', '1941-10-15', null, null), +(25, 'Uncle Jim', '1968-11-18', 8, 7), +(98, 'Sister Amy', '2001-06-20', 20, 30), +(7, 'Grandma Sally', '1943-08-23', null, 6), +(8, 'Grandpa Ben', '1940-10-21', null, null), +(6, 'Grandgrandma Martha', '1923-05-17', null, null), +(67, 'Cousin Eddie', '1992-02-28', 25, 27), +(27, 'Auntie Melinda', '1971-03-29', null, null); + +let q= +with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, + w_id, w_name, w_dob, w_father, w_mother) +as +( + select h.*, w.* + from folks h, folks w, coupled_ancestors a + where a.father = h.id AND a.mother = w.id + union + select h.*, w.* + from folks v, folks h, folks w + where v.name = 'Me' and + (v.father = h.id AND v.mother= w.id) +), +coupled_ancestors (id, name, dob, father, mother) +as +( + select h_id, h_name, h_dob, h_father, h_mother + from ancestor_couples + union + select w_id, w_name, w_dob, w_father, w_mother + from ancestor_couples +) +select h_name, h_dob, w_name, w_dob + from ancestor_couples; + +eval $q; +eval explain $q; +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q= +with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, + w_id, w_name, w_dob, w_father, w_mother) +as +( + select h.*, w.* + from folks h, folks w, coupled_ancestors a + where a.father = h.id AND a.mother = w.id +), +coupled_ancestors (id, name, dob, father, mother) +as +( + select * + from folks + where name = 'Me' + union all + select h_id, h_name, h_dob, h_father, h_mother + from ancestor_couples + union all + select w_id, w_name, w_dob, w_father, w_mother + from ancestor_couples +) +select h_name, h_dob, w_name, w_dob + from ancestor_couples; + +eval $q; +eval explain $q; +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +drop table folks; + +set big_tables=@save_big_tables; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_class.h b/sql/sql_class.h index 35068245830..b68e3553a2d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5152,10 +5152,15 @@ class select_union_recursive :public select_union public: /* The temporary table with the new records generated by one iterative step */ TABLE *incr_table; + /* The TMP_TABLE_PARAM structure used to create incr_table */ + TMP_TABLE_PARAM incr_table_param; /* One of tables from the list rec_tables (determined dynamically) */ TABLE *first_rec_table_to_update; - /* The temporary tables used for recursive table references */ - List rec_tables; + /* + The list of all recursive table references to the CTE for whose + specification this select_union_recursive was created + */ + List rec_table_refs; /* The count of how many times cleanup() was called with cleaned==false for the unit specifying the recursive CTE for which this object was created @@ -5165,7 +5170,8 @@ class select_union_recursive :public select_union select_union_recursive(THD *thd_arg): select_union(thd_arg), - incr_table(0), first_rec_table_to_update(0), cleanup_count(0) {}; + incr_table(0), first_rec_table_to_update(0), cleanup_count(0) + { incr_table_param.init(); }; int send_data(List &items); bool create_result_table(THD *thd, List *column_types, diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index a8bccf0c1dd..dd764dad7cf 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -1429,10 +1429,11 @@ void With_element::print(String *str, enum_query_type query_type) bool With_element::instantiate_tmp_tables() { - List_iterator_fast
li(rec_result->rec_tables); - TABLE *rec_table; - while ((rec_table= li++)) + List_iterator_fast li(rec_result->rec_table_refs); + TABLE_LIST *rec_tbl; + while ((rec_tbl= li++)) { + TABLE *rec_table= rec_tbl->table; if (!rec_table->is_created() && instantiate_tmp_table(rec_table, rec_table->s->key_info, diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 5379dd45bfb..33f323b86a0 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -677,7 +677,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) if (derived->is_with_table_recursive_reference()) { /* Here 'derived" is a secondary recursive table reference */ - unit->with_element->rec_result->rec_tables.push_back(derived->table); + unit->with_element->rec_result->rec_table_refs.push_back(derived); } } DBUG_ASSERT(derived->table || res); @@ -733,7 +733,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) derived->fill_me= FALSE; - if (!(derived->derived_result= new (thd->mem_root) select_union(thd))) + if ((!derived->is_with_table_recursive_reference() || + !derived->derived_result) && + !(derived->derived_result= new (thd->mem_root) select_union(thd))) DBUG_RETURN(TRUE); // out of memory lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; @@ -752,7 +754,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) Depending on the result field translation will or will not be created. */ - if (derived->init_derived(thd, FALSE)) + if (!derived->is_with_table_recursive_reference() && + derived->init_derived(thd, FALSE)) goto exit; /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8b4401b1009..d5e5a79eba2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11929,10 +11929,6 @@ void JOIN_TAB::cleanup() { DBUG_ENTER("JOIN_TAB::cleanup"); - if (tab_list && tab_list->is_with_table_recursive_reference() && - tab_list->with->is_cleaned()) - DBUG_VOID_RETURN; - DBUG_PRINT("enter", ("tab: %p table %s.%s", this, (table ? table->s->db.str : "?"), diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 7716f792fdc..7baedfb259c 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -211,7 +211,10 @@ select_union_recursive::create_result_table(THD *thd_arg, create_table, keep_row_order)) return true; - if (! (incr_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, + incr_table_param.init(); + incr_table_param.field_count= column_types->elements; + incr_table_param.bit_fields_as_long= bit_fields_as_long; + if (! (incr_table= create_tmp_table(thd_arg, &incr_table_param, *column_types, (ORDER*) 0, false, 1, options, HA_POS_ERROR, "", true, keep_row_order))) @@ -221,20 +224,6 @@ select_union_recursive::create_result_table(THD *thd_arg, for (uint i=0; i < table->s->fields; i++) incr_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); - TABLE *rec_table= 0; - if (! (rec_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, - (ORDER*) 0, false, 1, - options, HA_POS_ERROR, alias, - true, keep_row_order))) - return true; - - rec_table->keys_in_use_for_query.clear_all(); - for (uint i=0; i < table->s->fields; i++) - rec_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); - - if (rec_tables.push_back(rec_table)) - return true; - return false; } @@ -272,23 +261,25 @@ void select_union_recursive::cleanup() free_tmp_table(thd, incr_table); } - List_iterator
it(rec_tables); - TABLE *tab; - while ((tab= it++)) + List_iterator it(rec_table_refs); + TABLE_LIST *tbl; + while ((tbl= it++)) { + TABLE *tab= tbl->table; if (tab->is_created()) { tab->file->extra(HA_EXTRA_RESET_STATE); tab->file->ha_delete_all_rows(); } - /* + /* The table will be closed later in close_thread_tables(), because it might be used in the statements like ANALYZE WITH r AS (...) SELECT * from r - where r is defined through recursion. + where r is defined through recursion. */ tab->next= thd->rec_tables; thd->rec_tables= tab; + tbl->derived_result= 0; } } @@ -715,9 +706,29 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, goto err; if (!derived->table) { - derived->table= with_element->rec_result->rec_tables.head(); - if (derived->derived_result) - derived->derived_result->table= derived->table; + bool res= false; + + if ((!derived->is_with_table_recursive_reference() || + !derived->derived_result) && + !(derived->derived_result= new (thd->mem_root) select_union(thd))) + goto err; // out of memory + thd->create_tmp_table_for_derived= TRUE; + res= derived->derived_result->create_result_table(thd, + &types, + FALSE, + create_options, + derived->alias, + FALSE, FALSE); + thd->create_tmp_table_for_derived= FALSE; + if (res) + goto err; + derived->derived_result->set_unit(this); + derived->table= derived->derived_result->table; + if (derived->is_with_table_recursive_reference()) + { + /* Here 'derived" is the primary recursive table reference */ + derived->with->rec_result->rec_table_refs.push_back(derived); + } } with_element->mark_as_with_prepared_anchor(); is_rec_result_table_created= true; @@ -1272,11 +1283,11 @@ bool st_select_lex_unit::exec_recursive() TABLE *incr_table= with_element->rec_result->incr_table; st_select_lex *end= NULL; bool is_unrestricted= with_element->is_unrestricted(); - List_iterator_fast
li(with_element->rec_result->rec_tables); + List_iterator_fast li(with_element->rec_result->rec_table_refs); TMP_TABLE_PARAM *tmp_table_param= &with_element->rec_result->tmp_table_param; ha_rows examined_rows= 0; bool was_executed= executed; - TABLE *rec_table; + TABLE_LIST *rec_tbl; DBUG_ENTER("st_select_lex_unit::exec_recursive"); @@ -1335,8 +1346,9 @@ bool st_select_lex_unit::exec_recursive() else with_element->level++; - while ((rec_table= li++)) + while ((rec_tbl= li++)) { + TABLE *rec_table= rec_tbl->table; saved_error= incr_table->insert_all_rows_into_tmp_table(thd, rec_table, tmp_table_param, From 87fa6d2c5c74338bcba8254a663400b49840172e Mon Sep 17 00:00:00 2001 From: sjaakola Date: Wed, 2 Dec 2020 17:28:49 +0200 Subject: [PATCH 49/72] MDEV-24327 wsrep XID checkpointing order with log_slave_updates=OFF If log_slave_updates==OFF, wsrep applier threads used to be configured with option: thd->variables.option_bits&= ~(OPTION_BIN_LOG); (i.e. like sql_log_bin=ON). And this was regardless of log-bin configuration. With this, having configuration of: --log-bin && --log-slave-updates=OFF, local threads used binlogging, but applier threads did not. And further: local threads went through binlog group commit, while applier threads did direct commits. This resulted in situation, where applier threads entered earlier in wsrep XID checkpointing, and could sync their wsrep XID out of order. Later local thread commit would see that higher seqno was already checkpointed, and fire an assert because of this. As a fix, applier threads are now forced to enable binlogging regardless of log-slave-updates configuration. This PR comes with new mtr test: galera.MDEV-24327, which causes a scenario where applier transaction is applied and committed while earlier local transaction is parked before commit order monitor enter. A buggy mariadb versoin would fail for assertion because of wsrep XID checkpoint order violation. --- mysql-test/suite/galera/r/MDEV-24327.result | 35 +++++++++ mysql-test/suite/galera/t/MDEV-24327.cnf | 6 ++ mysql-test/suite/galera/t/MDEV-24327.test | 87 +++++++++++++++++++++ sql/wsrep_high_priority_service.cc | 11 +-- 4 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-24327.result create mode 100644 mysql-test/suite/galera/t/MDEV-24327.cnf create mode 100644 mysql-test/suite/galera/t/MDEV-24327.test diff --git a/mysql-test/suite/galera/r/MDEV-24327.result b/mysql-test/suite/galera/r/MDEV-24327.result new file mode 100644 index 00000000000..d309749efa4 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-24327.result @@ -0,0 +1,35 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +INSERT INTO t1 VALUES (1, 'f'); +INSERT INTO t1 VALUES (2, 'g'); +connection node_1; +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE t1 SET f2 = '1' WHERE f1 = 1; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET SESSION wsrep_sync_wait=0; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync'; +connection node_1; +COMMIT; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_2; +UPDATE t1 SET f2 = '2' WHERE f1 = 2; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +SELECT * FROM t1; +f1 f2 +1 1 +2 2 +"node 1 is complete now" +connection node_2; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MDEV-24327.cnf b/mysql-test/suite/galera/t/MDEV-24327.cnf new file mode 100644 index 00000000000..390a9aab0f4 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-24327.cnf @@ -0,0 +1,6 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +log-bin=mariadb-bin +log-slave-updates=OFF + diff --git a/mysql-test/suite/galera/t/MDEV-24327.test b/mysql-test/suite/galera/t/MDEV-24327.test new file mode 100644 index 00000000000..7aeffea11fa --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-24327.test @@ -0,0 +1,87 @@ +# +# MDEV-24327 wsrep XID checkpointing order violation with log_slave_updates=OFF +# +# Here we have configure two node cluster with --log-bin=ON and --log-slave_-updates=OFF +# +# a transaction in node executes so far that it has replicated and reached +# commit phase, We have sync point before entering commit order monitor and +# the transaction is parked there +# +# Then another transaction is executed in node 2, it replicates and commits in node 2 +# and is received and applied in node 1. After applying it will remain waiting for +# commit order monitor, as it has later seqno than the first transaction in node 1. +# +# control connection in node 1 waits to see the +# +# With the buggy version of MDEV-24327, the applier has however, already synced the +# wsrep XID checkpoint +# +# +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/galera_have_debug_sync.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +INSERT INTO t1 VALUES (1, 'f'); +INSERT INTO t1 VALUES (2, 'g'); + +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; + +UPDATE t1 SET f2 = '1' WHERE f1 = 1; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +SET SESSION wsrep_sync_wait=0; +--connection node_1a +--let $expected_wsrep_received = `SELECT VARIABLE_VALUE+1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received'` +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +# Block the commit, send the COMMIT and wait until it gets blocked + +--let $galera_sync_point = commit_monitor_master_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a + +# wait for the commit to block in sync point + +--let $galera_sync_point = commit_monitor_master_enter_sync +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +# +# replicate non conflicting transaction from node 2 +# it will get later seqno and should sync XID checkpoint after transaction in node 1 +# +--connection node_2 +UPDATE t1 SET f2 = '2' WHERE f1 = 2; + +# +# wait until update from node 2 has been committed +# if XID checkpointing order was violated, node 1 would crash for assert +# + +--connection node_1a +--let $wait_condition = SELECT VARIABLE_VALUE = $expected_wsrep_received FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received' +--source include/wait_condition.inc + +--let $galera_sync_point = commit_monitor_master_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--reap +SELECT * FROM t1; +--echo "node 1 is complete now" + + +--connection node_2 +DROP TABLE t1; diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index d52dcfdba3f..341c409b4f2 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -142,11 +142,12 @@ Wsrep_high_priority_service::Wsrep_high_priority_service(THD* thd) /* Disable general logging on applier threads */ thd->variables.option_bits |= OPTION_LOG_OFF; - /* Enable binlogging if opt_log_slave_updates is set */ - if (opt_log_slave_updates) - thd->variables.option_bits|= OPTION_BIN_LOG; - else - thd->variables.option_bits&= ~(OPTION_BIN_LOG); + + /* enable binlogging regardless of log_slave_updates setting + this is for ensuring that both local and applier transaction go through + same commit ordering algorithm in group commit control + */ + thd->variables.option_bits|= OPTION_BIN_LOG; thd->net.vio= 0; thd->reset_db(&db_str); From 41a961d85c9a083c816a9f628d97786964d208a5 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Wed, 2 Dec 2020 20:52:35 +0200 Subject: [PATCH 50/72] MDEV-24327 wsrep XID checkpointing order violation with cert failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handling of write sets, which fail in certification happens differently than with write sets which pass certification. When certification fails, the write set applying can be skipped and applier needs only to take care of wsrep XID checkpointing. With current implementation, this can rush ahead of wsrep XID checkpointing of successful write sets. The fix in this PR registers wsrep XID checkpointing of certification failure cases in group commit, which guarantees that XID ceckpointing order is synchronized with real committing transactions. Reviewed-by: Jan Lindström --- sql/wsrep_binlog.cc | 4 ++-- sql/wsrep_high_priority_service.cc | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index 787ebc042ae..d04d9989e99 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -358,7 +358,7 @@ void wsrep_register_for_group_commit(THD *thd) DBUG_VOID_RETURN; } - DBUG_ASSERT(thd->wsrep_trx().state() == wsrep::transaction::s_committing); + DBUG_ASSERT(thd->wsrep_trx().ordered()); wait_for_commit *wfc= thd->wait_for_commit_ptr= &thd->wsrep_wfc; @@ -381,7 +381,7 @@ void wsrep_register_for_group_commit(THD *thd) void wsrep_unregister_from_group_commit(THD *thd) { - DBUG_ASSERT(thd->wsrep_trx().state() == wsrep::transaction::s_ordered_commit); + DBUG_ASSERT(thd->wsrep_trx().ordered()); wait_for_commit *wfc= thd->wait_for_commit_ptr; if (wfc) diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index 341c409b4f2..1adbb312ac0 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -443,8 +443,24 @@ int Wsrep_high_priority_service::log_dummy_write_set(const wsrep::ws_handle& ws_ cs.before_rollback(); cs.after_rollback(); } + + if (!WSREP_EMULATE_BINLOG(m_thd)) + { + wsrep_register_for_group_commit(m_thd); + ret = ret || cs.provider().commit_order_leave(ws_handle, ws_meta, err); + m_thd->wait_for_prior_commit(); + } + wsrep_set_SE_checkpoint(ws_meta.gtid()); - ret= ret || cs.provider().commit_order_leave(ws_handle, ws_meta, err); + + if (!WSREP_EMULATE_BINLOG(m_thd)) + { + wsrep_unregister_from_group_commit(m_thd); + } + else + { + ret= ret || cs.provider().commit_order_leave(ws_handle, ws_meta, err); + } cs.after_applying(); } DBUG_RETURN(ret); From 2cb5fb6019f4ea10106d9059307b2dbf9b9605e8 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Wed, 2 Dec 2020 17:28:49 +0200 Subject: [PATCH 51/72] MDEV-24327 wsrep XID checkpointing order with log_slave_updates=OFF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If log_slave_updates==OFF, wsrep applier threads used to be configured with option: thd->variables.option_bits&= ~(OPTION_BIN_LOG); (i.e. like sql_log_bin=ON). And this was regardless of log-bin configuration. With this, having configuration of: --log-bin && --log-slave-updates=OFF, local threads used binlogging, but applier threads did not. And further: local threads went through binlog group commit, while applier threads did direct commits. This resulted in situation, where applier threads entered earlier in wsrep XID checkpointing, and could sync their wsrep XID out of order. Later local thread commit would see that higher seqno was already checkpointed, and fire an assert because of this. As a fix, applier threads are now forced to enable binlogging regardless of log-slave-updates configuration. This PR comes with new mtr test: galera.MDEV-24327, which causes a scenario where applier transaction is applied and committed while earlier local transaction is parked before commit order monitor enter. A buggy mariadb versoin would fail for assertion because of wsrep XID checkpoint order violation. Reviewed-by: Jan Lindström --- mysql-test/suite/galera/r/MDEV-24327.result | 33 ++++++++ mysql-test/suite/galera/t/MDEV-24327.cnf | 6 ++ mysql-test/suite/galera/t/MDEV-24327.test | 87 +++++++++++++++++++++ sql/wsrep_thd.cc | 11 +-- 4 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-24327.result create mode 100644 mysql-test/suite/galera/t/MDEV-24327.cnf create mode 100644 mysql-test/suite/galera/t/MDEV-24327.test diff --git a/mysql-test/suite/galera/r/MDEV-24327.result b/mysql-test/suite/galera/r/MDEV-24327.result new file mode 100644 index 00000000000..e7cd9d08f4b --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-24327.result @@ -0,0 +1,33 @@ +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +INSERT INTO t1 VALUES (1, 'f'); +INSERT INTO t1 VALUES (2, 'g'); +connection node_1; +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE t1 SET f2 = '1' WHERE f1 = 1; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET SESSION wsrep_sync_wait=0; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_enter_sync'; +connection node_1; +COMMIT; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_2; +UPDATE t1 SET f2 = '2' WHERE f1 = 2; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +SELECT * FROM t1; +f1 f2 +1 1 +2 2 +"node 1 is complete now" +connection node_2; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MDEV-24327.cnf b/mysql-test/suite/galera/t/MDEV-24327.cnf new file mode 100644 index 00000000000..390a9aab0f4 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-24327.cnf @@ -0,0 +1,6 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +log-bin=mariadb-bin +log-slave-updates=OFF + diff --git a/mysql-test/suite/galera/t/MDEV-24327.test b/mysql-test/suite/galera/t/MDEV-24327.test new file mode 100644 index 00000000000..fe3dbbe2870 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-24327.test @@ -0,0 +1,87 @@ +# +# MDEV-24327 wsrep XID checkpointing order violation with log_slave_updates=OFF +# +# Here we have configure two node cluster with --log-bin=ON and --log-slave_-updates=OFF +# +# a transaction in node executes so far that it has replicated and reached +# commit phase, We have sync point before entering commit order monitor and +# the transaction is parked there +# +# Then another transaction is executed in node 2, it replicates and commits in node 2 +# and is received and applied in node 1. After applying it will remain waiting for +# commit order monitor, as it has later seqno than the first transaction in node 1. +# +# control connection in node 1 waits to see the +# +# With the buggy version of MDEV-24327, the applier has however, already synced the +# wsrep XID checkpoint +# +# +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/galera_have_debug_sync.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +INSERT INTO t1 VALUES (1, 'f'); +INSERT INTO t1 VALUES (2, 'g'); + +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; + +UPDATE t1 SET f2 = '1' WHERE f1 = 1; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +SET SESSION wsrep_sync_wait=0; +--connection node_1a +--let $expected_wsrep_received = `SELECT VARIABLE_VALUE+1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received'` +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +# Block the commit, send the COMMIT and wait until it gets blocked + +--let $galera_sync_point = commit_monitor_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a + +# wait for the commit to block in sync point + +--let $galera_sync_point = commit_monitor_enter_sync +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +# +# replicate non conflicting transaction from node 2 +# it will get later seqno and should sync XID checkpoint after transaction in node 1 +# +--connection node_2 +UPDATE t1 SET f2 = '2' WHERE f1 = 2; + +# +# wait until update from node 2 has been committed +# if XID checkpointing order was violated, node 1 would crash for assert +# + +--connection node_1a +--let $wait_condition = SELECT VARIABLE_VALUE = $expected_wsrep_received FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received' +--source include/wait_condition.inc + +--let $galera_sync_point = commit_monitor_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--reap +SELECT * FROM t1; +--echo "node 1 is complete now" + + +--connection node_2 +DROP TABLE t1; diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 2396b8663df..1c43aeaaead 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -146,11 +146,12 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow) // Disable general logging on applier threads thd->variables.option_bits |= OPTION_LOG_OFF; - // Enable binlogging if opt_log_slave_updates is set - if (opt_log_slave_updates) - thd->variables.option_bits|= OPTION_BIN_LOG; - else - thd->variables.option_bits&= ~(OPTION_BIN_LOG); + + /* enable binlogging regardless of log_slave_updates setting + this is for ensuring that both local and applier transaction go through + same commit ordering algorithm in group commit control + */ + thd->variables.option_bits|= OPTION_BIN_LOG; if (!thd->wsrep_rgi) thd->wsrep_rgi= wsrep_relay_group_init(thd, "wsrep_relay"); From 25d6f634b89c4b1ad8ae721921b5ccf595073270 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 17 Dec 2020 10:09:16 -0800 Subject: [PATCH 52/72] MDEV-20751 Permission Issue With Nested CTEs Due to this bug the server reported bogus messages about lack of SELECT privileges for base tables used in the specifications of CTE tables. It happened only if such a CTE were referred to at least twice. For any non-recursive reference to CTE that is not primary the specification of the CTE is cloned. The function check_table_access() is called for such reference. The function checks privileges of the tables referenced in the specification. As no name resolution was performed for CTE references whose definitions occurred outside the specification before the call of check_table_access() that was supposed to check the access rights of the underlying tables these references were considered as references to base tables rather than references to CTEs. Yet for CTEs as well as for derived tables no privileges are needed and thus cannot be granted. The patch ensures proper name resolution of all references to CTEs before any acl checks. Approved by Oleksandr Byelkin --- .../r/cte_nonrecursive_not_embedded.result | 48 +++++++++++++++ .../t/cte_nonrecursive_not_embedded.test | 58 +++++++++++++++++++ sql/sql_cte.cc | 18 +++++- 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/cte_nonrecursive_not_embedded.result create mode 100644 mysql-test/t/cte_nonrecursive_not_embedded.test diff --git a/mysql-test/r/cte_nonrecursive_not_embedded.result b/mysql-test/r/cte_nonrecursive_not_embedded.result new file mode 100644 index 00000000000..c96a1ec2849 --- /dev/null +++ b/mysql-test/r/cte_nonrecursive_not_embedded.result @@ -0,0 +1,48 @@ +# +# MDEV-20751: query using many CTEs with grant_tables enabled +# +connection default; +CREATE DATABASE db; +USE db; +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (3), (7), (1); +CREATE TABLE t2 (a int) ENGINE=MYISAM; +INSERT INTO t2 VALUES (2), (8), (4); +CREATE USER 'u1'@'localhost'; +GRANT USAGE ON db.* TO 'u1'@'localhost'; +GRANT SELECT ON db.t1 TO 'u1'@'localhost'; +FLUSH PRIVILEGES; +connect u1,'localhost',u1,,; +connection u1; +USE db; +WITH +cte1 AS +(SELECT a FROM t1), +cte2 AS +(SELECT cte1.a FROM t1,cte1 WHERE cte1.a = t1.a), +cte3 AS +(SELECT cte2.a FROM t1,cte1,cte2 WHERE cte1.a = t1.a AND t1.a = cte2.a), +cte4 AS +(SELECT cte2.a FROM t1,cte2 WHERE cte2.a = t1.a) +SELECT * FROM cte4 as r; +a +3 +7 +1 +WITH +cte1 AS +(SELECT a FROM t2), +cte2 AS +(SELECT cte1.a FROM t2,cte1 WHERE cte1.a = t2.a), +cte3 AS +(SELECT cte2.a FROM t2,cte1,cte2 WHERE cte1.a = t2.a AND t2.a = cte2.a), +cte4 AS +(SELECT cte2.a FROM t2,cte2 WHERE cte2.a = t2.a) +SELECT * FROM cte4 as r; +ERROR 42000: SELECT command denied to user 'u1'@'localhost' for table 't2' +disconnect u1; +connection default; +DROP USER 'u1'@'localhost'; +DROP DATABASE db; +USE test; +# End of 10.2 tests diff --git a/mysql-test/t/cte_nonrecursive_not_embedded.test b/mysql-test/t/cte_nonrecursive_not_embedded.test new file mode 100644 index 00000000000..e80baeaf591 --- /dev/null +++ b/mysql-test/t/cte_nonrecursive_not_embedded.test @@ -0,0 +1,58 @@ +-- source include/not_embedded.inc + +--echo # +--echo # MDEV-20751: query using many CTEs with grant_tables enabled +--echo # + +--connection default + +CREATE DATABASE db; +USE db; + +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (3), (7), (1); +CREATE TABLE t2 (a int) ENGINE=MYISAM; +INSERT INTO t2 VALUES (2), (8), (4); + + +CREATE USER 'u1'@'localhost'; +GRANT USAGE ON db.* TO 'u1'@'localhost'; +GRANT SELECT ON db.t1 TO 'u1'@'localhost'; +FLUSH PRIVILEGES; + +--connect (u1,'localhost',u1,,) +--connection u1 +USE db; + +WITH +cte1 AS +(SELECT a FROM t1), +cte2 AS +(SELECT cte1.a FROM t1,cte1 WHERE cte1.a = t1.a), +cte3 AS +(SELECT cte2.a FROM t1,cte1,cte2 WHERE cte1.a = t1.a AND t1.a = cte2.a), +cte4 AS +(SELECT cte2.a FROM t1,cte2 WHERE cte2.a = t1.a) +SELECT * FROM cte4 as r; + +--error ER_TABLEACCESS_DENIED_ERROR +WITH +cte1 AS +(SELECT a FROM t2), +cte2 AS +(SELECT cte1.a FROM t2,cte1 WHERE cte1.a = t2.a), +cte3 AS +(SELECT cte2.a FROM t2,cte1,cte2 WHERE cte1.a = t2.a AND t2.a = cte2.a), +cte4 AS +(SELECT cte2.a FROM t2,cte2 WHERE cte2.a = t2.a) +SELECT * FROM cte4 as r; + +--disconnect u1 +--connection default + +DROP USER 'u1'@'localhost'; +DROP DATABASE db; + +USE test; + +--echo # End of 10.2 tests diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index dd764dad7cf..e07a525f691 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -864,8 +864,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, goto err; spec_tables_tail= tbl; } - if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE)) - goto err; if (spec_tables) { if (with_table->next_global) @@ -891,6 +889,22 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, with_select)); if (check_dependencies_in_with_clauses(lex->with_clauses_list)) res= NULL; + /* + Resolve references to CTE from the spec_tables list that has not + been resolved yet. + */ + for (TABLE_LIST *tbl= spec_tables; + tbl; + tbl= tbl->next_global) + { + if (!tbl->with) + tbl->with= with_select->find_table_def_in_with_clauses(tbl); + if (tbl == spec_tables_tail) + break; + } + if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE)) + goto err; + lex->sphead= NULL; // in order not to delete lex->sphead lex_end(lex); err: From 83d2e0841ee30727c609f23957cc592399a3aca4 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Thu, 17 Dec 2020 02:41:17 +1000 Subject: [PATCH 53/72] MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB row_upd_clust_step() calls row_upd_del_mark_clust_rec() which would allocate some memory in row_ins_foreign_fill_virtual(). Then, row_upd_store_row() would access the allocated memory, but only after potentially freeing that memory by invoking mem_heap_empty(), leading to ASAN heap-use-after-free diagnostics. row_ins_foreign_fill_virtual(): Use a more appropriate memory heap with a longer lifetime. --- .../suite/gcol/r/innodb_virtual_fk.result | 28 ++++++++++++++ .../suite/gcol/t/innodb_virtual_fk.test | 37 +++++++++++++++++++ storage/innobase/row/row0ins.cc | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result index 50685e04a69..68601823e31 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result @@ -790,3 +790,31 @@ t1 CREATE TABLE `t1` ( ALTER TABLE t1 DROP INDEX f1; ALTER TABLE t1 DROP f3; DROP TABLE t1; +# +# MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB +# +CREATE TABLE emails ( +id int, +PRIMARY KEY (id) +) ENGINE=InnoDB; +CREATE TABLE email_stats ( +id int, +email_id int, +date_sent char(4), +generated_email_id int as (email_id), +PRIMARY KEY (id), +KEY mautic_generated_sent_date_email_id (generated_email_id), +FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL +) ENGINE=InnoDB; +CREATE TABLE emails_metadata ( +email_id int, +PRIMARY KEY (email_id), +CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE +) ENGINE=InnoDB; +INSERT INTO emails VALUES (1); +INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); +INSERT INTO emails_metadata VALUES (1); +DELETE FROM emails; +DROP TABLE email_stats; +DROP TABLE emails_metadata; +DROP TABLE emails; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test index 23d3ee97290..da20612f0a1 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test @@ -649,3 +649,40 @@ SHOW CREATE TABLE t1; ALTER TABLE t1 DROP INDEX f1; ALTER TABLE t1 DROP f3; DROP TABLE t1; + +--echo # +--echo # MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB +--echo # + +CREATE TABLE emails ( + id int, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE email_stats ( + id int, + email_id int, + date_sent char(4), + generated_email_id int as (email_id), + PRIMARY KEY (id), + KEY mautic_generated_sent_date_email_id (generated_email_id), + FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL +) ENGINE=InnoDB; + + +CREATE TABLE emails_metadata ( + email_id int, + PRIMARY KEY (email_id), + CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE +) ENGINE=InnoDB; + + +INSERT INTO emails VALUES (1); +INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); +INSERT INTO emails_metadata VALUES (1); + +DELETE FROM emails; + +DROP TABLE email_stats; +DROP TABLE emails_metadata; +DROP TABLE emails; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index ca04be71953..635e7f659eb 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -931,7 +931,7 @@ row_ins_foreign_fill_virtual( update->old_vrow = row_build( ROW_COPY_DATA, index, rec, offsets, index->table, NULL, NULL, - &ext, cascade->heap); + &ext, update->heap); n_diff = update->n_fields; if (index->table->vc_templ == NULL) { From 4e43e2f92d1b418dcc84ab8ab085ef1b9b1a066b Mon Sep 17 00:00:00 2001 From: Alice Sherepa Date: Thu, 3 Dec 2020 15:30:35 +0100 Subject: [PATCH 54/72] MDEV-22008 rpl.rpl_semi_sync fails in bb, MDEV-24418 reenable binlog_truncate_innodb and binlog_spurious_ddl_errors, rpl_parallel_retry fails in bb --- mysql-test/extra/rpl_tests/rpl_semi_sync.inc | 72 +++---- mysql-test/suite/binlog/disabled.def | 2 - .../r/binlog_spurious_ddl_errors.result | 7 +- .../binlog/r/binlog_truncate_innodb.result | 185 +++++++++++------- .../t/binlog_spurious_ddl_errors-master.opt | 1 - .../binlog/t/binlog_spurious_ddl_errors.test | 1 - .../t/binlog_truncate_innodb-master.opt | 1 - .../binlog/t/binlog_truncate_innodb.test | 3 +- .../binlog_encryption/rpl_semi_sync.result | 22 +-- mysql-test/suite/rpl/r/rpl_semi_sync.result | 22 +-- .../rpl/r/rpl_semi_sync_after_sync.result | 22 +-- .../rpl/r/rpl_semi_sync_after_sync_row.result | 22 +-- .../suite/rpl/t/rpl_parallel_retry.test | 3 + 13 files changed, 157 insertions(+), 206 deletions(-) delete mode 100644 mysql-test/suite/binlog/t/binlog_spurious_ddl_errors-master.opt delete mode 100644 mysql-test/suite/binlog/t/binlog_truncate_innodb-master.opt diff --git a/mysql-test/extra/rpl_tests/rpl_semi_sync.inc b/mysql-test/extra/rpl_tests/rpl_semi_sync.inc index 12053c54f4e..85a83167d42 100644 --- a/mysql-test/extra/rpl_tests/rpl_semi_sync.inc +++ b/mysql-test/extra/rpl_tests/rpl_semi_sync.inc @@ -10,7 +10,6 @@ source include/have_innodb.inc; source include/master-slave.inc; let $engine_type= InnoDB; -#let $engine_type= MyISAM; # Suppress warnings that might be generated during the test connection master; @@ -94,7 +93,6 @@ enable_query_log; echo [ status of semi-sync on master should be OFF ]; show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_status'; ---replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; # reset master to make sure the following test will start with a clean environment @@ -201,16 +199,23 @@ connection slave; source include/stop_slave.inc; connection master; +--source include/kill_binlog_dump_threads.inc set global rpl_semi_sync_master_timeout= 5000; # The first semi-sync check should be on because after slave stop, # there are no transactions on the master. echo [ master status should be ON ]; -show status like 'Rpl_semi_sync_master_status'; + +let $status_var= Rpl_semi_sync_master_status; +let $status_var_value= ON; +source include/wait_for_status_var.inc; + +let $status_var= Rpl_semi_sync_master_clients; +let $status_var_value= 0; +source include/wait_for_status_var.inc; + show status like 'Rpl_semi_sync_master_no_tx'; ---replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; -show status like 'Rpl_semi_sync_master_clients'; echo [ semi-sync replication of these transactions will fail ]; insert into t1 values (500); @@ -225,7 +230,6 @@ source include/wait_for_status_var.inc; echo [ master status should be OFF ]; show status like 'Rpl_semi_sync_master_status'; show status like 'Rpl_semi_sync_master_no_tx'; ---replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; # Semi-sync status on master is now OFF, so all these transactions @@ -246,7 +250,6 @@ insert into t1 values (100); echo [ master status should be OFF ]; show status like 'Rpl_semi_sync_master_status'; show status like 'Rpl_semi_sync_master_no_tx'; ---replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; --echo # @@ -274,9 +277,11 @@ connection master; # The master semi-sync status should be on again after slave catches up. echo [ master status should be ON again after slave catches up ]; -show status like 'Rpl_semi_sync_master_status'; + +let $status_var= Rpl_semi_sync_master_status; +let $status_var_value= ON; +source include/wait_for_status_var.inc; show status like 'Rpl_semi_sync_master_no_tx'; ---replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; show status like 'Rpl_semi_sync_master_clients'; @@ -332,11 +337,7 @@ replace_result $engine_type ENGINE_TYPE; eval create table t1 (a int) engine = $engine_type; drop table t1; -##show status like 'Rpl_semi_sync_master_status'; - sync_slave_with_master; ---replace_column 2 # -show status like 'Rpl_relay%'; echo [ test reset master ]; connection master; @@ -353,19 +354,7 @@ source include/stop_slave.inc; reset slave; # Kill the dump thread on master for previous slave connection and -# wait for it to exit -connection master; -let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; -if ($_tid) -{ - --replace_result $_tid _tid - eval kill query $_tid; - - # After dump thread exit, Rpl_semi_sync_master_clients will be 0 - let $status_var= Rpl_semi_sync_master_clients; - let $status_var_value= 0; - source include/wait_for_status_var.inc; -} +--source include/kill_binlog_dump_threads.inc connection slave; source include/start_slave.inc; @@ -404,17 +393,7 @@ connection master; reset master; # Kill the dump thread on master for previous slave connection and wait for it to exit -let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; -if ($_tid) -{ - --replace_result $_tid _tid - eval kill query $_tid; - - # After dump thread exit, Rpl_semi_sync_master_clients will be 0 - let $status_var= Rpl_semi_sync_master_clients; - let $status_var_value= 0; - source include/wait_for_status_var.inc; -} +--source include/kill_binlog_dump_threads.inc # Do not binlog the following statement because it will generate # different events for ROW and STATEMENT format @@ -459,21 +438,16 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; connection master; # Kill the dump thread on master for previous slave connection and wait for it to exit -let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; -if ($_tid) -{ - --replace_result $_tid _tid - eval kill query $_tid; - - # After dump thread exit, Rpl_semi_sync_master_clients will be 0 - let $status_var= Rpl_semi_sync_master_clients; - let $status_var_value= 0; - source include/wait_for_status_var.inc; -} +--source include/kill_binlog_dump_threads.inc echo [ Semi-sync status on master should be ON ]; -show status like 'Rpl_semi_sync_master_clients'; +let $status_var= Rpl_semi_sync_master_clients; +let $status_var_value= 0; +source include/wait_for_status_var.inc; show status like 'Rpl_semi_sync_master_status'; +let $status_var= Rpl_semi_sync_master_status; +let $status_var_value= ON; +source include/wait_for_status_var.inc; set global rpl_semi_sync_master_enabled= 0; connection slave; diff --git a/mysql-test/suite/binlog/disabled.def b/mysql-test/suite/binlog/disabled.def index 424e5549541..888298bbb09 100644 --- a/mysql-test/suite/binlog/disabled.def +++ b/mysql-test/suite/binlog/disabled.def @@ -9,5 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -binlog_truncate_innodb : BUG#11764459 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed -binlog_spurious_ddl_errors : BUG#11761680 2013-01-18 astha Fixed on mysql-5.6 and trunk diff --git a/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result b/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result index 1a81eee1a58..798bd8ab853 100644 --- a/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result +++ b/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result @@ -1,5 +1,5 @@ SET @old_binlog_format= @@global.binlog_format; -INSTALL PLUGIN example SONAME 'ha_example.so'; +INSTALL PLUGIN example SONAME 'ha_example'; ################################################################################ # Verifies if ER_BINLOG_STMT_MODE_AND_ROW_ENGINE happens by setting the binlog # format to STATEMENT and the transaction isolation level to READ COMMITTED as @@ -18,7 +18,7 @@ ALTER TABLE t_row ADD COLUMN b INT; CREATE TRIGGER trig_row BEFORE INSERT ON t_row FOR EACH ROW INSERT INTO t_stmt VALUES (1); CREATE INDEX i ON t_row(a); CREATE TABLE t_row_new ENGINE = InnoDB SELECT * FROM t_row; -ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED. +ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. DROP TABLE t_row; @@ -36,12 +36,11 @@ DROP TABLE t_row; SET binlog_format = ROW; CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE; ALTER TABLE t_stmt ADD COLUMN b INT; -ERROR 42000: This version of MySQL doesn't yet support 'ALTER TABLE' CREATE TRIGGER trig_stmt BEFORE INSERT ON t_stmt FOR EACH ROW INSERT INTO t_stmt VALUES (1); CREATE INDEX i ON t_stmt(a); ERROR 42000: Too many key parts specified; max 0 parts allowed CREATE TABLE t_stmt_new ENGINE = EXAMPLE SELECT * FROM t_stmt; -ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging. +ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging DROP TABLE t_stmt; diff --git a/mysql-test/suite/binlog/r/binlog_truncate_innodb.result b/mysql-test/suite/binlog/r/binlog_truncate_innodb.result index 8beeeb1a428..87ce8e30dee 100644 --- a/mysql-test/suite/binlog/r/binlog_truncate_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_truncate_innodb.result @@ -7,9 +7,11 @@ INSERT INTO t2 VALUES (1),(2),(3); **** Truncate of empty table shall be logged TRUNCATE TABLE t1; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -18,18 +20,17 @@ DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -37,16 +38,20 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; # Even though the isolation level might be permissive, truncate # table follows a stricter isolation as its locking is based on @@ -59,9 +64,11 @@ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -71,18 +78,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -90,16 +96,20 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; @@ -109,9 +119,11 @@ SET TRANSACTION ISOLATION LEVEL READ COMMITTED; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -121,18 +133,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -140,16 +151,20 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; @@ -159,9 +174,11 @@ SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -171,18 +188,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -190,16 +206,20 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; @@ -209,9 +229,11 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -221,18 +243,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -240,16 +261,20 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Annotate_rows # # INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; SET BINLOG_FORMAT=STATEMENT; RESET MASTER; @@ -261,9 +286,11 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -273,18 +300,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -292,14 +318,16 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; # Truncate is not supported for SBR if the isolation level is # READ UNCOMMITTED or READ COMMITTED. These specific isolation @@ -312,9 +340,11 @@ SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -324,18 +354,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -343,14 +372,16 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; @@ -360,9 +391,11 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; TRUNCATE TABLE t1; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; TRUNCATE TABLE t2; -show binlog events from ; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; # @@ -372,18 +405,17 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1),(2); SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -# Connection: default BEGIN; INSERT INTO t2 SELECT * FROM t1; -# Connection: truncate +connect truncate,localhost,root,,; TRUNCATE TABLE t1; -# Connection: default +connection default; INSERT INTO t2 SELECT * FROM t1; SELECT COUNT(*) FROM t2; COUNT(*) 4 COMMIT; -# Connection: truncate +connection truncate; # Reaping TRUNCATE TABLE SELECT COUNT(*) FROM t1; COUNT(*) @@ -391,13 +423,16 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 4 -# Connection: default -show binlog events from ; +connection default; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +disconnect truncate; DROP TABLE t1,t2; -SET BINLOG_FORMAT=@old_binlog_format; +SET @@global.binlog_format = @old_binlog_format; +SET @@session.binlog_format = @old_binlog_format; diff --git a/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors-master.opt b/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors-master.opt deleted file mode 100644 index 627becdbfb5..00000000000 --- a/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors-master.opt +++ /dev/null @@ -1 +0,0 @@ ---innodb diff --git a/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test b/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test index e64e7838a31..29a860764a9 100644 --- a/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test +++ b/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test @@ -71,7 +71,6 @@ DROP TABLE t_row; SET binlog_format = ROW; CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE; ---error ER_NOT_SUPPORTED_YET ALTER TABLE t_stmt ADD COLUMN b INT; CREATE TRIGGER trig_stmt BEFORE INSERT ON t_stmt FOR EACH ROW INSERT INTO t_stmt VALUES (1); diff --git a/mysql-test/suite/binlog/t/binlog_truncate_innodb-master.opt b/mysql-test/suite/binlog/t/binlog_truncate_innodb-master.opt deleted file mode 100644 index 69cc489a969..00000000000 --- a/mysql-test/suite/binlog/t/binlog_truncate_innodb-master.opt +++ /dev/null @@ -1 +0,0 @@ ---loose-innodb \ No newline at end of file diff --git a/mysql-test/suite/binlog/t/binlog_truncate_innodb.test b/mysql-test/suite/binlog/t/binlog_truncate_innodb.test index 56dd5bda505..9e331738ab5 100644 --- a/mysql-test/suite/binlog/t/binlog_truncate_innodb.test +++ b/mysql-test/suite/binlog/t/binlog_truncate_innodb.test @@ -41,4 +41,5 @@ source extra/binlog_tests/binlog_truncate.test; let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; source extra/binlog_tests/binlog_truncate.test; -SET BINLOG_FORMAT=@old_binlog_format; +SET @@global.binlog_format = @old_binlog_format; +SET @@session.binlog_format = @old_binlog_format; \ No newline at end of file diff --git a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result index 6d574681d73..ad6a89648ad 100644 --- a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result +++ b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result @@ -163,20 +163,15 @@ connection slave; connection slave; include/stop_slave.inc connection master; +include/kill_binlog_dump_threads.inc set global rpl_semi_sync_master_timeout= 5000; [ master status should be ON ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 0 show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 14 -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 1 [ semi-sync replication of these transactions will fail ] insert into t1 values (500); [ master status should be OFF ] @@ -234,9 +229,6 @@ max(a) 500 connection master; [ master status should be ON again after slave catches up ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 12 @@ -303,8 +295,6 @@ connection master; create table t1 (a int) engine = ENGINE_TYPE; drop table t1; connection slave; -show status like 'Rpl_relay%'; -Variable_name Value [ test reset master ] connection master; reset master; @@ -320,8 +310,7 @@ Rpl_semi_sync_master_yes_tx 0 connection slave; include/stop_slave.inc reset slave; -connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; @@ -353,7 +342,7 @@ include/stop_slave.inc reset slave; connection master; reset master; -kill query _tid; +include/kill_binlog_dump_threads.inc set sql_log_bin=0; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; flush privileges; @@ -404,11 +393,8 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc [ Semi-sync status on master should be ON ] -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 0 show status like 'Rpl_semi_sync_master_status'; Variable_name Value Rpl_semi_sync_master_status ON diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync.result index 6d574681d73..ad6a89648ad 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result @@ -163,20 +163,15 @@ connection slave; connection slave; include/stop_slave.inc connection master; +include/kill_binlog_dump_threads.inc set global rpl_semi_sync_master_timeout= 5000; [ master status should be ON ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 0 show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 14 -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 1 [ semi-sync replication of these transactions will fail ] insert into t1 values (500); [ master status should be OFF ] @@ -234,9 +229,6 @@ max(a) 500 connection master; [ master status should be ON again after slave catches up ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 12 @@ -303,8 +295,6 @@ connection master; create table t1 (a int) engine = ENGINE_TYPE; drop table t1; connection slave; -show status like 'Rpl_relay%'; -Variable_name Value [ test reset master ] connection master; reset master; @@ -320,8 +310,7 @@ Rpl_semi_sync_master_yes_tx 0 connection slave; include/stop_slave.inc reset slave; -connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; @@ -353,7 +342,7 @@ include/stop_slave.inc reset slave; connection master; reset master; -kill query _tid; +include/kill_binlog_dump_threads.inc set sql_log_bin=0; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; flush privileges; @@ -404,11 +393,8 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc [ Semi-sync status on master should be ON ] -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 0 show status like 'Rpl_semi_sync_master_status'; Variable_name Value Rpl_semi_sync_master_status ON diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result index 927113726fa..11affc4d803 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result @@ -164,20 +164,15 @@ connection slave; connection slave; include/stop_slave.inc connection master; +include/kill_binlog_dump_threads.inc set global rpl_semi_sync_master_timeout= 5000; [ master status should be ON ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 0 show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 16 -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 1 [ semi-sync replication of these transactions will fail ] insert into t1 values (500); [ master status should be OFF ] @@ -235,9 +230,6 @@ max(a) 500 connection master; [ master status should be ON again after slave catches up ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 12 @@ -304,8 +296,6 @@ connection master; create table t1 (a int) engine = ENGINE_TYPE; drop table t1; connection slave; -show status like 'Rpl_relay%'; -Variable_name Value [ test reset master ] connection master; reset master; @@ -321,8 +311,7 @@ Rpl_semi_sync_master_yes_tx 0 connection slave; include/stop_slave.inc reset slave; -connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; @@ -354,7 +343,7 @@ include/stop_slave.inc reset slave; connection master; reset master; -kill query _tid; +include/kill_binlog_dump_threads.inc set sql_log_bin=0; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; flush privileges; @@ -405,11 +394,8 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc [ Semi-sync status on master should be ON ] -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 0 show status like 'Rpl_semi_sync_master_status'; Variable_name Value Rpl_semi_sync_master_status ON diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result index 30280551ce2..1a550be05a7 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result @@ -164,20 +164,15 @@ connection slave; connection slave; include/stop_slave.inc connection master; +include/kill_binlog_dump_threads.inc set global rpl_semi_sync_master_timeout= 5000; [ master status should be ON ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 0 show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 14 -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 1 [ semi-sync replication of these transactions will fail ] insert into t1 values (500); [ master status should be OFF ] @@ -235,9 +230,6 @@ max(a) 500 connection master; [ master status should be ON again after slave catches up ] -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status ON show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value Rpl_semi_sync_master_no_tx 12 @@ -304,8 +296,6 @@ connection master; create table t1 (a int) engine = ENGINE_TYPE; drop table t1; connection slave; -show status like 'Rpl_relay%'; -Variable_name Value [ test reset master ] connection master; reset master; @@ -321,8 +311,7 @@ Rpl_semi_sync_master_yes_tx 0 connection slave; include/stop_slave.inc reset slave; -connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; @@ -354,7 +343,7 @@ include/stop_slave.inc reset slave; connection master; reset master; -kill query _tid; +include/kill_binlog_dump_threads.inc set sql_log_bin=0; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; flush privileges; @@ -405,11 +394,8 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF connection master; -kill query _tid; +include/kill_binlog_dump_threads.inc [ Semi-sync status on master should be ON ] -show status like 'Rpl_semi_sync_master_clients'; -Variable_name Value -Rpl_semi_sync_master_clients 0 show status like 'Rpl_semi_sync_master_status'; Variable_name Value Rpl_semi_sync_master_status ON diff --git a/mysql-test/suite/rpl/t/rpl_parallel_retry.test b/mysql-test/suite/rpl/t/rpl_parallel_retry.test index 96863f9021d..0140784c8b9 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_retry.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_retry.test @@ -436,6 +436,9 @@ SET @@DEBUG_SYNC='now SIGNAL proceed_by_1000'; --connection spoiler_21 ROLLBACK; +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE '%debug sync point%'; +--source include/wait_condition.inc + --echo # Release the 2nd worker to proceed --connection spoiler_22 ROLLBACK; From d1e9a4c15c7ea4121408c21e02a0006a19689508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 19 Dec 2020 09:41:14 +0200 Subject: [PATCH 55/72] MDEV-23065 : Crash after setting wsrep_on to ON dynamically and reconnect At end_connection make sure we have wsrep before trying to free connection assigned to it. --- mysql-test/suite/galera/r/galera#500.result | 2 ++ mysql-test/suite/galera/t/galera#500.test | 7 +++++++ sql/sql_connect.cc | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/r/galera#500.result b/mysql-test/suite/galera/r/galera#500.result index 7ba02c56053..2e3f659bd79 100644 --- a/mysql-test/suite/galera/r/galera#500.result +++ b/mysql-test/suite/galera/r/galera#500.result @@ -1,3 +1,5 @@ +connection node_1; +connection node_2; connection node_2; SET SESSION wsrep_sync_wait = 0; SET GLOBAL wsrep_provider_options="gmcast.isolate=2"; diff --git a/mysql-test/suite/galera/t/galera#500.test b/mysql-test/suite/galera/t/galera#500.test index 3c8490b6907..471620b32c1 100644 --- a/mysql-test/suite/galera/t/galera#500.test +++ b/mysql-test/suite/galera/t/galera#500.test @@ -8,6 +8,11 @@ --source include/galera_cluster.inc --source include/galera_have_debug_sync.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + # Force node_2 gcomm background thread to terminate via exception. --connection node_2 --let $wsrep_cluster_address = `SELECT @@wsrep_cluster_address` @@ -36,3 +41,5 @@ SET SESSION wsrep_on=0; --connection node_2 CALL mtr.add_suppression("WSREP: exception from gcomm, backend must be restarted: Gcomm backend termination was requested by setting gmcast.isolate=2."); + +--source include/auto_increment_offset_restore.inc diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index b2900a20b28..aa7a877ed20 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1112,7 +1112,7 @@ void end_connection(THD *thd) { NET *net= &thd->net; #ifdef WITH_WSREP - if (WSREP(thd)) + if (WSREP(thd) && wsrep) { wsrep_status_t rcode= wsrep->free_connection(wsrep, thd->thread_id); if (rcode) { From 5785de72ac85ba37eda837c691aaf9a9195ba45d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 16 Dec 2020 19:35:24 +0100 Subject: [PATCH 56/72] Item_func_like calls escape_item->fix_fields() twice this happens if Item_func_like is copied (get_copy()). after one copy gets fixed, the other tries to fix escape item again. --- mysql-test/r/func_like.result | 5 +++++ mysql-test/t/func_like.test | 10 +++++++++- sql/item_cmpfunc.cc | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index 0ba8e41f164..ee8f9734754 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -289,3 +289,8 @@ a b c d 3 f_ 1 0 1 3 f\_ 0 1 0 drop table t1; +create table t1 (f int); +insert t1 values (1),(2); +select 1 from (select distinct * from t1) as x where f < (select 1 like 2 escape (3=1)); +1 +drop table t1; diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 5026bb76aa3..bc0000046ef 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -187,7 +187,7 @@ DROP TABLE t1; --echo # # -# Item_func_line::print() +# Item_func_like::print() # create view v1 as select 'foo!' like 'foo!!', 'foo!' like 'foo!!' escape '!'; show create view v1; @@ -207,3 +207,11 @@ insert t1 (a) values ('3 f_'), ('3 f\_'); set sql_mode=default; select * from t1; drop table t1; + +# +# Item_func_like::fix_fields() +# +create table t1 (f int); +insert t1 values (1),(2); +select 1 from (select distinct * from t1) as x where f < (select 1 like 2 escape (3=1)); +drop table t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2a0972216f8..d0941ef58c2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5413,7 +5413,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); if (Item_bool_func2::fix_fields(thd, ref) || - escape_item->fix_fields(thd, &escape_item) || + (!escape_item->fixed && escape_item->fix_fields(thd, &escape_item)) || fix_escape_item(thd, escape_item, &cmp_value1, escape_used_in_parsing, cmp_collation.collation, &escape)) return TRUE; From a587ded283d8abd1f20258b283911abe759f5f64 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 14 Dec 2020 18:25:08 +0100 Subject: [PATCH 57/72] MDEV-24346 valgrind error in main.precedence in queries like create view v1 as select 2 like 1 escape (3 in (select 0 union select 1)); select 2 union select * from v1; Item_func_like::escape was left uninitialized, because Item_in_optimizer is const_during_execution() but not actually const_item() during execution. It's not, because const subquery evaluation was disabled for derived. Practically it only needs to be disabled for multi-update that runs fix_fields() before all tables are locked. --- mysql-test/suite/innodb/r/innodb_multi_update.result | 1 + mysql-test/suite/innodb/t/innodb_multi_update.test | 1 + sql/item_cmpfunc.cc | 6 +++++- sql/sql_derived.cc | 2 -- sql/sql_update.cc | 7 +++++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_multi_update.result b/mysql-test/suite/innodb/r/innodb_multi_update.result index 64f9ebc2fc2..93bd4e6716c 100644 --- a/mysql-test/suite/innodb/r/innodb_multi_update.result +++ b/mysql-test/suite/innodb/r/innodb_multi_update.result @@ -81,4 +81,5 @@ CREATE TABLE t1(f1 INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; ERROR 21000: Operand should contain 1 column(s) +UPDATE (SELECT ((SELECT 1 FROM t1),1) = (1,1) FROM t1 WHERE (SELECT 1 FROM t1)) x, t1 AS d SET d.f1 = 1; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_multi_update.test b/mysql-test/suite/innodb/t/innodb_multi_update.test index 8d5283a9ed5..74a7aea7d13 100644 --- a/mysql-test/suite/innodb/t/innodb_multi_update.test +++ b/mysql-test/suite/innodb/t/innodb_multi_update.test @@ -35,4 +35,5 @@ CREATE TABLE t1(f1 INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); --error ER_OPERAND_COLUMNS UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +UPDATE (SELECT ((SELECT 1 FROM t1),1) = (1,1) FROM t1 WHERE (SELECT 1 FROM t1)) x, t1 AS d SET d.f1 = 1; DROP TABLE t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d0941ef58c2..e0dad886a06 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5261,6 +5261,7 @@ void Item_func_like::print(String *str, enum_query_type query_type) longlong Item_func_like::val_int() { DBUG_ASSERT(fixed == 1); + DBUG_ASSERT(escape != -1); String* res= args[0]->val_str(&cmp_value1); if (args[0]->null_value) { @@ -5352,10 +5353,13 @@ bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str, my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE"); return TRUE; } - + + IF_DBUG(*escape= -1,); + if (escape_item->const_item()) { /* If we are on execution stage */ + /* XXX is it safe to evaluate is_expensive() items here? */ String *escape_str= escape_item->val_str(tmp_str); if (escape_str) { diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 33f323b86a0..be5905da683 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -738,14 +738,12 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) !(derived->derived_result= new (thd->mem_root) select_union(thd))) DBUG_RETURN(TRUE); // out of memory - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; // st_select_lex_unit::prepare correctly work for single select if ((res= unit->prepare(thd, derived->derived_result, 0))) goto exit; if (derived->with && (res= derived->with->rename_columns_of_derived_unit(thd, unit))) goto exit; - lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; if ((res= check_duplicate_names(thd, unit->types, 0))) goto exit; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 5e40cd242a4..7454d16d55d 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1534,7 +1534,11 @@ int mysql_multi_update_prepare(THD *thd) During prepare phase acquire only S metadata locks instead of SW locks to keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE and global read lock. + + Don't evaluate any subqueries even if constant, because + tables aren't locked yet. */ + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI) { if (open_tables(thd, &table_list, &table_count, @@ -1557,6 +1561,9 @@ int mysql_multi_update_prepare(THD *thd) { DBUG_RETURN(TRUE); } + + lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; + (void) read_statistics_for_tables_if_needed(thd, table_list); /* @todo: downgrade the metadata locks here. */ From 59211ab7b9fb3c106e805bebd393731f42f95abe Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 15 Dec 2020 00:16:21 +0100 Subject: [PATCH 58/72] MDEV-24346 valgrind error in main.precedence Part II. It's still possible to bypass Item_func_like::escape initialization in Item_func_like::fix_fields(). This requires ESCAPE argument being a cacheable subquery that uses tables and is inside a derived table which is used in multi-update. Instead of implementing a complex or expensive fix for this particular ridiculously artificial case, let's simply disallow it. --- mysql-test/r/func_like.result | 8 ++++++++ mysql-test/t/func_like.test | 10 ++++++++++ sql/item_cmpfunc.cc | 13 ++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index ee8f9734754..dcbcd2591ac 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -294,3 +294,11 @@ insert t1 values (1),(2); select 1 from (select distinct * from t1) as x where f < (select 1 like 2 escape (3=1)); 1 drop table t1; +create table t1(f1 int); +insert into t1 values(1); +update (select 1 like 2 escape (1 in (select 1 from t1))) x, t1 as d set d.f1 = 1; +ERROR HY000: Incorrect arguments to ESCAPE +select * from (select 1 like 2 escape (1 in (select 1 from t1))) x; +1 like 2 escape (1 in (select 1 from t1)) +0 +drop table t1; diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index bc0000046ef..465d1df1380 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -215,3 +215,13 @@ create table t1 (f int); insert t1 values (1),(2); select 1 from (select distinct * from t1) as x where f < (select 1 like 2 escape (3=1)); drop table t1; + +# +# Item_func_like::fix_fields, ESCAPE, const_item() +# +create table t1(f1 int); +insert into t1 values(1); +--error ER_WRONG_ARGUMENTS +update (select 1 like 2 escape (1 in (select 1 from t1))) x, t1 as d set d.f1 = 1; +select * from (select 1 like 2 escape (1 in (select 1 from t1))) x; +drop table t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e0dad886a06..bfd7f3dbd1b 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5348,7 +5348,18 @@ bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str, bool escape_used_in_parsing, CHARSET_INFO *cmp_cs, int *escape) { - if (!escape_item->const_during_execution()) + /* + ESCAPE clause accepts only constant arguments and Item_param. + + Subqueries during context_analysis_only might decide they're + const_during_execution, but not quite const yet, not evaluate-able. + This is fine, as most of context_analysis_only modes will never + reach val_int(), so we won't need the value. + CONTEXT_ANALYSIS_ONLY_DERIVED being a notable exception here. + */ + if (!escape_item->const_during_execution() || + (!escape_item->const_item() && + !(thd->lex->context_analysis_only & ~CONTEXT_ANALYSIS_ONLY_DERIVED))) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE"); return TRUE; From 6f40d5c8d6bf8742b2450410fc024caf3ac114b4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 16 Dec 2020 20:12:04 +0100 Subject: [PATCH 59/72] Item_func_like::walk() was ignoring escape_item in particular, it caused escape_item->is_expensive() property to be lost instead of being properly propagated up. --- mysql-test/r/func_like.result | 5 +++++ mysql-test/t/func_like.test | 9 +++++++++ sql/item_cmpfunc.h | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index dcbcd2591ac..5bcd98ca238 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -302,3 +302,8 @@ select * from (select 1 like 2 escape (1 in (select 1 from t1))) x; 1 like 2 escape (1 in (select 1 from t1)) 0 drop table t1; +create table t1 (f int); +insert t1 values (1),(2); +create view v1 as select * from t1 where (1 like 2 escape (3 in (('h', 'b') in (select 'k', 'k' union select 'g', 'j'))) and f >= 0); +drop view v1; +drop table t1; diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 465d1df1380..c7a59a6fcbd 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -225,3 +225,12 @@ insert into t1 values(1); update (select 1 like 2 escape (1 in (select 1 from t1))) x, t1 as d set d.f1 = 1; select * from (select 1 like 2 escape (1 in (select 1 from t1))) x; drop table t1; + +# +# Item_func_like::walk +# +create table t1 (f int); +insert t1 values (1),(2); +create view v1 as select * from t1 where (1 like 2 escape (3 in (('h', 'b') in (select 'k', 'k' union select 'g', 'j'))) and f >= 0); +drop view v1; +drop table t1; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 22736339bf6..26469d88929 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -2013,6 +2013,13 @@ public: return this; } + bool walk(Item_processor processor, bool walk_subquery, void *arg) + { + return walk_args(processor, walk_subquery, arg) + || escape_item->walk(processor, walk_subquery, arg) + || (this->*processor)(arg); + } + bool find_selective_predicates_list_processor(void *arg); Item *get_copy(THD *thd, MEM_ROOT *mem_root) From dfe8ef8bd83b359f00e9caa3d1df05434d329958 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 21 Apr 2020 18:40:15 +0200 Subject: [PATCH 60/72] MDEV-22630 mysql_upgrade (MariaDB 5.2.X --> MariaDB 10.3.X) does not fix auth_string to change it to authentication_string cherry-pick from 10.4: commit b976b9bfc3e Author: Sergei Golubchik Date: Tue Apr 21 18:40:15 2020 +0200 MDEV-21244 mysql_upgrade creating empty global_priv table support upgrades from 5.2 privilege tables --- scripts/mysql_system_tables_fix.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 8e0894c41b3..9a8ebaa119e 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -646,6 +646,7 @@ UPDATE user SET Create_tablespace_priv = Super_priv WHERE @hadCreateTablespacePr ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL AFTER max_user_connections, ADD authentication_string TEXT NOT NULL AFTER plugin; +ALTER TABLE user CHANGE auth_string authentication_string TEXT NOT NULL; ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, MODIFY authentication_string TEXT NOT NULL; ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER authentication_string; From b79b3ff65571287882724b7b5cbe21004594a4d9 Mon Sep 17 00:00:00 2001 From: mkaruza Date: Fri, 2 Oct 2020 11:39:27 +0200 Subject: [PATCH 61/72] MDEV-23468: inline_mysql_socket_send: Assertion `mysql_socket.fd != -1' failed on shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closing remaining threads in `wsrep_close_client_connections` should also check `thd_is_connection_alive` for thd before closing connection. Assert is happening when thread already doing shutdown, but still not removed from threads list. Reviewed-by: Jan Lindström --- sql/wsrep_mysqld.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 7732dc0eefe..93ea3bc539f 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -46,6 +46,7 @@ #include #include #include "log_event.h" +#include "sql_connect.h" #include @@ -2441,10 +2442,12 @@ static my_bool kill_remaining_threads(THD *thd, THD *caller_thd) if (is_client_connection(thd) && !abort_replicated(thd) && !is_replaying_connection(thd) && + thd_is_connection_alive(thd) && thd != caller_thd) { + WSREP_INFO("killing local connection: %lld", (longlong) thd->thread_id); - close_connection(thd, 0); + close_connection(thd); } #endif return 0; From d4258f3a8fba0f8972714325c0dc0ca925879b86 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 22 Dec 2020 03:33:53 +0300 Subject: [PATCH 62/72] MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS Assign create_info->alias for ALTER TABLE since it is NULL and later accessed for printing error message. --- mysql-test/suite/versioning/r/partition.result | 7 +++++++ mysql-test/suite/versioning/t/partition.test | 9 +++++++++ sql/sql_table.cc | 1 + 3 files changed, 17 insertions(+) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index a89053369a7..06aa0ded32d 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -683,4 +683,11 @@ create table t1 (a int) with system versioning partition by system_time alter table t1 add partition (partition p2); ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME` drop table t1; +# +# MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS +# +create or replace table t1 (a int) with system versioning; +alter table t1 partition by system_time (partition pn current); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +drop table t1; # End of 10.3 tests diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 957fddc730d..454e4068e15 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -652,6 +652,15 @@ alter table t1 add partition (partition p2); # Cleanup drop table t1; +--echo # +--echo # MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS +--echo # +create or replace table t1 (a int) with system versioning; +--error ER_VERS_WRONG_PARTS +alter table t1 partition by system_time (partition pn current); +# Cleanup +drop table t1; + --echo # End of 10.3 tests --source suite/versioning/common_finish.inc diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 55cc33b4680..1237bba2286 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9850,6 +9850,7 @@ do_continue:; tmp_disable_binlog(thd); create_info->options|=HA_CREATE_TMP_ALTER; + create_info->alias= alter_ctx.table_name; error= create_table_impl(thd, &alter_ctx.db, &alter_ctx.table_name, &alter_ctx.new_db, &alter_ctx.tmp_name, From 7410ff436e95de09c2f3f0028e7af8b3a043028b Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 22 Dec 2020 03:33:53 +0300 Subject: [PATCH 63/72] MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low First part (row0mysql.cc) fixes ins_node_set_new_row() usage workflow as it is designed to operate on empty row (see row_get_prebuilt_insert_row() for example). Second part (row0ins.cc) fixes duplicate key error in FTS_DOC_ID_INDEX since history rows must not generate entries in that index. We detect FTS_DOC_ID_INDEX by a number of attributes and skip it if the row is historical. Misc fixes: row_build_index_entry_low() does not accept non-NULL tuple for FTS index (subject assertion fails), assertion (index->type != DICT_FTS) adds code understanding. Now as historical_row is copied in row_update_vers_insert() there is no need to copy the row twice: ROW_COPY_POINTERS is used to build historical_row initially. dbug_print_rec() debug functions. --- mysql-test/suite/versioning/r/delete.result | 19 +++++++++ mysql-test/suite/versioning/r/update.result | 20 +++++++++ mysql-test/suite/versioning/t/delete.test | 15 +++++++ mysql-test/suite/versioning/t/update.test | 15 +++++++ storage/innobase/include/row0ins.h | 1 + storage/innobase/row/row0ins.cc | 31 +++++++++++++- storage/innobase/row/row0mysql.cc | 45 +++++++++++++++++---- storage/innobase/row/row0row.cc | 2 + storage/innobase/ut/ut0ut.cc | 39 ++++++++++++++++++ 9 files changed, 179 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result index 5aa239b9cb8..4a0fec639b0 100644 --- a/mysql-test/suite/versioning/r/delete.result +++ b/mysql-test/suite/versioning/r/delete.result @@ -130,3 +130,22 @@ ERROR 42S02: Table 'test.xx' doesn't exist drop procedure pr; drop trigger tr; drop table t1; +# +# MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low +# +create table t1 ( +f1 int, f2 text, f3 int, fulltext (f2), key(f1), key(f3), +foreign key r (f3) references t1 (f1) on delete set null) +with system versioning engine innodb; +insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1); +select f1, f3, check_row(row_start, row_end) from t1; +f1 f3 check_row(row_start, row_end) +1 1 CURRENT ROW +1 1 CURRENT ROW +delete from t1; +select f1, f3, check_row(row_start, row_end) from t1 for system_time all; +f1 f3 check_row(row_start, row_end) +1 1 HISTORICAL ROW +1 NULL ERROR: row_end == row_start +1 1 HISTORICAL ROW +drop table t1; diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index cd26c341113..0b239423834 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -241,6 +241,26 @@ B2 salary 1 2500 drop table t1; drop table t2; +# Ensure FTS retains correct history +create table t1 ( +x int, y text, fulltext (y), +row_start SYS_DATATYPE as row start invisible, +row_end SYS_DATATYPE as row end invisible, +period for system_time (row_start, row_end)) +with system versioning engine innodb; +insert into t1 values (1, repeat('LONG', 2048)); +update t1 set x= x + 1; +select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y; +x left(y, 4) length(y) check_row(row_start, row_end) +1 LONG 8192 HISTORICAL ROW +2 LONG 8192 CURRENT ROW +update t1 set y= 'SHORT'; +select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y; +x left(y, 4) length(y) check_row(row_start, row_end) +1 LONG 8192 HISTORICAL ROW +2 LONG 8192 HISTORICAL ROW +2 SHOR 5 CURRENT ROW +drop tables t1; ### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row) create or replace table t1 (a int primary key, b int) with system versioning engine myisam; diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test index 492463f9395..e2f7240303d 100644 --- a/mysql-test/suite/versioning/t/delete.test +++ b/mysql-test/suite/versioning/t/delete.test @@ -94,4 +94,19 @@ drop procedure pr; drop trigger tr; drop table t1; +--echo # +--echo # MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low +--echo # +create table t1 ( + f1 int, f2 text, f3 int, fulltext (f2), key(f1), key(f3), + foreign key r (f3) references t1 (f1) on delete set null) +with system versioning engine innodb; +insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1); +select f1, f3, check_row(row_start, row_end) from t1; +delete from t1; +select f1, f3, check_row(row_start, row_end) from t1 for system_time all; + +# cleanup +drop table t1; + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index 06f81ea9064..f64dcfd0e5c 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -147,6 +147,21 @@ select @tmp2 = sys_trx_start as B2, salary from t2; drop table t1; drop table t2; +--echo # Ensure FTS retains correct history +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + x int, y text, fulltext (y), + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) +with system versioning engine innodb; +insert into t1 values (1, repeat('LONG', 2048)); +update t1 set x= x + 1; +select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y; +update t1 set y= 'SHORT'; +select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y; +drop tables t1; + --echo ### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row) create or replace table t1 (a int primary key, b int) with system versioning engine myisam; diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index 34427dc6dc7..9a16394a052 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -206,6 +206,7 @@ struct ins_node_t if this is NULL, entry list should be created and buffers for sys fields in row allocated */ void vers_update_end(row_prebuilt_t *prebuilt, bool history_row); + bool vers_history_row() const; /* true if 'row' is historical */ }; /** Create an insert object. diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index d581fd21d99..88152841293 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3566,6 +3566,16 @@ row_ins_get_row_from_select( } } +inline +bool ins_node_t::vers_history_row() const +{ + if (!table->versioned()) + return false; + dfield_t* row_end = dtuple_get_nth_field(row, table->vers_end); + return row_end->vers_history_row(); +} + + /***********************************************************//** Inserts a row to a table. @return DB_SUCCESS if operation successfully completed, else error @@ -3604,12 +3614,31 @@ row_ins( ut_ad(node->state == INS_NODE_INSERT_ENTRIES); while (node->index != NULL) { - if (node->index->type != DICT_FTS) { + dict_index_t *index = node->index; + /* + We do not insert history rows into FTS_DOC_ID_INDEX because + it is unique by FTS_DOC_ID only and we do not want to add + row_end to unique key. Fulltext field works the way new + FTS_DOC_ID is created on every fulltext UPDATE, so holding only + FTS_DOC_ID for history is enough. + */ + const unsigned type = index->type; + if (index->type & DICT_FTS) { + } else if (!(type & DICT_UNIQUE) || index->n_uniq > 1 + || !node->vers_history_row()) { + dberr_t err = row_ins_index_entry_step(node, thr); if (err != DB_SUCCESS) { DBUG_RETURN(err); } + } else { + /* Unique indexes with system versioning must contain + the version end column. The only exception is a hidden + FTS_DOC_ID_INDEX that InnoDB may create on a hidden or + user-created FTS_DOC_ID column. */ + ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME)); + ut_ad(!strcmp(index->fields[0].name, FTS_DOC_ID_COL_NAME)); } node->index = dict_table_get_next_index(node->index); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index dc88b41c6b4..848f60c47d0 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2104,10 +2104,18 @@ row_mysql_unfreeze_data_dictionary( @param buf Buffer to hold start time data */ void thd_get_query_start_data(THD *thd, char *buf); -/** Function restores btr_pcur_t, creates dtuple_t from rec_t, -sets row_end = CURRENT_TIMESTAMP/trx->id, inserts it to a table and updates -table statistics. -This is used in UPDATE CASCADE/SET NULL of a system versioning table. +/** Insert history row when evaluating foreign key referential action. + +1. Create new dtuple_t 'row' from node->historical_row; +2. Update its row_end to current timestamp; +3. Insert it to a table; +4. Update table statistics. + +This is used in UPDATE CASCADE/SET NULL of a system versioned referenced table. + +node->historical_row: dtuple_t containing pointers of row changed by refertial +action. + @param[in] thr current query thread @param[in] node a node which just updated a row in a foreign table @return DB_SUCCESS or some error */ @@ -2119,9 +2127,16 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) dict_table_t* table = node->table; ut_ad(table->versioned()); - dtuple_t* row = node->historical_row; - ut_ad(row); - node->historical_row = NULL; + dtuple_t* row; + const ulint n_cols = dict_table_get_n_cols(table); + const ulint n_v_cols = dict_table_get_n_v_cols(table); + + ut_ad(n_cols == dtuple_get_n_fields(node->historical_row)); + ut_ad(n_v_cols == dtuple_get_n_v_fields(node->historical_row)); + + row = dtuple_create_with_vcol(node->historical_heap, n_cols, n_v_cols); + + dict_table_copy_types(row, table); ins_node_t* insert_node = ins_node_create(INS_DIRECT, table, node->historical_heap); @@ -2134,6 +2149,22 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) insert_node->common.parent = thr; ins_node_set_new_row(insert_node, row); + ut_ad(n_cols > DATA_N_SYS_COLS); + // Exclude DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR + for (ulint i = 0; i < n_cols - DATA_N_SYS_COLS; i++) { + dfield_t *dst= dtuple_get_nth_field(row, i); + dfield_t *src= dtuple_get_nth_field(node->historical_row, i); + dfield_copy(dst, src); + } + + for (ulint i = 0; i < n_v_cols; i++) { + dfield_t *dst= dtuple_get_nth_v_field(row, i); + dfield_t *src= dtuple_get_nth_v_field(node->historical_row, i); + dfield_copy(dst, src); + } + + node->historical_row = NULL; + row_end = dtuple_get_nth_field(row, table->vers_end); if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) { mach_write_to_8(row_end_data, trx->id); diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index bcb128f2870..f6b7a9f49b6 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -294,6 +294,8 @@ row_build_index_entry_low( continue; } + ut_ad(!(index->type & DICT_FTS)); + if ((!ind_field || ind_field->prefix_len == 0) && (!dfield_is_ext(dfield) || dict_index_is_clust(index))) { diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 6d2b84625f7..65a2c9356e2 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -38,6 +38,7 @@ Created 5/11/1994 Heikki Tuuri #include #include "log.h" #include "my_cpu.h" +#include "rem0rec.h" /**********************************************************//** Returns the number of milliseconds since some epoch. The @@ -627,4 +628,42 @@ fatal_or_error::~fatal_or_error() } // namespace ib +#ifndef DBUG_OFF +const char * dbug_print_rec(const rec_t* rec, const rec_offs* offsets) +{ + rec_printer r(rec, offsets); + return r.str().c_str(); +} + +const char * dbug_print_rec(const rec_t* rec, ulint info, const rec_offs* offsets) +{ + rec_printer r(rec, info, offsets); + return r.str().c_str(); +} + +const char * dbug_print_rec(const dtuple_t* tuple) +{ + rec_printer r(tuple); + return r.str().c_str(); +} + +const char * dbug_print_rec(const dfield_t* field, ulint n) +{ + rec_printer r(field, n); + return r.str().c_str(); +} + +const char * dbug_print_rec(const rec_t* rec, dict_index_t* index) +{ + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs* offsets = offsets_; + rec_offs_init(offsets_); + mem_heap_t* tmp_heap = NULL; + offsets = rec_get_offsets(rec, index, offsets, true, + ULINT_UNDEFINED, &tmp_heap); + rec_printer r(rec, offsets); + return r.str().c_str(); +} +#endif /* !DBUG_OFF */ + #endif /* !UNIV_INNOCHECKSUM */ From 932ec586aada4bd78f613ee10750effc7f442327 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 22 Dec 2020 03:33:53 +0300 Subject: [PATCH 64/72] MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table First part of the fix (row0mysql.cc) addresses external columns when adding history row on referential action. The full data must be retrieved before the row is inserted. Second part of the fix (the rest) avoids duplicate primary key error between the history row generated on referential action and the history row generated by SQL command. Both command and referential action can happen on same table since foreign key can be self-reference (parent and child tables are same). Moreover, the self-reference can refer multiple rows when the key is non-unique. In such case history is generated by referential action occured on first row but processed all rows by a matched key. The second round is when the next row is processed by a command but history already exists. In such case we check TRX_ID of existing history row and if it is the same we assume the above situation and skip adding one more history row or failing the command. --- mysql-test/suite/versioning/common.inc | 21 +++++++++++++++++++ mysql-test/suite/versioning/common_finish.inc | 2 ++ mysql-test/suite/versioning/r/delete.result | 8 +++---- mysql-test/suite/versioning/r/foreign.result | 16 ++++++++++++++ mysql-test/suite/versioning/r/trx_id.result | 8 +++++++ mysql-test/suite/versioning/t/delete.test | 4 ++-- mysql-test/suite/versioning/t/foreign.test | 18 ++++++++++++++++ mysql-test/suite/versioning/t/trx_id.test | 6 ++++++ sql/sql_delete.cc | 10 ++++++++- storage/innobase/data/data0data.cc | 2 +- storage/innobase/include/data0data.h | 10 +++++++++ storage/innobase/row/row0ins.cc | 12 +++++++++++ storage/innobase/row/row0mysql.cc | 21 ++++++++++++++++++- 13 files changed, 129 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc index efb081a02e4..25adf15dd50 100644 --- a/mysql-test/suite/versioning/common.inc +++ b/mysql-test/suite/versioning/common.inc @@ -70,6 +70,11 @@ returns int deterministic return sys_trx_end = $sys_datatype_max; +eval create or replace function current_row_ts(sys_trx_end timestamp(6)) +returns int +deterministic + return convert_tz(sys_trx_end, '+00:00', @@time_zone) = TIMESTAMP'2038-01-19 03:14:07.999999'; + delimiter ~~; eval create or replace function check_row(row_start $sys_datatype_expl, row_end $sys_datatype_expl) returns varchar(255) @@ -86,4 +91,20 @@ begin end~~ delimiter ;~~ +delimiter ~~; +eval create or replace function check_row_ts(row_start timestamp(6), row_end timestamp(6)) +returns varchar(255) +deterministic +begin + if row_end < row_start then + return "ERROR: row_end < row_start"; + elseif row_end = row_start then + return "ERROR: row_end == row_start"; + elseif current_row_ts(row_end) then + return "CURRENT ROW"; + end if; + return "HISTORICAL ROW"; +end~~ +delimiter ;~~ + --enable_query_log diff --git a/mysql-test/suite/versioning/common_finish.inc b/mysql-test/suite/versioning/common_finish.inc index 61641c6c5ce..3c4e7b66ff3 100644 --- a/mysql-test/suite/versioning/common_finish.inc +++ b/mysql-test/suite/versioning/common_finish.inc @@ -4,5 +4,7 @@ drop procedure if exists verify_trt; drop procedure if exists verify_trt_dummy; drop function if exists current_row; drop function if exists check_row; +drop function if exists current_row_ts; +drop function if exists check_row_ts; --enable_warnings --enable_query_log diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result index 4a0fec639b0..0f9e2c22130 100644 --- a/mysql-test/suite/versioning/r/delete.result +++ b/mysql-test/suite/versioning/r/delete.result @@ -138,13 +138,13 @@ f1 int, f2 text, f3 int, fulltext (f2), key(f1), key(f3), foreign key r (f3) references t1 (f1) on delete set null) with system versioning engine innodb; insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1); -select f1, f3, check_row(row_start, row_end) from t1; -f1 f3 check_row(row_start, row_end) +select f1, f3, check_row_ts(row_start, row_end) from t1; +f1 f3 check_row_ts(row_start, row_end) 1 1 CURRENT ROW 1 1 CURRENT ROW delete from t1; -select f1, f3, check_row(row_start, row_end) from t1 for system_time all; -f1 f3 check_row(row_start, row_end) +select f1, f3, check_row_ts(row_start, row_end) from t1 for system_time all; +f1 f3 check_row_ts(row_start, row_end) 1 1 HISTORICAL ROW 1 NULL ERROR: row_end == row_start 1 1 HISTORICAL ROW diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index 32b5e5cf3d8..e54afdbc74e 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -398,6 +398,8 @@ Warning 1265 Data truncated for column 'f12' at row 7 SET timestamp = 9; REPLACE INTO t2 SELECT * FROM t2; DROP TABLE t1, t2; +set timestamp= default; +set time_zone='+00:00'; # # MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation # @@ -427,3 +429,17 @@ insert into t2 values (1), (1); # DELETE from foreign table is allowed delete from t2; drop tables t2, t1; +# +# MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table +# +create table t1 (pk int primary key, f1 int,f2 int, f3 text, +key(f1), fulltext(f3), key(f3(10)), +foreign key (f2) references t1 (f1) on delete set null +) engine=innodb with system versioning; +insert into t1 values (1, 8, 8, 'SHORT'), (2, 8, 8, repeat('LONG', 8071)); +delete from t1; +select pk, f1, f2, left(f3, 4), check_row_ts(row_start, row_end) from t1 for system_time all order by pk; +pk f1 f2 left(f3, 4) check_row_ts(row_start, row_end) +1 8 8 SHOR HISTORICAL ROW +2 8 8 LONG HISTORICAL ROW +drop table t1; diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index 5dd9e7aa188..58d02505fb6 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -5,7 +5,15 @@ sys_trx_start bigint(20) unsigned as row start invisible, sys_trx_end bigint(20) unsigned as row end invisible, period for system_time (sys_trx_start, sys_trx_end) ) with system versioning; +# No history inside the transaction +start transaction; insert into t1 (x) values (1); +update t1 set x= x + 1; +update t1 set x= x + 1; +commit; +select *, sys_trx_start > 1, sys_trx_end from t1 for system_time all; +x sys_trx_start > 1 sys_trx_end +3 1 18446744073709551615 # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry set @@system_versioning_alter_history=keep; create or replace table t1 (x int); diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test index e2f7240303d..a5a0497fef2 100644 --- a/mysql-test/suite/versioning/t/delete.test +++ b/mysql-test/suite/versioning/t/delete.test @@ -102,9 +102,9 @@ create table t1 ( foreign key r (f3) references t1 (f1) on delete set null) with system versioning engine innodb; insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1); -select f1, f3, check_row(row_start, row_end) from t1; +select f1, f3, check_row_ts(row_start, row_end) from t1; delete from t1; -select f1, f3, check_row(row_start, row_end) from t1 for system_time all; +select f1, f3, check_row_ts(row_start, row_end) from t1 for system_time all; # cleanup drop table t1; diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index 7493f99cba7..725f51f0660 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -421,6 +421,8 @@ REPLACE INTO t2 SELECT * FROM t2; # Cleanup DROP TABLE t1, t2; +set timestamp= default; +set time_zone='+00:00'; --let $datadir= `select @@datadir` --remove_file $datadir/test/t1.data --remove_file $datadir/test/t1.data.2 @@ -458,4 +460,20 @@ insert into t2 values (1), (1); delete from t2; drop tables t2, t1; +--echo # +--echo # MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table +--echo # +create table t1 (pk int primary key, f1 int,f2 int, f3 text, + key(f1), fulltext(f3), key(f3(10)), + foreign key (f2) references t1 (f1) on delete set null +) engine=innodb with system versioning; + +insert into t1 values (1, 8, 8, 'SHORT'), (2, 8, 8, repeat('LONG', 8071)); + +delete from t1; +select pk, f1, f2, left(f3, 4), check_row_ts(row_start, row_end) from t1 for system_time all order by pk; + +# cleanup +drop table t1; + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test index 38724a47fd1..7dfc8acb080 100644 --- a/mysql-test/suite/versioning/t/trx_id.test +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -14,7 +14,13 @@ create or replace table t1 ( period for system_time (sys_trx_start, sys_trx_end) ) with system versioning; +--echo # No history inside the transaction +start transaction; insert into t1 (x) values (1); +update t1 set x= x + 1; +update t1 set x= x + 1; +commit; +select *, sys_trx_start > 1, sys_trx_end from t1 for system_time all; --echo # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry set @@system_versioning_alter_history=keep; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 929455977e6..0857c4e5457 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -246,7 +246,15 @@ int TABLE::delete_row() store_record(this, record[1]); vers_update_end(); - return file->ha_update_row(record[1], record[0]); + int err= file->ha_update_row(record[1], record[0]); + /* + MDEV-23644: we get HA_ERR_FOREIGN_DUPLICATE_KEY iff we already got history + row with same trx_id which is the result of foreign key action, so we + don't need one more history row. + */ + if (err == HA_ERR_FOREIGN_DUPLICATE_KEY) + return file->ha_delete_row(record[0]); + return err; } diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 47e58f1614a..3e23cd6f662 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -738,7 +738,7 @@ void dtuple_convert_back_big_rec( /*========================*/ dict_index_t* index MY_ATTRIBUTE((unused)), /*!< in: index */ - dtuple_t* entry, /*!< in: entry whose data was put to vector */ + dtuple_t* entry, /*!< in/out: entry whose data was put to vector */ big_rec_t* vector) /*!< in, own: big rec vector; it is freed in this function */ { diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index 11a7f2e516f..002332852b8 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -543,6 +543,16 @@ struct dtuple_t { inserted or updated. @param[in] index index possibly with instantly added columns */ void trim(const dict_index_t& index); + bool vers_history_row() const + { + for (ulint i = 0; i < n_fields; i++) { + const dfield_t* field = &fields[i]; + if (field->type.vers_sys_end()) { + return field->vers_history_row(); + } + } + return false; + } }; inline ulint dtuple_get_n_fields(const dtuple_t* tuple) diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 88152841293..43f80adebbd 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2385,6 +2385,18 @@ row_ins_duplicate_error_in_clust( duplicate: trx->error_info = cursor->index; err = DB_DUPLICATE_KEY; + if (cursor->index->table->versioned() + && entry->vers_history_row()) + { + ulint trx_id_len; + byte *trx_id = rec_get_nth_field( + rec, offsets, n_unique, + &trx_id_len); + ut_ad(trx_id_len == DATA_TRX_ID_LEN); + if (trx->id == trx_read_trx_id(trx_id)) { + err = DB_FOREIGN_DUPLICATE_KEY; + } + } goto func_exit; } } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 848f60c47d0..c643a907722 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2125,6 +2125,7 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) dfield_t* row_end; char row_end_data[8]; dict_table_t* table = node->table; + page_size_t page_size= dict_table_page_size(table); ut_ad(table->versioned()); dtuple_t* row; @@ -2152,9 +2153,27 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) ut_ad(n_cols > DATA_N_SYS_COLS); // Exclude DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR for (ulint i = 0; i < n_cols - DATA_N_SYS_COLS; i++) { - dfield_t *dst= dtuple_get_nth_field(row, i); dfield_t *src= dtuple_get_nth_field(node->historical_row, i); + dfield_t *dst= dtuple_get_nth_field(row, i); dfield_copy(dst, src); + if (dfield_is_ext(src)) { + byte *field_data + = static_cast(dfield_get_data(src)); + ulint ext_len; + ulint field_len = dfield_get_len(src); + + ut_a(field_len >= BTR_EXTERN_FIELD_REF_SIZE); + + ut_a(memcmp(field_data + field_len + - BTR_EXTERN_FIELD_REF_SIZE, + field_ref_zero, + BTR_EXTERN_FIELD_REF_SIZE)); + + byte *data = btr_copy_externally_stored_field( + &ext_len, field_data, page_size, field_len, + node->historical_heap); + dfield_set_data(dst, data, ext_len); + } } for (ulint i = 0; i < n_v_cols; i++) { From 9b38ed4c85bda254f48c02890f134adf227700e3 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 22 Dec 2020 08:34:18 +0300 Subject: [PATCH 65/72] MDEV-23446 UPDATE does not insert history row if the row is not changed Add history row outside of compare_record() check. For TRX_ID versioning we have to fail can_compare_record to force InnoDB update which adds history row; and there in ha_innobase::update_row() is additional "row changed" check where we force history row anyway. --- mysql-test/suite/versioning/r/update.result | 29 +++++++++ mysql-test/suite/versioning/t/update.test | 25 ++++++++ sql/sql_update.cc | 69 +++++++++++---------- storage/innobase/handler/ha_innodb.cc | 14 +++++ 4 files changed, 105 insertions(+), 32 deletions(-) diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index 0b239423834..fbb9f541b06 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -370,3 +370,32 @@ insert into t1 (a) values (1), (2); update ignore t1 set a= 3; delete history from t1; drop table t1; +# +# MDEV-23446 UPDATE does not insert history row if the row is not changed +# +create table t1 ( +a int, +row_start SYS_DATATYPE as row start invisible, +row_end SYS_DATATYPE as row end invisible, +period for system_time (row_start, row_end)) with system versioning; +insert into t1 values (1); +update t1 set a= 1; +select *, check_row(row_start, row_end) from t1 for system_time all order by row_end; +a check_row(row_start, row_end) +1 HISTORICAL ROW +1 CURRENT ROW +# multi-update +create or replace table t2 like t1; +create or replace table t3 like t1; +insert into t2 values (1); +insert into t3 values (1); +update t2, t3 set t2.a= 1, t3.a= 1 where t2.a = t3.a; +select *, check_row(row_start, row_end) from t2 for system_time all order by row_end; +a check_row(row_start, row_end) +1 HISTORICAL ROW +1 CURRENT ROW +select *, check_row(row_start, row_end) from t2 for system_time all order by row_end; +a check_row(row_start, row_end) +1 HISTORICAL ROW +1 CURRENT ROW +drop tables t1, t2, t3; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index f64dcfd0e5c..7f99e307942 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -301,4 +301,29 @@ delete history from t1; # cleanup drop table t1; +--echo # +--echo # MDEV-23446 UPDATE does not insert history row if the row is not changed +--echo # +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + a int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) with system versioning; +insert into t1 values (1); +update t1 set a= 1; +select *, check_row(row_start, row_end) from t1 for system_time all order by row_end; + +--echo # multi-update +create or replace table t2 like t1; +create or replace table t3 like t1; +insert into t2 values (1); +insert into t3 values (1); +update t2, t3 set t2.a= 1, t3.a= 1 where t2.a = t3.a; +select *, check_row(row_start, row_end) from t2 for system_time all order by row_end; +select *, check_row(row_start, row_end) from t2 for system_time all order by row_end; + +# cleanup +drop tables t1, t2, t3; + source suite/versioning/common_finish.inc; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 318ab8e7f69..314256cd8c5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -52,8 +52,9 @@ compare_record(TABLE*). */ bool records_are_comparable(const TABLE *table) { - return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) || - bitmap_is_subset(table->write_set, table->read_set); + return !table->versioned(VERS_TRX_ID) && + (((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) || + bitmap_is_subset(table->write_set, table->read_set)); } @@ -960,25 +961,27 @@ update_begin: } else if (likely(!error)) { - if (has_vers_fields && table->versioned()) - { - if (table->versioned(VERS_TIMESTAMP)) - { - store_record(table, record[2]); - table->mark_columns_per_binlog_row_image(); - error= vers_insert_history_row(table); - restore_record(table, record[2]); - } - if (likely(!error)) - updated_sys_ver++; - } - if (likely(!error)) - updated++; + if (has_vers_fields && table->versioned(VERS_TRX_ID)) + updated_sys_ver++; + updated++; } if (unlikely(error) && (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL))) { + goto error; + } + } + + if (likely(!error) && has_vers_fields && table->versioned(VERS_TIMESTAMP)) + { + store_record(table, record[2]); + table->mark_columns_per_binlog_row_image(); + error= vers_insert_history_row(table); + restore_record(table, record[2]); + if (unlikely(error)) + { +error: /* If (ignore && error is ignorable) we don't have to do anything; otherwise... @@ -989,10 +992,11 @@ update_begin: flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); - table->file->print_error(error,MYF(flags)); - error= 1; - break; - } + table->file->print_error(error,MYF(flags)); + error= 1; + break; + } + updated_sys_ver++; } if (table->triggers && @@ -2410,6 +2414,7 @@ int multi_update::send_data(List ¬_used_values) if (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)) { +error: /* If (ignore && error == is ignorable) we don't have to do anything; otherwise... @@ -2431,19 +2436,8 @@ int multi_update::send_data(List ¬_used_values) error= 0; updated--; } - else if (has_vers_fields && table->versioned()) + else if (has_vers_fields && table->versioned(VERS_TRX_ID)) { - if (table->versioned(VERS_TIMESTAMP)) - { - store_record(table, record[2]); - if (vers_insert_history_row(table)) - { - restore_record(table, record[2]); - error= 1; - break; - } - restore_record(table, record[2]); - } updated_sys_ver++; } /* non-transactional or transactional table got modified */ @@ -2457,6 +2451,17 @@ int multi_update::send_data(List ¬_used_values) } } } + if (has_vers_fields && table->versioned(VERS_TIMESTAMP)) + { + store_record(table, record[2]); + if (vers_insert_history_row(table)) + { + restore_record(table, record[2]); + goto error; + } + restore_record(table, record[2]); + updated_sys_ver++; + } if (table->triggers && unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d1f155eecff..e66a340a7f0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8799,6 +8799,20 @@ ha_innobase::update_row( MySQL that the row is not really updated and it should not increase the count of updated rows. This is fix for http://bugs.mysql.com/29157 */ + if (m_prebuilt->versioned_write + && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE + /* Multiple UPDATE of same rows in single transaction create + historical rows only once. */ + && trx->id != table->vers_start_id()) { + error = row_insert_for_mysql((byte*) old_row, + m_prebuilt, + ROW_INS_HISTORICAL); + if (error != DB_SUCCESS) { + goto func_exit; + } + innobase_srv_conc_exit_innodb(m_prebuilt); + innobase_active_small(); + } DBUG_RETURN(HA_ERR_RECORD_IS_THE_SAME); } else { const bool vers_set_fields = m_prebuilt->versioned_write From 04741dc736e803b0a91c76d19de464e25b4a1977 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Mon, 21 Dec 2020 14:44:56 +0100 Subject: [PATCH 66/72] MENT-1047 Assertion `active() == false' failed with "XA START.." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Galera replication does not support XA transactions yet. Reject any attempt to `XA START` a transaction, if Galera is enabled. Reviewed-by: Jan Lindström --- mysql-test/suite/galera/r/MENT-1047.result | 4 ++++ mysql-test/suite/galera/t/MENT-1047.test | 7 +++++++ sql/sql_parse.cc | 8 ++++++++ 3 files changed, 19 insertions(+) create mode 100644 mysql-test/suite/galera/r/MENT-1047.result create mode 100644 mysql-test/suite/galera/t/MENT-1047.test diff --git a/mysql-test/suite/galera/r/MENT-1047.result b/mysql-test/suite/galera/r/MENT-1047.result new file mode 100644 index 00000000000..76d58f6d52f --- /dev/null +++ b/mysql-test/suite/galera/r/MENT-1047.result @@ -0,0 +1,4 @@ +connection node_2; +connection node_1; +XA START 'trx'; +ERROR 42000: This version of MariaDB doesn't yet support 'XA transactions with Galera replication' diff --git a/mysql-test/suite/galera/t/MENT-1047.test b/mysql-test/suite/galera/t/MENT-1047.test new file mode 100644 index 00000000000..1431818f806 --- /dev/null +++ b/mysql-test/suite/galera/t/MENT-1047.test @@ -0,0 +1,7 @@ +# +# MENT-1047 - Reject XA with Galera replication +# +--source include/galera_cluster.inc + +--error ER_NOT_SUPPORTED_YET +XA START 'trx'; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 036c1215ea6..472dc3b386a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5987,6 +5987,14 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_XA_START: +#ifdef WITH_WSREP + if (WSREP(thd)) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), + "XA transactions with Galera replication"); + break; + } +#endif /* WITH_WSREP */ if (trans_xa_start(thd)) goto error; my_ok(thd); From df4f4bd84acce75150caff95b08c9b82d61e45db Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 22 Dec 2020 19:17:20 +0300 Subject: [PATCH 67/72] MDEV-24444: ASAN use-after-poison in Item_func_in::get_func_mm_tree with NOT IN Fix a trivial error in the fix for MDEV-21958: check the key in the right table. --- mysql-test/r/range.result | 10 ++++++++++ mysql-test/t/range.test | 13 +++++++++++++ sql/opt_range.cc | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 49bce9a316d..1d07cb04c06 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -3174,5 +3174,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1000 Using where drop table t1,t2; # +# MDEV-24444: ASAN use-after-poison in Item_func_in::get_func_mm_tree with NOT IN +# +CREATE TABLE t1 (id INT, a CHAR(3), b INT, PRIMARY KEY(id), KEY(b), KEY(a)); +INSERT INTO t1 VALUES (1,'foo',10),(2,'bar',20); +CREATE TABLE t2 (code CHAR(8), num INT, PRIMARY KEY (code)); +INSERT INTO t2 VALUES ('100',1),('111',2); +SELECT * FROM t1 JOIN t2 ON (t2.code = t1.b) WHERE t1.a NOT IN ('baz', 'qux') OR t2.num != 3; +id a b code num +DROP TABLE t1, t2; +# # End of 10.2 tests # diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 4088aa2990e..2f55889afec 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -2204,6 +2204,19 @@ explain select * from t2 force index (primary) where pk not in (1,2,3); drop table t1,t2; +--echo # +--echo # MDEV-24444: ASAN use-after-poison in Item_func_in::get_func_mm_tree with NOT IN +--echo # +CREATE TABLE t1 (id INT, a CHAR(3), b INT, PRIMARY KEY(id), KEY(b), KEY(a)); +INSERT INTO t1 VALUES (1,'foo',10),(2,'bar',20); + +CREATE TABLE t2 (code CHAR(8), num INT, PRIMARY KEY (code)); +INSERT INTO t2 VALUES ('100',1),('111',2); + +SELECT * FROM t1 JOIN t2 ON (t2.code = t1.b) WHERE t1.a NOT IN ('baz', 'qux') OR t2.num != 3; + +DROP TABLE t1, t2; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3a6579b0471..27ea4a83714 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7173,7 +7173,7 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, uint key_no; while ((key_no= it.next_bit()) != key_map::Iterator::BITMAP_END) { - KEY *key_info= ¶m->table->key_info[key_no]; + KEY *key_info= &field->table->key_info[key_no]; if (key_info->user_defined_key_parts == 1 && (key_info->flags & HA_NOSAME)) { From 8d8370e31d48e0bc6139c18770746f9959c21598 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 22 Dec 2020 19:22:41 +0300 Subject: [PATCH 68/72] Forgot to add this change to previous cset --- mysql-test/r/range_mrr_icp.result | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result index 3561283044a..f3203fea73d 100644 --- a/mysql-test/r/range_mrr_icp.result +++ b/mysql-test/r/range_mrr_icp.result @@ -3186,6 +3186,16 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1000 Using where drop table t1,t2; # +# MDEV-24444: ASAN use-after-poison in Item_func_in::get_func_mm_tree with NOT IN +# +CREATE TABLE t1 (id INT, a CHAR(3), b INT, PRIMARY KEY(id), KEY(b), KEY(a)); +INSERT INTO t1 VALUES (1,'foo',10),(2,'bar',20); +CREATE TABLE t2 (code CHAR(8), num INT, PRIMARY KEY (code)); +INSERT INTO t2 VALUES ('100',1),('111',2); +SELECT * FROM t1 JOIN t2 ON (t2.code = t1.b) WHERE t1.a NOT IN ('baz', 'qux') OR t2.num != 3; +id a b code num +DROP TABLE t1, t2; +# # End of 10.2 tests # set optimizer_switch=@mrr_icp_extra_tmp; From 097786c485c6d10064e8bc593b6aa54e477712f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 23 Dec 2020 14:24:06 +0200 Subject: [PATCH 69/72] Partially revert 7410ff436e95de09c2f3f0028e7af8b3a043028b Remove the unused dbug_print_rec() functions because they break the clang build due to -Wreturn-stack-address --- storage/innobase/ut/ut0ut.cc | 39 ------------------------------------ 1 file changed, 39 deletions(-) diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 65a2c9356e2..6d2b84625f7 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -38,7 +38,6 @@ Created 5/11/1994 Heikki Tuuri #include #include "log.h" #include "my_cpu.h" -#include "rem0rec.h" /**********************************************************//** Returns the number of milliseconds since some epoch. The @@ -628,42 +627,4 @@ fatal_or_error::~fatal_or_error() } // namespace ib -#ifndef DBUG_OFF -const char * dbug_print_rec(const rec_t* rec, const rec_offs* offsets) -{ - rec_printer r(rec, offsets); - return r.str().c_str(); -} - -const char * dbug_print_rec(const rec_t* rec, ulint info, const rec_offs* offsets) -{ - rec_printer r(rec, info, offsets); - return r.str().c_str(); -} - -const char * dbug_print_rec(const dtuple_t* tuple) -{ - rec_printer r(tuple); - return r.str().c_str(); -} - -const char * dbug_print_rec(const dfield_t* field, ulint n) -{ - rec_printer r(field, n); - return r.str().c_str(); -} - -const char * dbug_print_rec(const rec_t* rec, dict_index_t* index) -{ - rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; - rec_offs* offsets = offsets_; - rec_offs_init(offsets_); - mem_heap_t* tmp_heap = NULL; - offsets = rec_get_offsets(rec, index, offsets, true, - ULINT_UNDEFINED, &tmp_heap); - rec_printer r(rec, offsets); - return r.str().c_str(); -} -#endif /* !DBUG_OFF */ - #endif /* !UNIV_INNOCHECKSUM */ From f87737db0424a981926868b50b383ad741b40803 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 24 Dec 2020 15:47:01 +0100 Subject: [PATCH 70/72] Bring changes to oracle parser --- sql/sql_yacc_ora.yy | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 735d5ad59a2..503cb7dcf1b 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -288,7 +288,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* We should not introduce any further shift/reduce conflicts. */ -%expect 70 +%expect 63 /* Comments for TOKENS. @@ -1332,7 +1332,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type literal insert_ident order_ident temporal_literal simple_ident expr sum_expr in_sum_expr - variable variable_aux bool_pri + variable variable_aux predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr primary_expr string_factor_expr mysql_concatenation_expr @@ -9781,23 +9781,19 @@ expr: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bool_pri - ; - -bool_pri: - bool_pri EQUAL_SYM predicate %prec EQUAL_SYM + | expr EQUAL_SYM predicate %prec EQUAL_SYM { $$= new (thd->mem_root) Item_func_equal(thd, $1, $3); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bool_pri comp_op predicate %prec '=' + | expr comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bool_pri comp_op all_or_any '(' subselect ')' %prec '=' + | expr comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); if (unlikely($$ == NULL)) From 8e16c885a860a987eab4f3689e28288e0594e708 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 24 Dec 2020 20:47:21 +0300 Subject: [PATCH 71/72] MDEV-24476 Overloaded functions dbug_print_rec break compilation in 10.3 dbug_print_rec() functions used to print data inside GDB. --- storage/innobase/ut/ut0ut.cc | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 6d2b84625f7..d331beb9230 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -38,6 +38,9 @@ Created 5/11/1994 Heikki Tuuri #include #include "log.h" #include "my_cpu.h" +#ifndef DBUG_OFF +#include "rem0rec.h" +#endif /**********************************************************//** Returns the number of milliseconds since some epoch. The @@ -627,4 +630,49 @@ fatal_or_error::~fatal_or_error() } // namespace ib +#ifndef DBUG_OFF +static char dbug_print_buf[1024]; + +const char * dbug_print_rec(const rec_t* rec, const rec_offs* offsets) +{ + rec_printer r(rec, offsets); + strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); + return dbug_print_buf; +} + +const char * dbug_print_rec(const rec_t* rec, ulint info, const rec_offs* offsets) +{ + rec_printer r(rec, info, offsets); + strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); + return dbug_print_buf; +} + +const char * dbug_print_rec(const dtuple_t* tuple) +{ + rec_printer r(tuple); + strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); + return dbug_print_buf; +} + +const char * dbug_print_rec(const dfield_t* field, ulint n) +{ + rec_printer r(field, n); + strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); + return dbug_print_buf; +} + +const char * dbug_print_rec(const rec_t* rec, dict_index_t* index) +{ + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs* offsets = offsets_; + rec_offs_init(offsets_); + mem_heap_t* tmp_heap = NULL; + offsets = rec_get_offsets(rec, index, offsets, true, + ULINT_UNDEFINED, &tmp_heap); + rec_printer r(rec, offsets); + strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); + return dbug_print_buf; +} +#endif /* !DBUG_OFF */ + #endif /* !UNIV_INNOCHECKSUM */ From 1e9af7996e7f84934da8241b61f349b2626f7cf5 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 24 Dec 2020 22:15:40 +0100 Subject: [PATCH 72/72] Fix MDEV-21958 code to be working with not 64 MAX_INDEXES --- sql/opt_range.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 27ea4a83714..1b4f20bc39c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7171,7 +7171,7 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, { key_map::Iterator it(field->key_start); uint key_no; - while ((key_no= it.next_bit()) != key_map::Iterator::BITMAP_END) + while ((key_no= it++) != key_map::Iterator::BITMAP_END) { KEY *key_info= &field->table->key_info[key_no]; if (key_info->user_defined_key_parts == 1 &&