diff options
99 files changed, 2786 insertions, 407 deletions
@@ -4,17 +4,19 @@ organization registered in the USA. The current main sponsors of the MariaDB Foundation are: Alibaba Cloud https://intl.aliyun.com (2017) -Booking.com https://www.booking.com (2013 - 2017) -Development Bank of Singapore https://dbs.com (2016 - 2017) -MariaDB Corporation https://www.mariadb.com (2013 - 2017) -Visma https://visma.com (2015 - 2017) -Acronis http://acronis.com (2016 - 2017) -Nexedi https://www.nexedi.com (2016 - 2017) -Automattic https://automattic.com (2014 - 2017) -Tencent Game DBA http://tencentdba.com/about (2016 - 2017) -Tencent TDSQL http://tdsql.org/ (2016 - 2017) -Verkkokauppa.com https://www.verkkokauppa.com (2015 - 2017) -Virtuozzo https://virtuozzo.com (2016 - 2017) +Booking.com https://www.booking.com (2013) +Tencent Cloud https://cloud.tencent.com (2017) +Development Bank of Singapore https://dbs.com (2016) +IBM https://www.ibm.com (2017) +MariaDB Corporation https://www.mariadb.com (2013) +Visma https://visma.com (2015) +Acronis http://acronis.com (2016) +Nexedi https://www.nexedi.com (2016) +Automattic https://automattic.com (2014) +Tencent Game DBA http://tencentdba.com/about (2016) +Tencent TDSQL http://tdsql.org (2016) +Verkkokauppa.com https://www.verkkokauppa.com (2015) +Virtuozzo https://virtuozzo.com (2016) For a full list of sponsors, see https://mariadb.org/about/supporters/ diff --git a/client/mysql.cc b/client/mysql.cc index d85b118a2bb..d81d8abfcfd 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2323,8 +2323,10 @@ static bool add_line(String &buffer, char *line, ulong line_length, continue; } #endif - if (!*ml_comment && inchar == '\\' && - !(*in_string && + if (!*ml_comment && inchar == '\\' && *in_string != '`' && + !(*in_string == '"' && + (mysql.server_status & SERVER_STATUS_ANSI_QUOTES)) && + !(*in_string && (mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES))) { // Found possbile one character command like \c diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a23e61f1fc3..95f358524cf 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1720,12 +1720,23 @@ void log_msg(const char *fmt, ...) int cat_file(DYNAMIC_STRING* ds, const char* filename) { int fd; - int len; - char buff[16384]; + size_t len; + char *buff; if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0) return 1; - while((len= (int)my_read(fd, (uchar*)&buff, sizeof(buff)-1, MYF(0))) > 0) + + len= (size_t) my_seek(fd, 0, SEEK_END, MYF(0)); + my_seek(fd, 0, SEEK_SET, MYF(0)); + if (len == (size_t)MY_FILEPOS_ERROR || + !(buff= (char*)my_malloc(len + 1, MYF(0)))) + { + my_close(fd, MYF(0)); + return 1; + } + len= my_read(fd, (uchar*)buff, len, MYF(0)); + my_close(fd, MYF(0)); + { char *p= buff, *start= buff,*end=buff+len; while (p < end) @@ -1748,7 +1759,7 @@ int cat_file(DYNAMIC_STRING* ds, const char* filename) *p= 0; replace_dynstr_append_mem(ds, start, p-start); } - my_close(fd, MYF(0)); + my_free(buff); return 0; } @@ -6490,6 +6501,16 @@ my_bool end_of_query(int c) } +static inline bool is_escape_char(char c, char in_string) +{ + if (c != '\\' || in_string == '`') return false; + if (!cur_con) return true; + uint server_status= cur_con->mysql->server_status; + if (server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) return false; + return !(server_status & SERVER_STATUS_ANSI_QUOTES && in_string == '"'); +} + + /* Read one "line" from the file @@ -6516,7 +6537,7 @@ my_bool end_of_query(int c) int read_line(char *buf, int size) { - char c, UNINIT_VAR(last_quote), last_char= 0; + char c, last_quote=0, last_char= 0; char *p= buf, *buf_end= buf + size - 1; int skip_char= 0; my_bool have_slash= FALSE; @@ -6598,7 +6619,7 @@ int read_line(char *buf, int size) state= R_Q; } } - have_slash= (c == '\\'); + have_slash= is_escape_char(c, last_quote); break; case R_COMMENT: @@ -6668,7 +6689,7 @@ int read_line(char *buf, int size) case R_Q: if (c == last_quote) state= R_NORMAL; - else if (c == '\\') + else if (is_escape_char(c, last_quote)) state= R_SLASH_IN_Q; break; diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 7a037d7ce43..47daa88d0a2 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -33,7 +33,12 @@ SET(CPACK_COMPONENTS_ALL Server ManPagesServer IniFiles Server_Scripts ) SET(CPACK_RPM_PACKAGE_NAME ${CPACK_PACKAGE_NAME}) -SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}") +IF(CMAKE_VERSION VERSION_LESS "3.6.0") + SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}") +ELSE() + SET(CPACK_RPM_FILE_NAME "RPM-DEFAULT") + SET(CPACK_RPM_DEBUGINFO_PACKAGE ON) +ENDIF() SET(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}") SET(CPACK_RPM_PACKAGE_LICENSE "GPLv2") diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index d407ea3d26f..be25c3bbd28 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -124,7 +124,7 @@ MACRO (MYSQL_CHECK_SSL) SET(OPENSSL_ROOT_DIR ${WITH_SSL_PATH}) ENDIF() ENDIF() - FIND_PACKAGE(OpenSSL) + FIND_PACKAGE(OpenSSL 1.0.0) IF(OPENSSL_FOUND) SET(OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY}) INCLUDE(CheckSymbolExists) diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index c6ec54c3a6c..5cf63ea94c1 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -345,7 +345,8 @@ get_mysql_vars(MYSQL *connection) char *innodb_data_home_dir_var = NULL; char *innodb_undo_directory_var = NULL; char *innodb_page_size_var = NULL; - + char *innodb_undo_tablespaces_var = NULL; + char *endptr; unsigned long server_version = mysql_get_server_version(connection); bool ret = true; @@ -373,6 +374,7 @@ get_mysql_vars(MYSQL *connection) {"innodb_data_home_dir", &innodb_data_home_dir_var}, {"innodb_undo_directory", &innodb_undo_directory_var}, {"innodb_page_size", &innodb_page_size_var}, + {"innodb_undo_tablespaces", &innodb_undo_tablespaces_var}, {NULL, NULL} }; @@ -461,62 +463,55 @@ get_mysql_vars(MYSQL *connection) } /* get some default values is they are missing from my.cnf */ - if (!check_if_param_set("datadir") && datadir_var && *datadir_var) { + if (datadir_var && *datadir_var) { strmake(mysql_real_data_home, datadir_var, FN_REFLEN - 1); mysql_data_home= mysql_real_data_home; } - if (!check_if_param_set("innodb_data_file_path") - && innodb_data_file_path_var && *innodb_data_file_path_var) { + if (innodb_data_file_path_var && *innodb_data_file_path_var) { innobase_data_file_path = my_strdup( innodb_data_file_path_var, MYF(MY_FAE)); } - if (!check_if_param_set("innodb_data_home_dir") - && innodb_data_home_dir_var && *innodb_data_home_dir_var) { + if (innodb_data_home_dir_var && *innodb_data_home_dir_var) { innobase_data_home_dir = my_strdup( innodb_data_home_dir_var, MYF(MY_FAE)); } - if (!check_if_param_set("innodb_log_group_home_dir") - && innodb_log_group_home_dir_var + if (innodb_log_group_home_dir_var && *innodb_log_group_home_dir_var) { srv_log_group_home_dir = my_strdup( innodb_log_group_home_dir_var, MYF(MY_FAE)); } - if (!check_if_param_set("innodb_undo_directory") - && innodb_undo_directory_var && *innodb_undo_directory_var) { + if (innodb_undo_directory_var && *innodb_undo_directory_var) { srv_undo_dir = my_strdup( innodb_undo_directory_var, MYF(MY_FAE)); } - if (!check_if_param_set("innodb_log_files_in_group") - && innodb_log_files_in_group_var) { - char *endptr; - + if (innodb_log_files_in_group_var) { srv_n_log_files = strtol( innodb_log_files_in_group_var, &endptr, 10); ut_ad(*endptr == 0); } - if (!check_if_param_set("innodb_log_file_size") - && innodb_log_file_size_var) { - char *endptr; - + if (innodb_log_file_size_var) { srv_log_file_size = strtoll( innodb_log_file_size_var, &endptr, 10); ut_ad(*endptr == 0); } - if (!check_if_param_set("innodb_page_size") && innodb_page_size_var) { - char *endptr; - + if (innodb_page_size_var) { innobase_page_size = strtoll( innodb_page_size_var, &endptr, 10); ut_ad(*endptr == 0); } + if (innodb_undo_tablespaces_var) { + srv_undo_tablespaces = strtoul(innodb_undo_tablespaces_var, &endptr, 10); + ut_ad(*endptr == 0); + } + out: free_mysql_variables(mysql_vars); diff --git a/extra/mariabackup/xbstream.c b/extra/mariabackup/xbstream.c index edfe20a9e3c..f3880f9ec03 100644 --- a/extra/mariabackup/xbstream.c +++ b/extra/mariabackup/xbstream.c @@ -444,7 +444,11 @@ extract_worker_thread_func(void *arg) } if (chunk.type == XB_CHUNK_TYPE_EOF) { + pthread_mutex_lock(ctxt->mutex); pthread_mutex_unlock(&entry->mutex); + my_hash_delete(ctxt->filehash, (uchar *) entry); + pthread_mutex_unlock(ctxt->mutex); + continue; } diff --git a/include/mysql_com.h b/include/mysql_com.h index 0ca40dd0418..06c934bf9bd 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -387,7 +387,9 @@ enum enum_indicator_type This status flag, when on, implies that one of the state information has changed on the server because of the execution of the last statement. */ -#define SERVER_SESSION_STATE_CHANGED (1UL << 14) +#define SERVER_SESSION_STATE_CHANGED 16384U + +#define SERVER_STATUS_ANSI_QUOTES 32768U /** Server status flags that must be cleared when starting diff --git a/libmariadb b/libmariadb -Subproject 524f14a8e3655e2565d25325764ee40fc659b51 +Subproject eb058204233863f1b949209e5c4649489174d29 diff --git a/mysql-test/include/binlog_parallel_replication_marks.test b/mysql-test/include/binlog_parallel_replication_marks.test new file mode 100644 index 00000000000..a6db745c25b --- /dev/null +++ b/mysql-test/include/binlog_parallel_replication_marks.test @@ -0,0 +1,86 @@ +# Test the markings on GTID events (ddl, waited, trans, +# @@skip_parallel_replication) that are used to control parallel +# replication on the slave. + +--source include/have_innodb.inc + +RESET MASTER; +--source include/wait_for_binlog_checkpoint.inc + +set time_zone="+02:00"; +--let $stable_stamp= `SELECT UNIX_TIMESTAMP("2020-01-21 15:32:22")` +eval set timestamp=$stable_stamp; + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--let $binlog_pos1=query_get_value(SHOW MASTER STATUS, Position, 1) +/* GTID */ INSERT INTO t1 VALUES (1,0); +/* GTID */ BEGIN; +/* GTID */ INSERT INTO t1 VALUES (2,0); +/* GTID */ ALTER TABLE t1 ADD c INT; +/* GTID */ INSERT INTO t1 VALUES (3,0,0); +/* GTID */ COMMIT; +/* GTID */ BEGIN; +/* GTID */ UPDATE t1 SET b=1, c=1 WHERE a=2; +/* GTID */ CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +/* GTID */ INSERT INTO t2 VALUES (4,10), (5,20); +/* GTID */ INSERT INTO t1 SELECT a, 2, b FROM t2; +/* GTID */ DROP TEMPORARY TABLE t2; +/* GTID */ INSERT INTO t1 VALUES (6, 3, 0); +/* GTID */ COMMIT; +/* GTID */ CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ BEGIN; +/* GTID */ DELETE FROM t1 WHERE a=5; +/* GTID */ INSERT INTO t3 VALUES (7); +/* GTID */ INSERT INTO t1 SELECT a, 4, 0 FROM t3; +/* GTID */ UPDATE t1 SET c=1 WHERE a=7; +/* GTID */ DROP TEMPORARY TABLE t3; +/* GTID */ COMMIT; +/* GTID */ CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ BEGIN; +/* GTID */ INSERT INTO t1 VALUES (8, 5, 0); +/* GTID */ ALTER TABLE t4 ADD b INT; +/* GTID */ INSERT INTO t1 VALUES (9, 5, 1); +/* GTID */ COMMIT; +connect (tmp_con,localhost,root,,); +eval set timestamp=$stable_stamp; +/* GTID */ INSERT INTO t1 VALUES (10, 6, 0); +/* GTID */ BEGIN; +/* GTID */ CREATE TEMPORARY TABLE t5 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ INSERT INTO t1 VALUES (11, 7, 0); +/* GTID */ COMMIT; +--let $before_drop_pos=query_get_value(SHOW MASTER STATUS, Position, 1) +disconnect tmp_con; +connection default; + +# We need to wait for the implicit DROP TEMPORARY TABLE to be logged after +# tmp_con disconnect, otherwise we get sporadic test failures. +--let $wait_condition= SELECT variable_value > $before_drop_pos FROM information_schema.global_status WHERE variable_name = 'binlog_snapshot_position' +--source include/wait_condition.inc + +--let $binlog_pos2=query_get_value(SHOW MASTER STATUS, Position, 1) + +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; + +--let $MYSQLD_DATADIR= `select @@datadir` +--let $file= $MYSQLTEST_VARDIR/tmp/binlog_parallel_replication_marks.out +--let OUTPUT_FILE=$file +exec $MYSQL_BINLOG --start_position=$binlog_pos1 --stop_position=$binlog_pos2 $MYSQLD_DATADIR/$binlog_file > $file; + +perl; +my $file= $ENV{'OUTPUT_FILE'}; +open F, "<", $file + or die "Unable to open file '$file': $!\n"; +while (<F>) { + s/^#\d+ \d+:\d+:\d+ /# /; + s/GTID \d+-\d+-\d+/GTID #-#-#/; + s/end_log_pos \d+/end_log_pos #/; + s/table id \d+/table id #/; + s/mapped to number \d+/mapped to number #/; + s/CRC32 0x[0-9a-f]+/CRC32 0x########/; + print if /GTID|BEGIN|COMMIT|Table_map|Write_rows|Update_rows|Delete_rows|generated by server|40005 TEMPORARY/; +} +close F; +EOF + +DROP TABLE t1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e4a44214ce8..1c1d0f17a26 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3085,6 +3085,7 @@ sub mysql_install_db { my $args; mtr_init_args(\$args); mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--disable-getopt-prefix-matching"); mtr_add_arg($args, "--bootstrap"); mtr_add_arg($args, "--basedir=%s", $install_basedir); mtr_add_arg($args, "--datadir=%s", $install_datadir); diff --git a/mysql-test/r/contributors.result b/mysql-test/r/contributors.result index 4a26d0f19dd..5d92184f191 100644 --- a/mysql-test/r/contributors.result +++ b/mysql-test/r/contributors.result @@ -2,9 +2,11 @@ SHOW CONTRIBUTORS; Name Location Comment Booking.com https://www.booking.com Founding member, Platinum Sponsor of the MariaDB Foundation Alibaba Cloud https://intl.aliyun.com Platinum Sponsor of the MariaDB Foundation +Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundation MariaDB Corporation https://mariadb.com Founding member, Gold Sponsor of the MariaDB Foundation Visma https://visma.com Gold Sponsor of the MariaDB Foundation DBS https://dbs.com Gold Sponsor of the MariaDB Foundation +IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation Nexedi https://www.nexedi.com Silver Sponsor of the MariaDB Foundation Acronis http://www.acronis.com Silver Sponsor of the MariaDB Foundation Auttomattic https://automattic.com Bronze Sponsor of the MariaDB Foundation diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 389a5d3850a..08af0186080 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -5606,6 +5606,23 @@ SELECT 'a','aa'; a aa a aa # +# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +# +SET NAMES utf8, character_set_connection=ucs2; +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_utf8'derived_merge=on'; +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SET NAMES utf8, character_set_connection=ucs2; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub; +c2 +616263646566676869-616263646566676869 +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub; +c2 +YWJjZGVmZ2hp-YWJjZGVmZ2hp +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# # End of 10.0 tests # select collation(cast("a" as char(10) unicode binary)); diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index cf3e738395a..6e88ad00ad9 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -172,3 +172,7 @@ UPDATE t1 SET a = 'new' WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; ERROR 22007: Illegal value used as argument of dynamic column function drop table t1; +set max_session_mem_used = 8192; +select * from seq_1_to_1000; +Got one of the listed errors +set global max_session_mem_used = default; diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result index 925158ab129..b87ee7bfc52 100644 --- a/mysql-test/r/func_concat.result +++ b/mysql-test/r/func_concat.result @@ -149,3 +149,116 @@ CALL p1(); ########################################40100.000 DROP PROCEDURE p1; # End of 5.1 tests +# +# Start of 10.0 tests +# +# +# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('1234567'); +SELECT CONCAT(SUBSTR(t2, 1, 3), SUBSTR(t2, 5)) c1, +CONCAT(SUBSTR(t2,1,3),'---',SUBSTR(t2,5)) c2 +FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; +c1 c2 +123567 123---567 +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; +c2 +1234567-1234567 +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('1234567'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; +c2 +1234567-1234567 +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT REVERSE(t) t2 FROM t1) sub; +c2 +7654321-7654321 +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SOUNDEX(t) t2 FROM t1) sub; +c2 +- +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub; +c2 +MTIzNDU2Nw==-MTIzNDU2Nw== +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT WEIGHT_STRING(t) t2 FROM t1) sub; +c2 +1234567-1234567 +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub; +c2 +31323334353637-31323334353637 +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT QUOTE(t) t2 FROM t1) sub; +c2 +'1234567'-'1234567' +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES(TO_BASE64('abcdefghi')); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FROM_BASE64(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES(HEX('abcdefghi')); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UNHEX(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(30) CHARSET latin1); +INSERT INTO t1 VALUES('test'); +SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub; +c2 +16 +SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub; +c2 +33 +SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub; +c2 +34 +SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub; +c2 +4 +SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub; +c2 +9 +SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub; +c2 +10 +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(64) CHARSET latin1); +INSERT INTO t1 VALUES('123456789'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT MD5(t) t2 FROM t1) sub; +c2 +25f9e794323b453885f5181f1b624d0b-25f9e794323b453885f5181f1b624d0b +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FORMAT(t,2) t2 FROM t1) sub; +c2 +123,456,789.00-123,456,789.00 +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT INSERT(t,3,4,'xxx') t2 FROM t1) sub; +c2 +abxxxghi-abxxxghi +DROP TABLE t1; +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LEFT(t,10) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RIGHT(t,10) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SUBSTR(t,1,10) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LTRIM(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RTRIM(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TRIM(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/func_crypt.result b/mysql-test/r/func_crypt.result index c8a621e2fd3..aaa6aa61eae 100644 --- a/mysql-test/r/func_crypt.result +++ b/mysql-test/r/func_crypt.result @@ -107,6 +107,24 @@ OLD_PASSWORD(c1) PASSWORD(c1) DROP TABLE t1; # End of 5.0 tests # +# Start of 10.0 tests +# +# +# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT ENCRYPT(t,'aa') t2 FROM t1) sub; +c2 +aaHHlPHAM4sjs-aaHHlPHAM4sjs +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# +# End of 10.0 tests +# +# # Start of 10.1 tests # # Start of func_str_ascii_checksum.inc diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 31335dc2af6..49618c5c8a6 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -1713,6 +1713,24 @@ AsText(g) NULL POINT(1 1) # +# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 (x INT, y INT); +INSERT INTO t1 VALUES(0,0); +SELECT LENGTH(t2) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub; +c2 +25 +SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub; +c2 +51 +SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub; +c2 +52 +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# # End 10.0 tests # SHOW CREATE TABLE information_schema.geometry_columns; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 4097a22ea43..09f014da627 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -544,3 +544,61 @@ ERROR 1300 (HY000) at line 2: Invalid utf8 character string: 'test\xF0\x9F\x98\x set GLOBAL sql_mode=default; End of tests +create table `a1\``b1` (a int); +show tables; +Tables_in_test +a1\`b1 +insert `a1\``b1` values (1),(2); +show create table `a1\``b1`; +Table Create Table +a1\`b1 CREATE TABLE `a1\``b1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `a1\``b1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `a1\``b1` VALUES (1),(2); +insert `a1\``b1` values (4),(5); +show create table `a1\``b1`; +Table Create Table +a1\`b1 CREATE TABLE `a1\``b1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from `a1\``b1`; +a +1 +2 +drop table `a1\``b1`; +set sql_mode=ansi_quotes; +create table "a1\""b1" (a int); +show tables; +Tables_in_test +a1\"b1 +insert "a1\""b1" values (1),(2); +show create table "a1\""b1"; +Table Create Table +a1\"b1 CREATE TABLE "a1\""b1" ( + "a" int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE "a1\""b1" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO "a1\""b1" VALUES (1),(2); +insert "a1\""b1" values (4),(5); +show create table "a1\""b1"; +Table Create Table +a1\"b1 CREATE TABLE "a1\""b1" ( + "a" int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from "a1\""b1"; +a +1 +2 +drop table "a1\""b1"; +set sql_mode=default; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index bc4c96ed26f..8716274dd4b 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1,3 +1,4 @@ +Windows bug: happens when a new line is exactly at the right offset The following options may be given as the first argument: --print-defaults Print the program argument list and exit. --no-defaults Don't read default options from any option file. @@ -1258,7 +1259,7 @@ ft-query-expansion-limit 20 ft-stopword-file (No default value) gdb FALSE general-log FALSE -getopt-prefix-matching TRUE +getopt-prefix-matching FALSE group-concat-max-len 1048576 gtid-domain-id 0 gtid-ignore-duplicates FALSE diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 237f04d6d28..fe269152357 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -983,5 +983,10 @@ disconnect con1; con2 disconnect con2; -closed_connection- -End of tests connection default; +set sql_mode=no_backslash_escapes; +select "foo\""bar"; +foo\"bar +foo\"bar +set sql_mode=default; +End of tests diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 02381ebeed5..f43e6ce18af 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -3143,3 +3143,19 @@ id select_type table type possible_keys key key_len ref rows Extra drop table t0,t1,t2,t3; set @@optimizer_switch=@tmp_8989; set optimizer_switch='orderby_uses_equalities=on'; +# +# MDEV-10880: Assertions `keypart_map' or +# `prebuilt->search_tuple->n_fields > 0' fail on DISTINCT and +# GROUP BY constant +# +CREATE TABLE t1 (pk INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT DISTINCT pk FROM t1 GROUP BY 'foo'; +pk +1 +SELECT DISTINCT pk FROM t1; +pk +1 +2 +3 +DROP TABLE t1; diff --git a/mysql-test/r/partition_alter.result b/mysql-test/r/partition_alter.result index df3ed14e10a..6aa0039c8d2 100644 --- a/mysql-test/r/partition_alter.result +++ b/mysql-test/r/partition_alter.result @@ -100,3 +100,23 @@ t1 CREATE TABLE `t1` ( insert t1 values (2, '2020-01-03', 20); ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` drop table t1; +create table t1 (id_1 int auto_increment, id_2 int, id_3 int, d1 date, dt1 datetime default current_timestamp, dt2 datetime default current_timestamp on update current_timestamp, primary key (id_2, id_3), key(id_1)) partition by hash(id_2) partitions 3 (partition p01, partition p02, partition p03); +insert into t1 values(0, 1, 1, NULL, now(), now()); +alter online table t1 delay_key_write=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id_1` int(11) NOT NULL AUTO_INCREMENT, + `id_2` int(11) NOT NULL, + `id_3` int(11) NOT NULL, + `d1` date DEFAULT NULL, + `dt1` datetime DEFAULT current_timestamp(), + `dt2` datetime DEFAULT current_timestamp() ON UPDATE current_timestamp(), + PRIMARY KEY (`id_2`,`id_3`), + KEY `id_1` (`id_1`) +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 + PARTITION BY HASH (`id_2`) +(PARTITION `p01` ENGINE = MyISAM, + PARTITION `p02` ENGINE = MyISAM, + PARTITION `p03` ENGINE = MyISAM) +drop table t1; diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index ede18083b85..bbcfa7d6980 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2303,6 +2303,94 @@ pk f1 sq 5 3 5 set optimizer_switch= @save_optimizer_switch; DROP TABLE t1,t2; +# +# mdev-12838: scan of materialized of semi-join subquery in join +# +set @save_optimizer_switch=@@optimizer_switch; +CREATE TABLE t1 ( +dispatch_group varchar(32), +assignment_group varchar(32), +sys_id char(32), +PRIMARY KEY (sys_id), +KEY idx1 (dispatch_group), +KEY idx2 (assignment_group) +) ENGINE=MyISAM; +CREATE TABLE t2 ( +ugroup varchar(32), +user varchar(32), +sys_id char(32), +PRIMARY KEY (sys_id), +KEY idx3 (ugroup), +KEY idx4 (user) +) ENGINE=MyISAM; +CREATE TABLE t3 ( +type mediumtext, +sys_id char(32), +PRIMARY KEY (sys_id) +) ENGINE=MyISAM; +set optimizer_switch='materialization=off'; +explain SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary +1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index +SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +assignment_group +df50316637232000158bbfc8bcbe5d23 +e08fad2637232000158bbfc8bcbe5d39 +ec70316637232000158bbfc8bcbe5d60 +7b10fd2637232000158bbfc8bcbe5d30 +ebb4620037332000158bbfc8bcbe5d89 +set optimizer_switch='materialization=on'; +explain SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index +2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where +2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +assignment_group +df50316637232000158bbfc8bcbe5d23 +e08fad2637232000158bbfc8bcbe5d39 +ec70316637232000158bbfc8bcbe5d60 +7b10fd2637232000158bbfc8bcbe5d30 +ebb4620037332000158bbfc8bcbe5d89 +DROP TABLE t1,t2,t3; +set optimizer_switch=@save_optimizer_switch; # End of 5.5 tests # # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result index 17da3a18b4e..bdbe07cf879 100644 --- a/mysql-test/r/subselect_mat_cost_bugs.result +++ b/mysql-test/r/subselect_mat_cost_bugs.result @@ -485,3 +485,20 @@ FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3 ON (f3 = t2b.f2) ); f1 DROP TABLE t1,t2,t3; +# +# MDEV-12963: min/max optimization optimizing away all tables employed +# for uncorrelated IN subquery used in a disjunct of WHERE +# +create table t1 (a int, index idx(a)) engine=myisam; +insert into t1 values (4),(7),(1),(3),(9); +select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5; +a +3 +7 +9 +explain +select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index idx idx 5 NULL 5 Using where; Using index +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1; diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index f0bf539b2fb..3ff0e619188 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -1648,3 +1648,25 @@ Warnings: Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where rand() < 0 drop table t1,t2; set optimizer_switch=@save_optimizer_switch; +# +# mdev-12855: materialization of a semi-join subquery + ORDER BY +# +CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('qux'),('foo'); +CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB; +INSERT INTO t2 VALUES ('bar'),('foo'),('qux'); +SELECT f1 FROM t1 +WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' ) +HAVING f1 != 'foo' +ORDER BY f1; +f1 +qux +explain SELECT f1 FROM t1 +WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' ) +HAVING f1 != 'foo' +ORDER BY f1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index f1 f1 11 NULL 2 Using where; Using index +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 11 func 1 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +DROP TABLE t1,t2; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 72f875cf8a7..8109c36441e 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2343,6 +2343,94 @@ pk f1 sq 5 3 5 set optimizer_switch= @save_optimizer_switch; DROP TABLE t1,t2; +# +# mdev-12838: scan of materialized of semi-join subquery in join +# +set @save_optimizer_switch=@@optimizer_switch; +CREATE TABLE t1 ( +dispatch_group varchar(32), +assignment_group varchar(32), +sys_id char(32), +PRIMARY KEY (sys_id), +KEY idx1 (dispatch_group), +KEY idx2 (assignment_group) +) ENGINE=MyISAM; +CREATE TABLE t2 ( +ugroup varchar(32), +user varchar(32), +sys_id char(32), +PRIMARY KEY (sys_id), +KEY idx3 (ugroup), +KEY idx4 (user) +) ENGINE=MyISAM; +CREATE TABLE t3 ( +type mediumtext, +sys_id char(32), +PRIMARY KEY (sys_id) +) ENGINE=MyISAM; +set optimizer_switch='materialization=off'; +explain SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary +1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index +SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +assignment_group +df50316637232000158bbfc8bcbe5d23 +e08fad2637232000158bbfc8bcbe5d39 +ec70316637232000158bbfc8bcbe5d60 +7b10fd2637232000158bbfc8bcbe5d30 +ebb4620037332000158bbfc8bcbe5d89 +set optimizer_switch='materialization=on'; +explain SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index +2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where +2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND +t1.dispatch_group IN +(SELECT t2.ugroup +FROM t2, t3 t3_i +WHERE t2.ugroup = t3_i.sys_id AND +t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND +t2.user = '86826bf03710200044e0bfc8bcbe5d79'); +assignment_group +df50316637232000158bbfc8bcbe5d23 +e08fad2637232000158bbfc8bcbe5d39 +ec70316637232000158bbfc8bcbe5d60 +7b10fd2637232000158bbfc8bcbe5d30 +ebb4620037332000158bbfc8bcbe5d89 +DROP TABLE t1,t2,t3; +set optimizer_switch=@save_optimizer_switch; # End of 5.5 tests # # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index bd0ebb54ee7..1fae4e6ec9f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5991,6 +5991,68 @@ use_case_id InitialDeadline 10 2015-12-18 drop view v1; drop table t1; +# +# MDEV-12666: CURRENT_ROLE() and DATABASE() does not work in a view +# +# DATABASE() fails only when the initial view creation features a NULL +# default database. +# +# CREATE, USE and DROP database so that we have no "default" database. +# +CREATE DATABASE temporary; +USE temporary; +DROP DATABASE temporary; +SELECT DATABASE(); +DATABASE() +NULL +CREATE VIEW test.v_no_db AS SELECT DATABASE() = 'temporary_two'; +SHOW CREATE VIEW test.v_no_db; +View Create View character_set_client collation_connection +v_no_db CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v_no_db` AS select database() = 'temporary_two' AS `DATABASE() = 'temporary_two'` latin1 latin1_swedish_ci +PREPARE prepared_no_database FROM "SELECT DATABASE() = 'temporary_two'"; +# +# All statements should return NULL +# +EXECUTE prepared_no_database; +DATABASE() = 'temporary_two' +NULL +SELECT DATABASE() = 'temporary_two'; +DATABASE() = 'temporary_two' +NULL +SELECT * FROM test.v_no_db; +DATABASE() = 'temporary_two' +NULL +CREATE DATABASE temporary_two; +USE temporary_two; +CREATE VIEW test.v_with_db AS SELECT DATABASE() = 'temporary_two'; +PREPARE prepared_with_database FROM "SELECT DATABASE() = 'temporary_two'"; +# +# All statements should return 1; +# +SELECT DATABASE() = 'temporary_two'; +DATABASE() = 'temporary_two' +1 +SELECT * FROM test.v_no_db; +DATABASE() = 'temporary_two' +1 +SELECT * FROM test.v_with_db; +DATABASE() = 'temporary_two' +1 +EXECUTE prepared_with_database; +DATABASE() = 'temporary_two' +1 +# +# Prepared statements maintain default database to be the same +# during on creation so this should return NULL still. +# See MySQL bug #25843 +# +EXECUTE prepared_no_database; +DATABASE() = 'temporary_two' +NULL +DROP DATABASE temporary_two; +DROP VIEW test.v_no_db; +DROP VIEW test.v_with_db; +USE test; # ----------------------------------------------------------------- # -- End of 10.0 tests. # ----------------------------------------------------------------- @@ -6080,6 +6142,24 @@ three COUNT(*) drop view v1; drop table t1; # +# MDEV-12819: order by ordering expression changed to empty string +# when creatin view with union +# +create table t1 (t1col1 int, t1col2 int,t1col3 int ); +create table t2 (t2col1 int, t2col2 int, t2col3 int); +create view v1 as +select t1col1,t1col2,t1col3 from t1 +union all +select t2col1,t2col2,t2col3 from t2 +order by 2,3; +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 select `t1`.`t1col1` AS `t1col1`,`t1`.`t1col2` AS `t1col2`,`t1`.`t1col3` AS `t1col3` from `t1` union all select `t2`.`t2col1` AS `t2col1`,`t2`.`t2col2` AS `t2col2`,`t2`.`t2col3` AS `t2col3` from `t2` order by 2,3 latin1 latin1_swedish_ci +select * from v1; +t1col1 t1col2 t1col3 +drop view v1; +drop table t1,t2; +# # End of 10.1 tests # # diff --git a/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result b/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result new file mode 100644 index 00000000000..68455cb454b --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result @@ -0,0 +1,113 @@ +RESET MASTER; +set time_zone="+02:00"; +set timestamp=1579613542; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +/* GTID */ INSERT INTO t1 VALUES (1,0); +/* GTID */ BEGIN; +/* GTID */ INSERT INTO t1 VALUES (2,0); +/* GTID */ ALTER TABLE t1 ADD c INT; +/* GTID */ INSERT INTO t1 VALUES (3,0,0); +/* GTID */ COMMIT; +/* GTID */ BEGIN; +/* GTID */ UPDATE t1 SET b=1, c=1 WHERE a=2; +/* GTID */ CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +/* GTID */ INSERT INTO t2 VALUES (4,10), (5,20); +/* GTID */ INSERT INTO t1 SELECT a, 2, b FROM t2; +/* GTID */ DROP TEMPORARY TABLE t2; +/* GTID */ INSERT INTO t1 VALUES (6, 3, 0); +/* GTID */ COMMIT; +/* GTID */ CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ BEGIN; +/* GTID */ DELETE FROM t1 WHERE a=5; +/* GTID */ INSERT INTO t3 VALUES (7); +/* GTID */ INSERT INTO t1 SELECT a, 4, 0 FROM t3; +/* GTID */ UPDATE t1 SET c=1 WHERE a=7; +/* GTID */ DROP TEMPORARY TABLE t3; +/* GTID */ COMMIT; +/* GTID */ CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ BEGIN; +/* GTID */ INSERT INTO t1 VALUES (8, 5, 0); +/* GTID */ ALTER TABLE t4 ADD b INT; +/* GTID */ INSERT INTO t1 VALUES (9, 5, 1); +/* GTID */ COMMIT; +connect tmp_con,localhost,root,,; +set timestamp=1579613542; +/* GTID */ INSERT INTO t1 VALUES (10, 6, 0); +/* GTID */ BEGIN; +/* GTID */ CREATE TEMPORARY TABLE t5 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ INSERT INTO t1 VALUES (11, 7, 0); +/* GTID */ COMMIT; +disconnect tmp_con; +connection default; +FLUSH LOGS; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (1,0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (2,0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +/* GTID */ ALTER TABLE t1 ADD c INT +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (3,0,0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ UPDATE t1 SET b=1, c=1 WHERE a=2 +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Update_rows: table id # flags: STMT_END_F +#Q> /* GTID */ INSERT INTO t1 SELECT a, 2, b FROM t2 +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +#Q> /* GTID */ INSERT INTO t1 VALUES (6, 3, 0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ DELETE FROM t1 WHERE a=5 +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Delete_rows: table id # flags: STMT_END_F +#Q> /* GTID */ INSERT INTO t1 SELECT a, 4, 0 FROM t3 +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +#Q> /* GTID */ UPDATE t1 SET c=1 WHERE a=7 +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Update_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (8, 5, 0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (9, 5, 1) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (10, 6, 0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +#Q> /* GTID */ INSERT INTO t1 VALUES (11, 7, 0) +# server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # +# server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t5` +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_stm_mix.result b/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_stm_mix.result new file mode 100644 index 00000000000..d0ccb2adc14 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_stm_mix.result @@ -0,0 +1,99 @@ +RESET MASTER; +set time_zone="+02:00"; +set timestamp=1579613542; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +/* GTID */ INSERT INTO t1 VALUES (1,0); +/* GTID */ BEGIN; +/* GTID */ INSERT INTO t1 VALUES (2,0); +/* GTID */ ALTER TABLE t1 ADD c INT; +/* GTID */ INSERT INTO t1 VALUES (3,0,0); +/* GTID */ COMMIT; +/* GTID */ BEGIN; +/* GTID */ UPDATE t1 SET b=1, c=1 WHERE a=2; +/* GTID */ CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +/* GTID */ INSERT INTO t2 VALUES (4,10), (5,20); +/* GTID */ INSERT INTO t1 SELECT a, 2, b FROM t2; +/* GTID */ DROP TEMPORARY TABLE t2; +/* GTID */ INSERT INTO t1 VALUES (6, 3, 0); +/* GTID */ COMMIT; +/* GTID */ CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ BEGIN; +/* GTID */ DELETE FROM t1 WHERE a=5; +/* GTID */ INSERT INTO t3 VALUES (7); +/* GTID */ INSERT INTO t1 SELECT a, 4, 0 FROM t3; +/* GTID */ UPDATE t1 SET c=1 WHERE a=7; +/* GTID */ DROP TEMPORARY TABLE t3; +/* GTID */ COMMIT; +/* GTID */ CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ BEGIN; +/* GTID */ INSERT INTO t1 VALUES (8, 5, 0); +/* GTID */ ALTER TABLE t4 ADD b INT; +/* GTID */ INSERT INTO t1 VALUES (9, 5, 1); +/* GTID */ COMMIT; +connect tmp_con,localhost,root,,; +set timestamp=1579613542; +/* GTID */ INSERT INTO t1 VALUES (10, 6, 0); +/* GTID */ BEGIN; +/* GTID */ CREATE TEMPORARY TABLE t5 (a INT PRIMARY KEY) ENGINE=InnoDB; +/* GTID */ INSERT INTO t1 VALUES (11, 7, 0); +/* GTID */ COMMIT; +disconnect tmp_con; +connection default; +FLUSH LOGS; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +/* GTID */ INSERT INTO t1 VALUES (1,0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +/* GTID */ INSERT INTO t1 VALUES (2,0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +/* GTID */ ALTER TABLE t1 ADD c INT +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +/* GTID */ INSERT INTO t1 VALUES (3,0,0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +BEGIN +/* GTID */ UPDATE t1 SET b=1, c=1 WHERE a=2 +/* GTID */ CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +/* GTID */ INSERT INTO t2 VALUES (4,10), (5,20) +/* GTID */ INSERT INTO t1 SELECT a, 2, b FROM t2 +DROP TEMPORARY TABLE `t2` /* generated by server */ +/* GTID */ INSERT INTO t1 VALUES (6, 3, 0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +/* GTID */ CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +BEGIN +/* GTID */ DELETE FROM t1 WHERE a=5 +/* GTID */ INSERT INTO t3 VALUES (7) +/* GTID */ INSERT INTO t1 SELECT a, 4, 0 FROM t3 +/* GTID */ UPDATE t1 SET c=1 WHERE a=7 +DROP TEMPORARY TABLE `t3` /* generated by server */ +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +/* GTID */ CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +/* GTID */ INSERT INTO t1 VALUES (8, 5, 0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +/* GTID */ ALTER TABLE t4 ADD b INT +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +/* GTID */ INSERT INTO t1 VALUES (9, 5, 1) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# trans +BEGIN +/* GTID */ INSERT INTO t1 VALUES (10, 6, 0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +BEGIN +/* GTID */ CREATE TEMPORARY TABLE t5 (a INT PRIMARY KEY) ENGINE=InnoDB +/* GTID */ INSERT INTO t1 VALUES (11, 7, 0) +COMMIT/*!*/; +# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl +DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t5` +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/t/binlog_parallel_replication_marks_row.test b/mysql-test/suite/binlog/t/binlog_parallel_replication_marks_row.test new file mode 100644 index 00000000000..82898486089 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_parallel_replication_marks_row.test @@ -0,0 +1,3 @@ +--source include/have_log_bin.inc +--source include/have_binlog_format_row.inc +--source include/binlog_parallel_replication_marks.test diff --git a/mysql-test/suite/binlog/t/binlog_parallel_replication_marks_stm_mix.test b/mysql-test/suite/binlog/t/binlog_parallel_replication_marks_stm_mix.test new file mode 100644 index 00000000000..15042b3a07f --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_parallel_replication_marks_stm_mix.test @@ -0,0 +1,3 @@ +--source include/have_log_bin.inc +--source include/have_binlog_format_mixed_or_statement.inc +--source include/binlog_parallel_replication_marks.test diff --git a/mysql-test/suite/galera/r/MW-369.result b/mysql-test/suite/galera/r/MW-369.result new file mode 100644 index 00000000000..516904d1b2a --- /dev/null +++ b/mysql-test/suite/galera/r/MW-369.result @@ -0,0 +1,155 @@ +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +DELETE FROM p WHERE f1 = 1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +INSERT INTO c VALUES (1, 1); +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +1 0 +2 0 +SELECT * FROM c; +f1 p_id +1 1 +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, +f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p SET f2 = 1 WHERE f1 = 1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +UPDATE c SET f2 = 1 WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +SELECT * FROM p; +f1 f2 +1 1 +2 0 +SELECT * FROM c; +f1 p_id f2 +1 1 1 +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p SET f2 = 1 WHERE f1 = 1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +DELETE FROM c WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +SELECT * FROM p; +f1 f2 +1 1 +2 0 +SELECT * FROM c; +f1 p_id +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER UNIQUE KEY) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f2)) ; +INSERT INTO p VALUES (1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p SET f2 = 1 WHERE f1 = 1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +INSERT INTO c VALUES (1, 0);; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +1 0 +SELECT * FROM c; +f1 p_id +1 0 +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) +ON DELETE CASCADE) ; +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +DELETE FROM p WHERE f1 = 1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +UPDATE c SET f2 = 1 WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +1 0 +2 0 +SELECT * FROM c; +f1 p_id f2 +1 1 1 +DROP TABLE c; +DROP TABLE p; diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result index cb306734002..9a0cd03d153 100644 --- a/mysql-test/suite/galera/r/galera_defaults.result +++ b/mysql-test/suite/galera/r/galera_defaults.result @@ -1,5 +1,5 @@ -SELECT COUNT(*) = 42 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%'; -COUNT(*) = 42 +SELECT COUNT(*) = 43 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%'; +COUNT(*) = 43 1 SELECT VARIABLE_NAME, VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -26,6 +26,7 @@ WSREP_CONVERT_LOCK_TO_TRX OFF WSREP_DBUG_OPTION WSREP_DEBUG OFF WSREP_DESYNC OFF +WSREP_DIRTY_READS OFF WSREP_DRUPAL_282555_WORKAROUND OFF WSREP_FORCED_BINLOG_FORMAT NONE WSREP_GTID_DOMAIN_ID 0 @@ -50,7 +51,7 @@ WSREP_SST_DONOR WSREP_SST_DONOR_REJECTS_QUERIES OFF WSREP_SST_METHOD rsync WSREP_SYNC_WAIT 7 -<BASE_DIR>; <BASE_HOST>; <BASE_PORT>; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; <GCACHE_DIR>; gcache.keep_pages_size = 0; gcache.mem_size = 0; <GCACHE_NAME>; gcache.page_size = 128M; gcache.recover = no; gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; <RECV_Q_HARD_LIMIT>;gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; <GMCAST_LISTEN_ADDR>; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; <IST_RECV_ADDR>; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = PT30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; +<BASE_DIR>; <BASE_HOST>; <BASE_PORT>; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT15S; evs.info_log_mask = 0; evs.install_timeout = PT7.5S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; <GCACHE_DIR>; gcache.keep_pages_size = 0; gcache.mem_size = 0; <GCACHE_NAME>; gcache.page_size = 128M; gcache.recover = no; gcache.size = 10M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; <GCS_RECV_Q_HARD_LIMIT>; gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; <GMCAST_LISTEN_ADDR>; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; <IST_RECV_ADDR>; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = PT30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep_%' AND VARIABLE_NAME != 'wsrep_debug_sync_waiters'; diff --git a/mysql-test/suite/galera/r/galera_var_node_address.result b/mysql-test/suite/galera/r/galera_var_node_address.result index fe3b5613903..c9c9b52d9cb 100644 --- a/mysql-test/suite/galera/r/galera_var_node_address.result +++ b/mysql-test/suite/galera/r/galera_var_node_address.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("WSREP: Stray state UUID msg: .* current group state WAIT_STATE_UUID .*"); SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 4 1 diff --git a/mysql-test/suite/galera/t/MW-369.inc b/mysql-test/suite/galera/t/MW-369.inc new file mode 100644 index 00000000000..5fd9ef150ae --- /dev/null +++ b/mysql-test/suite/galera/t/MW-369.inc @@ -0,0 +1,75 @@ +# +# This file should be included from tests for MW-369 to run concurrent +# transaction from node_1 with autocommit query from node_2. +# +# The parameters: +# * $mw_369_parent_query - the parent query to be run inside transaction +# * $mw_369_child_query - the child query +# +# The operations are the following: +# +# node_1: +# START TRANSACTION; +# $mw_369_parent_query +# node_2 +# $mw_369_child_query - will be blocked on node_1 in apply monitor +# node_1: +# COMMIT; - will be blocked on node_1 in local monitor +# +# The $mw_369_child_query is always expected to succeed. The caller is +# responsible for checking if the final COMMIT on connection node_1 +# succeeds. +# + +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; + +--eval $mw_369_parent_query + +# +# Block the $mw_369_child_query from node_2 +# +# --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +# +# insert client row, which will make it impossible to replay the +# delete on parent +# +--connection node_2 +--eval $mw_369_child_query + +# +# Wait until $mw_369_child_query from node_2 reaches the sync point and +# block the 'COMMIT' from node_1 before it certifies. +# +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--let $galera_sync_point = local_monitor_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +--send COMMIT + +# +# Wait until both sync points have been reached +# +--connection node_1a +--let $galera_sync_point = apply_monitor_slave_enter_sync local_monitor_enter_sync +--source include/galera_wait_sync_point.inc + +# +# both threads are now parked in sync points, signal them to continue +# +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc + +--let $galera_sync_point = local_monitor_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc diff --git a/mysql-test/suite/galera/t/MW-369.test b/mysql-test/suite/galera/t/MW-369.test new file mode 100644 index 00000000000..bfb9460b411 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-369.test @@ -0,0 +1,247 @@ +# +# Test A Outline: +# =============== +# +# This test tests the scenario for MW-369 where a new child table +# row referring to parent table row is inserted concurrently from +# another node while the transaction which tries to delete a +# referred row from the parent table is committing. +# +# The p table will originally have rows (1, 0), (2, 0). +# The c table will be empty. +# +# A new row (1, 1) pointing to parent row (1, 0) is inserted from +# connection node_2, the transaction which tries to remove the +# parent row (1, 0) is run from connection node_1. +# +# Expected outcome: +# ================ +# +# The transaction on node_1 will fail. The parent table will contain +# rows (1, 0), (2, 0) and the child table will contain row (1, 1). +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source suite/galera/include/galera_have_debug_sync.inc + +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); + +--let $mw_369_parent_query = DELETE FROM p WHERE f1 = 1 +--let $mw_369_child_query = INSERT INTO c VALUES (1, 1) + +# +# we must open connection node_1a here, MW-369.inc will use it later +# +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +# +# Test B Outline: +# =============== +# +# This test tests the scenario for MW-369 where a existing +# child table row is updated concurrently from another node +# with a transaction which updates the parent table. +# +# The p table will originally have rows (1, 0), (2, 0). +# The c table will originally have rows (1, 1, 0) which points +# to parent table row (1, 0). +# +# Expected outcome: +# ================ +# +# Both updates should succeed since they are done to separate tables and +# rows. The parent table will contain rows (1, 1), (2, 0). The child +# table will contain row (1, 1, 1). +# + +--connection node_1 +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, + f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); + +--let mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1 +--let $mw_369_child_query = UPDATE c SET f2 = 1 WHERE f1 = 1 +--source MW-369.inc + +# Commit succeeds +--connection node_1 +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +# +# Test C Outline: +# =============== +# +# This test tests the scenario for MW-369 where a child table row is +# deleted concurrently from the other node while a transaction updates +# the parent table referred by the child table row. +# +# The p table will originally have rows (1, 0), (2, 0) +# The c table will originally have row (1, 1) which points to parent +# table row (1, 0). +# +# A row (1, 1) pointing to parent row (1, 0) is deleted from +# connection node_2, the transaction which tries to update the +# parent row (1, 0) is run from connection node_1. +# +# Expected Outcome: +# ================ +# Both operations on node_1 and node_2 should succeed without conflicts. +# The parent table should contain values (1, 1), (2, 0) and the child +# table should be empty. + +--connection node_1 +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1); + +--let $mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1 +--let $mw_369_child_query = DELETE FROM c WHERE f1 = 1 +--source MW-369.inc + +# Commit succeeds +--connection node_1 +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + + +# +# Test D Outline: +# =============== +# +# This test is similar to test A, where parent row is deleted while a child row +# is inserted simultaneously on node 2. However, in this test case the FK +# constraint's target column is a unique key, and parent row is not delete, +# but this key value is changed so that insert on node 2 will cause FK +# violation +# +# The p table will originally have rows (1, 0) +# The c table will originally be empty +# +# in node_1, parent row is updated to value (1,1) +# A row (1, 0) pointing to the old version of parent row (1, 0) is inserted +# in connection node_2 +# +# Expected Outcome: +# ================ +# This is a true conflict and one transaciton must abort. In this case it is node_1 +# transaction, which was scheduled later. +# Parent table should have row (1,0) +# child table should have row (1,0) +# + +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER UNIQUE KEY) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f2)) ; + +INSERT INTO p VALUES (1, 0); + +--let $mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1 +--let $mw_369_child_query = INSERT INTO c VALUES (1, 0); +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +# +# Test E Outline: +# =============== +# +# This test is similar to test B, where parent row is deleted while a child row +# is updated simultaneously on node 2. However, in this test case the FK +# constraint has ON DELETE CASCADE option, and the delete on parent row will +# cascade a delete on child row as well. This will cause true conflict with +# connection node_2, which tries to update unrelated column on child table. +# +# The p table will originally have rows (1, 0), (2,0) +# The c table will originally have row (1,1,0) +# +# in node_1, parent row (1,0) is deleted and cascaded delete will happen on +# child table row (1,1,0). +# in connection node_2 child table row is update to value (1,1,1) +# +# Expected Outcome: +# ================ +# This is a true conflict and one transaciton must abort. In this case it is node_1 +# transaction, which was scheduled later. +# Parent table should have rows (1,0), (2,0) +# child table should have row (1,1,1) +# + + +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) + ON DELETE CASCADE) ; + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); + +--let $mw_369_parent_query = DELETE FROM p WHERE f1 = 1 +--let $mw_369_child_query = UPDATE c SET f2 = 1 WHERE f1 = 1 +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +--sleep 3 diff --git a/mysql-test/suite/galera/t/galera_defaults.test b/mysql-test/suite/galera/t/galera_defaults.test index 3b1cb7b8650..32fc24097d2 100644 --- a/mysql-test/suite/galera/t/galera_defaults.test +++ b/mysql-test/suite/galera/t/galera_defaults.test @@ -13,13 +13,13 @@ # Make sure that the test is operating on the right version of galera library. --disable_query_log ---let $galera_version=25.3.17 +--let $galera_version=3.20 source ../wsrep/include/check_galera_version.inc; --enable_query_log # Global Variables -SELECT COUNT(*) = 42 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%'; +SELECT COUNT(*) = 43 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%'; SELECT VARIABLE_NAME, VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES diff --git a/mysql-test/suite/galera/t/galera_var_node_address.test b/mysql-test/suite/galera/t/galera_var_node_address.test index cf118cf9934..c2105823326 100644 --- a/mysql-test/suite/galera/t/galera_var_node_address.test +++ b/mysql-test/suite/galera/t/galera_var_node_address.test @@ -6,6 +6,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +call mtr.add_suppression("WSREP: Stray state UUID msg: .* current group state WAIT_STATE_UUID .*"); SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --connection node_1 diff --git a/mysql-test/suite/ndb/r/ndb_restore_discover.result b/mysql-test/suite/ndb/r/ndb_restore_discover.result deleted file mode 100644 index de10af87047..00000000000 --- a/mysql-test/suite/ndb/r/ndb_restore_discover.result +++ /dev/null @@ -1,33 +0,0 @@ -# -# 18075170 - sql node restart required to avoid deadlock after -# restore -# -CREATE TABLE t1 (id INT) ENGINE=NDBCluster; -CREATE TABLE t2 (id INT) ENGINE=NDBCluster; -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); -DROP TABLE t1; -DROP TABLE t2; -SET autocommit = 0; -SELECT * FROM t1; -id -1 -SELECT * FROM t2; -id -1 -ROLLBACK; -SET autocommit = 1; -drop table t1; -drop table t2; -SET autocommit = 0; -SELECT * FROM t1; -id -1 -SELECT * FROM t2; -id -1 -ALTER TABLE t1 ADD val INT; -ROLLBACK; -SET autocommit = 1; -drop table t1; -drop table t2; diff --git a/mysql-test/suite/ndb/t/ndb_restore_discover.test b/mysql-test/suite/ndb/t/ndb_restore_discover.test deleted file mode 100644 index 6631c74d5c8..00000000000 --- a/mysql-test/suite/ndb/t/ndb_restore_discover.test +++ /dev/null @@ -1,70 +0,0 @@ --- source include/have_ndb.inc --- source include/count_sessions.inc - ---echo # ---echo # 18075170 - sql node restart required to avoid deadlock after ---echo # restore ---echo # -# Test Auto Discover option within a transaction -# and make sure the transaction is not broken. -CREATE TABLE t1 (id INT) ENGINE=NDBCluster; -CREATE TABLE t2 (id INT) ENGINE=NDBCluster; - -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); - --- source include/ndb_backup.inc - -DROP TABLE t1; -DROP TABLE t2; - --- source include/ndb_restore_master.inc - -SET autocommit = 0; -SELECT * FROM t1; - -# Without fix below select was resulting in DEADLOCK error. With fix select -# should succeed. -SELECT * FROM t2; -ROLLBACK; -SET autocommit = 1; - -drop table t1; -drop table t2; - -# -# Checking lock preservation in transaction -# -# Using existing backup to create the scenario. Tables are deleted as part of -# above test cleanup. Thus restoring the backup will bring the system to -# required state. --- source include/ndb_restore_master.inc - -SET autocommit = 0; -SELECT * FROM t1; -SELECT * FROM t2; - -connect(con2, localhost, root); ---SEND ALTER TABLE t1 ADD val INT - -connection default; -# Alter from con2 will be in waiting state as there is a lock on t1 from -# default connection due to active transaction. We check for this condition -# then releasing the lock by rollbacking active transaction. -let $wait_condition= - SELECT count(*) = 1 FROM information_schema.processlist WHERE state - LIKE "Waiting%" AND info = "ALTER TABLE t1 ADD val INT"; ---source include/wait_condition.inc -ROLLBACK; -SET autocommit = 1; - -connection con2; ---REAP - -disconnect con2; -connection default; -drop table t1; -drop table t2; - -# Wait till all disconnects are completed --- source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/perfschema/r/bad_option_2.result b/mysql-test/suite/perfschema/r/bad_option_2.result index d8fda2af3b6..7a5ab31aabd 100644 --- a/mysql-test/suite/perfschema/r/bad_option_2.result +++ b/mysql-test/suite/perfschema/r/bad_option_2.result @@ -1 +1 @@ -Found: ambiguous option '--performance-schema-max_=12' +FOUND 1 /ambiguous option '--performance-schema-max_=12'/ in bad_option_2.txt diff --git a/mysql-test/suite/perfschema/t/bad_option_2.test b/mysql-test/suite/perfschema/t/bad_option_2.test index 175767bb9f2..ce3e5c3243b 100644 --- a/mysql-test/suite/perfschema/t/bad_option_2.test +++ b/mysql-test/suite/perfschema/t/bad_option_2.test @@ -8,26 +8,9 @@ let $outfile= $MYSQLTEST_VARDIR/tmp/bad_option_2.txt; --error 0,1 --remove_file $outfile --error 3 ---exec $MYSQLD_BOOTSTRAP_CMD --loose-console --performance-schema-max_=12 > $outfile 2>&1 - -perl; - use strict; - use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/bad_option_2.txt"; - open(FILE, "<", $fname) or die; - my @lines= <FILE>; - # those must be in the file for the test to pass - my @patterns= - ("ambiguous option '--performance-schema-max_=12'"); - foreach my $one_line (@lines) - { - foreach my $one_pattern (@patterns) - { - # print pattern, not line, to get a stable output - print "Found: $one_pattern\n" if ($one_line =~ /$one_pattern/); - } - } - close FILE; -EOF +--exec $MYSQLD_BOOTSTRAP_CMD --loose-console --enable-getopt-prefix-matching --performance-schema-max_=12 > $outfile 2>&1 +--let SEARCH_PATTERN=ambiguous option '--performance-schema-max_=12' +--let SEARCH_FILE=$outfile +--source include/search_pattern_in_file.inc --remove_file $outfile diff --git a/mysql-test/suite/roles/current_role_view-12666.result b/mysql-test/suite/roles/current_role_view-12666.result new file mode 100644 index 00000000000..1d7a8b054df --- /dev/null +++ b/mysql-test/suite/roles/current_role_view-12666.result @@ -0,0 +1,103 @@ +CREATE USER has_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO has_role@'localhost'; +CREATE ROLE test_role; +GRANT test_role TO has_role@'localhost'; +CREATE USER no_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO no_role@'localhost'; +CREATE TABLE view_role_test ( +id int primary key, +role_name varchar(50) +); +INSERT INTO view_role_test VALUES (1, 'test_role'); +# +# Use the same logic for stored procedures. +# +PREPARE prepared_no_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; +# +# Creating a view with no CURRENT_ROLE() set and one with CURRENT_ROLE() +# set. Both should produce the same SHOW CREATE VIEW output. +# +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_no_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SHOW CREATE VIEW v_view_role_test_no_current_role; +View Create View character_set_client collation_connection +v_view_role_test_no_current_role CREATE ALGORITHM=UNDEFINED DEFINER=`no_role`@`localhost` SQL SECURITY INVOKER VIEW `v_view_role_test_no_current_role` AS select `view_role_test`.`id` AS `id`,`view_role_test`.`role_name` AS `role_name` from `view_role_test` where `view_role_test`.`role_name` = current_role() latin1 latin1_swedish_ci +# +# No values should be returned +# +EXECUTE prepared_no_current_role; +id role_name +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +id role_name +SELECT * FROM v_view_role_test_no_current_role; +id role_name +# +# Now let's set the role. Create identical views as before. See if +# their behaviour is different. It should not be. +# +SET ROLE test_role; +SELECT CURRENT_USER(); +CURRENT_USER() +root@localhost +SELECT CURRENT_ROLE(); +CURRENT_ROLE() +test_role +# +# Create the VIEW and prepared Statement with a CURRENT_ROLE() set. +# +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_with_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +PREPARE prepared_with_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; +SHOW CREATE VIEW v_view_role_test_with_current_role; +View Create View character_set_client collation_connection +v_view_role_test_with_current_role CREATE ALGORITHM=UNDEFINED DEFINER=`no_role`@`localhost` SQL SECURITY INVOKER VIEW `v_view_role_test_with_current_role` AS select `view_role_test`.`id` AS `id`,`view_role_test`.`role_name` AS `role_name` from `view_role_test` where `view_role_test`.`role_name` = current_role() latin1 latin1_swedish_ci +# +# Values should be returned for all select statements as we do have +# a CURRENT_ROLE() active; +# +EXECUTE prepared_no_current_role; +id role_name +1 test_role +EXECUTE prepared_with_current_role; +id role_name +1 test_role +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +id role_name +1 test_role +SELECT * FROM v_view_role_test_no_current_role; +id role_name +1 test_role +SELECT * FROM v_view_role_test_with_current_role; +id role_name +1 test_role +SET ROLE NONE; +# +# No values should be returned for all select statements as we do not have +# a CURRENT_ROLE() active; +# +EXECUTE prepared_no_current_role; +id role_name +EXECUTE prepared_with_current_role; +id role_name +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +id role_name +SELECT * FROM v_view_role_test_no_current_role; +id role_name +SELECT * FROM v_view_role_test_with_current_role; +id role_name +DROP USER has_role@'localhost'; +DROP USER no_role@'localhost'; +DROP ROLE test_role; +DROP table view_role_test; +DROP VIEW v_view_role_test_no_current_role; +DROP VIEW v_view_role_test_with_current_role; +DROP PREPARE prepared_no_current_role; +DROP PREPARE prepared_with_current_role; diff --git a/mysql-test/suite/roles/current_role_view-12666.test b/mysql-test/suite/roles/current_role_view-12666.test new file mode 100644 index 00000000000..32039ffef07 --- /dev/null +++ b/mysql-test/suite/roles/current_role_view-12666.test @@ -0,0 +1,102 @@ +# +# MDEV-12666 CURRENT_ROLE() does not work in a view +# +--source include/not_embedded.inc + +CREATE USER has_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO has_role@'localhost'; + +CREATE ROLE test_role; +GRANT test_role TO has_role@'localhost'; + +CREATE USER no_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO no_role@'localhost'; + +CREATE TABLE view_role_test ( + id int primary key, + role_name varchar(50) + ); + +INSERT INTO view_role_test VALUES (1, 'test_role'); + +--echo # +--echo # Use the same logic for stored procedures. +--echo # +PREPARE prepared_no_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; + +--echo # +--echo # Creating a view with no CURRENT_ROLE() set and one with CURRENT_ROLE() +--echo # set. Both should produce the same SHOW CREATE VIEW output. +--echo # +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_no_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); + +SHOW CREATE VIEW v_view_role_test_no_current_role; + + +--echo # +--echo # No values should be returned +--echo # +EXECUTE prepared_no_current_role; +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SELECT * FROM v_view_role_test_no_current_role; + +--echo # +--echo # Now let's set the role. Create identical views as before. See if +--echo # their behaviour is different. It should not be. +--echo # +SET ROLE test_role; + +SELECT CURRENT_USER(); +SELECT CURRENT_ROLE(); + +--echo # +--echo # Create the VIEW and prepared Statement with a CURRENT_ROLE() set. +--echo # +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_with_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); + +PREPARE prepared_with_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; + +SHOW CREATE VIEW v_view_role_test_with_current_role; + + +--echo # +--echo # Values should be returned for all select statements as we do have +--echo # a CURRENT_ROLE() active; +--echo # +EXECUTE prepared_no_current_role; +EXECUTE prepared_with_current_role; +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SELECT * FROM v_view_role_test_no_current_role; +SELECT * FROM v_view_role_test_with_current_role; + +SET ROLE NONE; +--echo # +--echo # No values should be returned for all select statements as we do not have +--echo # a CURRENT_ROLE() active; +--echo # +EXECUTE prepared_no_current_role; +EXECUTE prepared_with_current_role; +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SELECT * FROM v_view_role_test_no_current_role; +SELECT * FROM v_view_role_test_with_current_role; + + +DROP USER has_role@'localhost'; +DROP USER no_role@'localhost'; +DROP ROLE test_role; + +DROP table view_role_test; +DROP VIEW v_view_role_test_no_current_role; +DROP VIEW v_view_role_test_with_current_role; +DROP PREPARE prepared_no_current_role; +DROP PREPARE prepared_with_current_role; diff --git a/mysql-test/suite/roles/show_create_database-10463.result b/mysql-test/suite/roles/show_create_database-10463.result new file mode 100644 index 00000000000..a9b376a891f --- /dev/null +++ b/mysql-test/suite/roles/show_create_database-10463.result @@ -0,0 +1,69 @@ +drop database if exists db; +Warnings: +Note 1008 Can't drop database 'db'; database doesn't exist +create role r1; +create user beep@'%'; +create database db; +create table db.t1 (i int); +create table db.t2 (b int); +grant select on db.* to r1; +grant r1 to beep@'%'; +connect con1,localhost,beep,,; +show databases; +Database +information_schema +test +show create database db; +ERROR 42000: Access denied for user 'beep'@'localhost' to database 'db' +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; +table_schema table_name +set role r1; +show databases; +Database +db +information_schema +test +show create database db; +Database Create Database +db CREATE DATABASE `db` /*!40100 DEFAULT CHARACTER SET latin1 */ +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; +table_schema table_name +db t1 +db t2 +connection default; +create role r2; +create user beep2@'%'; +grant update on db.* to r2; +grant r2 to beep2; +connect con2,localhost,beep2,,; +show databases; +Database +information_schema +test +show create database db; +ERROR 42000: Access denied for user 'beep2'@'localhost' to database 'db' +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; +table_schema table_name +set role r2; +show databases; +Database +db +information_schema +test +show create database db; +Database Create Database +db CREATE DATABASE `db` /*!40100 DEFAULT CHARACTER SET latin1 */ +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; +table_schema table_name +db t1 +db t2 +connection default; +drop database db; +drop role r1; +drop user beep; +drop role r2; +drop user beep2; diff --git a/mysql-test/suite/roles/show_create_database-10463.test b/mysql-test/suite/roles/show_create_database-10463.test new file mode 100644 index 00000000000..2d921629c10 --- /dev/null +++ b/mysql-test/suite/roles/show_create_database-10463.test @@ -0,0 +1,55 @@ +source include/not_embedded.inc; + +drop database if exists db; + +create role r1; +create user beep@'%'; + +create database db; +create table db.t1 (i int); +create table db.t2 (b int); +grant select on db.* to r1; +grant r1 to beep@'%'; + +--connect (con1,localhost,beep,,) +show databases; +--error ER_DBACCESS_DENIED_ERROR +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; + +set role r1; +show databases; +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; + + +connection default; +create role r2; +create user beep2@'%'; + +grant update on db.* to r2; +grant r2 to beep2; +--connect (con2,localhost,beep2,,) +show databases; +--error ER_DBACCESS_DENIED_ERROR +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; + +set role r2; +show databases; + +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db'; + + +connection default; + +drop database db; +drop role r1; +drop user beep; +drop role r2; +drop user beep2; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result index 0bb0f57e463..7c8a2a94104 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result @@ -560,6 +560,56 @@ a b 57 7 58 8 59 9 +*** MDEV-8075: DROP TEMPORARY TABLE not marked as ddl, causing optimistic parallel replication to fail *** +connection server_2; +include/stop_slave.inc +connection server_1; +INSERT INTO t1 VALUES (40, 10); +CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (41); +BEGIN; +INSERT INTO t2 SELECT a, 20 FROM t1; +DROP TEMPORARY TABLE t1; +COMMIT; +INSERT INTO t1 VALUES (42, 10); +include/save_master_gtid.inc +SELECT * FROM t1 WHERE a >= 40 ORDER BY a; +a b +40 10 +42 10 +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a b +41 20 +50 0 +51 1 +52 2 +53 3 +54 4 +55 5 +56 6 +57 7 +58 8 +59 9 +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a >= 40 ORDER BY a; +a b +40 10 +42 10 +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a b +41 20 +50 0 +51 1 +52 2 +53 3 +54 4 +55 5 +56 6 +57 7 +58 8 +59 9 connection server_2; include/stop_slave.inc SET GLOBAL slave_parallel_mode=@old_parallel_mode; diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test index 789f59a3637..b5d78033088 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test @@ -460,6 +460,30 @@ SELECT * FROM t2 WHERE a >= 50 ORDER BY a; SELECT * FROM t2 WHERE a >= 50 ORDER BY a; +--echo *** MDEV-8075: DROP TEMPORARY TABLE not marked as ddl, causing optimistic parallel replication to fail *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (40, 10); +CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (41); +BEGIN; +INSERT INTO t2 SELECT a, 20 FROM t1; +DROP TEMPORARY TABLE t1; +COMMIT; +INSERT INTO t1 VALUES (42, 10); +--source include/save_master_gtid.inc +SELECT * FROM t1 WHERE a >= 40 ORDER BY a; +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a >= 40 ORDER BY a; +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; + # Clean up. --connection server_2 diff --git a/mysql-test/suite/wsrep/include/check_galera_version.inc b/mysql-test/suite/wsrep/include/check_galera_version.inc index cb35269249b..e495da8f1ee 100644 --- a/mysql-test/suite/wsrep/include/check_galera_version.inc +++ b/mysql-test/suite/wsrep/include/check_galera_version.inc @@ -2,7 +2,7 @@ # Enable tests to check the galera library version. # # ==== Usage ==== -# --let $galera_version=25.3.6 +# --let $galera_version=3.6 # source include/check_galera_lib_version.inc; # # Parameters: @@ -15,25 +15,22 @@ # Required Version eval SET @GALERA_VERSION='$galera_version'; -SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\1') AS UNSIGNED) INTO @GALERA_MAJOR_VERSION; -SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\2') AS UNSIGNED) INTO @GALERA_MID_VERSION; -SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\3') AS UNSIGNED) INTO @GALERA_MINOR_VERSION; +SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+).*','\\1') AS UNSIGNED) INTO @GALERA_MAJOR_VERSION; +SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+).*','\\2') AS UNSIGNED) INTO @GALERA_MINOR_VERSION; # Actual SELECT VARIABLE_VALUE INTO @ACTUAL_GALERA_VERSION FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep_provider_version'; -SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\1') AS UNSIGNED) INTO @ACTUAL_GALERA_MAJOR_VERSION; -SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\2') AS UNSIGNED) INTO @ACTUAL_GALERA_MID_VERSION; -SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\3') AS UNSIGNED) INTO @ACTUAL_GALERA_MINOR_VERSION; +SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+).*','\\1') AS UNSIGNED) INTO @ACTUAL_GALERA_MAJOR_VERSION; +SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+).*','\\2') AS UNSIGNED) INTO @ACTUAL_GALERA_MINOR_VERSION; # For testing -#SELECT @GALERA_MAJOR_VERSION, @GALERA_MID_VERSION, @GALERA_MINOR_VERSION; +#SELECT @GALERA_MAJOR_VERSION, @GALERA_MINOR_VERSION; #SELECT @ACTUAL_GALERA_VERSION; -#SELECT @ACTUAL_GALERA_MAJOR_VERSION, @ACTUAL_GALERA_MID_VERSION, @ACTUAL_GALERA_MINOR_VERSION; +#SELECT @ACTUAL_GALERA_MAJOR_VERSION, @ACTUAL_GALERA_MINOR_VERSION; if (!`SELECT (@ACTUAL_GALERA_MAJOR_VERSION > @GALERA_MAJOR_VERSION) OR - (@ACTUAL_GALERA_MAJOR_VERSION = @GALERA_MAJOR_VERSION AND @ACTUAL_GALERA_MID_VERSION > @GALERA_MID_VERSION) OR - (@ACTUAL_GALERA_MAJOR_VERSION = @GALERA_MAJOR_VERSION AND @ACTUAL_GALERA_MID_VERSION = @GALERA_MID_VERSION AND @ACTUAL_GALERA_MINOR_VERSION >= @GALERA_MINOR_VERSION) + (@ACTUAL_GALERA_MAJOR_VERSION = @GALERA_MAJOR_VERSION AND @ACTUAL_GALERA_MINOR_VERSION >= @GALERA_MINOR_VERSION) `) { skip Test requires Galera library version $galera_version; diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test index f9823192c18..e8589fa9242 100644 --- a/mysql-test/t/bootstrap.test +++ b/mysql-test/t/bootstrap.test @@ -59,6 +59,12 @@ drop table t1; SELECT 'bug' as '' FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb' and SUPPORT='YES'; +# +# MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init +# +--error 1 +--exec $MYSQLD_BOOTSTRAP_CMD --myisam_recover_options=NONE + --echo End of 5.5 tests --source include/not_windows_embedded.inc diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 6745d64d11b..7a054534c85 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -929,6 +929,22 @@ SET NAMES utf8, character_set_connection=ucs2; SELECT 'a','aa'; --echo # +--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +--echo # + +SET NAMES utf8, character_set_connection=ucs2; +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_utf8'derived_merge=on'; +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SET NAMES utf8, character_set_connection=ucs2; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub; +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; + + +--echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index 6ce6e439919..d1d83248df4 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -1,6 +1,7 @@ # # Test some error conditions # +--source include/have_sequence.inc --disable_warnings drop table if exists t1; @@ -198,3 +199,11 @@ CREATE TABLE t1 (a CHAR(3), b BLOB); UPDATE t1 SET a = 'new' WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; drop table t1; + +# +# errors caused by max_session_mem_used +# +set max_session_mem_used = 8192; +--error ER_SQL_DISCOVER_ERROR,ER_OPTION_PREVENTS_STATEMENT +select * from seq_1_to_1000; +set global max_session_mem_used = default; diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test index e56d1121808..be573f494a2 100644 --- a/mysql-test/t/func_concat.test +++ b/mysql-test/t/func_concat.test @@ -145,3 +145,94 @@ CALL p1(); DROP PROCEDURE p1; --echo # End of 5.1 tests + + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_merge=on'; + +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('1234567'); +SELECT CONCAT(SUBSTR(t2, 1, 3), SUBSTR(t2, 5)) c1, + CONCAT(SUBSTR(t2,1,3),'---',SUBSTR(t2,5)) c2 + FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; +DROP TABLE t1; + +# Other functions affected by MDEV-10306 + +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('1234567'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT REVERSE(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SOUNDEX(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT WEIGHT_STRING(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT QUOTE(t) t2 FROM t1) sub; +DROP TABLE t1; + +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES(TO_BASE64('abcdefghi')); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FROM_BASE64(t) t2 FROM t1) sub; +DROP TABLE t1; + +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES(HEX('abcdefghi')); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UNHEX(t) t2 FROM t1) sub; +DROP TABLE t1; + +CREATE TABLE t1 (t VARCHAR(30) CHARSET latin1); +INSERT INTO t1 VALUES('test'); +SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub; +DROP TABLE t1; + + +# Functions not affected by MDEV-10306 +# They only had an unused tmp_value, which was removed. + +CREATE TABLE t1 (t VARCHAR(64) CHARSET latin1); +INSERT INTO t1 VALUES('123456789'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT MD5(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FORMAT(t,2) t2 FROM t1) sub; +DROP TABLE t1; + +# Functions not affected by MDEV-10306 +# They already use tmp_value only for internal purposes and +# return the result in the String passed to val_str() + +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT INSERT(t,3,4,'xxx') t2 FROM t1) sub; +DROP TABLE t1; + + +# Functions not affected by MDEV-10306 +# They use this code style: +# String *res= args[0]->val_str(str); +# tmp_value.set(*res, start, end); +# return &tmp_value; + +CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LEFT(t,10) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RIGHT(t,10) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SUBSTR(t,1,10) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LTRIM(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RTRIM(t) t2 FROM t1) sub; +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TRIM(t) t2 FROM t1) sub; +DROP TABLE t1; + +SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/func_crypt.test b/mysql-test/t/func_crypt.test index ab5be573932..d091aa4ae86 100644 --- a/mysql-test/t/func_crypt.test +++ b/mysql-test/t/func_crypt.test @@ -70,6 +70,28 @@ SELECT OLD_PASSWORD(c1), PASSWORD(c1) FROM t1; DROP TABLE t1; --echo # End of 5.0 tests +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_merge=on'; +# ENCRYPT() is not affected by MDEV-10306 +# It already uses tmp_value only for internal purposes and +# returns the result in the String passed to val_str() +CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1); +INSERT INTO t1 VALUES('abcdefghi'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT ENCRYPT(t,'aa') t2 FROM t1) sub; +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # End of 10.0 tests +--echo # --echo # --echo # Start of 10.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 0c8bbbfc819..6e4ae6d624c 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -1465,6 +1465,21 @@ DROP VIEW v1; SELECT AsText(g) FROM (SELECT NULL AS g UNION SELECT Point(1,1)) AS t1; --echo # +--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 (x INT, y INT); +INSERT INTO t1 VALUES(0,0); +SELECT LENGTH(t2) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub; +SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub; +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; + + +--echo # --echo # End 10.0 tests --echo # diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 8df9a0c82bf..300695612fd 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -645,3 +645,33 @@ EOF set GLOBAL sql_mode=default; --echo --echo End of tests + +# +# MDEV-13187 incorrect backslash parsing in clients +# +create table `a1\``b1` (a int); +show tables; +insert `a1\``b1` values (1),(2); +show create table `a1\``b1`; +--exec $MYSQL_DUMP --compact test +--exec $MYSQL_DUMP test > $MYSQLTEST_VARDIR/tmp/bug.sql +insert `a1\``b1` values (4),(5); +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug.sql +show create table `a1\``b1`; +select * from `a1\``b1`; +drop table `a1\``b1`; + +# same with ansi_quotes +set sql_mode=ansi_quotes; +create table "a1\""b1" (a int); +show tables; +insert "a1\""b1" values (1),(2); +show create table "a1\""b1"; +--exec $MYSQL_DUMP --compact --compatible=postgres test +--exec $MYSQL_DUMP --compatible=postgres test > $MYSQLTEST_VARDIR/tmp/bug.sql +insert "a1\""b1" values (4),(5); +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug.sql +show create table "a1\""b1"; +select * from "a1\""b1"; +drop table "a1\""b1"; +set sql_mode=default; diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 01f26f09543..f6ac0042e9d 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -42,6 +42,7 @@ perl; $re2=join('|', @plugins); $skip=0; open(F, '<', "$ENV{MYSQL_TMP_DIR}/mysqld--help.txt") or die; + print "Windows bug: happens when a new line is exactly at the right offset\n"; while (<F>) { next if 1../The following groups are read/; # formatting, skip line consisting entirely of dashes and blanks diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 2f1296560d0..d6c68ecf3c2 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -2945,11 +2945,17 @@ disconnect $x; # Disconnect the selected connection disconnect $y; --echo $CURRENT_CONNECTION +connection default; +# +# MDEV-13187 incorrect backslash parsing in clients +# +set sql_mode=no_backslash_escapes; +select "foo\""bar"; +set sql_mode=default; --echo End of tests -connection default; # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 92c7cdf44b6..8722401ccae 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -2094,3 +2094,15 @@ set @@optimizer_switch=@tmp_8989; set optimizer_switch='orderby_uses_equalities=on'; + +--echo # +--echo # MDEV-10880: Assertions `keypart_map' or +--echo # `prebuilt->search_tuple->n_fields > 0' fail on DISTINCT and +--echo # GROUP BY constant +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT DISTINCT pk FROM t1 GROUP BY 'foo'; +SELECT DISTINCT pk FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/partition_alter.test b/mysql-test/t/partition_alter.test index e320efcefb9..ce6672c4b9d 100644 --- a/mysql-test/t/partition_alter.test +++ b/mysql-test/t/partition_alter.test @@ -105,3 +105,12 @@ show create table t1; insert t1 values (2, '2020-01-03', 20); drop table t1; --list_files $datadir/test + +# +# MDEV-13097 Online alter of a partitioned MyISAM table with auto_increment +# +create table t1 (id_1 int auto_increment, id_2 int, id_3 int, d1 date, dt1 datetime default current_timestamp, dt2 datetime default current_timestamp on update current_timestamp, primary key (id_2, id_3), key(id_1)) partition by hash(id_2) partitions 3 (partition p01, partition p02, partition p03); +insert into t1 values(0, 1, 1, NULL, now(), now()); +alter online table t1 delay_key_write=1; +show create table t1; +drop table t1; diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test index 9e3ac603ec6..35f2b9588fe 100644 --- a/mysql-test/t/subselect_mat_cost_bugs.test +++ b/mysql-test/t/subselect_mat_cost_bugs.test @@ -507,3 +507,19 @@ SELECT * FROM t1 ON (f3 = t2b.f2) ); DROP TABLE t1,t2,t3; + +--echo # +--echo # MDEV-12963: min/max optimization optimizing away all tables employed +--echo # for uncorrelated IN subquery used in a disjunct of WHERE +--echo # + +create table t1 (a int, index idx(a)) engine=myisam; +insert into t1 values (4),(7),(1),(3),(9); + +select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5; +explain +select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5; + +drop table t1; + + diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test index 0f2892ae2dc..cfb6c8c2819 100644 --- a/mysql-test/t/subselect_sj2_mat.test +++ b/mysql-test/t/subselect_sj2_mat.test @@ -283,3 +283,23 @@ select * from t1 where (rand() < 0) and i in (select i from t2); drop table t1,t2; set optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # mdev-12855: materialization of a semi-join subquery + ORDER BY +--echo # + +CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('qux'),('foo'); +CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB; +INSERT INTO t2 VALUES ('bar'),('foo'),('qux'); + +let $q= +SELECT f1 FROM t1 +WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' ) +HAVING f1 != 'foo' +ORDER BY f1; + +eval $q; +eval explain $q; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index b3c603728ee..bfd3b28a5b2 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1950,6 +1950,213 @@ set optimizer_switch= @save_optimizer_switch; DROP TABLE t1,t2; +--echo # +--echo # mdev-12838: scan of materialized of semi-join subquery in join +--echo # + +set @save_optimizer_switch=@@optimizer_switch; + +CREATE TABLE t1 ( + dispatch_group varchar(32), + assignment_group varchar(32), + sys_id char(32), + PRIMARY KEY (sys_id), + KEY idx1 (dispatch_group), + KEY idx2 (assignment_group) +) ENGINE=MyISAM; + +CREATE TABLE t2 ( + ugroup varchar(32), + user varchar(32), + sys_id char(32), + PRIMARY KEY (sys_id), + KEY idx3 (ugroup), + KEY idx4 (user) +) ENGINE=MyISAM; + +CREATE TABLE t3 ( + type mediumtext, + sys_id char(32), + PRIMARY KEY (sys_id) +) ENGINE=MyISAM; + +--disable_query_log + +INSERT INTO t1 VALUES +('e5d9f63237232000158bbfc8bcbe5dbf','f304ae0037332000158bbfc8bcbe5d4f', +'5398c0e037003000158bbfc8bcbe5dbb'), +('69d9f63237232000158bbfc8bcbe5dcb','7172ea0037332000158bbfc8bcbe5db6', +'5c188ca037003000158bbfc8bcbe5dbc'), +('577ed708d773020058c92cf65e61037a','699708d4d773020058c92cf65e61037c', +'623a8cd4d773020058c92cf65e6103ea'), +('96fb652637232000158bbfc8bcbe5db4','df50316637232000158bbfc8bcbe5d23', +'6835bd6637232000158bbfc8bcbe5d21'), +('e1d9f63237232000158bbfc8bcbe5db8','96346e0037332000158bbfc8bcbe5daa', +'697880e037003000158bbfc8bcbe5dcd'), +('25d9f63237232000158bbfc8bcbe5dbe','f304ae0037332000158bbfc8bcbe5d4f', +'6a9804e037003000158bbfc8bcbe5d09'), +('96fb652637232000158bbfc8bcbe5db4','e08fad2637232000158bbfc8bcbe5d39', +'6d25f96637232000158bbfc8bcbe5d79'), +('e9d9f63237232000158bbfc8bcbe5dc6','7172ea0037332000158bbfc8bcbe5db6', +'702880e037003000158bbfc8bcbe5d94'), +('a5d9f63237232000158bbfc8bcbe5dca','f304ae0037332000158bbfc8bcbe5d4f', +'7188c0e037003000158bbfc8bcbe5d75'), +('65d9f63237232000158bbfc8bcbe5dc4','f304ae0037332000158bbfc8bcbe5d4f', +'778880e037003000158bbfc8bcbe5d9e'), +('a1d9f63237232000158bbfc8bcbe5dc3','7172ea0037332000158bbfc8bcbe5db6', +'7d0840e037003000158bbfc8bcbe5dde'), +('21d9f63237232000158bbfc8bcbe5db7','96346e0037332000158bbfc8bcbe5daa', +'7f6880e037003000158bbfc8bcbe5da7'), +('96fb652637232000158bbfc8bcbe5db4','ec70316637232000158bbfc8bcbe5d60', +'8025f96637232000158bbfc8bcbe5dd0'), +('3dd9f63237232000158bbfc8bcbe5dcc','7172ea0037332000158bbfc8bcbe5db6', +'823880e037003000158bbfc8bcbe5ded'), +('96fb652637232000158bbfc8bcbe5db4','7b10fd2637232000158bbfc8bcbe5d30', +'9a353d6637232000158bbfc8bcbe5dee'), +('75d9f63237232000158bbfc8bcbe5dd0','ebb4620037332000158bbfc8bcbe5d89', +'a558c0e037003000158bbfc8bcbe5d36'), +('6dd9f63237232000158bbfc8bcbe5db5','96346e0037332000158bbfc8bcbe5daa', +'bc78cca037003000158bbfc8bcbe5d74'), +('add9f63237232000158bbfc8bcbe5dc7','7172ea0037332000158bbfc8bcbe5db6', +'c53804a037003000158bbfc8bcbe5db8'), +('fdd9f63237232000158bbfc8bcbe5dcd','7864ae0037332000158bbfc8bcbe5db8', +'cfe740e037003000158bbfc8bcbe5de8'), +('96fb652637232000158bbfc8bcbe5db4','3120fd2637232000158bbfc8bcbe5d42', +'e2257d6637232000158bbfc8bcbe5ded'), +('3c3725e237232000158bbfc8bcbe5da1','96346e0037332000158bbfc8bcbe5daa', +'ee78c0e037003000158bbfc8bcbe5db5'), +('a9d9f63237232000158bbfc8bcbe5dc0','7172ea0037332000158bbfc8bcbe5db6', +'f00888a037003000158bbfc8bcbe5dd3'), +('29d9f63237232000158bbfc8bcbe5db9','7172ea0037332000158bbfc8bcbe5db6', +'fa0880e037003000158bbfc8bcbe5d70'), +('b1d9f63237232000158bbfc8bcbe5dcf','ebb4620037332000158bbfc8bcbe5d89', +'fa48c0e037003000158bbfc8bcbe5d28'); + +INSERT INTO t2 VALUES +('17801ac21b13200050fdfbcd2c0713e8','8e826bf03710200044e0bfc8bcbe5d86', +'14c19a061b13200050fdfbcd2c07134b'), +('577ed708d773020058c92cf65e61037a','931644d4d773020058c92cf65e61034c', +'339888d4d773020058c92cf65e6103aa'), +('df50316637232000158bbfc8bcbe5d23','92826bf03710200044e0bfc8bcbe5da9', +'3682f56637232000158bbfc8bcbe5d44'), +('b4f342b237232000158bbfc8bcbe5def','86826bf03710200044e0bfc8bcbe5d70', +'38e4c2b237232000158bbfc8bcbe5dea'), +('7b10fd2637232000158bbfc8bcbe5d30','8a826bf03710200044e0bfc8bcbe5d72', +'4442b56637232000158bbfc8bcbe5d43'), +('3120fd2637232000158bbfc8bcbe5d42','82826bf03710200044e0bfc8bcbe5d89', +'49d2396637232000158bbfc8bcbe5d12'), +('96fb652637232000158bbfc8bcbe5db4','86826bf03710200044e0bfc8bcbe5d79', +'4e3ca52637232000158bbfc8bcbe5d3e'), +('17801ac21b13200050fdfbcd2c0713e8','824fd523bf4320007a6d257b3f073963', +'58c19a061b13200050fdfbcd2c07134e'), +('699708d4d773020058c92cf65e61037c','901784d4d773020058c92cf65e6103da', +'5bc708d4d773020058c92cf65e6103d5'), +('75d9f63237232000158bbfc8bcbe5dd0','86826bf03710200044e0bfc8bcbe5d79', +'6b52cb7237232000158bbfc8bcbe5ded'), +('f253da061b13200050fdfbcd2c0713ab','8e826bf03710200044e0bfc8bcbe5d86', +'81045e061b13200050fdfbcd2c071373'), +('7b10fd2637232000158bbfc8bcbe5d30','8e826bf03710200044e0bfc8bcbe5d74', +'8c42b56637232000158bbfc8bcbe5d3f'), +('e5d9f63237232000158bbfc8bcbe5dbf','7a826bf03710200044e0bfc8bcbe5df5', +'a7acfe3237232000158bbfc8bcbe5d78'), +('8a5055c9c61122780043563ef53438e3','9ee1b13dc6112271007f9d0efdb69cd0', +'a9aff553c6112276015a8006174bee21'), +('8a4dde73c6112278017a6a4baf547aa7','9ee1b13dc6112271007f9d0efdb69cd0', +'a9b2f526c61122760003ae07349d294f'), +('aaccc971c0a8001500fe1ff4302de101','9ee1b13dc6112271007f9d0efdb69cd0', +'aacceed3c0a80015009069bba51c4e21'), +('65d9f63237232000158bbfc8bcbe5dc4','8d56406a0a0a0a6b004070b354aada28', +'ac1bfa3237232000158bbfc8bcbe5dc3'), +('b85d44954a3623120004689b2d5dd60a','97000fcc0a0a0a6e0104ca999f619e5b', +'b77bc032cbb00200d71cb9c0c24c9c45'), +('220f8e71c61122840197e57c33464f70','8d56406a0a0a0a6b004070b354aada28', +'b9b74f080a0a0b343ba75b95bdb27056'), +('e08fad2637232000158bbfc8bcbe5d39','82826bf03710200044e0bfc8bcbe5d80', +'be02756637232000158bbfc8bcbe5d8b'), +('ebb4620037332000158bbfc8bcbe5d89','7682abf03710200044e0bfc8bcbe5d25', +'c0122f4437732000158bbfc8bcbe5d7d'), +('96fb652637232000158bbfc8bcbe5db4','7a82abf03710200044e0bfc8bcbe5d27', +'c23ca52637232000158bbfc8bcbe5d3b'), +('22122b37c611228400f9ff91c857581d','9ee1b13dc6112271007f9d0efdb69cd0', +'d23bbf5dac14641866947512bde59dc5'), +('db53a9290a0a0a650091abebccf833c6','9ee1b13dc6112271007f9d0efdb69cd0', +'db54a0f60a0a0a65002c54dcb72b4f41'), +('e08fad2637232000158bbfc8bcbe5d39','8e826bf03710200044e0bfc8bcbe5d86', +'f602756637232000158bbfc8bcbe5d88'), +('699708d4d773020058c92cf65e61037c','8d59d601d7b3020058c92cf65e6103c2', +'f718a241d7b3020058c92cf65e610332'), +('df50316637232000158bbfc8bcbe5d23','9e826bf03710200044e0bfc8bcbe5da6', +'fe82f56637232000158bbfc8bcbe5d4e'), +('f972d6061b13200050fdfbcd2c0713e5','780395f0df031100a9e78b6c3df2631f', +'ff4395f0df031100a9e78b6c3df2637e'); + +INSERT INTO t3 VALUES +('87245e061b13200050fdfbcd2c0713cc','7172ea0037332000158bbfc8bcbe5db6'), +('74af88c6c611227d0066386e74dc853d','74ad1ff3c611227d01d25feac2af603f'), +('59e22fb137032000158bbfc8bcbe5d52','75d9f63237232000158bbfc8bcbe5dd0'), +('98906fb137032000158bbfc8bcbe5d65','781da52637232000158bbfc8bcbe5db8'), +('87245e061b13200050fdfbcd2c0713cc','7864ae0037332000158bbfc8bcbe5db8'), +('87245e061b13200050fdfbcd2c0713cc','7b10fd2637232000158bbfc8bcbe5d30'), +('59e22fb137032000158bbfc8bcbe5d52','81a880e037003000158bbfc8bcbe5df8'), +('74af88c6c611227d0066386e74dc853d','8a4cb6d4c61122780043b1642efcd52b'), +('1cb8ab9bff500200158bffffffffff62','8a4dde73c6112278017a6a4baf547aa7'), +('1cb8ab9bff500200158bffffffffff62','8a5055c9c61122780043563ef53438e3'), +('87245e061b13200050fdfbcd2c0713cc','96346e0037332000158bbfc8bcbe5daa'), +('59e22fb137032000158bbfc8bcbe5d52','96fb652637232000158bbfc8bcbe5db4'), +('59e22fb137032000158bbfc8bcbe5d52','a1d9f63237232000158bbfc8bcbe5dc3'), +('59e22fb137032000158bbfc8bcbe5d52','a5d9f63237232000158bbfc8bcbe5dca'), +('1cb8ab9bff500200158bffffffffff62','a715cd759f2002002920bde8132e7018'), +('59e22fb137032000158bbfc8bcbe5d52','a9d9f63237232000158bbfc8bcbe5dc0'), +('74af88c6c611227d0066386e74dc853d','aacb62e2c0a80015007f67f752c2b12c'), +('74af88c6c611227d0066386e74dc853d','aaccc971c0a8001500fe1ff4302de101'), +('59e22fb137032000158bbfc8bcbe5d52','add9f63237232000158bbfc8bcbe5dbb'), +('59e22fb137032000158bbfc8bcbe5d52','add9f63237232000158bbfc8bcbe5dc7'), +('59e22fb137032000158bbfc8bcbe5d52','b1d9f63237232000158bbfc8bcbe5dcf'), +('1cb8ab9bff500200158bffffffffff62','b85d44954a3623120004689b2d5dd60a'), +('1cb8ab9bff500200158bffffffffff62','b97e89b94a36231201676b73322a0311'), +('1cb8ab9bff500200158bffffffffff62','cfcbad03d711110050f5edcb9e61038f'), +('1cb8ab9bff500200158bffffffffff62','d625dccec0a8016700a222a0f7900d06'), +('1cb8ab9bff500200158bffffffffff62','db53580b0a0a0a6501aa37c294a2ba6b'), +('1cb8ab9bff500200158bffffffffff62','db53a9290a0a0a650091abebccf833c6'), +('1cb8ab9bff500200158bffffffffff62','dc0db135c332010016194ffe5bba8f23'), +('87245e061b13200050fdfbcd2c0713cc','df50316637232000158bbfc8bcbe5d23'), +('87245e061b13200050fdfbcd2c0713cc','e08fad2637232000158bbfc8bcbe5d39'), +('59e22fb137032000158bbfc8bcbe5d52','e1d9f63237232000158bbfc8bcbe5db8'), +('59e22fb137032000158bbfc8bcbe5d52','e5d9f63237232000158bbfc8bcbe5db4'), +('59e22fb137032000158bbfc8bcbe5d52','e5d9f63237232000158bbfc8bcbe5dbf'), +('59e22fb137032000158bbfc8bcbe5d52','e9d9f63237232000158bbfc8bcbe5dba'), +('59e22fb137032000158bbfc8bcbe5d52','e9d9f63237232000158bbfc8bcbe5dc6'), +('87245e061b13200050fdfbcd2c0713cc','ebb4620037332000158bbfc8bcbe5d89'), +('87245e061b13200050fdfbcd2c0713cc','ec70316637232000158bbfc8bcbe5d60'), +('87245e061b13200050fdfbcd2c0713cc','f253da061b13200050fdfbcd2c0713ab'), +('87245e061b13200050fdfbcd2c0713cc','f304ae0037332000158bbfc8bcbe5d4f'), +('98906fb137032000158bbfc8bcbe5d65','f972d6061b13200050fdfbcd2c0713e5'), +('59e22fb137032000158bbfc8bcbe5d52','fdd9f63237232000158bbfc8bcbe5dcd'); + +--enable_query_log + +let $q= +SELECT t1.assignment_group +FROM t1, t3 +WHERE t1.assignment_group = t3.sys_id AND + t1.dispatch_group IN + (SELECT t2.ugroup + FROM t2, t3 t3_i + WHERE t2.ugroup = t3_i.sys_id AND + t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND + t2.user = '86826bf03710200044e0bfc8bcbe5d79'); + +set optimizer_switch='materialization=off'; +eval explain $q; +eval $q; + +set optimizer_switch='materialization=on'; +eval explain $q; +eval $q; + +DROP TABLE t1,t2,t3; +set optimizer_switch=@save_optimizer_switch; + --echo # End of 5.5 tests --echo # --echo # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index bab640e1371..4430b65e5f4 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5818,6 +5818,55 @@ SELECT * FROM v1 where use_case_id = 10; drop view v1; drop table t1; +--echo # +--echo # MDEV-12666: CURRENT_ROLE() and DATABASE() does not work in a view +--echo # +--echo # DATABASE() fails only when the initial view creation features a NULL +--echo # default database. +--echo # +--echo # CREATE, USE and DROP database so that we have no "default" database. +--echo # +CREATE DATABASE temporary; +USE temporary; +DROP DATABASE temporary; +SELECT DATABASE(); + +CREATE VIEW test.v_no_db AS SELECT DATABASE() = 'temporary_two'; +SHOW CREATE VIEW test.v_no_db; +PREPARE prepared_no_database FROM "SELECT DATABASE() = 'temporary_two'"; + +--echo # +--echo # All statements should return NULL +--echo # +EXECUTE prepared_no_database; +SELECT DATABASE() = 'temporary_two'; +SELECT * FROM test.v_no_db; + +CREATE DATABASE temporary_two; +USE temporary_two; +CREATE VIEW test.v_with_db AS SELECT DATABASE() = 'temporary_two'; +PREPARE prepared_with_database FROM "SELECT DATABASE() = 'temporary_two'"; + +--echo # +--echo # All statements should return 1; +--echo # +SELECT DATABASE() = 'temporary_two'; +SELECT * FROM test.v_no_db; +SELECT * FROM test.v_with_db; +EXECUTE prepared_with_database; + +--echo # +--echo # Prepared statements maintain default database to be the same +--echo # during on creation so this should return NULL still. +--echo # See MySQL bug #25843 +--echo # +EXECUTE prepared_no_database; + +DROP DATABASE temporary_two; +DROP VIEW test.v_no_db; +DROP VIEW test.v_with_db; +USE test; + --echo # ----------------------------------------------------------------- --echo # -- End of 10.0 tests. --echo # ----------------------------------------------------------------- @@ -5893,6 +5942,27 @@ drop view v1; drop table t1; --echo # +--echo # MDEV-12819: order by ordering expression changed to empty string +--echo # when creatin view with union +--echo # + +create table t1 (t1col1 int, t1col2 int,t1col3 int ); +create table t2 (t2col1 int, t2col2 int, t2col3 int); + +create view v1 as +select t1col1,t1col2,t1col3 from t1 +union all +select t2col1,t2col2,t2col3 from t2 +order by 2,3; + +show create view v1; + +select * from v1; + +drop view v1; +drop table t1,t2; + +--echo # --echo # End of 10.1 tests --echo # diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 72648d4c9a8..06f6a29e4a0 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -205,7 +205,7 @@ int my_realpath(char *to, const char *filename, myf MyFlags) const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd) { - char buf[PATH_MAX+1]; + char buf[FN_REFLEN + 1]; char *s= buf, *e= buf+1, *end= strnmov(buf, pathname, sizeof(buf)); int fd, dfd= -1; diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index da11b86e768..892e09148ef 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -126,12 +126,21 @@ const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd); res= AT; \ if (dfd >= 0) close(dfd); \ return res; -#elif defined(HAVE_REALPATH) +#elif defined(HAVE_REALPATH) && defined(PATH_MAX) #define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \ char buf[PATH_MAX+1]; \ if (realpath(pathname, buf) == NULL) return -1; \ if (strcmp(pathname, buf)) { errno= ENOTDIR; return -1; } \ return NOAT; +#elif defined(HAVE_REALPATH) +#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \ + char *buf= realpath(pathname, NULL); \ + int res; \ + if (buf == NULL) return -1; \ + if (strcmp(pathname, buf)) { errno= ENOTDIR; res= -1; } \ + else res= NOAT; \ + free(buf); \ + return res; #else #define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \ return NOAT; diff --git a/sql/contributors.h b/sql/contributors.h index 3a771e2b493..88a4a088acf 100644 --- a/sql/contributors.h +++ b/sql/contributors.h @@ -39,9 +39,11 @@ struct show_table_contributors_st show_table_contributors[]= { /* MariaDB foundation sponsors, in contribution, size , time order */ {"Booking.com", "https://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"}, {"Alibaba Cloud", "https://intl.aliyun.com", "Platinum Sponsor of the MariaDB Foundation"}, + {"Tencent Cloud", "https://cloud.tencent.com", "Platinum Sponsor of the MariaDB Foundation"}, {"MariaDB Corporation", "https://mariadb.com", "Founding member, Gold Sponsor of the MariaDB Foundation"}, {"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"}, {"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"}, + {"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"}, {"Nexedi", "https://www.nexedi.com", "Silver Sponsor of the MariaDB Foundation"}, {"Acronis", "http://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"}, {"Auttomattic", "https://automattic.com", "Bronze Sponsor of the MariaDB Foundation"}, diff --git a/sql/handler.cc b/sql/handler.cc index 95b16a51980..a4a2297bd2f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4856,7 +4856,12 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, { if (error) { - DBUG_ASSERT(share->error); // tdc_lock_share needs that + if (!share->error) + { + share->error= OPEN_FRM_ERROR_ALREADY_ISSUED; + plugin_unlock(0, share->db_plugin); + } + /* report an error, unless it is "generic" and a more specific one was already reported diff --git a/sql/handler.h b/sql/handler.h index ee4836dcc34..d021edf28d2 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1465,16 +1465,30 @@ struct THD_TRANS static unsigned int const CREATED_TEMP_TABLE= 0x02; static unsigned int const DROPPED_TEMP_TABLE= 0x04; static unsigned int const DID_WAIT= 0x08; + static unsigned int const DID_DDL= 0x10; void mark_created_temp_table() { DBUG_PRINT("debug", ("mark_created_temp_table")); m_unsafe_rollback_flags|= CREATED_TEMP_TABLE; } + void mark_dropped_temp_table() + { + DBUG_PRINT("debug", ("mark_dropped_temp_table")); + m_unsafe_rollback_flags|= DROPPED_TEMP_TABLE; + } + bool has_created_dropped_temp_table() const { + return + (m_unsafe_rollback_flags & (CREATED_TEMP_TABLE|DROPPED_TEMP_TABLE)) != 0; + } void mark_trans_did_wait() { m_unsafe_rollback_flags|= DID_WAIT; } bool trans_did_wait() const { return (m_unsafe_rollback_flags & DID_WAIT) != 0; } + void mark_trans_did_ddl() { m_unsafe_rollback_flags|= DID_DDL; } + bool trans_did_ddl() const { + return (m_unsafe_rollback_flags & DID_DDL) != 0; + } }; diff --git a/sql/item.h b/sql/item.h index 3cb904d3c59..cee88756bbf 100644 --- a/sql/item.h +++ b/sql/item.h @@ -994,25 +994,20 @@ public: store return value of this method. NOTE - Buffer passed via argument should only be used if the item itself - doesn't have an own String buffer. In case when the item maintains - it's own string buffer, it's preferable to return it instead to - minimize number of mallocs/memcpys. - The caller of this method can modify returned string, but only in case - when it was allocated on heap, (is_alloced() is true). This allows - the caller to efficiently use a buffer allocated by a child without - having to allocate a buffer of it's own. The buffer, given to - val_str() as argument, belongs to the caller and is later used by the - caller at it's own choosing. - A few implications from the above: - - unless you return a string object which only points to your buffer - but doesn't manages it you should be ready that it will be - modified. - - even for not allocated strings (is_alloced() == false) the caller - can change charset (see Item_func_{typecast/binary}. XXX: is this - a bug? - - still you should try to minimize data copying and return internal - object whenever possible. + The caller can modify the returned String, if it's not marked + "const" (with the String::mark_as_const() method). That means that + if the item returns its own internal buffer (e.g. tmp_value), it + *must* be marked "const" [1]. So normally it's preferrable to + return the result value in the String, that was passed as an + argument. But, for example, SUBSTR() returns a String that simply + points into the buffer of SUBSTR()'s args[0]->val_str(). Such a + String is always "const", so it's ok to use tmp_value for that and + avoid reallocating/copying of the argument String. + + [1] consider SELECT CONCAT(f, ":", f) FROM (SELECT func() AS f); + here the return value of f() is used twice in the top-level + select, and if they share the same tmp_value buffer, modifying the + first one will implicitly modify the second too. RETURN In case of NULL value return 0 (NULL pointer) and set null_value flag @@ -1771,7 +1766,7 @@ public: { return this; } virtual bool expr_cache_is_needed(THD *) { return FALSE; } virtual Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); - bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs) + bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs) const { /* This will return "true" if conversion happens: diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 16bad154862..560d822bea7 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1949,7 +1949,7 @@ String *Item_func_buffer::val_str(String *str_value) { DBUG_ENTER("Item_func_buffer::val_str"); DBUG_ASSERT(fixed == 1); - String *obj= args[0]->val_str(&tmp_value); + String *obj= args[0]->val_str(str_value); double dist= args[1]->val_real(); Geometry_buffer buffer; Geometry *g; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index a164f9dec89..abe189395ec 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -297,7 +297,6 @@ public: class Item_func_spatial_collection: public Item_geometry_func { - String tmp_value; enum Geometry::wkbType coll_type; enum Geometry::wkbType item_type; public: @@ -483,7 +482,6 @@ protected: Gcalc_result_receiver res_receiver; Gcalc_operation_reducer operation; - String tmp_value; public: Item_func_buffer(THD *thd, Item *obj, Item *distance): diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e91cf64fd04..3c2b2374f1e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -66,8 +66,14 @@ size_t username_char_length= 80; Conversion happens only in case of "tricky" Item character set (e.g. UCS2). Normally conversion does not happen, and val_str_ascii() is immediately returned instead. + + No matter if conversion is needed or not needed, + the result is always returned in "str" (see MDEV-10306 why). + + @param [OUT] str - Store the result here + @param [IN] ascii_buffer - Use this temporary buffer to call val_str_ascii() */ -String *Item_func::val_str_from_val_str_ascii(String *str, String *str2) +String *Item_func::val_str_from_val_str_ascii(String *str, String *ascii_buffer) { DBUG_ASSERT(fixed == 1); @@ -79,19 +85,19 @@ String *Item_func::val_str_from_val_str_ascii(String *str, String *str2) return res; } - DBUG_ASSERT(str != str2); + DBUG_ASSERT(str != ascii_buffer); uint errors; - String *res= val_str_ascii(str); + String *res= val_str_ascii(ascii_buffer); if (!res) return 0; - if ((null_value= str2->copy(res->ptr(), res->length(), - &my_charset_latin1, collation.collation, - &errors))) + if ((null_value= str->copy(res->ptr(), res->length(), + &my_charset_latin1, collation.collation, + &errors))) return 0; - return str2; + return str; } @@ -307,11 +313,11 @@ void Item_aes_crypt::create_key(String *user_key, uchar *real_key) } -String *Item_aes_crypt::val_str(String *str) +String *Item_aes_crypt::val_str(String *str2) { DBUG_ASSERT(fixed == 1); StringBuffer<80> user_key_buf; - String *sptr= args[0]->val_str(str); + String *sptr= args[0]->val_str(&str_value); String *user_key= args[1]->val_str(&user_key_buf); uint32 aes_length; @@ -320,17 +326,17 @@ String *Item_aes_crypt::val_str(String *str) null_value=0; aes_length=my_aes_get_size(MY_AES_ECB, sptr->length()); - if (!str_value.alloc(aes_length)) // Ensure that memory is free + if (!str2->alloc(aes_length)) // Ensure that memory is free { uchar rkey[AES_KEY_LENGTH / 8]; create_key(user_key, rkey); if (!my_aes_crypt(MY_AES_ECB, what, (uchar*)sptr->ptr(), sptr->length(), - (uchar*)str_value.ptr(), &aes_length, + (uchar*)str2->ptr(), &aes_length, rkey, AES_KEY_LENGTH / 8, 0, 0)) { - str_value.length((uint) aes_length); - return &str_value; + str2->length((uint) aes_length); + return str2; } } } @@ -345,6 +351,7 @@ void Item_func_aes_encrypt::fix_length_and_dec() } + void Item_func_aes_decrypt::fix_length_and_dec() { max_length=args[0]->max_length; @@ -373,7 +380,7 @@ void Item_func_to_base64::fix_length_and_dec() String *Item_func_to_base64::val_str_ascii(String *str) { - String *res= args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); bool too_long= false; int length; if (!res || @@ -381,7 +388,7 @@ String *Item_func_to_base64::val_str_ascii(String *str) (too_long= ((uint) (length= my_base64_needed_encoded_length((int) res->length())) > current_thd->variables.max_allowed_packet)) || - tmp_value.alloc((uint) length)) + str->alloc((uint) length)) { null_value= 1; // NULL input, too long input, or OOM. if (too_long) @@ -395,11 +402,11 @@ String *Item_func_to_base64::val_str_ascii(String *str) } return 0; } - my_base64_encode(res->ptr(), (int) res->length(), (char*) tmp_value.ptr()); + my_base64_encode(res->ptr(), (int) res->length(), (char*) str->ptr()); DBUG_ASSERT(length > 0); - tmp_value.length((uint) length - 1); // Without trailing '\0' + str->length((uint) length - 1); // Without trailing '\0' null_value= 0; - return &tmp_value; + return str; } @@ -420,7 +427,7 @@ void Item_func_from_base64::fix_length_and_dec() String *Item_func_from_base64::val_str(String *str) { - String *res= args[0]->val_str_ascii(str); + String *res= args[0]->val_str_ascii(&tmp_value); int length; const char *end_ptr; @@ -440,11 +447,11 @@ String *Item_func_from_base64::val_str(String *str) goto err; } - if (tmp_value.alloc((uint) length)) + if (str->alloc((uint) length)) goto err; if ((length= my_base64_decode(res->ptr(), (int) res->length(), - (char *) tmp_value.ptr(), &end_ptr, 0)) < 0 || + (char *) str->ptr(), &end_ptr, 0)) < 0 || end_ptr < res->ptr() + res->length()) { THD *thd= current_thd; @@ -454,9 +461,9 @@ String *Item_func_from_base64::val_str(String *str) goto err; } - tmp_value.length((uint) length); + str->length((uint) length); null_value= 0; - return &tmp_value; + return str; err: null_value= 1; // NULL input, too long input, OOM, or badly formed input return 0; @@ -712,7 +719,7 @@ String *Item_func_des_encrypt::val_str(String *str) struct st_des_keyschedule keyschedule; const char *append_str="********"; uint key_number, res_length, tail; - String *res= args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); if ((null_value= args[0]->null_value)) return 0; // ENCRYPT(NULL) == NULL @@ -736,7 +743,7 @@ String *Item_func_des_encrypt::val_str(String *str) } else { - String *keystr=args[1]->val_str(&tmp_value); + String *keystr= args[1]->val_str(str); if (!keystr) goto error; key_number=127; // User key string @@ -768,23 +775,23 @@ String *Item_func_des_encrypt::val_str(String *str) tmp_arg.length(0); tmp_arg.append(res->ptr(), res->length()); code= ER_OUT_OF_RESOURCES; - if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1)) + if (tmp_arg.append(append_str, tail) || str->alloc(res_length+1)) goto error; tmp_arg[res_length-1]=tail; // save extra length - tmp_value.realloc(res_length+1); - tmp_value.length(res_length+1); - tmp_value.set_charset(&my_charset_bin); - tmp_value[0]=(char) (128 | key_number); + str->realloc(res_length+1); + str->length(res_length+1); + str->set_charset(&my_charset_bin); + (*str)[0]=(char) (128 | key_number); // Real encryption bzero((char*) &ivec,sizeof(ivec)); DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()), - (uchar*) (tmp_value.ptr()+1), + (uchar*) (str->ptr()+1), res_length, &keyschedule.ks1, &keyschedule.ks2, &keyschedule.ks3, &ivec, TRUE); - return &tmp_value; + return str; error: THD *thd= current_thd; @@ -810,7 +817,7 @@ String *Item_func_des_decrypt::val_str(String *str) DES_cblock ivec; struct st_des_keyblock keyblock; struct st_des_keyschedule keyschedule; - String *res= args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); uint length,tail; if ((null_value= args[0]->null_value)) @@ -834,7 +841,7 @@ String *Item_func_des_decrypt::val_str(String *str) else { // We make good 24-byte (168 bit) key from given plaintext key with MD5 - String *keystr=args[1]->val_str(&tmp_value); + String *keystr= args[1]->val_str(str); if (!keystr) goto error; @@ -849,23 +856,23 @@ String *Item_func_des_decrypt::val_str(String *str) DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3); } code= ER_OUT_OF_RESOURCES; - if (tmp_value.alloc(length-1)) + if (str->alloc(length-1)) goto error; bzero((char*) &ivec,sizeof(ivec)); DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1, - (uchar*) (tmp_value.ptr()), + (uchar*) (str->ptr()), length-1, &keyschedule.ks1, &keyschedule.ks2, &keyschedule.ks3, &ivec, FALSE); /* Restore old length of key */ - if ((tail=(uint) (uchar) tmp_value[length-2]) > 8) + if ((tail=(uint) (uchar) (*str)[length-2]) > 8) goto wrong_key; // Wrong key - tmp_value.length(length-1-tail); - tmp_value.set_charset(&my_charset_bin); - return &tmp_value; + str->length(length-1-tail); + str->set_charset(&my_charset_bin); + return str; error: { @@ -1063,25 +1070,26 @@ void Item_func_concat_ws::fix_length_and_dec() String *Item_func_reverse::val_str(String *str) { DBUG_ASSERT(fixed == 1); - String *res = args[0]->val_str(str); - char *ptr, *end, *tmp; + String *res= args[0]->val_str(&tmp_value); + const char *ptr, *end; + char *tmp; if ((null_value=args[0]->null_value)) return 0; /* An empty string is a special case as the string pointer may be null */ if (!res->length()) return make_empty_result(); - if (tmp_value.alloced_length() < res->length() && - tmp_value.realloc(res->length())) + if (str->alloced_length() < res->length() && + str->realloc(res->length())) { null_value= 1; return 0; } - tmp_value.length(res->length()); - tmp_value.set_charset(res->charset()); - ptr= (char *) res->ptr(); - end= ptr + res->length(); - tmp= (char *) tmp_value.ptr() + tmp_value.length(); + str->length(res->length()); + str->set_charset(res->charset()); + ptr= res->ptr(); + end= res->end(); + tmp= (char *) str->end(); #ifdef USE_MB if (use_mb(res->charset())) { @@ -1091,7 +1099,7 @@ String *Item_func_reverse::val_str(String *str) if ((l= my_ismbchar(res->charset(),ptr,end))) { tmp-= l; - DBUG_ASSERT(tmp >= tmp_value.ptr()); + DBUG_ASSERT(tmp >= str->ptr()); memcpy(tmp,ptr,l); ptr+= l; } @@ -1105,7 +1113,7 @@ String *Item_func_reverse::val_str(String *str) while (ptr < end) *--tmp= *ptr++; } - return &tmp_value; + return str; } @@ -2285,6 +2293,7 @@ String *Item_func_database::val_str(String *str) } else str->copy(thd->db, thd->db_length, system_charset_info); + null_value= 0; return str; } @@ -2319,6 +2328,28 @@ bool Item_func_user::init(const char *user, const char *host) } +Item *Item_func_sysconst::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) +{ + /* + During view or prepared statement creation, the item should not + make use of const_charset_converter as it would imply substitution + with constant items which is not correct. Functions can have different + values during view creation and view execution based on context. + + Return the identical item during view creation and prepare. + */ + if (thd->lex->is_ps_or_view_context_analysis()) + return this; + return const_charset_converter(thd, tocs, true, fully_qualified_func_name()); +} + +bool Item_func_sysconst::const_item() const +{ + if (current_thd->lex->is_ps_or_view_context_analysis()) + return false; + return true; +} + bool Item_func_user::fix_fields(THD *thd, Item **ref) { return (Item_func_sysconst::fix_fields(thd, ref) || @@ -2344,15 +2375,13 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref) Security_context *ctx= context && context->security_ctx ? context->security_ctx : thd->security_ctx; - if (ctx->priv_role[0]) { if (str_value.copy(ctx->priv_role, strlen(ctx->priv_role), system_charset_info)) return 1; - - null_value= maybe_null= 0; str_value.mark_as_const(); + null_value= maybe_null= 0; return 0; } null_value= maybe_null= 1; @@ -2366,7 +2395,6 @@ void Item_func_soundex::fix_length_and_dec() DBUG_ASSERT(collation.collation != NULL); set_if_bigger(char_length, 4); fix_char_length(char_length); - tmp_value.set_charset(collation.collation); } @@ -2411,7 +2439,7 @@ static bool my_uni_isalpha(int wc) String *Item_func_soundex::val_str(String *str) { DBUG_ASSERT(fixed == 1); - String *res =args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); char last_ch,ch; CHARSET_INFO *cs= collation.collation; my_wc_t wc; @@ -2421,10 +2449,11 @@ String *Item_func_soundex::val_str(String *str) if ((null_value= args[0]->null_value)) return 0; /* purecov: inspected */ - if (tmp_value.alloc(MY_MAX(res->length(), 4 * cs->mbminlen))) - return str; /* purecov: inspected */ - char *to= (char *) tmp_value.ptr(); - char *to_end= to + tmp_value.alloced_length(); + if (str->alloc(MY_MAX(res->length(), 4 * cs->mbminlen))) + return &tmp_value; /* purecov: inspected */ + str->set_charset(collation.collation); + char *to= (char *) str->ptr(); + char *to_end= to + str->alloced_length(); char *from= (char *) res->ptr(), *end= from + res->length(); for ( ; ; ) /* Skip pre-space */ @@ -2509,8 +2538,8 @@ String *Item_func_soundex::val_str(String *str) to+= nbytes; } - tmp_value.length((uint) (to-tmp_value.ptr())); - return &tmp_value; + str->length((uint) (to - str->ptr())); + return str; } @@ -3332,13 +3361,13 @@ String *Item_func_conv_charset::val_str(String *str) DBUG_ASSERT(fixed == 1); if (use_cached_value) return null_value ? 0 : &str_value; - String *arg= args[0]->val_str(str); + String *arg= args[0]->val_str(&tmp_value); String_copier_for_item copier(current_thd); return ((null_value= args[0]->null_value || - copier.copy_with_warn(collation.collation, &tmp_value, + copier.copy_with_warn(collation.collation, str, arg->charset(), arg->ptr(), arg->length(), arg->length()))) ? - 0 : &tmp_value; + 0 : str; } void Item_func_conv_charset::fix_length_and_dec() @@ -3479,7 +3508,7 @@ String *Item_func_weight_string::val_str(String *str) DBUG_ASSERT(fixed == 1); if (args[0]->result_type() != STRING_RESULT || - !(res= args[0]->val_str(str))) + !(res= args[0]->val_str(&tmp_value))) goto nl; /* @@ -3529,19 +3558,20 @@ String *Item_func_weight_string::val_str(String *str) goto nl; } } - if (tmp_value.alloc(tmp_length)) + + if (str->alloc(tmp_length)) goto nl; frm_length= cs->coll->strnxfrm(cs, - (uchar *) tmp_value.ptr(), tmp_length, + (uchar *) str->ptr(), tmp_length, nweights ? nweights : tmp_length, (const uchar *) res->ptr(), res->length(), flags); DBUG_ASSERT(frm_length <= tmp_length); - tmp_value.length(frm_length); + str->length(frm_length); null_value= 0; - return &tmp_value; + return str; nl: null_value= 1; @@ -3597,18 +3627,18 @@ String *Item_func_hex::val_str_ascii(String *str) } /* Convert given string to a hex string, character by character */ - res= args[0]->val_str(str); - if (!res || tmp_value.alloc(res->length()*2+1)) + res= args[0]->val_str(&tmp_value); + if (!res || str->alloc(res->length()*2+1)) { null_value=1; return 0; } null_value=0; - tmp_value.length(res->length()*2); - tmp_value.set_charset(&my_charset_latin1); + str->length(res->length()*2); + str->set_charset(&my_charset_latin1); - octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length()); - return &tmp_value; + octet2hex((char*) str->ptr(), res->ptr(), res->length()); + return str; } /** Convert given hex string to a binary string. */ @@ -3621,8 +3651,8 @@ String *Item_func_unhex::val_str(String *str) uint length; DBUG_ASSERT(fixed == 1); - res= args[0]->val_str(str); - if (!res || tmp_value.alloc(length= (1+res->length())/2)) + res= args[0]->val_str(&tmp_value); + if (!res || str->alloc(length= (1+res->length())/2)) { null_value=1; return 0; @@ -3630,8 +3660,8 @@ String *Item_func_unhex::val_str(String *str) from= res->ptr(); null_value= 0; - tmp_value.length(length); - to= (char*) tmp_value.ptr(); + str->length(length); + to= (char*) str->ptr(); if (res->length() % 2) { int hex_char; @@ -3649,7 +3679,7 @@ String *Item_func_unhex::val_str(String *str) if ((null_value= (hex_char == -1))) return 0; } - return &tmp_value; + return str; } @@ -3900,7 +3930,7 @@ String *Item_func_quote::val_str(String *str) ulong max_allowed_packet= current_thd->variables.max_allowed_packet; char *from, *to, *end, *start; - String *arg= args[0]->val_str(str); + String *arg= args[0]->val_str(&tmp_value); uint arg_length, new_length; if (!arg) // Null argument { @@ -3927,7 +3957,7 @@ String *Item_func_quote::val_str(String *str) set_if_smaller(new_length, max_allowed_packet); } - if (tmp_value.alloc(new_length)) + if (str->alloc(new_length)) goto null; if (collation.collation->mbmaxlen > 1) @@ -3935,7 +3965,7 @@ String *Item_func_quote::val_str(String *str) CHARSET_INFO *cs= collation.collation; int mblen; uchar *to_end; - to= (char*) tmp_value.ptr(); + to= (char*) str->ptr(); to_end= (uchar*) to + new_length; /* Put leading quote */ @@ -3972,14 +4002,14 @@ String *Item_func_quote::val_str(String *str) if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0) goto toolong; to+= mblen; - new_length= to - tmp_value.ptr(); + new_length= to - str->ptr(); goto ret; } /* We replace characters from the end to the beginning */ - to= (char*) tmp_value.ptr() + new_length - 1; + to= (char*) str->ptr() + new_length - 1; *to--= '\''; for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) { @@ -4009,10 +4039,10 @@ String *Item_func_quote::val_str(String *str) *to= '\''; ret: - tmp_value.length(new_length); - tmp_value.set_charset(collation.collation); + str->length(new_length); + str->set_charset(collation.collation); null_value= 0; - return &tmp_value; + return str; toolong: push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN, @@ -4086,7 +4116,7 @@ String *Item_func_compress::val_str(String *str) char *tmp, *last_char; DBUG_ASSERT(fixed == 1); - if (!(res= args[0]->val_str(str))) + if (!(res= args[0]->val_str(&tmp_value))) { null_value= 1; return 0; @@ -4107,13 +4137,13 @@ String *Item_func_compress::val_str(String *str) // Check new_size overflow: new_size <= res->length() if (((uint32) (new_size+5) <= res->length()) || - buffer.realloc((uint32) new_size + 4 + 1)) + str->realloc((uint32) new_size + 4 + 1)) { null_value= 1; return 0; } - body= ((Byte*)buffer.ptr()) + 4; + body= ((Byte*)str->ptr()) + 4; // As far as we have checked res->is_empty() we can use ptr() if ((err= my_compress_buffer(body, &new_size, (const uchar *)res->ptr(), @@ -4127,7 +4157,7 @@ String *Item_func_compress::val_str(String *str) return 0; } - tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects + tmp= (char*) str->ptr(); // int4store is a macro; avoid side effects int4store(tmp, res->length() & 0x3FFFFFFF); /* This is to ensure that things works for CHAR fields, which trim ' ': */ @@ -4138,15 +4168,15 @@ String *Item_func_compress::val_str(String *str) new_size++; } - buffer.length((uint32)new_size + 4); - return &buffer; + str->length((uint32)new_size + 4); + return str; } String *Item_func_uncompress::val_str(String *str) { DBUG_ASSERT(fixed == 1); - String *res= args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); ulong new_size; int err; uint code; @@ -4179,14 +4209,14 @@ String *Item_func_uncompress::val_str(String *str) max_allowed_packet)); goto err; } - if (buffer.realloc((uint32)new_size)) + if (str->realloc((uint32)new_size)) goto err; - if ((err= uncompress((Byte*)buffer.ptr(), &new_size, + if ((err= uncompress((Byte*)str->ptr(), &new_size, ((const Bytef*)res->ptr())+4,res->length()-4)) == Z_OK) { - buffer.length((uint32) new_size); - return &buffer; + str->length((uint32) new_size); + return str; } code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR : diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 65c6dacbc73..0729f8f9c15 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -142,7 +142,6 @@ public: class Item_func_md5 :public Item_str_ascii_checksum_func { - String tmp_value; public: Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); @@ -258,7 +257,6 @@ public: class Item_func_decode_histogram :public Item_str_func { - String tmp_value; public: Item_func_decode_histogram(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} @@ -684,10 +682,7 @@ class Item_func_sysconst :public Item_str_func public: Item_func_sysconst(THD *thd): Item_str_func(thd) { collation.set(system_charset_info,DERIVATION_SYSCONST); } - Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) - { - return const_charset_converter(thd, tocs, true, fully_qualified_func_name()); - } + Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); /* Used to create correct Item name in new converted item in safe_charset_converter, return string representation of this function @@ -699,6 +694,7 @@ public: return mark_unsupported_function(fully_qualified_func_name(), arg, VCOL_SESSION_FUNC); } + bool const_item() const; }; @@ -787,7 +783,7 @@ public: String *val_str(String *) { DBUG_ASSERT(fixed == 1); - return (null_value ? 0 : &str_value); + return null_value ? NULL : &str_value; } bool check_vcol_func_processor(void *arg) { @@ -844,7 +840,6 @@ public: class Item_func_format :public Item_str_ascii_func { - String tmp_str; MY_LOCALE *locale; public: Item_func_format(THD *thd, Item *org, Item *dec): @@ -909,7 +904,6 @@ public: class Item_func_binlog_gtid_pos :public Item_str_func { - String tmp_value; public: Item_func_binlog_gtid_pos(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} @@ -1354,7 +1348,7 @@ public: class Item_func_compress: public Item_str_binary_checksum_func { - String buffer; + String tmp_value; public: Item_func_compress(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) {} @@ -1367,7 +1361,7 @@ public: class Item_func_uncompress: public Item_str_binary_checksum_func { - String buffer; + String tmp_value; public: Item_func_uncompress(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) {} diff --git a/sql/log_event.cc b/sql/log_event.cc index 79e8f7e0a94..26c288ef767 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7451,8 +7451,10 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg, if (thd_arg->transaction.stmt.trans_did_wait() || thd_arg->transaction.all.trans_did_wait()) flags2|= FL_WAITED; - if (sql_command_flags[thd->lex->sql_command] & - (CF_DISALLOW_IN_RO_TRANS | CF_AUTO_COMMIT_TRANS)) + if (thd_arg->transaction.stmt.trans_did_ddl() || + thd_arg->transaction.stmt.has_created_dropped_temp_table() || + thd_arg->transaction.all.trans_did_ddl() || + thd_arg->transaction.all.has_created_dropped_temp_table()) flags2|= FL_DDL; else if (is_transactional) flags2|= FL_TRANSACTIONAL; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 871a3140891..373f9bae26e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4036,8 +4036,9 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) (longlong) thd->status_var.local_memory_used, size)); thd->status_var.local_memory_used+= size; - if (thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && - !thd->killed) + if (size > 0 && + thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && + !thd->killed && !thd->get_stmt_da()->is_set()) { char buf[1024]; thd->killed= KILL_QUERY; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 0b01925ba93..f37db88957a 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3443,6 +3443,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) table_map remaining_tables= 0; table_map handled_tabs= 0; join->sjm_lookup_tables= 0; + join->sjm_scan_tables= 0; for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--) { POSITION *pos= join->best_positions + tablenr; @@ -3500,6 +3501,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) for (i= tablenr; i != (first + sjm->tables - 1); i--) rem_tables |= join->best_positions[i].table->table->map; + for (i= first; i < first+ sjm->tables; i++) + join->sjm_scan_tables |= join->best_positions[i].table->table->map; + POSITION dummy; join->cur_sj_inner_tables= 0; for (i= first + sjm->tables; i <= tablenr; i++) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index fda922c3e12..9bdb096a116 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -124,10 +124,13 @@ int Relay_log_info::init(const char* info_fname) char fname[FN_REFLEN+128]; const char* msg = 0; int error = 0; + mysql_mutex_t *log_lock; DBUG_ENTER("Relay_log_info::init"); if (inited) // Set if this function called DBUG_RETURN(0); + + log_lock= relay_log.get_log_lock(); fn_format(fname, info_fname, mysql_data_home, "", 4+32); mysql_mutex_lock(&data_lock); cur_log_fd = -1; @@ -207,7 +210,6 @@ a file name for --relay-log-index option", opt_relaylog_index_name); /* For multimaster, add connection name to relay log filenames */ char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN]; char *buf_relaylog_index_name= opt_relaylog_index_name; - mysql_mutex_t *log_lock; create_logfile_name_with_suffix(buf_relay_logname, sizeof(buf_relay_logname), @@ -227,7 +229,6 @@ a file name for --relay-log-index option", opt_relaylog_index_name); note, that if open() fails, we'll still have index file open but a destructor will take care of that */ - log_lock= relay_log.get_log_lock(); mysql_mutex_lock(log_lock); if (relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) || relay_log.open(ln, LOG_BIN, 0, 0, SEQ_READ_APPEND, @@ -304,7 +305,9 @@ Failed to open the existing relay log info file '%s' (errno %d)", if (info_fd >= 0) mysql_file_close(info_fd, MYF(0)); info_fd= -1; + mysql_mutex_lock(log_lock); relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); + mysql_mutex_unlock(log_lock); mysql_mutex_unlock(&data_lock); DBUG_RETURN(1); } @@ -426,7 +429,9 @@ err: if (info_fd >= 0) mysql_file_close(info_fd, MYF(0)); info_fd= -1; + mysql_mutex_lock(log_lock); relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); + mysql_mutex_unlock(log_lock); mysql_mutex_unlock(&data_lock); DBUG_RETURN(1); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3d34f657ae3..a4e522b90d3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -724,6 +724,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) debug_sync_control(0), #endif /* defined(ENABLED_DEBUG_SYNC) */ wait_for_commit_ptr(0), + m_internal_handler(0), main_da(0, false, false), m_stmt_da(&main_da), tdc_hash_pins(0), @@ -916,7 +917,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) MYF(MY_WME|MY_THREAD_SPECIFIC)); } - m_internal_handler= NULL; m_binlog_invoker= INVOKER_NONE; memset(&invoker_user, 0, sizeof(invoker_user)); memset(&invoker_host, 0, sizeof(invoker_host)); @@ -1252,6 +1252,8 @@ void THD::init(void) server_status= SERVER_STATUS_AUTOCOMMIT; if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES; + if (variables.sql_mode & MODE_ANSI_QUOTES) + server_status|= SERVER_STATUS_ANSI_QUOTES; transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= FALSE; diff --git a/sql/sql_class.h b/sql/sql_class.h index 8052e28fbb4..acd3ff0300e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4279,7 +4279,16 @@ public: { main_lex.restore_set_statement_var(); } - + /* Copy relevant `stmt` transaction flags to `all` transaction. */ + void merge_unsafe_rollback_flags() + { + if (transaction.stmt.modified_non_trans_table) + transaction.all.modified_non_trans_table= TRUE; + transaction.all.m_unsafe_rollback_flags|= + (transaction.stmt.m_unsafe_rollback_flags & + (THD_TRANS::DID_WAIT | THD_TRANS::CREATED_TEMP_TABLE | + THD_TRANS::DROPPED_TEMP_TABLE | THD_TRANS::DID_DDL)); + } /* Reset current_linfo Setting current_linfo to 0 needs to be done with LOCK_thread_count to diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 5cb4cd87296..35ec7fa74e1 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1462,7 +1462,7 @@ THD *CONNECT::create_thd(THD *thd) res= my_net_init(&thd->net, vio, thd, MYF(MY_THREAD_SPECIFIC)); vio= 0; // Vio now handled by thd - if (res) + if (res || thd->is_error()) { if (!thd_reused) delete thd; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5d6cf96a9a3..d037bad76ec 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4419,6 +4419,15 @@ void select_create::store_values(List<Item> &values) bool select_create::send_eof() { DBUG_ENTER("select_create::send_eof"); + + /* + The routine that writes the statement in the binary log + is in select_insert::prepare_eof(). For that reason, we + mark the flag at this point. + */ + if (table->s->tmp_table) + thd->transaction.stmt.mark_created_temp_table(); + if (prepare_eof()) { abort_result_set(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7c910e87c75..ac742d79681 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3325,6 +3325,7 @@ mysql_execute_command(THD *thd) goto error; } } + thd->transaction.stmt.mark_trans_did_ddl(); } #ifndef DBUG_OFF @@ -7456,8 +7457,7 @@ void THD::reset_for_next_command() if (!thd->in_multi_stmt_transaction_mode()) { thd->variables.option_bits&= ~OPTION_KEEP_LOG; - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); } DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx); thd->thread_specific_used= FALSE; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 5249f3b6ab3..97ef24f44ed 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -327,6 +327,12 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); +bool plugin_is_forced(struct st_plugin_int *p) +{ + return p->load_option == PLUGIN_FORCE || + p->load_option == PLUGIN_FORCE_PLUS_PERMANENT; +} + static void report_error(int where_to, uint error, ...) { va_list args; @@ -1397,7 +1403,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin, if (options_only || state == PLUGIN_IS_DISABLED) { - ret= 0; + ret= !options_only && plugin_is_forced(plugin); state= PLUGIN_IS_DISABLED; goto err; } @@ -1711,8 +1717,7 @@ int plugin_init(int *argc, char **argv, int flags) while ((plugin_ptr= *(--reap))) { mysql_mutex_unlock(&LOCK_plugin); - if (plugin_ptr->load_option == PLUGIN_FORCE || - plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT) + if (plugin_is_forced(plugin_ptr)) reaped_mandatory_plugin= TRUE; plugin_deinitialize(plugin_ptr, true); mysql_mutex_lock(&LOCK_plugin); @@ -3666,8 +3671,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, plugin_dash.length + 1); strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS); - if (tmp->load_option != PLUGIN_FORCE && - tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + if (!plugin_is_forced(tmp)) { /* support --skip-plugin-foo syntax */ options[0].name= plugin_name_ptr; @@ -4054,8 +4058,11 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, my_afree(tmp_backup); } - if (tmp->load_option != PLUGIN_FORCE && - tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + /* + We adjust the default value to account for the hardcoded exceptions + we have set for the federated and ndbcluster storage engines. + */ + if (!plugin_is_forced(tmp)) opts[0].def_value= opts[1].def_value= plugin_load_option; error= handle_options(argc, &argv, opts, mark_changed); @@ -4071,8 +4078,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, Set plugin loading policy from option value. First element in the option list is always the <plugin name> option value. */ - if (tmp->load_option != PLUGIN_FORCE && - tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + if (!plugin_is_forced(tmp)) plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value; } diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 67547f7a030..6c9df6a9606 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -122,7 +122,7 @@ #define OPTION_AUTOCOMMIT (1ULL << 8) // THD, user #define OPTION_BIG_SELECTS (1ULL << 9) // THD, user #define OPTION_LOG_OFF (1ULL << 10) // THD, user -#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user, unused +#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user #define TMP_TABLE_ALL_COLUMNS (1ULL << 12) // SELECT, intern #define OPTION_WARNINGS (1ULL << 13) // THD, user #define OPTION_AUTO_IS_NULL (1ULL << 14) // THD, user, binlog diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2c7ccbf3e2b..e8e399868db 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1451,6 +1451,7 @@ JOIN::optimize_inner() if (!select_lex->have_window_funcs()) zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved + select_lex->min_max_opt_list.empty(); const_tables= top_join_tab_count= table_count; /* Extract all table-independent conditions and replace the WHERE @@ -2662,8 +2663,11 @@ bool JOIN::make_aggr_tables_info() if (sort_table_cond) { if (!curr_tab->select) + { if (!(curr_tab->select= new SQL_SELECT)) DBUG_RETURN(true); + curr_tab->select->head= curr_tab->table; + } if (!curr_tab->select->cond) curr_tab->select->cond= sort_table_cond; else @@ -5971,7 +5975,7 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab) Item_field *cur_item; key_map possible_keys(0); - if (join->group_list) + if (join->group_list || join->simple_group) { /* Collect all query fields referenced in the GROUP clause. */ for (cur_group= join->group_list; cur_group; cur_group= cur_group->next) (*cur_group->item)->walk(&Item::collect_item_field_processor, 0, @@ -8367,6 +8371,63 @@ bool JOIN_TAB::hash_join_is_possible() } +/** + @brief + Check whether a KEYUSE can be really used for access this join table + + @param join Join structure with the best join order + for which the check is performed + @param keyuse Evaluated KEYUSE structure + + @details + This function is supposed to be used after the best execution plan have been + already chosen and the JOIN_TAB array for the best join order been already set. + For a given KEYUSE to access this JOIN_TAB in the best execution plan the + function checks whether it really can be used. The function first performs + the check with access_from_tables_is_allowed(). If it succeeds it checks + whether the keyuse->val does not use some fields of a materialized semijoin + nest that cannot be used to build keys to access outer tables. + Such KEYUSEs exists for the query like this: + select * from ot + where ot.c in (select it1.c from it1, it2 where it1.c=f(it2.c)) + Here we have two KEYUSEs to access table ot: with val=it1.c and val=f(it2.c). + However if the subquery was materialized the second KEYUSE cannot be employed + to access ot. + + @retval true the given keyuse can be used for ref access of this JOIN_TAB + @retval false otherwise +*/ + +bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, + KEYUSE *keyuse) +{ + if (!access_from_tables_is_allowed(keyuse->used_tables, + join->sjm_lookup_tables)) + return false; + if (join->sjm_scan_tables & table->map) + return true; + table_map keyuse_sjm_scan_tables= keyuse->used_tables & + join->sjm_scan_tables; + if (!keyuse_sjm_scan_tables) + return true; + uint sjm_tab_nr= 0; + while (!(keyuse_sjm_scan_tables & table_map(1) << sjm_tab_nr)) + sjm_tab_nr++; + JOIN_TAB *sjm_tab= join->map2table[sjm_tab_nr]; + TABLE_LIST *emb_sj_nest= sjm_tab->emb_sj_nest; + if (!(emb_sj_nest->sj_mat_info && emb_sj_nest->sj_mat_info->is_used && + emb_sj_nest->sj_mat_info->is_sj_scan)) + return true; + st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select(); + for (uint i= 0; i < sjm_sel->item_list.elements; i++) + { + if (sjm_sel->ref_pointer_array[i] == keyuse->val) + return true; + } + return false; +} + + static uint cache_record_length(JOIN *join,uint idx) { @@ -8956,6 +9017,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, do { if (!(~used_tables & keyuse->used_tables) && + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) && are_tables_local(join_tab, keyuse->used_tables)) { if (first_keyuse) @@ -8970,6 +9032,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, { if (curr->keypart == keyuse->keypart && !(~used_tables & curr->used_tables) && + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, + keyuse) && are_tables_local(join_tab, curr->used_tables)) break; } @@ -9004,6 +9068,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, do { if (!(~used_tables & keyuse->used_tables) && + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) && are_tables_local(join_tab, keyuse->used_tables)) { bool add_key_part= TRUE; @@ -9013,7 +9078,9 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, { if (curr->keypart == keyuse->keypart && !(~used_tables & curr->used_tables) && - are_tables_local(join_tab, curr->used_tables)) + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, + curr) && + are_tables_local(join_tab, curr->used_tables)) { keyuse->keypart= NO_KEYPART; add_key_part= FALSE; @@ -9115,8 +9182,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, do { if (!(~used_tables & keyuse->used_tables) && - j->access_from_tables_is_allowed(keyuse->used_tables, - join->sjm_lookup_tables)) + j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse)) { if (are_tables_local(j, keyuse->val->used_tables())) { @@ -9186,8 +9252,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, for (i=0 ; i < keyparts ; keyuse++,i++) { while (((~used_tables) & keyuse->used_tables) || - !j->access_from_tables_is_allowed(keyuse->used_tables, - join->sjm_lookup_tables) || + !j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) || keyuse->keypart == NO_KEYPART || (keyuse->keypart != (is_hash_join_key_no(key) ? diff --git a/sql/sql_select.h b/sql/sql_select.h index ab5dc08e044..886a66c3ef4 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -604,6 +604,8 @@ typedef struct st_join_table { !(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables)); } + bool keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, KEYUSE *keyuse); + void remove_redundant_bnl_scan_conds(); void save_explain_data(Explain_table_access *eta, table_map prefix_tables, @@ -1120,6 +1122,11 @@ public: to materialize and access by lookups */ table_map sjm_lookup_tables; + /** + Bitmap of semijoin tables that the chosen plan decided + to materialize to scan the results of materialization + */ + table_map sjm_scan_tables; /* Constant tables for which we have found a row (as opposed to those for which we didn't). @@ -1488,6 +1495,7 @@ public: in_to_exists_having= NULL; emb_sjm_nest= NULL; sjm_lookup_tables= 0; + sjm_scan_tables= 0; } /* True if the plan guarantees that it will be returned zero or one row */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index cf4c2526807..229d284bc3d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1336,8 +1336,13 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname, if (test_all_bits(sctx->master_access, DB_ACLS)) db_access=DB_ACLS; else - db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname->str, 0) | - sctx->master_access); + { + db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname->str, 0) | + sctx->master_access; + if (sctx->priv_role[0]) + db_access|= acl_get("", "", sctx->priv_role, dbname->str, 0); + } + if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname->str)) { status_var_increment(thd->status_var.access_denied_errors); @@ -4995,8 +5000,10 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) } #ifndef NO_EMBEDDED_ACCESS_CHECKS if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || - acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) || - !check_grant_db(thd, db_name->str)) + acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, false) || + (sctx->priv_role[0] ? + acl_get("", "", sctx->priv_role, db_name->str, false) : 0) || + !check_grant_db(thd, db_name->str)) #endif { load_db_opt_by_name(thd, db_name->str, &create); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5e247915905..5c5f2d373c7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2549,6 +2549,9 @@ err: if (non_trans_tmp_table_deleted || trans_tmp_table_deleted || non_tmp_table_deleted) { + if (non_trans_tmp_table_deleted || trans_tmp_table_deleted) + thd->transaction.stmt.mark_dropped_temp_table(); + query_cache_invalidate3(thd, tables, 0); if (!dont_log_query && mysql_bin_log.is_open()) { @@ -5091,6 +5094,9 @@ err: if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table()) DBUG_RETURN(result); + if (create_info->tmp_table()) + thd->transaction.stmt.mark_created_temp_table(); + /* Write log if no error or if we already deleted a table */ if (!result || thd->log_current_statement) { @@ -5617,13 +5623,17 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, DBUG_PRINT("info", ("res: %d tmp_table: %d create_info->table: %p", res, create_info->tmp_table(), local_create_info.table)); - if (!res && create_info->tmp_table() && local_create_info.table) + if (create_info->tmp_table()) { - /* - Remember that tmp table creation was logged so that we know if - we should log a delete of it. - */ - local_create_info.table->s->table_creation_was_logged= 1; + thd->transaction.stmt.mark_created_temp_table(); + if (!res && local_create_info.table) + { + /* + Remember that tmp table creation was logged so that we know if + we should log a delete of it. + */ + local_create_info.table->s->table_creation_was_logged= 1; + } } do_logging= TRUE; } @@ -9655,8 +9665,12 @@ bool mysql_trans_prepare_alter_copy_data(THD *thd) bool mysql_trans_commit_alter_copy_data(THD *thd) { bool error= FALSE; + uint save_unsafe_rollback_flags; DBUG_ENTER("mysql_trans_commit_alter_copy_data"); + /* Save flags as transcommit_implicit_are_deleting_them */ + save_unsafe_rollback_flags= thd->transaction.stmt.m_unsafe_rollback_flags; + if (ha_enable_transaction(thd, TRUE)) DBUG_RETURN(TRUE); @@ -9671,6 +9685,7 @@ bool mysql_trans_commit_alter_copy_data(THD *thd) if (trans_commit_implicit(thd)) error= TRUE; + thd->transaction.stmt.m_unsafe_rollback_flags= save_unsafe_rollback_flags; DBUG_RETURN(error); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 431d6822f0e..92923779be7 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -772,7 +772,9 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (saved_error) goto err; - if (fake_select_lex != NULL && thd->stmt_arena->is_stmt_prepare()) + if (fake_select_lex != NULL && + (thd->stmt_arena->is_stmt_prepare() || + (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))) { /* Validate the global parameters of this union */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 2c74ad5cb29..e2071184365 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3052,6 +3052,10 @@ static bool fix_sql_mode(sys_var *self, THD *thd, enum_var_type type) thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES; else thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES; + if (thd->variables.sql_mode & MODE_ANSI_QUOTES) + thd->server_status|= SERVER_STATUS_ANSI_QUOTES; + else + thd->server_status&= ~SERVER_STATUS_ANSI_QUOTES; } return false; } diff --git a/sql/table.cc b/sql/table.cc index 511a1567a53..b03f64bc7e0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4499,16 +4499,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) DBUG_ASSERT(!file->keyread_enabled()); - /* mark the record[0] uninitialized */ - TRASH_ALLOC(record[0], s->reclength); - - /* - Initialize the null marker bits, to ensure that if we are doing a read - of only selected columns (like in keyread), all null markers are - initialized. - */ - memset(record[0], 255, s->null_bytes); - memset(record[1], 255, s->null_bytes); + restore_record(this, s->default_values); /* Tables may be reused in a sub statement. */ DBUG_ASSERT(!file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN)); diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 174d1b6e184..42ebb87cbe4 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -1384,6 +1384,7 @@ bool THD::log_events_and_free_tmp_shares() variables.character_set_client= cs_save; get_stmt_da()->set_overwrite_status(true); + transaction.stmt.mark_dropped_temp_table(); if ((error= (mysql_bin_log.write(&qinfo) || error))) { /* diff --git a/sql/transaction.cc b/sql/transaction.cc index 9bacfb81bba..d01519b8bd4 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -198,11 +198,10 @@ bool trans_begin(THD *thd, uint flags) thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); /* - The following set should not be needed as the flag should always be 0 - when we come here. We should at some point change this to an assert. + The following set should not be needed as transaction state should + already be reset. We should at some point change this to an assert. */ - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); thd->has_waiter= false; thd->waiting_on_group_commit= false; @@ -323,8 +322,7 @@ bool trans_commit(THD *thd) else (void) RUN_HOOK(transaction, after_commit, (thd, FALSE)); thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); thd->lex->start_transaction_opt= 0; trans_track_end_trx(thd); @@ -373,8 +371,7 @@ bool trans_commit_implicit(THD *thd) } thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); /* Upon implicit commit, reset the current transaction @@ -420,8 +417,7 @@ bool trans_rollback(THD *thd) thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); /* Reset the binlog transaction marker */ thd->variables.option_bits&= ~OPTION_GTID_BEGIN; - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); thd->lex->start_transaction_opt= 0; trans_track_end_trx(thd); @@ -467,8 +463,7 @@ bool trans_rollback_implicit(THD *thd) preserve backward compatibility. */ thd->variables.option_bits&= ~(OPTION_KEEP_LOG); - thd->transaction.all.modified_non_trans_table= false; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); /* Rollback should clear transaction_rollback_request flag. */ DBUG_ASSERT(! thd->transaction_rollback_request); @@ -506,6 +501,8 @@ bool trans_commit_stmt(THD *thd) */ DBUG_ASSERT(! thd->in_sub_stmt); + thd->merge_unsafe_rollback_flags(); + if (thd->transaction.stmt.ha_list) { if (WSREP_ON) @@ -559,6 +556,8 @@ bool trans_rollback_stmt(THD *thd) */ DBUG_ASSERT(! thd->in_sub_stmt); + thd->merge_unsafe_rollback_flags(); + if (thd->transaction.stmt.ha_list) { if (WSREP_ON) @@ -979,8 +978,7 @@ bool trans_xa_commit(THD *thd) } thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); @@ -1037,8 +1035,7 @@ bool trans_xa_rollback(THD *thd) res= xa_trans_force_rollback(thd); thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); - thd->transaction.all.modified_non_trans_table= FALSE; - thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT; + thd->transaction.all.reset(); thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 439b253e80d..15dc0b70733 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1439,11 +1439,12 @@ row_ins_foreign_check_on_constraint( #ifdef WITH_WSREP err = wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - clust_rec, - clust_index, - FALSE, FALSE); + thr_get_trx(thr), + foreign, + clust_rec, + clust_index, + FALSE, + (node) ? TRUE : FALSE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %d\n", err); @@ -1609,6 +1610,10 @@ row_ins_check_foreign_constraint( rec_offs_init(offsets_); +#ifdef WITH_WSREP + upd_node= NULL; +#endif /* WITH_WSREP */ + ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S)); err = DB_SUCCESS; @@ -1802,9 +1807,10 @@ row_ins_check_foreign_constraint( err = wsrep_append_foreign_key( thr_get_trx(thr), foreign, - rec, - check_index, - check_ref, TRUE); + rec, + check_index, + check_ref, + (upd_node) ? TRUE : FALSE); #endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 28c60308ce9..213b1dc9ec3 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2364,7 +2364,8 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info, { uint options= table->s->db_options_in_use; - if (create_info->auto_increment_value != stats.auto_increment_value || + if ((create_info->used_fields & HA_CREATE_USED_AUTO && + create_info->auto_increment_value != stats.auto_increment_value) || create_info->data_file_name != data_file_name || create_info->index_file_name != index_file_name || table_changes == IS_EQUAL_NO || diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 7fbee0312ee..32536306320 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2072,7 +2072,6 @@ os_file_create_func( file = INVALID_HANDLE_VALUE; } } - #else /* __WIN__ */ int create_flag; const char* mode_str = NULL; diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index 6072b303d3a..00b8ce17b26 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1296,11 +1296,12 @@ row_ins_foreign_check_on_constraint( #ifdef WITH_WSREP err = wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - clust_rec, - clust_index, - FALSE, FALSE); + thr_get_trx(thr), + foreign, + clust_rec, + clust_index, + FALSE, + (node) ? TRUE : FALSE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %d\n", err); @@ -1461,6 +1462,9 @@ row_ins_check_foreign_constraint( ulint* offsets = offsets_; rec_offs_init(offsets_); +#ifdef WITH_WSREP + upd_node= NULL; +#endif /* WITH_WSREP */ run_again: #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_SHARED)); @@ -1651,8 +1655,9 @@ run_again: thr_get_trx(thr), foreign, rec, - check_index, - check_ref, TRUE); + check_index, + check_ref, + (upd_node) ? TRUE : FALSE); #endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp index 9a174b8529e..9281ce27d34 100644 --- a/win/packaging/ca/CustomAction.cpp +++ b/win/packaging/ca/CustomAction.cpp @@ -180,7 +180,7 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall, empty= true; for(;;) { - if (wcscmp(data.cFileName, L".") || wcscmp(data.cFileName, L"..")) + if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) { empty= false; break; |