diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-10-13 12:33:56 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-10-13 12:33:56 +0300 |
commit | 99bb3fb656f4a2a06c808b7c5d50e18e4c44b73b (patch) | |
tree | 121d54271137b00d58b23505644be3bc3a819a9e | |
parent | cda072bb4ba9e01d523d8deb995f28aa7a19fe11 (diff) | |
parent | a736a3174a4e7c0d92a38901ae61f563d4afede7 (diff) | |
download | mariadb-git-99bb3fb656f4a2a06c808b7c5d50e18e4c44b73b.tar.gz |
Merge 10.4 into 10.5
70 files changed, 1083 insertions, 327 deletions
diff --git a/.gitignore b/.gitignore index 1f7f71191c5..5005dbae363 100644 --- a/.gitignore +++ b/.gitignore @@ -378,6 +378,7 @@ x86/ build/ bld/ [Bb]in/ +/cmake-build-debug/ [Oo]bj/ # Roslyn cache directories @@ -560,7 +561,7 @@ compile_commands.json .vscode/ # Clion && other JetBrains ides -.idea +/.idea/ .cache/clangd diff --git a/client/mysql.cc b/client/mysql.cc index e49f7979a93..a606decb350 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1672,11 +1672,14 @@ static struct my_option my_long_options[] = &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"binary-mode", 0, - "By default, ASCII '\\0' is disallowed and '\\r\\n' is translated to '\\n'. " - "This switch turns off both features, and also turns off parsing of all client" - "commands except \\C and DELIMITER, in non-interactive mode (for input " - "piped to mysql or loaded using the 'source' command). This is necessary " - "when processing output from mysqlbinlog that may contain blobs.", + "Binary mode allows certain character sequences to be processed as data " + "that would otherwise be treated with a special meaning by the parser. " + "Specifically, this switch turns off parsing of all client commands except " + "\\C and DELIMITER in non-interactive mode (i.e., when binary mode is " + "combined with either 1) piped input, 2) the --batch mysql option, or 3) " + "the 'source' command). Also, in binary mode, occurrences of '\\r\\n' and " + "ASCII '\\0' are preserved within strings, whereas by default, '\\r\\n' is " + "translated to '\\n' and '\\0' is disallowed in user input.", &opt_binary_mode, &opt_binary_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"connect-expired-password", 0, "Notify the server that this client is prepared to handle expired " @@ -2321,8 +2324,15 @@ static bool add_line(String &buffer, char *line, size_t line_length, { // Found possbile one character command like \c - if (!(inchar = (uchar) *++pos)) - break; // readline adds one '\' + /* + The null-terminating character (ASCII '\0') marks the end of user + input. Then, by default, upon encountering a '\0' while parsing, it + should stop. However, some data naturally contains binary zeros + (e.g., zipped files). Real_binary_mode signals the parser to expect + '\0' within the data and not to end parsing if found. + */ + if (!(inchar = (uchar) *++pos) && (!real_binary_mode || !*in_string)) + break; // readline adds one '\' if (*in_string || inchar == 'N') // \N is short for NULL { // Don't allow commands in string *out++='\\'; diff --git a/include/ft_global.h b/include/ft_global.h index 725363c3aa8..9f2d52610ba 100644 --- a/include/ft_global.h +++ b/include/ft_global.h @@ -90,7 +90,8 @@ void ft_free_stopwords(void); FT_INFO *ft_init_search(uint,void *, uint, uchar *, size_t, CHARSET_INFO *, uchar *); -my_bool ft_boolean_check_syntax_string(const uchar *); +my_bool ft_boolean_check_syntax_string(const uchar *, size_t length, + CHARSET_INFO *cs); /* Internal symbols for fulltext between maria and MyISAM */ diff --git a/include/my_context.h b/include/my_context.h index ea0e3496887..45d2a7d7ffa 100644 --- a/include/my_context.h +++ b/include/my_context.h @@ -52,6 +52,9 @@ struct my_context { #ifdef MY_CONTEXT_USE_UCONTEXT +#if defined(__APPLE__) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE +#endif #include <ucontext.h> struct my_context { diff --git a/include/my_global.h b/include/my_global.h index da0d9920e06..1d7c91f37b8 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2019, MariaDB Corporation. + Copyright (c) 2009, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/include/mysql_com.h b/include/mysql_com.h index 78d9a5f3494..eb2ee7410d8 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -197,13 +197,13 @@ enum enum_indicator_type #define FIELD_FLAGS_COLUMN_FORMAT_MASK (3U << FIELD_FLAGS_COLUMN_FORMAT) #define FIELD_IS_DROPPED (1U << 26) /* Intern: Field is being dropped */ -#define VERS_SYS_START_FLAG (1 << 27) /* autogenerated column declared with +#define VERS_ROW_START (1 << 27) /* autogenerated column declared with `generated always as row start` (see II.a SQL Standard) */ -#define VERS_SYS_END_FLAG (1 << 28) /* autogenerated column declared with +#define VERS_ROW_END (1 << 28) /* autogenerated column declared with `generated always as row end` (see II.a SQL Standard).*/ -#define VERS_SYSTEM_FIELD (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG) +#define VERS_SYSTEM_FIELD (VERS_ROW_START | VERS_ROW_END) #define VERS_UPDATE_UNVERSIONED_FLAG (1 << 29) /* column that doesn't support system versioning when table itself supports it*/ diff --git a/man/mysql.1 b/man/mysql.1 index 519581394db..65c87e48179 100644 --- a/man/mysql.1 +++ b/man/mysql.1 @@ -206,7 +206,14 @@ option\&. .\" binary-mode option: mysql \fB\-\-binary\-mode\fR .sp -By default, ASCII '\e0' is disallowed and '\er\en' is translated to '\en'\&. This switch turns off both features, and also turns off parsing of all client commands except \eC and DELIMITER, in non-interactive mode (for input piped to mysql or loaded using the 'source' command)\&. This is necessary when processing output from mysqlbinlog that may contain blobs\&. +Binary mode allows certain character sequences to be processed as data that +would otherwise be treated with a special meaning by the parser\&. +Specifically, this switch turns off parsing of all client commands except \eC +and DELIMITER in non-interactive mode (i\&.e\&., when binary mode is combined +with either 1) piped input, 2) the --batch mysql option, or 3) the 'source' +command)\&. Also, in binary mode, occurrences of '\er\en' and ASCII '\e0' are +preserved within strings, whereas by default, '\er\en' is translated to '\en' +and '\e0' is disallowed in user input\&. .RE .sp .RS 4 diff --git a/mysql-test/main/ctype_utf16_def.result b/mysql-test/main/ctype_utf16_def.result index 98b6f7d913d..b5827d45619 100644 --- a/mysql-test/main/ctype_utf16_def.result +++ b/mysql-test/main/ctype_utf16_def.result @@ -8,3 +8,8 @@ character_set_server utf16 SHOW VARIABLES LIKE 'ft_stopword_file'; Variable_name Value ft_stopword_file (built-in) +# +# MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +# +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/ctype_utf16_def.test b/mysql-test/main/ctype_utf16_def.test index 0829cd53285..c6de842f618 100644 --- a/mysql-test/main/ctype_utf16_def.test +++ b/mysql-test/main/ctype_utf16_def.test @@ -7,3 +7,10 @@ call mtr.add_suppression("'utf16' can not be used as client character set"); SHOW VARIABLES LIKE 'collation_server'; SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'ft_stopword_file'; + +--echo # +--echo # MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +--echo # + +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/ctype_utf32_def.opt b/mysql-test/main/ctype_utf32_def.opt new file mode 100644 index 00000000000..3b0880cbff3 --- /dev/null +++ b/mysql-test/main/ctype_utf32_def.opt @@ -0,0 +1 @@ +--character-set-server=utf32,latin1 --collation-server=utf32_general_ci diff --git a/mysql-test/main/ctype_utf32_def.result b/mysql-test/main/ctype_utf32_def.result new file mode 100644 index 00000000000..611072eb75b --- /dev/null +++ b/mysql-test/main/ctype_utf32_def.result @@ -0,0 +1,6 @@ +call mtr.add_suppression("'utf32' can not be used as client character set"); +# +# MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +# +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/ctype_utf32_def.test b/mysql-test/main/ctype_utf32_def.test new file mode 100644 index 00000000000..e23f96052d3 --- /dev/null +++ b/mysql-test/main/ctype_utf32_def.test @@ -0,0 +1,9 @@ +--source include/have_utf32.inc +call mtr.add_suppression("'utf32' can not be used as client character set"); + +--echo # +--echo # MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +--echo # + +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result index 0d2c2e6acbc..e8f5bd8e48a 100644 --- a/mysql-test/main/default.result +++ b/mysql-test/main/default.result @@ -3387,6 +3387,14 @@ CREATE OR REPLACE TABLE t1(i int); ALTER TABLE t1 ADD b CHAR(255) DEFAULT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`; ERROR 42S22: Unknown column 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' in 'DEFAULT' DROP TABLE t1; +# +# MDEV-18278 Misleading error message in error log upon failed table creation +# +create table t1 (a int as (a)); +ERROR 01000: Expression for field `a` is referring to uninitialized field `a` +show warnings; +Level Code Message +Error 4029 Expression for field `a` is referring to uninitialized field `a` # end of 10.2 test # # MDEV-22703 DEFAULT() on a BLOB column can overwrite the default @@ -3403,3 +3411,4 @@ length(DEFAULT(h)) 25 INSERT INTO t1 () VALUES (); drop table t1; +# end of 10.3 test diff --git a/mysql-test/main/default.test b/mysql-test/main/default.test index c0561deac67..bcd6ef7a9fb 100644 --- a/mysql-test/main/default.test +++ b/mysql-test/main/default.test @@ -2109,6 +2109,13 @@ CREATE OR REPLACE TABLE t1(i int); ALTER TABLE t1 ADD b CHAR(255) DEFAULT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`; DROP TABLE t1; +--echo # +--echo # MDEV-18278 Misleading error message in error log upon failed table creation +--echo # +--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD +create table t1 (a int as (a)); +show warnings; + --echo # end of 10.2 test --echo # @@ -2126,3 +2133,5 @@ SELECT DEFAULT(h) FROM t1; SELECT length(DEFAULT(h)) FROM t1; INSERT INTO t1 () VALUES (); drop table t1; + +--echo # end of 10.3 test diff --git a/mysql-test/main/delayed_blob.opt b/mysql-test/main/delayed_blob.opt new file mode 100644 index 00000000000..e442a822046 --- /dev/null +++ b/mysql-test/main/delayed_blob.opt @@ -0,0 +1 @@ +--init_connect="set @a='something unique to have MTR start a dedicated mariadbd for this test and shutdown it after the test'" diff --git a/mysql-test/main/delayed_blob.result b/mysql-test/main/delayed_blob.result new file mode 100644 index 00000000000..caa2e3ae5fe --- /dev/null +++ b/mysql-test/main/delayed_blob.result @@ -0,0 +1,17 @@ +# +# MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED +# +SET sql_mode='TRADITIONAL'; +CREATE TABLE t1 (c BLOB) ENGINE=MyISAM; +INSERT DELAYED INTO t1 VALUES (''||''); +ERROR 22007: Truncated incorrect DOUBLE value: '' +DROP TABLE t1; +SET sql_mode=DEFAULT; +# +# MDEV-24467 Memory not freed after failed INSERT DELAYED +# +CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM; +ALTER TABLE t1 ADD b BLOB DEFAULT 'x'; +INSERT DELAYED INTO t1 (a) VALUES ('foo'); +ERROR 22001: Data too long for column 'a' at row 1 +DROP TABLE t1; diff --git a/mysql-test/main/delayed_blob.test b/mysql-test/main/delayed_blob.test new file mode 100644 index 00000000000..bf3e01a8825 --- /dev/null +++ b/mysql-test/main/delayed_blob.test @@ -0,0 +1,21 @@ +--echo # +--echo # MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED +--echo # + +SET sql_mode='TRADITIONAL'; +CREATE TABLE t1 (c BLOB) ENGINE=MyISAM; +--error ER_TRUNCATED_WRONG_VALUE +INSERT DELAYED INTO t1 VALUES (''||''); +DROP TABLE t1; +SET sql_mode=DEFAULT; + + +--echo # +--echo # MDEV-24467 Memory not freed after failed INSERT DELAYED +--echo # + +CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM; +ALTER TABLE t1 ADD b BLOB DEFAULT 'x'; +--error ER_DATA_TOO_LONG +INSERT DELAYED INTO t1 (a) VALUES ('foo'); +DROP TABLE t1; diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index b8a2d34786f..5d9aff6f6ad 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5019,6 +5019,18 @@ DROP TABLE t1; # End of 10.1 tests # # +# Start of 10.2 tests +# +# +# MDEV-24742 Server crashes in Charset::numchars / String::numchars +# +SELECT NULL IN (RIGHT(AES_ENCRYPT('foo','bar'), LAST_INSERT_ID()), 'qux'); +NULL IN (RIGHT(AES_ENCRYPT('foo','bar'), LAST_INSERT_ID()), 'qux') +NULL +# +# End of 10.2 tests +# +# # Start of 10.3 tests # # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 4df473fa0f6..432bc64f769 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -1991,6 +1991,22 @@ DROP TABLE t1; --echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-24742 Server crashes in Charset::numchars / String::numchars +--echo # + +SELECT NULL IN (RIGHT(AES_ENCRYPT('foo','bar'), LAST_INSERT_ID()), 'qux'); + + +--echo # +--echo # End of 10.2 tests +--echo # + + +--echo # --echo # Start of 10.3 tests --echo # diff --git a/mysql-test/main/invisible_field.result b/mysql-test/main/invisible_field.result index 9b42b043ec6..081c1ada1ee 100644 --- a/mysql-test/main/invisible_field.result +++ b/mysql-test/main/invisible_field.result @@ -538,7 +538,7 @@ a b insert into t2 values(1); select a,b from t2; a b -NULL 1 +12 1 drop table t1,t2; create table t1 (a int invisible, b int, c int); create table t2 (a int, b int, d int); @@ -627,3 +627,18 @@ drop table t1; create table t1 (a int, b int invisible); insert delayed into t1 values (1); drop table t1; +# +# MDEV-25891 Computed default for INVISIBLE column is ignored in INSERT +# +create table t1( +a int, +x int default (a), +y int default (a) invisible, +z int default (33) invisible); +insert into t1 values (1, default); +insert into t1 (a) values (2); +select a, x, y, z from t1; +a x y z +1 1 1 33 +2 2 2 33 +drop table t1; diff --git a/mysql-test/main/invisible_field.test b/mysql-test/main/invisible_field.test index 7a48347ec29..558ca7aa3a2 100644 --- a/mysql-test/main/invisible_field.test +++ b/mysql-test/main/invisible_field.test @@ -279,3 +279,16 @@ create table t1 (a int, b int invisible); insert delayed into t1 values (1); # cleanup drop table t1; + +--echo # +--echo # MDEV-25891 Computed default for INVISIBLE column is ignored in INSERT +--echo # +create table t1( + a int, + x int default (a), + y int default (a) invisible, + z int default (33) invisible); +insert into t1 values (1, default); +insert into t1 (a) values (2); +select a, x, y, z from t1; +drop table t1; diff --git a/mysql-test/main/multi_update.result b/mysql-test/main/multi_update.result index 4001a47ecd4..3ec9ea0caa5 100644 --- a/mysql-test/main/multi_update.result +++ b/mysql-test/main/multi_update.result @@ -1151,3 +1151,13 @@ b 1 3 drop tables t1, t2; +# +# MDEV-22464 Server crash on UPDATE with nested subquery +# +create table t1 (a int) ; +insert into t1 (a) values (1),(2),(3) ; +select a from t1 where a= (select 2 from t1 having (a = 3)); +ERROR 21000: Subquery returns more than 1 row +update t1 set a= (select 2 from t1 having (a = 3)); +ERROR 21000: Subquery returns more than 1 row +drop tables t1; diff --git a/mysql-test/main/multi_update.test b/mysql-test/main/multi_update.test index 84f06a7c165..3ee36f97fc5 100644 --- a/mysql-test/main/multi_update.test +++ b/mysql-test/main/multi_update.test @@ -1087,3 +1087,14 @@ update t1 left join t2 on a = b set b= 3 order by b; select * from t2; drop tables t1, t2; + +--echo # +--echo # MDEV-22464 Server crash on UPDATE with nested subquery +--echo # +create table t1 (a int) ; +insert into t1 (a) values (1),(2),(3) ; +--error ER_SUBQUERY_NO_1_ROW +select a from t1 where a= (select 2 from t1 having (a = 3)); +--error ER_SUBQUERY_NO_1_ROW +update t1 set a= (select 2 from t1 having (a = 3)); +drop tables t1; diff --git a/mysql-test/main/mysql_binary_zero_insert.result b/mysql-test/main/mysql_binary_zero_insert.result new file mode 100644 index 00000000000..0bed7487b3e --- /dev/null +++ b/mysql-test/main/mysql_binary_zero_insert.result @@ -0,0 +1,54 @@ +# Note: This test assumes NO_BACKSLASH_ESCAPES is not set in SQL_MODE. +############################## +# Setup +############################## +# +# Saving old state +# +set @old_sql_mode= @@global.SQL_MODE; +set @@global.SQL_MODE= ""; +# +# Create table for data entry +# +CREATE TABLE tb (`id` int(11) NOT NULL AUTO_INCREMENT,`cb` longblob DEFAULT NULL, PRIMARY KEY (`id`)) AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; +RESET MASTER; +############################## +# Test Case +############################## +# +# \0 (0x5c00 in binary) should be allowed in data strings if +# --binary-mode is enabled. +# +FOUND 10 /\x5c\x00/ in binary_zero_inserts.sql +# MYSQL --binary-mode test < MYSQL_TMP_DIR/binary_zero_inserts.sql +# +# Ensure a row exists from each insert statement with a \0 +# +SELECT COUNT(*)=8 from tb; +COUNT(*)=8 +1 +# +# Ensure that the binary zero was parsed and exists in the row data +# Note: We only look for 00 because the 5c only served as an escape +# in parsing. +# +# MYSQL_DUMP test tb --hex-blob | grep INSERT > MYSQL_TMP_DIR/dump.sql +FOUND 10 /00/ in dump.sql +# +# Ensure data consistency on mysqlbinlog replay +# +FLUSH LOGS; +# MYSQL_BINLOG MYSQLD_DATADIR/binlog_file > MYSQL_TMP_DIR/binlog_zeros.sql +FOUND 10 /\x5c\x00/ in binlog_zeros.sql +# MYSQL --binary-mode test < MYSQL_TMP_DIR/binlog_zeros.sql +# Table checksum is equivalent before and after binlog replay +# +# A \0 should still be treated as end-of-query in binary mode. +# +# MYSQL --binary-mode -B test < MYSQL_TMP_DIR/binary_zero_eoq.sql +############################## +# Cleanup +############################## +SET @@global.sql_mode= @old_sql_mode; +drop table tb; +RESET MASTER; diff --git a/mysql-test/main/mysql_binary_zero_insert.test b/mysql-test/main/mysql_binary_zero_insert.test new file mode 100644 index 00000000000..b327c8a4d1e --- /dev/null +++ b/mysql-test/main/mysql_binary_zero_insert.test @@ -0,0 +1,170 @@ +# +# Purpose: +# This test ensures that the mysql client is able to properly handle the +# binary data sequence 0x5c00, i.e. the null-terminating character \0, in a +# string when --binary-mode is enabled. Specifically, this sequence is valid to +# appear anywhere within a binary data string, and it should not end the string +# or SQL command. Additionally, \0 outside of a string should still end the +# query. +# +# Methodology: +# This test initially inserts data with binary strings containing \0. To +# ensure the mysql client is able to process this data correctly, perl is used +# to create a SQL file that contains \0 in strings, and this file is used as +# input into the client. The row data is then validated by searching for binary +# zeros in mysqldump output. +# +# +# References: +# MDEV-25444: mysql --binary-mode is not able to replay some mysqlbinlog +# outputs + +--echo # Note: This test assumes NO_BACKSLASH_ESCAPES is not set in SQL_MODE. + +--source include/have_log_bin.inc + +--echo ############################## +--echo # Setup +--echo ############################## + +--echo # +--echo # Saving old state +--echo # +set @old_sql_mode= @@global.SQL_MODE; +set @@global.SQL_MODE= ""; + +--echo # +--echo # Create table for data entry +--echo # +CREATE TABLE tb (`id` int(11) NOT NULL AUTO_INCREMENT,`cb` longblob DEFAULT NULL, PRIMARY KEY (`id`)) AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; + +# Will replay binlog later and we don't want to recreate the table +RESET MASTER; + + +--echo ############################## +--echo # Test Case +--echo ############################## + +--echo # +--echo # \0 (0x5c00 in binary) should be allowed in data strings if +--echo # --binary-mode is enabled. +--echo # +--perl + my $dir= $ENV{'MYSQL_TMP_DIR'}; + open (my $FILE, '>', "$dir/binary_zero_inserts.sql") or die "open(): $!"; + + print $FILE "TRUNCATE TABLE tb;\n"; + + # INSERT INTO tb(cb) VALUES(_binary '\0'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","5c00"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary '\0A'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","5c0041"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary 'A\0'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","415c00"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary 'A\0B'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","415c0042"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary '\0A\0'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","5c00415c00"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary '\\\0'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","5c5c5c00"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary '\0\0'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","5c005c00"; + print $FILE "');\n"; + + # INSERT INTO tb(cb) VALUES(_binary '\\0'); + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; + print $FILE pack "H*","5c5c00"; + print $FILE "');\n"; + + close ($FILE); +EOF +--let SEARCH_PATTERN= \x5c\x00 +--let SEARCH_FILE= $MYSQL_TMP_DIR/binary_zero_inserts.sql +--source include/search_pattern_in_file.inc +--echo # MYSQL --binary-mode test < MYSQL_TMP_DIR/binary_zero_inserts.sql +--exec $MYSQL --binary-mode test < $MYSQL_TMP_DIR/binary_zero_inserts.sql + +--echo # +--echo # Ensure a row exists from each insert statement with a \0 +--echo # +SELECT COUNT(*)=8 from tb; + +--echo # +--echo # Ensure that the binary zero was parsed and exists in the row data +--echo # Note: We only look for 00 because the 5c only served as an escape +--echo # in parsing. +--echo # +--echo # MYSQL_DUMP test tb --hex-blob | grep INSERT > MYSQL_TMP_DIR/dump.sql +--exec $MYSQL_DUMP test tb --hex-blob | grep INSERT > $MYSQL_TMP_DIR/dump.sql +--let SEARCH_PATTERN= 00 +--let SEARCH_FILE= $MYSQL_TMP_DIR/dump.sql +--source include/search_pattern_in_file.inc + +--echo # +--echo # Ensure data consistency on mysqlbinlog replay +--echo # +--let $good_checksum= `CHECKSUM TABLE tb` +let $MYSQLD_DATADIR= `SELECT @@datadir`; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +FLUSH LOGS; +--echo # MYSQL_BINLOG MYSQLD_DATADIR/binlog_file > MYSQL_TMP_DIR/binlog_zeros.sql +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQL_TMP_DIR/binlog_zeros.sql +--let SEARCH_PATTERN= \x5c\x00 +--let SEARCH_FILE= $MYSQL_TMP_DIR/binlog_zeros.sql +--source include/search_pattern_in_file.inc +--echo # MYSQL --binary-mode test < MYSQL_TMP_DIR/binlog_zeros.sql +--exec $MYSQL --binary-mode test < $MYSQL_TMP_DIR/binlog_zeros.sql +if ($good_checksum != `CHECKSUM TABLE tb`) +{ + die "Blob with binary zero data changed after binary log replay"; +} +--echo # Table checksum is equivalent before and after binlog replay + +--echo # +--echo # A \0 should still be treated as end-of-query in binary mode. +--echo # +--perl + my $dir= $ENV{'MYSQL_TMP_DIR'}; + open (my $FILE, '>', "$dir/binary_zero_eoq.sql") or die "open(): $!"; + + # INSERT INTO tb(cb) VALUES(_binary 'text')\0 + print $FILE "INSERT INTO tb(cb) VALUES (_binary 'text')"; + print $FILE pack "H*","5c00"; + + close ($FILE); +EOF +--echo # MYSQL --binary-mode -B test < MYSQL_TMP_DIR/binary_zero_eoq.sql +--exec $MYSQL --binary-mode -B test < $MYSQL_TMP_DIR/binary_zero_eoq.sql + + +--echo ############################## +--echo # Cleanup +--echo ############################## + +--remove_file $MYSQL_TMP_DIR/binary_zero_inserts.sql +--remove_file $MYSQL_TMP_DIR/binary_zero_eoq.sql +--remove_file $MYSQL_TMP_DIR/binlog_zeros.sql +--remove_file $MYSQL_TMP_DIR/dump.sql +SET @@global.sql_mode= @old_sql_mode; +drop table tb; +RESET MASTER; diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 4129deb6fc5..8a6fe8e16c1 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -16,9 +16,7 @@ MDEV-20225 : MDEV-20886 galera.MDEV-20225 MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-328B : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-329 : MDEV-19962 Galera test failure on MW-329 -galera_FK_duplicate_client_insert : MDEV-24473: galera.galera_FK_duplicate_client_insert MTR failed: SIGABRT. InnoDB: Conflicting lock on table. Assertion failure in lock0lock.cc galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event() -galera_bf_abort_at_after_statement : MDEV-21557: galera_bf_abort_at_after_statement MTR failed: query 'reap' succeeded - should have failed with errno 1213 galera_bf_abort_group_commit : MDEV-18282 Galera test failure on galera.galera_bf_abort_group_commit galera_bf_kill_debug : MDEV-24485 wsrep::client_state::do_acquire_ownership(): Assertion `state_ == s_idle || mode_ != m_local' failed galera_bf_lock_wait : MDEV-21597 wsrep::transaction::start_transaction(): Assertion `active() == false' failed @@ -32,18 +30,12 @@ galera_parallel_simple : MDEV-20318 galera.galera_parallel_simple fails galera_pc_ignore_sb : MDEV-20888 galera.galera_pc_ignore_sb galera_pc_recovery : MDEV-25199 cluster fails to start up galera_shutdown_nonprim : MDEV-21493 galera.galera_shutdown_nonprim -galera_toi_ddl_nonconflicting : MDEV-21518 galera.galera_toi_ddl_nonconflicting -galera_toi_truncate : MDEV-22996 Hang on galera_toi_truncate test case galera_trigger : MDEV-24048 galera.galera_trigger MTR fails: Result content mismatch +galera_var_ignore_apply_errors : MDEV-26770 galera_var_ignore_apply_errors fails Server did not transition to READY state galera_var_node_address : MDEV-20485 Galera test failure galera_var_notify_cmd : MDEV-21905 Galera test galera_var_notify_cmd causes hang -galera_var_reject_queries : assertion in inline_mysql_socket_send -galera_var_replicate_myisam_on : MDEV-24062 Galera test failure on galera_var_replicate_myisam_on galera_var_retry_autocommit: MDEV-18181 Galera test failure on galera.galera_var_retry_autocommit mysql-wsrep#198 : MDEV-24446: galera.mysql-wsrep#198 MTR failed: query 'reap' failed: 2000: Unknown MySQL error partition : MDEV-19958 Galera test failure on galera.partition query_cache: MDEV-15805 Test failure on galera.query_cache versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch -galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons -pxc-421: wsrep_provider is read-only for security reasons - diff --git a/mysql-test/suite/galera/r/galera_toi_truncate.result b/mysql-test/suite/galera/r/galera_toi_truncate.result index a02487ac347..bd3ee0dd75e 100644 --- a/mysql-test/suite/galera/r/galera_toi_truncate.result +++ b/mysql-test/suite/galera/r/galera_toi_truncate.result @@ -3,16 +3,24 @@ connection node_1; connection node_1; CREATE TABLE ten (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB; INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +CREATE TABLE t1 (id int not null primary key auto_increment, f1 INTEGER) ENGINE=InnoDB; connection node_2; -SET SESSION wsrep_retry_autocommit = 0; -INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6, ten AS a7, ten AS a8; -connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; -connection node_2a; +set session wsrep_sync_wait=0; +connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1b; +SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb"; +connection node_2; +INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1; +connection node_1b; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; +connection node_1; +TRUNCATE TABLE t1;; +connection node_1b; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; +SET GLOBAL debug_dbug = ""; +SET DEBUG_SYNC = "RESET"; connection node_1; -TRUNCATE TABLE t1; connection node_2; -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction SELECT COUNT(*) AS EXPECT_0 FROM t1; EXPECT_0 0 @@ -20,5 +28,6 @@ connection node_1; SELECT COUNT(*) AS EXPECT_0 FROM t1; EXPECT_0 0 +disconnect node_1b; DROP TABLE t1; DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_var_reject_queries.result b/mysql-test/suite/galera/r/galera_var_reject_queries.result index 1b2bc1c5e16..33ee9262638 100644 --- a/mysql-test/suite/galera/r/galera_var_reject_queries.result +++ b/mysql-test/suite/galera/r/galera_var_reject_queries.result @@ -1,11 +1,6 @@ -<<<<<<< HEAD connection node_2; connection node_1; -||||||| merged common ancestors -======= -call mtr.add_suppression("WSREP has not yet prepared node for application use"); ->>>>>>> 10.3 -CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; connection node_1; SET SESSION wsrep_reject_queries = ALL; @@ -27,7 +22,7 @@ VARIABLE_VALUE = 2 INSERT INTO t1 VALUES (1); connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1; SET GLOBAL wsrep_reject_queries = NONE; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SELECT COUNT(*) AS EXPECT_1 FROM t1; +EXPECT_1 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result b/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result index ad28f5a426e..314da703e58 100644 --- a/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result +++ b/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result @@ -53,8 +53,8 @@ COUNT(*) = 0 1 DROP TABLE t1; connection node_1; -CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; -CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES (1); @@ -100,7 +100,7 @@ DROP TABLE t2; # MDEV-11152: wsrep_replicate_myisam: SELECT gets replicated using TO # connection node_1; -CREATE TABLE t1 (i INT) ENGINE=INNODB; +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=INNODB; INSERT INTO t1 VALUES(1); SELECT * FROM t1; i @@ -237,5 +237,14 @@ DROP TRIGGER tr1; DROP TRIGGER tr2; DROP TRIGGER tr3; DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, b INT, UNIQUE(a)) ENGINE=MyISAM; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1; +SET GLOBAL wsrep_replicate_myisam=ON; +INSERT INTO t1 (a,b) VALUES (10,20); +connection node_2; +SELECT * from t1; +a b +1 20 connection node_1; +DROP TABLE t1; connection node_2; diff --git a/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result b/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result deleted file mode 100644 index 7a645407004..00000000000 --- a/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result +++ /dev/null @@ -1,23 +0,0 @@ -connection node_2; -connection node_1; -connection node_1; -connection node_2; -connection node_1; -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -connection node_2; -SET GLOBAL wsrep_provider='none'; -INSERT INTO t1 VALUES (2); -connection node_1; -INSERT INTO t1 VALUES (3); -connection node_2; -SET SESSION wsrep_sync_wait = 0; -INSERT INTO t1 VALUES (4); -SELECT COUNT(*) = 4 FROM t1; -COUNT(*) = 4 -1 -connection node_1; -SELECT COUNT(*) = 3 FROM t1; -COUNT(*) = 3 -1 -DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/pxc-421.result b/mysql-test/suite/galera/r/pxc-421.result deleted file mode 100644 index 058af15c098..00000000000 --- a/mysql-test/suite/galera/r/pxc-421.result +++ /dev/null @@ -1,46 +0,0 @@ -connection node_2; -connection node_1; -connection node_1; -connection node_2; -connection node_1; -set GLOBAL wsrep_slave_threads=26; -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -INSERT INTO t1 (f1) SELECT * from t1 as x1; -connection node_2; -set GLOBAL wsrep_slave_threads=16; -SET GLOBAL wsrep_provider='none'; -INSERT INTO t1 VALUES (2); -connection node_1; -INSERT INTO t1 VALUES (3); -connection node_2; -INSERT INTO t1 VALUES (4); -set GLOBAL wsrep_slave_threads=5; -SELECT COUNT(*) = 5 FROM t1; -COUNT(*) = 5 -1 -connection node_1; -set GLOBAL wsrep_slave_threads=12; -SELECT COUNT(*) = 4 FROM t1; -COUNT(*) = 4 -1 -INSERT INTO t1 VALUES (100), (101), (102); -connection node_2; -set GLOBAL wsrep_slave_threads=5; -INSERT INTO t1 (f1) SELECT * from t1 as x1; -show global variables like 'wsrep_slave_threads'; -Variable_name Value -wsrep_slave_threads 5 -SET GLOBAL wsrep_slave_threads = 1; -SELECT COUNT(*) FROM t1; -COUNT(*) -16 -connection node_1; -SELECT COUNT(*) FROM t1; -COUNT(*) -15 -show global variables like 'wsrep_slave_threads'; -Variable_name Value -wsrep_slave_threads 12 -SET GLOBAL wsrep_slave_threads = 1; -DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test b/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test index dbd2510cba3..d431fc0b9ed 100644 --- a/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test +++ b/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test @@ -8,6 +8,8 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER); --connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1'; +--source include/wait_condition.inc --send ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 (f1, f2) VALUES (DEFAULT, 123); --connection node_1 diff --git a/mysql-test/suite/galera/t/galera_toi_truncate.test b/mysql-test/suite/galera/t/galera_toi_truncate.test index 5b23a8c3f3e..ab94d9397ce 100644 --- a/mysql-test/suite/galera/t/galera_toi_truncate.test +++ b/mysql-test/suite/galera/t/galera_toi_truncate.test @@ -6,6 +6,7 @@ --source include/galera_cluster.inc --source include/have_debug_sync.inc --source include/have_debug.inc +--source include/galera_have_debug_sync.inc # # INSERT and TRUNCATE on different nodes @@ -15,32 +16,51 @@ CREATE TABLE ten (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB; INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +CREATE TABLE t1 (id int not null primary key auto_increment, f1 INTEGER) ENGINE=InnoDB; --connection node_2 +set session wsrep_sync_wait=0; --let $wait_condition = SELECT COUNT(*) = 10 FROM ten; --source include/wait_condition.inc -# Prevent autocommit retring from masking the deadlock error we expect to get -SET SESSION wsrep_retry_autocommit = 0; ---send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6, ten AS a7, ten AS a8 +--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1b ---connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 ---connection node_2a ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Sending data%' AND INFO LIKE 'INSERT INTO t1 (f1)%'; ---source include/wait_condition.inc +# block applier before applying +SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb"; + +--connection node_2 +--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1 + +--connection node_1b +# wait until applier has reached the sync point +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; --connection node_1 -TRUNCATE TABLE t1; +--send TRUNCATE TABLE t1; + +--connection node_1b +# release the applier +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; +SET GLOBAL debug_dbug = ""; +SET DEBUG_SYNC = "RESET"; + +--connection node_1 +--reap --connection node_2 ---error ER_LOCK_DEADLOCK --reap +--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; +--source include/wait_condition.inc SELECT COUNT(*) AS EXPECT_0 FROM t1; --connection node_1 +--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; +--source include/wait_condition.inc SELECT COUNT(*) AS EXPECT_0 FROM t1; +--disconnect node_1b + DROP TABLE t1; DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_var_reject_queries.test b/mysql-test/suite/galera/t/galera_var_reject_queries.test index aa31b94d6e0..60aabe9bc17 100644 --- a/mysql-test/suite/galera/t/galera_var_reject_queries.test +++ b/mysql-test/suite/galera/t/galera_var_reject_queries.test @@ -5,9 +5,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc -call mtr.add_suppression("WSREP has not yet prepared node for application use"); - -CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 @@ -44,6 +42,6 @@ INSERT INTO t1 VALUES (1); --connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1 SET GLOBAL wsrep_reject_queries = NONE; -SELECT COUNT(*) = 1 FROM t1; +SELECT COUNT(*) AS EXPECT_1 FROM t1; DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test b/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test index adb5cb04273..acebe4cccdc 100644 --- a/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test +++ b/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test @@ -80,8 +80,8 @@ DROP TABLE t1; # --connection node_1 -CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; -CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES (1); @@ -136,7 +136,7 @@ DROP TABLE t2; --echo # MDEV-11152: wsrep_replicate_myisam: SELECT gets replicated using TO --echo # --connection node_1 -CREATE TABLE t1 (i INT) ENGINE=INNODB; +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=INNODB; INSERT INTO t1 VALUES(1); # This command should not get replicated. SELECT * FROM t1; @@ -218,7 +218,16 @@ DROP TRIGGER tr2; DROP TRIGGER tr3; DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, b INT, UNIQUE(a)) ENGINE=MyISAM; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1; +SET GLOBAL wsrep_replicate_myisam=ON; +INSERT INTO t1 (a,b) VALUES (10,20); + +--connection node_2 +SELECT * from t1; --connection node_1 +DROP TABLE t1; + --disable_query_log --eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig --enable_query_log @@ -227,3 +236,4 @@ DROP TABLE t1,t2; --disable_query_log --eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig --enable_query_log + diff --git a/mysql-test/suite/galera/t/galera_wsrep_provider_unset_set.test b/mysql-test/suite/galera/t/galera_wsrep_provider_unset_set.test deleted file mode 100644 index 7f91495fcc4..00000000000 --- a/mysql-test/suite/galera/t/galera_wsrep_provider_unset_set.test +++ /dev/null @@ -1,50 +0,0 @@ -# -# Test that wsrep_provider can be unset and then set back to its original value -# and replication will continue except for any updates made while the value was 'none' -# - ---source include/galera_cluster.inc ---source include/have_innodb.inc - -# Save original auto_increment_offset values. ---let $node_1=node_1 ---let $node_2=node_2 ---source include/auto_increment_offset_save.inc - ---connection node_1 -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); - ---connection node_2 ---let $wsrep_provider_orig = `SELECT @@wsrep_provider` ---let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address` - -SET GLOBAL wsrep_provider='none'; -INSERT INTO t1 VALUES (2); - ---connection node_1 -INSERT INTO t1 VALUES (3); - ---connection node_2 ---disable_query_log ---eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; ---eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig'; ---enable_query_log - -SET SESSION wsrep_sync_wait = 0; - ---source include/wait_until_connected_again.inc ---source include/galera_wait_ready.inc - -INSERT INTO t1 VALUES (4); - -# Node #2 has all the inserts -SELECT COUNT(*) = 4 FROM t1; - ---connection node_1 -# Node #1 is missing the insert made while Node #2 was not replicated -SELECT COUNT(*) = 3 FROM t1; - -DROP TABLE t1; - ---source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/pxc-421.test b/mysql-test/suite/galera/t/pxc-421.test deleted file mode 100644 index 33a2b157f18..00000000000 --- a/mysql-test/suite/galera/t/pxc-421.test +++ /dev/null @@ -1,67 +0,0 @@ -# -# PXC-421: Test deadlock involving updates of -# wsrep_provider, wsrep_cluster_address and wsrep_slave_threads. -# - ---source include/galera_cluster.inc ---source include/have_innodb.inc - -# Save original auto_increment_offset values. ---let $node_1=node_1 ---let $node_2=node_2 ---source include/auto_increment_offset_save.inc - ---connection node_1 ---let $wsrep_slave_1 = `SELECT @@wsrep_slave_threads` -set GLOBAL wsrep_slave_threads=26; -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -INSERT INTO t1 (f1) SELECT * from t1 as x1; - ---connection node_2 ---let $wsrep_slave_2 = `SELECT @@wsrep_slave_threads` -set GLOBAL wsrep_slave_threads=16; ---let $wsrep_provider_orig = `SELECT @@wsrep_provider` ---let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address` - -SET GLOBAL wsrep_provider='none'; -INSERT INTO t1 VALUES (2); - ---connection node_1 -INSERT INTO t1 VALUES (3); - ---connection node_2 ---disable_query_log ---eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; ---eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig'; ---enable_query_log - ---source include/wait_until_connected_again.inc - -INSERT INTO t1 VALUES (4); -set GLOBAL wsrep_slave_threads=5; - -# Node #2 has all the inserts -SELECT COUNT(*) = 5 FROM t1; - ---connection node_1 -set GLOBAL wsrep_slave_threads=12; -# Node #1 is missing the insert made while Node #2 was not replicated -SELECT COUNT(*) = 4 FROM t1; -INSERT INTO t1 VALUES (100), (101), (102); - ---connection node_2 -set GLOBAL wsrep_slave_threads=5; -INSERT INTO t1 (f1) SELECT * from t1 as x1; -show global variables like 'wsrep_slave_threads'; ---eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_2 -SELECT COUNT(*) FROM t1; - ---connection node_1 -SELECT COUNT(*) FROM t1; -show global variables like 'wsrep_slave_threads'; ---eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_1 -DROP TABLE t1; - ---source include/auto_increment_offset_restore.inc - diff --git a/mysql-test/suite/galera_3nodes_sr/r/MDEV-26707.result b/mysql-test/suite/galera_3nodes_sr/r/MDEV-26707.result new file mode 100644 index 00000000000..8de724c1576 --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/r/MDEV-26707.result @@ -0,0 +1,86 @@ +connection node_2; +connection node_1; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connect node_3a, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +connection node_2; +SET SESSION wsrep_trx_fragment_size=1; +BEGIN; +INSERT INTO t1 VALUES (21); +connection node_1; +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +EXPECT_1 +1 +connection node_3; +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +EXPECT_1 +1 +connection node_3a; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1a; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_2a; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_2; +SET DEBUG_SYNC = 'wsrep_before_certification SIGNAL before_cert WAIT_FOR continue'; +COMMIT; +connection node_2a; +SET DEBUG_SYNC = 'now WAIT_FOR before_cert'; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +SET DEBUG_SYNC = 'now SIGNAL continue'; +connection node_2; +ERROR HY000: Got error 6 "No such device or address" during COMMIT +connection node_2a; +SET DEBUG_SYNC = 'RESET'; +connection node_1a; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_3a; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +SET SESSION wsrep_sync_wait = 0; +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +EXPECT_1 +1 +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1a; +SET SESSION wsrep_sync_wait = 0; +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +EXPECT_1 +1 +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_2a; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1a; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_3a; +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1a; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 +0 +connection node_2a; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 +0 +connection node_3a; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 +0 +connection node_1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result b/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result index e9dc5518e96..933038e00f1 100644 --- a/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result +++ b/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result @@ -32,14 +32,18 @@ Killing server ... # restart connection node_1; COMMIT; -SELECT COUNT(*) = 5 FROM t1; -COUNT(*) = 5 +count_match 1 -connection node_2; -SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; -COUNT(*) = 0 +count_match 1 connection node_1; +SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +COUNT(*) +0 +connection node_2; +SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +COUNT(*) +0 +connection node_1; DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/suite/galera_3nodes_sr/suite.pm b/mysql-test/suite/galera_3nodes_sr/suite.pm index a65c2b5df30..becc764733a 100644 --- a/mysql-test/suite/galera_3nodes_sr/suite.pm +++ b/mysql-test/suite/galera_3nodes_sr/suite.pm @@ -37,6 +37,8 @@ push @::global_suppressions, qr|WSREP: Protocol violation. JOIN message sender .* is not in state transfer \(SYNCED\). Message ignored.|, qr|WSREP: Protocol violation. JOIN message sender .* is not in state transfer \(JOINED\). Message ignored.|, qr(WSREP: Action message in non-primary configuration from member [0-9]*), + qr(WSREP: Last Applied Action message in non-primary configuration from member [0-9]*), + qr|WSREP: .*core_handle_uuid_msg.*|, qr(WSREP: --wsrep-causal-reads=ON takes precedence over --wsrep-sync-wait=0. WSREP_SYNC_WAIT_BEFORE_READ is on), qr(WSREP: JOIN message from member .* in non-primary configuration. Ignored.), ); diff --git a/mysql-test/suite/galera_3nodes_sr/t/MDEV-26707.test b/mysql-test/suite/galera_3nodes_sr/t/MDEV-26707.test new file mode 100644 index 00000000000..ed7adc8313a --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/t/MDEV-26707.test @@ -0,0 +1,162 @@ +# +# MDEV-26707: SR transaction rolls back locally, but not in cluster +# +# This test excercises the following scenario: +# Initially we have a three node cluster where node 2 has an active +# SR transaction that has replicated one fragment. +# Node 3 disconnects from the cluster, followed by disconnect of node 2. +# Node 2 attempts to COMMIT its transaction, but fails because node 2 is +# non-primary. This failure causes the transaction to rolled back locally +# (node 2 can't communicate with the cluster at this point, so rollback +# fragment cannot be sent successfully) +# Node 3 joins back creating non-primary view (node 1, node 3). +# Then node 2 joins back creating primary view (node 1, node 1, node 3). +# If bug is present, we have that node 2 has rolled back locally, while +# the same transaction is still active nodes 1 and 3, leaving entries +# in their wsrep_streaming_log tables. +# + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connect node_3a, 127.0.0.1, root, , test, $NODE_MYPORT_3 + + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); + +--connection node_2 +SET SESSION wsrep_trx_fragment_size=1; +BEGIN; +INSERT INTO t1 VALUES (21); + +--connection node_1 +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; + +--connection node_2 +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; + +--connection node_3 +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; + +# +# Disconnect node 3 from cluster +# +--connection node_3a +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_2a +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SET SESSION wsrep_sync_wait = DEFAULT; + +# +# Issue commit block COMMIT before certification on node 2 +# +--connection node_2 +SET DEBUG_SYNC = 'wsrep_before_certification SIGNAL before_cert WAIT_FOR continue'; +--send COMMIT + +--connection node_2a +SET DEBUG_SYNC = 'now WAIT_FOR before_cert'; + +# +# Disconnect node 2 +# +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SET SESSION wsrep_sync_wait = DEFAULT; + + +# +# Unblock COMMIT and expect it to fail +# +SET DEBUG_SYNC = 'now SIGNAL continue'; + +--connection node_2 +--error ER_ERROR_DURING_COMMIT +--reap + +--connection node_2a +SET DEBUG_SYNC = 'RESET'; + +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SET SESSION wsrep_sync_wait = DEFAULT; + + +# +# Reconnect node 3 +# +--connection node_3a +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_streaming_log; +SET SESSION wsrep_sync_wait = DEFAULT; + + +# +# Reconnect node 2 +# +--connection node_2a +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +--source include/galera_wait_ready.inc +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +--source include/galera_wait_ready.inc +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_3a +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +--source include/galera_wait_ready.inc +SET SESSION wsrep_sync_wait = DEFAULT; + + +# +# Expect no entries in wsrep_streaming_log +# +--connection node_1a +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +--connection node_2a +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +--connection node_3a +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; + + +--connection node_1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test index 92566fa6323..ea549a6bea2 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test @@ -51,20 +51,37 @@ INSERT INTO t1 VALUES (5); --source include/kill_galera.inc --source include/start_mysqld.inc -# Expect that the SR table will get some entries after the restart ---let $wait_condition = SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; ---source include/wait_condition.inc - --connection node_1 +# The following COMMIT usually succeeds. Due to timing, +# it is however possible that this node delivers the same +# view twice during configuration change. In which case +# this transaction will mistakenly be considered orphaned, +# and aborted. +--error 0, ER_LOCK_DEADLOCK COMMIT; -SELECT COUNT(*) = 5 FROM t1; ---connection node_2 -SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; ---let $wait_condition = SELECT COUNT(*) = 5 FROM t1; ---source include/wait_condition.inc -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; +--disable_query_log +if ($mysql_errno == 0) { + --connection node_1 + SELECT COUNT(*) = 5 AS count_match FROM t1; + --connection node_2 + SELECT COUNT(*) = 5 AS count_match FROM t1; +} + +if ($mysql_errno == 1213) { + --connection node_1 + SELECT COUNT(*) = 0 AS count_match FROM t1; + --connection node_2 + SELECT COUNT(*) = 0 AS count_match FROM t1; +} +--enable_query_log + +--connection node_1 +SELECT COUNT(*) FROM mysql.wsrep_streaming_log; + +--connection node_2 +SELECT COUNT(*) FROM mysql.wsrep_streaming_log; --connection node_1 DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/mdev-14846.result b/mysql-test/suite/innodb/r/mdev-14846.result new file mode 100644 index 00000000000..219bd718feb --- /dev/null +++ b/mysql-test/suite/innodb/r/mdev-14846.result @@ -0,0 +1,52 @@ +CREATE TABLE t1 ( +pk INT, +f1 VARCHAR(10) NOT NULL, +f2 VARCHAR(10) NULL, +f3 INT UNSIGNED NULL, +KEY (f1), +PRIMARY KEY (pk) +) ENGINE=InnoDB; +CREATE OR REPLACE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'k','g',6),(2,'y','r',0),(3,'t','q',1),(4,'a','r',NULL),(5,'z','t',NULL); +CREATE TABLE t2 (f VARCHAR(10) NULL) ENGINE=InnoDB; +INSERT INTO t2 VALUES (NULL),('g'),('e'),('g'); +CREATE TABLE t3 ( +f1 VARCHAR(10) NOT NULL, +f2 VARCHAR(10) NULL, +f3 INT UNSIGNED NULL +) ENGINE=InnoDB; +INSERT INTO t3 VALUES ('k','n',9),('y','b',8),('m','w',6); +CREATE TABLE t4 (f INT NULL) ENGINE=InnoDB; +INSERT INTO t4 VALUES (8),(9); +UPDATE t1 SET t1.pk = -109 WHERE t1.f1 IN ( SELECT 'a' FROM t4 WHERE f >= 1 ); +SET DEBUG_SYNC='now SIGNAL con1_dml'; +connect con1,localhost,root,,test; +SET DEBUG_SYNC='now WAIT_FOR con1_dml'; +begin; +SELECT * FROM t1 for update; +pk f1 f2 f3 +-109 a r NULL +1 k g 6 +2 y r 0 +3 t q 1 +5 z t NULL +SET DEBUG_SYNC='now SIGNAL default_dml'; +connection default; +SET DEBUG_SYNC='now WAIT_FOR default_dml'; +UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h'; +connect con2,localhost,root,,test; +set debug_sync='now WAIT_FOR default_dml'; +SET DEBUG_SYNC='now SIGNAL con1_dml2'; +disconnect con2; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR con1_dml2'; +UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); +connection default; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection con1; +COMMIT; +disconnect con1; +connection default; +DROP VIEW v4; +DROP TABLE t1, t2, t3, t4; +set debug_sync= reset; diff --git a/mysql-test/suite/innodb/t/mdev-14846.opt b/mysql-test/suite/innodb/t/mdev-14846.opt new file mode 100644 index 00000000000..c8fe0561390 --- /dev/null +++ b/mysql-test/suite/innodb/t/mdev-14846.opt @@ -0,0 +1 @@ +--loose-innodb_lock_waits diff --git a/mysql-test/suite/innodb/t/mdev-14846.test b/mysql-test/suite/innodb/t/mdev-14846.test new file mode 100644 index 00000000000..adcefecd52f --- /dev/null +++ b/mysql-test/suite/innodb/t/mdev-14846.test @@ -0,0 +1,70 @@ +--source include/have_innodb.inc +--source include/count_sessions.inc +--source include/have_debug_sync.inc + +CREATE TABLE t1 ( + pk INT, + f1 VARCHAR(10) NOT NULL, + f2 VARCHAR(10) NULL, + f3 INT UNSIGNED NULL, + KEY (f1), + PRIMARY KEY (pk) +) ENGINE=InnoDB; + +CREATE OR REPLACE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'k','g',6),(2,'y','r',0),(3,'t','q',1),(4,'a','r',NULL),(5,'z','t',NULL); + +CREATE TABLE t2 (f VARCHAR(10) NULL) ENGINE=InnoDB; +INSERT INTO t2 VALUES (NULL),('g'),('e'),('g'); + +CREATE TABLE t3 ( + f1 VARCHAR(10) NOT NULL, + f2 VARCHAR(10) NULL, + f3 INT UNSIGNED NULL +) ENGINE=InnoDB; + +INSERT INTO t3 VALUES ('k','n',9),('y','b',8),('m','w',6); + +CREATE TABLE t4 (f INT NULL) ENGINE=InnoDB; +INSERT INTO t4 VALUES (8),(9); +UPDATE t1 SET t1.pk = -109 WHERE t1.f1 IN ( SELECT 'a' FROM t4 WHERE f >= 1 ); +SET DEBUG_SYNC='now SIGNAL con1_dml'; + +--connect (con1,localhost,root,,test) +SET DEBUG_SYNC='now WAIT_FOR con1_dml'; +begin; +SELECT * FROM t1 for update; # Holds x lock of all records in the table t1 +SET DEBUG_SYNC='now SIGNAL default_dml'; + +--connection default +SET DEBUG_SYNC='now WAIT_FOR default_dml'; +--send UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h' +# It holds the lock of all record in t3 and tries to acquire record lock for the table t1. + +--connect (con2,localhost,root,,test) +set debug_sync='now WAIT_FOR default_dml'; +let $wait_condition= +select count(*) > 0 from information_schema.innodb_lock_waits; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL con1_dml2'; +disconnect con2; + +# Cleanup +--connection con1 +SET DEBUG_SYNC='now WAIT_FOR con1_dml2'; +UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); +# It holds the record lock on table t1 and tries to acquire record lock on t3. +# leads to deadlock (con1 trx is waiting for default trx and vice versa) + +--connection default +--error ER_LOCK_DEADLOCK +--reap + +connection con1; +COMMIT; +disconnect con1; + +--connection default +DROP VIEW v4; +DROP TABLE t1, t2, t3, t4; +set debug_sync= reset; diff --git a/mysql-test/suite/plugins/r/feedback_plugin_send.result b/mysql-test/suite/plugins/r/feedback_plugin_send.result index 5a48c703ec4..69046e16dd9 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_send.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result @@ -24,7 +24,23 @@ VARIABLE_VALUE>0 VARIABLE_NAME 1 Collation used utf8mb4_bin 1 Collation used utf8_bin 1 Collation used utf8_general_ci +prepare stmt from "SELECT VARIABLE_VALUE>0, VARIABLE_NAME FROM INFORMATION_SCHEMA.FEEDBACK WHERE VARIABLE_NAME LIKE 'Collation used %' ORDER BY VARIABLE_NAME"; +execute stmt; +VARIABLE_VALUE>0 VARIABLE_NAME +1 Collation used binary +1 Collation used latin1_swedish_ci +1 Collation used utf8mb4_bin +1 Collation used utf8_bin +1 Collation used utf8_general_ci +execute stmt; +VARIABLE_VALUE>0 VARIABLE_NAME +1 Collation used binary +1 Collation used latin1_swedish_ci +1 Collation used utf8mb4_bin +1 Collation used utf8_bin +1 Collation used utf8_general_ci +deallocate prepare stmt; set global sql_mode=ONLY_FULL_GROUP_BY; # restart -6: feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent -6: feedback plugin: server replied 'ok' +feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent +feedback plugin: server replied 'ok' diff --git a/mysql-test/suite/plugins/t/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test index b28f9d4cb38..0ea1814ec29 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_send.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test @@ -38,6 +38,6 @@ perl; while ($_=<LOG>) { $logg{$&}++ if /feedback plugin:.*/; } - print "$logg{$_}: $_\n" for sort keys %logg; + print "$_\n" for sort keys %logg; close LOG; EOF diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index e07f1408ab7..0cdc5945acf 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -763,6 +763,25 @@ set system_versioning_alter_history= keep; alter ignore table t1 drop pk; drop table t1; # +# MDEV-22660 SIGSEGV on adding system versioning and modifying system column +# +create or replace table t1 (a int); +alter table t1 +add row_start timestamp(6) as row start, +add row_end timestamp(6) as row end, +add period for system_time(row_start, row_end), +with system versioning, +modify row_end varchar(8); +ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `row_start` and `row_end` +alter table t1 +add row_start timestamp(6) as row start, +add row_end timestamp(6) as row end, +add period for system_time(row_start, row_end), +with system versioning, +modify row_start varchar(8); +ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `row_start` and `row_end` +drop table t1; +# # MDEV-21941 RENAME doesn't work for system time or period fields # create or replace table t1 (a int) with system versioning; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 9d3101fb4ad..85b61c8655e 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -656,6 +656,28 @@ drop table t1; --echo # +--echo # MDEV-22660 SIGSEGV on adding system versioning and modifying system column +--echo # +create or replace table t1 (a int); +--error ER_VERS_PERIOD_COLUMNS +alter table t1 + add row_start timestamp(6) as row start, + add row_end timestamp(6) as row end, + add period for system_time(row_start, row_end), + with system versioning, + modify row_end varchar(8); +--error ER_VERS_PERIOD_COLUMNS +alter table t1 + add row_start timestamp(6) as row start, + add row_end timestamp(6) as row end, + add period for system_time(row_start, row_end), + with system versioning, + modify row_start varchar(8); +# cleanup +drop table t1; + + +--echo # --echo # MDEV-21941 RENAME doesn't work for system time or period fields --echo # create or replace table t1 (a int) with system versioning; diff --git a/mysys/my_context.c b/mysys/my_context.c index 5423f59d19b..4153927d335 100644 --- a/mysys/my_context.c +++ b/mysys/my_context.c @@ -29,6 +29,10 @@ #endif #ifdef MY_CONTEXT_USE_UCONTEXT +#ifdef __APPLE__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif /* The makecontext() only allows to pass integers into the created context :-( We want to pass pointers, so we do it this kinda hackish way. @@ -154,6 +158,9 @@ my_context_destroy(struct my_context *c) DBUG_FREE_CODE_STATE(&c->dbug_state); } +#ifdef __APPLE__ +#pragma GCC diagnostic pop +#endif #endif /* MY_CONTEXT_USE_UCONTEXT */ diff --git a/sql/field.cc b/sql/field.cc index 08bde5f58e1..7ff07540538 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2490,7 +2490,7 @@ Field *Field::make_new_field(MEM_ROOT *root, TABLE *new_table, tmp->unireg_check= Field::NONE; tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG | - VERS_SYS_START_FLAG | VERS_SYS_END_FLAG | + VERS_ROW_START | VERS_ROW_END | VERS_UPDATE_UNVERSIONED_FLAG); tmp->reset_fields(); tmp->invisible= VISIBLE; diff --git a/sql/field.h b/sql/field.h index 6ada7f94507..6747f8070dc 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1797,7 +1797,7 @@ public: bool vers_sys_field() const { - return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG); + return flags & (VERS_ROW_START | VERS_ROW_END); } bool vers_update_unversioned() const @@ -5305,7 +5305,7 @@ public: } bool vers_sys_field() const { - return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG); + return flags & (VERS_ROW_START | VERS_ROW_END); } void create_length_to_internal_length_bit(); void create_length_to_internal_length_newdecimal(); diff --git a/sql/handler.cc b/sql/handler.cc index d49a695f197..2fad0dca954 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7852,11 +7852,11 @@ bool Vers_parse_info::is_end(const char *name) const } bool Vers_parse_info::is_start(const Create_field &f) const { - return f.flags & VERS_SYS_START_FLAG; + return f.flags & VERS_ROW_START; } bool Vers_parse_info::is_end(const Create_field &f) const { - return f.flags & VERS_SYS_END_FLAG; + return f.flags & VERS_ROW_END; } static Create_field *vers_init_sys_field(THD *thd, const char *field_name, int flags, bool integer) @@ -7916,8 +7916,8 @@ bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info) period= start_end_t(default_start, default_end); as_row= period; - if (vers_create_sys_field(thd, default_start, alter_info, VERS_SYS_START_FLAG) || - vers_create_sys_field(thd, default_end, alter_info, VERS_SYS_END_FLAG)) + if (vers_create_sys_field(thd, default_start, alter_info, VERS_ROW_START) || + vers_create_sys_field(thd, default_end, alter_info, VERS_ROW_END)) { return true; } @@ -8072,7 +8072,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, return true; } my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0), - f->flags & VERS_SYS_START_FLAG ? "START" : "END", f->field_name.str); + f->flags & VERS_ROW_START ? "START" : "END", f->field_name.str); return true; } } @@ -8186,13 +8186,13 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_ while ((f= it++)) { - if (f->flags & VERS_SYS_START_FLAG) + if (f->flags & VERS_ROW_START) { f_start= f; if (f_end) break; } - else if (f->flags & VERS_SYS_END_FLAG) + else if (f->flags & VERS_ROW_END) { f_end= f; if (f_start) @@ -8338,6 +8338,7 @@ bool Vers_type_trx::check_sys_fields(const LEX_CSTRING &table_name, return false; } + bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, const Lex_table_name &db, Alter_info *alter_info) const @@ -8346,18 +8347,21 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, return true; List_iterator<Create_field> it(alter_info->create_list); - const Create_field *row_start= NULL; - const Create_field *row_end= NULL; + const Create_field *row_start= nullptr; + const Create_field *row_end= nullptr; while (const Create_field *f= it++) { - if (f->flags & VERS_SYS_START_FLAG && !row_start) + if (f->flags & VERS_ROW_START && !row_start) row_start= f; - if (f->flags & VERS_SYS_END_FLAG && !row_end) + if (f->flags & VERS_ROW_END && !row_end) row_end= f; } - DBUG_ASSERT(row_start); - DBUG_ASSERT(row_end); + if (!row_start || !row_end) + { + my_error(ER_VERS_PERIOD_COLUMNS, MYF(0), as_row.start.str, as_row.end.str); + return true; + } const Vers_type_handler *row_start_vers= row_start->type_handler()->vers(); @@ -8367,10 +8371,7 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, return true; } - if (row_start_vers->check_sys_fields(table_name, row_start, row_end)) - return true; - - return false; + return row_start_vers->check_sys_fields(table_name, row_start, row_end); } bool Table_period_info::check_field(const Create_field* f, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fb359884f13..2967a0b42aa 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -354,6 +354,8 @@ String *Item_aes_crypt::val_str(String *str2) rkey, AES_KEY_LENGTH / 8, 0, 0)) { str2->length((uint) aes_length); + DBUG_ASSERT(collation.collation == &my_charset_bin); + str2->set_charset(&my_charset_bin); return str2; } } diff --git a/sql/item_vers.cc b/sql/item_vers.cc index 792c434b8c3..9a594533628 100644 --- a/sql/item_vers.cc +++ b/sql/item_vers.cc @@ -30,7 +30,7 @@ bool Item_func_history::val_bool() { Item_field *f= static_cast<Item_field *>(args[0]); DBUG_ASSERT(f->fixed); - DBUG_ASSERT(f->field->flags & VERS_SYS_END_FLAG); + DBUG_ASSERT(f->field->flags & VERS_ROW_END); return !f->field->is_max(); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 072cd42cc23..ec90962e918 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8502,7 +8502,9 @@ static int get_options(int *argc_ptr, char ***argv_ptr) if (global_system_variables.low_priority_updates) thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY; - if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax)) + if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax, + strlen(ft_boolean_syntax), + system_charset_info)) { sql_print_error("Invalid ft-boolean-syntax string: %s", ft_boolean_syntax); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1e6bf3f0213..01e8a65fda4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8799,6 +8799,8 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, if (!thd->is_error()) { thd->abort_on_warning= FALSE; + if (table->default_field && table->update_default_fields(ignore_errors)) + goto err; if (table->versioned()) table->vers_update_fields(); if (table->vfield && diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 9090416847f..31c5543d2df 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -121,11 +121,13 @@ public: */ enum explain_connection_type connection_type; +protected: /* A node may have children nodes. When a node's explain structure is created, children nodes may not yet have QPFs. This is why we store ids. */ Dynamic_array<int> children; +public: void add_child(int select_no) { children.append(select_no); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3ef13ea2e1d..c4d0a871ba5 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1342,7 +1342,18 @@ values_loop_end: abort: #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) + { end_delayed_insert(thd); + /* + In case of an error (e.g. data truncation), the data type specific data + in fields (e.g. Field_blob::value) was not taken over + by the delayed writer thread. All fields in table_list->table + will be freed by free_root() soon. We need to free the specific + data before free_root() to avoid a memory leak. + */ + for (Field **ptr= table_list->table->field ; *ptr ; ptr++) + (*ptr)->free(); + } #endif if (table != NULL) table->file->ha_release_auto_increment(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 03dcd825de7..5f9742a9e20 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9605,7 +9605,7 @@ bool LEX::last_field_generated_always_as_row_start() Vers_parse_info &info= vers_get_info(); Lex_ident *p= &info.as_row.start; return last_field_generated_always_as_row_start_or_end(p, "START", - VERS_SYS_START_FLAG); + VERS_ROW_START); } @@ -9614,7 +9614,7 @@ bool LEX::last_field_generated_always_as_row_end() Vers_parse_info &info= vers_get_info(); Lex_ident *p= &info.as_row.end; return last_field_generated_always_as_row_start_or_end(p, "END", - VERS_SYS_END_FLAG); + VERS_ROW_END); } void st_select_lex_unit::reset_distinct() diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 21e0540e9dd..ec1630b01b0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4695,7 +4695,8 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds, bool free_join= 1; DBUG_ENTER("mysql_select"); - select_lex->context.resolve_in_select_list= TRUE; + if (!fields.is_empty()) + select_lex->context.resolve_in_select_list= true; JOIN *join; if (select_lex->join != 0) { @@ -21025,26 +21026,33 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, will be re-evaluated again. It could be fixed, but, probably, it's not worth doing now. */ - if (tab->select_cond && !tab->select_cond->val_int()) + if (tab->select_cond) { - /* The condition attached to table tab is false */ - if (tab == join_tab) - { - found= 0; - if (not_exists_opt_is_applicable) - DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); - } - else + const longlong res= tab->select_cond->val_int(); + if (join->thd->is_error()) + DBUG_RETURN(NESTED_LOOP_ERROR); + + if (!res) { - /* - Set a return point if rejected predicate is attached - not to the last table of the current nest level. - */ - join->return_tab= tab; - if (not_exists_opt_is_applicable) - DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + /* The condition attached to table tab is false */ + if (tab == join_tab) + { + found= 0; + if (not_exists_opt_is_applicable) + DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + } else - DBUG_RETURN(NESTED_LOOP_OK); + { + /* + Set a return point if rejected predicate is attached + not to the last table of the current nest level. + */ + join->return_tab= tab; + if (not_exists_opt_is_applicable) + DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + else + DBUG_RETURN(NESTED_LOOP_OK); + } } } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6ff9ef8a810..04c2e959a3c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2213,11 +2213,11 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list, } else { - if (field->flags & VERS_SYS_START_FLAG) + if (field->flags & VERS_ROW_START) { packet->append(STRING_WITH_LEN(" GENERATED ALWAYS AS ROW START")); } - else if (field->flags & VERS_SYS_END_FLAG) + else if (field->flags & VERS_ROW_END) { packet->append(STRING_WITH_LEN(" GENERATED ALWAYS AS ROW END")); } @@ -6068,7 +6068,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, } else if (field->flags & VERS_SYSTEM_FIELD) { - if (field->flags & VERS_SYS_START_FLAG) + if (field->flags & VERS_ROW_START) { table->field[21]->store(STRING_WITH_LEN("ROW START"), cs); buf.set(STRING_WITH_LEN("STORED GENERATED"), cs); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7f6fa541640..d28ba06e963 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8566,7 +8566,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, def= new (thd->mem_root) Create_field(thd, field, field); def->invisible= INVISIBLE_SYSTEM; alter_info->flags|= ALTER_CHANGE_COLUMN; - if (field->flags & VERS_SYS_START_FLAG) + if (field->flags & VERS_ROW_START) create_info->vers_info.as_row.start= def->field_name= Vers_parse_info::default_start; else create_info->vers_info.as_row.end= def->field_name= Vers_parse_info::default_end; @@ -8597,9 +8597,9 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, def->change= alter->name; def->field_name= alter->new_name; column_rename_param.fields.push_back(def); - if (field->flags & VERS_SYS_START_FLAG) + if (field->flags & VERS_ROW_START) create_info->vers_info.as_row.start= alter->new_name; - else if (field->flags & VERS_SYS_END_FLAG) + else if (field->flags & VERS_ROW_END) create_info->vers_info.as_row.end= alter->new_name; if (table->s->period.name) { @@ -8661,9 +8661,9 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, !vers_system_invisible) { StringBuffer<NAME_LEN*3> tmp; - if (!(dropped_sys_vers_fields & VERS_SYS_START_FLAG)) + if (!(dropped_sys_vers_fields & VERS_ROW_START)) append_drop_column(thd, &tmp, table->vers_start_field()); - if (!(dropped_sys_vers_fields & VERS_SYS_END_FLAG)) + if (!(dropped_sys_vers_fields & VERS_ROW_END)) append_drop_column(thd, &tmp, table->vers_end_field()); my_error(ER_MISSING, MYF(0), table->s->table_name.str, tmp.c_ptr()); goto err; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 118dcaf9d59..c1801c1ae3e 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -8144,7 +8144,7 @@ Field *Type_handler_longlong:: const Column_definition_attributes *attr, uint32 flags) const { - if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG)) + if (flags & (VERS_ROW_START|VERS_ROW_END)) return new (mem_root) Field_vers_trx_id(rec.ptr(), (uint32) attr->length, rec.null_ptr(), rec.null_bit(), diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index d826d01edbf..565f26bcdb2 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1180,7 +1180,9 @@ static Sys_var_ulong Sys_flush_time( static bool check_ftb_syntax(sys_var *self, THD *thd, set_var *var) { return ft_boolean_check_syntax_string((uchar*) - (var->save_result.string_value.str)); + (var->save_result.string_value.str), + var->save_result.string_value.length, + self->charset(thd)); } static bool query_cache_flush(sys_var *self, THD *thd, enum_var_type type) { diff --git a/sql/table.cc b/sql/table.cc index 91a94238514..ba7461ed7a5 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1340,7 +1340,10 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, if (check_vcol_forward_refs(field, field->vcol_info, 0) || check_vcol_forward_refs(field, field->check_constraint, 1) || check_vcol_forward_refs(field, field->default_value, 0)) + { + *error_reported= true; goto end; + } } table->find_constraint_correlated_indexes(); @@ -2583,9 +2586,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (versioned) { if (i == vers.start_fieldno) - flags|= VERS_SYS_START_FLAG; + flags|= VERS_ROW_START; else if (i == vers.end_fieldno) - flags|= VERS_SYS_END_FLAG; + flags|= VERS_ROW_END; if (flags & VERS_SYSTEM_FIELD) { diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index 7022600e140..be58437a766 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -12,6 +12,7 @@ #include <mysql.h> #include <sql_error.h> #include <stdio.h> +#include <cassert> #include "bsonudf.h" @@ -691,7 +692,7 @@ PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n) break; default: - break; + DBUG_ASSERT(!"Implement new op type support."); } // endswitch Op return valp = AllocateValue(g, type, lng, prec); @@ -4979,7 +4980,7 @@ char *bbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, uint n = 2; int* x = GetIntArgPtr(g, args, n); BJNX bnx(g, NULL, TYPE_STRING); - PBVAL top, jarp = NULL, jvp = NULL; + PBVAL jarp = NULL, top = NULL, jvp = NULL; PBVAL jsp = bnx.MakeValue(args, 0, true, &top); if (bnx.CheckPath(g, args, jsp, jvp, 2)) diff --git a/storage/connect/inihandl.cpp b/storage/connect/inihandl.cpp index c39c94fb30d..cd06f7fadd7 100644 --- a/storage/connect/inihandl.cpp +++ b/storage/connect/inihandl.cpp @@ -191,7 +191,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section ) secno++; } - for (key = section->key; key; key = key->next) + for (key = section->key; key; key = key->next) { if (key->name[0]) { fprintf(file, "%s", SVP(key->name)); @@ -199,9 +199,9 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section ) fprintf(file, "=%s", SVP(key->value)); fprintf(file, "\n"); - } // endif key->name - - } // endfor section + } // endif key->name + } + } // endfor section } // end of PROFILE_Save diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index 4584dbd4b91..61b1915d5e0 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -79,18 +79,25 @@ FT_WORD * ft_linearize(TREE *wtree, MEM_ROOT *mem_root) DBUG_RETURN(wlist); } -my_bool ft_boolean_check_syntax_string(const uchar *str) +my_bool ft_boolean_check_syntax_string(const uchar *str, size_t length, + CHARSET_INFO *cs) { uint i, j; + if (cs->mbminlen != 1) + { + DBUG_ASSERT(0); + return 1; + } + if (!str || - (strlen((char*) str)+1 != sizeof(DEFAULT_FTB_SYNTAX)) || + (length + 1 != sizeof(DEFAULT_FTB_SYNTAX)) || (str[0] != ' ' && str[1] != ' ')) return 1; for (i=0; i<sizeof(DEFAULT_FTB_SYNTAX); i++) { /* limiting to 7-bit ascii only */ - if ((unsigned char)(str[i]) > 127 || my_isalnum(default_charset_info, str[i])) + if ((unsigned char)(str[i]) > 127 || my_isalnum(cs, str[i])) return 1; for (j=0; j<i; j++) if (str[i] == str[j] && (i != 11 || j != 10)) diff --git a/wsrep-lib b/wsrep-lib -Subproject efb4aab090cb9c1b57b9e7f9988ae1c41f48344 +Subproject 22921e7082ddfb45222f21a585aa8b877e62aa8 |