diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-10-13 16:37:12 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-10-13 16:37:12 +0300 |
commit | b4911f5a34f8dcfb642c6f14535bc9d5d97ade44 (patch) | |
tree | aa2dd694fa9d8fc42aaa0a6c5efb7bd1ec5ddd90 | |
parent | 8c5e5e1be9353b90f341aad73cb3d2ed7c405a96 (diff) | |
parent | 607de9c7ac53c3fbf0e92ca7a2c505014cd4e4de (diff) | |
download | mariadb-git-b4911f5a34f8dcfb642c6f14535bc9d5d97ade44.tar.gz |
Merge 10.6 into 10.7
85 files changed, 1235 insertions, 388 deletions
diff --git a/.gitignore b/.gitignore index e2a227492d3..3aeedcd0774 100644 --- a/.gitignore +++ b/.gitignore @@ -359,6 +359,7 @@ x86/ build/ bld/ [Bb]in/ +/cmake-build-debug/ [Oo]bj/ # Roslyn cache directories @@ -542,7 +543,7 @@ compile_commands.json .vscode/ # Clion && other JetBrains ides -.idea +/.idea/ .cache/clangd diff --git a/client/mysql.cc b/client/mysql.cc index d66b7706f16..0ca0f08a687 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1685,11 +1685,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 " @@ -2385,8 +2388,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/debian/control b/debian/control index 22f0bea2b7b..683198ab9e0 100644 --- a/debian/control +++ b/debian/control @@ -629,7 +629,7 @@ Recommends: libhtml-template-perl Pre-Depends: adduser (>= 3.40), debconf, mariadb-common (>= ${source:Version}) -Depends: galera-4 (>=26.4), +Depends: galera-4 (>= 26.4), gawk, iproute2 [linux-any], libdbi-perl, diff --git a/debian/mariadb-server-10.7.postinst b/debian/mariadb-server-10.7.postinst index 23fa348693b..13800b7bce2 100644 --- a/debian/mariadb-server-10.7.postinst +++ b/debian/mariadb-server-10.7.postinst @@ -161,7 +161,7 @@ EOF # Clean up old flags before setting new one rm -f $mysql_datadir/debian-*.flag # Flag data dir to avoid downgrades - touch $mysql_datadir/debian-10.7.flag + touch "$mysql_datadir/debian-$MAJOR_VER.flag" # initiate databases. Output is not allowed by debconf :-( # This will fail if we are upgrading an existing database; in this case diff --git a/debian/mariadb-test.install b/debian/mariadb-test.install index 97384bd7ef1..36b49bdab97 100644 --- a/debian/mariadb-test.install +++ b/debian/mariadb-test.install @@ -5,6 +5,7 @@ usr/bin/mariadb-test-embedded usr/lib/*/libmariadb3/plugin/auth_test_plugin.so usr/lib/*/libmariadb3/plugin/qa_auth_client.so usr/lib/*/libmariadb3/plugin/qa_auth_interface.so +usr/lib/*/libmariadb3/plugin/test_sql_service.so usr/lib/mysql/plugin/adt_null.so usr/lib/mysql/plugin/auth_0x0100.so usr/lib/mysql/plugin/auth_test_plugin.so diff --git a/debian/po/de.po b/debian/po/de.po index a8f8cad1787..fdbd3f2986a 100644 --- a/debian/po/de.po +++ b/debian/po/de.po @@ -10,7 +10,7 @@ msgstr "" "POT-Creation-Date: 2019-07-23 19:16-0300\n" "PO-Revision-Date: 2016-05-12 22:39+0100\n" "Last-Translator: Chris Leick <c.leick@vollbio.de>\n" -"Language-Team: german <debian-l10n-german@lists.debian.org>\n" +"Language-Team: German <debian-l10n-german@lists.debian.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/debian/po/es.po b/debian/po/es.po index 043ab9a2ab6..82f1a8ed576 100644 --- a/debian/po/es.po +++ b/debian/po/es.po @@ -1,4 +1,4 @@ -# mariadb translation to spanish +# MariaDB translation to Spanish # Copyright (C) 2005-2016 Software in the Public Interest, SPI Inc. # This file is distributed under the same license as the mariadb package. # diff --git a/debian/po/it.po b/debian/po/it.po index 1adfc8bbf24..eeef6960313 100644 --- a/debian/po/it.po +++ b/debian/po/it.po @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: mariadb-10.7 10.0.13 italian debconf templates\n" +"Project-Id-Version: mariadb-10.7 10.0.13 Italian debconf templates\n" "Report-Msgid-Bugs-To: mariadb-10.7@packages.debian.org\n" "POT-Creation-Date: 2019-07-23 19:16-0300\n" "PO-Revision-Date: 2017-083-20 20:29+0100\n" diff --git a/debian/rules b/debian/rules index 2f6938b04a4..1f26f8ce6e7 100755 --- a/debian/rules +++ b/debian/rules @@ -34,8 +34,8 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) MAKEFLAGS += -j$(NUMJOBS) else - # NUMJOBS cannot be empty as it is used as a parameter to mtr, default to 1. - NUMJOBS = 1 + # NUMJOBS cannot be empty as it is used as a parameter to mtr, default to 'auto'. + NUMJOBS = auto endif # RocksDB cannot build on 32-bit platforms diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index 0039e1be393..6d829021b40 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -21,7 +21,7 @@ stages: - build - test - upgrade in Sid - - upgrade from Buster/Stretch + - upgrade from Bullseye/Buster/Stretch - upgrade extras - test extras - publish # Stage referenced by Salsa-CI template aptly stanza, so must exist even though not used @@ -46,6 +46,11 @@ build: - ccache -s # Show ccache stats to validate it worked - mv ${CCACHE_TMP_DIR} ${CCACHE_WORK_DIR} || true +build bullseye-backports: + extends: .build-package + variables: + RELEASE: bullseye-backports + build buster-backports: extends: .build-package script: @@ -114,7 +119,6 @@ blhc: stage: test extras needs: - job: build native deb - artifacts: true # In addition to Salsa-CI, also run these fully MariaDB specific build jobs @@ -135,9 +139,10 @@ blhc: dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed service mysql status || service mariadb status # Early MariaDB 10.5 only had 'mariadb' mysql --skip-column-names -e "select @@version, @@version_comment" # Show version - echo 'SHOW DATABASES;' | mysql # List databases before upgrade - mysql -e "SELECT Host, User, plugin,authentication_string FROM user;" mysql - mysql -e "SELECT * FROM plugin;" mysql + mysql --table -e 'SHOW DATABASES;' # List databases before upgrade + mysql --table -e "SELECT host,user,plugin,authentication_string FROM user;" mysql + mysql --table -e "SELECT * FROM plugin;" mysql + mysql --table -e "SHOW PLUGINS;" mysql .test-enable-sid-repos: &test-enable-sid-repos | # Replace any old repos with just Sid @@ -159,10 +164,12 @@ blhc: cp -ra /etc/mysql debug/etc-mysql cp -ra /var/log/mysql debug/var-log-mysql mariadb --skip-column-names -e "select @@version, @@version_comment" # Show version - echo 'SHOW DATABASES;' | mariadb # List databases - mariadb -e "create database test; use test; create table t(a int primary key) engine=innodb; insert into t values (1); select * from t; drop table t; drop database test;" # Test that InnoDB works - mariadb -e "SELECT Host, User, plugin,authentication_string FROM user;" mysql - mariadb -e "SELECT * FROM plugin;" mysql + mariadb --table -e 'SHOW DATABASES;' # List databases + mariadb --table -e "SELECT host,user,plugin,authentication_string FROM user;" mysql + mariadb --table -e "SELECT * FROM plugin;" mysql + mariadb --table -e "SHOW PLUGINS;" mysql + # Test that InnoDB works and that command 'mysql' is also still usable + mysql -e "CREATE DATABASE test; USE test; CREATE TABLE t(a INT PRIMARY KEY) ENGINE=INNODB; INSERT INTO t VALUEs (1); SELECT * FROM t; DROP TABLE t; DROP DATABASE test;" .test-verify-libs: &test-verify-libs # Don't use a collapsed command as Gitlab-CI would hide each command from the output @@ -214,7 +221,6 @@ fresh install: stage: test needs: - job: build - artifacts: true image: debian:${RELEASE} artifacts: when: always @@ -236,7 +242,6 @@ mariadb-10.7 Sid upgrade: stage: upgrade in Sid needs: - job: build - artifacts: true image: debian:${RELEASE} artifacts: when: always @@ -254,11 +259,36 @@ mariadb-10.7 Sid upgrade: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ +mariadb-10.5 Bullseye to mariadb-10.7 upgrade: + stage: upgrade from Bullseye/Buster/Stretch + needs: + - job: build + image: debian:bullseye + artifacts: + when: always + name: "$CI_BUILD_NAME" + paths: + - ${WORKING_DIR}/debug + script: + - *test-prepare-container + # Install everything MariaDB currently in Debian Bullseye + - apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadb*' + # Verify installation of MariaDB from Bullseye + - *test-verify-initial + - *test-enable-sid-repos + - *test-install + - service mariadb status + - *test-verify-final + variables: + GIT_STRATEGY: none + except: + variables: + - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + mariadb-10.3 Buster to mariadb-10.7 upgrade: - stage: upgrade from Buster/Stretch + stage: upgrade from Bullseye/Buster/Stretch needs: - job: build - artifacts: true image: debian:buster artifacts: when: always @@ -282,10 +312,9 @@ mariadb-10.3 Buster to mariadb-10.7 upgrade: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ mariadb-10.1 Stretch to mariadb-10.7 upgrade: - stage: upgrade from Buster/Stretch + stage: upgrade from Bullseye/Buster/Stretch needs: - job: build - artifacts: true image: debian:stretch artifacts: when: always @@ -299,8 +328,7 @@ mariadb-10.1 Stretch to mariadb-10.7 upgrade: - apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadbd*' 'libmariadbclient*' # Verify installation of MariaDB from Stretch - *test-verify-initial - # Remove manpages 4.10 that conflicts with manpages-dev 5.10 on console_ioctl.4.gz - - apt-get remove -y manpages + - apt-get remove -y manpages # Workaround for Bug#99375 - *test-enable-sid-repos - *test-install - service mysql status @@ -315,7 +343,6 @@ test basic features: stage: test needs: - job: build - artifacts: true image: debian:${RELEASE} artifacts: when: always @@ -399,7 +426,6 @@ build mariadbclient consumer Python-MySQLdb: stage: test needs: - job: build - artifacts: true image: debian:${RELEASE} script: - *test-prepare-container @@ -421,7 +447,6 @@ libmysql* to libmariadb* upgrade: stage: upgrade in Sid needs: - job: build - artifacts: true image: debian:${RELEASE} artifacts: when: always @@ -455,7 +480,6 @@ default-libmysqlclient-dev Sid upgrade: stage: upgrade in Sid needs: - job: build - artifacts: true image: debian:${RELEASE} artifacts: when: always @@ -473,10 +497,9 @@ default-libmysqlclient-dev Sid upgrade: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ default-libmysqlclient-dev Buster upgrade: - stage: upgrade from Buster/Stretch + stage: upgrade from Bullseye/Buster/Stretch needs: - job: build - artifacts: true image: debian:buster artifacts: when: always @@ -495,10 +518,9 @@ default-libmysqlclient-dev Buster upgrade: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ default-libmysqlclient-dev Stretch upgrade: - stage: upgrade from Buster/Stretch + stage: upgrade from Bullseye/Buster/Stretch needs: - job: build - artifacts: true image: debian:stretch artifacts: when: always @@ -509,14 +531,37 @@ default-libmysqlclient-dev Stretch upgrade: - *test-prepare-container - apt-get install -y pkg-config default-libmysqlclient-dev - pkg-config --list-all - # Remove manpages 4.10 that conflicts with manpages-dev 5.10 on console_ioctl.4.gz - - apt-get remove -y manpages + - apt-get remove -y manpages # Workaround for Bug#99375 + - *test-enable-sid-repos + - *test-install-all-libs + - *test-verify-libs + except: + variables: + - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + +mariadb-connector-c Stretch upgrade: + stage: upgrade from Bullseye/Buster/Stretch + needs: + - job: build + image: debian:stretch + artifacts: + when: always + name: "$CI_BUILD_NAME" + paths: + - ${WORKING_DIR}/debug + script: + - *test-prepare-container + - apt-get install -y pkg-config libmariadb2 libmariadb-dev libmariadb-dev-compat + - pkg-config --list-all + - apt-get remove -y manpages # Workaround for Bug#99375 - *test-enable-sid-repos - *test-install-all-libs - *test-verify-libs except: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + allow_failure: true + # Upgrading libc from Stretch to Bookworm is not possible due to Bug#993755 # Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. # The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. @@ -524,7 +569,6 @@ mysql-8.0 Sid to mariadb-10.7 upgrade: stage: upgrade in Sid needs: - job: build - artifacts: true image: debian:sid artifacts: when: always @@ -552,7 +596,6 @@ mysql-8.0 Focal to mariadb-10.7 upgrade: stage: upgrade extras needs: - job: build buster-backports - artifacts: true image: debian:buster artifacts: when: always @@ -587,7 +630,6 @@ mariadb.org-10.5 to mariadb-10.7 upgrade: stage: upgrade extras needs: - job: build - artifacts: true image: debian:sid artifacts: when: always @@ -626,7 +668,6 @@ mariadb.org-10.4 to mariadb-10.7 upgrade: stage: upgrade extras needs: - job: build - artifacts: true image: debian:sid artifacts: when: always @@ -659,7 +700,6 @@ mariadb.org-10.3 to mariadb-10.7 upgrade: stage: upgrade extras needs: - job: build - artifacts: true image: debian:sid artifacts: when: always @@ -695,7 +735,6 @@ mariadb.org-10.2 to mariadb-10.7 upgrade: stage: upgrade extras needs: - job: build - artifacts: true image: debian:sid artifacts: when: always @@ -731,7 +770,6 @@ mysql.com-5.7 to mariadb-10.7 upgrade: stage: upgrade extras needs: - job: build buster-backports - artifacts: true image: debian:buster artifacts: when: always @@ -763,7 +801,6 @@ percona-xtradb-5.7 to mariadb-10.7 upgrade (MDEV-22679): stage: upgrade extras needs: - job: build buster-backports - artifacts: true image: debian:buster artifacts: when: always diff --git a/debian/tests/control b/debian/tests/control index b596e57c816..1d5ff57bbfb 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -7,5 +7,5 @@ Depends: mariadb-plugin-rocksdb | mariadb-server-10.7 Restrictions: allow-stderr needs-root isolation-container Tests: upstream -Depends: mariadb-test +Depends: mariadb-test, eatmydata Restrictions: allow-stderr breaks-testbed diff --git a/debian/tests/upstream b/debian/tests/upstream index 51b0a60a0ac..f216df24371 100644 --- a/debian/tests/upstream +++ b/debian/tests/upstream @@ -59,7 +59,9 @@ fi cd /usr/share/mysql/mysql-test echo "starting mysql-test-tun.pl..." -perl -I. ./mysql-test-run.pl --suite=main --vardir="$WORKDIR/var" --tmpdir="$WORKDIR/tmp" \ +eatmydata perl -I. ./mysql-test-run.pl --suite=main \ + --vardir="$WORKDIR/var" --tmpdir="$WORKDIR/tmp" \ --parallel=auto --skip-rpl \ - --force --skip-test-list=$SKIP_TEST_LST $@ 2>&1 + --force --skip-test-list=$SKIP_TEST_LST \ + --xml-report=$AUTOPKGTEST_ARTIFACTS/mysql-test-run-junit.xml $@ 2>&1 echo "run: OK" 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_global.h b/include/my_global.h index e552f5256ec..224909116dd 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 e0a81a7e31b..b0d5b026dd8 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 7f722659d2f..4bc35938f6c 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 492cda6b9f5..51bf908162e 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 f6f8db95f98..ce54d3e85a1 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 f3f8fc8f19c..7fd22704fcb 100644 --- a/mysql-test/main/invisible_field.test +++ b/mysql-test/main/invisible_field.test @@ -281,3 +281,16 @@ insert delayed into t1 values (1); --disable_prepare_warnings # 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..21d21740043 --- /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 -A8 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 0c2b2facc2c..b797056f962 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -16,10 +16,8 @@ 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_applier_ftwrl_table_alter : MDEV-26502 : galera.galera_applier_ftwrl_table_alter MTR failed : Result content mismatch 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 @@ -34,15 +32,12 @@ 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_sst_mysqldump : MDEV-26501 : galera.galera_sst_mysqldump MTR failed: galera SST with mysqldump failed -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_unicode_identifiers : MDEV-26500 : galera.galera_unicode_identifiers MTR failed: InnoDB: innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.mutex galera_var_dirty_reads : MDEV-25615 Galera test failure on galera_var_dirty_reads +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 galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons mysql-wsrep#198 : MDEV-24446: galera.mysql-wsrep#198 MTR failed: query 'reap' failed: 2000: Unknown MySQL error 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_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_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..a041274162f --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/r/MDEV-26707.result @@ -0,0 +1,105 @@ +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; +Timeout in wait_condition.inc for SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +Id User Host db Command Time State Info Progress +1 system user NULL Sleep 66 wsrep aborter idle NULL 0.000 +2 system user NULL Sleep 66 closing tables NULL 0.000 +10 root localhost test Sleep 58 NULL 0.000 +11 root localhost:52722 test Sleep 56 NULL 0.000 +12 root localhost:52724 test Query 0 starting show full processlist 0.000 +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 +1 +connection node_2a; +Timeout in wait_condition.inc for SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +Id User Host db Command Time State Info Progress +1 system user NULL Sleep 96 wsrep aborter idle NULL 0.000 +2 system user NULL Sleep 87 closing tables NULL 0.000 +10 root localhost:37222 test Sleep 64 NULL 0.000 +11 root localhost:37228 test Query 0 starting show full processlist 0.000 +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 +1 +connection node_3a; +Timeout in wait_condition.inc for SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +Id User Host db Command Time State Info Progress +1 system user NULL Sleep 122 wsrep aborter idle NULL 0.000 +2 system user NULL Sleep 117 closing tables NULL 0.000 +10 root localhost:60992 test Sleep 117 NULL 0.000 +11 root localhost:60994 test Query 0 starting show full processlist 0.000 +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 +1 +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..98c20cd14d5 --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/t/MDEV-26707.test @@ -0,0 +1,168 @@ +# +# 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 +--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +--connection node_2a +--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +--connection node_3a +--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +--source include/wait_condition.inc +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..b10ea915a4f 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_send.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result @@ -21,10 +21,26 @@ ORDER BY VARIABLE_NAME; VARIABLE_VALUE>0 VARIABLE_NAME 1 Collation used binary 1 Collation used latin1_swedish_ci +1 Collation used utf8mb3_bin +1 Collation used utf8mb3_general_ci 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 utf8mb3_bin +1 Collation used utf8mb3_general_ci +1 Collation used utf8mb4_bin +execute stmt; +VARIABLE_VALUE>0 VARIABLE_NAME +1 Collation used binary +1 Collation used latin1_swedish_ci +1 Collation used utf8mb3_bin +1 Collation used utf8mb3_general_ci +1 Collation used utf8mb4_bin +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 53f0537ff92..0ec2f887950 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -658,6 +658,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/sql/field.cc b/sql/field.cc index 46a3a1deea3..a5cd595f05b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2501,7 +2501,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 94a45d23802..0408ae90b3f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1800,7 +1800,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 @@ -5306,7 +5306,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 cce50dc9289..e4543bde5de 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -8200,11 +8200,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) @@ -8264,8 +8264,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; } @@ -8420,7 +8420,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; } } @@ -8534,13 +8534,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) @@ -8686,6 +8686,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 @@ -8694,18 +8695,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(); @@ -8715,10 +8719,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 1a210f79ce5..5254872fef2 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -360,6 +360,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 c510329eed0..3f648cde890 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 e3d474150d2..fcd5528d4bc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8475,7 +8475,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 e1221fb6f6e..2894aeaff2f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8865,6 +8865,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 d034d7cbf35..bfd52290374 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 132932ab4f4..40a6e5f1eac 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1349,7 +1349,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 41ba2a4a31e..f0b9503df1c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9707,7 +9707,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); } @@ -9716,7 +9716,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 ce99e68c59c..eaf58d1cb3f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4914,7 +4914,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) { @@ -21216,26 +21217,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 7aedbcd84c7..3b8bfab66a0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2234,11 +2234,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")); } @@ -6099,7 +6099,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 9131f16abb3..882da2b6705 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7854,7 +7854,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; @@ -7885,9 +7885,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) { @@ -7949,9 +7949,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 76d1f35cd42..0764265f978 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -8160,7 +8160,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 c2a219ee015..a5d87963d28 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1236,7 +1236,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 30db6ab8683..9d891ce413a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1347,7 +1347,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(); @@ -2647,9 +2650,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/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index 16c9bf077ba..70759e381a5 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -428,7 +428,14 @@ static inline int wsrep_after_statement(THD* thd) { DBUG_ENTER("wsrep_after_statement"); - DBUG_RETURN(thd->wsrep_cs().state() != wsrep::client_state::s_none && + WSREP_DEBUG("wsrep_after_statement for %lu client_state %s " + " client_mode %s trans_state %s", + thd_get_thread_id(thd), + wsrep::to_c_string(thd->wsrep_cs().state()), + wsrep::to_c_string(thd->wsrep_cs().mode()), + wsrep::to_c_string(thd->wsrep_cs().transaction().state())); + DBUG_RETURN((thd->wsrep_cs().state() != wsrep::client_state::s_none && + thd->wsrep_cs().mode() == Wsrep_client_state::m_local) && !thd->internal_transaction() ? thd->wsrep_cs().after_statement() : 0); } diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index ac2b3dfe3c2..d735bbee491 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/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index ab0b0986010..d8da37b42cc 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -126,7 +126,7 @@ static void buf_flush_validate_skip() #endif /* UNIV_DEBUG */ /** Wake up the page cleaner if needed */ -inline void buf_pool_t::page_cleaner_wakeup() +void buf_pool_t::page_cleaner_wakeup() { if (!page_cleaner_idle()) return; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e992b435b2d..b4ac23348fd 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -17143,7 +17143,12 @@ innodb_max_dirty_pages_pct_update( } srv_max_buf_pool_modified_pct = in_val; - pthread_cond_signal(&buf_pool.do_flush_list); + + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + buf_pool.page_cleaner_wakeup(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + mysql_mutex_lock(&LOCK_global_system_variables); } /****************************************************************//** @@ -17174,7 +17179,12 @@ innodb_max_dirty_pages_pct_lwm_update( } srv_max_dirty_pages_pct_lwm = in_val; - pthread_cond_signal(&buf_pool.do_flush_list); + + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + buf_pool.page_cleaner_wakeup(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + mysql_mutex_lock(&LOCK_global_system_variables); } /*************************************************************//** diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index a99bada12f9..35ad50f70c1 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1841,7 +1841,7 @@ public: return page_cleaner_is_idle; } /** Wake up the page cleaner if needed */ - inline void page_cleaner_wakeup(); + void page_cleaner_wakeup(); /** Register whether an explicit wakeup of the page cleaner is needed */ void page_cleaner_set_idle(bool deep_sleep) diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 1c306670354..010594b471b 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1483,7 +1483,10 @@ inline void fil_space_t::reacquire() inline bool fil_space_t::set_stopping_check() { mysql_mutex_assert_owner(&fil_system.mutex); -#if defined __GNUC__ && (defined __i386__ || defined __x86_64__) +#if defined __clang_major__ && __clang_major__ < 10 + /* Only clang-10 introduced support for asm goto */ + return n_pending.fetch_or(STOPPING, std::memory_order_relaxed) & STOPPING; +#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) static_assert(STOPPING == 1U << 31, "compatibility"); __asm__ goto("lock btsl $31, %0\t\njnc %l1" : : "m" (n_pending) : "cc", "memory" : not_stopped); diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 4d927227944..b2fa2e735f9 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -803,6 +803,9 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key, return; } +repeat: + lsn_t ret_lsn1= 0, ret_lsn2= 0; + if (flush_to_disk && flush_lock.acquire(lsn, callback) != group_commit_lock::ACQUIRED) return; @@ -817,20 +820,32 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key, log_write(rotate_key); ut_a(log_sys.write_lsn == write_lsn); - write_lock.release(write_lsn); + ret_lsn1= write_lock.release(write_lsn); } - if (!flush_to_disk) - return; - - /* Flush the highest written lsn.*/ - auto flush_lsn = write_lock.value(); - flush_lock.set_pending(flush_lsn); - log_write_flush_to_disk_low(flush_lsn); - flush_lock.release(flush_lsn); + if (flush_to_disk) + { + /* Flush the highest written lsn.*/ + auto flush_lsn = write_lock.value(); + flush_lock.set_pending(flush_lsn); + log_write_flush_to_disk_low(flush_lsn); + ret_lsn2= flush_lock.release(flush_lsn); + + log_flush_notify(flush_lsn); + DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); + } - log_flush_notify(flush_lsn); - DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); + if (ret_lsn1 || ret_lsn2) + { + /* + There is no new group commit lead, some async waiters could stall. + Rerun log_write_up_to(), to prevent that. + */ + lsn= std::max(ret_lsn1, ret_lsn2); + static const completion_callback dummy{[](void *) {},nullptr}; + callback= &dummy; + goto repeat; + } } /** Write to the log file up to the last log entry. diff --git a/storage/innobase/log/log0sync.cc b/storage/innobase/log/log0sync.cc index 30433007639..65cc1d0633c 100644 --- a/storage/innobase/log/log0sync.cc +++ b/storage/innobase/log/log0sync.cc @@ -274,11 +274,11 @@ group_commit_lock::lock_return_code group_commit_lock::acquire(value_type num, c return lock_return_code::EXPIRED; } -void group_commit_lock::release(value_type num) +group_commit_lock::value_type group_commit_lock::release(value_type num) { completion_callback callbacks[1000]; size_t callback_count = 0; - + value_type ret = 0; std::unique_lock<std::mutex> lk(m_mtx); m_lock = false; @@ -359,6 +359,12 @@ void group_commit_lock::release(value_type num) { wakeup_list->m_group_commit_leader=true; } + else + { + /* Tell the caller that some pending callbacks left, and he should + do something to prevent stalls. This should be a rare situation.*/ + ret= m_pending_callbacks[0].first; + } } lk.unlock(); @@ -371,6 +377,7 @@ void group_commit_lock::release(value_type num) next= cur->m_next; cur->m_sema.wake(); } + return ret; } #ifndef DBUG_OFF diff --git a/storage/innobase/log/log0sync.h b/storage/innobase/log/log0sync.h index ec4ad6eb99b..00686d39dac 100644 --- a/storage/innobase/log/log0sync.h +++ b/storage/innobase/log/log0sync.h @@ -39,16 +39,23 @@ It has a state consisting of Operations supported on this semaphore -1.acquire(num): +1.acquire(num, callback): - waits until current value exceeds num, or until lock is granted. + if running synchronously (callback is nullptr) - returns EXPIRED if current_value >= num, - or ACQUIRED, if current_value < num and lock is granted. + or ACQUIRED, if current_value < num and lock is granted, + or CALLBACK_QUEUED, if callback was not nullptr, and function + would otherwise have to wait 2.release(num) - releases lock - sets new current value to max(num,current_value) - releases some threads waiting in acquire() +- executes some callbacks +- might return some lsn, meaning there are some pending + callbacks left, and there is no new group commit lead + (i.e caller must do something to flush those pending callbacks) 3. value() - read current value @@ -82,7 +89,7 @@ public: CALLBACK_QUEUED }; lock_return_code acquire(value_type num, const completion_callback *cb); - void release(value_type num); + value_type release(value_type num); value_type value() const; value_type pending() const; void set_pending(value_type num); diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc index 2e22a01eb8f..82f8d615477 100644 --- a/storage/innobase/sync/srw_lock.cc +++ b/storage/innobase/sync/srw_lock.cc @@ -308,7 +308,10 @@ Hence, we will manually translate fetch_or() using GCC-style inline assembler code or a Microsoft intrinsic function. */ -#if defined __GNUC__ && (defined __i386__ || defined __x86_64__) + +#if defined __clang_major__ && __clang_major__ < 10 +/* Only clang-10 introduced support for asm goto */ +#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) # define IF_FETCH_OR_GOTO(mem, bit, label) \ __asm__ goto("lock btsl $" #bit ", %0\n\t" \ "jc %l1" : : "m" (mem) : "cc", "memory" : label); 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 |