diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-07-03 14:02:05 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-07-03 14:02:05 +0400 |
commit | e61568ee9305c6c93c1a9f298a7fe04532881f24 (patch) | |
tree | c80b0967460f7c4f8743831690f7369e11c73722 | |
parent | 4b0cedf82d8d8ba582648dcb4a2620c146862a43 (diff) | |
parent | c3289d27eef39a47fed2ce1ff239013ed6870f39 (diff) | |
download | mariadb-git-e61568ee9305c6c93c1a9f298a7fe04532881f24.tar.gz |
Merge remote-tracking branch 'origin/10.3' into 10.4
448 files changed, 11180 insertions, 4445 deletions
diff --git a/.gitignore b/.gitignore index 932c666b74a..832df90347b 100644 --- a/.gitignore +++ b/.gitignore @@ -127,6 +127,7 @@ scripts/mytop scripts/wsrep_sst_common scripts/wsrep_sst_mysqldump scripts/wsrep_sst_rsync +scripts/wsrep_sst_rsync_wan scripts/wsrep_sst_mariabackup scripts/wsrep_sst_xtrabackup scripts/wsrep_sst_xtrabackup-v2 @@ -166,9 +167,9 @@ sql/mysql_tzinfo_to_sql sql/mysqld sql/sql_builtin.cc sql/sql_yacc.cc -sql/sql_yacc.h +sql/sql_yacc.hh sql/sql_yacc_ora.cc -sql/sql_yacc_ora.h +sql/sql_yacc_ora.hh storage/heap/hp_test1 storage/heap/hp_test2 storage/maria/aria_chk @@ -498,6 +499,12 @@ UpgradeLog*.htm # Microsoft Fakes FakesAssemblies/ +# macOS garbage +.DS_Store + +# QtCreator && CodeBlocks +*.cbp + compile_commands.json .clang-format .kscope/ diff --git a/.travis.compiler.sh b/.travis.compiler.sh index db5c9ee01ce..7a3b0dbc371 100755 --- a/.travis.compiler.sh +++ b/.travis.compiler.sh @@ -1,49 +1,51 @@ #!/bin/sh set -v -x + +# Exclude modules from build not directly affecting the current +# test suites found in $MYSQL_TEST_SUITES, to conserve job time +# as well as disk usage + +function exclude_modules() { +# excludes for all +CMAKE_OPT="${CMAKE_OPT} -DPLUGIN_TOKUDB=NO -DPLUGIN_MROONGA=NO -DPLUGIN_SPIDER=NO -DPLUGIN_OQGRAPH=NO -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_SPHINX=NO" +# exclude storage engines not being tested in current job +if [[ ! "${MYSQL_TEST_SUITES}" =~ "archive" ]]; then + CMAKE_OPT="${CMAKE_OPT} -DPLUGIN_ARCHIVE=NO" +fi +if [[ ! "${MYSQL_TEST_SUITES}" =~ "rocksdb" ]]; then + CMAKE_OPT="${CMAKE_OPT} -DPLUGIN_ROCKSDB=NO" +fi +} + if [[ "${TRAVIS_OS_NAME}" == 'linux' ]]; then + TEST_CASE_TIMEOUT=2 + exclude_modules; + if which ccache ; then + CMAKE_OPT="${CMAKE_OPT} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" + ccache --max-size=1200M + fi if [[ "${CXX}" == 'clang++' ]]; then - CMAKE_OPT="-DWITHOUT_TOKUDB_STORAGE_ENGINE=ON -DWITHOUT_MROONGA_STORAGE_ENGINE=ON" - #CMAKE_OPT="${CMAKE_OPT} -DWITH_ASAN=ON" - if which ccache ; then - CMAKE_OPT="${CMAKE_OPT} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" - fi - case ${GCC_VERSION} in - 5) CXX=clang++-4.0 ;; - 6) CXX=clang++-5.0 ;; - esac export CXX CC=${CXX/++/} elif [[ "${CXX}" == 'g++' ]]; then - CMAKE_OPT="" - if [[ "${MYSQL_TEST_SUITES}" == 'rpl' ]]; then - CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_TOKUDB_STORAGE_ENGINE=TRUE" - CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_MROONGA_STORAGE_ENGINE=TRUE" - fi - export CXX=g++-${GCC_VERSION} - export CC=gcc-${GCC_VERSION} + export CXX=g++-${CC_VERSION} + export CC=gcc-${CC_VERSION} fi - if [[ ${GCC_VERSION} == 6 ]]; then - wget http://mirrors.kernel.org/ubuntu/pool/universe/p/percona-xtradb-cluster-galera-2.x/percona-xtradb-cluster-galera-2.x_165-0ubuntu1_amd64.deb ; - ar vx percona-xtradb-cluster-galera-2.x_165-0ubuntu1_amd64.deb - tar -xJvf data.tar.xz - export WSREP_PROVIDER=$PWD/usr/lib/libgalera_smm.so - MYSQL_TEST_SUITES="${MYSQL_TEST_SUITES},wsrep" - #elif [[ ${GCC_VERSION} != 5 ]]; then - #CMAKE_OPT="${CMAKE_OPT} -DWITH_ASAN=ON" + if [[ ${CC_VERSION} == 6 ]]; then + wget http://mirrors.kernel.org/ubuntu/pool/universe/p/percona-xtradb-cluster-galera-2.x/percona-xtradb-cluster-galera-2.x_165-0ubuntu1_amd64.deb ; + ar vx percona-xtradb-cluster-galera-2.x_165-0ubuntu1_amd64.deb + tar -xJvf data.tar.xz + export WSREP_PROVIDER=$PWD/usr/lib/libgalera_smm.so + MYSQL_TEST_SUITES="${MYSQL_TEST_SUITES},wsrep" fi -else - # osx_image based tests - CMAKE_OPT="-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl" - #CMAKE_OPT="${CMAKE_OPT} -DWITH_ASAN=ON" +fi + +if [[ "${TRAVIS_OS_NAME}" == 'osx' ]]; then + TEST_CASE_TIMEOUT=20 + exclude_modules; + CMAKE_OPT="${CMAKE_OPT} -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl" if which ccache ; then CMAKE_OPT="${CMAKE_OPT} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" fi - if [[ "${MYSQL_TEST_SUITES}" == 'rpl' ]]; then - CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_TOKUDB_STORAGE_ENGINE=ON" - fi - CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_MROONGA_STORAGE_ENGINE=ON" - if [[ "${TYPE}" == "Debug" ]]; then - CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_TOKUDB_STORAGE_ENGINE=ON" - fi fi set +v +x diff --git a/.travis.yml b/.travis.yml index 444c1c0d790..6142e76e1e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,17 +17,20 @@ compiler: - clang cache: + timeout: 300 apt: true - ccache: true # Does not currently work for clang builds: https://github.com/travis-ci/travis-ci/issues/6201 + ccache: true directories: - /usr/local/Cellar # Fails do to permission error: https://github.com/travis-ci/travis-ci/issues/8092 env: matrix: - - GCC_VERSION=4.8 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rpl - - GCC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=main,archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts - - GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption,rocksdb - - GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,perfschema,plugins,multi_source,roles + - CC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=main + - CC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts + - CC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rpl + - CC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption + - CC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rocksdb + - CC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,perfschema,plugins,multi_source,roles matrix: exclude: @@ -81,39 +84,44 @@ matrix: # https://github.com/travis-ci/travis-ci/issues/7062 - /run/shm isn't writable or executable # in trusty containers - export MTR_MEM=/tmp - - env DEB_BUILD_OPTIONS="parallel=6" debian/autobake-deb.sh; + - env DEB_BUILD_OPTIONS="parallel=4" debian/autobake-deb.sh; - ccache --show-stats - # Until OSX becomes a bit more stable: MDEV-12435 + # Until OSX becomes a bit more stable: MDEV-12435 MDEV-16213 allow_failures: - os: osx compiler: clang - env: GCC_VERSION=4.8 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rpl + env: CC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rpl - os: osx compiler: clang - env: GCC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=main,archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts + env: CC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=main - os: osx compiler: clang - env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption,rocksdb + env: CC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts - os: osx compiler: clang - env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,perfschema,plugins,multi_source,roles + env: CC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption + - os: osx + compiler: clang + env: CC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rocksdb + - os: osx + compiler: clang + env: CC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,perfschema,plugins,multi_source,roles addons: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-4.0 - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main' + - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main' packages: # make sure these include all compilers and all build dependencies (see list above) - gcc-5 - g++-5 - gcc-6 - g++-6 - - clang-4.0 - - llvm-4.0-dev - clang-5.0 - llvm-5.0-dev - - libasan0 + - clang-6.0 + - llvm-6.0-dev - bison - chrpath - cmake @@ -152,25 +160,29 @@ before_install: brew link ccache; fi -script: +before_script: + - df -h - ccache --version -# Clang: -# mroonga just generates too many warnings with clang and travis stops the job -# tokudb has fatal warnings + - ccache --show-stats + +script: +# following modules are disabled after sourcing .travis.compiler.sh: +# clang disabled: mroonga just generates too many warnings with clang and travis stops the job +# cland disabled: tokudb has fatal warnings +# gcc/rpl: tokudb and mroonga - source .travis.compiler.sh - cmake . -DCMAKE_BUILD_TYPE=${TYPE} ${CMAKE_OPT} - -DWITH_SSL=system -DWITH_ZLIB=system -DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC -DAWS_SDK_EXTERNAL_PROJECT=ON - - make -j 6 + -DWITH_SSL=system -DWITH_ZLIB=system + - make -j 4 - cd mysql-test -# With ASAN --thread-stack=400K to account for overhead -# Test timeout needs to be 10(minutes) or less due to travis out timeout - - ./mtr --force --max-test-fail=20 --parallel=6 --testcase-timeout=2 + - travis_wait 30 ./mtr --force --max-test-fail=20 --parallel=4 --testcase-timeout=${TEST_CASE_TIMEOUT} --suite=${MYSQL_TEST_SUITES} --skip-test-list=unstable-tests --skip-test=binlog.binlog_unsafe - ccache --show-stats + - df -h notifications: irc: diff --git a/CMakeLists.txt b/CMakeLists.txt index 76b0817f8c7..58b6cc62e9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,7 +297,7 @@ ELSE() ENDIF() SET(DEFAULT_CHARSET_HOME "${DEFAULT_MYSQL_HOME}") SET(PLUGINDIR "${DEFAULT_MYSQL_HOME}/${INSTALL_PLUGINDIR}") -IF(INSTALL_SYSCONFDIR AND NOT DEFAULT_SYSCONFDIR) +IF(INSTALL_SYSCONFDIR AND NOT DEFAULT_SYSCONFDIR AND NOT DEB) SET(DEFAULT_SYSCONFDIR "${INSTALL_SYSCONFDIR}") ENDIF() @@ -398,6 +398,7 @@ IF(NOT WITHOUT_SERVER) IF(WITH_EMBEDDED_SERVER) ADD_SUBDIRECTORY(libmysqld) ADD_SUBDIRECTORY(libmysqld/examples) + ADD_SUBDIRECTORY(unittest/embedded) ENDIF(WITH_EMBEDDED_SERVER) IF(WITH_WSREP) diff --git a/README.md b/README.md index 00587110004..abb7b263482 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +Code status: +------------ + +* [![tests status](https://secure.travis-ci.org/MariaDB/server.png?branch=10.3)](https://travis-ci.org/MariaDB/server) travis-ci.org (10.3 branch) + ## MariaDB: drop-in replacement for MySQL MariaDB is designed as a drop-in replacement of MySQL(R) with more @@ -68,8 +73,3 @@ The code for MariaDB, including all revision history, can be found at: https://github.com/MariaDB/server *************************************************************************** - -Code status: ------------- - -* [![tests status](https://secure.travis-ci.org/MariaDB/server.png?branch=10.2)](https://travis-ci.org/MariaDB/server) travis-ci.org (10.2 branch) @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=3 -MYSQL_VERSION_PATCH=8 +MYSQL_VERSION_PATCH=9 SERVER_MATURITY=stable diff --git a/client/mysqldump.c b/client/mysqldump.c index dc87338aac2..c2c1aa6fc6c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -5090,6 +5090,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (opt_xml) print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS); + + /* obtain dump of routines (procs/functions) */ + if (opt_routines && mysql_get_server_version(mysql) >= 50009) + { + DBUG_PRINT("info", ("Dumping routines for database %s", db)); + dump_routines_for_db(db); + } + if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500) { verbose_msg("-- Setting savepoint...\n"); @@ -5099,7 +5107,6 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DBUG_RETURN(1); } } - /* Dump each selected table */ for (pos= dump_tables; pos < end; pos++) { @@ -5161,12 +5168,6 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DBUG_PRINT("info", ("Dumping events for database %s", db)); dump_events_for_db(db); } - /* obtain dump of routines (procs/functions) */ - if (opt_routines && mysql_get_server_version(mysql) >= 50009) - { - DBUG_PRINT("info", ("Dumping routines for database %s", db)); - dump_routines_for_db(db); - } free_root(&glob_root, MYF(0)); if (opt_xml) { diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 420dc2b94af..4cb6cbcc15b 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -850,7 +850,7 @@ build_table_string(void) if (auto_generate_sql_guid_primary) { - dynstr_append(&table_string, "id varchar(32) primary key"); + dynstr_append(&table_string, "id varchar(36) primary key"); if (num_int_cols || num_char_cols || auto_generate_sql_guid_primary) dynstr_append(&table_string, ","); @@ -865,7 +865,7 @@ build_table_string(void) if (count) /* Except for the first pass we add a comma */ dynstr_append(&table_string, ","); - if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count) + if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(36) unique key", count) > HUGE_STRING_LENGTH) { fprintf(stderr, "Memory Allocation error in create table\n"); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b9aac043017..829ae0b95c1 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -125,7 +125,8 @@ static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, - display_metadata= FALSE, display_result_sorted= FALSE; + display_metadata= FALSE, display_result_sorted= FALSE, + display_session_track_info= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; static my_bool disable_connect_log= 0; static my_bool disable_warnings= 0, disable_column_names= 0; @@ -153,6 +154,7 @@ static struct property prop_list[] = { { &abort_on_error, 0, 1, 0, "$ENABLED_ABORT_ON_ERROR" }, { &disable_connect_log, 0, 1, 1, "$ENABLED_CONNECT_LOG" }, { &disable_info, 0, 1, 1, "$ENABLED_INFO" }, + { &display_session_track_info, 0, 1, 1, "$ENABLED_STATE_CHANGE_INFO" }, { &display_metadata, 0, 0, 0, "$ENABLED_METADATA" }, { &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" }, { &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" }, @@ -166,6 +168,7 @@ enum enum_prop { P_ABORT= 0, P_CONNECT, P_INFO, + P_SESSION_TRACK, P_META, P_PS, P_QUERY, @@ -362,6 +365,7 @@ enum enum_commands { Q_WAIT_FOR_SLAVE_TO_STOP, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, + Q_ENABLE_SESSION_TRACK_INFO, Q_DISABLE_SESSION_TRACK_INFO, Q_ENABLE_METADATA, Q_DISABLE_METADATA, Q_ENABLE_COLUMN_NAMES, Q_DISABLE_COLUMN_NAMES, Q_EXEC, Q_DELIMITER, @@ -384,6 +388,7 @@ enum enum_commands { Q_RESULT_FORMAT_VERSION, Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, Q_ENABLE_PREPARE_WARNINGS, Q_DISABLE_PREPARE_WARNINGS, + Q_RESET_CONNECTION, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND, @@ -435,6 +440,8 @@ const char *command_names[]= "disable_warnings", "enable_info", "disable_info", + "enable_session_track_info", + "disable_session_track_info", "enable_metadata", "disable_metadata", "enable_column_names", @@ -491,6 +498,7 @@ const char *command_names[]= "send_eval", "enable_prepare_warnings", "disable_prepare_warnings", + "reset_connection", 0 }; @@ -6532,6 +6540,34 @@ void do_delimiter(struct st_command* command) } +/* + do_reset_connection + + DESCRIPTION + Reset the current session. +*/ + +static void do_reset_connection() +{ +#ifndef EMBEDDED_LIBRARY + MYSQL *mysql = cur_con->mysql; + + DBUG_ENTER("do_reset_connection"); + if (mysql_reset_connection(mysql)) + die("reset connection failed: %s", mysql_error(mysql)); + if (cur_con->stmt) + { + mysql_stmt_close(cur_con->stmt); + cur_con->stmt= NULL; + } + DBUG_VOID_RETURN; +#else + die("reset connection failed: unsupported by embedded server client library"); + return; +#endif +} + + my_bool match_delimiter(int c, const char *delim, size_t length) { uint i; @@ -7787,6 +7823,70 @@ void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows, } +/** + @brief Append state change information (received through Ok packet) to the output. + + @param [in,out] ds Dynamic string to hold the content to be printed. + @param [in] mysql Connection handle. +*/ + +static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) +{ +#ifndef EMBEDDED_LIBRARY + for (unsigned int type= SESSION_TRACK_BEGIN; type <= SESSION_TRACK_END; type++) + { + const char *data; + size_t data_length; + + if (!mysql_session_track_get_first(mysql, + (enum_session_state_type) type, + &data, &data_length)) + { + dynstr_append(ds, "-- "); + switch (type) + { + case SESSION_TRACK_SYSTEM_VARIABLES: + dynstr_append(ds, "Tracker : SESSION_TRACK_SYSTEM_VARIABLES\n"); + break; + case SESSION_TRACK_SCHEMA: + dynstr_append(ds, "Tracker : SESSION_TRACK_SCHEMA\n"); + break; + case SESSION_TRACK_STATE_CHANGE: + dynstr_append(ds, "Tracker : SESSION_TRACK_STATE_CHANGE\n"); + break; + case SESSION_TRACK_GTIDS: + dynstr_append(ds, "Tracker : SESSION_TRACK_GTIDS\n"); + break; + case SESSION_TRACK_TRANSACTION_CHARACTERISTICS: + dynstr_append(ds, "Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS\n"); + break; + case SESSION_TRACK_TRANSACTION_TYPE: + dynstr_append(ds, "Tracker : SESSION_TRACK_TRANSACTION_TYPE\n"); + break; + default: + DBUG_ASSERT(0); + dynstr_append(ds, "\n"); + } + + + dynstr_append(ds, "-- "); + dynstr_append_mem(ds, data, data_length); + } + else + continue; + while (!mysql_session_track_get_next(mysql, + (enum_session_state_type) type, + &data, &data_length)) + { + dynstr_append(ds, "\n-- "); + dynstr_append_mem(ds, data, data_length); + } + dynstr_append(ds, "\n\n"); + } +#endif /* EMBEDDED_LIBRARY */ +} + + /* Display the table headings with the names tab separated */ @@ -7967,6 +8067,9 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_info) append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); + if (display_session_track_info) + append_session_track_info(ds, mysql); + /* Add all warnings to the result. We can't do this if we are in the middle of processing results from multi-statement, because @@ -8382,6 +8485,10 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, if (!disable_info) append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); + if (display_session_track_info) + append_session_track_info(ds, mysql); + + if (!disable_warnings) { /* Get the warnings from execute */ @@ -8777,6 +8884,7 @@ void init_re(void) "[[:space:]]*SELECT[[:space:]]|" "[[:space:]]*CREATE[[:space:]]+TABLE[[:space:]]|" "[[:space:]]*DO[[:space:]]|" + "[[:space:]]*HANDLER[[:space:]]+.*[[:space:]]+READ[[:space:]]|" "[[:space:]]*SET[[:space:]]+OPTION[[:space:]]|" "[[:space:]]*DELETE[[:space:]]+MULTI[[:space:]]|" "[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|" @@ -9362,6 +9470,12 @@ int main(int argc, char **argv) case Q_DISABLE_INFO: set_property(command, P_INFO, 1); break; + case Q_ENABLE_SESSION_TRACK_INFO: + set_property(command, P_SESSION_TRACK, 1); + break; + case Q_DISABLE_SESSION_TRACK_INFO: + set_property(command, P_SESSION_TRACK, 0); + break; case Q_ENABLE_METADATA: set_property(command, P_META, 1); break; @@ -9572,6 +9686,9 @@ int main(int argc, char **argv) case Q_PING: handle_command_error(command, mysql_ping(cur_con->mysql), -1); break; + case Q_RESET_CONNECTION: + do_reset_connection(); + break; case Q_SEND_SHUTDOWN: handle_command_error(command, mysql_shutdown(cur_con->mysql, diff --git a/cmake/bison.cmake b/cmake/bison.cmake deleted file mode 100644 index d825e407b22..00000000000 --- a/cmake/bison.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2009 Sun Microsystems, Inc. -# Use is subject to license terms. -# -# 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 -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -IF(CMAKE_SYSTEM_NAME MATCHES "SunOS") - # On Solaris, /opt/csw often contains a newer bison - IF(NOT BISON_EXECUTABLE AND EXISTS /opt/csw/bin/bison) - SET(BISON_EXECUTABLE /opt/csw/bin/bison) - ENDIF() -ENDIF() -IF(WIN32) - SET(BISON_PATH_HINTS - HINTS - C:/gnuwin32/bin - C:/cygwin64/bin - C:/cygwin/bin) -ENDIF() -FIND_PROGRAM(BISON_EXECUTABLE bison - ${BISON_PATH_HINTS} - DOC "path to the bison executable") -MARK_AS_ADVANCED(BISON_EXECUTABLE "") -IF(NOT BISON_EXECUTABLE) - MESSAGE("Warning: Bison executable not found in PATH") -ELSEIF(BISON_EXECUTABLE AND NOT BISON_USABLE) - # Check version as well - EXEC_PROGRAM(${BISON_EXECUTABLE} ARGS --version OUTPUT_VARIABLE BISON_VERSION_STR) - # Get first line in case it's multiline - STRING(REGEX REPLACE "([^\n]+).*" "\\1" FIRST_LINE "${BISON_VERSION_STR}") - # get version information - STRING(REGEX REPLACE ".* ([0-9]+)\\.([0-9]+)" "\\1" BISON_VERSION_MAJOR "${FIRST_LINE}") - STRING(REGEX REPLACE ".* ([0-9]+)\\.([0-9]+)" "\\2" BISON_VERSION_MINOR "${FIRST_LINE}") - IF (BISON_VERSION_MAJOR LESS 2) - MESSAGE("Warning: bison version is old. please update to version 2") - ELSE() - SET(BISON_USABLE 1 CACHE INTERNAL "Bison version 2 or higher") - ENDIF() -ENDIF() - -# Use bison to generate C++ and header file -MACRO (RUN_BISON input_yy output_cc output_h name_prefix) - IF(BISON_TOO_OLD) - IF(EXISTS ${output_cc} AND EXISTS ${output_h}) - SET(BISON_USABLE FALSE) - ENDIF() - ENDIF() - IF(BISON_USABLE) - # Workaround for VS regenerating output even - # when outputs are up-to-date. At least, fix output timestamp - # after build so that files that depend on generated header are - # not rebuilt. - IF(CMAKE_GENERATOR MATCHES "Visual Studio") - FIND_PROGRAM(TOUCH_EXECUTABLE touch DOC "Path to touch executable" - PATHS "C:/Program Files/Git/usr/bin" - "C:/Program Files (x86)/Git/usr/bin") - IF(TOUCH_EXECUTABLE) - SET(VS_FIX_OUTPUT_TIMESTAMPS - COMMAND ${TOUCH_EXECUTABLE} -r ${input_yy} ${output_cc} - COMMAND ${TOUCH_EXECUTABLE} -r ${input_yy} ${output_h}) - ENDIF() - ENDIF() - - ADD_CUSTOM_COMMAND( - OUTPUT ${output_cc} - ${output_h} - COMMAND ${BISON_EXECUTABLE} -y -p ${name_prefix} - --output=${output_cc} - --defines=${output_h} - ${input_yy} - ${VS_FIX_OUTPUT_TIMESTAMPS} - DEPENDS ${input_yy} - ) - ELSE() - # Bison is missing or not usable, e.g too old - IF(EXISTS ${output_cc} AND EXISTS ${output_h}) - IF(${input_yy} IS_NEWER_THAN ${output_cc} OR ${input_yy} IS_NEWER_THAN ${output_h}) - # Possibly timestamps are messed up in source distribution. - MESSAGE("Warning: no usable bison found, ${input_yy} will not be rebuilt.") - ENDIF() - ELSE() - # Output files are missing, bail out. - SET(ERRMSG - "Bison (GNU parser generator) is required to build MySQL." - "Please install bison." - ) - IF(WIN32) - SET(ERRMSG ${ERRMSG} - "You can download bison from http://gnuwin32.sourceforge.net/packages/bison.htm " - "Choose 'Complete package, except sources' installation. We recommend to " - "install bison into a directory without spaces, e.g C:\\GnuWin32.") - ENDIF() - MESSAGE(FATAL_ERROR ${ERRMSG}) - ENDIF() - ENDIF() -ENDMACRO() diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 63e2419951b..379a56c283d 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -171,6 +171,7 @@ SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d") SET(INSTALL_BINDIR_DEB "bin") SET(INSTALL_SBINDIR_DEB "sbin") SET(INSTALL_SCRIPTDIR_DEB "bin") +SET(INSTALL_SYSCONFDIR_DEB "/etc") SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d") # SET(INSTALL_LIBDIR_DEB "lib") diff --git a/cmake/make_dist.cmake.in b/cmake/make_dist.cmake.in index 885cfa2a706..43498f1f888 100644 --- a/cmake/make_dist.cmake.in +++ b/cmake/make_dist.cmake.in @@ -67,8 +67,8 @@ IF(NOT GIT_EXECUTABLE) # Save bison output first. CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.cc ${CMAKE_BINARY_DIR}/sql_yacc.cc COPYONLY) - CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.h - ${CMAKE_BINARY_DIR}/sql_yacc.h COPYONLY) + CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.hh + ${CMAKE_BINARY_DIR}/sql_yacc.hh COPYONLY) IF(CMAKE_GENERATOR MATCHES "Makefiles") # make clean @@ -81,10 +81,10 @@ IF(NOT GIT_EXECUTABLE) # Restore bison output CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql_yacc.cc ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc COPYONLY) - CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql_yacc.h + CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql_yacc.hh ${CMAKE_BINARY_DIR}/sql/sql_yacc.h COPYONLY) FILE(REMOVE ${CMAKE_BINARY_DIR}/sql_yacc.cc) - FILE(REMOVE ${CMAKE_BINARY_DIR}/sql_yacc.h) + FILE(REMOVE ${CMAKE_BINARY_DIR}/sql_yacc.hh) ENDIF() EXECUTE_PROCESS( @@ -102,10 +102,15 @@ IF(NOT GIT_EXECUTABLE) ENDIF() # Copy bison output -CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.h - ${PACKAGE_DIR}/sql/sql_yacc.h COPYONLY) +CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.hh + ${PACKAGE_DIR}/sql/sql_yacc.hh COPYONLY) CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.cc ${PACKAGE_DIR}/sql/sql_yacc.cc COPYONLY) +# Copy bison output +CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.hh + ${PACKAGE_DIR}/sql/sql_yacc_ora.hh COPYONLY) +CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.cc + ${PACKAGE_DIR}/sql/sql_yacc_orac.cc COPYONLY) # Add documentation, if user has specified where to find them IF(MYSQL_DOCS_LOCATION) diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 132bb2eea7b..56575211c61 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -26,9 +26,15 @@ then sed 's|DINSTALL_MYSQLTESTDIR=share/mysql/mysql-test|DINSTALL_MYSQLTESTDIR=false|' -i debian/rules # Also skip building RocksDB and TokuDB to save even more time and disk space - sed 's|-DDEB|-DWITHOUT_TOKUDB_STORAGE_ENGINE=true -DWITHOUT_MROONGA_STORAGE_ENGINE=true -DWITHOUT_ROCKSDB_STORAGE_ENGINE=true -DDEB|' -i debian/rules + sed 's|-DDEB|-DPLUGIN_TOKUDB=NO -DPLUGIN_MROONGA=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_SPIDER=NO -DPLUGIN_OQGRAPH=NO -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_SPHINX=NO -WITH_EMBEDDED_SERVER=OFF -DDEB|' -i debian/rules fi +# Convert gcc version to numberical value. Format is Mmmpp where M is Major +# version, mm is minor version and p is patch. +# -dumpfullversion & -dumpversion to make it uniform across old and new (>=7) +GCCVERSION=$(gcc -dumpfullversion -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' \ + -e 's/\.\([0-9]\)/0\1/g' \ + -e 's/^[0-9]\{3,4\}$/&00/') # Look up distro-version specific stuff # @@ -36,19 +42,12 @@ fi # Debian policy and targeting Debian Sid. Then case-by-case run in autobake-deb.sh # tests for backwards compatibility and strip away parts on older builders. -# If iproute2 is not available (before Debian Jessie and Ubuntu Trusty) -# fall back to the old iproute package. -if ! apt-cache madison iproute2 | grep 'iproute2 *|' >/dev/null 2>&1 -then - sed 's/iproute2/iproute/' -i debian/control -fi - # If libcrack2 (>= 2.9.0) is not available (before Debian Jessie and Ubuntu Trusty) # clean away the cracklib stanzas so the package can build without them. if ! apt-cache madison libcrack2-dev | grep 'libcrack2-dev *| *2\.9' >/dev/null 2>&1 then sed '/libcrack2-dev/d' -i debian/control - sed '/Package: mariadb-plugin-cracklib/,+11d' -i debian/control + sed '/Package: mariadb-plugin-cracklib/,+9d' -i debian/control fi # If libpcre3-dev (>= 2:8.35-3.2~) is not available (before Debian Jessie or Ubuntu Wily) @@ -85,19 +84,12 @@ fi # Debian Jessie and older and on Ubuntu Xenial and older with the following error message: # /usr/bin/ld.bfd.real: /tmp/ccOIwjFo.ltrans0.ltrans.o: relocation R_X86_64_PC32 against symbol # `toku_product_name_strings' can not be used when making a shared object; recompile with -fPIC -# Therefore we need to disable PIE on those releases using debhelper as proxy for detection. -if ! apt-cache madison debhelper | grep 'debhelper *| *1[0-9]\.' >/dev/null 2>&1 +# Therefore we need to disable PIE on those releases using gcc as proxy for detection. +if [[ $GCCVERSION -lt 60000 ]] then sed 's/hardening=+all$/hardening=+all,-pie/' -i debian/rules fi - -# Convert gcc version to numberical value. Format is Mmmpp where M is Major -# version, mm is minor version and p is patch. -# -dumpfullversion & -dumpversion to make it uniform across old and new (>=7) -GCCVERSION=$(gcc -dumpfullversion -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' \ - -e 's/\.\([0-9]\)/0\1/g' \ - -e 's/^[0-9]\{3,4\}$/&00/') # Don't build rocksdb package if gcc version is less than 4.8 or we are running on # x86 32 bit. if [[ $GCCVERSION -lt 40800 ]] || [[ $(arch) =~ i[346]86 ]] || [[ $TRAVIS ]] @@ -120,8 +112,7 @@ Breaks: mariadb-aws-key-management-10.1, mariadb-aws-key-management-10.2 Replaces: mariadb-aws-key-management-10.1, mariadb-aws-key-management-10.2 -Depends: libcurl3, - mariadb-server-10.3, +Depends: mariadb-server-10.3, \${misc:Depends}, \${shlibs:Depends} Description: Amazon Web Service Key Management Service Plugin for MariaDB @@ -129,13 +120,19 @@ Description: Amazon Web Service Key Management Service Plugin for MariaDB Services Key Management Service for managing encryption keys used for MariaDB data-at-rest encryption. EOF + + sed -i -e "/-DPLUGIN_AWS_KEY_MANAGEMENT=NO/d" debian/rules fi # Mroonga, TokuDB never built on Travis CI anyway, see build flags above if [[ $TRAVIS ]] then - sed -i -e "/Package: mariadb-plugin-tokudb/,+17d" debian/control - sed -i -e "/Package: mariadb-plugin-mroonga/,+16d" debian/control + sed -i -e "/Package: mariadb-plugin-tokudb/,+19d" debian/control + sed -i -e "/Package: mariadb-plugin-mroonga/,+17d" debian/control + sed -i -e "/Package: mariadb-plugin-spider/,+18d" debian/control + sed -i -e "/Package: mariadb-plugin-oqgraph/,+16d" debian/control + sed -i -e "/usr\/lib\/mysql\/plugin\/ha_sphinx.so/d" debian/mariadb-server-10.3.install + sed -i -e "/Package: libmariadbd-dev/,+19d" debian/control fi # Adjust changelog, add new version diff --git a/debian/control b/debian/control index ba783955dc3..2465cfd6b27 100644 --- a/debian/control +++ b/debian/control @@ -423,7 +423,7 @@ Pre-Depends: adduser (>= 3.40), mariadb-common (>= ${source:Version}) Depends: galera-3 (>=25.3), gawk, - iproute2, + iproute | iproute2, libdbi-perl, lsb-base (>= 3.0-10), lsof, @@ -569,6 +569,7 @@ Description: OQGraph storage engine for MariaDB Package: mariadb-plugin-tokudb Architecture: amd64 Depends: mariadb-server-10.3 (= ${binary:Version}), + libjemalloc1 (>= 3.0.0~), ${misc:Depends}, ${shlibs:Depends} Breaks: mariadb-server-10.0, @@ -704,9 +705,6 @@ Depends: libcrack2 (>= 2.9.0), Description: CrackLib Password Validation Plugin for MariaDB This password validation plugin uses cracklib to allow only sufficiently secure (as defined by cracklib) user passwords in MariaDB. - . - Plese refer to the MariaDB Knowledge Base on more information on - how to use this tool. Package: mariadb-test Architecture: any diff --git a/debian/mariadb-plugin-tokudb.install b/debian/mariadb-plugin-tokudb.install index d15db03b3e5..5858b145b70 100644 --- a/debian/mariadb-plugin-tokudb.install +++ b/debian/mariadb-plugin-tokudb.install @@ -1,4 +1,5 @@ etc/mysql/conf.d/tokudb.cnf etc/mysql/mariadb.conf.d +etc/systemd/system/mariadb.service.d/tokudb.conf usr/bin/tokuft_logprint usr/bin/tokuftdump usr/lib/mysql/plugin/ha_tokudb.so diff --git a/debian/mariadb-server-10.3.postinst b/debian/mariadb-server-10.3.postinst index aa6ea07a888..dbe664f30fb 100644 --- a/debian/mariadb-server-10.3.postinst +++ b/debian/mariadb-server-10.3.postinst @@ -50,14 +50,14 @@ EOF return $retval } -# This is necessary because mysql_install_db removes the pid file in /var/run -# and because changed configuration options should take effect immediately. -# In case the server wasn't running at all it should be ok if the stop -# script fails. I can't tell at this point because of the cleaned /var/run. -set +e; invoke stop; set -e - case "$1" in configure) + # This is needed because mysql_install_db removes the pid file in /var/run + # and because changed configuration options should take effect immediately. + # In case the server wasn't running at all it should be ok if the stop + # script fails. I can't tell at this point because of the cleaned /var/run. + set +e; invoke stop; set -e + mysql_statedir=/usr/share/mysql mysql_datadir=/var/lib/mysql mysql_logdir=/var/log/mysql @@ -242,6 +242,13 @@ EOF abort-upgrade|abort-remove|abort-configure) ;; + triggered) + if [ -x "$(command -v systemctl)" ]; then + systemctl daemon-reload + fi + invoke restart + ;; + *) echo "postinst called with unknown argument '$1'" 1>&2 exit 1 diff --git a/debian/mariadb-server-10.3.triggers b/debian/mariadb-server-10.3.triggers new file mode 100644 index 00000000000..d1f5f5e14f1 --- /dev/null +++ b/debian/mariadb-server-10.3.triggers @@ -0,0 +1,2 @@ +interest-noawait /etc/mysql +interest-noawait /etc/systemd/system/mariadb.service.d diff --git a/debian/rules b/debian/rules index ceb2171a289..b3f88189d29 100755 --- a/debian/rules +++ b/debian/rules @@ -88,6 +88,7 @@ endif -DINSTALL_LIBDIR=lib/$(DEB_HOST_MULTIARCH) \ -DINSTALL_PLUGINDIR=lib/mysql/plugin \ -DINSTALL_MYSQLTESTDIR=share/mysql/mysql-test \ + -DPLUGIN_AWS_KEY_MANAGEMENT=NO \ -DDEB=$(DEB_VENDOR) ..' # This is needed, otherwise 'make test' will run before binaries have been built diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index a0c5fbcca1b..3d713776dc4 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -58,6 +58,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "backup_mysql.h" #include <btr0btr.h> +#define ROCKSDB_BACKUP_DIR "#rocksdb" + /* list of files to sync for --rsync mode */ static std::set<std::string> rsync_list; /* locations of tablespaces read from .isl files */ @@ -66,6 +68,21 @@ static std::map<std::string, std::string> tablespace_locations; /* Whether LOCK BINLOG FOR BACKUP has been issued during backup */ bool binlog_locked; +static void rocksdb_create_checkpoint(); +static bool has_rocksdb_plugin(); +static void copy_or_move_dir(const char *from, const char *to, bool copy, bool allow_hardlinks); +static void rocksdb_backup_checkpoint(); +static void rocksdb_copy_back(); + +static bool is_abs_path(const char *path) +{ +#ifdef _WIN32 + return path[0] && path[1] == ':' && (path[2] == '/' || path[2] == '\\'); +#else + return path[0] == '/'; +#endif +} + /************************************************************************ Struct represents file or directory. */ struct datadir_node_t { @@ -1138,7 +1155,8 @@ bool copy_or_move_file(const char *src_file_path, const char *dst_file_path, const char *dst_dir, - uint thread_n) + uint thread_n, + bool copy = xtrabackup_copy_back) { ds_ctxt_t *datasink = ds_data; /* copy to datadir by default */ char filedir[FN_REFLEN]; @@ -1186,7 +1204,7 @@ copy_or_move_file(const char *src_file_path, free(link_filepath); } - ret = (xtrabackup_copy_back ? + ret = (copy ? copy_file(datasink, src_file_path, dst_file_path, thread_n) : move_file(datasink, src_file_path, dst_file_path, dst_dir, thread_n)); @@ -1203,6 +1221,7 @@ cleanup: +static bool backup_files(const char *from, bool prep_mode) { @@ -1370,6 +1389,10 @@ bool backup_start() return false; } + if (has_rocksdb_plugin()) { + rocksdb_create_checkpoint(); + } + // There is no need to stop slave thread before coping non-Innodb data when // --no-lock option is used because --no-lock option requires that no DDL or // DML to non-transaction tables can occur. @@ -1455,6 +1478,10 @@ bool backup_finish() } } + if (has_rocksdb_plugin()) { + rocksdb_backup_checkpoint(); + } + msg_ts("Backup created in directory '%s'\n", xtrabackup_target_dir); if (mysql_binlog_position != NULL) { msg("MySQL binlog position: %s\n", mysql_binlog_position); @@ -1770,6 +1797,16 @@ copy_back() int i_tmp; bool is_ibdata_file; + if (strstr(node.filepath,"/" ROCKSDB_BACKUP_DIR "/") +#ifdef _WIN32 + || strstr(node.filepath,"\\" ROCKSDB_BACKUP_DIR "\\") +#endif + ) + { + // copied at later step + continue; + } + /* create empty directories */ if (node.is_empty_dir) { char path[FN_REFLEN]; @@ -1854,6 +1891,8 @@ copy_back() } } + rocksdb_copy_back(); + cleanup: if (it != NULL) { datadir_iter_free(it); @@ -2030,3 +2069,234 @@ static bool backup_files_from_datadir(const char *dir_path) os_file_closedir(dir); return ret; } + + +static int rocksdb_remove_checkpoint_directory() +{ + xb_mysql_query(mysql_connection, "set global rocksdb_remove_mariabackup_checkpoint=ON", false); + return 0; +} + +static bool has_rocksdb_plugin() +{ + static bool first_time = true; + static bool has_plugin= false; + if (!first_time || !xb_backup_rocksdb) + return has_plugin; + + const char *query = "SELECT COUNT(*) FROM information_schema.plugins WHERE plugin_name='rocksdb'"; + MYSQL_RES* result = xb_mysql_query(mysql_connection, query, true); + MYSQL_ROW row = mysql_fetch_row(result); + if (row) + has_plugin = !strcmp(row[0], "1"); + mysql_free_result(result); + first_time = false; + return has_plugin; +} + +static char *trim_trailing_dir_sep(char *path) +{ + size_t path_len = strlen(path); + while (path_len) + { + char c = path[path_len - 1]; + if (c == '/' IF_WIN(|| c == '\\', )) + path_len--; + else + break; + } + path[path_len] = 0; + return path; +} + +/* +Create a file hardlink. +@return true on success, false on error. +*/ +static bool make_hardlink(const char *from_path, const char *to_path) +{ + DBUG_EXECUTE_IF("no_hardlinks", return false;); + char to_path_full[FN_REFLEN]; + if (!is_abs_path(to_path)) + { + fn_format(to_path_full, to_path, ds_data->root, "", MYF(MY_RELATIVE_PATH)); + } + else + { + strncpy(to_path_full, to_path, sizeof(to_path_full)); + } +#ifdef _WIN32 + return CreateHardLink(to_path_full, from_path, NULL); +#else + return !link(from_path, to_path_full); +#endif +} + +/* + Copies or moves a directory (non-recursively so far). + Helper function used to backup rocksdb checkpoint, or copy-back the + rocksdb files. + + Has optimization that allows to use hardlinks when possible + (source and destination are directories on the same device) +*/ +static void copy_or_move_dir(const char *from, const char *to, bool do_copy, bool allow_hardlinks) +{ + datadir_node_t node; + datadir_node_init(&node); + datadir_iter_t *it = datadir_iter_new(from, false); + + while (datadir_iter_next(it, &node)) + { + char to_path[FN_REFLEN]; + const char *from_path = node.filepath; + snprintf(to_path, sizeof(to_path), "%s/%s", to, base_name(from_path)); + bool rc = false; + if (do_copy && allow_hardlinks) + { + rc = make_hardlink(from_path, to_path); + if (rc) + { + msg_ts("[%02u] Creating hardlink from %s to %s\n", + 1, from_path, to_path); + } + else + { + allow_hardlinks = false; + } + } + + if (!rc) + { + rc = (do_copy ? + copy_file(ds_data, from_path, to_path, 1) : + move_file(ds_data, from_path, node.filepath_rel, + to, 1)); + } + if (!rc) + exit(EXIT_FAILURE); + } + datadir_iter_free(it); + datadir_node_free(&node); + +} + +/* + Obtain user level lock , to protect the checkpoint directory of the server + from being user/overwritten by different backup processes, if backups are + running in parallel. + + This lock will be acquired before rocksdb checkpoint is created, held + while all files from it are being copied to their final backup destination, + and finally released after the checkpoint is removed. +*/ +static void rocksdb_lock_checkpoint() +{ + msg_ts("Obtaining rocksdb checkpoint lock.\n"); + MYSQL_RES *res = + xb_mysql_query(mysql_connection, "SELECT GET_LOCK('mariabackup_rocksdb_checkpoint',3600)", true, true); + + MYSQL_ROW r = mysql_fetch_row(res); + if (r && r[0] && strcmp(r[0], "1")) + { + msg_ts("Could not obtain rocksdb checkpont lock\n"); + exit(EXIT_FAILURE); + } +} + +static void rocksdb_unlock_checkpoint() +{ + xb_mysql_query(mysql_connection, + "SELECT RELEASE_LOCK('mariabackup_rocksdb_checkpoint')", false, true); +} + + +/* + Create temporary checkpoint in $rocksdb_datadir/mariabackup-checkpoint + directory. + A (user-level) lock named 'mariabackup_rocksdb_checkpoint' will also be + acquired be this function. +*/ +#define MARIADB_CHECKPOINT_DIR "mariabackup-checkpoint" +static char rocksdb_checkpoint_dir[FN_REFLEN]; + +static void rocksdb_create_checkpoint() +{ + MYSQL_RES *result = xb_mysql_query(mysql_connection, "SELECT @@rocksdb_datadir,@@datadir", true, true); + MYSQL_ROW row = mysql_fetch_row(result); + + DBUG_ASSERT(row && row[0] && row[1]); + + char *rocksdbdir = row[0]; + char *datadir = row[1]; + + if (is_abs_path(rocksdbdir)) + { + snprintf(rocksdb_checkpoint_dir, sizeof(rocksdb_checkpoint_dir), + "%s/" MARIADB_CHECKPOINT_DIR, trim_trailing_dir_sep(rocksdbdir)); + } + else + { + snprintf(rocksdb_checkpoint_dir, sizeof(rocksdb_checkpoint_dir), + "%s/%s/" MARIADB_CHECKPOINT_DIR, trim_trailing_dir_sep(datadir), + trim_dotslash(rocksdbdir)); + } + mysql_free_result(result); + +#ifdef _WIN32 + for (char *p = rocksdb_checkpoint_dir; *p; p++) + if (*p == '\\') *p = '/'; +#endif + + rocksdb_lock_checkpoint(); + + if (!access(rocksdb_checkpoint_dir, 0)) + { + msg_ts("Removing rocksdb checkpoint from previous backup attempt.\n"); + rocksdb_remove_checkpoint_directory(); + } + + char query[FN_REFLEN + 32]; + snprintf(query, sizeof(query), "SET GLOBAL rocksdb_create_checkpoint='%s'", rocksdb_checkpoint_dir); + xb_mysql_query(mysql_connection, query, false, true); +} + +/* + Copy files from rocksdb temporary checkpoint to final destination. + remove temp.checkpoint directory (in server's datadir) + and release user level lock acquired inside rocksdb_create_checkpoint(). +*/ +static void rocksdb_backup_checkpoint() +{ + msg_ts("Backing up rocksdb files.\n"); + char rocksdb_backup_dir[FN_REFLEN]; + snprintf(rocksdb_backup_dir, sizeof(rocksdb_backup_dir), "%s/" ROCKSDB_BACKUP_DIR , xtrabackup_target_dir); + bool backup_to_directory = xtrabackup_backup && xtrabackup_stream_fmt == XB_STREAM_FMT_NONE; + if (backup_to_directory) + { + if (my_mkdir(rocksdb_backup_dir, 0777, MYF(0))){ + msg_ts("Can't create rocksdb backup directory %s\n", rocksdb_backup_dir); + exit(EXIT_FAILURE); + } + } + copy_or_move_dir(rocksdb_checkpoint_dir, ROCKSDB_BACKUP_DIR, true, backup_to_directory); + rocksdb_remove_checkpoint_directory(); + rocksdb_unlock_checkpoint(); +} + +/* + Copies #rocksdb directory to the $rockdb_data_dir, on copy-back +*/ +static void rocksdb_copy_back() { + if (access(ROCKSDB_BACKUP_DIR, 0)) + return; + char rocksdb_home_dir[FN_REFLEN]; + if (xb_rocksdb_datadir && is_abs_path(xb_rocksdb_datadir)) { + strncpy(rocksdb_home_dir, xb_rocksdb_datadir, sizeof(rocksdb_home_dir)); + } else { + snprintf(rocksdb_home_dir, sizeof(rocksdb_home_dir), "%s/%s", mysql_data_home, + xb_rocksdb_datadir?trim_dotslash(xb_rocksdb_datadir): ROCKSDB_BACKUP_DIR); + } + mkdirp(rocksdb_home_dir, 0777, MYF(0)); + copy_or_move_dir(ROCKSDB_BACKUP_DIR, rocksdb_home_dir, xtrabackup_copy_back, xtrabackup_copy_back); +} diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 3517d9136d4..d04f680c8ef 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -187,6 +187,7 @@ xb_mysql_query(MYSQL *connection, const char *query, bool use_result, if (!use_result) { mysql_free_result(mysql_result); + mysql_result = NULL; } } @@ -1784,12 +1785,17 @@ mdl_lock_table(ulint space_id) MYSQL_RES *mysql_result = xb_mysql_query(mdl_con, oss.str().c_str(), true, true); while (MYSQL_ROW row = mysql_fetch_row(mysql_result)) { + + DBUG_EXECUTE_IF("rename_during_mdl_lock_table", + if (strcmp(row[0], "test/t1") == 0) + xb_mysql_query(mysql_connection, "RENAME TABLE test.t1 to test.t2", false, true + );); + std::string full_table_name = ut_get_name(0,row[0]); std::ostringstream lock_query; lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0"; - msg_ts("Locking MDL for %s\n", full_table_name.c_str()); - xb_mysql_query(mdl_con, lock_query.str().c_str(), false, false); + xb_mysql_query(mdl_con, lock_query.str().c_str(), false, true); } pthread_mutex_unlock(&mdl_lock_con_mutex); diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 179172d3629..33a8e638ccf 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -109,6 +109,7 @@ int sys_var_init(); char xtrabackup_real_target_dir[FN_REFLEN] = "./xtrabackup_backupfiles/"; char *xtrabackup_target_dir= xtrabackup_real_target_dir; static my_bool xtrabackup_version; +static my_bool verbose; my_bool xtrabackup_backup; my_bool xtrabackup_prepare; my_bool xtrabackup_copy_back; @@ -146,6 +147,8 @@ char *xtrabackup_tmpdir; char *xtrabackup_tables; char *xtrabackup_tables_file; char *xtrabackup_tables_exclude; +char *xb_rocksdb_datadir; +my_bool xb_backup_rocksdb = 1; typedef std::list<regex_t> regex_list_t; static regex_list_t regex_include_list; @@ -172,7 +175,6 @@ typedef struct xb_filter_entry_struct xb_filter_entry_t; lsn_t checkpoint_lsn_start; lsn_t checkpoint_no_start; static lsn_t log_copy_scanned_lsn; -static bool log_copying; static bool log_copying_running; static bool io_watching_thread_running; @@ -202,9 +204,9 @@ my_bool opt_ssl_verify_server_cert; /* === metadata of backup === */ #define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints" char metadata_type[30] = ""; /*[full-backuped|log-applied|incremental]*/ -lsn_t metadata_from_lsn; +static lsn_t metadata_from_lsn; lsn_t metadata_to_lsn; -lsn_t metadata_last_lsn; +static lsn_t metadata_last_lsn; static ds_file_t* dst_log_file; @@ -684,11 +686,16 @@ enum options_xtrabackup OPT_XTRA_TABLES_EXCLUDE, OPT_XTRA_DATABASES_EXCLUDE, OPT_PROTOCOL, - OPT_LOCK_DDL_PER_TABLE + OPT_LOCK_DDL_PER_TABLE, + OPT_ROCKSDB_DATADIR, + OPT_BACKUP_ROCKSDB }; struct my_option xb_client_options[] = { + {"verbose", 'V', "display verbose output", + (G_PTR*) &verbose, (G_PTR*) &verbose, 0, GET_BOOL, NO_ARG, + FALSE, 0, 0, 0, 0, 0}, {"version", 'v', "print xtrabackup version information", (G_PTR *) &xtrabackup_version, (G_PTR *) &xtrabackup_version, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -1183,7 +1190,7 @@ struct my_option xb_server_options[] = "The algorithm InnoDB uses for page checksumming. [CRC32, STRICT_CRC32, " "INNODB, STRICT_INNODB, NONE, STRICT_NONE]", &srv_checksum_algorithm, &srv_checksum_algorithm, &innodb_checksum_algorithm_typelib, GET_ENUM, - REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_INNODB, 0, 0, 0, 0, 0}, + REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_CRC32, 0, 0, 0, 0, 0}, {"innodb_undo_directory", OPT_INNODB_UNDO_DIRECTORY, "Directory where undo tablespace files live, this path can be absolute.", @@ -1228,6 +1235,17 @@ struct my_option xb_server_options[] = (uchar*) &opt_lock_ddl_per_table, (uchar*) &opt_lock_ddl_per_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"rocksdb-datadir", OPT_ROCKSDB_DATADIR, "RocksDB data directory." + "This option is only used with --copy-back or --move-back option", + &xb_rocksdb_datadir, &xb_rocksdb_datadir, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + + { "rocksdb-backup", OPT_BACKUP_ROCKSDB, "Backup rocksdb data, if rocksdb plugin is installed." + "Used only with --backup option. Can be useful for partial backups, to exclude all rocksdb data", + &xb_backup_rocksdb, &xb_backup_rocksdb, + 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, + + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1735,7 +1753,7 @@ static bool innodb_init_param() srv_max_n_open_files = ULINT_UNDEFINED - 5; srv_innodb_status = (ibool) innobase_create_status_file; - srv_print_verbose_log = 1; + srv_print_verbose_log = verbose ? 2 : 1; /* Store the default charset-collation number of this MySQL installation */ @@ -2442,25 +2460,13 @@ skip: return(FALSE); } -/** How to copy a redo log segment in backup */ -enum copy_logfile { - /** Initial copying: copy at least one block */ - COPY_FIRST, - /** Tracking while copying data files */ - COPY_ONLINE, - /** Final copying: copy until the end of the log */ - COPY_LAST -}; - /** Copy redo log blocks to the data sink. -@param[in] copy how to copy the log -@param[in] start_lsn buffer start LSN -@param[in] end_lsn buffer end LSN -@return last scanned LSN (equals to last copied LSN if copy=COPY_LAST) +@param start_lsn buffer start LSN +@param end_lsn buffer end LSN +@param last whether we are copying the final part of the log +@return last scanned LSN @retval 0 on failure */ -static -lsn_t -xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn) +static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last) { lsn_t scanned_lsn = start_lsn; const byte* log_block = log_sys.buf; @@ -2475,6 +2481,9 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn) && scanned_checkpoint - checkpoint >= 0x80000000UL) { /* Garbage from a log buffer flush which was made before the most recent database recovery */ + msg("mariabackup: checkpoint wrap: " + LSN_PF ",%zx,%zx\n", + scanned_lsn, scanned_checkpoint, checkpoint); break; } @@ -2495,6 +2504,8 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn) >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE || data_len <= LOG_BLOCK_HDR_SIZE) { /* We got a garbage block (abrupt end of the log). */ + msg("mariabackup: garbage block: " LSN_PF ",%zu\n", + scanned_lsn, data_len); break; } else { /* We got a partial block (abrupt end of the log). */ @@ -2514,7 +2525,7 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn) log_sys.log.scanned_lsn = scanned_lsn; - end_lsn = copy == COPY_LAST + end_lsn = last ? ut_uint64_align_up(scanned_lsn, OS_FILE_LOG_BLOCK_SIZE) : scanned_lsn & ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1); @@ -2534,10 +2545,9 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn) } /** Copy redo log until the current end of the log is reached -@param copy how to copy the log +@param last whether we are copying the final part of the log @return whether the operation failed */ -static bool -xtrabackup_copy_logfile(copy_logfile copy) +static bool xtrabackup_copy_logfile(bool last = false) { ut_a(dst_log_file != NULL); ut_ad(recv_sys != NULL); @@ -2550,32 +2560,28 @@ xtrabackup_copy_logfile(copy_logfile copy) start_lsn = ut_uint64_align_down(log_copy_scanned_lsn, OS_FILE_LOG_BLOCK_SIZE); - /* When copying the first or last part of the log, retry a few - times to ensure that all log up to the last checkpoint will be - read. */ do { end_lsn = start_lsn + RECV_SCAN_SIZE; xtrabackup_io_throttling(); log_mutex_enter(); - lsn_t lsn= start_lsn; - for(int retries= 0; retries < 100; retries++) { - if (log_sys.log.read_log_seg(&lsn, end_lsn)) { + for (int retries= 0; retries < 100; retries++) { + if (log_sys.log.read_log_seg(&lsn, end_lsn) + || lsn != start_lsn) { break; } - msg("Retrying read of a redo log block"); + msg("Retrying read of log at LSN=" LSN_PF "\n", lsn); my_sleep(1000); } - start_lsn = xtrabackup_copy_log(copy, start_lsn, lsn); + start_lsn = (lsn == start_lsn) + ? 0 : xtrabackup_copy_log(start_lsn, lsn, last); log_mutex_exit(); if (!start_lsn) { - ds_close(dst_log_file); - dst_log_file = NULL; msg("mariabackup: Error: xtrabackup_copy_logfile()" " failed.\n"); return(true); @@ -2601,12 +2607,23 @@ static os_thread_ret_t DECLARE_THREAD(log_copying_thread)(void*) */ my_thread_init(); - do { + for (;;) { os_event_reset(log_copying_stop); os_event_wait_time_low(log_copying_stop, xtrabackup_log_copy_interval * 1000ULL, 0); - } while (log_copying && xtrabackup_copy_logfile(COPY_ONLINE)); + if (xtrabackup_copy_logfile()) { + break; + } + + log_mutex_enter(); + bool completed = metadata_to_lsn + && metadata_to_lsn < log_copy_scanned_lsn; + log_mutex_exit(); + if (completed) { + break; + } + } log_copying_running = false; my_thread_end(); @@ -2621,7 +2638,7 @@ static os_thread_ret_t DECLARE_THREAD(io_watching_thread)(void*) /* currently, for --backup only */ ut_a(xtrabackup_backup); - while (log_copying) { + while (log_copying_running && !metadata_to_lsn) { os_thread_sleep(1000000); /*1 sec*/ io_ticket = xtrabackup_throttle; os_event_set(wait_throttle); @@ -3638,16 +3655,16 @@ end: static void stop_backup_threads() { - log_copying = false; - - if (log_copying_stop) { + if (log_copying_stop && log_copying_running) { os_event_set(log_copying_stop); - msg("mariabackup: Stopping log copying thread.\n"); + fputs("mariabackup: Stopping log copying thread", stderr); + fflush(stderr); while (log_copying_running) { - msg("."); + putc('.', stderr); + fflush(stderr); os_thread_sleep(200000); /*0.2 sec*/ } - msg("\n"); + putc('\n', stderr); os_event_destroy(log_copying_stop); } @@ -3662,10 +3679,10 @@ static void stop_backup_threads() /** Implement the core of --backup @return whether the operation succeeded */ -static -bool -xtrabackup_backup_low() +static bool xtrabackup_backup_low() { + ut_ad(!metadata_to_lsn); + /* read the latest checkpoint lsn */ { ulint max_cp_field; @@ -3674,13 +3691,15 @@ xtrabackup_backup_low() if (recv_find_max_checkpoint(&max_cp_field) == DB_SUCCESS && log_sys.log.format != 0) { + if (max_cp_field == LOG_CHECKPOINT_1) { + log_header_read(max_cp_field); + } metadata_to_lsn = mach_read_from_8( log_sys.checkpoint_buf + LOG_CHECKPOINT_LSN); msg("mariabackup: The latest check point" " (for incremental): '" LSN_PF "'\n", metadata_to_lsn); } else { - metadata_to_lsn = 0; msg("mariabackup: Error: recv_find_max_checkpoint() failed.\n"); } log_mutex_exit(); @@ -3688,11 +3707,13 @@ xtrabackup_backup_low() stop_backup_threads(); - if (!dst_log_file || xtrabackup_copy_logfile(COPY_LAST)) { + if (metadata_to_lsn && xtrabackup_copy_logfile(true)) { + ds_close(dst_log_file); + dst_log_file = NULL; return false; } - if (ds_close(dst_log_file)) { + if (ds_close(dst_log_file) || !metadata_to_lsn) { dst_log_file = NULL; return false; } @@ -3771,6 +3792,7 @@ xtrabackup_backup_func() srv_read_only_mode = TRUE; srv_operation = SRV_OPERATION_BACKUP; + metadata_to_lsn = 0; if (xb_close_files) msg("mariabackup: warning: close-files specified. Use it " @@ -3781,7 +3803,12 @@ xtrabackup_backup_func() /* initialize components */ if(innodb_init_param()) { fail: + metadata_to_lsn = log_copying_running; stop_backup_threads(); + if (dst_log_file) { + ds_close(dst_log_file); + dst_log_file = NULL; + } if (fil_system.is_initialised()) { innodb_shutdown(); } @@ -3996,9 +4023,7 @@ reread_log_header: goto log_write_fail; } - /* start flag */ - log_copying = TRUE; - + log_copying_running = true; /* start io throttle */ if(xtrabackup_throttle) { os_thread_id_t io_watching_thread_id; @@ -4016,6 +4041,8 @@ reread_log_header: if (err != DB_SUCCESS) { msg("mariabackup: error: xb_load_tablespaces() failed with" " error %s.\n", ut_strerr(err)); +fail_before_log_copying_thread_start: + log_copying_running = false; goto fail; } @@ -4023,11 +4050,10 @@ reread_log_header: log_copy_scanned_lsn = checkpoint_lsn_start; recv_sys->recovered_lsn = log_copy_scanned_lsn; - if (xtrabackup_copy_logfile(COPY_FIRST)) - goto fail; + if (xtrabackup_copy_logfile()) + goto fail_before_log_copying_thread_start; log_copying_stop = os_event_create(0); - log_copying_running = true; os_thread_create(log_copying_thread, NULL, &log_copying_thread_id); /* FLUSH CHANGED_PAGE_BITMAPS call */ diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index c77485cb4de..857c253f803 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -44,6 +44,9 @@ extern char *xtrabackup_incremental_basedir; extern char *innobase_data_home_dir; extern char *innobase_buffer_pool_filename; extern char *xb_plugin_dir; +extern char *xb_rocksdb_datadir; +extern my_bool xb_backup_rocksdb; + extern uint opt_protocol; extern ds_ctxt_t *ds_meta; extern ds_ctxt_t *ds_data; @@ -56,9 +59,7 @@ extern xb_page_bitmap *changed_page_bitmap; extern char *xtrabackup_incremental; extern my_bool xtrabackup_incremental_force_scan; -extern lsn_t metadata_from_lsn; extern lsn_t metadata_to_lsn; -extern lsn_t metadata_last_lsn; extern xb_stream_fmt_t xtrabackup_stream_fmt; extern ibool xtrabackup_stream; diff --git a/include/my_global.h b/include/my_global.h index 7bf0ee43186..11d17ad146a 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -619,6 +619,8 @@ typedef SOCKET_SIZE_TYPE size_socket; #endif #ifndef SOCK_CLOEXEC #define SOCK_CLOEXEC 0 +#else +#define HAVE_SOCK_CLOEXEC #endif /* additional file share flags for win32 */ diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h index 3baabb6e57d..b8854edbfd0 100644 --- a/include/mysql/psi/mysql_socket.h +++ b/include/mysql/psi/mysql_socket.h @@ -561,6 +561,12 @@ inline_mysql_socket_socket (key, (const my_socket*)&mysql_socket.fd, NULL, 0); } #endif + + /* SOCK_CLOEXEC isn't always a number - can't preprocessor compare */ +#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) && !defined(HAVE_SOCK_CLOEXEC) + (void) fcntl(mysql_socket.fd, F_SETFD, FD_CLOEXEC); +#endif + return mysql_socket; } diff --git a/include/mysql_com.h b/include/mysql_com.h index cfe155d445f..902c0ff2706 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -179,6 +179,7 @@ enum enum_indicator_type #define BINCMP_FLAG 131072U /* Intern: Used by sql_yacc */ #define GET_FIXED_FIELDS_FLAG (1U << 18) /* Used to get fields in item tree */ #define FIELD_IN_PART_FUNC_FLAG (1U << 19)/* Field part of partition func */ +#define PART_INDIRECT_KEY_FLAG (1U << 20) /** Intern: Field in TABLE object for new version of altered table, diff --git a/include/ssl_compat.h b/include/ssl_compat.h index 54e80af769d..2777ae94527 100644 --- a/include/ssl_compat.h +++ b/include/ssl_compat.h @@ -27,7 +27,7 @@ #define HAVE_OPENSSL11 1 #define SSL_LIBRARY OpenSSL_version(OPENSSL_VERSION) #define ERR_remove_state(X) ERR_clear_error() -#define EVP_CIPHER_CTX_SIZE 168 +#define EVP_CIPHER_CTX_SIZE 176 #define EVP_MD_CTX_SIZE 48 #undef EVP_MD_CTX_init #define EVP_MD_CTX_init(X) do { bzero((X), EVP_MD_CTX_SIZE); EVP_MD_CTX_reset(X); } while(0) @@ -77,6 +77,10 @@ #define X509_get0_notAfter(X) X509_get_notAfter(X) #endif +#ifndef TLS1_3_VERSION +#define SSL_CTX_set_ciphersuites(X,Y) 0 +#endif + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ diff --git a/libmariadb b/libmariadb -Subproject a12a0b8362fe8c92ec7252c8da19c14d22e289f +Subproject ebf5db6cd0c7d10b0632a1389faa9731e3c09cf diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index f1fcfac58f5..d7450eb3e87 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -28,9 +28,9 @@ ${SSL_INTERNAL_INCLUDE_DIRS} ) SET(GEN_SOURCES -${CMAKE_BINARY_DIR}/sql/sql_yacc.h +${CMAKE_BINARY_DIR}/sql/sql_yacc.hh ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc -${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.h +${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.hh ${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.cc ${CMAKE_BINARY_DIR}/sql/lex_hash.h ) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index d32a96255b9..715f1dde5b5 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -55,6 +55,9 @@ extern "C" void unireg_clear(int exit_code) DBUG_VOID_RETURN; } + +static my_bool mysql_embedded_init= 0; + /* Wrapper error handler for embedded server to call client/server error handler based on whether thread is in client/server context @@ -518,6 +521,8 @@ int init_embedded_server(int argc, char **argv, char **groups) const char *fake_groups[] = { "server", "embedded", 0 }; my_bool acl_error; + DBUG_ASSERT(mysql_embedded_init == 0); + if (my_thread_init()) return 1; @@ -637,15 +642,20 @@ int init_embedded_server(int argc, char **argv, char **groups) } execute_ddl_log_recovery(); + mysql_embedded_init= 1; return 0; } void end_embedded_server() { - my_free(copy_arguments_ptr); - copy_arguments_ptr=0; - clean_up(0); - clean_up_mutexes(); + if (mysql_embedded_init) + { + my_free(copy_arguments_ptr); + copy_arguments_ptr=0; + clean_up(0); + clean_up_mutexes(); + mysql_embedded_init= 0; + } } diff --git a/mysql-test/include/autoinc_mdev15353.inc b/mysql-test/include/autoinc_mdev15353.inc new file mode 100644 index 00000000000..9085cb29f20 --- /dev/null +++ b/mysql-test/include/autoinc_mdev15353.inc @@ -0,0 +1,29 @@ +DELIMITER $$; +CREATE PROCEDURE autoinc_mdev15353_one(engine VARCHAR(64), t VARCHAR(64)) +BEGIN + DECLARE query TEXT DEFAULT 'CREATE TABLE t1 (' + ' id TTT NOT NULL AUTO_INCREMENT,' + ' name CHAR(30) NOT NULL,' + ' PRIMARY KEY (id)) ENGINE=EEE'; + EXECUTE IMMEDIATE REPLACE(REPLACE(query,'TTT', t), 'EEE', engine); + SHOW CREATE TABLE t1; + INSERT INTO t1 (name) VALUES ('dog'); + SELECT * FROM t1; + UPDATE t1 SET id=-1 WHERE id=1; + SELECT * FROM t1; + INSERT INTO t1 (name) VALUES ('cat'); + SELECT * FROM t1; + DROP TABLE t1; +END; +$$ +DELIMITER ;$$ + +CALL autoinc_mdev15353_one(@engine, 'tinyint'); +CALL autoinc_mdev15353_one(@engine, 'smallint'); +CALL autoinc_mdev15353_one(@engine, 'mediumint'); +CALL autoinc_mdev15353_one(@engine, 'int'); +CALL autoinc_mdev15353_one(@engine, 'bigint'); +CALL autoinc_mdev15353_one(@engine, 'float'); +CALL autoinc_mdev15353_one(@engine, 'double'); + +DROP PROCEDURE autoinc_mdev15353_one; diff --git a/mysql-test/include/wait_until_connected_again.inc b/mysql-test/include/wait_until_connected_again.inc index 2e80ea2ed7d..26168d10558 100644 --- a/mysql-test/include/wait_until_connected_again.inc +++ b/mysql-test/include/wait_until_connected_again.inc @@ -11,7 +11,7 @@ let $counter= 5000; let $mysql_errno= 9999; while ($mysql_errno) { - --error 0,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,2002,2006,2013 + --error 0,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013 show status; dec $counter; diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index cb5553a086c..cb3783eca5a 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -2235,6 +2235,29 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; # +# MDEV-14668 ADD PRIMARY KEY IF NOT EXISTS on composite key +# +CREATE TABLE t1 ( +`ID` BIGINT(20) NOT NULL, +`RANK` MEDIUMINT(4) NOT NULL, +`CHECK_POINT` BIGINT(20) NOT NULL, +UNIQUE INDEX `HORIZON_UIDX01` (`ID`, `RANK`) +) ENGINE=InnoDB; +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `ID` bigint(20) NOT NULL, + `RANK` mediumint(4) NOT NULL, + `CHECK_POINT` bigint(20) NOT NULL, + PRIMARY KEY (`ID`,`CHECK_POINT`), + UNIQUE KEY `HORIZON_UIDX01` (`ID`,`RANK`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +Warnings: +Note 1061 Multiple primary key defined +DROP TABLE t1; +# # End of 10.0 tests # # @@ -2380,5 +2403,16 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; # +# MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed +# in Locked_tables_list::unlock_locked_tables +# +CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB; +INSERT INTO t1 (i) VALUES (1),(1); +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD UNIQUE(i); +ERROR 23000: Duplicate entry '1' for key 'i' +UNLOCK TABLES; +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index aa9faf710f5..5c218c26923 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -1835,6 +1835,21 @@ SHOW CREATE TABLE t1; DROP TABLE t1; --echo # +--echo # MDEV-14668 ADD PRIMARY KEY IF NOT EXISTS on composite key +--echo # +CREATE TABLE t1 ( + `ID` BIGINT(20) NOT NULL, + `RANK` MEDIUMINT(4) NOT NULL, + `CHECK_POINT` BIGINT(20) NOT NULL, + UNIQUE INDEX `HORIZON_UIDX01` (`ID`, `RANK`) + ) ENGINE=InnoDB; + +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +DROP TABLE t1; + +--echo # --echo # End of 10.0 tests --echo # @@ -1938,5 +1953,21 @@ show create table t1; drop table t1; --echo # +--echo # MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed +--echo # in Locked_tables_list::unlock_locked_tables +--echo # + +CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB; +INSERT INTO t1 (i) VALUES (1),(1); +LOCK TABLE t1 WRITE; +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD UNIQUE(i); + +# Cleanup +UNLOCK TABLES; +DROP TABLE t1; + + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/analyze_stmt_orderby.result b/mysql-test/main/analyze_stmt_orderby.result index dd7bd6b53f7..deb19d4d93a 100644 --- a/mysql-test/main/analyze_stmt_orderby.result +++ b/mysql-test/main/analyze_stmt_orderby.result @@ -306,7 +306,7 @@ ANALYZE "r_rows": 10, "r_total_time_ms": "REPLACED", "filtered": 100, - "r_filtered": 1, + "r_filtered": 100, "attached_condition": "t0.a is not null" } } diff --git a/mysql-test/main/auto_increment.result b/mysql-test/main/auto_increment.result index 12cbf294b69..bd61d73f08c 100644 --- a/mysql-test/main/auto_increment.result +++ b/mysql-test/main/auto_increment.result @@ -537,3 +537,155 @@ pk -5 1 drop table t1; +# +# End of 5.3 tests +# +# +# MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +# +CREATE TABLE t1 ( +id TINYINT NOT NULL AUTO_INCREMENT, +name CHAR(30) NOT NULL, +PRIMARY KEY (id) +) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +id name +-1 dog +2 cat +DROP TABLE t1; +# +# End of 5.5 tests +# +# +# MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +# +SET @engine='MyISAM'; +CREATE PROCEDURE autoinc_mdev15353_one(engine VARCHAR(64), t VARCHAR(64)) +BEGIN +DECLARE query TEXT DEFAULT 'CREATE TABLE t1 (' + ' id TTT NOT NULL AUTO_INCREMENT,' + ' name CHAR(30) NOT NULL,' + ' PRIMARY KEY (id)) ENGINE=EEE'; +EXECUTE IMMEDIATE REPLACE(REPLACE(query,'TTT', t), 'EEE', engine); +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +SELECT * FROM t1; +UPDATE t1 SET id=-1 WHERE id=1; +SELECT * FROM t1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; +END; +$$ +CALL autoinc_mdev15353_one(@engine, 'tinyint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'smallint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` smallint(6) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'mediumint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` mediumint(9) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'int'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'bigint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'float'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` float NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'double'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` double NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +DROP PROCEDURE autoinc_mdev15353_one; +# +# End of 10.2 tests +# diff --git a/mysql-test/main/auto_increment.test b/mysql-test/main/auto_increment.test index 7f0ab5dc169..1c359ec5268 100644 --- a/mysql-test/main/auto_increment.test +++ b/mysql-test/main/auto_increment.test @@ -397,3 +397,39 @@ insert into t1 values(null); select last_insert_id(); select * from t1; drop table t1; + +--echo # +--echo # End of 5.3 tests +--echo # + +--echo # +--echo # MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +--echo # + +CREATE TABLE t1 ( + id TINYINT NOT NULL AUTO_INCREMENT, + name CHAR(30) NOT NULL, + PRIMARY KEY (id) +) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # + +--echo # +--echo # MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +--echo # + +SET @engine='MyISAM'; +--source include/autoinc_mdev15353.inc + +--echo # +--echo # End of 10.2 tests +--echo # + diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index 150fe13f7fb..879d837f9f1 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -1478,3 +1478,37 @@ select 2 as f; f 2 drop table t1; +# +# MDEV-16473: query with CTE when no database is set +# +create database db_mdev_16473; +use db_mdev_16473; +drop database db_mdev_16473; +# Now no default database is set +select database(); +database() +NULL +with cte as (select 1 as a) select * from cte; +a +1 +create database db_mdev_16473; +create table db_mdev_16473.t1 (a int); +insert into db_mdev_16473.t1 values (2), (7), (3), (1); +with cte as (select * from db_mdev_16473.t1) select * from cte; +a +2 +7 +3 +1 +with cte as (select * from db_mdev_16473.t1) +select * from cte, t1 as t where cte.a=t.a; +ERROR 3D000: No database selected +with cte as (select * from db_mdev_16473.t1) +select * from cte, db_mdev_16473.t1 as t where cte.a=t.a; +a a +2 2 +7 7 +3 3 +1 1 +drop database db_mdev_16473; +use test; diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test index 98a77940c99..11c864bcac1 100644 --- a/mysql-test/main/cte_nonrecursive.test +++ b/mysql-test/main/cte_nonrecursive.test @@ -1029,4 +1029,31 @@ with cte as select 2 as f; drop table t1; -
\ No newline at end of file + +--echo # +--echo # MDEV-16473: query with CTE when no database is set +--echo # + +create database db_mdev_16473; +use db_mdev_16473; +drop database db_mdev_16473; + +--echo # Now no default database is set +select database(); + +with cte as (select 1 as a) select * from cte; + +create database db_mdev_16473; +create table db_mdev_16473.t1 (a int); +insert into db_mdev_16473.t1 values (2), (7), (3), (1); +with cte as (select * from db_mdev_16473.t1) select * from cte; + +--error ER_NO_DB_ERROR +with cte as (select * from db_mdev_16473.t1) +select * from cte, t1 as t where cte.a=t.a; +with cte as (select * from db_mdev_16473.t1) +select * from cte, db_mdev_16473.t1 as t where cte.a=t.a; + +drop database db_mdev_16473; + +use test; diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 867da5bbbf3..0cd8b4cb844 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -13206,6 +13206,341 @@ a 2 DROP TABLE t1; # +# MDEV-16386: pushing condition into the HAVING clause when ambiguous +# fields warning appears +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,2),(2,3),(3,4); +SELECT * FROM +( +SELECT t1.b AS a +FROM t1 +GROUP BY t1.a +) dt +WHERE (dt.a=2); +a +2 +EXPLAIN FORMAT=JSON SELECT * FROM +( +SELECT t1.b AS a +FROM t1 +GROUP BY t1.a +) dt +WHERE (dt.a=2); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "dt.a = 2", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "a = 2", + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * FROM +( +SELECT t1.b AS a +FROM t1 +GROUP BY t1.a +HAVING (t1.a<3) +) dt +WHERE (dt.a>1); +a +2 +3 +EXPLAIN FORMAT=JSON SELECT * FROM +( +SELECT t1.b AS a +FROM t1 +GROUP BY t1.a +HAVING (t1.a<3) +) dt +WHERE (dt.a>1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "dt.a > 1", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "t1.a < 3 and a > 1", + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * FROM +( +SELECT 'ab' AS a +FROM t1 +GROUP BY t1.a +) dt +WHERE (dt.a='ab'); +a +ab +ab +ab +EXPLAIN FORMAT=JSON SELECT * FROM +( +SELECT 'ab' AS a +FROM t1 +GROUP BY t1.a +) dt +WHERE (dt.a='ab'); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "dt.a = 'ab'", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * FROM +( +SELECT 1 AS a +FROM t1 +GROUP BY t1.a +) dt +WHERE (dt.a=1); +a +1 +1 +1 +EXPLAIN FORMAT=JSON SELECT * FROM +( +SELECT 1 AS a +FROM t1 +GROUP BY t1.a +) dt +WHERE (dt.a=1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "dt.a = 1", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +DROP TABLE t1; +# +# MDEV-16517: pushdown condition with the IN predicate defined +# with non-constant values +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,2),(1,3); +SELECT * FROM +( +SELECT t1.a +FROM t1 +WHERE 1 IN (0,t1.a) +GROUP BY t1.a +) AS dt1 +JOIN +( +SELECT t1.a +FROM t1 +WHERE 1 IN (0,t1.a) +) AS dt2 +ON dt1.a = dt2.a; +a a +1 1 +1 1 +EXPLAIN FORMAT=JSON SELECT * FROM +( +SELECT t1.a +FROM t1 +WHERE 1 IN (0,t1.a) +GROUP BY t1.a +) AS dt1 +JOIN +( +SELECT t1.a +FROM t1 +WHERE 1 IN (0,t1.a) +) AS dt2 +ON dt1.a = dt2.a; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "1 in (0,dt1.a)", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "1 in (0,t1.a) and 1 in (0,t1.a)" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "t1.a = dt1.a" + } + } +} +SELECT * FROM +( +SELECT t1.a,MAX(t1.b) +FROM t1 +GROUP BY t1.a +) AS dt, t1 +WHERE dt.a=t1.a AND dt.a IN (1,t1.a); +a MAX(t1.b) a b +1 3 1 2 +1 3 1 3 +EXPLAIN FORMAT=JSON SELECT * FROM +( +SELECT t1.a,MAX(t1.b) +FROM t1 +GROUP BY t1.a +) AS dt, t1 +WHERE dt.a=t1.a AND dt.a IN (1,t1.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "dt.a in (1,dt.a)", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t1.a in (1,t1.a)" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "t1.a = dt.a" + } + } +} +DROP TABLE t1; +# # MDEV-10855: Pushdown into derived with window functions # set @save_optimizer_switch= @@optimizer_switch; diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index d523ea3916f..e51646a9764 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -2176,7 +2176,7 @@ CREATE TABLE t2 (x INT, y INT, z INT); INSERT INTO t1 VALUES (1,1,66,1), (1,1,56,2), (3,2,42,3); INSERT INTO t2 VALUES (1,1,66), (1,12,32); -LET $query= +let $query= SELECT * FROM t2, ( @@ -2187,11 +2187,11 @@ FROM t2, ) AS v1 WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.a=t2.x) AND (v1.max_c>30); -EVAL $query; -EVAL EXPLAIN $query; -EVAL EXPLAIN FORMAT=JSON $query; +eval $query; +eval EXPLAIN $query; +eval EXPLAIN FORMAT=JSON $query; -LET $query= +let $query= SELECT * FROM t2, ( @@ -2202,9 +2202,9 @@ FROM t2, ) AS v1 WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.b=v1.d) AND (v1.a=t2.x) AND (v1.max_c>30); -EVAL $query; -EVAL EXPLAIN $query; -EVAL EXPLAIN FORMAT=JSON $query; +eval $query; +eval EXPLAIN $query; +eval EXPLAIN FORMAT=JSON $query; DROP TABLE t1,t2; @@ -2230,7 +2230,7 @@ CREATE TABLE t2 (e INT, f INT, g INT); INSERT INTO t1 VALUES (1,14),(2,13),(1,19),(2,32),(3,24); INSERT INTO t2 VALUES (1,19,2),(3,24,1),(1,12,2),(3,11,3),(2,32,1); -LET $query= +let $query= SELECT * FROM t1 WHERE (t1.a,t1.b) IN ( @@ -2244,11 +2244,11 @@ WHERE (t1.a,t1.b) IN WHERE d_tab.e>1 ) ; -EVAL $query; -EVAL EXPLAIN $query; -EVAL EXPLAIN FORMAT=JSON $query; +eval $query; +eval EXPLAIN $query; +eval EXPLAIN FORMAT=JSON $query; -LET $query= +let $query= SELECT * FROM t1 WHERE (t1.a,t1.b) IN ( @@ -2262,11 +2262,11 @@ WHERE (t1.a,t1.b) IN WHERE d_tab.max_f<25 ) ; -EVAL $query; -EVAL EXPLAIN $query; -EVAL EXPLAIN FORMAT=JSON $query; +eval $query; +eval EXPLAIN $query; +eval EXPLAIN FORMAT=JSON $query; -LET $query= +let $query= SELECT * FROM t1 WHERE (t1.a,t1.b) IN ( @@ -2280,11 +2280,11 @@ WHERE (t1.a,t1.b) IN GROUP BY d_tab.g ) ; -EVAL $query; -EVAL EXPLAIN $query; -EVAL EXPLAIN FORMAT=JSON $query; +eval $query; +eval EXPLAIN $query; +eval EXPLAIN FORMAT=JSON $query; -LET $query= +let $query= SELECT * FROM t1 WHERE (t1.a,t1.b) IN ( @@ -2298,9 +2298,9 @@ WHERE (t1.a,t1.b) IN GROUP BY d_tab.g ) ; -EVAL $query; -EVAL EXPLAIN $query; -EVAL EXPLAIN FORMAT=JSON $query; +eval $query; +eval EXPLAIN $query; +eval EXPLAIN FORMAT=JSON $query; DROP TABLE t1,t2; @@ -2320,6 +2320,100 @@ WHERE (a>0 AND a<2 OR a IN (2,3)) AND DROP TABLE t1; +--echo # +--echo # MDEV-16386: pushing condition into the HAVING clause when ambiguous +--echo # fields warning appears +--echo # + +CREATE TABLE t1 (a INT, b INT); + +INSERT INTO t1 VALUES (1,2),(2,3),(3,4); + +let $query= +SELECT * FROM +( + SELECT t1.b AS a + FROM t1 + GROUP BY t1.a +) dt +WHERE (dt.a=2); +eval $query; +eval EXPLAIN FORMAT=JSON $query; + +let $query= +SELECT * FROM +( + SELECT t1.b AS a + FROM t1 + GROUP BY t1.a + HAVING (t1.a<3) +) dt +WHERE (dt.a>1); +eval $query; +eval EXPLAIN FORMAT=JSON $query; + +let $query= +SELECT * FROM +( + SELECT 'ab' AS a + FROM t1 + GROUP BY t1.a +) dt +WHERE (dt.a='ab'); +eval $query; +eval EXPLAIN FORMAT=JSON $query; + +let $query= +SELECT * FROM +( + SELECT 1 AS a + FROM t1 + GROUP BY t1.a +) dt +WHERE (dt.a=1); +eval $query; +eval EXPLAIN FORMAT=JSON $query; + +DROP TABLE t1; + +--echo # +--echo # MDEV-16517: pushdown condition with the IN predicate defined +--echo # with non-constant values +--echo # + +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,2),(1,3); + +let $query= +SELECT * FROM +( + SELECT t1.a + FROM t1 + WHERE 1 IN (0,t1.a) + GROUP BY t1.a +) AS dt1 +JOIN +( + SELECT t1.a + FROM t1 + WHERE 1 IN (0,t1.a) +) AS dt2 +ON dt1.a = dt2.a; +eval $query; +eval EXPLAIN FORMAT=JSON $query; + +let $query= +SELECT * FROM +( + SELECT t1.a,MAX(t1.b) + FROM t1 + GROUP BY t1.a +) AS dt, t1 +WHERE dt.a=t1.a AND dt.a IN (1,t1.a); +eval $query; +eval EXPLAIN FORMAT=JSON $query; +DROP TABLE t1; + # Start of 10.3 tests --echo # diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index 6c4b3310e11..86dd73f5733 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -2977,5 +2977,45 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 /* select#1 */ select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#3 */ select `test`.`t2`.`c2` from `test`.`t2` where <cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`)) DROP TABLE t1, t2; +# +# Bug mdev-16420: materialized view that renames columns +# in inner part of outer join +# +CREATE TABLE t1 (id int, PRIMARY KEY (id)); +INSERT INTO t1 VALUES (2), (3), (7), (1); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT v1.id AS order_pk FROM v1 GROUP BY v1.id; +CREATE VIEW v3 AS +SELECT t.id AS order_pk FROM (SELECT * FROM t1) AS t GROUP BY t.id; +SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk; +id order_pk +1 1 +2 2 +3 3 +7 7 +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index +1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00 +2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v2`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v2` on(`v2`.`order_pk` = `test`.`t1`.`id`) where 1 +SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk; +id order_pk +1 1 +2 2 +3 3 +7 7 +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index +1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00 +2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v3`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v3` on(`v3`.`order_pk` = `test`.`t1`.`id`) where 1 +DROP VIEW v1,v2,v3; +DROP TABLE t1; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index 9b0cf9dca7d..68f334e1ac4 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -1949,6 +1949,30 @@ eval EXPLAIN EXTENDED $q; DROP TABLE t1, t2; +--echo # +--echo # Bug mdev-16420: materialized view that renames columns +--echo # in inner part of outer join +--echo # + +CREATE TABLE t1 (id int, PRIMARY KEY (id)); +INSERT INTO t1 VALUES (2), (3), (7), (1); + +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT v1.id AS order_pk FROM v1 GROUP BY v1.id; +CREATE VIEW v3 AS +SELECT t.id AS order_pk FROM (SELECT * FROM t1) AS t GROUP BY t.id; + +SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk; +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk; + +SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk; +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk; + +DROP VIEW v1,v2,v3; +DROP TABLE t1; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 915ae6edbc8..9a12c0feccb 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -739,6 +739,14 @@ drop table t1; select json_extract('{"test":8.437e-5}','$.test'); json_extract('{"test":8.437e-5}','$.test') 8.437e-5 +select json_value('{"b":true}','$.b')=1; +json_value('{"b":true}','$.b')=1 +1 +CREATE TABLE t1 (c VARCHAR(8)); +INSERT INTO t1 VALUES ('foo'),('bar'); +SELECT * FROM t1 WHERE c IN (JSON_EXTRACT('{"a":"b"}', '$.*')); +c +DROP TABLE t1; # # End of 10.2 tests # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 83a0f4eac74..0cb6fd195b6 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -397,6 +397,21 @@ drop table t1; select json_extract('{"test":8.437e-5}','$.test'); +# +# MDEV-15905 select json_value('{"b":true}','$.b')=1 --> false with +# "Truncated incorrect DOUBLE value: 'true'" +# +select json_value('{"b":true}','$.b')=1; + +# +# MDEV-16209 JSON_EXTRACT in query crashes server. +# + +CREATE TABLE t1 (c VARCHAR(8)); +INSERT INTO t1 VALUES ('foo'),('bar'); +SELECT * FROM t1 WHERE c IN (JSON_EXTRACT('{"a":"b"}', '$.*')); +DROP TABLE t1; + --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/func_misc.result b/mysql-test/main/func_misc.result index e7570004700..2aa305191bd 100644 --- a/mysql-test/main/func_misc.result +++ b/mysql-test/main/func_misc.result @@ -1563,6 +1563,26 @@ def INET_ATON("255.255.255.255.255.255.255.255") 8 21 20 Y 32928 0 63 INET_ATON("255.255.255.255.255.255.255.255") 18446744073709551615 # +# MDEV-8049 name_const() is not consistent about its signess +# +SELECT 18446744073709551615 AS c1, name_const('a',18446744073709551615) AS c2; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def c1 8 20 20 N 32929 0 63 +def c2 8 20 20 Y 32928 0 63 +c1 c2 +18446744073709551615 18446744073709551615 +CREATE TABLE t1 AS SELECT 18446744073709551615 AS c1, name_const('a',18446744073709551615) AS c2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) unsigned NOT NULL, + `c2` bigint(20) unsigned DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +18446744073709551615 18446744073709551615 +DROP TABLE t1; +# # End of 10.3 tests # # diff --git a/mysql-test/main/func_misc.test b/mysql-test/main/func_misc.test index 9b9c9476420..1301b172910 100644 --- a/mysql-test/main/func_misc.test +++ b/mysql-test/main/func_misc.test @@ -1205,6 +1205,20 @@ SELECT INET_ATON("255.255.255.255.255.255.255.255"); --disable_metadata --echo # +--echo # MDEV-8049 name_const() is not consistent about its signess +--echo # + +--enable_metadata +--disable_ps_protocol +SELECT 18446744073709551615 AS c1, name_const('a',18446744073709551615) AS c2; +--enable_ps_protocol +--disable_metadata + +CREATE TABLE t1 AS SELECT 18446744073709551615 AS c1, name_const('a',18446744073709551615) AS c2; +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; +--echo # --echo # End of 10.3 tests --echo # diff --git a/mysql-test/main/func_time_hires.result b/mysql-test/main/func_time_hires.result index 0f822456724..a76571a67b5 100644 --- a/mysql-test/main/func_time_hires.result +++ b/mysql-test/main/func_time_hires.result @@ -206,3 +206,22 @@ time(f1) 21:00:00.000000 21:00:01.000000 drop table t1; +# +# Start of 10.3 tests +# +# +# MDEV-10182 Bad value when inserting COALESCE(CURRENT_TIMESTAMP) into a DECIMAL column +# +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30.000000'); +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (CURRENT_TIMESTAMP(6)); +INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP(6))); +SELECT * FROM t1; +a +20010101102030 +20010101102030 +DROP TABLE t1; +SET timestamp=DEFAULT; +# +# End of 10.3 tests +# diff --git a/mysql-test/main/func_time_hires.test b/mysql-test/main/func_time_hires.test index 4dcd51a85ba..35fd36b8456 100644 --- a/mysql-test/main/func_time_hires.test +++ b/mysql-test/main/func_time_hires.test @@ -106,3 +106,24 @@ alter table t1 modify f1 varchar(100); select time(f1) from t1; select time(f1) from t1 union all select time(f1 + interval 1 second) from t1; drop table t1; + + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-10182 Bad value when inserting COALESCE(CURRENT_TIMESTAMP) into a DECIMAL column +--echo # + +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30.000000'); +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (CURRENT_TIMESTAMP(6)); +INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP(6))); +SELECT * FROM t1; +DROP TABLE t1; +SET timestamp=DEFAULT; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/main/gis-debug.result b/mysql-test/main/gis-debug.result index 60954993a5e..2daa810db0d 100644 --- a/mysql-test/main/gis-debug.result +++ b/mysql-test/main/gis-debug.result @@ -469,7 +469,6 @@ Note 1105 DBUG: [0,0] handler=int Note 1105 DBUG: [0,1] handler=geometry Note 1105 DBUG: [0,2] handler=int Error 4078 Illegal parameter data types int and geometry for operation 'in' -Note 1105 DBUG: types_compatible=yes bisect=yes SELECT (1,(0,0)) IN ((1,(POINT(1,1),0)),(0,(0,0))); ERROR HY000: Illegal parameter data types int and geometry for operation 'in' SHOW WARNINGS; @@ -490,7 +489,6 @@ Note 1105 DBUG: [0,0] handler=int Note 1105 DBUG: [0,1] handler=geometry Note 1105 DBUG: [0,2] handler=int Error 4078 Illegal parameter data types int and geometry for operation 'in' -Note 1105 DBUG: types_compatible=yes bisect=yes SET SESSION debug_dbug="-d,Predicant_to_list_comparator"; SET SESSION debug_dbug="-d,Item_func_in"; SET SESSION debug_dbug="-d,cmp_item"; diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index 1d4402185a5..1279bcdd41e 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -1451,6 +1451,7 @@ CURRENT_USER() root@localhost SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); +update mysql.user set plugin=''; # Bug#57952 diff --git a/mysql-test/main/grant.test b/mysql-test/main/grant.test index 72e427493da..cb4254fe8c6 100644 --- a/mysql-test/main/grant.test +++ b/mysql-test/main/grant.test @@ -1265,6 +1265,9 @@ SELECT CURRENT_USER(); SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); +#cleanup after MDEV-16238 +update mysql.user set plugin=''; + # # Bug#57952: privilege change is not taken into account by EXECUTE. # diff --git a/mysql-test/main/grant2.result b/mysql-test/main/grant2.result index d7e42f9b7aa..ffb41c1b5f8 100644 --- a/mysql-test/main/grant2.result +++ b/mysql-test/main/grant2.result @@ -372,8 +372,8 @@ mysqltest_1@127.0.0.1 set password = password('changed'); disconnect b12302; connection default; -select host, length(password) from mysql.user where user like 'mysqltest\_1'; -host length(password) +select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; +host length(authentication_string) 127.0.0.1 41 revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.1'; delete from mysql.user where user like 'mysqltest\_1'; @@ -387,8 +387,8 @@ mysqltest_1@127.0.0.0/255.0.0.0 set password = password('changed'); disconnect b12302_2; connection default; -select host, length(password) from mysql.user where user like 'mysqltest\_1'; -host length(password) +select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; +host length(authentication_string) 127.0.0.0/255.0.0.0 41 revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.0/255.0.0.0'; delete from mysql.user where user like 'mysqltest\_1'; diff --git a/mysql-test/main/grant2.test b/mysql-test/main/grant2.test index cee5df089df..1f7450df6c1 100644 --- a/mysql-test/main/grant2.test +++ b/mysql-test/main/grant2.test @@ -385,7 +385,7 @@ select current_user(); set password = password('changed'); disconnect b12302; connection default; -select host, length(password) from mysql.user where user like 'mysqltest\_1'; +select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.1'; delete from mysql.user where user like 'mysqltest\_1'; flush privileges; @@ -396,7 +396,7 @@ select current_user(); set password = password('changed'); disconnect b12302_2; connection default; -select host, length(password) from mysql.user where user like 'mysqltest\_1'; +select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.0/255.0.0.0'; delete from mysql.user where user like 'mysqltest\_1'; flush privileges; diff --git a/mysql-test/main/having.result b/mysql-test/main/having.result index 6c206a1699d..f37cc48772e 100644 --- a/mysql-test/main/having.result +++ b/mysql-test/main/having.result @@ -711,6 +711,23 @@ a ct set sql_mode=@save_sql_mode; drop table t1; # +# mdev-16235: impossible HAVING in query without aggregation +# +explain extended +select * from mysql.help_topic where example = 'foo' having description is null; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +Warnings: +Note 1003 select `mysql`.`help_topic`.`help_topic_id` AS `help_topic_id`,`mysql`.`help_topic`.`name` AS `name`,`mysql`.`help_topic`.`help_category_id` AS `help_category_id`,`mysql`.`help_topic`.`description` AS `description`,`mysql`.`help_topic`.`example` AS `example`,`mysql`.`help_topic`.`url` AS `url` from `mysql`.`help_topic` where `mysql`.`help_topic`.`example` = 'foo' having 0 +select * from mysql.help_topic where example = 'foo' having description is null; +help_topic_id name help_category_id description example url +# +# End of 5. tests +# +# +# Start of 10.0 tests +# +# # Bug mdev-5160: two-way join with HAVING over the second table # CREATE TABLE t1 (c1 varchar(6)) ENGINE=MyISAM; diff --git a/mysql-test/main/having.test b/mysql-test/main/having.test index c9231fef3be..179af14559f 100644 --- a/mysql-test/main/having.test +++ b/mysql-test/main/having.test @@ -746,6 +746,23 @@ set sql_mode=@save_sql_mode; drop table t1; --echo # +--echo # mdev-16235: impossible HAVING in query without aggregation +--echo # + +explain extended +select * from mysql.help_topic where example = 'foo' having description is null; + +select * from mysql.help_topic where example = 'foo' having description is null; + +--echo # +--echo # End of 5. tests +--echo # + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # --echo # Bug mdev-5160: two-way join with HAVING over the second table --echo # diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 5fcda217d01..0e6b4168ea5 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -1489,7 +1489,7 @@ USE test; End of 5.0 tests. select * from information_schema.engines WHERE ENGINE="MyISAM"; ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -MyISAM DEFAULT MyISAM storage engine NO NO NO +MyISAM DEFAULT Non-transactional engine with good performance and small data footprint NO NO NO grant select on *.* to user3148@localhost; connect con3148,localhost,user3148,,test; connection con3148; diff --git a/mysql-test/main/limit.result b/mysql-test/main/limit.result index 064fa5a18a7..b47644eb40d 100644 --- a/mysql-test/main/limit.result +++ b/mysql-test/main/limit.result @@ -146,3 +146,19 @@ a 16 DROP TABLE t1; End of 5.1 tests +# +# mdev-16235: SELECT over a table with LIMIT 0 +# +EXPLAIN +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; +start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text thread_id rows_affected +EXPLAIN +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; +help_topic_id name help_category_id description example url +End of 5.5 tests diff --git a/mysql-test/main/limit.test b/mysql-test/main/limit.test index 4dbe13096d4..668d3b74518 100644 --- a/mysql-test/main/limit.test +++ b/mysql-test/main/limit.test @@ -115,3 +115,17 @@ SELECT a FROM t1 ORDER BY a LIMIT 2 OFFSET 14; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # mdev-16235: SELECT over a table with LIMIT 0 +--echo # + +EXPLAIN +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; + +EXPLAIN +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; + +--echo End of 5.5 tests diff --git a/mysql-test/main/lock.result b/mysql-test/main/lock.result index e3fd16ee59a..0805fd45864 100644 --- a/mysql-test/main/lock.result +++ b/mysql-test/main/lock.result @@ -406,7 +406,7 @@ LOCK TABLE t1 WRITE; HANDLER t1 OPEN; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction HANDLER t1 READ FIRST; -ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction +Got one of the listed errors HANDLER t1 CLOSE; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction UNLOCK TABLES; diff --git a/mysql-test/main/lock.test b/mysql-test/main/lock.test index 2c2c5d42783..92ab8294273 100644 --- a/mysql-test/main/lock.test +++ b/mysql-test/main/lock.test @@ -474,7 +474,7 @@ LOCK TABLE t1 WRITE; --echo # HANDLER commands are not allowed in LOCK TABLES mode --error ER_LOCK_OR_ACTIVE_TRANSACTION HANDLER t1 OPEN; ---error ER_LOCK_OR_ACTIVE_TRANSACTION +--error ER_LOCK_OR_ACTIVE_TRANSACTION,ER_UNKNOWN_TABLE HANDLER t1 READ FIRST; --error ER_LOCK_OR_ACTIVE_TRANSACTION HANDLER t1 CLOSE; diff --git a/mysql-test/main/max_statement_time.result b/mysql-test/main/max_statement_time.result index 44ee03b813a..a87a899b575 100644 --- a/mysql-test/main/max_statement_time.result +++ b/mysql-test/main/max_statement_time.result @@ -181,3 +181,6 @@ ERROR 70100: Query execution was interrupted (max_statement_time exceeded) set max_statement_time = 0; drop procedure pr; drop table t1; +SET max_statement_time= 1; +CREATE TABLE t ENGINE=InnoDB SELECT * FROM seq_1_to_50000; +ERROR 70100: Query execution was interrupted (max_statement_time exceeded) diff --git a/mysql-test/main/max_statement_time.test b/mysql-test/main/max_statement_time.test index 0882daff139..24b6d9311f2 100644 --- a/mysql-test/main/max_statement_time.test +++ b/mysql-test/main/max_statement_time.test @@ -5,6 +5,7 @@ --source include/not_embedded.inc --source include/have_innodb.inc +--source include/have_sequence.inc --source include/not_valgrind.inc --echo @@ -226,3 +227,10 @@ call pr(); set max_statement_time = 0; drop procedure pr; drop table t1; + +# +# MDEV-16615 ASAN SEGV in handler::print_error or server crash after error upon CREATE TABLE +# +SET max_statement_time= 1; +--error ER_STATEMENT_TIMEOUT +CREATE TABLE t ENGINE=InnoDB SELECT * FROM seq_1_to_50000; diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 620afb32666..11e46657888 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -5608,6 +5608,21 @@ DROP DATABASE db1; DROP DATABASE db2; FOUND 1 /Database: mysql/ in bug11505.sql # +# MDEV-15021: Fix the order in which routines are called +# +use test; +CREATE FUNCTION f() RETURNS INT RETURN 1; +CREATE VIEW v1 AS SELECT f(); +# Running mysqldump -uroot test --routines --tables v1 > **vardir**/test.dmp +DROP VIEW v1; +DROP FUNCTION f; +# Running mysql -uroot test < **vardir**/test.dmp +# +# Cleanup after succesful import. +# +DROP VIEW v1; +DROP FUNCTION f; +# # Test for --add-drop-trigger # use test; diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test index ebe54bac44a..61287b3170d 100644 --- a/mysql-test/main/mysqldump.test +++ b/mysql-test/main/mysqldump.test @@ -2645,6 +2645,28 @@ exec $MYSQL_DUMP mysql func > $SEARCH_FILE; source include/search_pattern_in_file.inc; --echo # +--echo # MDEV-15021: Fix the order in which routines are called +--echo # +use test; +CREATE FUNCTION f() RETURNS INT RETURN 1; +CREATE VIEW v1 AS SELECT f(); + +--echo # Running mysqldump -uroot test --routines --tables v1 > **vardir**/test.dmp +--exec $MYSQL_DUMP -uroot test --routines --tables v1 > $MYSQLTEST_VARDIR/test.dmp + +DROP VIEW v1; +DROP FUNCTION f; + +--echo # Running mysql -uroot test < **vardir**/test.dmp +--exec $MYSQL -uroot test < $MYSQLTEST_VARDIR/test.dmp + +--echo # +--echo # Cleanup after succesful import. +--echo # +DROP VIEW v1; +DROP FUNCTION f; + +--echo # --echo # Test for --add-drop-trigger --echo # use test; diff --git a/mysql-test/main/mysqlslap.result b/mysql-test/main/mysqlslap.result index d3c5107dee3..791cb5ac6b3 100644 --- a/mysql-test/main/mysqlslap.result +++ b/mysql-test/main/mysqlslap.result @@ -255,3 +255,6 @@ Benchmark # MDEV-4684 - Enhancement request: --init-command support for mysqlslap # DROP TABLE t1; +# +# Bug MDEV-15789 (Upstream: #80329): MYSQLSLAP OPTIONS --AUTO-GENERATE-SQL-GUID-PRIMARY and --AUTO-GENERATE-SQL-SECONDARY-INDEXES DONT WORK +# diff --git a/mysql-test/main/mysqlslap.test b/mysql-test/main/mysqlslap.test index c49c4ab3d7d..81115d59d09 100644 --- a/mysql-test/main/mysqlslap.test +++ b/mysql-test/main/mysqlslap.test @@ -80,3 +80,11 @@ DROP DATABASE bug58090; --exec $MYSQL_SLAP --create-schema=test --init-command="CREATE TABLE t1(a INT)" --silent --concurrency=1 --iterations=1 DROP TABLE t1; + +--echo # +--echo # Bug MDEV-15789 (Upstream: #80329): MYSQLSLAP OPTIONS --AUTO-GENERATE-SQL-GUID-PRIMARY and --AUTO-GENERATE-SQL-SECONDARY-INDEXES DONT WORK +--echo # + +--exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --create-schema=slap + +--exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-secondary-indexes=1 --create-schema=slap diff --git a/mysql-test/main/mysqltest_tracking_info.result b/mysql-test/main/mysqltest_tracking_info.result new file mode 100644 index 00000000000..df966ae1d39 --- /dev/null +++ b/mysql-test/main/mysqltest_tracking_info.result @@ -0,0 +1,31 @@ +SELECT @@session.character_set_connection; +@@session.character_set_connection +latin1 +SET @@session.session_track_system_variables='character_set_connection'; +# tracking info on +SET NAMES 'utf8'; +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- character_set_connection +-- utf8 + +SET NAMES 'big5'; +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- character_set_connection +-- big5 + +# tracking info on once +SET NAMES 'utf8'; +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- character_set_connection +-- utf8 + +SET NAMES 'big5'; +# tracking info on +SET NAMES 'utf8'; +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- character_set_connection +-- utf8 + +# tracking info off once +SET NAMES 'big5'; +SET @@session.session_track_system_variables= default; diff --git a/mysql-test/main/mysqltest_tracking_info.test b/mysql-test/main/mysqltest_tracking_info.test new file mode 100644 index 00000000000..d31f68b3cbd --- /dev/null +++ b/mysql-test/main/mysqltest_tracking_info.test @@ -0,0 +1,25 @@ + +--source include/no_protocol.inc +--source include/not_embedded.inc + +SELECT @@session.character_set_connection; +SET @@session.session_track_system_variables='character_set_connection'; + +--echo # tracking info on +--enable_session_track_info +SET NAMES 'utf8'; +SET NAMES 'big5'; +--disable_session_track_info +--echo # tracking info on once +--enable_session_track_info ONCE +SET NAMES 'utf8'; +SET NAMES 'big5'; +--echo # tracking info on +--enable_session_track_info +SET NAMES 'utf8'; +--echo # tracking info off once +--disable_session_track_info ONCE +SET NAMES 'big5'; +--disable_session_track_info + +SET @@session.session_track_system_variables= default; diff --git a/mysql-test/main/olap.result b/mysql-test/main/olap.result index 6fdbe008016..1931fac6029 100644 --- a/mysql-test/main/olap.result +++ b/mysql-test/main/olap.result @@ -767,7 +767,29 @@ NULL DROP TABLE t1, t2; End of 5.0 tests # -# Start of 10.3 tests +# End of 10.0 tests +# +# +# MDEV-16190 Server crashes in Item_null_result::field_type on SELECT with time field, ROLLUP and HAVING +# +CREATE TABLE t1 (t TIME) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('12:12:12'); +SELECT t, COUNT(*) FROM t1 GROUP BY t WITH ROLLUP HAVING t > '00:00:00'; +t COUNT(*) +12:12:12 1 +DROP TABLE t1; +CREATE TABLE t1 (t TIME) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('12:12:12'),('12:12:13'); +SELECT t, COUNT(*) FROM t1 GROUP BY t WITH ROLLUP HAVING t > '00:00:00'; +t COUNT(*) +12:12:12 1 +12:12:13 1 +DROP TABLE t1; +# +# End of 10.1 tests +# +# +# End of 10.2 tests # # # MDEV-12886 Different default for INT and BIGINT column in a VIEW for a SELECT with ROLLUP diff --git a/mysql-test/main/olap.test b/mysql-test/main/olap.test index 74dbe8ba10b..3756712b49d 100644 --- a/mysql-test/main/olap.test +++ b/mysql-test/main/olap.test @@ -406,7 +406,29 @@ DROP TABLE t1, t2; --echo End of 5.0 tests --echo # ---echo # Start of 10.3 tests +--echo # End of 10.0 tests +--echo # + +--echo # +--echo # MDEV-16190 Server crashes in Item_null_result::field_type on SELECT with time field, ROLLUP and HAVING +--echo # +CREATE TABLE t1 (t TIME) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('12:12:12'); +SELECT t, COUNT(*) FROM t1 GROUP BY t WITH ROLLUP HAVING t > '00:00:00'; +DROP TABLE t1; + +CREATE TABLE t1 (t TIME) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('12:12:12'),('12:12:13'); +SELECT t, COUNT(*) FROM t1 GROUP BY t WITH ROLLUP HAVING t > '00:00:00'; +DROP TABLE t1; + + +--echo # +--echo # End of 10.1 tests +--echo # + +--echo # +--echo # End of 10.2 tests --echo # --echo # @@ -462,5 +484,4 @@ SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WIT --enable_warnings DROP TABLE t1; - --echo # End of 10.3 Tests diff --git a/mysql-test/main/partition_alter.result b/mysql-test/main/partition_alter.result index 448c26c7919..ca6359f94de 100644 --- a/mysql-test/main/partition_alter.result +++ b/mysql-test/main/partition_alter.result @@ -59,7 +59,7 @@ partition p2 values less than ('2020-10-19')); insert t1 values (0, '2000-01-02', 0); insert t1 values (1, '2020-01-02', 10); alter table t1 add check (b in (0, 1)); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`#sql-temporary` +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` alter table t1 add check (b in (0, 10)); show create table t1; Table Create Table @@ -84,7 +84,7 @@ partition p2 values less than ('2020-10-19')); insert t1 values (0, '2000-01-02', 0); insert t1 values (1, '2020-01-02', 10); alter table t1 add check (b in (0, 1)); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`#sql-temporary` +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` alter table t1 add check (b in (0, 10)); show create table t1; Table Create Table diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index f9d0b004591..682c3e31be4 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -4368,7 +4368,46 @@ LINE3 3 drop table t1; # End of 5.5 tests # -# Start of 10.2 tests +# End of 10.0 tests +# +# +# MDEV-12060 Crash in EXECUTE IMMEDIATE with an expression returning a GRANT command +# (the 10.1 part) +# +CREATE PROCEDURE p2 () +BEGIN +SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR PREPARE stmt FROM 'SELECT 1'; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +END; +/ +CALL p2(); +1 +1 +DROP PROCEDURE p2; +BEGIN NOT ATOMIC +SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR PREPARE stmt FROM 'SELECT 1'; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +END; +/ +1 +1 +BEGIN NOT ATOMIC +SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR PREPARE stmt FROM 'SELECT 1'; +DEALLOCATE PREPARE stmt; +END; +/ +BEGIN NOT ATOMIC +PREPARE stmt FROM 'SELECT 1'; +SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR EXECUTE stmt; +DEALLOCATE PREPARE stmt; +END; +/ +1 +1 +# +# End of 10.1 tests # # # MDEV-10709 Expressions as parameters to Dynamic SQL @@ -4921,9 +4960,6 @@ DROP TABLE t1; # End of MDEV-10866 Extend PREPARE and EXECUTE IMMEDIATE to understand expressions # # -# End of 10.2 tests -# -# # MDEV-11360 Dynamic SQL: DEFAULT as a bind parameter # CREATE TABLE t1 (a INT DEFAULT 10, b INT DEFAULT NULL); @@ -5251,3 +5287,39 @@ execute stmt; execute stmt; execute stmt; drop table t1; +# +# MDEV-12060 Crash in EXECUTE IMMEDIATE with an expression returning a GRANT command +# +CREATE ROLE testrole; +CREATE OR REPLACE PROCEDURE p1() +BEGIN +END; +/ +CREATE PROCEDURE p2 (wgrp VARCHAR(10)) +BEGIN +EXECUTE IMMEDIATE concat('GRANT EXECUTE ON PROCEDURE p1 TO ',wgrp); +END; +/ +CALL p2('testrole'); +DROP PROCEDURE p2; +CREATE PROCEDURE p2 () +BEGIN +EXECUTE IMMEDIATE concat(_utf8'GRANT EXECUTE ON PROCEDURE p1 TO ',_latin1'testrole'); +END; +/ +CALL p2(); +DROP PROCEDURE p2; +CREATE PROCEDURE p2 () +BEGIN +PREPARE stmt FROM concat(_utf8'GRANT EXECUTE ON PROCEDURE p1 TO ',_latin1' testrole'); +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +END; +/ +CALL p2(); +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP ROLE testrole; +# +# End of 10.2 tests +# diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index 7ab24cd541d..79c08d62290 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -3875,7 +3875,58 @@ drop table t1; --echo # End of 5.5 tests --echo # ---echo # Start of 10.2 tests +--echo # End of 10.0 tests +--echo # + +--echo # +--echo # MDEV-12060 Crash in EXECUTE IMMEDIATE with an expression returning a GRANT command +--echo # (the 10.1 part) +--echo # + +DELIMITER /; +CREATE PROCEDURE p2 () +BEGIN + SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR PREPARE stmt FROM 'SELECT 1'; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; +END; +/ +DELIMITER ;/ +CALL p2(); +DROP PROCEDURE p2; + + +DELIMITER /; +BEGIN NOT ATOMIC + SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR PREPARE stmt FROM 'SELECT 1'; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; +END; +/ +DELIMITER ;/ + + +DELIMITER /; +BEGIN NOT ATOMIC + SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR PREPARE stmt FROM 'SELECT 1'; + DEALLOCATE PREPARE stmt; +END; +/ +DELIMITER ;/ + + +DELIMITER /; +BEGIN NOT ATOMIC + PREPARE stmt FROM 'SELECT 1'; + SET STATEMENT join_cache_level=CAST(CONCAT(_utf8'6',_latin1'') AS INT) FOR EXECUTE stmt; + DEALLOCATE PREPARE stmt; +END; +/ +DELIMITER ;/ + + +--echo # +--echo # End of 10.1 tests --echo # --echo # @@ -4386,9 +4437,6 @@ DROP TABLE t1; --echo # End of MDEV-10866 Extend PREPARE and EXECUTE IMMEDIATE to understand expressions --echo # ---echo # ---echo # End of 10.2 tests ---echo # --echo # @@ -4687,3 +4735,55 @@ execute stmt; execute stmt; execute stmt; drop table t1; + + +--echo # +--echo # MDEV-12060 Crash in EXECUTE IMMEDIATE with an expression returning a GRANT command +--echo # + +CREATE ROLE testrole; +DELIMITER /; +CREATE OR REPLACE PROCEDURE p1() +BEGIN +END; +/ +DELIMITER ;/ + +DELIMITER /; +CREATE PROCEDURE p2 (wgrp VARCHAR(10)) +BEGIN + EXECUTE IMMEDIATE concat('GRANT EXECUTE ON PROCEDURE p1 TO ',wgrp); +END; +/ +DELIMITER ;/ +CALL p2('testrole'); +DROP PROCEDURE p2; + +DELIMITER /; +CREATE PROCEDURE p2 () +BEGIN + EXECUTE IMMEDIATE concat(_utf8'GRANT EXECUTE ON PROCEDURE p1 TO ',_latin1'testrole'); +END; +/ +DELIMITER ;/ +CALL p2(); +DROP PROCEDURE p2; + +DELIMITER /; +CREATE PROCEDURE p2 () +BEGIN + PREPARE stmt FROM concat(_utf8'GRANT EXECUTE ON PROCEDURE p1 TO ',_latin1' testrole'); + EXECUTE stmt; + DEALLOCATE PREPARE stmt; +END; +/ +DELIMITER ;/ +CALL p2(); +DROP PROCEDURE p2; + +DROP PROCEDURE p1; +DROP ROLE testrole; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/main/read_only_innodb.result b/mysql-test/main/read_only_innodb.result index b6e294b633c..abfc5322ed0 100644 --- a/mysql-test/main/read_only_innodb.result +++ b/mysql-test/main/read_only_innodb.result @@ -237,14 +237,6 @@ a a 5 10 DROP TABLE temp1, temp2; -# MDEV-14185 CREATE TEMPORARY TABLE AS SELECT causes error 1290 with read_only and InnoDB. - -CREATE TEMPORARY TABLE temp1 ENGINE=INNODB AS SELECT a FROM t1; -SELECT * FROM temp1; -a -1 -DROP TABLE temp1; - # Disconnect and cleanup disconnect con1; diff --git a/mysql-test/main/read_only_innodb.test b/mysql-test/main/read_only_innodb.test index a9310a1a78e..9ba3ccaca07 100644 --- a/mysql-test/main/read_only_innodb.test +++ b/mysql-test/main/read_only_innodb.test @@ -241,15 +241,6 @@ SELECT * FROM temp1, temp2; DROP TABLE temp1, temp2; --echo ---echo # MDEV-14185 CREATE TEMPORARY TABLE AS SELECT causes error 1290 with read_only and InnoDB. ---echo - -CREATE TEMPORARY TABLE temp1 ENGINE=INNODB AS SELECT a FROM t1; -SELECT * FROM temp1; -DROP TABLE temp1; - - ---echo --echo # Disconnect and cleanup --echo disconnect con1; diff --git a/mysql-test/main/reset_connection.result b/mysql-test/main/reset_connection.result new file mode 100644 index 00000000000..925195f704e --- /dev/null +++ b/mysql-test/main/reset_connection.result @@ -0,0 +1,7 @@ +FLUSH STATUS; +SHOW local STATUS LIKE 'com_select'; +Variable_name Value +Com_select 10 +SHOW local STATUS LIKE 'com_select'; +Variable_name Value +Com_select 0 diff --git a/mysql-test/main/reset_connection.test b/mysql-test/main/reset_connection.test new file mode 100644 index 00000000000..49f41c32fc3 --- /dev/null +++ b/mysql-test/main/reset_connection.test @@ -0,0 +1,25 @@ +--source include/not_embedded.inc + +FLUSH STATUS; + +--disable_result_log +--disable_query_log + +let $i = 10; +begin; +while ($i) +{ + dec $i; + SELECT 1; +} +commit; + +--enable_query_log +--enable_result_log + +SHOW local STATUS LIKE 'com_select'; + +--reset_connection + +SHOW local STATUS LIKE 'com_select'; + diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result index 9cb6ee3e9bf..aff14b23ccb 100644 --- a/mysql-test/main/selectivity.result +++ b/mysql-test/main/selectivity.result @@ -356,13 +356,13 @@ and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 6005 0.00 Using temporary; Using filesort -1 PRIMARY orders eq_ref PRIMARY,i_o_custkey PRIMARY 4 <subquery2>.l_orderkey 1 100.00 Using where +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 -1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 <subquery2>.l_orderkey 4 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index 2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (/* select#2 */ select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where `dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey` and `dbt3_s001`.`orders`.`o_orderkey` = `<subquery2>`.`l_orderkey` and `dbt3_s001`.`lineitem`.`l_orderkey` = `<subquery2>`.`l_orderkey` group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +Note 1003 /* select#1 */ select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (/* select#2 */ select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where `dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey` and `<subquery2>`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` and `dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem @@ -1530,6 +1530,68 @@ t 10:00:00 11:00:00 DROP TABLE t1; +# +# MDEV-16374: filtered shows 0 for materilization scan for a semi join, which makes optimizer +# always pick materialization scan over materialization lookup +# +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 values (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10), +(11,11),(12,12),(13,13),(14,14),(15,15); +set @@optimizer_use_condition_selectivity=2; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where `<subquery2>`.`max(a)` = `test`.`t1`.`a` +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +set @@optimizer_use_condition_selectivity=1; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where `<subquery2>`.`max(a)` = `test`.`t1`.`a` +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +drop table t1,t0; set histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/selectivity.test b/mysql-test/main/selectivity.test index 3e60f242083..cf12bdaea21 100644 --- a/mysql-test/main/selectivity.test +++ b/mysql-test/main/selectivity.test @@ -1045,6 +1045,24 @@ SELECT * FROM (SELECT t FROM t1 WHERE d IS NULL) sq; DROP TABLE t1; +--echo # +--echo # MDEV-16374: filtered shows 0 for materilization scan for a semi join, which makes optimizer +--echo # always pick materialization scan over materialization lookup +--echo # + +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 values (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10), +(11,11),(12,12),(13,13),(14,14),(15,15); +set @@optimizer_use_condition_selectivity=2; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +select * from t1 where a in (select max(a) from t1 group by b); +set @@optimizer_use_condition_selectivity=1; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +select * from t1 where a in (select max(a) from t1 group by b); +drop table t1,t0; + set histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index 236647c6091..ab698760c55 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -359,13 +359,13 @@ and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 6005 0.00 Using temporary; Using filesort -1 PRIMARY orders eq_ref PRIMARY,i_o_custkey PRIMARY 4 <subquery2>.l_orderkey 1 100.00 Using where +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 -1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 <subquery2>.l_orderkey 4 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index 2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00 Warnings: -Note 1003 /* select#1 */ select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (/* select#2 */ select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where `dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey` and `dbt3_s001`.`orders`.`o_orderkey` = `<subquery2>`.`l_orderkey` and `dbt3_s001`.`lineitem`.`l_orderkey` = `<subquery2>`.`l_orderkey` group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +Note 1003 /* select#1 */ select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (/* select#2 */ select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where `dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey` and `<subquery2>`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` and `dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem @@ -1150,6 +1150,7 @@ alter table t1 change column a a int; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Note Data truncated for column 'avg_frequency' at row 1 test.t1 analyze status OK flush table t1; explain extended select * from t1 where a between 5 and 7; @@ -1540,6 +1541,68 @@ t 10:00:00 11:00:00 DROP TABLE t1; +# +# MDEV-16374: filtered shows 0 for materilization scan for a semi join, which makes optimizer +# always pick materialization scan over materialization lookup +# +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 values (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10), +(11,11),(12,12),(13,13),(14,14),(15,15); +set @@optimizer_use_condition_selectivity=2; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where `<subquery2>`.`max(a)` = `test`.`t1`.`a` +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +set @@optimizer_use_condition_selectivity=1; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where `<subquery2>`.`max(a)` = `test`.`t1`.`a` +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +drop table t1,t0; set histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/session_tracker_last_gtid.result b/mysql-test/main/session_tracker_last_gtid.result new file mode 100644 index 00000000000..795d0aaa2a2 --- /dev/null +++ b/mysql-test/main/session_tracker_last_gtid.result @@ -0,0 +1,34 @@ +# +# MDEV-15477: SESSION_SYSVARS_TRACKER does not track last_gtid +# +SET gtid_seq_no=1000; +SET @@session.session_track_system_variables='last_gtid'; +create table t1 (a int) engine=innodb; +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- last_gtid +-- 0-1-1000 + +select @@last_gtid; +@@last_gtid +0-1-1000 +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- last_gtid +-- 0-1-1000 + +insert into t1 values (1); +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- last_gtid +-- 0-1-1001 + +select @@last_gtid; +@@last_gtid +0-1-1001 +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- last_gtid +-- 0-1-1001 + +drop table t1; +-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES +-- last_gtid +-- 0-1-1002 + diff --git a/mysql-test/main/session_tracker_last_gtid.test b/mysql-test/main/session_tracker_last_gtid.test new file mode 100644 index 00000000000..24cf2104a0c --- /dev/null +++ b/mysql-test/main/session_tracker_last_gtid.test @@ -0,0 +1,19 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc + +--enable_session_track_info + +--echo # +--echo # MDEV-15477: SESSION_SYSVARS_TRACKER does not track last_gtid +--echo # + +SET gtid_seq_no=1000; +SET @@session.session_track_system_variables='last_gtid'; +create table t1 (a int) engine=innodb; +select @@last_gtid; +insert into t1 values (1); +select @@last_gtid; +drop table t1; + +--disable_session_track_info diff --git a/mysql-test/main/set_password_plugin-9835.result b/mysql-test/main/set_password.result index 3cc723957d8..315d0bef9fb 100644 --- a/mysql-test/main/set_password_plugin-9835.result +++ b/mysql-test/main/set_password.result @@ -11,10 +11,10 @@ select user, host, password, plugin, authentication_string from mysql.user where user host password plugin authentication_string natauth localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 newpass localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 -newpassnat localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +newpassnat localhost mysql_native_password *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 oldauth localhost 378b243e220ca493 oldpass localhost 378b243e220ca493 -oldpassold localhost 378b243e220ca493 +oldpassold localhost mysql_old_password 378b243e220ca493 connect con,localhost,natauth,test,; select current_user(); current_user() @@ -86,12 +86,12 @@ set password for oldpass@localhost = PASSWORD('test2'); set password for oldpassold@localhost = PASSWORD('test2'); select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; user host password plugin authentication_string -natauth localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E -newpass localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E -newpassnat localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E -oldauth localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E -oldpass localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E -oldpassold localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +natauth localhost mysql_native_password *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +newpass localhost mysql_native_password *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +newpassnat localhost mysql_native_password *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldauth localhost mysql_native_password *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldpass localhost mysql_native_password *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldpassold localhost mysql_native_password *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E connect con,localhost,natauth,test2,; select current_user(); current_user() @@ -158,3 +158,24 @@ connection default; drop user natauth@localhost, newpass@localhost, newpassnat@localhost; drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; set global secure_auth=default; +create user foo@localhost identified with mysql_native_password; +update mysql.user set authentication_string=password('foo'), plugin='mysql_native_password' where user='foo' and host='localhost'; +set password for 'foo'@'localhost' = password('bar'); +flush privileges; +connect foo, localhost, foo, bar; +select user(), current_user(); +user() current_user() +foo@localhost foo@localhost +show grants; +Grants for foo@localhost +GRANT USAGE ON *.* TO 'foo'@'localhost' IDENTIFIED BY PASSWORD '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB' +disconnect foo; +connection default; +select user,host,password,plugin,authentication_string from mysql.user where user='foo'; +user host password plugin authentication_string +foo localhost mysql_native_password *E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB +set password for 'foo'@'localhost' = ''; +select user,host,password,plugin,authentication_string from mysql.user where user='foo'; +user host password plugin authentication_string +foo localhost mysql_native_password +drop user foo@localhost; diff --git a/mysql-test/main/set_password_plugin-9835.test b/mysql-test/main/set_password.test index 6afccd74f9d..fc1ecb5ef5c 100644 --- a/mysql-test/main/set_password_plugin-9835.test +++ b/mysql-test/main/set_password.test @@ -129,3 +129,19 @@ drop user natauth@localhost, newpass@localhost, newpassnat@localhost; drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; set global secure_auth=default; +# +# MDEV-16238 root/localhost authn prioritizes authentication_string over Password +# +create user foo@localhost identified with mysql_native_password; +update mysql.user set authentication_string=password('foo'), plugin='mysql_native_password' where user='foo' and host='localhost'; +set password for 'foo'@'localhost' = password('bar'); +flush privileges; +--connect foo, localhost, foo, bar +select user(), current_user(); +show grants; +--disconnect foo +--connection default +select user,host,password,plugin,authentication_string from mysql.user where user='foo'; +set password for 'foo'@'localhost' = ''; +select user,host,password,plugin,authentication_string from mysql.user where user='foo'; +drop user foo@localhost; diff --git a/mysql-test/main/show_grants_with_plugin-7985.result b/mysql-test/main/show_grants_with_plugin-7985.result index 81880e5cc40..0f8e1e39969 100644 --- a/mysql-test/main/show_grants_with_plugin-7985.result +++ b/mysql-test/main/show_grants_with_plugin-7985.result @@ -71,7 +71,7 @@ connection default; set password for u1 = PASSWORD('SOMETHINGELSE'); select user, host, password, plugin, authentication_string from mysql.user where user = 'u1'; user host password plugin authentication_string -u1 % *054B7BBD2B9A553DA560520DCD3F76DA2D81B7C6 +u1 % mysql_native_password *054B7BBD2B9A553DA560520DCD3F76DA2D81B7C6 # # Here we should use the password field, as that primes over # the authentication_string field. @@ -112,7 +112,7 @@ connection default; # Now we remove the authentication plugin password, flush privileges and # try again. # -update mysql.user set authentication_string = '' where user='u1'; +update mysql.user set password=authentication_string, plugin='', authentication_string='' where user='u1'; select user, host, password, plugin, authentication_string from mysql.user where user = 'u1'; user host password plugin authentication_string u1 % *054B7BBD2B9A553DA560520DCD3F76DA2D81B7C6 @@ -172,7 +172,7 @@ connection default; set password for u1 = ''; select user, host, password, plugin, authentication_string from mysql.user where user = 'u1'; user host password plugin authentication_string -u1 % +u1 % mysql_native_password # # Test no password connect. # diff --git a/mysql-test/main/show_grants_with_plugin-7985.test b/mysql-test/main/show_grants_with_plugin-7985.test index 84f71c72667..85952870254 100644 --- a/mysql-test/main/show_grants_with_plugin-7985.test +++ b/mysql-test/main/show_grants_with_plugin-7985.test @@ -91,7 +91,7 @@ show grants; --echo # Now we remove the authentication plugin password, flush privileges and --echo # try again. --echo # -update mysql.user set authentication_string = '' where user='u1'; +update mysql.user set password=authentication_string, plugin='', authentication_string='' where user='u1'; select user, host, password, plugin, authentication_string from mysql.user where user = 'u1'; flush privileges; show grants for u1; diff --git a/mysql-test/main/sp-code.result b/mysql-test/main/sp-code.result index 001b03a0e3b..c3af01d19e8 100644 --- a/mysql-test/main/sp-code.result +++ b/mysql-test/main/sp-code.result @@ -1113,23 +1113,26 @@ Pos Instruction 10 stmt 0 "SELECT rec1.a, rec1.b" 11 cfetch cur1@1 rec1@0 12 jump 6 -13 cursor_copy_struct cur0 rec0@1 -14 copen cur0@0 -15 cfetch cur0@0 rec0@1 -16 jump_if_not 21(21) `cur0`%FOUND -17 set rec0.a@1["a"] 10 -18 set rec0.b@1["b"] 'b0' -19 cfetch cur0@0 rec0@1 -20 jump 16 -21 cursor_copy_struct cur2 rec2@2 -22 copen cur2@2 -23 cfetch cur2@2 rec2@2 -24 jump_if_not 29(29) `cur2`%FOUND -25 set rec2.a@2["a"] 10 -26 set rec2.b@2["b"] 'b0' -27 cfetch cur2@2 rec2@2 -28 jump 24 -29 cpop 3 +13 cclose cur1@1 +14 cursor_copy_struct cur0 rec0@1 +15 copen cur0@0 +16 cfetch cur0@0 rec0@1 +17 jump_if_not 22(22) `cur0`%FOUND +18 set rec0.a@1["a"] 10 +19 set rec0.b@1["b"] 'b0' +20 cfetch cur0@0 rec0@1 +21 jump 17 +22 cclose cur0@0 +23 cursor_copy_struct cur2 rec2@2 +24 copen cur2@2 +25 cfetch cur2@2 rec2@2 +26 jump_if_not 31(31) `cur2`%FOUND +27 set rec2.a@2["a"] 10 +28 set rec2.b@2["b"] 'b0' +29 cfetch cur2@2 rec2@2 +30 jump 26 +31 cclose cur2@2 +32 cpop 3 DROP PROCEDURE p1; # Nested explicit cursor FOR loops CREATE PROCEDURE p1() @@ -1164,14 +1167,14 @@ Pos Instruction 1 cursor_copy_struct cur0 rec0@0 2 copen cur0@0 3 cfetch cur0@0 rec0@0 -4 jump_if_not 29(29) `cur0`%FOUND +4 jump_if_not 31(31) `cur0`%FOUND 5 cpush cur1@1 6 set rec0.a@0["a"] 11 7 set rec0.b@0["b"] 'b0' 8 cursor_copy_struct cur1 rec1@1 9 copen cur1@1 10 cfetch cur1@1 rec1@1 -11 jump_if_not 26(26) `cur1`%FOUND +11 jump_if_not 27(27) `cur1`%FOUND 12 set rec1.a@1["a"] 11 13 set rec1.b@1["b"] 'b1' 14 cpush cur2@2 @@ -1183,13 +1186,16 @@ Pos Instruction 20 set rec2.b@2["b"] 'b2' 21 cfetch cur2@2 rec2@2 22 jump 18 -23 cpop 1 -24 cfetch cur1@1 rec1@1 -25 jump 11 -26 cpop 1 -27 cfetch cur0@0 rec0@0 -28 jump 4 -29 cpop 1 +23 cclose cur2@2 +24 cpop 1 +25 cfetch cur1@1 rec1@1 +26 jump 11 +27 cclose cur1@1 +28 cpop 1 +29 cfetch cur0@0 rec0@0 +30 jump 4 +31 cclose cur0@0 +32 cpop 1 DROP PROCEDURE p1; # Implicit cursor FOR loops CREATE PROCEDURE p1() diff --git a/mysql-test/main/sp-condition-handler.result b/mysql-test/main/sp-condition-handler.result new file mode 100644 index 00000000000..350c5d2bd3d --- /dev/null +++ b/mysql-test/main/sp-condition-handler.result @@ -0,0 +1,43 @@ +# +# Start of 10.3 tests +# +# +# MDEV-16595 SP with a CONTINUE HANDLER inside a loop wastes THD memory aggressively +# +CREATE PROCEDURE p1() +BEGIN +DECLARE mem_used_old BIGINT UNSIGNED DEFAULT +(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS +WHERE VARIABLE_NAME='MEMORY_USED'); +DECLARE i INT DEFAULT 1; +WHILE i <= 1000 +DO +BEGIN +DECLARE msg TEXT; +DECLARE mem_used_cur BIGINT UNSIGNED DEFAULT +(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS +WHERE VARIABLE_NAME='MEMORY_USED'); +DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23001' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23002' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23003' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23004' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23005' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23006' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23007' SET @x=1; +DECLARE CONTINUE HANDLER FOR SQLSTATE '23008' SET @x=1; +IF (mem_used_cur >= mem_used_old * 1.1) THEN +SHOW STATUS LIKE 'Memory_used'; +SET msg=CONCAT('Memory leak detected: i=', i, ' mem_used_old=',mem_used_old,' mem_used_cur=', mem_used_cur); +SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT=msg; +END IF; +END; +SET i=i+1; +END WHILE; +END; +$$ +CALL p1; +DROP PROCEDURE p1; +# +# End of 10.3 tests +# diff --git a/mysql-test/main/sp-condition-handler.test b/mysql-test/main/sp-condition-handler.test new file mode 100644 index 00000000000..29f841607e2 --- /dev/null +++ b/mysql-test/main/sp-condition-handler.test @@ -0,0 +1,50 @@ + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-16595 SP with a CONTINUE HANDLER inside a loop wastes THD memory aggressively +--echo # + +DELIMITER $$; +CREATE PROCEDURE p1() +BEGIN + DECLARE mem_used_old BIGINT UNSIGNED DEFAULT + (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS + WHERE VARIABLE_NAME='MEMORY_USED'); + DECLARE i INT DEFAULT 1; + WHILE i <= 1000 + DO + BEGIN + DECLARE msg TEXT; + DECLARE mem_used_cur BIGINT UNSIGNED DEFAULT + (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS + WHERE VARIABLE_NAME='MEMORY_USED'); + DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23001' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23002' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23003' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23004' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23005' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23006' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23007' SET @x=1; + DECLARE CONTINUE HANDLER FOR SQLSTATE '23008' SET @x=1; + IF (mem_used_cur >= mem_used_old * 1.1) THEN + SHOW STATUS LIKE 'Memory_used'; + SET msg=CONCAT('Memory leak detected: i=', i, ' mem_used_old=',mem_used_old,' mem_used_cur=', mem_used_cur); + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT=msg; + END IF; + END; + SET i=i+1; + END WHILE; +END; +$$ +DELIMITER ;$$ +CALL p1; +DROP PROCEDURE p1; + + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/main/sp-cursor.result b/mysql-test/main/sp-cursor.result index 1f8cb7f0635..f1dd8ed5eaa 100644 --- a/mysql-test/main/sp-cursor.result +++ b/mysql-test/main/sp-cursor.result @@ -611,3 +611,105 @@ a b a b 2 b2 DROP TABLE t1; +# +# MDEV-15941 Explicit cursor FOR loop does not close the cursor +# +BEGIN NOT ATOMIC +DECLARE v INT; +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +FETCH cur INTO v; +END; +$$ +rec.a +1 +ERROR 24000: Cursor is not open +BEGIN NOT ATOMIC +DECLARE v INT; +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label: +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +FETCH cur INTO v; +END; +$$ +rec.a +1 +ERROR 24000: Cursor is not open +BEGIN NOT ATOMIC +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +OPEN cur; +FOR rec IN cur DO +SELECT rec.a; +END FOR; +END; +$$ +ERROR 24000: Cursor is already open +BEGIN NOT ATOMIC +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +END; +$$ +rec.a +1 +rec.a +1 +BEGIN NOT ATOMIC +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label1: +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +label2: +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +END; +$$ +rec.a +1 +rec.a +1 +# +# MDEV-16584 SP with a cursor inside a loop wastes THD memory aggressively +# +CREATE PROCEDURE p1() +BEGIN +DECLARE mem_used_old BIGINT UNSIGNED DEFAULT +(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS +WHERE VARIABLE_NAME='MEMORY_USED'); +DECLARE i INT DEFAULT 1; +WHILE i <= 5000 +DO +BEGIN +DECLARE msg TEXT; +DECLARE mem_used_cur BIGINT UNSIGNED DEFAULT +(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS +WHERE VARIABLE_NAME='MEMORY_USED'); +DECLARE cur CURSOR FOR SELECT 1 FROM DUAL; +IF (mem_used_cur >= mem_used_old * 2) THEN +SHOW STATUS LIKE 'Memory_used'; +SET msg=CONCAT('Memory leak detected: i=', i, ' mem_used_old=',mem_used_old,' mem_used_cur=', mem_used_cur); +SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT=msg; +END IF; +END; +SET i=i+1; +END WHILE; +END; +$$ +CALL p1; +DROP PROCEDURE p1; diff --git a/mysql-test/main/sp-cursor.test b/mysql-test/main/sp-cursor.test index 2e7a72cf8d0..735514ff376 100644 --- a/mysql-test/main/sp-cursor.test +++ b/mysql-test/main/sp-cursor.test @@ -607,3 +607,119 @@ END; $$ DELIMITER ;$$ DROP TABLE t1; + + +--echo # +--echo # MDEV-15941 Explicit cursor FOR loop does not close the cursor +--echo # + +DELIMITER $$; +--error ER_SP_CURSOR_NOT_OPEN +BEGIN NOT ATOMIC + DECLARE v INT; + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; + FOR rec IN cur + DO + SELECT rec.a; + END FOR; + FETCH cur INTO v; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_SP_CURSOR_NOT_OPEN +BEGIN NOT ATOMIC + DECLARE v INT; + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label: + FOR rec IN cur + DO + SELECT rec.a; + END FOR; + FETCH cur INTO v; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_SP_CURSOR_ALREADY_OPEN +BEGIN NOT ATOMIC + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; + OPEN cur; + FOR rec IN cur DO + SELECT rec.a; + END FOR; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; + FOR rec IN cur + DO + SELECT rec.a; + END FOR; + FOR rec IN cur + DO + SELECT rec.a; + END FOR; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label1: + FOR rec IN cur + DO + SELECT rec.a; + END FOR; +label2: + FOR rec IN cur + DO + SELECT rec.a; + END FOR; +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # MDEV-16584 SP with a cursor inside a loop wastes THD memory aggressively +--echo # + +DELIMITER $$; +CREATE PROCEDURE p1() +BEGIN + DECLARE mem_used_old BIGINT UNSIGNED DEFAULT + (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS + WHERE VARIABLE_NAME='MEMORY_USED'); + DECLARE i INT DEFAULT 1; + WHILE i <= 5000 + DO + BEGIN + DECLARE msg TEXT; + DECLARE mem_used_cur BIGINT UNSIGNED DEFAULT + (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS + WHERE VARIABLE_NAME='MEMORY_USED'); + DECLARE cur CURSOR FOR SELECT 1 FROM DUAL; + IF (mem_used_cur >= mem_used_old * 2) THEN + SHOW STATUS LIKE 'Memory_used'; + SET msg=CONCAT('Memory leak detected: i=', i, ' mem_used_old=',mem_used_old,' mem_used_cur=', mem_used_cur); + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT=msg; + END IF; + END; + SET i=i+1; + END WHILE; +END; +$$ +DELIMITER ;$$ +CALL p1; +DROP PROCEDURE p1; diff --git a/mysql-test/main/sp-security.result b/mysql-test/main/sp-security.result index 882072ff7c7..7813ab6a192 100644 --- a/mysql-test/main/sp-security.result +++ b/mysql-test/main/sp-security.result @@ -755,6 +755,7 @@ GRANT EXECUTE ON PROCEDURE `test`.`sp1` TO 'root'@'localhost' GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION drop procedure sp1; set password=''; +update mysql.user set plugin=''; # # MDEV-13396 Unexpected "alter routine comand defined" during CREATE OR REPLACE PROCEDURE # diff --git a/mysql-test/main/sp-security.test b/mysql-test/main/sp-security.test index 059a5dd0fa8..73d0263dd69 100644 --- a/mysql-test/main/sp-security.test +++ b/mysql-test/main/sp-security.test @@ -1023,6 +1023,8 @@ grant execute on procedure sp1 to current_user() identified by 'barfoo'; show grants; drop procedure sp1; set password=''; +#cleanup after MDEV-16238 +update mysql.user set plugin=''; --echo # --echo # MDEV-13396 Unexpected "alter routine comand defined" during CREATE OR REPLACE PROCEDURE diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 64caf0fd554..4315cc60925 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -8356,6 +8356,34 @@ CREATE PROCEDURE foo ( IN i INT UNSIGNED ) BEGIN END; CALL foo( LAST_INSERT_ID() ); DROP PROCEDURE foo; # +# MDEV-15870 Using aggregate and window function in unexpected places can crash the server +# +CREATE PROCEDURE p1 (a TEXT) BEGIN END; +CALL p1(RANK() OVER (ORDER BY 1)); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +CALL p1(ROW_NUMBER() OVER ()); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +CALL p1(SUM(1)); +ERROR HY000: Invalid use of group function +DROP PROCEDURE p1; +# +# MDEV-16311 Server crash when using a NAME_CONST() with a CURSOR +# +SET sql_mode=STRICT_ALL_TABLES; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +BEGIN NOT ATOMIC +DECLARE a INT; +DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1; +OPEN c; +FETCH c INTO a; +CLOSE c; +END; +$$ +ERROR 22007: Incorrect integer value: 'y' for column 'a' at row 1 +DROP TABLE t1; +SET sql_mode=DEFAULT; +# # Start of 10.3 tests # # diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index cfd6604acce..c4d85f63498 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -9869,6 +9869,41 @@ CALL foo( LAST_INSERT_ID() ); DROP PROCEDURE foo; --echo # +--echo # MDEV-15870 Using aggregate and window function in unexpected places can crash the server +--echo # + +CREATE PROCEDURE p1 (a TEXT) BEGIN END; +--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION +CALL p1(RANK() OVER (ORDER BY 1)); +--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION +CALL p1(ROW_NUMBER() OVER ()); +--error ER_INVALID_GROUP_FUNC_USE +CALL p1(SUM(1)); +DROP PROCEDURE p1; + + +--echo # +--echo # MDEV-16311 Server crash when using a NAME_CONST() with a CURSOR +--echo # + +SET sql_mode=STRICT_ALL_TABLES; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +DELIMITER $$; +--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +BEGIN NOT ATOMIC + DECLARE a INT; + DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1; + OPEN c; + FETCH c INTO a; + CLOSE c; +END; +$$ +DELIMITER ;$$ +DROP TABLE t1; +SET sql_mode=DEFAULT; + +--echo # --echo # Start of 10.3 tests --echo # diff --git a/mysql-test/main/sql_mode.result b/mysql-test/main/sql_mode.result index 02574c1c545..238bae2efd8 100644 --- a/mysql-test/main/sql_mode.result +++ b/mysql-test/main/sql_mode.result @@ -780,3 +780,27 @@ END; $$ ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'error; END' at line 4 +# +# End of 10.2 tests +# +# +# Start of 10.3 tests +# +# +# MDEV-16471 mysqldump throws "Variable 'sql_mode' can't be set to the value of 'NULL' (1231)" +# +SET sql_mode='ORACLE,EMPTY_STRING_IS_NULL'; +SELECT @@sql_mode; +@@sql_mode +PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT +SELECT '' AS empty; +empty +NULL +SET sql_mode=''; +SELECT @@sql_mode; +@@sql_mode + +SET sql_mode=DEFAULT; +# +# End of 10.3 tests +# diff --git a/mysql-test/main/sql_mode.test b/mysql-test/main/sql_mode.test index 9f38dc935e7..8cf50f73f6f 100644 --- a/mysql-test/main/sql_mode.test +++ b/mysql-test/main/sql_mode.test @@ -554,3 +554,26 @@ BEGIN END; $$ DELIMITER ;$$ + +--echo # +--echo # End of 10.2 tests +--echo # + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-16471 mysqldump throws "Variable 'sql_mode' can't be set to the value of 'NULL' (1231)" +--echo # + +SET sql_mode='ORACLE,EMPTY_STRING_IS_NULL'; +SELECT @@sql_mode; +SELECT '' AS empty; +SET sql_mode=''; +SELECT @@sql_mode; +SET sql_mode=DEFAULT; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/main/statistics.result b/mysql-test/main/statistics.result index 8f87b166e8d..574eb5f4727 100644 --- a/mysql-test/main/statistics.result +++ b/mysql-test/main/statistics.result @@ -1086,6 +1086,9 @@ test t2 idx4 3 1.1304 ANALYZE TABLE t2 PERSISTENT FOR COLUMNS() INDEXES ALL; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 test.t2 analyze status OK SELECT * FROM mysql.index_stats ORDER BY index_name, prefix_arity, table_name; db_name table_name index_name prefix_arity avg_frequency @@ -1146,6 +1149,11 @@ test t2 idx4 4 1.0000 ANALYZE TABLE t2 PERSISTENT FOR COLUMNS ALL INDEXES ALL; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected +test.t2 analyze Note Data truncated for column 'avg_length' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 test.t2 analyze status OK SELECT * FROM mysql.index_stats ORDER BY index_name, prefix_arity, table_name; db_name table_name index_name prefix_arity avg_frequency @@ -1171,6 +1179,8 @@ test t2 idx3 1 8.5000 ANALYZE TABLE t2 PERSISTENT FOR COLUMNS() INDEXES ALL; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 +test.t2 analyze Note Data truncated for column 'avg_frequency' at row 1 test.t2 analyze status OK SELECT * FROM mysql.index_stats ORDER BY index_name, prefix_arity, table_name; db_name table_name index_name prefix_arity avg_frequency @@ -1682,6 +1692,27 @@ set use_stat_tables=@save_use_stat_tables; set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; drop table t1,t2; # +# MDEV-16507: statistics for temporary tables should not be used +# +SET +@save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +SET @@use_stat_tables = preferably ; +SET @@optimizer_use_condition_selectivity = 4; +CREATE TABLE t1 ( +TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +ON UPDATE CURRENT_TIMESTAMP +); +SET @had_t1_table= @@warning_count != 0; +CREATE TEMPORARY TABLE tmp_t1 LIKE t1; +INSERT INTO tmp_t1 VALUES (now()); +INSERT INTO t1 SELECT * FROM tmp_t1 WHERE @had_t1_table=0; +DROP TABLE t1; +SET +use_stat_tables=@save_use_stat_tables; +SET +optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +# End of 10.0 tests +# # MDEV-9590: Always print "Engine-independent statistic" warnings and # might be filtering columns unintentionally from engines # diff --git a/mysql-test/main/statistics.test b/mysql-test/main/statistics.test index 368cee0f8c8..b2e544064b0 100644 --- a/mysql-test/main/statistics.test +++ b/mysql-test/main/statistics.test @@ -819,6 +819,32 @@ set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivi drop table t1,t2; --echo # +--echo # MDEV-16507: statistics for temporary tables should not be used +--echo # + +SET +@save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +SET @@use_stat_tables = preferably ; +SET @@optimizer_use_condition_selectivity = 4; + +CREATE TABLE t1 ( + TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + ON UPDATE CURRENT_TIMESTAMP +); + +SET @had_t1_table= @@warning_count != 0; +CREATE TEMPORARY TABLE tmp_t1 LIKE t1; +INSERT INTO tmp_t1 VALUES (now()); +INSERT INTO t1 SELECT * FROM tmp_t1 WHERE @had_t1_table=0; +DROP TABLE t1; + +SET +use_stat_tables=@save_use_stat_tables; +SET +optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +--echo # End of 10.0 tests + +--echo # --echo # MDEV-9590: Always print "Engine-independent statistic" warnings and --echo # might be filtering columns unintentionally from engines --echo # diff --git a/mysql-test/main/subselect_mat_cost_bugs.result b/mysql-test/main/subselect_mat_cost_bugs.result index 125da8da517..658722112d2 100644 --- a/mysql-test/main/subselect_mat_cost_bugs.result +++ b/mysql-test/main/subselect_mat_cost_bugs.result @@ -334,7 +334,7 @@ SELECT * FROM t1 WHERE (f1) IN (SELECT f1 FROM t2) LIMIT 0; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Zero limit 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where SELECT * FROM t1 WHERE (f1) IN (SELECT f1 FROM t2) diff --git a/mysql-test/main/subselect_sj2_mat.result b/mysql-test/main/subselect_sj2_mat.result index 6a1f310511f..62248536e34 100644 --- a/mysql-test/main/subselect_sj2_mat.result +++ b/mysql-test/main/subselect_sj2_mat.result @@ -1670,3 +1670,150 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 11 func 1 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where DROP TABLE t1,t2; +# +# MDEV-16225: wrong resultset from query with semijoin=on +# +CREATE TABLE t1 ( +`id` int(10) NOT NULL AUTO_INCREMENT, +`local_name` varchar(64) NOT NULL, +PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; +insert into t1(`id`,`local_name`) values +(1,'Cash Advance'), +(2,'Cash Advance'), +(3,'Rollover'), +(4,'AL Installment'), +(5,'AL Installment'), +(6,'AL Installment'), +(7,'AL Installment'), +(8,'AL Installment'), +(9,'AL Installment'), +(10,'Internet Payday'), +(11,'Rollover - Internet Payday'), +(12,'AL Monthly Installment'), +(13,'AL Semi-Monthly Installment'); +explain +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( +t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) +OR +(t.id IN (0,4,12,13,1,10,3,11)) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t index PRIMARY PRIMARY 4 NULL 13 Using where; Using index +2 MATERIALIZED <subquery3> ALL distinct_key NULL NULL NULL 8 +2 MATERIALIZED A ALL PRIMARY NULL NULL NULL 13 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED B ALL PRIMARY NULL NULL NULL 13 Using where +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( +t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) +OR +(t.id IN (0,4,12,13,1,10,3,11)) +); +id +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +drop table t1; +# +# MDEV-15247: Crash when SET NAMES 'utf8' is set +# +CREATE TABLE t1 ( +id_category int unsigned, +id_product int unsigned, +PRIMARY KEY (id_category,id_product) +) ENGINE=MyISAM; +INSERT INTO `t1` VALUES (31,216), (31,215), (31,214), (31,213), (31,212), (32,211), (32,210), (32,209), (32,208), (29,207), (30,315372), (2,161), (2,132), (33,315380), (31,315371), (29,315370), (29,315373), (29,315369), (29,315374), (29,315368), (29,315375), (29,315367), (29,183), (29,182), (30,177), (29,315376), (13,315365), (2,167), (2,315357), (2,164), (2,159), (2,131), (2,127), (14,315364), (27,315363), (29,205), (29,204), (29,203), (29,202), (29,201), (29,200), (29,199), (29,198), (29,197), (29,196), (29,195), (29,194), (29,193), (29,192), (29,191), (29,190), (29,189), (14,188), (29,187), (29,186), (29,185), (29,184), (29,315377), (29,315378), (29,181), (33,315379), (29,179), (30,178), (29,180), (30,176), (30,175), (30,174), (30,173), (30,172), (11,171), (27,315357), (23,108), (23,102); +CREATE TABLE t2 ( +id_product int, +id_t2 int, +KEY id_t2 (id_t2), +KEY id_product (id_product) +) ENGINE=MyISAM; +INSERT INTO `t2` VALUES (11,31), (11,31), (11,31), (11,32), (11,32), +(11,32), (10,26), (11,32), (10,28), (11,32), (10,29), (11,33), (10,26), +(11,33), (10,27), (9,23), (11,32), (10,26), (8,18), (7,15), (11,32), +(10,28), (11,32), (10,28), (11,32), (10,29), (11,32), (10,29), (8,19), +(7,16), (8,18), (7,16), (8,20), (7,16), (11,32), (10,28), (8,19), +(7,16), (8,20), (7,16), (11,32), (10,29), (8,19), (7,16), (8,20), +(7,16), (10,27), (9,23), (10,27), (9,23), (10,27), (9,23), (11,32), +(10,27), (11,32), (10,27), (8,18), (7,15), (10,26), (9,24), (8,19), +(7,16), (10,26), (9,23), (8,19), (7,16), (8,18), (7,16), (8,18), (7,16), +(9,23), (8,18), (9,23), (8,19), (7,16), (7,16), (8,19), (7,16), (11,31), +(10,27), (9,24), (11,31), (10,27), (9,23), (8,19), (11,31), (10,26), (9,24), +(8,19), (11,31), (10,26), (9,25), (8,18), (11,31), (10,26), (9,23), (8,19), +(11,31), (10,26), (9,23), (8,18), (11,31), (10,30), (9,23), (8,18), (11,31), +(10,30), (9,23), (8,19), (11,31), (10,26), (9,25), (8,19), (8,21), (11,32), +(10,26), (9,22), (8,19), (11,32), (10,26), (9,22), (8,18), (11,32), (10,26), +(9,22), (8,20), (11,33), (10,26), (9,22), (8,19), (11,33), (10,26), (9,22), +(8,18), (11,33), (10,26), (9,22), (8,20), (11,32), (10,26), (9,24), (8,19), +(11,32), (10,26), (9,25), (8,19), (11,32), (10,26), (9,25), (8,18), (11,32), +(10,26), (9,23), (8,18), (11,32), (10,30), (9,23), (8,18), (11,32), (10,30), +(9,23), (8,19), (11,32), (10,26), (9,23), (8,19), (11,32), (10,27), (9,23), +(11,32), (10,27), (9,23), (11,32), (10,27), (9,23), (10,26), (9,22), (8,19), +(7,15), (10,26), (9,22), (8,20), (7,15), (10,26), (9,22), (8,18), (7,15), +(8,19), (10,26), (10,26), (11,33), (10,26), (11,33), (10,26), (11,33), +(10,27), (11,33), (10,27), (11,31), (10,26), (11,31), (10,26), (8,18), +(7,15), (9,23), (9,23), (9,24), (8,21), (7,15), (7,15), (7,15), (7,15), +(7,15), (7,15), (7,15), (7,15), (7,15), (8,18), (7,17), (8,18), (7,17), (8,19), (8,19); +CREATE TABLE t3 ( +id_product int unsigned, +PRIMARY KEY (id_product) +) ENGINE=MyISAM; +INSERT INTO t3 VALUES +(102),(103),(104),(105),(106),(107),(108),(109),(110), +(315371),(315373),(315374),(315375),(315376),(315377), +(315378),(315379),(315380); +CREATE TABLE t4 ( +id_product int not null, +id_shop int, +PRIMARY KEY (id_product,id_shop) +) ENGINE=MyISAM ; +INSERT INTO t4 VALUES +(202,1),(201,1),(200,1),(199,1),(198,1),(197,1),(196,1),(195,1), +(194,1),(193,1),(192,1),(191,1),(190,1),(189,1),(188,1),(187,1), +(186,1),(185,1),(184,1),(183,1),(182,1),(181,1),(179,1),(178,1), +(177,1),(176,1),(126,1),(315380,1); +CREATE TABLE t5 (id_product int) ENGINE=MyISAM; +INSERT INTO `t5` VALUES +(652),(668),(669),(670),(671),(673),(674),(675),(676), +(677),(679),(680),(681),(682),(683),(684),(685),(686); +explain +SELECT * FROM t3 +JOIN t4 ON (t4.id_product = t3.id_product AND t4.id_shop = 1) +JOIN t1 ON (t1.id_product = t3.id_product) +LEFT JOIN t5 ON (t5.id_product = t3.id_product) +WHERE 1=1 +AND t3.id_product IN (SELECT id_product FROM t2 t2_1 WHERE t2_1.id_t2 = 32) +AND t3.id_product IN (SELECT id_product FROM t2 t2_2 WHERE t2_2.id_t2 = 15) +AND t3.id_product IN (SELECT id_product FROM t2 t2_3 WHERE t2_3.id_t2 = 18 OR t2_3.id_t2 = 19) +AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2_4.id_t2 = 23) +AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 8 NULL 73 Using index +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.id_product 1 Using index +1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t4 eq_ref PRIMARY PRIMARY 8 test.t1.id_product,const 1 Using where; Using index +1 PRIMARY <subquery6> eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where +4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 32 Using index condition; Using where +3 MATERIALIZED t2_2 ref id_t2,id_product id_t2 5 const 12 +2 MATERIALIZED t2_1 ref id_t2,id_product id_t2 5 const 50 +6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 30 Using index condition; Using where +drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/main/subselect_sj2_mat.test b/mysql-test/main/subselect_sj2_mat.test index 0234f0cb7b6..bba436078e3 100644 --- a/mysql-test/main/subselect_sj2_mat.test +++ b/mysql-test/main/subselect_sj2_mat.test @@ -303,3 +303,132 @@ eval $q; eval explain $q; DROP TABLE t1,t2; + +--echo # +--echo # MDEV-16225: wrong resultset from query with semijoin=on +--echo # + +CREATE TABLE t1 ( + `id` int(10) NOT NULL AUTO_INCREMENT, + `local_name` varchar(64) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; + +insert into t1(`id`,`local_name`) values +(1,'Cash Advance'), +(2,'Cash Advance'), +(3,'Rollover'), +(4,'AL Installment'), +(5,'AL Installment'), +(6,'AL Installment'), +(7,'AL Installment'), +(8,'AL Installment'), +(9,'AL Installment'), +(10,'Internet Payday'), +(11,'Rollover - Internet Payday'), +(12,'AL Monthly Installment'), +(13,'AL Semi-Monthly Installment'); + +explain +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( + t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) + OR + (t.id IN (0,4,12,13,1,10,3,11)) +); +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( + t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) + OR + (t.id IN (0,4,12,13,1,10,3,11)) +); +drop table t1; + +--echo # +--echo # MDEV-15247: Crash when SET NAMES 'utf8' is set +--echo # + +CREATE TABLE t1 ( + id_category int unsigned, + id_product int unsigned, + PRIMARY KEY (id_category,id_product) +) ENGINE=MyISAM; + +INSERT INTO `t1` VALUES (31,216), (31,215), (31,214), (31,213), (31,212), (32,211), (32,210), (32,209), (32,208), (29,207), (30,315372), (2,161), (2,132), (33,315380), (31,315371), (29,315370), (29,315373), (29,315369), (29,315374), (29,315368), (29,315375), (29,315367), (29,183), (29,182), (30,177), (29,315376), (13,315365), (2,167), (2,315357), (2,164), (2,159), (2,131), (2,127), (14,315364), (27,315363), (29,205), (29,204), (29,203), (29,202), (29,201), (29,200), (29,199), (29,198), (29,197), (29,196), (29,195), (29,194), (29,193), (29,192), (29,191), (29,190), (29,189), (14,188), (29,187), (29,186), (29,185), (29,184), (29,315377), (29,315378), (29,181), (33,315379), (29,179), (30,178), (29,180), (30,176), (30,175), (30,174), (30,173), (30,172), (11,171), (27,315357), (23,108), (23,102); + +CREATE TABLE t2 ( + id_product int, + id_t2 int, + KEY id_t2 (id_t2), + KEY id_product (id_product) +) ENGINE=MyISAM; + +INSERT INTO `t2` VALUES (11,31), (11,31), (11,31), (11,32), (11,32), +(11,32), (10,26), (11,32), (10,28), (11,32), (10,29), (11,33), (10,26), +(11,33), (10,27), (9,23), (11,32), (10,26), (8,18), (7,15), (11,32), +(10,28), (11,32), (10,28), (11,32), (10,29), (11,32), (10,29), (8,19), +(7,16), (8,18), (7,16), (8,20), (7,16), (11,32), (10,28), (8,19), +(7,16), (8,20), (7,16), (11,32), (10,29), (8,19), (7,16), (8,20), +(7,16), (10,27), (9,23), (10,27), (9,23), (10,27), (9,23), (11,32), +(10,27), (11,32), (10,27), (8,18), (7,15), (10,26), (9,24), (8,19), +(7,16), (10,26), (9,23), (8,19), (7,16), (8,18), (7,16), (8,18), (7,16), +(9,23), (8,18), (9,23), (8,19), (7,16), (7,16), (8,19), (7,16), (11,31), +(10,27), (9,24), (11,31), (10,27), (9,23), (8,19), (11,31), (10,26), (9,24), +(8,19), (11,31), (10,26), (9,25), (8,18), (11,31), (10,26), (9,23), (8,19), +(11,31), (10,26), (9,23), (8,18), (11,31), (10,30), (9,23), (8,18), (11,31), +(10,30), (9,23), (8,19), (11,31), (10,26), (9,25), (8,19), (8,21), (11,32), +(10,26), (9,22), (8,19), (11,32), (10,26), (9,22), (8,18), (11,32), (10,26), +(9,22), (8,20), (11,33), (10,26), (9,22), (8,19), (11,33), (10,26), (9,22), +(8,18), (11,33), (10,26), (9,22), (8,20), (11,32), (10,26), (9,24), (8,19), +(11,32), (10,26), (9,25), (8,19), (11,32), (10,26), (9,25), (8,18), (11,32), +(10,26), (9,23), (8,18), (11,32), (10,30), (9,23), (8,18), (11,32), (10,30), +(9,23), (8,19), (11,32), (10,26), (9,23), (8,19), (11,32), (10,27), (9,23), +(11,32), (10,27), (9,23), (11,32), (10,27), (9,23), (10,26), (9,22), (8,19), +(7,15), (10,26), (9,22), (8,20), (7,15), (10,26), (9,22), (8,18), (7,15), +(8,19), (10,26), (10,26), (11,33), (10,26), (11,33), (10,26), (11,33), +(10,27), (11,33), (10,27), (11,31), (10,26), (11,31), (10,26), (8,18), +(7,15), (9,23), (9,23), (9,24), (8,21), (7,15), (7,15), (7,15), (7,15), +(7,15), (7,15), (7,15), (7,15), (7,15), (8,18), (7,17), (8,18), (7,17), (8,19), (8,19); + +CREATE TABLE t3 ( + id_product int unsigned, + PRIMARY KEY (id_product) +) ENGINE=MyISAM; + +INSERT INTO t3 VALUES +(102),(103),(104),(105),(106),(107),(108),(109),(110), +(315371),(315373),(315374),(315375),(315376),(315377), +(315378),(315379),(315380); + +CREATE TABLE t4 ( + id_product int not null, + id_shop int, + PRIMARY KEY (id_product,id_shop) +) ENGINE=MyISAM ; + +INSERT INTO t4 VALUES +(202,1),(201,1),(200,1),(199,1),(198,1),(197,1),(196,1),(195,1), +(194,1),(193,1),(192,1),(191,1),(190,1),(189,1),(188,1),(187,1), +(186,1),(185,1),(184,1),(183,1),(182,1),(181,1),(179,1),(178,1), +(177,1),(176,1),(126,1),(315380,1); + +CREATE TABLE t5 (id_product int) ENGINE=MyISAM; +INSERT INTO `t5` VALUES +(652),(668),(669),(670),(671),(673),(674),(675),(676), +(677),(679),(680),(681),(682),(683),(684),(685),(686); + +explain +SELECT * FROM t3 + JOIN t4 ON (t4.id_product = t3.id_product AND t4.id_shop = 1) + JOIN t1 ON (t1.id_product = t3.id_product) +LEFT JOIN t5 ON (t5.id_product = t3.id_product) +WHERE 1=1 +AND t3.id_product IN (SELECT id_product FROM t2 t2_1 WHERE t2_1.id_t2 = 32) +AND t3.id_product IN (SELECT id_product FROM t2 t2_2 WHERE t2_2.id_t2 = 15) +AND t3.id_product IN (SELECT id_product FROM t2 t2_3 WHERE t2_3.id_t2 = 18 OR t2_3.id_t2 = 19) +AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2_4.id_t2 = 23) +AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26); + +drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/main/subselect_sj_nonmerged.result b/mysql-test/main/subselect_sj_nonmerged.result index c7e04225ffe..47970668ae5 100644 --- a/mysql-test/main/subselect_sj_nonmerged.result +++ b/mysql-test/main/subselect_sj_nonmerged.result @@ -77,9 +77,9 @@ explain select * from t4 where t4.a in (select max(t2.a) from t1, t2 group by t2.b) and t4.b in (select max(t2.a) from t1, t2 group by t2.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 -1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using join buffer (flat, BNL join) -1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12 +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 +1 PRIMARY t4 ref a a 5 <subquery2>.max(t2.a) 12 Using index condition +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 test.t4.b 1 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 3 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary diff --git a/mysql-test/main/type_bit.result b/mysql-test/main/type_bit.result index 30cd94c9277..eeedc501dc4 100644 --- a/mysql-test/main/type_bit.result +++ b/mysql-test/main/type_bit.result @@ -830,3 +830,22 @@ def COALESCE(val, 1) 246 2 1 Y 32896 0 63 COALESCE(val, 1) 0 DROP TABLE t1; +# +# End of 10.1 tests +# +# +# Start of 10.2 tests +# +# +# MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result +# +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED)); +ALTER TABLE t1 MODIFY a BIT(64); +SELECT a+0 FROM t1; +a+0 +18446744073709551615 +DROP TABLE IF EXISTS t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/main/type_bit.test b/mysql-test/main/type_bit.test index bb282fc15e5..04db1511833 100644 --- a/mysql-test/main/type_bit.test +++ b/mysql-test/main/type_bit.test @@ -458,3 +458,28 @@ DROP TABLE t2; SELECT COALESCE(val, 1) FROM t1; --disable_metadata DROP TABLE t1; + +--echo # +--echo # End of 10.1 tests +--echo # + + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result +--echo # + +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED)); +ALTER TABLE t1 MODIFY a BIT(64); +SELECT a+0 FROM t1; +DROP TABLE IF EXISTS t1; + + +--echo # +--echo # End of 10.2 tests +--echo # + diff --git a/mysql-test/main/type_blob.result b/mysql-test/main/type_blob.result index 569ba65df3f..3c99366168c 100644 --- a/mysql-test/main/type_blob.result +++ b/mysql-test/main/type_blob.result @@ -1063,3 +1063,19 @@ DROP TABLE t1; # # End of 5.5 tests # +# +# Start of 10.2 test +# +# +# MDEV-12809 Bad column type created for TEXT(1431655798) CHARACTER SET utf8 +# +CREATE TABLE t1 (a TEXT(1431655798) CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` longtext CHARACTER SET utf8 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +# +# End of 10.2 test +# diff --git a/mysql-test/main/type_blob.test b/mysql-test/main/type_blob.test index 8db6ac6da2a..2c74d4ea241 100644 --- a/mysql-test/main/type_blob.test +++ b/mysql-test/main/type_blob.test @@ -680,3 +680,21 @@ DROP TABLE t1; --echo # --echo # End of 5.5 tests --echo # + + +--echo # +--echo # Start of 10.2 test +--echo # + +--echo # +--echo # MDEV-12809 Bad column type created for TEXT(1431655798) CHARACTER SET utf8 +--echo # + +CREATE TABLE t1 (a TEXT(1431655798) CHARACTER SET utf8); +SHOW CREATE TABLE t1; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 test +--echo # diff --git a/mysql-test/main/type_decimal.result b/mysql-test/main/type_decimal.result index 4d0f6fc12fd..aed56164a39 100644 --- a/mysql-test/main/type_decimal.result +++ b/mysql-test/main/type_decimal.result @@ -1033,6 +1033,31 @@ c1 c2 0.123456 0.123456 SET sql_mode=DEFAULT; # +# MDEV-12574 MAX(old_decimal) produces a column of the old DECIMAL type +# +SHOW CREATE TABLE t1dec102; +Table Create Table +t1dec102 CREATE TABLE `t1dec102` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE TABLE t1 AS SELECT a, MAX(a), COALESCE(a) FROM t1dec102; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2) DEFAULT NULL, + `MAX(a)` decimal(10,2) DEFAULT NULL, + `COALESCE(a)` decimal(10,2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1dec102; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +DROP TABLE t1dec102; +# # End of 10.2 tests # # @@ -1046,7 +1071,7 @@ CREATE TABLE t1 AS SELECT MAX(a) FROM t1dec102; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `MAX(a)` decimal(10,2)/*old*/ DEFAULT NULL + `MAX(a)` decimal(10,2) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 AS SELECT COALESCE(a) FROM t1dec102; diff --git a/mysql-test/main/type_decimal.test b/mysql-test/main/type_decimal.test index dd4ba5df40d..3921e86a940 100644 --- a/mysql-test/main/type_decimal.test +++ b/mysql-test/main/type_decimal.test @@ -628,6 +628,27 @@ SELECT SET sql_mode=DEFAULT; --echo # +--echo # MDEV-12574 MAX(old_decimal) produces a column of the old DECIMAL type +--echo # + +let $MYSQLD_DATADIR= `select @@datadir`; +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1dec102.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1dec102.MYI + +SHOW CREATE TABLE t1dec102; + +CREATE TABLE t1 AS SELECT a, MAX(a), COALESCE(a) FROM t1dec102; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1dec102; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +DROP TABLE t1dec102; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/type_int.result b/mysql-test/main/type_int.result index 348d72b125b..9fe045172f8 100644 --- a/mysql-test/main/type_int.result +++ b/mysql-test/main/type_int.result @@ -91,6 +91,19 @@ a 10 DROP TABLE t1; # +# MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result +# +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED)); +SELECT * FROM t1; +a +18446744073709551615 +ALTER TABLE t1 MODIFY a BIGINT UNSIGNED; +SELECT * FROM t1; +a +18446744073709551615 +DROP TABLE t1; +# # End of 10.2 tests # # diff --git a/mysql-test/main/type_int.test b/mysql-test/main/type_int.test index f340d9a72bd..b3fe250d1b8 100644 --- a/mysql-test/main/type_int.test +++ b/mysql-test/main/type_int.test @@ -74,6 +74,18 @@ SELECT * FROM t1; DROP TABLE t1; --echo # +--echo # MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result +--echo # + +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED)); +SELECT * FROM t1; +ALTER TABLE t1 MODIFY a BIGINT UNSIGNED; +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 3d56cd8e435..7607cebc3a5 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3317,3 +3317,20 @@ DROP TABLE t1,t2; # # Start of 10.3 tests # +# +# MDEV-16489 when lead() returns null on a datetime field, the result is treated as the literal string '[NULL]' +# +CREATE TABLE t1 (d datetime); +INSERT INTO t1 VALUES ('2018-01-01 00:00:00'),('2018-02-01 00:00:00'); +SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; +d x +2018-01-01 00:00:00 2018-02-01 00:00:00 +2018-02-01 00:00:00 NULL +DROP TABLE t1; +CREATE TABLE t1 (d time); +INSERT INTO t1 VALUES ('00:00:01'),('00:00:02'); +SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; +d x +00:00:01 00:00:02 +00:00:02 NULL +DROP TABLE t1; diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index d483cdbaa83..4b73f70d737 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2086,3 +2086,17 @@ DROP TABLE t1,t2; --echo # --echo # Start of 10.3 tests --echo # + +--echo # +--echo # MDEV-16489 when lead() returns null on a datetime field, the result is treated as the literal string '[NULL]' +--echo # + +CREATE TABLE t1 (d datetime); +INSERT INTO t1 VALUES ('2018-01-01 00:00:00'),('2018-02-01 00:00:00'); +SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (d time); +INSERT INTO t1 VALUES ('00:00:01'),('00:00:02'); +SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; +DROP TABLE t1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ddb79b925b6..6586e51dcd2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5727,7 +5727,7 @@ sub lldb_arguments { $input = $input ? "< $input" : ""; # write init file for mysqld or client - mtr_tofile($lldb_init_file, "set args $str $input\n"); + mtr_tofile($lldb_init_file, "process launch --stop-at-entry -- $str $input\n"); print "\nTo start lldb for $type, type in another window:\n"; print "cd $glob_mysql_test_dir && lldb -s $lldb_init_file $$exe\n"; diff --git a/mysql-test/std_data/frm/t1.frm b/mysql-test/std_data/frm/t1.frm Binary files differnew file mode 100644 index 00000000000..a998f54ec67 --- /dev/null +++ b/mysql-test/std_data/frm/t1.frm diff --git a/mysql-test/suite/compat/oracle/r/parser.result b/mysql-test/suite/compat/oracle/r/parser.result index 28ed8eb8185..c8600c29bd4 100644 --- a/mysql-test/suite/compat/oracle/r/parser.result +++ b/mysql-test/suite/compat/oracle/r/parser.result @@ -448,3 +448,54 @@ BEGIN SELECT precedes INTO precedes FROM DUAL; END; / +# +# MDEV-16464 Oracle Comp.: Sql-Error on "SELECT name, comment FROM mysql.proc" +# +SET sql_mode=ORACLE; +SELECT name, comment FROM mysql.proc WHERE db='test'; +name comment +CREATE TABLE comment (comment INT); +SELECT comment FROM comment; +comment +SELECT comment comment FROM comment comment; +comment +SELECT comment AS comment FROM comment AS comment; +comment +DROP TABLE comment; +DECLARE +comment INT; +BEGIN +SELECT comment INTO comment FROM DUAL; +END; +/ +CREATE PROCEDURE comment COMMENT 'test' AS +BEGIN +SELECT 1; +END; +/ +BEGIN +comment; +END; +/ +1 +1 +CALL comment(); +1 +1 +CALL comment; +1 +1 +DROP PROCEDURE comment; +CREATE FUNCTION comment RETURN INT COMMENT 'test' AS +BEGIN +RETURN 1; +END; +/ +Warnings: +Note 1585 This function 'comment' has the same name as a native function +SELECT test.comment() FROM DUAL; +test.comment() +1 +Warnings: +Note 1585 This function 'comment' has the same name as a native function +DROP FUNCTION comment; diff --git a/mysql-test/suite/compat/oracle/r/sp-code.result b/mysql-test/suite/compat/oracle/r/sp-code.result index f1dd4180854..1049563511c 100644 --- a/mysql-test/suite/compat/oracle/r/sp-code.result +++ b/mysql-test/suite/compat/oracle/r/sp-code.result @@ -1084,23 +1084,26 @@ Pos Instruction 10 stmt 0 "SELECT rec1.a, rec1.b" 11 cfetch cur1@1 rec1@0 12 jump 6 -13 cursor_copy_struct cur0 rec0@1 -14 copen cur0@0 -15 cfetch cur0@0 rec0@1 -16 jump_if_not 21(21) "cur0"%FOUND -17 set rec0.a@1["a"] 10 -18 set rec0.b@1["b"] 'b0' -19 cfetch cur0@0 rec0@1 -20 jump 16 -21 cursor_copy_struct cur2 rec2@2 -22 copen cur2@2 -23 cfetch cur2@2 rec2@2 -24 jump_if_not 29(29) "cur2"%FOUND -25 set rec2.a@2["a"] 10 -26 set rec2.b@2["b"] 'b0' -27 cfetch cur2@2 rec2@2 -28 jump 24 -29 cpop 3 +13 cclose cur1@1 +14 cursor_copy_struct cur0 rec0@1 +15 copen cur0@0 +16 cfetch cur0@0 rec0@1 +17 jump_if_not 22(22) "cur0"%FOUND +18 set rec0.a@1["a"] 10 +19 set rec0.b@1["b"] 'b0' +20 cfetch cur0@0 rec0@1 +21 jump 17 +22 cclose cur0@0 +23 cursor_copy_struct cur2 rec2@2 +24 copen cur2@2 +25 cfetch cur2@2 rec2@2 +26 jump_if_not 31(31) "cur2"%FOUND +27 set rec2.a@2["a"] 10 +28 set rec2.b@2["b"] 'b0' +29 cfetch cur2@2 rec2@2 +30 jump 26 +31 cclose cur2@2 +32 cpop 3 DROP PROCEDURE p1; CREATE PROCEDURE p1 AS @@ -1137,14 +1140,14 @@ Pos Instruction 1 cursor_copy_struct cur0 rec0@0 2 copen cur0@0 3 cfetch cur0@0 rec0@0 -4 jump_if_not 29(29) "cur0"%FOUND +4 jump_if_not 31(31) "cur0"%FOUND 5 cpush cur1@1 6 set rec0.a@0["a"] 11 7 set rec0.b@0["b"] 'b0' 8 cursor_copy_struct cur1 rec1@1 9 copen cur1@1 10 cfetch cur1@1 rec1@1 -11 jump_if_not 26(26) "cur1"%FOUND +11 jump_if_not 27(27) "cur1"%FOUND 12 set rec1.a@1["a"] 11 13 set rec1.b@1["b"] 'b1' 14 cpush cur2@2 @@ -1156,13 +1159,16 @@ Pos Instruction 20 set rec2.b@2["b"] 'b2' 21 cfetch cur2@2 rec2@2 22 jump 18 -23 cpop 1 -24 cfetch cur1@1 rec1@1 -25 jump 11 -26 cpop 1 -27 cfetch cur0@0 rec0@0 -28 jump 4 -29 cpop 1 +23 cclose cur2@2 +24 cpop 1 +25 cfetch cur1@1 rec1@1 +26 jump 11 +27 cclose cur1@1 +28 cpop 1 +29 cfetch cur0@0 rec0@0 +30 jump 4 +31 cclose cur0@0 +32 cpop 1 DROP PROCEDURE p1; # # MDEV-12098 sql_mode=ORACLE: Implicit cursor FOR loop diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result index a46daf30a8f..093d52ba4e3 100644 --- a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result +++ b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result @@ -1331,6 +1331,93 @@ rec2.a rec2.b DROP PROCEDURE p1; DROP TABLE t1; # +# MDEV-15941 Explicit cursor FOR loop does not close the cursor +# +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +v INT; +BEGIN +FOR rec IN cur +LOOP +NULL; +END LOOP; +FETCH cur INTO v; +END; +$$ +ERROR 24000: Cursor is not open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +v INT; +BEGIN +<<label>> +FOR rec IN cur +LOOP +NULL; +END LOOP label; +FETCH cur INTO v; +END; +$$ +ERROR 24000: Cursor is not open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +OPEN cur; +FOR rec IN cur +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 24000: Cursor is already open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP; +SELECT cur%ISOPEN; +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP; +SELECT cur%ISOPEN; +END; +$$ +rec.a +1 +cur%ISOPEN +0 +rec.a +1 +cur%ISOPEN +0 +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +<<label1>> +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP label1; +SELECT cur%ISOPEN; +<<label2>> +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP; +SELECT cur%ISOPEN; +END; +$$ +rec.a +1 +cur%ISOPEN +0 +rec.a +1 +cur%ISOPEN +0 +# # MDEV-14139 Anchored data types for variables # DECLARE diff --git a/mysql-test/suite/compat/oracle/t/parser.test b/mysql-test/suite/compat/oracle/t/parser.test index a8f5eda7016..86b6b270ccd 100644 --- a/mysql-test/suite/compat/oracle/t/parser.test +++ b/mysql-test/suite/compat/oracle/t/parser.test @@ -208,3 +208,53 @@ END; / DELIMITER ;/ + + +--echo # +--echo # MDEV-16464 Oracle Comp.: Sql-Error on "SELECT name, comment FROM mysql.proc" +--echo # + +SET sql_mode=ORACLE; +SELECT name, comment FROM mysql.proc WHERE db='test'; + +CREATE TABLE comment (comment INT); +SELECT comment FROM comment; +SELECT comment comment FROM comment comment; +SELECT comment AS comment FROM comment AS comment; +DROP TABLE comment; + +DELIMITER /; +DECLARE + comment INT; +BEGIN + SELECT comment INTO comment FROM DUAL; +END; +/ +DELIMITER ;/ + +DELIMITER /; +CREATE PROCEDURE comment COMMENT 'test' AS +BEGIN + SELECT 1; +END; +/ +BEGIN + comment; +END; +/ +DELIMITER ;/ +CALL comment(); +CALL comment; +DROP PROCEDURE comment; + +DELIMITER /; +CREATE FUNCTION comment RETURN INT COMMENT 'test' AS +BEGIN + RETURN 1; +END; +/ +DELIMITER ;/ +enable_prepare_warnings; +SELECT test.comment() FROM DUAL; +disable_prepare_warnings; +DROP FUNCTION comment; diff --git a/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test b/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test index fd148d1f261..31e28d5c8de 100644 --- a/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test +++ b/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test @@ -1425,6 +1425,98 @@ DROP TABLE t1; --echo # +--echo # MDEV-15941 Explicit cursor FOR loop does not close the cursor +--echo # + +DELIMITER $$; +--error ER_SP_CURSOR_NOT_OPEN +DECLARE + CURSOR cur IS SELECT 1 AS a FROM DUAL; + v INT; +BEGIN + FOR rec IN cur + LOOP + NULL; + END LOOP; + FETCH cur INTO v; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_SP_CURSOR_NOT_OPEN +DECLARE + CURSOR cur IS SELECT 1 AS a FROM DUAL; + v INT; +BEGIN +<<label>> + FOR rec IN cur + LOOP + NULL; + END LOOP label; + FETCH cur INTO v; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_SP_CURSOR_ALREADY_OPEN +DECLARE + CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN + OPEN cur; + FOR rec IN cur + LOOP + NULL; + END LOOP; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +DECLARE + CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN + FOR rec IN cur + LOOP + SELECT rec.a; + END LOOP; + SELECT cur%ISOPEN; + FOR rec IN cur + LOOP + SELECT rec.a; + END LOOP; + SELECT cur%ISOPEN; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +DECLARE + CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +<<label1>> + FOR rec IN cur + LOOP + SELECT rec.a; + END LOOP label1; + SELECT cur%ISOPEN; +<<label2>> + FOR rec IN cur + LOOP + SELECT rec.a; + END LOOP; + SELECT cur%ISOPEN; +END; +$$ +DELIMITER ;$$ + + +--echo # --echo # MDEV-14139 Anchored data types for variables --echo # diff --git a/mysql-test/suite/encryption/disabled.def b/mysql-test/suite/encryption/disabled.def index 9777a4ac99a..d92d3495cb8 100644 --- a/mysql-test/suite/encryption/disabled.def +++ b/mysql-test/suite/encryption/disabled.def @@ -12,5 +12,3 @@ innodb_scrub : MDEV-8139 scrubbing does not work reliably innodb_scrub_background : MDEV-8139 scrubbing does not work reliably -innodb-redo-badkey : MDEV-13893 / MDEV-12699 Improve crash recovery of corrupted data pages - diff --git a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result index 251ea73cd4c..cc9d385bbbd 100644 --- a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result +++ b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result @@ -1,7 +1,7 @@ call mtr.add_suppression("mysqld: File .*"); call mtr.add_suppression("Plugin 'file_key_management' .*"); call mtr.add_suppression("InnoDB: cannot enable encryption, encryption plugin is not available"); -call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error\\."); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); call mtr.add_suppression("InnoDB: The page \\[page id: space=[0-9]+, page number=[0-9]+\\] in file '.*test.t[1-4]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); diff --git a/mysql-test/suite/encryption/t/innodb-discard-import.test b/mysql-test/suite/encryption/t/innodb-discard-import.test index e105cf82b67..62dafec4eba 100644 --- a/mysql-test/suite/encryption/t/innodb-discard-import.test +++ b/mysql-test/suite/encryption/t/innodb-discard-import.test @@ -1,10 +1,6 @@ -- source include/have_innodb.inc +-- source include/innodb_page_size_small.inc -- source include/have_file_key_management_plugin.inc -# embedded does not support restart --- source include/not_embedded.inc --- source include/not_valgrind.inc -# Avoid CrashReporter popup on Mac --- source include/not_crashrep.inc # # MDEV-8770: Incorrect error message when importing page compressed tablespace @@ -28,7 +24,9 @@ create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes en show warnings; create table t2(c1 bigint not null, b char(200)) engine=innodb page_compressed=1 encrypted=yes encryption_key_id=4; show warnings; -create table t3(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=4; +let $kbs= `select floor(@@global.innodb_page_size/1024)`; +--replace_regex / key_block_size=\d+//i +eval create table t3(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=4 key_block_size=$kbs; show warnings; create table t4(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; show warnings; @@ -89,6 +87,7 @@ ALTER TABLE t2 IMPORT TABLESPACE; SHOW CREATE TABLE t2; SELECT COUNT(*) FROM t2; ALTER TABLE t3 IMPORT TABLESPACE; +--replace_regex / key_block_size=\d+//i SHOW CREATE TABLE t3; SELECT COUNT(*) FROM t3; ALTER TABLE t4 IMPORT TABLESPACE; @@ -118,5 +117,5 @@ DROP TABLE t1,t2,t3,t4; # reset system --disable_query_log -EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algo; +eval SET GLOBAL innodb_compression_algorithm = $innodb_compression_algo; --enable_query_log diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.test b/mysql-test/suite/encryption/t/innodb-missing-key.test index 17059cc093d..cf851a54def 100644 --- a/mysql-test/suite/encryption/t/innodb-missing-key.test +++ b/mysql-test/suite/encryption/t/innodb-missing-key.test @@ -61,5 +61,3 @@ SELECT COUNT(1) FROM t2; SELECT COUNT(1) FROM t3; DROP TABLE t1, t2, t3; - - diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test index 37565ab4827..66720eb8585 100644 --- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test +++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test @@ -6,7 +6,7 @@ call mtr.add_suppression("mysqld: File .*"); call mtr.add_suppression("Plugin 'file_key_management' .*"); call mtr.add_suppression("InnoDB: cannot enable encryption, encryption plugin is not available"); -call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error\\."); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); call mtr.add_suppression("InnoDB: The page \\[page id: space=[0-9]+, page number=[0-9]+\\] in file '.*test.t[1-4]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); diff --git a/mysql-test/suite/federated/have_federatedx.inc b/mysql-test/suite/federated/have_federatedx.inc index 56ce31f5b2f..2250dd205bd 100644 --- a/mysql-test/suite/federated/have_federatedx.inc +++ b/mysql-test/suite/federated/have_federatedx.inc @@ -1,5 +1,5 @@ if (!`SELECT count(*) FROM information_schema.plugins WHERE plugin_name = 'federated' AND plugin_status = 'active' AND - plugin_description LIKE '%FederatedX%'`){ + plugin_description LIKE '%transactions%'`){ skip Need FederatedX engine; } diff --git a/mysql-test/suite/funcs_1/r/is_engines_archive.result b/mysql-test/suite/funcs_1/r/is_engines_archive.result index 2772992495c..52802b17acd 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_archive.result +++ b/mysql-test/suite/funcs_1/r/is_engines_archive.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'ARCHIVE'; ENGINE ARCHIVE SUPPORT YES -COMMENT Archive storage engine +COMMENT gzip-compresses tables for a low storage footprint TRANSACTIONS NO XA NO SAVEPOINTS NO diff --git a/mysql-test/suite/funcs_1/r/is_engines_csv.result b/mysql-test/suite/funcs_1/r/is_engines_csv.result index 2a7e61ee4d3..7e413b9af6f 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_csv.result +++ b/mysql-test/suite/funcs_1/r/is_engines_csv.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'CSV'; ENGINE CSV SUPPORT YES -COMMENT CSV storage engine +COMMENT Stores tables as CSV files TRANSACTIONS NO XA NO SAVEPOINTS NO diff --git a/mysql-test/suite/funcs_1/r/is_engines_federated.result b/mysql-test/suite/funcs_1/r/is_engines_federated.result index 8057a0266c5..20926458ed0 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_federated.result +++ b/mysql-test/suite/funcs_1/r/is_engines_federated.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'FEDERATED'; ENGINE FEDERATED SUPPORT YES -COMMENT FederatedX pluggable storage engine +COMMENT Allows to access tables on other MariaDB servers, supports transactions and more TRANSACTIONS YES XA NO SAVEPOINTS YES diff --git a/mysql-test/suite/funcs_1/r/is_engines_myisam.result b/mysql-test/suite/funcs_1/r/is_engines_myisam.result index 7e42c864187..d307ce4be6a 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_myisam.result +++ b/mysql-test/suite/funcs_1/r/is_engines_myisam.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'MyISAM'; ENGINE MyISAM SUPPORT DEFAULT -COMMENT MyISAM storage engine +COMMENT Non-transactional engine with good performance and small data footprint TRANSACTIONS NO XA NO SAVEPOINTS NO diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 58d7b6cc8be..322eff3506f 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -27,6 +27,9 @@ galera_ssl_upgrade : MDEV-13549 Galera test failures galera.MW-329 : wsrep_local_replays not stable galera.MW-328A : have_deadlocks test not stable query_cache : MDEV-15805 Test failure on galera.query_cache +MW-416 : MDEV-13549 Galera test failures +galera_wan : MDEV-13549 Galera test failures +MW-388 : MDEV-13549 Galera test failures galera.MW-44 : MDEV-15809 Test failure on galera.MW-44 galera.galera_pc_ignore_sb : MDEV-15811 Test failure on galera_pc_ignore_sb galera_kill_applier : race condition at the start of the test diff --git a/mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf b/mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf deleted file mode 100644 index f68fe524904..00000000000 --- a/mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf +++ /dev/null @@ -1,83 +0,0 @@ - -# -# Let's understand the topology. -# * Independent Master with server-id = 1 -# * Galera cluster with 2 nodes: node#1 and node#2 with server-id = 2, 3 -# node#1 act as slave to Independent Master with server-id = 1 -# * Independent Slave with server-id = 4 replicating from galera node#2 -# - -# Use default setting for mysqld processes -!include include/default_mysqld.cnf - -[mysqld] -log-slave-updates -log-bin=mysqld-bin -binlog-format=row -gtid-mode=on -enforce-gtid-consistency=true - -[mysqld.1] -server-id=1 - -[mysqld.2] -server-id=2 - -wsrep_provider=@ENV.WSREP_PROVIDER -wsrep_cluster_address='gcomm://' -wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.install_timeout = PT15S; evs.max_install_timeouts=1;' - -# enforce read-committed characteristics across the cluster -wsrep_causal_reads=ON -wsrep_sync_wait = 15 - -wsrep_node_address=127.0.0.1 -wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port -wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port - -# Required for Galera -innodb_autoinc_lock_mode=2 - -innodb_flush_log_at_trx_commit=2 - -[mysqld.3] -server-id=3 - -wsrep_provider=@ENV.WSREP_PROVIDER -wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.2.#galera_port' -wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.install_timeout = PT15S; evs.max_install_timeouts = 1;' - -# enforce read-committed characteristics across the cluster -wsrep_causal_reads=ON -wsrep_sync_wait = 15 - -wsrep_node_address=127.0.0.1 -wsrep_sst_receive_address=127.0.0.2:@mysqld.3.#sst_port -wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port - -# Required for Galera -innodb_autoinc_lock_mode=2 - -innodb_flush_log_at_trx_commit=2 - -[mysqld.4] -server-id=4 - -[ENV] -NODE_MYPORT_1= @mysqld.1.port -NODE_MYSOCK_1= @mysqld.1.socket - -NODE_MYPORT_2= @mysqld.2.port -NODE_MYSOCK_2= @mysqld.2.socket - -NODE_MYPORT_3= @mysqld.3.port -NODE_MYSOCK_3= @mysqld.3.socket - -NODE_MYPORT_4= @mysqld.4.port -NODE_MYSOCK_4= @mysqld.4.socket - -NODE_GALERAPORT_2= @mysqld.2.#galera_port -NODE_GALERAPORT_3= @mysqld.3.#galera_port - -NODE_SSTPORT_2= @mysqld.2.#sst_port -NODE_SSTPORT_3= @mysqld.3.#sst_port diff --git a/mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf b/mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf deleted file mode 100644 index d5490280ab2..00000000000 --- a/mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf +++ /dev/null @@ -1,87 +0,0 @@ -# -# This .cnf file creates a setup with a 2-node Galera cluster and one stand-alone MySQL server, to be used as a slave -# - -# Use default setting for mysqld processes -!include include/default_mysqld.cnf - -[mysqld] -default-storage-engine=InnoDB - -[mysqld.1] -server-id=1 -binlog-format=row -log-bin=mysqld-bin -log_slave_updates -gtid-mode=on -enforce-gtid-consistency=true -event-scheduler=1 - -wsrep_provider=@ENV.WSREP_PROVIDER -wsrep_cluster_address='gcomm://' -wsrep_provider_options='base_port=@mysqld.1.#galera_port' - -# enforce read-committed characteristics across the cluster -wsrep_causal_reads=ON -wsrep_sync_wait = 15 - -wsrep_node_address=127.0.0.1 -wsrep_sst_receive_address=127.0.0.2:@mysqld.1.#sst_port -wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port - -# Required for Galera -innodb_autoinc_lock_mode=2 - -innodb_flush_log_at_trx_commit=2 - -[mysqld.2] -server-id=2 -binlog-format=row -log-bin=mysqld-bin -log_slave_updates -gtid-mode=on -enforce-gtid-consistency=true -event-scheduler=1 - -wsrep_provider=@ENV.WSREP_PROVIDER -wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.2.#galera_port' - -# enforce read-committed characteristics across the cluster -wsrep_causal_reads=ON -wsrep_sync_wait = 15 - -wsrep_node_address=127.0.0.1 -wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port -wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port - -# Required for Galera -innodb_autoinc_lock_mode=2 - -innodb_flush_log_at_trx_commit=2 - -[mysqld.3] -server-id=3 -replicate-ignore-db=test -replicate-wild-ignore-table=test.% -log-bin=mysqld-bin -log_slave_updates -gtid-mode=on -enforce-gtid-consistency=true -event-scheduler=1 - -[ENV] -NODE_MYPORT_1= @mysqld.1.port -NODE_MYSOCK_1= @mysqld.1.socket - -NODE_MYPORT_2= @mysqld.2.port -NODE_MYSOCK_2= @mysqld.2.socket - -NODE_MYPORT_3= @mysqld.3.port -NODE_MYSOCK_3= @mysqld.3.socket - -NODE_GALERAPORT_1= @mysqld.1.#galera_port -NODE_GALERAPORT_2= @mysqld.2.#galera_port - -NODE_SSTPORT_1= @mysqld.1.#sst_port -NODE_SSTPORT_2= @mysqld.2.#sst_port diff --git a/mysql-test/suite/galera/r/MW-416.result b/mysql-test/suite/galera/r/MW-416.result new file mode 100644 index 00000000000..05399b213a8 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-416.result @@ -0,0 +1,114 @@ +CREATE USER 'userMW416'@'localhost'; +GRANT SELECT, INSERT, UPDATE ON test.* TO 'userMW416'@'localhost'; +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; +Variable_name Value +wsrep_replicated 2 +ALTER DATABASE db CHARACTER SET = utf8; +ERROR 42000: Access denied for user 'userMW416'@'localhost' to database 'db' +ALTER EVENT ev1 RENAME TO ev2; +ERROR 42000: Access denied for user 'userMW416'@'localhost' to database 'test' +ALTER FUNCTION fun1 COMMENT 'foo'; +ERROR 42000: alter routine command denied to user 'userMW416'@'localhost' for routine 'test.fun1' +ALTER LOGFILE GROUP lfg ADD UNDOFILE 'file' ENGINE=InnoDB; +Got one of the listed errors +ALTER PROCEDURE proc1 COMMENT 'foo'; +Got one of the listed errors +ALTER SERVER srv OPTIONS (USER 'sally'); +Got one of the listed errors +ALTER TABLE tbl DROP COLUMN col; +Got one of the listed errors +ALTER TABLESPACE tblspc DROP DATAFILE 'file' ENGINE=innodb; +Got one of the listed errors +ALTER VIEW vw AS SELECT 1; +Got one of the listed errors +CREATE DATABASE db; +Got one of the listed errors +CREATE EVENT ev1 ON SCHEDULE AT CURRENT_TIMESTAMP DO SELECT 1; +Got one of the listed errors +CREATE FUNCTION fun1() RETURNS int RETURN(1); +Got one of the listed errors +CREATE FUNCTION fun1 RETURNS STRING SONAME 'funlib.so'; +Got one of the listed errors +CREATE PROCEDURE proc1() BEGIN END; +Got one of the listed errors +CREATE INDEX idx ON tbl(id); +Got one of the listed errors +CREATE LOGFILE GROUP lfg ADD UNDOFILE 'undofile' ENGINE innodb; +Got one of the listed errors +CREATE SERVER srv FOREIGN DATA WRAPPER 'fdw' OPTIONS (USER 'user'); +Got one of the listed errors +CREATE TABLE t (i int); +Got one of the listed errors +CREATE TABLESPACE tblspc ADD DATAFILE 'file' ENGINE=innodb; +Got one of the listed errors +CREATE TRIGGER trg BEFORE UPDATE ON t FOR EACH ROW BEGIN END; +Got one of the listed errors +CREATE VIEW vw AS SELECT 1; +Got one of the listed errors +DROP DATABASE db; +Got one of the listed errors +DROP EVENT ev; +Got one of the listed errors +DROP FUNCTION fun1; +Got one of the listed errors +DROP INDEX idx ON t0; +Got one of the listed errors +DROP LOGFILE GROUP lfg; +Got one of the listed errors +DROP PROCEDURE proc1; +Got one of the listed errors +DROP SERVEr srv; +Got one of the listed errors +DROP TABLE t0; +Got one of the listed errors +DROP TABLESPACE tblspc; +Got one of the listed errors +DROP TRIGGER trg; +Got one of the listed errors +DROP VIEW vw; +Got one of the listed errors +RENAME TABLE t0 TO t1; +Got one of the listed errors +TRUNCATE TABLE t0; +Got one of the listed errors +ALTER USER myuser PASSWORD EXPIRE; +Got one of the listed errors +CREATE USER myuser IDENTIFIED BY 'pass'; +Got one of the listed errors +DROP USER myuser; +Got one of the listed errors +GRANT ALL ON *.* TO 'myuser'; +Got one of the listed errors +RENAME USER myuser TO mariauser; +Got one of the listed errors +REVOKE SELECT ON test FROM myuser; +Got one of the listed errors +REVOKE ALL, GRANT OPTION FROM myuser; +Got one of the listed errors +REVOKE PROXY ON myuser FROM myuser; +Got one of the listed errors +ANALYZE TABLE db.tbl; +Got one of the listed errors +CHECK TABLE db.tbl; +Got one of the listed errors +CHECKSUM TABLE db.tbl; +Got one of the listed errors +OPTIMIZE TABLE db.tbl; +Got one of the listed errors +REPAIR TABLE db.tbl; +Got one of the listed errors +INSTALL PLUGIN plg SONAME 'plg.so'; +Got one of the listed errors +UNINSTALL PLUGIN plg; +Got one of the listed errors +DROP USER 'userMW416'@'localhost'; +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +test +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; +Variable_name Value +wsrep_replicated 3 diff --git a/mysql-test/suite/galera/r/galera#500.result b/mysql-test/suite/galera/r/galera#500.result new file mode 100644 index 00000000000..6a07d0359a4 --- /dev/null +++ b/mysql-test/suite/galera/r/galera#500.result @@ -0,0 +1,10 @@ +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options="gmcast.isolate=2"; +SET SESSION wsrep_sync_wait = 0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status non-Primary +SET SESSION wsrep_sync_wait = default; +SET GLOBAL wsrep_provider_options="pc.bootstrap=1"; +SET SESSION wsrep_on=0; +CALL mtr.add_suppression("WSREP: exception from gcomm, backend must be restarted: Gcomm backend termination was requested by setting gmcast.isolate=2."); diff --git a/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result b/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result index 0a88b290e59..93ab4a3f3d4 100644 --- a/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result @@ -1,13 +1,21 @@ Setting SST method to mysqldump ... +call mtr.add_suppression("WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to '127.0.0.1'"); +call mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos"); +connection node_1; CREATE USER 'sst'; GRANT ALL PRIVILEGES ON *.* TO 'sst'; SET GLOBAL wsrep_sst_auth = 'sst:'; +connection node_2; SET GLOBAL wsrep_sst_method = 'mysqldump'; +connection node_1; +connection node_2; +connection node_1; CREATE USER sslsst; GRANT ALL PRIVILEGES ON *.* TO sslsst; GRANT USAGE ON *.* TO sslsst REQUIRE SSL; SET GLOBAL wsrep_sst_auth = 'sslsst:'; Performing State Transfer on a server that has been temporarily disconnected +connection node_1; CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -17,6 +25,7 @@ INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); COMMIT; +connection node_2; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node2_committed_before'); @@ -27,6 +36,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Unloading wsrep provider ... SET GLOBAL wsrep_provider = 'none'; +connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_committed_during'); @@ -41,6 +51,7 @@ INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_disconnect_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -48,6 +59,7 @@ INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; Loading wsrep provider ... SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -57,6 +69,7 @@ INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); COMMIT; +connection node_1; INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); @@ -71,6 +84,7 @@ INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); COMMIT; +connection node_1a_galera_st_disconnect_slave; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -85,6 +99,7 @@ COUNT(*) = 0 1 COMMIT; SET AUTOCOMMIT=ON; +connection node_1; SELECT COUNT(*) = 35 FROM t1; COUNT(*) = 35 1 @@ -94,8 +109,10 @@ COUNT(*) = 0 DROP TABLE t1; COMMIT; SET AUTOCOMMIT=ON; +connection node_1; CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); DROP USER sst; +connection node_2; CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); CALL mtr.add_suppression("InnoDB: Error: Table \"mysql\"\\.\"innodb_index_stats\" not found"); CALL mtr.add_suppression("Can't open and lock time zone table"); @@ -103,5 +120,3 @@ CALL mtr.add_suppression("Can't open and lock privilege tables"); CALL mtr.add_suppression("Info table is not ready to be used"); CALL mtr.add_suppression("Native table .* has the wrong structure"); DROP USER sslsst; -SET GLOBAL general_log = ON; -SET GLOBAL slow_query_log = ON; diff --git a/mysql-test/suite/galera/r/galera_var_dirty_reads.result b/mysql-test/suite/galera/r/galera_var_dirty_reads.result index 020efb7b8f1..049aa5be3cc 100644 --- a/mysql-test/suite/galera/r/galera_var_dirty_reads.result +++ b/mysql-test/suite/galera/r/galera_var_dirty_reads.result @@ -1,5 +1,7 @@ connection node_1; connection node_2; +connection node_1; +connection node_2; connection node_2; CREATE TABLE t1(i INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); diff --git a/mysql-test/suite/galera/t/MW-416.test b/mysql-test/suite/galera/t/MW-416.test new file mode 100644 index 00000000000..df4fa35abc7 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-416.test @@ -0,0 +1,134 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--source include/wait_until_ready.inc + +CREATE USER 'userMW416'@'localhost'; +GRANT SELECT, INSERT, UPDATE ON test.* TO 'userMW416'@'localhost'; + +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; + +--connect userMW416, localhost, userMW416,, test, $NODE_MYPORT_1 +--connection userMW416 + +# DDL + +--error 1044 +ALTER DATABASE db CHARACTER SET = utf8; +--error 1044 +ALTER EVENT ev1 RENAME TO ev2; +--error 1370 +ALTER FUNCTION fun1 COMMENT 'foo'; +#--error 1044,1227 +#ALTER INSTANCE ROTATE INNODB MASTER KEY; +--error 1044,1227 +ALTER LOGFILE GROUP lfg ADD UNDOFILE 'file' ENGINE=InnoDB; +--error 1044,1227,1370 +ALTER PROCEDURE proc1 COMMENT 'foo'; +--error 1044,1227,1370 +ALTER SERVER srv OPTIONS (USER 'sally'); +--error 1044,1142,1227,1370 +ALTER TABLE tbl DROP COLUMN col; +--error 1044,1227,1370 +ALTER TABLESPACE tblspc DROP DATAFILE 'file' ENGINE=innodb; +--error 1044,1142,1227,1370 +ALTER VIEW vw AS SELECT 1; + +--error 1044,1227,1370 +CREATE DATABASE db; +--error 1044,1227,1370 +CREATE EVENT ev1 ON SCHEDULE AT CURRENT_TIMESTAMP DO SELECT 1; +--error 1044,1227,1370 +CREATE FUNCTION fun1() RETURNS int RETURN(1); +--error 1044,1227,1370 +CREATE FUNCTION fun1 RETURNS STRING SONAME 'funlib.so'; +--error 1044,1227,1370 +CREATE PROCEDURE proc1() BEGIN END; +--error 1044,1142,1227,1370 +CREATE INDEX idx ON tbl(id); +--error 1044,1142,1227,1370 +CREATE LOGFILE GROUP lfg ADD UNDOFILE 'undofile' ENGINE innodb; +--error 1044,1142,1227,1370 +CREATE SERVER srv FOREIGN DATA WRAPPER 'fdw' OPTIONS (USER 'user'); +--error 1044,1142,1227,1370 +CREATE TABLE t (i int); +--error 1044,1142,1227,1370 +CREATE TABLESPACE tblspc ADD DATAFILE 'file' ENGINE=innodb; +--error 1044,1142,1227,1370 +CREATE TRIGGER trg BEFORE UPDATE ON t FOR EACH ROW BEGIN END; +--error 1044,1142,1227,1370 +CREATE VIEW vw AS SELECT 1; + + + +--error 1044,1142,1227,1370 +DROP DATABASE db; +--error 1044,1142,1227,1370 +DROP EVENT ev; +--error 1044,1142,1227,1370 +DROP FUNCTION fun1; +--error 1044,1142,1227,1370 +DROP INDEX idx ON t0; +--error 1044,1142,1227,1370,1064 +DROP LOGFILE GROUP lfg; +--error 1044,1142,1227,1370 +DROP PROCEDURE proc1; +--error 1044,1142,1227,1370 +DROP SERVEr srv; +--error 1044,1142,1227,1370 +DROP TABLE t0; +--error 1044,1142,1227,1370,1064 +DROP TABLESPACE tblspc; +--error 1044,1142,1227,1360,1370 +DROP TRIGGER trg; +--error 1044,1142,1227,1370 +DROP VIEW vw; + +--error 1044,1142,1227,1370 +RENAME TABLE t0 TO t1; + +--error 1044,1142,1227,1370 +TRUNCATE TABLE t0; + +# DCL + +# account management +--error 1044,1142,1227,1370,1064 +ALTER USER myuser PASSWORD EXPIRE; +--error 1044,1142,1227,1370 +CREATE USER myuser IDENTIFIED BY 'pass'; +--error 1044,1142,1227,1370 +DROP USER myuser; +--error 1044,1045,1142,1227,1370 +GRANT ALL ON *.* TO 'myuser'; +--error 1044,1142,1227,1370 +RENAME USER myuser TO mariauser; +--error 1044,1142,1227,1370 +REVOKE SELECT ON test FROM myuser; +--error 1044,1142,1227,1370,1698 +REVOKE ALL, GRANT OPTION FROM myuser; +--error 1044,1142,1227,1370,1698 +REVOKE PROXY ON myuser FROM myuser; + +# table maintenance +--error 1044,1142,1227,1370 +ANALYZE TABLE db.tbl; +--error 1044,1142,1227,1370 +CHECK TABLE db.tbl; +--error 1044,1142,1227,1370 +CHECKSUM TABLE db.tbl; +--error 1044,1142,1227,1370 +OPTIMIZE TABLE db.tbl; +--error 1044,1142,1227,1370 +REPAIR TABLE db.tbl; + +# plugin and user defined functions +--error 1044,1142,1227,1370 +INSTALL PLUGIN plg SONAME 'plg.so'; +--error 1044,1142,1227,1370 +UNINSTALL PLUGIN plg; + +--connection node_1 +DROP USER 'userMW416'@'localhost'; +SHOW DATABASES; +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; diff --git a/mysql-test/suite/galera/t/galera#500.test b/mysql-test/suite/galera/t/galera#500.test new file mode 100644 index 00000000000..3c8490b6907 --- /dev/null +++ b/mysql-test/suite/galera/t/galera#500.test @@ -0,0 +1,38 @@ +# +# The purpose of this test is to verify that if an exception is +# thrown from gcomm background thread, the provider terminates properly +# and wsrep_ready becomes 0. +# + +--source include/have_innodb.inc +--source include/galera_cluster.inc +--source include/galera_have_debug_sync.inc + +# Force node_2 gcomm background thread to terminate via exception. +--connection node_2 +--let $wsrep_cluster_address = `SELECT @@wsrep_cluster_address` +# Setting gmcast.isolate=2 will force gcomm background thread to +# throw exception. +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options="gmcast.isolate=2"; + +# Wait until wsrep_ready becomes 0. +--let $wait_condition = SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME ='wsrep_ready' +--source include/wait_condition.inc + +# Wait until node_1 ends up in non-prim and rebootstrap the cluster. +--connection node_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 +SHOW STATUS LIKE 'wsrep_cluster_status'; +SET SESSION wsrep_sync_wait = default; +SET GLOBAL wsrep_provider_options="pc.bootstrap=1"; + +# Restart node_2 +--connection node_2 +SET SESSION wsrep_on=0; +--source include/restart_mysqld.inc + +--connection node_2 +CALL mtr.add_suppression("WSREP: exception from gcomm, backend must be restarted: Gcomm backend termination was requested by setting gmcast.isolate=2."); diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test index 3bfcdc9f117..08165f30f7d 100644 --- a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test +++ b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test @@ -5,6 +5,7 @@ --source include/galera_cluster.inc --source include/big_test.inc +--source include/have_log_bin.inc SET SESSION wsrep_sync_wait = 0; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 LONGBLOB) ENGINE=InnoDB; @@ -93,6 +94,8 @@ END| DELIMITER ;| +--let $wsrep_last_committed_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` + --connect node_1_insert_simple, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connect node_1_insert_multi, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connect node_1_insert_transaction, 127.0.0.1, root, , test, $NODE_MYPORT_1 @@ -124,6 +127,13 @@ DELIMITER ;| --connection node_2 SET SESSION wsrep_sync_wait = 0; + +# Make sure that node_2 is not killed while TOIs are applied. +# Otherwhise we risk that grastate file is marked unsafe, and +# as a consequence the node cannot rejoin with IST. +--let $wait_condition = SELECT VARIABLE_VALUE > $wsrep_last_committed_before FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' +--source include/wait_condition.inc + --source include/kill_galera.inc --sleep 10 @@ -172,9 +182,8 @@ SET SESSION wsrep_sync_wait = 0; --source include/start_mysqld.inc --connection node_1 ---source include/wait_until_connected_again.inc ---source include/galera_wait_ready.inc --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc --let $diff_servers = 1 2 --source include/diff_servers.inc diff --git a/mysql-test/suite/galera/t/galera_many_tables_pk.test b/mysql-test/suite/galera/t/galera_many_tables_pk.test index 551307b123f..73c5fc1622c 100644 --- a/mysql-test/suite/galera/t/galera_many_tables_pk.test +++ b/mysql-test/suite/galera/t/galera_many_tables_pk.test @@ -16,7 +16,7 @@ if (!`SELECT @@open_files_limit >= 1024`){ while ($count) { --disable_query_log - --let $ddl_var = `SELECT CONCAT("CREATE TABLE t", $count, " (f1 INTEGER AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB")` + --let $ddl_var = `SELECT CONCAT("CREATE TABLE t", $count, " (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB")` --eval $ddl_var --enable_query_log --dec $count @@ -37,7 +37,7 @@ START TRANSACTION; while ($count) { --disable_query_log - --let $ddl_var = `SELECT CONCAT("INSERT INTO t", $count, " VALUES (DEFAULT)")` + --let $ddl_var = `SELECT CONCAT("INSERT INTO t", $count, " VALUES (1)")` --eval $ddl_var --enable_query_log --dec $count diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup.test b/mysql-test/suite/galera/t/galera_sst_mariabackup.test index 0e7ac487700..bcb9ade3a25 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc --source include/have_mariabackup.inc diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump.test b/mysql-test/suite/galera/t/galera_sst_mysqldump.test index 390e9815b20..835fac94a68 100644 --- a/mysql-test/suite/galera/t/galera_sst_mysqldump.test +++ b/mysql-test/suite/galera/t/galera_sst_mysqldump.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source suite/galera/include/galera_sst_set_mysqldump.inc diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf index e108484b248..44e5573b3e6 100644 --- a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf +++ b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf @@ -12,10 +12,6 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore [mysqld] wsrep_debug=ON -ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/galera-cert.pem -ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/galera-cert.pem -ssl-key=@ENV.MYSQL_TEST_DIR/std_data/galera-key.pem - [client] ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test index c813e04169f..0dbc63b531c 100644 --- a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test @@ -5,9 +5,12 @@ --source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc ---source include/have_openssl.inc +--source include/have_ssl_communication.inc --source suite/galera/include/galera_sst_set_mysqldump.inc +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc --connection node_1 CREATE USER sslsst; @@ -18,12 +21,7 @@ SET GLOBAL wsrep_sst_auth = 'sslsst:'; --source suite/galera/include/galera_st_disconnect_slave.inc +--source include/auto_increment_offset_restore.inc --source suite/galera/include/galera_sst_restore.inc -DROP USER sslsst; - ---connection node_2 -# We have to manually restore global_log and slow_query_log due to mysql-wsrep#108 -# Otherwise MTR's check_testcases complains -SET GLOBAL general_log = ON; -SET GLOBAL slow_query_log = ON; +DROP USER sslsst; diff --git a/mysql-test/suite/galera/t/galera_sst_rsync.test b/mysql-test/suite/galera/t/galera_sst_rsync.test index f796356cac7..5c08707e870 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --let $node_1=node_1 diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf index 1e29673c0ff..3abf2549aae 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf @@ -8,7 +8,7 @@ wsrep_debug=ON [xtrabackup] backup-locks close-files -compact +#compact - disabled in xtrabackup 2.4, https://bugs.launchpad.net/percona-xtrabackup/+bug/1192834/comments/29 # compression requires qpress from the Percona repositories # compress # compress-threads=2 diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.test b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.test index f1fd0f3ddf3..c270e4d0b19 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.test +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc --source include/have_xtrabackup.inc diff --git a/mysql-test/suite/galera/t/galera_var_dirty_reads.test b/mysql-test/suite/galera/t/galera_var_dirty_reads.test index 3e2108868af..1f01c4aac07 100644 --- a/mysql-test/suite/galera/t/galera_var_dirty_reads.test +++ b/mysql-test/suite/galera/t/galera_var_dirty_reads.test @@ -11,6 +11,11 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.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_2 --let $wsrep_cluster_address_saved = `SELECT @@global.wsrep_cluster_address` diff --git a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result index 1464222a079..7e0d282ec7f 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result +++ b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result @@ -11,6 +11,7 @@ SET SESSION wsrep_sync_wait = 0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 +SET SESSION wsrep_sync_wait = DEFAULT; SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 1 diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test index a87f19ac94e..03236a3cb93 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test @@ -50,6 +50,7 @@ SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_N --enable_query_log --source include/wait_until_connected_again.inc +SET SESSION wsrep_sync_wait = DEFAULT; SELECT COUNT(*) = 1 FROM t1; DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index fadbb3b8031..577b3255620 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -691,9 +691,13 @@ a b c 1 127 0 SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR ALTER TABLE t ADD UNIQUE INDEX (c(1)); +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 SELECT * FROM t WHERE c = '0'; a b c 1 127 0 +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 DROP TABLE t; # # Bug#21688115 VIRTUAL COLUMN COMPUTATION SAVE_IN_FIELD() diff --git a/mysql-test/suite/handler/handler.inc b/mysql-test/suite/handler/handler.inc index 2432ff13e55..c29ee0c693d 100644 --- a/mysql-test/suite/handler/handler.inc +++ b/mysql-test/suite/handler/handler.inc @@ -373,7 +373,9 @@ connection con2; send optimize table t1; --sleep 1 connection default; +--disable_ps_protocol handler t1 read next; +--enable_ps_protocol handler t1 close; connection con2; reap; diff --git a/mysql-test/suite/handler/ps.result b/mysql-test/suite/handler/ps.result new file mode 100644 index 00000000000..54685f9156b --- /dev/null +++ b/mysql-test/suite/handler/ps.result @@ -0,0 +1,9 @@ +create table t1 (i int); +handler test.t1 open handler_a; +flush status; +handler handler_a read first; +i +show status like 'Com_stmt_prepare%'; +Variable_name Value +Com_stmt_prepare OK +drop table t1; diff --git a/mysql-test/suite/handler/ps.test b/mysql-test/suite/handler/ps.test new file mode 100644 index 00000000000..68091190c85 --- /dev/null +++ b/mysql-test/suite/handler/ps.test @@ -0,0 +1,11 @@ +# +# MDEV-15729 Server crashes in Field::make_field upon HANDLER READ executed with PS protocol +# +create table t1 (i int); +handler test.t1 open handler_a; +flush status; +handler handler_a read first; +# handler...read must be prepared in --ps-protocol mode +--replace_result $PS_PROTOCOL OK +show status like 'Com_stmt_prepare%'; +drop table t1; diff --git a/mysql-test/suite/heap/heap_auto_increment.result b/mysql-test/suite/heap/heap_auto_increment.result index 5b04a77e9eb..e3fd377d4ef 100644 --- a/mysql-test/suite/heap/heap_auto_increment.result +++ b/mysql-test/suite/heap/heap_auto_increment.result @@ -39,3 +39,152 @@ _rowid _rowid skey sval 1 1 1 hello 2 2 2 hey drop table t1; +# +# MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +# +CREATE TABLE t1 ( +id TINYINT NOT NULL AUTO_INCREMENT, +name CHAR(30) NOT NULL, +PRIMARY KEY (id) +) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +id name +-1 dog +2 cat +DROP TABLE t1; +# +# End of 5.5 tests +# +# +# MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +# +SET @engine='MEMORY'; +CREATE PROCEDURE autoinc_mdev15353_one(engine VARCHAR(64), t VARCHAR(64)) +BEGIN +DECLARE query TEXT DEFAULT 'CREATE TABLE t1 (' + ' id TTT NOT NULL AUTO_INCREMENT,' + ' name CHAR(30) NOT NULL,' + ' PRIMARY KEY (id)) ENGINE=EEE'; +EXECUTE IMMEDIATE REPLACE(REPLACE(query,'TTT', t), 'EEE', engine); +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +SELECT * FROM t1; +UPDATE t1 SET id=-1 WHERE id=1; +SELECT * FROM t1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; +END; +$$ +CALL autoinc_mdev15353_one(@engine, 'tinyint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'smallint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` smallint(6) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'mediumint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` mediumint(9) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'int'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'bigint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'float'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` float NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'double'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` double NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +DROP PROCEDURE autoinc_mdev15353_one; +# +# End of 10.2 tests +# diff --git a/mysql-test/suite/heap/heap_auto_increment.test b/mysql-test/suite/heap/heap_auto_increment.test index 016bc946209..a480251f3e8 100644 --- a/mysql-test/suite/heap/heap_auto_increment.test +++ b/mysql-test/suite/heap/heap_auto_increment.test @@ -33,3 +33,35 @@ select _rowid,t1._rowid,skey,sval from t1; drop table t1; # End of 4.1 tests + +--echo # +--echo # MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +--echo # + +CREATE TABLE t1 ( + id TINYINT NOT NULL AUTO_INCREMENT, + name CHAR(30) NOT NULL, + PRIMARY KEY (id) +) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # + +--echo # +--echo # MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +--echo # + +SET @engine='MEMORY'; +--source include/autoinc_mdev15353.inc + +--echo # +--echo # End of 10.2 tests +--echo # + diff --git a/mysql-test/suite/innodb/include/alter_not_null.inc b/mysql-test/suite/innodb/include/alter_not_null.inc new file mode 100644 index 00000000000..109fad38d16 --- /dev/null +++ b/mysql-test/suite/innodb/include/alter_not_null.inc @@ -0,0 +1,94 @@ +--source include/have_innodb.inc + +CREATE TABLE t1(f1 INT)ENGINE=INNODB; +INSERT INTO t1 VALUES(NULL); +SELECT * FROM t1; +--enable_info +--error $error_code +ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL; +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 CHAR(10))ENGINE=INNODB; +INSERT INTO t1 VALUES(NULL); +SELECT * FROM t1; +--enable_info +--error $error_code +ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL; +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 VARCHAR(10))ENGINE=INNODB; +INSERT INTO t1 VALUES(NULL); +SELECT * FROM t1; +--enable_info +--error $error_code +ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL; +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 TEXT)ENGINE=INNODB; +INSERT INTO t1 VALUES(NULL); +SELECT * FROM t1; +--enable_info +--error $error_code +ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc'; +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB; +INSERT INTO t1 VALUES(2, 2, NULL); +SELECT * FROM t1; +--enable_info +--error $error_code +ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2); +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL DEFAULT 0, b TINYINT)ENGINE=InnoDB; +INSERT INTO t1 VALUES(10, NULL); +SELECT * FROM t1; +--enable_info +--error $error_code +ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0); +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(a INT, v INT AS (a), c INT, d INT NOT NULL, e INT) ENGINE=InnoDB; +--enable_info +ALTER TABLE t1 DROP COLUMN c, CHANGE COLUMN e e INT NOT NULL; +--disable_info +DROP TABLE t1; + +CREATE TABLE t1 (a INT, v INT AS (a), d INT NOT NULL, e INT) ENGINE=InnoDB; +--enable_info +ALTER TABLE t1 FORCE; +--disable_info +DROP TABLE t1; + +# Alter ignore should work irrespective of sql mode + +CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; +INSERT INTO t1 VALUES(1, NULL); +--enable_info +ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; +--disable_info +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-16126 Crash or ASAN heap-buffer-overflow in +--echo # mach_read_from_n_little_endian upon ALTER TABLE with blob +--echo # + +CREATE TABLE t1(a INT, v INT AS (a), b INT, c BLOB) ENGINE=InnoDB; +--enable_info +ALTER TABLE t1 ADD PRIMARY KEY(b); +--disable_info +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff new file mode 100644 index 00000000000..01db97e59f8 --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff @@ -0,0 +1,42 @@ +7,8c7,8 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 +21,22c21,22 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 +35,36c35,36 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 +49,50c49,50 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 +63,64c63,64 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 +77,78c77,78 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 +98,99c98,99 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 diff --git a/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff new file mode 100644 index 00000000000..e02d235cb72 --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff @@ -0,0 +1,72 @@ +7,10c7 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +13c10 +< 0 +--- +> NULL +21,24c18 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +27c21 +< +--- +> NULL +35,38c29 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +41c32 +< +--- +> NULL +49,52c40 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +55c43 +< +--- +> NULL +63,66c51 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f3' at row 1 +--- +> ERROR 01000: Data truncated for column 'f3' at row 1 +69c54 +< 2 2 0 +--- +> 2 2 NULL +77,80c62 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'b' at row 1 +--- +> ERROR 01000: Data truncated for column 'b' at row 1 +83c65 +< 10 0 +--- +> 10 NULL +98,99c80,81 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +--- +> affected rows: 1 +> info: Records: 1 Duplicates: 0 Warnings: 1 diff --git a/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff new file mode 100644 index 00000000000..ec97b174bdf --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff @@ -0,0 +1,66 @@ +7,10c7 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +13c10 +< 0 +--- +> NULL +21,24c18 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +27c21 +< +--- +> NULL +35,38c29 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +41c32 +< +--- +> NULL +49,52c40 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f1' at row 1 +--- +> ERROR 01000: Data truncated for column 'f1' at row 1 +55c43 +< +--- +> NULL +63,66c51 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'f3' at row 1 +--- +> ERROR 01000: Data truncated for column 'f3' at row 1 +69c54 +< 2 2 0 +--- +> 2 2 NULL +77,80c62 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'b' at row 1 +--- +> ERROR 01000: Data truncated for column 'b' at row 1 +83c65 +< 10 0 +--- +> 10 NULL diff --git a/mysql-test/suite/innodb/r/alter_not_null.result b/mysql-test/suite/innodb/r/alter_not_null.result index 8380378593d..688493351b8 100644 --- a/mysql-test/suite/innodb/r/alter_not_null.result +++ b/mysql-test/suite/innodb/r/alter_not_null.result @@ -1,4 +1,3 @@ -set @@sql_mode = 'STRICT_TRANS_TABLES'; CREATE TABLE t1(f1 INT)ENGINE=INNODB; INSERT INTO t1 VALUES(NULL); SELECT * FROM t1; @@ -6,7 +5,9 @@ f1 NULL ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL; affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 SELECT * FROM t1; f1 0 @@ -18,7 +19,9 @@ f1 NULL ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL; affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 SELECT * FROM t1; f1 @@ -30,7 +33,9 @@ f1 NULL ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL; affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 SELECT * FROM t1; f1 @@ -42,25 +47,23 @@ f1 NULL ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc'; affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 SELECT * FROM t1; f1 -abc + DROP TABLE t1; CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB; INSERT INTO t1 VALUES(2, 2, NULL); SELECT * FROM t1; f1 f2 f3 2 2 NULL -ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2), ALGORITHM=INPLACE; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: cannot convert NULL to non-constant DEFAULT. Try ALGORITHM=COPY -UPDATE t1 SET f3 = 0; -SELECT * FROM t1; -f1 f2 f3 -2 2 0 ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2); -affected rows: 1 -info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'f3' at row 1 SELECT * FROM t1; f1 f2 f3 2 2 0 @@ -70,14 +73,35 @@ INSERT INTO t1 VALUES(10, NULL); SELECT * FROM t1; f1 b 10 NULL -ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0), algorithm=INPLACE; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: cannot convert NULL to non-constant DEFAULT. Try ALGORITHM=COPY +ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'b' at row 1 +SELECT * FROM t1; +f1 b +10 0 DROP TABLE t1; CREATE TABLE t1(a INT, v INT AS (a), c INT, d INT NOT NULL, e INT) ENGINE=InnoDB; -ALTER TABLE t1 DROP COLUMN c, CHANGE COLUMN e e INT NOT NULL, ALGORITHM=INPLACE; +ALTER TABLE t1 DROP COLUMN c, CHANGE COLUMN e e INT NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; CREATE TABLE t1 (a INT, v INT AS (a), d INT NOT NULL, e INT) ENGINE=InnoDB; -ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; +ALTER TABLE t1 FORCE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +DROP TABLE t1; +CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; +INSERT INTO t1 VALUES(1, NULL); +ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'c2' at row 1 +SELECT * FROM t1; +c1 c2 +1 0 DROP TABLE t1; # # MDEV-16126 Crash or ASAN heap-buffer-overflow in @@ -85,4 +109,6 @@ DROP TABLE t1; # CREATE TABLE t1(a INT, v INT AS (a), b INT, c BLOB) ENGINE=InnoDB; ALTER TABLE t1 ADD PRIMARY KEY(b); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/alter_not_null_debug,STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null_debug,STRICT.rdiff new file mode 100644 index 00000000000..09c717c44b0 --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_not_null_debug,STRICT.rdiff @@ -0,0 +1,11 @@ +18,21c18 +< affected rows: 0 +< info: Records: 0 Duplicates: 0 Warnings: 1 +< Warnings: +< Warning 1265 Data truncated for column 'c2' at row 3 +--- +> ERROR 01000: Data truncated for column 'c2' at row 3 +24c21 +< 2 0 +--- +> 2 NULL diff --git a/mysql-test/suite/innodb/r/alter_not_null_debug.result b/mysql-test/suite/innodb/r/alter_not_null_debug.result index 788eef6420b..c12f1fbca3d 100644 --- a/mysql-test/suite/innodb/r/alter_not_null_debug.result +++ b/mysql-test/suite/innodb/r/alter_not_null_debug.result @@ -1,68 +1,78 @@ CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; -INSERT INTO t1 VALUES(1, NULL); +INSERT INTO t1 VALUES(1, 1); SET DEBUG_SYNC= 'row_merge_after_scan SIGNAL opened WAIT_FOR flushed'; -ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; +affected rows: 0 +ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; connect con1,localhost,root; SET DEBUG_SYNC= 'now WAIT_FOR opened'; +affected rows: 0 INSERT INTO t1 VALUES(2, NULL); +affected rows: 1 +UPDATE t1 SET c1 = 3 WHERE c2 = 1; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 SET DEBUG_SYNC= 'now SIGNAL flushed'; +affected rows: 0 connection default; -ERROR 22004: Invalid use of NULL value +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'c2' at row 3 SELECT * FROM t1; c1 c2 -1 NULL -2 NULL -UPDATE t1 SET c2 = 0 WHERE c1 = 2; +2 0 +3 1 +DROP TABLE t1; +CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; +INSERT INTO t1 VALUES(1, 1); SET DEBUG_SYNC= 'row_merge_after_scan SIGNAL opened WAIT_FOR flushed'; -# Alter ignore can convert the NULL values from -# CONCURRENT DML to constants -ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; +affected rows: 0 +ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; connection con1; SET DEBUG_SYNC= 'now WAIT_FOR opened'; -UPDATE t1 SET c2 = NULL WHERE c1 = 2; -INSERT INTO t1 VALUES (3, NULL); +affected rows: 0 +INSERT INTO t1 VALUES(2, 3); +affected rows: 1 +UPDATE t1 SET c1 = 3 WHERE c2 = 1; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 SET DEBUG_SYNC= 'now SIGNAL flushed'; +affected rows: 0 connection default; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SELECT * FROM t1; c1 c2 -1 2 -2 2 -3 2 +2 3 +3 1 DROP TABLE t1; CREATE TABLE t1(c1 INT NOT NULL, c2 INT, c3 INT, PRIMARY KEY(c1))ENGINE=INNODB; -INSERT INTO t1 VALUES(1, NULL, NULL); +INSERT INTO t1 VALUES(1, 2, 3); SET DEBUG_SYNC= 'row_merge_after_scan SIGNAL opened WAIT_FOR flushed'; -# Alter Successfully converts from null to not null -ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; +affected rows: 0 +ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; connection con1; SET DEBUG_SYNC= 'now WAIT_FOR opened'; +affected rows: 0 UPDATE t1 SET c2= 2 WHERE c1 = 1; -INSERT INTO t1 VALUES (2, 3, 4); -SET DEBUG_SYNC= 'now SIGNAL flushed'; -connection default; -SELECT * FROM t1; -c1 c2 c3 -1 2 NULL -2 3 4 -SET DEBUG_SYNC= 'row_merge_after_scan -SIGNAL opened WAIT_FOR flushed'; -# Alter fails because concurrent dml inserts null value -ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; -connection con1; -SET DEBUG_SYNC= 'now WAIT_FOR opened'; -UPDATE t1 SET c3= 2 WHERE c1 = 2; -INSERT INTO t1 VALUES (4, 3, NULL); +affected rows: 0 +info: Rows matched: 1 Changed: 0 Warnings: 0 +INSERT INTO t1 VALUES (2, NULL, 4); +affected rows: 1 SET DEBUG_SYNC= 'now SIGNAL flushed'; +affected rows: 0 connection default; -ERROR 22004: Invalid use of NULL value +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'c2' at row 3 SELECT * FROM t1; c1 c2 c3 -1 2 NULL -2 3 2 -4 3 NULL +1 2 3 +2 0 4 DROP TABLE t1; disconnect con1; SET DEBUG_SYNC='RESET'; diff --git a/mysql-test/suite/innodb/r/innodb-16k.result b/mysql-test/suite/innodb/r/innodb-16k.result index 07b40269e8f..b99aba15f0f 100644 --- a/mysql-test/suite/innodb/r/innodb-16k.result +++ b/mysql-test/suite/innodb/r/innodb-16k.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("InnoDB: Cannot add field .* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page."); +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/r/innodb-alter-timestamp.result b/mysql-test/suite/innodb/r/innodb-alter-timestamp.result index b8686d6812e..d4c0aa6a50e 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-timestamp.result +++ b/mysql-test/suite/innodb/r/innodb-alter-timestamp.result @@ -2,16 +2,18 @@ CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb; INSERT INTO t1 VALUES(NULL); ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(), ALGORITHM=INPLACE; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: cannot convert NULL to non-constant DEFAULT. Try ALGORITHM=COPY +ERROR 01000: Data truncated for column 'i1' at row 1 ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(), ALGORITHM=COPY; ERROR 01000: Data truncated for column 'i1' at row 1 ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY(id), ALGORITHM=INPLACE; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY -ALTER TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE; +ALTER IGNORE TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE; affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Warning 1265 Data truncated for column 'i1' at row 1 ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT; affected rows: 1 info: Records: 1 Duplicates: 0 Warnings: 0 diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result index ee1adc07661..eb7ff026b1a 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc.result @@ -1351,6 +1351,7 @@ t CREATE TABLE `t` ( KEY `i` (`i`) ) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1 DROP TABLE t; +SET auto_increment_increment = DEFAULT; # # MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op()) # @@ -1369,3 +1370,123 @@ SELECT * FROM t1; a -1 DROP TABLE t1; +# +# MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +# +SET @engine='INNODB'; +CREATE PROCEDURE autoinc_mdev15353_one(engine VARCHAR(64), t VARCHAR(64)) +BEGIN +DECLARE query TEXT DEFAULT 'CREATE TABLE t1 (' + ' id TTT NOT NULL AUTO_INCREMENT,' + ' name CHAR(30) NOT NULL,' + ' PRIMARY KEY (id)) ENGINE=EEE'; +EXECUTE IMMEDIATE REPLACE(REPLACE(query,'TTT', t), 'EEE', engine); +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +SELECT * FROM t1; +UPDATE t1 SET id=-1 WHERE id=1; +SELECT * FROM t1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; +END; +$$ +CALL autoinc_mdev15353_one(@engine, 'tinyint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'smallint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` smallint(6) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'mediumint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` mediumint(9) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'int'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'bigint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'float'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` float NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'double'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` double NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +DROP PROCEDURE autoinc_mdev15353_one; diff --git a/mysql-test/suite/innodb/r/innodb-blob.result b/mysql-test/suite/innodb/r/innodb-blob.result index d48bfdf0f80..c2b46661e31 100644 --- a/mysql-test/suite/innodb/r/innodb-blob.result +++ b/mysql-test/suite/innodb/r/innodb-blob.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles!"); +FLUSH TABLES; CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=InnoDB; CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t3 (a INT PRIMARY KEY, b TEXT, c TEXT) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb/r/innodb-corrupted-table.result b/mysql-test/suite/innodb/r/innodb-corrupted-table.result index 1a8cea06c4c..9a0b3d81810 100644 --- a/mysql-test/suite/innodb/r/innodb-corrupted-table.result +++ b/mysql-test/suite/innodb/r/innodb-corrupted-table.result @@ -1,5 +1,5 @@ -call mtr.add_suppression("Table .* has a primary key in InnoDB data dictionary, but not in MariaDB.*"); -call mtr.add_suppression("InnoDB: Table .* contains .* indexes inside InnoDB, which is different from the number of indexes .* defined in the MariaDB.*"); +call mtr.add_suppression("Table .* has a primary key in InnoDB data dictionary, but not in MariaDB"); +call mtr.add_suppression("InnoDB: Table .* contains .* indexes inside InnoDB"); create table t1 (pk int, i int, key(i)) engine=InnoDB; insert into t1 values (1,1),(2,2); flush tables; diff --git a/mysql-test/suite/innodb/r/innodb-mdev-7513.result b/mysql-test/suite/innodb/r/innodb-mdev-7513.result index 55b4d3462b0..2ef54911cf1 100644 --- a/mysql-test/suite/innodb/r/innodb-mdev-7513.result +++ b/mysql-test/suite/innodb/r/innodb-mdev-7513.result @@ -1,5 +1,4 @@ -call mtr.add_suppression("InnoDB: Cannot add field `.* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page."); -call mtr.add_suppression("Row size too large (> 8126)*"); +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); CREATE TABLE t1 ( text1 TEXT, text2 TEXT, text3 TEXT, diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_default.result b/mysql-test/suite/innodb/r/innodb-page_compression_default.result index 39a14072571..8977a149935 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_default.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_default.result @@ -1,4 +1,3 @@ -call mtr.add_suppression("InnoDB: Compression failed for space [0-9]+ name test/innodb_page_compressed[0-9] len [0-9]+ err 2 write_size [0-9]+."); create table innodb_normal (c1 int not null auto_increment primary key, b char(200)) engine=innodb; create table innodb_page_compressed1 (c1 int not null auto_increment primary key, b char(200)) engine=innodb page_compressed=1 page_compression_level=1; create table innodb_page_compressed2 (c1 int not null auto_increment primary key, b char(200)) engine=innodb page_compressed=1 page_compression_level=2; diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_snappy.result b/mysql-test/suite/innodb/r/innodb-page_compression_snappy.result index e99e55ed9a8..98c353e87e3 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_snappy.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_snappy.result @@ -1,4 +1,3 @@ -call mtr.add_suppression("InnoDB: Compression failed for space [0-9]+ name test/innodb_page_compressed[0-9] len [0-9]+ err 2 write_size [0-9]+."); set global innodb_compression_algorithm = snappy; create table innodb_normal (c1 int not null auto_increment primary key, b char(200)) engine=innodb; create table innodb_page_compressed1 (c1 int not null auto_increment primary key, b char(200)) engine=innodb page_compressed=1 page_compression_level=1; diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index d8482ebb23a..5b5c4d6b9e1 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -409,7 +409,7 @@ ALTER TABLE t1 DROP COLUMN c22f, ADD PRIMARY KEY c3p5(c3(5)); ERROR 42000: Key column 'c22f' doesn't exist in table SET @old_sql_mode = @@sql_mode; SET @@sql_mode = 'STRICT_TRANS_TABLES'; -ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)), +ALTER IGNORE TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)), ALGORITHM = INPLACE; ERROR 23000: Duplicate entry '' for key 'PRIMARY' SET @@sql_mode = @old_sql_mode; @@ -428,7 +428,7 @@ INSERT INTO t1 VALUES(33101,347,NULL,''); SET DEBUG_SYNC = 'now SIGNAL ins_done0'; # session con1 connection con1; -ERROR 22004: Invalid use of NULL value +ERROR 01000: Data truncated for column 'c3' at row 323 SET @@sql_mode = @old_sql_mode; # session default connection default; diff --git a/mysql-test/suite/innodb/r/innodb_defragment_small.result b/mysql-test/suite/innodb/r/innodb_defragment_small.result index 7471c84bb44..fcb3bf2e07f 100644 --- a/mysql-test/suite/innodb/r/innodb_defragment_small.result +++ b/mysql-test/suite/innodb/r/innodb_defragment_small.result @@ -1,6 +1,13 @@ SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment; +SET @innodb_optimize_fulltext_orig=@@GLOBAL.innodb_optimize_fulltext_only; SET GLOBAL innodb_defragment = 1; -CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB; +SET GLOBAL innodb_optimize_fulltext_only = 0; +# +# MDEV-12198 innodb_defragment=1 crashes server on +# OPTIMIZE TABLE when FULLTEXT index exists +# +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), +KEY(a, b), FULLTEXT KEY(b)) ENGINE=INNODB; OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK @@ -11,12 +18,15 @@ INSERT INTO t1 VALUES (400000, REPEAT('A', 256)); OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK -DROP TABLE t1; # -# MDEV-12198 innodb_defragment=1 crashes server on -# OPTIMIZE TABLE when FULLTEXT index exists +# MDEV-15824 innodb_defragment=ON trumps +# innodb_optimize_fulltext_only=ON in OPTIMIZE TABLE # -CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB; +SET GLOBAL innodb_optimize_fulltext_only = 1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +SET GLOBAL innodb_defragment = 0; OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK @@ -27,3 +37,4 @@ Table Op Msg_type Msg_text test.t1 optimize status OK DROP TABLE t1; SET GLOBAL innodb_defragment = @innodb_defragment_orig; +SET GLOBAL innodb_optimize_fulltext_only = @innodb_optimize_fulltext_orig; diff --git a/mysql-test/suite/innodb/r/innodb_query_cache.result b/mysql-test/suite/innodb/r/innodb_query_cache.result new file mode 100644 index 00000000000..bbacbdfd748 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_query_cache.result @@ -0,0 +1,39 @@ +# +# MDEV-16087 Inconsistent SELECT results when query cache is enabled +# +set GLOBAL query_cache_type=ON; +set LOCAL query_cache_type=ON; +create table t1 (id bigint(20) auto_increment, primary key (id)) ENGINE=InnoDB; +create table t2 (id bigint(20) auto_increment, primary key (id)) ENGINE=InnoDB; +create table t3 (id bigint(20) auto_increment, primary key (id)) ENGINE=InnoDB; +connect con1,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +select * from t2; +id +connection default; +insert into t3 () values (); +connection con1; +insert into t1 () values (); +select * from t3; +id +connect con2,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +select * from t3; +id +1 +select * from t3; +id +1 +select sql_no_cache * from t3; +id +1 +rollback; +connection con1; +rollback; +disconnect con1; +disconnect con2; +connection default; +drop table t1; +drop table t2; +drop table t3; +set GLOBAL query_cache_type=default; diff --git a/mysql-test/suite/innodb/r/rename_table.result b/mysql-test/suite/innodb/r/rename_table.result index 3d7c3ff1b0e..9c45117cf10 100644 --- a/mysql-test/suite/innodb/r/rename_table.result +++ b/mysql-test/suite/innodb/r/rename_table.result @@ -18,3 +18,9 @@ path ./abc_def2/test1.ibd DROP DATABASE abc_def; DROP DATABASE abc_def2; +call mtr.add_suppression("InnoDB: (Operating system error|The error means|Cannot rename file)"); +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +RENAME TABLE t1 TO non_existing_db.t1; +ERROR HY000: Error on rename of './test/t1' to './non_existing_db/t1' (errno: 168 "Unknown (generic) error from engine") +FOUND 1 /\[ERROR\] InnoDB: Cannot rename file '.*t1\.ibd' to '.*non_existing_db/ in mysqld.1.err +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/strict_mode.result b/mysql-test/suite/innodb/r/strict_mode.result index 2f120afbc09..33afae708b4 100644 --- a/mysql-test/suite/innodb/r/strict_mode.result +++ b/mysql-test/suite/innodb/r/strict_mode.result @@ -2,7 +2,7 @@ # Bug #17852083 PRINT A WARNING WHEN DDL HAS AN ERROR IN # INNODB_STRICT_MODE = 1 # -call mtr.add_suppression("InnoDB: Cannot add field .* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page."); +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); set innodb_strict_mode = 0; create table t1 (id int auto_increment primary key, v varchar(32), diff --git a/mysql-test/suite/innodb/t/alter_non_null.inc b/mysql-test/suite/innodb/t/alter_non_null.inc new file mode 100644 index 00000000000..3d26aab5ab1 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_non_null.inc @@ -0,0 +1,2 @@ +# See also alter_non_null.combinations +--source include/have_innodb.inc diff --git a/mysql-test/suite/innodb/t/alter_not_null.combinations b/mysql-test/suite/innodb/t/alter_not_null.combinations new file mode 100644 index 00000000000..815223ce1cb --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_not_null.combinations @@ -0,0 +1,5 @@ +[COPY] +--alter_algorithm=copy + +[INPLACE] +--alter_algorithm=inplace diff --git a/mysql-test/suite/innodb/t/alter_not_null.test b/mysql-test/suite/innodb/t/alter_not_null.test index f4606dfa6c5..839d7f18a5e 100644 --- a/mysql-test/suite/innodb/t/alter_not_null.test +++ b/mysql-test/suite/innodb/t/alter_not_null.test @@ -1,75 +1,10 @@ ---source include/have_innodb.inc -set @@sql_mode = 'STRICT_TRANS_TABLES'; +--source alter_sql_mode.inc -CREATE TABLE t1(f1 INT)ENGINE=INNODB; -INSERT INTO t1 VALUES(NULL); -SELECT * FROM t1; ---enable_info -ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL; ---disable_info -SELECT * FROM t1; -DROP TABLE t1; +let $sql_mode = `SELECT @@SQL_MODE`; +let $error_code = 0; -CREATE TABLE t1(f1 CHAR(10))ENGINE=INNODB; -INSERT INTO t1 VALUES(NULL); -SELECT * FROM t1; ---enable_info -ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL; ---disable_info -SELECT * FROM t1; -DROP TABLE t1; +if ($sql_mode == "STRICT_TRANS_TABLES") { + let $error_code = WARN_DATA_TRUNCATED; +} -CREATE TABLE t1(f1 VARCHAR(10))ENGINE=INNODB; -INSERT INTO t1 VALUES(NULL); -SELECT * FROM t1; ---enable_info -ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL; ---disable_info -SELECT * FROM t1; -DROP TABLE t1; - -CREATE TABLE t1(f1 TEXT)ENGINE=INNODB; -INSERT INTO t1 VALUES(NULL); -SELECT * FROM t1; ---enable_info -ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc'; ---disable_info -SELECT * FROM t1; -DROP TABLE t1; - -CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB; -INSERT INTO t1 VALUES(2, 2, NULL); -SELECT * FROM t1; ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2), ALGORITHM=INPLACE; -UPDATE t1 SET f3 = 0; -SELECT * FROM t1; ---enable_info -ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2); ---disable_info -SELECT * FROM t1; -DROP TABLE t1; - -CREATE TABLE t1(f1 INT NOT NULL DEFAULT 0, b TINYINT)ENGINE=InnoDB; -INSERT INTO t1 VALUES(10, NULL); -SELECT * FROM t1; ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0), algorithm=INPLACE; -DROP TABLE t1; - -CREATE TABLE t1(a INT, v INT AS (a), c INT, d INT NOT NULL, e INT) ENGINE=InnoDB; -ALTER TABLE t1 DROP COLUMN c, CHANGE COLUMN e e INT NOT NULL, ALGORITHM=INPLACE; -DROP TABLE t1; - -CREATE TABLE t1 (a INT, v INT AS (a), d INT NOT NULL, e INT) ENGINE=InnoDB; -ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; -DROP TABLE t1; - ---echo # ---echo # MDEV-16126 Crash or ASAN heap-buffer-overflow in ---echo # mach_read_from_n_little_endian upon ALTER TABLE with blob ---echo # - -CREATE TABLE t1(a INT, v INT AS (a), b INT, c BLOB) ENGINE=InnoDB; -ALTER TABLE t1 ADD PRIMARY KEY(b); -DROP TABLE t1; +--source include/alter_not_null.inc diff --git a/mysql-test/suite/innodb/t/alter_not_null_debug.test b/mysql-test/suite/innodb/t/alter_not_null_debug.test index 9c1500dc829..058f0fc02a5 100644 --- a/mysql-test/suite/innodb/t/alter_not_null_debug.test +++ b/mysql-test/suite/innodb/t/alter_not_null_debug.test @@ -1,67 +1,71 @@ --source include/have_innodb.inc --source include/have_debug.inc --source include/have_debug_sync.inc +--source alter_sql_mode.inc + +let $sql_mode = `SELECT @@SQL_MODE`; +let $error_code = 0; + +if ($sql_mode == "STRICT_TRANS_TABLES") { + let $error_code = WARN_DATA_TRUNCATED; +} + + +# Alter table should fail for strict sql mode CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; -INSERT INTO t1 VALUES(1, NULL); +INSERT INTO t1 VALUES(1, 1); +--enable_info SET DEBUG_SYNC= 'row_merge_after_scan SIGNAL opened WAIT_FOR flushed'; -send ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; +send ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; connect (con1,localhost,root); SET DEBUG_SYNC= 'now WAIT_FOR opened'; INSERT INTO t1 VALUES(2, NULL); +UPDATE t1 SET c1 = 3 WHERE c2 = 1; SET DEBUG_SYNC= 'now SIGNAL flushed'; connection default; ---error ER_INVALID_USE_OF_NULL +--error $error_code reap; +--disable_info SELECT * FROM t1; -UPDATE t1 SET c2 = 0 WHERE c1 = 2; +DROP TABLE t1; + +# Alter table should successfully apply the log for the alter operation + +CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; +INSERT INTO t1 VALUES(1, 1); +--enable_info SET DEBUG_SYNC= 'row_merge_after_scan SIGNAL opened WAIT_FOR flushed'; ---echo # Alter ignore can convert the NULL values from ---echo # CONCURRENT DML to constants -send ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; +send ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; connection con1; SET DEBUG_SYNC= 'now WAIT_FOR opened'; -UPDATE t1 SET c2 = NULL WHERE c1 = 2; -INSERT INTO t1 VALUES (3, NULL); +INSERT INTO t1 VALUES(2, 3); +UPDATE t1 SET c1 = 3 WHERE c2 = 1; SET DEBUG_SYNC= 'now SIGNAL flushed'; connection default; reap; +--disable_info SELECT * FROM t1; DROP TABLE t1; +# Alter ignore should not give error CREATE TABLE t1(c1 INT NOT NULL, c2 INT, c3 INT, PRIMARY KEY(c1))ENGINE=INNODB; -INSERT INTO t1 VALUES(1, NULL, NULL); +INSERT INTO t1 VALUES(1, 2, 3); +--enable_info SET DEBUG_SYNC= 'row_merge_after_scan SIGNAL opened WAIT_FOR flushed'; ---echo # Alter Successfully converts from null to not null - -send ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; - +send ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; connection con1; SET DEBUG_SYNC= 'now WAIT_FOR opened'; UPDATE t1 SET c2= 2 WHERE c1 = 1; -INSERT INTO t1 VALUES (2, 3, 4); -SET DEBUG_SYNC= 'now SIGNAL flushed'; -connection default; -reap; -SELECT * FROM t1; - -SET DEBUG_SYNC= 'row_merge_after_scan -SIGNAL opened WAIT_FOR flushed'; ---echo # Alter fails because concurrent dml inserts null value - -send ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE; -connection con1; -SET DEBUG_SYNC= 'now WAIT_FOR opened'; -UPDATE t1 SET c3= 2 WHERE c1 = 2; -INSERT INTO t1 VALUES (4, 3, NULL); +INSERT INTO t1 VALUES (2, NULL, 4); SET DEBUG_SYNC= 'now SIGNAL flushed'; connection default; ---error ER_INVALID_USE_OF_NULL reap; +--disable_info SELECT * FROM t1; DROP TABLE t1; disconnect con1; diff --git a/mysql-test/suite/innodb/t/alter_sql_mode.combinations b/mysql-test/suite/innodb/t/alter_sql_mode.combinations new file mode 100644 index 00000000000..2749bd1077c --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_sql_mode.combinations @@ -0,0 +1,5 @@ +[STRICT] +--sql_mode=STRICT_TRANS_TABLES + +[NON-STRICT] +--sql_mode= diff --git a/mysql-test/suite/innodb/t/alter_sql_mode.inc b/mysql-test/suite/innodb/t/alter_sql_mode.inc new file mode 100644 index 00000000000..d51208502a7 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_sql_mode.inc @@ -0,0 +1,2 @@ +# See also alter_sql_mode.combinations +--source include/have_innodb.inc diff --git a/mysql-test/suite/innodb/t/innodb-16k.test b/mysql-test/suite/innodb/t/innodb-16k.test index a3a92bdec6a..d83351ea7bf 100644 --- a/mysql-test/suite/innodb/t/innodb-16k.test +++ b/mysql-test/suite/innodb/t/innodb-16k.test @@ -3,7 +3,7 @@ --source include/have_innodb.inc --source include/have_innodb_16k.inc -call mtr.add_suppression("InnoDB: Cannot add field .* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page."); +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); let $MYSQLD_DATADIR= `select @@datadir`; diff --git a/mysql-test/suite/innodb/t/innodb-alter-timestamp.test b/mysql-test/suite/innodb/t/innodb-alter-timestamp.test index 32a54354016..8b56fb5be5d 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-timestamp.test +++ b/mysql-test/suite/innodb/t/innodb-alter-timestamp.test @@ -3,7 +3,7 @@ CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb; INSERT INTO t1 VALUES(NULL); --enable_info ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +--error WARN_DATA_TRUNCATED ALTER TABLE t1 CHANGE i1 i1 INT UNSIGNED NOT NULL DEFAULT rand(), ALGORITHM=INPLACE; --error WARN_DATA_TRUNCATED @@ -12,7 +12,7 @@ ALGORITHM=COPY; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY(id), ALGORITHM=INPLACE; -ALTER TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE; +ALTER IGNORE TABLE t1 ADD PRIMARY KEY(i1), ALGORITHM=INPLACE; ALTER TABLE t1 CHANGE i1 id INT UNSIGNED NOT NULL AUTO_INCREMENT; --disable_info SELECT * FROM t1; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index db265ff8f67..b8f2d75c876 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -683,6 +683,8 @@ INSERT INTO t VALUES (NULL); SELECT * FROM t; SHOW CREATE TABLE t; DROP TABLE t; +SET auto_increment_increment = DEFAULT; + --echo # --echo # MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op()) @@ -700,3 +702,11 @@ CREATE TABLE t1 (a DOUBLE PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; INSERT INTO t1 VALUES (-1); SELECT * FROM t1; DROP TABLE t1; + + +--echo # +--echo # MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +--echo # + +SET @engine='INNODB'; +--source include/autoinc_mdev15353.inc diff --git a/mysql-test/suite/innodb/t/innodb-blob.test b/mysql-test/suite/innodb/t/innodb-blob.test index 1c91305b0ee..fbf0641880b 100644 --- a/mysql-test/suite/innodb/t/innodb-blob.test +++ b/mysql-test/suite/innodb/t/innodb-blob.test @@ -6,13 +6,13 @@ # The 7000 in this test is a bit less than half the innodb_page_size. --source include/have_innodb_16k.inc -# DEBUG_SYNC must be compiled in. +--source include/have_debug.inc --source include/have_debug_sync.inc # Embedded server does not support restarting --source include/not_embedded.inc -call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles!"); +FLUSH TABLES; CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=InnoDB; CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb/t/innodb-corrupted-table.test b/mysql-test/suite/innodb/t/innodb-corrupted-table.test index 60da461a33c..5d8e2bd1eda 100644 --- a/mysql-test/suite/innodb/t/innodb-corrupted-table.test +++ b/mysql-test/suite/innodb/t/innodb-corrupted-table.test @@ -2,11 +2,11 @@ --source include/not_embedded.inc # -# MDEV-9918: [ERROR] mysqld got signal 11 during ALTER TABLE `name` COLUMN ADD +# MDEV-9918: [ERROR] mysqld got signal 11 during ALTER TABLE `name` COLUMN ADD # -call mtr.add_suppression("Table .* has a primary key in InnoDB data dictionary, but not in MariaDB.*"); -call mtr.add_suppression("InnoDB: Table .* contains .* indexes inside InnoDB, which is different from the number of indexes .* defined in the MariaDB.*"); +call mtr.add_suppression("Table .* has a primary key in InnoDB data dictionary, but not in MariaDB"); +call mtr.add_suppression("InnoDB: Table .* contains .* indexes inside InnoDB"); create table t1 (pk int, i int, key(i)) engine=InnoDB; insert into t1 values (1,1),(2,2); diff --git a/mysql-test/suite/innodb/t/innodb-mdev-7513.test b/mysql-test/suite/innodb/t/innodb-mdev-7513.test index 88f941ef70d..c0e16b9e9d2 100644 --- a/mysql-test/suite/innodb/t/innodb-mdev-7513.test +++ b/mysql-test/suite/innodb/t/innodb-mdev-7513.test @@ -3,8 +3,7 @@ # MDEV-7513: ib_warn_row_too_big dereferences null thd -call mtr.add_suppression("InnoDB: Cannot add field `.* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page."); -call mtr.add_suppression("Row size too large (> 8126)*"); +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); --disable_warnings CREATE TABLE t1 ( text1 TEXT, diff --git a/mysql-test/suite/innodb/t/innodb-mdev7046.test b/mysql-test/suite/innodb/t/innodb-mdev7046.test index 4804e253427..4e32c13ee50 100644 --- a/mysql-test/suite/innodb/t/innodb-mdev7046.test +++ b/mysql-test/suite/innodb/t/innodb-mdev7046.test @@ -9,9 +9,9 @@ # Ignore OS errors -call mtr.add_suppression("InnoDB: File ./test/t1*"); -call mtr.add_suppression("InnoDB: Error number*"); -call mtr.add_suppression("InnoDB: File ./test/t1#p#p1#sp#p1sp0.ibd: 'rename' returned OS error*"); +call mtr.add_suppression("InnoDB: File ./test/t1"); +call mtr.add_suppression("InnoDB: Error number"); +call mtr.add_suppression("InnoDB: Cannot rename file '.*/test/t1#[Pp]#p1#[Ss][Pp]#p1sp0\\.ibd' to"); call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation."); # MDEV-7046: MySQL#74480 - Failing assertion: os_file_status(newpath, &exists, &type) diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_default.test b/mysql-test/suite/innodb/t/innodb-page_compression_default.test index 1cc6c917548..34b1829485e 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_default.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_default.test @@ -1,8 +1,6 @@ --source include/have_innodb.inc --source include/not_embedded.inc -call mtr.add_suppression("InnoDB: Compression failed for space [0-9]+ name test/innodb_page_compressed[0-9] len [0-9]+ err 2 write_size [0-9]+."); - # All page compression test use the same --source include/innodb-page-compression.inc diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_snappy.test b/mysql-test/suite/innodb/t/innodb-page_compression_snappy.test index 532ec294d28..0186c24ef2e 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_snappy.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_snappy.test @@ -2,8 +2,6 @@ -- source include/have_innodb_snappy.inc --source include/not_embedded.inc -call mtr.add_suppression("InnoDB: Compression failed for space [0-9]+ name test/innodb_page_compressed[0-9] len [0-9]+ err 2 write_size [0-9]+."); - # snappy set global innodb_compression_algorithm = snappy; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index 538e4b68762..edf83247142 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -359,7 +359,7 @@ SET @old_sql_mode = @@sql_mode; # And adding a PRIMARY KEY will also add NOT NULL implicitly! SET @@sql_mode = 'STRICT_TRANS_TABLES'; --error ER_DUP_ENTRY -ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)), +ALTER IGNORE TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)), ALGORITHM = INPLACE; SET @@sql_mode = @old_sql_mode; @@ -384,7 +384,7 @@ SET DEBUG_SYNC = 'now SIGNAL ins_done0'; --echo # session con1 connection con1; ---error ER_INVALID_USE_OF_NULL +--error WARN_DATA_TRUNCATED reap; SET @@sql_mode = @old_sql_mode; diff --git a/mysql-test/suite/innodb/t/innodb_bug27216817.test b/mysql-test/suite/innodb/t/innodb_bug27216817.test deleted file mode 100644 index a93932b4a04..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug27216817.test +++ /dev/null @@ -1,28 +0,0 @@ -# -# BUG#27216817: INNODB: FAILING ASSERTION: -# PREBUILT->TABLE->N_MYSQL_HANDLES_OPENED == 1 -# - -source include/have_innodb.inc; -create table t1 (a int not null, b int not null) engine=innodb; -insert t1 values (1,2),(3,4); - -lock table t1 write, t1 tr read; -flush status; -alter table t1 add primary key (b); -show status like 'Handler_read_rnd_next'; -unlock tables; -alter table t1 drop primary key; - -lock table t1 write; -flush status; -alter table t1 add primary key (b); -show status like 'Handler_read_rnd_next'; -unlock tables; -alter table t1 drop primary key; - -flush status; -alter table t1 add primary key (b); -show status like 'Handler_read_rnd_next'; - -drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_defragment_small.test b/mysql-test/suite/innodb/t/innodb_defragment_small.test index 8500c173af7..6259dac448e 100644 --- a/mysql-test/suite/innodb/t/innodb_defragment_small.test +++ b/mysql-test/suite/innodb/t/innodb_defragment_small.test @@ -1,10 +1,17 @@ --source include/have_innodb.inc SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment; +SET @innodb_optimize_fulltext_orig=@@GLOBAL.innodb_optimize_fulltext_only; SET GLOBAL innodb_defragment = 1; +SET GLOBAL innodb_optimize_fulltext_only = 0; -# Small tests copied from innodb.innodb_defragment -CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB; +--echo # +--echo # MDEV-12198 innodb_defragment=1 crashes server on +--echo # OPTIMIZE TABLE when FULLTEXT index exists +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), + KEY(a, b), FULLTEXT KEY(b)) ENGINE=INNODB; OPTIMIZE TABLE t1; INSERT INTO t1 VALUES (100000, REPEAT('A', 256)); @@ -13,16 +20,17 @@ INSERT INTO t1 VALUES (300000, REPEAT('A', 256)); INSERT INTO t1 VALUES (400000, REPEAT('A', 256)); OPTIMIZE TABLE t1; -DROP TABLE t1; --echo # ---echo # MDEV-12198 innodb_defragment=1 crashes server on ---echo # OPTIMIZE TABLE when FULLTEXT index exists +--echo # MDEV-15824 innodb_defragment=ON trumps +--echo # innodb_optimize_fulltext_only=ON in OPTIMIZE TABLE --echo # -CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB; - +SET GLOBAL innodb_optimize_fulltext_only = 1; OPTIMIZE TABLE t1; +SET GLOBAL innodb_defragment = 0; +OPTIMIZE TABLE t1; + DROP TABLE t1; CREATE TABLE t1 (c POINT PRIMARY KEY, SPATIAL INDEX(c)) ENGINE=InnoDB; @@ -30,3 +38,4 @@ OPTIMIZE TABLE t1; DROP TABLE t1; SET GLOBAL innodb_defragment = @innodb_defragment_orig; +SET GLOBAL innodb_optimize_fulltext_only = @innodb_optimize_fulltext_orig; diff --git a/mysql-test/suite/innodb/t/innodb_query_cache.test b/mysql-test/suite/innodb/t/innodb_query_cache.test new file mode 100644 index 00000000000..7dbdf986946 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_query_cache.test @@ -0,0 +1,47 @@ +-- source include/have_innodb.inc +-- source include/have_query_cache.inc +-- source include/not_embedded.inc + +--echo # +--echo # MDEV-16087 Inconsistent SELECT results when query cache is enabled +--echo # + +set GLOBAL query_cache_type=ON; +set LOCAL query_cache_type=ON; + +create table t1 (id bigint(20) auto_increment, primary key (id)) ENGINE=InnoDB; +create table t2 (id bigint(20) auto_increment, primary key (id)) ENGINE=InnoDB; +create table t3 (id bigint(20) auto_increment, primary key (id)) ENGINE=InnoDB; + +connect (con1,localhost,root); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +select * from t2; + +connection default; +insert into t3 () values (); + +connection con1; +insert into t1 () values (); +select * from t3; + +connect (con2,localhost,root); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +select * from t3; +select * from t3; +select sql_no_cache * from t3; + +rollback; + +connection con1; + +rollback; + +disconnect con1; +disconnect con2; +connection default; + +drop table t1; +drop table t2; +drop table t3; + +set GLOBAL query_cache_type=default; diff --git a/mysql-test/suite/innodb/t/rename_table.test b/mysql-test/suite/innodb/t/rename_table.test index ea9f70bacb0..0191a94def2 100644 --- a/mysql-test/suite/innodb/t/rename_table.test +++ b/mysql-test/suite/innodb/t/rename_table.test @@ -29,3 +29,17 @@ DROP DATABASE abc_def; --source include/restart_mysqld.inc DROP DATABASE abc_def2; + +call mtr.add_suppression("InnoDB: (Operating system error|The error means|Cannot rename file)"); + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--replace_result "\\" "/" +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO non_existing_db.t1; + +--let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot rename file '.*t1\.ibd' to '.*non_existing_db +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +--source include/search_pattern_in_file.inc + +# Cleanup +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/strict_mode.test b/mysql-test/suite/innodb/t/strict_mode.test index 48fc1ef7881..e93b4cc9df9 100644 --- a/mysql-test/suite/innodb/t/strict_mode.test +++ b/mysql-test/suite/innodb/t/strict_mode.test @@ -5,7 +5,7 @@ --echo # INNODB_STRICT_MODE = 1 --echo # -call mtr.add_suppression("InnoDB: Cannot add field .* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page."); +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); set innodb_strict_mode = 0; diff --git a/mysql-test/suite/innodb_zip/r/4k.result b/mysql-test/suite/innodb_zip/r/4k.result index 585e54f1b94..e7e0d65b487 100644 --- a/mysql-test/suite/innodb_zip/r/4k.result +++ b/mysql-test/suite/innodb_zip/r/4k.result @@ -22,6 +22,10 @@ AND t.name LIKE 'mysql%' table_name n_cols table_flags index_name root_page type n_fields merge_threshold mysql/innodb_index_stats 11 33 PRIMARY 3 3 4 50 mysql/innodb_table_stats 9 33 PRIMARY 3 3 2 50 +mysql/transaction_registry 8 33 PRIMARY 3 3 1 50 +mysql/transaction_registry 8 33 commit_id 4 2 1 50 +mysql/transaction_registry 8 33 begin_timestamp 5 0 1 50 +mysql/transaction_registry 8 33 commit_timestamp 6 0 2 50 CREATE TABLE t1 (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; CREATE TABLE t2 (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; CREATE TABLE t3 (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb; diff --git a/mysql-test/suite/innodb_zip/r/8k.result b/mysql-test/suite/innodb_zip/r/8k.result index c6ca2c7a9d3..76cc9d59aba 100644 --- a/mysql-test/suite/innodb_zip/r/8k.result +++ b/mysql-test/suite/innodb_zip/r/8k.result @@ -22,6 +22,10 @@ AND t.name LIKE 'mysql%' table_name n_cols table_flags index_name root_page type n_fields merge_threshold mysql/innodb_index_stats 11 33 PRIMARY 3 3 4 50 mysql/innodb_table_stats 9 33 PRIMARY 3 3 2 50 +mysql/transaction_registry 8 33 PRIMARY 3 3 1 50 +mysql/transaction_registry 8 33 commit_id 4 2 1 50 +mysql/transaction_registry 8 33 begin_timestamp 5 0 1 50 +mysql/transaction_registry 8 33 commit_timestamp 6 0 2 50 CREATE TABLE t1 (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; CREATE TABLE t2 (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; CREATE TABLE t3 (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb; diff --git a/mysql-test/suite/maria/maria-autoinc.result b/mysql-test/suite/maria/maria-autoinc.result new file mode 100644 index 00000000000..a4ae1f72c1e --- /dev/null +++ b/mysql-test/suite/maria/maria-autoinc.result @@ -0,0 +1,120 @@ +# +# MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +# +SET @engine='ARIA'; +CREATE PROCEDURE autoinc_mdev15353_one(engine VARCHAR(64), t VARCHAR(64)) +BEGIN +DECLARE query TEXT DEFAULT 'CREATE TABLE t1 (' + ' id TTT NOT NULL AUTO_INCREMENT,' + ' name CHAR(30) NOT NULL,' + ' PRIMARY KEY (id)) ENGINE=EEE'; +EXECUTE IMMEDIATE REPLACE(REPLACE(query,'TTT', t), 'EEE', engine); +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +SELECT * FROM t1; +UPDATE t1 SET id=-1 WHERE id=1; +SELECT * FROM t1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; +END; +$$ +CALL autoinc_mdev15353_one(@engine, 'tinyint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'smallint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` smallint(6) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'mediumint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` mediumint(9) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'int'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'bigint'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'float'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` float NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +CALL autoinc_mdev15353_one(@engine, 'double'); +Table Create Table +t1 CREATE TABLE `t1` ( + `id` double NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +id name +1 dog +id name +-1 dog +id name +-1 dog +2 cat +DROP PROCEDURE autoinc_mdev15353_one; diff --git a/mysql-test/suite/maria/maria-autoinc.test b/mysql-test/suite/maria/maria-autoinc.test new file mode 100644 index 00000000000..e7dc10b503b --- /dev/null +++ b/mysql-test/suite/maria/maria-autoinc.test @@ -0,0 +1,8 @@ +-- source include/have_maria.inc + +--echo # +--echo # MDEV-15352 AUTO_INCREMENT breaks after updating a column value to a negative number +--echo # + +SET @engine='ARIA'; +--source include/autoinc_mdev15353.inc diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result index bd2403ad461..106bb85c4c8 100644 --- a/mysql-test/suite/maria/maria.result +++ b/mysql-test/suite/maria/maria.result @@ -2766,6 +2766,35 @@ INSERT INTO t1 (b) VALUES (''); ALTER TABLE t1 ENABLE KEYS; DROP TABLE t1; # +# Start of 5.5 tests +# +# +# MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +# +CREATE TABLE t1 ( +id TINYINT NOT NULL AUTO_INCREMENT, +name CHAR(30) NOT NULL, +PRIMARY KEY (id) +) ENGINE=ARIA; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +id name +-1 dog +2 cat +DROP TABLE t1; +# +# End of 5.5 tests +# +# # BUG#47444 - --myisam_repair_threads > 1 can result in all index # cardinalities=1 # diff --git a/mysql-test/suite/maria/maria.test b/mysql-test/suite/maria/maria.test index e4f8d2427c4..d7710047f48 100644 --- a/mysql-test/suite/maria/maria.test +++ b/mysql-test/suite/maria/maria.test @@ -1989,6 +1989,30 @@ ALTER TABLE t1 ENABLE KEYS; DROP TABLE t1; --echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +--echo # + +CREATE TABLE t1 ( + id TINYINT NOT NULL AUTO_INCREMENT, + name CHAR(30) NOT NULL, + PRIMARY KEY (id) +) ENGINE=ARIA; +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # + +--echo # --echo # BUG#47444 - --myisam_repair_threads > 1 can result in all index --echo # cardinalities=1 --echo # diff --git a/mysql-test/suite/mariabackup/apply-log-only-incr.test b/mysql-test/suite/mariabackup/apply-log-only-incr.test index 25cb3a82023..74ab680d840 100644 --- a/mysql-test/suite/mariabackup/apply-log-only-incr.test +++ b/mysql-test/suite/mariabackup/apply-log-only-incr.test @@ -36,7 +36,7 @@ connection default; --disable_result_log exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --ftwrl-wait-timeout=5 --ftwrl-wait-threshold=300 --ftwrl-wait-query-type=all --target-dir=$incremental_dir --incremental-basedir=$basedir ; -exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir ; +exec $XTRABACKUP --prepare --verbose --apply-log-only --target-dir=$basedir ; --enable_result_log let SEARCH_FILE=$MYSQLTEST_VARDIR/log/current_test; @@ -44,7 +44,7 @@ let SEARCH_FILE=$MYSQLTEST_VARDIR/log/current_test; --source include/search_pattern_in_file.inc --echo # expect NOT FOUND -exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ; +exec $XTRABACKUP --prepare --verbose --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ; --source include/search_pattern_in_file.inc --echo # expect NOT FOUND diff --git a/mysql-test/suite/mariabackup/include/have_rocksdb.inc b/mysql-test/suite/mariabackup/include/have_rocksdb.inc new file mode 100644 index 00000000000..d59f76f6cf3 --- /dev/null +++ b/mysql-test/suite/mariabackup/include/have_rocksdb.inc @@ -0,0 +1,4 @@ +if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'rocksdb'`) +{ + --skip Requires rocksdb +}
\ No newline at end of file diff --git a/mysql-test/suite/mariabackup/mdev-14447.test b/mysql-test/suite/mariabackup/mdev-14447.test index 48f37646231..689b578f2ab 100644 --- a/mysql-test/suite/mariabackup/mdev-14447.test +++ b/mysql-test/suite/mariabackup/mdev-14447.test @@ -18,8 +18,8 @@ exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir --disable_result_log echo # Prepare full backup, apply incremental one; -exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir; -exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ; +exec $XTRABACKUP --prepare --verbose --apply-log-only --target-dir=$basedir; +exec $XTRABACKUP --prepare --verbose --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ; echo # Restore and check results; let $targetdir=$basedir; diff --git a/mysql-test/suite/mariabackup/rename_during_mdl_lock.result b/mysql-test/suite/mariabackup/rename_during_mdl_lock.result new file mode 100644 index 00000000000..982851438f2 --- /dev/null +++ b/mysql-test/suite/mariabackup/rename_during_mdl_lock.result @@ -0,0 +1,3 @@ +CREATE TABLE t1(i int) ENGINE INNODB; +FOUND 1 /failed to execute query SELECT 1 FROM/ in backup.log +DROP TABLE t2; diff --git a/mysql-test/suite/mariabackup/rename_during_mdl_lock.test b/mysql-test/suite/mariabackup/rename_during_mdl_lock.test new file mode 100644 index 00000000000..0a41f1dfe74 --- /dev/null +++ b/mysql-test/suite/mariabackup/rename_during_mdl_lock.test @@ -0,0 +1,13 @@ +--source include/have_debug.inc +let $targetdir=$MYSQLTEST_VARDIR/backup; +mkdir $targetdir; +CREATE TABLE t1(i int) ENGINE INNODB; +--error 1 +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table --dbug=+d,rename_during_mdl_lock_table 2>$targetdir/backup.log; + +let SEARCH_FILE=$targetdir/backup.log; +let SEARCH_PATTERN=failed to execute query SELECT 1 FROM; +source include/search_pattern_in_file.inc; + +DROP TABLE t2; +rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/xb_rocksdb.opt b/mysql-test/suite/mariabackup/xb_rocksdb.opt new file mode 100644 index 00000000000..e582413e5b5 --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb.opt @@ -0,0 +1 @@ +--plugin-load=$HA_ROCKSDB_SO
\ No newline at end of file diff --git a/mysql-test/suite/mariabackup/xb_rocksdb.result b/mysql-test/suite/mariabackup/xb_rocksdb.result new file mode 100644 index 00000000000..84476eeaba0 --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb.result @@ -0,0 +1,22 @@ +CREATE TABLE t(i INT) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); +# xtrabackup backup +INSERT INTO t VALUES(2); +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart server +SELECT * FROM t; +i +1 +# xbstream extract +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart server +SELECT * FROM t; +i +1 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/xb_rocksdb.test b/mysql-test/suite/mariabackup/xb_rocksdb.test new file mode 100644 index 00000000000..e41f3b2bf7e --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb.test @@ -0,0 +1,52 @@ +--source include/have_rocksdb.inc + +CREATE TABLE t(i INT) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); +echo # xtrabackup backup; +# we'll backup to both directory and to stream to restore that later + +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +let $stream=$MYSQLTEST_VARDIR/tmp/backup.xb; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir $backup_extra_param; +--enable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --stream=xbstream > $stream 2>$MYSQLTEST_VARDIR/tmp/backup_stream.log; + +INSERT INTO t VALUES(2); + + +echo # xtrabackup prepare; +--disable_result_log +exec $XTRABACKUP --prepare --target-dir=$targetdir; +-- source include/restart_and_restore.inc +--enable_result_log + +SELECT * FROM t; + +rmdir $targetdir; +mkdir $targetdir; + + +echo # xbstream extract; + +exec $XBSTREAM -x -C $targetdir < $stream; + +echo # xtrabackup prepare; +--disable_result_log +exec $XTRABACKUP --prepare --target-dir=$targetdir; + +let $_datadir= `SELECT @@datadir`; +echo # shutdown server; +--source include/shutdown_mysqld.inc +echo # remove datadir; +rmdir $_datadir; +echo # xtrabackup move back; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --move-back --datadir=$_datadir --target-dir=$targetdir $copy_back_extra_param; +echo # restart server; +--source include/start_mysqld.inc + +--enable_result_log +SELECT * FROM t; + +DROP TABLE t; +rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir.opt b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.opt new file mode 100644 index 00000000000..0f069018e15 --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.opt @@ -0,0 +1 @@ +--plugin-load=$HA_ROCKSDB_SO --loose-rocksdb-datadir=$MYSQLTEST_VARDIR/tmp/rocksdb_datadir
\ No newline at end of file diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir.result b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.result new file mode 100644 index 00000000000..9227198cbec --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.result @@ -0,0 +1,9 @@ +CREATE TABLE t(i INT) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); +# xtrabackup backup +INSERT INTO t VALUES(2); +# xtrabackup prepare +SELECT * FROM t; +i +1 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test new file mode 100644 index 00000000000..c2e90d9075b --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test @@ -0,0 +1,34 @@ +if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'rocksdb'`) +{ + --skip Requires rocksdb +} + + +CREATE TABLE t(i INT) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); +echo # xtrabackup backup; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log + +INSERT INTO t VALUES(2); + + +echo # xtrabackup prepare; +--disable_result_log +exec $XTRABACKUP --prepare --target-dir=$targetdir; +let $_datadir= `SELECT @@datadir`; +let $_rocksdb_datadir=`SELECT @@rocksdb_datadir`; +--source include/shutdown_mysqld.inc +rmdir $_datadir; +rmdir $_rocksdb_datadir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --move-back --target-dir=$targetdir --datadir=$_datadir --rocksdb_datadir=$_rocksdb_datadir; +--enable_result_log +--source include/start_mysqld.inc + + +SELECT * FROM t; +DROP TABLE t; +rmdir $targetdir; + diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.opt b/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.opt new file mode 100644 index 00000000000..0f069018e15 --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.opt @@ -0,0 +1 @@ +--plugin-load=$HA_ROCKSDB_SO --loose-rocksdb-datadir=$MYSQLTEST_VARDIR/tmp/rocksdb_datadir
\ No newline at end of file diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.result b/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.result new file mode 100644 index 00000000000..9227198cbec --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.result @@ -0,0 +1,9 @@ +CREATE TABLE t(i INT) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); +# xtrabackup backup +INSERT INTO t VALUES(2); +# xtrabackup prepare +SELECT * FROM t; +i +1 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.test b/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.test new file mode 100644 index 00000000000..a71c63b98cc --- /dev/null +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir_debug.test @@ -0,0 +1,13 @@ +--source include/have_debug.inc +--source include/have_rocksdb.inc + +# Check how rocksdb backup works without hardlinks +let $backup_extra_param='--dbug=+d,no_hardlinks'; +let $copy_back_extra_param='--dbug=+d,no_hardlinks'; + +# Pretend that previous backup crashes, and left checkpoint directory +let $rocksdb_datadir= `SELECT @@rocksdb_datadir`; +mkdir $rocksdb_datadir/mariadb-checkpoint; + +--source xb_rocksdb_datadir.test + diff --git a/mysql-test/suite/parts/r/alter_data_directory_innodb.result b/mysql-test/suite/parts/r/alter_data_directory_innodb.result new file mode 100644 index 00000000000..d0ad8cd074c --- /dev/null +++ b/mysql-test/suite/parts/r/alter_data_directory_innodb.result @@ -0,0 +1,65 @@ +# +# MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir +# +CREATE TABLE t ( +a INT NOT NULL +) ENGINE=INNODB +PARTITION BY HASH (a) ( +PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB, +PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB +); +INSERT INTO t VALUES (1); +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY HASH (`a`) +(PARTITION `p1` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION `p2` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY HASH (`a`) +(PARTITION `p1` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION `p2` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) +ALTER TABLE t DROP PRIMARY KEY, ALGORITHM=COPY; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY HASH (`a`) +(PARTITION `p1` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION `p2` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) +SET @TMP = @@GLOBAL.INNODB_FILE_PER_TABLE; +SET GLOBAL INNODB_FILE_PER_TABLE=OFF; +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY HASH (`a`) +(PARTITION `p1` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION `p2` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) +SET GLOBAL INNODB_FILE_PER_TABLE=@TMP; +ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO ( +PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB, +PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB +); +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY HASH (`a`) +(PARTITION `p1` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION `p2` DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) +DROP TABLE t; diff --git a/mysql-test/suite/parts/t/alter_data_directory_innodb.test b/mysql-test/suite/parts/t/alter_data_directory_innodb.test new file mode 100644 index 00000000000..ac15e9bec6c --- /dev/null +++ b/mysql-test/suite/parts/t/alter_data_directory_innodb.test @@ -0,0 +1,46 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +--echo # +--echo # MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir +--echo # + +mkdir $MYSQLTEST_VARDIR/tmp/partitions_here; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval CREATE TABLE t ( + a INT NOT NULL +) ENGINE=INNODB +PARTITION BY HASH (a) ( + PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB, + PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB +); +INSERT INTO t VALUES (1); + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +ALTER TABLE t DROP PRIMARY KEY, ALGORITHM=COPY; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +SET @TMP = @@GLOBAL.INNODB_FILE_PER_TABLE; +SET GLOBAL INNODB_FILE_PER_TABLE=OFF; +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +SET GLOBAL INNODB_FILE_PER_TABLE=@TMP; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO ( + PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB, + PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB +); +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; + +DROP TABLE t; + +rmdir $MYSQLTEST_VARDIR/tmp/partitions_here/test; +rmdir $MYSQLTEST_VARDIR/tmp/partitions_here; diff --git a/mysql-test/suite/plugins/r/auth_ed25519.result b/mysql-test/suite/plugins/r/auth_ed25519.result index 1baec60da40..ee9320bbc6c 100644 --- a/mysql-test/suite/plugins/r/auth_ed25519.result +++ b/mysql-test/suite/plugins/r/auth_ed25519.result @@ -32,7 +32,7 @@ PLUGIN_AUTHOR Sergei Golubchik PLUGIN_DESCRIPTION Elliptic curve ED25519 based authentication PLUGIN_LICENSE GPL LOAD_OPTION ON -PLUGIN_MATURITY Beta +PLUGIN_MATURITY Stable PLUGIN_AUTH_VERSION 1.0-alpha create user test1@localhost identified via ed25519 using 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY'; show grants for test1@localhost; diff --git a/mysql-test/suite/plugins/r/processlist.result b/mysql-test/suite/plugins/r/processlist.result new file mode 100644 index 00000000000..c27534d9d78 --- /dev/null +++ b/mysql-test/suite/plugins/r/processlist.result @@ -0,0 +1,9 @@ +create table t1 (a int) engine=innodb; +start transaction; +insert t1 values (1); +connect con2,localhost,root; +state from show engine innodb status, must be empty + +disconnect con2; +connection default; +drop table t1; diff --git a/mysql-test/suite/plugins/t/processlist.test b/mysql-test/suite/plugins/t/processlist.test new file mode 100644 index 00000000000..39b715b867b --- /dev/null +++ b/mysql-test/suite/plugins/t/processlist.test @@ -0,0 +1,20 @@ +# +# MDEV-15359 Thread stay in "cleaning up" status after finishing +# +source include/have_innodb.inc; + +create table t1 (a int) engine=innodb; +start transaction; +insert t1 values (1); +let id=`select connection_id()`; +connect con2,localhost,root; +let $wait_condition=select state='' from information_schema.processlist where id = $id; +--source include/wait_condition.inc +replace_regex /\"/-/; #" +let s=`show engine innodb status`; +disable_query_log; +eval select regexp_replace("$s", '(?s)^.*MySQL thread id $id,.*root([^\n]*)\n.*', '\\\\1') as `state from show engine innodb status, must be empty`; +enable_query_log; +disconnect con2; +connection default; +drop table t1; diff --git a/mysql-test/suite/roles/grant_revoke_current.result b/mysql-test/suite/roles/grant_revoke_current.result index d9798463965..436bec92a8f 100644 --- a/mysql-test/suite/roles/grant_revoke_current.result +++ b/mysql-test/suite/roles/grant_revoke_current.result @@ -39,4 +39,5 @@ GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*34391 GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION GRANT USAGE ON *.* TO 'r1' set password=''; +update mysql.user set plugin=''; drop role r1; diff --git a/mysql-test/suite/roles/grant_revoke_current.test b/mysql-test/suite/roles/grant_revoke_current.test index 0ebe0170782..bffc04087b1 100644 --- a/mysql-test/suite/roles/grant_revoke_current.test +++ b/mysql-test/suite/roles/grant_revoke_current.test @@ -25,5 +25,7 @@ show grants; grant r1 to current_user() identified by 'barfoo'; show grants; set password=''; +#cleanup after MDEV-16238 +update mysql.user set plugin=''; drop role r1; diff --git a/mysql-test/suite/roles/set_default_role_ps-6960.result b/mysql-test/suite/roles/set_default_role_ps-6960.result index 60210d7f92c..c186e7bccb0 100644 --- a/mysql-test/suite/roles/set_default_role_ps-6960.result +++ b/mysql-test/suite/roles/set_default_role_ps-6960.result @@ -6,3 +6,4 @@ execute stmt; set password = ''; set default role NONE; drop role r1; +update mysql.user set plugin=''; diff --git a/mysql-test/suite/roles/set_default_role_ps-6960.test b/mysql-test/suite/roles/set_default_role_ps-6960.test index 8ac520e1776..8af95c9e8a0 100644 --- a/mysql-test/suite/roles/set_default_role_ps-6960.test +++ b/mysql-test/suite/roles/set_default_role_ps-6960.test @@ -13,3 +13,5 @@ execute stmt; set password = ''; set default role NONE; drop role r1; +#cleanup after MDEV-16238 +update mysql.user set plugin=''; diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc index 8bf5a4eea1e..548fdf789da 100644 --- a/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc @@ -5,9 +5,9 @@ # Requirements: ######################################### -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; sync_slave_with_master; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; connection master; diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index aed8bba3bc0..9eca21b38e4 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -20,21 +20,21 @@ GRANT DROP ON `test`.* TO 'rpl_do_grant'@'localhost' connection master; set password for rpl_do_grant@localhost=password("does it work?"); connection slave; -select password<>_binary'' from mysql.user where user=_binary'rpl_do_grant'; -password<>_binary'' +select authentication_string<>_binary'' from mysql.user where user=_binary'rpl_do_grant'; +authentication_string<>_binary'' 1 connection master; -update mysql.user set password='' where user='rpl_do_grant'; +update mysql.user set authentication_string='' where user='rpl_do_grant'; flush privileges; -select password<>'' from mysql.user where user='rpl_do_grant'; -password<>'' +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; +authentication_string<>'' 0 set sql_mode='ANSI_QUOTES'; set password for rpl_do_grant@localhost=password('does it work?'); set sql_mode=''; connection slave; -select password<>'' from mysql.user where user='rpl_do_grant'; -password<>'' +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; +authentication_string<>'' 1 connection master; delete from mysql.user where user=_binary'rpl_do_grant'; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 1f6a9370090..24ce8899e2c 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -480,72 +480,72 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; ******************** CREATE USER ******************** CREATE USER 'user_test_rpl'@'localhost' IDENTIFIED BY PASSWORD '*1111111111111111111111111111111111111111'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection master; ******************** GRANT ******************** GRANT SELECT ON *.* TO 'user_test_rpl'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 Y +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 Y connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 Y +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 Y connection master; ******************** REVOKE ******************** REVOKE SELECT ON *.* FROM 'user_test_rpl'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection master; ******************** SET PASSWORD ******************** SET PASSWORD FOR 'user_test_rpl'@'localhost' = '*0000000000000000000000000000000000000000'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl mysql_native_password *0000000000000000000000000000000000000000 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl mysql_native_password *0000000000000000000000000000000000000000 N connection master; ******************** RENAME USER ******************** RENAME USER 'user_test_rpl'@'localhost' TO 'user_test_rpl_2'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl_2 *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl_2 mysql_native_password *0000000000000000000000000000000000000000 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl_2 *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl_2 mysql_native_password *0000000000000000000000000000000000000000 N connection master; ******************** DROP USER ******************** DROP USER 'user_test_rpl_2'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv connection master; INSERT INTO t1 VALUES(100, 'test'); diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result index 7c8a2a94104..07b080a72c3 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result @@ -610,8 +610,39 @@ a b 57 7 58 8 59 9 +connection server_1; +DELETE FROM t1; +DELETE FROM t2; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +connection server_2; +set global log_warnings=2; +BEGIN; +INSERT INTO t1 SET a=1; +connection server_1; +SET @save.binlog_format=@@session.binlog_format; +SET @@SESSION.binlog_format=row; +BEGIN; +INSERT INTO t1 SET a=1; +INSERT INTO t2 SET a=1; +COMMIT; +BEGIN; +DELETE FROM t2; +COMMIT; +connection server_2; +connection server_2; +ROLLBACK; +connection server_1; +SET @@SESSION.binlog_format= @save.binlog_format; +DELETE FROM t1; +DELETE FROM t2; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc connection server_2; include/stop_slave.inc +set global log_warnings=default; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index 83b9a84744f..0024c7039e4 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -27,20 +27,20 @@ show grants for rpl_do_grant@localhost; connection master; set password for rpl_do_grant@localhost=password("does it work?"); sync_slave_with_master; -select password<>_binary'' from mysql.user where user=_binary'rpl_do_grant'; +select authentication_string<>_binary'' from mysql.user where user=_binary'rpl_do_grant'; # # Bug#24158 SET PASSWORD in binary log fails under ANSI_QUOTES # connection master; -update mysql.user set password='' where user='rpl_do_grant'; +update mysql.user set authentication_string='' where user='rpl_do_grant'; flush privileges; -select password<>'' from mysql.user where user='rpl_do_grant'; +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; set sql_mode='ANSI_QUOTES'; set password for rpl_do_grant@localhost=password('does it work?'); set sql_mode=''; sync_slave_with_master; -select password<>'' from mysql.user where user='rpl_do_grant'; +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; # clear what we have done, to not influence other tests. diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test index b5d78033088..a49d59c4eb4 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test @@ -484,10 +484,69 @@ SELECT * FROM t2 WHERE a >= 40 ORDER BY a; SELECT * FROM t1 WHERE a >= 40 ORDER BY a; SELECT * FROM t2 WHERE a >= 40 ORDER BY a; -# Clean up. +# partial cleanup to reuse the tables by following tests +--connection server_1 +DELETE FROM t1; +DELETE FROM t2; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +# +# MDEV-13577 optimistic parallel slave errors out to error log unnecessary +# + +# The 1st of the following two trx:s a blocker on slave +--connection server_2 +set global log_warnings=2; +BEGIN; +INSERT INTO t1 SET a=1; + +--connection server_1 +SET @save.binlog_format=@@session.binlog_format; +SET @@SESSION.binlog_format=row; + +BEGIN; + INSERT INTO t1 SET a=1; + INSERT INTO t2 SET a=1; +COMMIT; +# This transaction is going to win optimistical race with above INSERT +# on slave while being depend on it. That means it will face a kind of temporary error +# and then will retry to succeed. +BEGIN; + DELETE FROM t2; +COMMIT; + +# First make sure DELETE raced indeed to get stuck at retrying stage +# where it runs "realistically" now. There is nomore optimistic error +# in the errorlog, which is downgraded to the warning level (when +# --log-warnings > 1), see above suppression. +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +# Next release the 1st trx to commit. +--connection server_2 +ROLLBACK; + +# MDEV-13577 local cleanup: +--connection server_1 +SET @@SESSION.binlog_format= @save.binlog_format; +DELETE FROM t1; +DELETE FROM t2; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +# +# Clean up. +# --connection server_2 --source include/stop_slave.inc +set global log_warnings=default; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; --source include/start_slave.inc diff --git a/mysql-test/suite/sys_vars/r/maximum_basic.result b/mysql-test/suite/sys_vars/r/maximum_basic.result index 20b6bbc962e..becd6da91f4 100644 --- a/mysql-test/suite/sys_vars/r/maximum_basic.result +++ b/mysql-test/suite/sys_vars/r/maximum_basic.result @@ -16,3 +16,33 @@ Warning 1292 Truncated incorrect max_join_size value: '40960' SELECT @@session.max_join_size; @@session.max_join_size 8192 +SET @@session.use_stat_tables= COMPLEMENTARY; +SELECT @@session.use_stat_tables; +@@session.use_stat_tables +COMPLEMENTARY +SET @@session.use_stat_tables= PREFERABLY; +Warnings: +Warning 1292 Truncated incorrect use_stat_tables value: 'PREFERABLY' +SELECT @@session.use_stat_tables; +@@session.use_stat_tables +COMPLEMENTARY +SET @@session.use_stat_tables= 2; +Warnings: +Warning 1292 Truncated incorrect use_stat_tables value: '2' +SELECT @@session.use_stat_tables; +@@session.use_stat_tables +COMPLEMENTARY +SET @@session.sql_mode= 'REAL_AS_FLOAT'; +SELECT @@session.sql_mode; +@@session.sql_mode +REAL_AS_FLOAT +SET @@session.sql_mode= 'REAL_AS_FLOAT,ANSI_QUOTES'; +SELECT @@session.sql_mode; +@@session.sql_mode +REAL_AS_FLOAT,ANSI_QUOTES +SET @@session.sql_mode= 'ANSI_QUOTES,IGNORE_SPACE'; +Warnings: +Warning 1292 Truncated incorrect sql_mode value: 'ANSI_QUOTES,IGNORE_SPACE' +SELECT @@session.sql_mode; +@@session.sql_mode +ANSI_QUOTES diff --git a/mysql-test/suite/sys_vars/t/maximum_basic-master.opt b/mysql-test/suite/sys_vars/t/maximum_basic-master.opt index b6e5666f4fb..16e365d491c 100644 --- a/mysql-test/suite/sys_vars/t/maximum_basic-master.opt +++ b/mysql-test/suite/sys_vars/t/maximum_basic-master.opt @@ -1,3 +1,5 @@ --maximum-auto-increment-increment=8192 --maximum-tmp-table-size=8192 --maximum-max-join-size=8192 +--maximum-use-stat-tables=COMPLEMENTARY +--maximum-sql-mode='REAL_AS_FLOAT,ANSI_QUOTES' diff --git a/mysql-test/suite/sys_vars/t/maximum_basic.test b/mysql-test/suite/sys_vars/t/maximum_basic.test index 9961f65883a..3153d62d562 100644 --- a/mysql-test/suite/sys_vars/t/maximum_basic.test +++ b/mysql-test/suite/sys_vars/t/maximum_basic.test @@ -18,3 +18,22 @@ SELECT @@session.tmp_table_size; SET @@session.max_join_size=40960; SELECT @@session.max_join_size; +# +# enum +# +SET @@session.use_stat_tables= COMPLEMENTARY; +SELECT @@session.use_stat_tables; +SET @@session.use_stat_tables= PREFERABLY; +SELECT @@session.use_stat_tables; +SET @@session.use_stat_tables= 2; +SELECT @@session.use_stat_tables; + +# +# set +# +SET @@session.sql_mode= 'REAL_AS_FLOAT'; +SELECT @@session.sql_mode; +SET @@session.sql_mode= 'REAL_AS_FLOAT,ANSI_QUOTES'; +SELECT @@session.sql_mode; +SET @@session.sql_mode= 'ANSI_QUOTES,IGNORE_SPACE'; +SELECT @@session.sql_mode; diff --git a/mysql-test/suite/unit/suite.pm b/mysql-test/suite/unit/suite.pm index c92363a8601..c8180c59240 100644 --- a/mysql-test/suite/unit/suite.pm +++ b/mysql-test/suite/unit/suite.pm @@ -40,7 +40,7 @@ sub start_test { my $bin=$ENV{MTR_BINDIR} || '..'; return "Not run for embedded server" if $::opt_embedded_server; return "Not configured to run ctest" unless -f "$bin/CTestTestfile.cmake"; - my ($ctest_vs)= $opt_vs_config ? "-C $opt_vs_config" : ""; + my ($ctest_vs)= $::opt_vs_config ? "-C ".substr($::opt_vs_config,1) : ""; my (@ctest_list)= `cd "$bin" && ctest $ctest_vs --show-only --verbose`; return "No ctest" if $?; diff --git a/mysql-test/suite/vcol/r/index.result b/mysql-test/suite/vcol/r/index.result new file mode 100644 index 00000000000..8860a728bd1 --- /dev/null +++ b/mysql-test/suite/vcol/r/index.result @@ -0,0 +1,91 @@ +# +# Test table with a key that consists of indirect virtual fields +# +CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=myisam; +insert into t1 (a) values (1),(2),(3); +update t1 set a=5 where a=3; +delete from t1 where a=1; +select * from t1; +a b c +2 3 4 +5 6 7 +select * from t1 where c=7; +a b c +5 6 7 +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +select * from t1; +a b c +2 3 4 +5 6 7 +drop table t1; +CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=innodb; +insert into t1 (a) values (1),(2),(3); +update t1 set a=5 where a=3; +delete from t1 where a=1; +select * from t1; +a b c +2 3 4 +5 6 7 +select * from t1 where c=7; +a b c +5 6 7 +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +select * from t1; +a b c +2 3 4 +5 6 7 +drop table t1; +# +# MDEV-15114 +# ASAN heap-use-after-free in mem_heap_dup or +# dfield_data_is_binary_equal +# +CREATE TABLE t1 ( +pk INT, +extra tinyint, +c TEXT, +vc LONGTEXT AS (c) VIRTUAL, +i INT, +PRIMARY KEY(pk), +UNIQUE(i), +INDEX(vc(64)) +) ENGINE=InnoDB; +INSERT INTO t1 (pk,extra, c, i) VALUES (1, 10, REPEAT('foo ',15000),0); +REPLACE INTO t1 (pk,extra, c,i) SELECT pk,extra+10, c,i FROM t1; +select pk, extra, left(c, 10), length(c), left(vc,10), length(vc), extra from t1; +pk extra left(c, 10) length(c) left(vc,10) length(vc) extra +1 20 foo foo fo 60000 foo foo fo 60000 20 +DROP TABLE t1; +# +# Update of deleted row with binary logging enabled +# +SET BINLOG_FORMAT=row; +CREATE TABLE t1 ( +pk INT, +c TEXT, +vc LONGTEXT AS (c) VIRTUAL, +i INT, +PRIMARY KEY(pk), +UNIQUE(i), +INDEX(vc(64)) +) ENGINE=InnoDB; +INSERT INTO t1 (pk,c,i) VALUES (1,REPEAT('foo ',15000),10); +INSERT INTO t1 (pk,c,i) VALUES (2,REPEAT('bar ',15000),11); +connect c1,localhost,root,,; +connection c1; +begin; +DELETE from t1 WHERE pk=1; +connection default; +update t1 set pk=1 where pk=2; +connection c1; +commit; +connection default; +select pk, left(c, 10), length(c), i from t1; +pk left(c, 10) length(c) i +1 bar bar ba 60000 11 +drop table t1; +disconnect c1; diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 130eb0ff51a..f3edfa9c026 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -352,6 +352,16 @@ a b c DROP TABLE t1; SET sql_mode=DEFAULT; # +# MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe +# +SHOW TABLES; +Tables_in_test +t1 +SHOW CREATE TABLE t1; +ERROR HY000: Incorrect information in file: './test/t1.frm' +ALTER TABLE t1; +ERROR HY000: Incorrect information in file: './test/t1.frm' +# # End of 5.5 tests # # diff --git a/mysql-test/suite/vcol/t/index.test b/mysql-test/suite/vcol/t/index.test new file mode 100644 index 00000000000..72eed0a8a40 --- /dev/null +++ b/mysql-test/suite/vcol/t/index.test @@ -0,0 +1,81 @@ +--source include/have_innodb.inc +--source include/have_log_bin.inc + +--echo # +--echo # Test table with a key that consists of indirect virtual fields +--echo # + +CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=myisam; +insert into t1 (a) values (1),(2),(3); +update t1 set a=5 where a=3; +delete from t1 where a=1; +select * from t1; +select * from t1 where c=7; +check table t1; +select * from t1; +drop table t1; + +CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=innodb; +insert into t1 (a) values (1),(2),(3); +update t1 set a=5 where a=3; +delete from t1 where a=1; +select * from t1; +select * from t1 where c=7; +check table t1; +select * from t1; +drop table t1; + +--echo # +--echo # MDEV-15114 +--echo # ASAN heap-use-after-free in mem_heap_dup or +--echo # dfield_data_is_binary_equal +--echo # + +CREATE TABLE t1 ( + pk INT, + extra tinyint, + c TEXT, + vc LONGTEXT AS (c) VIRTUAL, + i INT, + PRIMARY KEY(pk), + UNIQUE(i), + INDEX(vc(64)) +) ENGINE=InnoDB; + +INSERT INTO t1 (pk,extra, c, i) VALUES (1, 10, REPEAT('foo ',15000),0); +REPLACE INTO t1 (pk,extra, c,i) SELECT pk,extra+10, c,i FROM t1; +select pk, extra, left(c, 10), length(c), left(vc,10), length(vc), extra from t1; +DROP TABLE t1; + +--echo # +--echo # Update of deleted row with binary logging enabled +--echo # + +SET BINLOG_FORMAT=row; + +CREATE TABLE t1 ( + pk INT, + c TEXT, + vc LONGTEXT AS (c) VIRTUAL, + i INT, + PRIMARY KEY(pk), + UNIQUE(i), + INDEX(vc(64)) +) ENGINE=InnoDB; + +INSERT INTO t1 (pk,c,i) VALUES (1,REPEAT('foo ',15000),10); +INSERT INTO t1 (pk,c,i) VALUES (2,REPEAT('bar ',15000),11); + +--connect (c1,localhost,root,,) +--connection c1 +begin; +DELETE from t1 WHERE pk=1; +--connection default +--send update t1 set pk=1 where pk=2 +--connection c1 +commit; +--connection default +--reap +select pk, left(c, 10), length(c), i from t1; +drop table t1; +disconnect c1; diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 2244967a968..b351e1eb4a6 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -1,5 +1,7 @@ --source include/have_ucs2.inc +let $MYSQLD_DATADIR= `select @@datadir`; + --disable_warnings drop table if exists t1,t2; --enable_warnings @@ -321,6 +323,22 @@ SELECT * FROM t1; DROP TABLE t1; SET sql_mode=DEFAULT; + +--echo # +--echo # MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe +--echo # + +--copy_file std_data/frm/t1.frm $MYSQLD_DATADIR/test/t1.frm +SHOW TABLES; +--replace_result $MYSQLD_DATADIR ./ +--error ER_NOT_FORM_FILE +SHOW CREATE TABLE t1; +--replace_result $MYSQLD_DATADIR ./ +--error ER_NOT_FORM_FILE +ALTER TABLE t1; +--remove_file $MYSQLD_DATADIR/test/t1.frm + + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index fafcf3c30b0..8db23ef6d39 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -19,6 +19,10 @@ t CREATE TABLE `t` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING alter table t add column y int; ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +alter table t add primary key (a); +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +alter table t add unique key (a); +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t engine innodb; ERROR HY000: Not allowed for system-versioned `test`.`t`. Change to/from native system versioning engine is not supported. alter table t drop system versioning; @@ -528,5 +532,15 @@ use test; create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; alter table t1 modify s timestamp(6) as row start; ERROR HY000: Can not change system versioning field `s` +# ignore CHECK for historical rows +create or replace table t (a int) with system versioning; +insert into t values (0), (1); +delete from t where a = 0; +alter table t add check (a > 1); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t` +alter table t add check (a > 0); +insert into t values (0); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t` +insert into t values (2); drop database test; create database test; diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result index 52db0db429a..1711be5212e 100644 --- a/mysql-test/suite/versioning/r/replace.result +++ b/mysql-test/suite/versioning/r/replace.result @@ -26,3 +26,11 @@ id x current 1 2 0 1 3 1 drop table t; +# MDEV-15645 Assertion `table->insert_values' failed in write_record upon REPLACE into a view with underlying versioned table +create or replace table t1 (a int, b int, primary key (a), unique(b)) with system versioning; +insert into t1 values (1,1); +create or replace table t2 (c int); +create or replace view v as select t1.* from t1 join t2; +replace into v (a, b) select a, b from t1; +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 87b8166ef91..be0781af002 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -557,6 +557,18 @@ i call p(3); i 1 +# +# MDEV-15947 ASAN heap-use-after-free in Item_ident::print or in my_strcasecmp_utf8 or unexpected ER_BAD_FIELD_ERROR upon call of stored procedure reading from versioned table +# +create or replace table t1 (i int) with system versioning; +create or replace procedure p() select * from t1; +call p; +i +flush tables; +call p; +i +call p; +i drop procedure p; drop table t1; call verify_trt_dummy(34); diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index 7b2ea04985d..2e0db5f2cde 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -379,3 +379,99 @@ DROP TABLE tts; DROP TABLE ttx; DROP FUNCTION fts; DROP FUNCTION ftx; +# +# MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute +# +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; +CREATE TABLE t ( +a INT, +b INT, +row_start BIGINT UNSIGNED AS ROW START INVISIBLE, +row_end BIGINT UNSIGNED AS ROW END INVISIBLE, +PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; +INSERT INTO t VALUES (1,1); +# without table rebuild +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t +ON c.table_id=t.table_id +WHERE t.name='test/t' AND c.name='a'; +prtype +50179 +ALTER TABLE t +CHANGE a a INT WITHOUT SYSTEM VERSIONING; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t +ON c.table_id=t.table_id +WHERE t.name='test/t' AND c.name='a'; +prtype +1027 +UPDATE t SET a=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; +COUNT(*) +1 +# with table rebuild +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t +ON c.table_id=t.table_id +WHERE t.name='test/t' AND c.name='a'; +prtype +1027 +ALTER TABLE t +CHANGE a a INT WITH SYSTEM VERSIONING, +ADD PRIMARY KEY pk(a); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t +ON c.table_id=t.table_id +WHERE t.name='test/t' AND c.name='a'; +prtype +50435 +UPDATE t SET a=1; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; +COUNT(*) +2 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `row_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE, + PRIMARY KEY (`a`,`row_end`), + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +# handles VIRTUAL columns too +CREATE OR REPLACE TABLE t ( +a INT AS (b + 1), +b INT, +row_start BIGINT UNSIGNED AS ROW START INVISIBLE, +row_end BIGINT UNSIGNED AS ROW END INVISIBLE, +PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; +INSERT INTO t VALUES (DEFAULT, 1); +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t +ON c.table_id=t.table_id +WHERE t.name='test/t' AND c.name='b'; +prtype +50179 +ALTER TABLE t +CHANGE b b INT WITHOUT SYSTEM VERSIONING; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t +ON c.table_id=t.table_id +WHERE t.name='test/t' AND c.name='b'; +prtype +1027 +UPDATE t SET b=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; +COUNT(*) +1 +DROP TABLE t; +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=ERROR; diff --git a/mysql-test/suite/versioning/r/trx_id_versioning_attribute_persistence.result b/mysql-test/suite/versioning/r/trx_id_versioning_attribute_persistence.result new file mode 100644 index 00000000000..bf555fb2a7d --- /dev/null +++ b/mysql-test/suite/versioning/r/trx_id_versioning_attribute_persistence.result @@ -0,0 +1,86 @@ +CREATE OR REPLACE TABLE t1 ( +a INT, +b INT, +row_start BIGINT UNSIGNED AS ROW START INVISIBLE, +row_end BIGINT UNSIGNED AS ROW END INVISIBLE, +PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; +CREATE OR REPLACE TABLE t2 ( +a INT WITHOUT SYSTEM VERSIONING, +b INT, +row_start BIGINT UNSIGNED AS ROW START INVISIBLE, +row_end BIGINT UNSIGNED AS ROW END INVISIBLE, +PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1); +INSERT INTO t2 VALUES (1,1); +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; +# without rebuild +ALTER TABLE t1 +CHANGE a a INT WITHOUT SYSTEM VERSIONING, +ALGORITHM=INSTANT; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t2 +CHANGE a a INT WITH SYSTEM VERSIONING, +ADD PRIMARY KEY pk (a), +ALGORITHM=INSTANT; +ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE +# with rebuild +ALTER TABLE t2 +CHANGE a a INT WITH SYSTEM VERSIONING, +ADD PRIMARY KEY pk (a); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET a=2; +SELECT COUNT(*) FROM t1 FOR SYSTEM_TIME ALL; +COUNT(*) +1 +UPDATE t2 SET a=2; +SELECT COUNT(*) FROM t2 FOR SYSTEM_TIME ALL; +COUNT(*) +2 +DROP TABLE t1, t2; +# rollback ALTER TABLE: nothing should change +CREATE TABLE t ( +a INT, +b INT, +row_start BIGINT UNSIGNED AS ROW START INVISIBLE, +row_end BIGINT UNSIGNED AS ROW END INVISIBLE, +PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; +INSERT INTO t VALUES (1, 1); +SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C +JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID +WHERE t.NAME='test/t' AND C.NAME='b'; +PRTYPE +50179 +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; +SET @SAVED_DEBUG_DBUG = @@SESSION.DEBUG_DBUG; +SET DEBUG_DBUG='+d,ib_commit_inplace_fail_1'; +ALTER TABLE t +CHANGE b b INT WITHOUT SYSTEM VERSIONING; +ERROR HY000: Internal error: Injected error! +SET DEBUG_DBUG = @SAVED_DEBUG_DBUG; +SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C +JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID +WHERE t.NAME='test/t' AND C.NAME='b'; +PRTYPE +50179 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `row_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; +COUNT(*) +1 +UPDATE t SET b=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; +COUNT(*) +2 +DROP TABLE t; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index d570b6f4259..05bd6019a32 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -12,6 +12,10 @@ show create table t; --error ER_VERS_ALTER_NOT_ALLOWED alter table t add column y int; +--error ER_VERS_ALTER_NOT_ALLOWED +alter table t add primary key (a); +--error ER_VERS_ALTER_NOT_ALLOWED +alter table t add unique key (a); --error ER_VERS_ALTER_ENGINE_PROHIBITED alter table t engine innodb; @@ -454,5 +458,16 @@ create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e --error ER_VERS_ALTER_SYSTEM_FIELD alter table t1 modify s timestamp(6) as row start; +--echo # ignore CHECK for historical rows +create or replace table t (a int) with system versioning; +insert into t values (0), (1); +delete from t where a = 0; +--error ER_CONSTRAINT_FAILED +alter table t add check (a > 1); +alter table t add check (a > 0); +--error ER_CONSTRAINT_FAILED +insert into t values (0); +insert into t values (2); + drop database test; create database test; diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test index a4f7b245988..bc7e084758d 100644 --- a/mysql-test/suite/versioning/t/replace.test +++ b/mysql-test/suite/versioning/t/replace.test @@ -29,4 +29,12 @@ replace t values (1, 3); select *, current_row(row_end) as current from t for system_time all order by x; drop table t; ---source suite/versioning/common_finish.inc +--echo # MDEV-15645 Assertion `table->insert_values' failed in write_record upon REPLACE into a view with underlying versioned table +create or replace table t1 (a int, b int, primary key (a), unique(b)) with system versioning; +insert into t1 values (1,1); +create or replace table t2 (c int); +create or replace view v as select t1.* from t1 join t2; +replace into v (a, b) select a, b from t1; + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index 845cf731af1..b7c2d500da1 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -363,6 +363,16 @@ call p(1); alter table t1 add system versioning; call p(2); call p(3); + +--echo # +--echo # MDEV-15947 ASAN heap-use-after-free in Item_ident::print or in my_strcasecmp_utf8 or unexpected ER_BAD_FIELD_ERROR upon call of stored procedure reading from versioned table +--echo # +create or replace table t1 (i int) with system versioning; +create or replace procedure p() select * from t1; +call p; +flush tables; +call p; +call p; drop procedure p; drop table t1; diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test index aab28d1057c..35ba6595440 100644 --- a/mysql-test/suite/versioning/t/trx_id.test +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -1,5 +1,4 @@ -- source include/have_innodb.inc --- source include/not_embedded.inc set default_storage_engine= innodb; @@ -411,3 +410,85 @@ DROP TABLE tts; DROP TABLE ttx; DROP FUNCTION fts; DROP FUNCTION ftx; + +--echo # +--echo # MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute +--echo # + +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; +CREATE TABLE t ( + a INT, + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +INSERT INTO t VALUES (1,1); + +--echo # without table rebuild +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; +--enable_info +ALTER TABLE t + CHANGE a a INT WITHOUT SYSTEM VERSIONING; +--disable_info +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; + +UPDATE t SET a=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +--echo # with table rebuild +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; +--enable_info +ALTER TABLE t + CHANGE a a INT WITH SYSTEM VERSIONING, + ADD PRIMARY KEY pk(a); +--disable_info +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; + +UPDATE t SET a=1; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +SHOW CREATE TABLE t; + +-- echo # handles VIRTUAL columns too +CREATE OR REPLACE TABLE t ( + a INT AS (b + 1), + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +INSERT INTO t VALUES (DEFAULT, 1); + +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='b'; +--enable_info +ALTER TABLE t + CHANGE b b INT WITHOUT SYSTEM VERSIONING; +--disable_info +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='b'; + +UPDATE t SET b=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +DROP TABLE t; +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=ERROR; diff --git a/mysql-test/suite/versioning/t/trx_id_versioning_attribute_persistence.test b/mysql-test/suite/versioning/t/trx_id_versioning_attribute_persistence.test new file mode 100644 index 00000000000..4e92ee247e4 --- /dev/null +++ b/mysql-test/suite/versioning/t/trx_id_versioning_attribute_persistence.test @@ -0,0 +1,87 @@ +-- source include/have_innodb.inc +-- source include/have_debug.inc + +CREATE OR REPLACE TABLE t1 ( + a INT, + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +CREATE OR REPLACE TABLE t2 ( + a INT WITHOUT SYSTEM VERSIONING, + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +INSERT INTO t1 VALUES (1,1); +INSERT INTO t2 VALUES (1,1); + +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; + +--enable_info +--echo # without rebuild +ALTER TABLE t1 + CHANGE a a INT WITHOUT SYSTEM VERSIONING, + ALGORITHM=INSTANT; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t2 + CHANGE a a INT WITH SYSTEM VERSIONING, + ADD PRIMARY KEY pk (a), + ALGORITHM=INSTANT; + +--echo # with rebuild +ALTER TABLE t2 + CHANGE a a INT WITH SYSTEM VERSIONING, + ADD PRIMARY KEY pk (a); +--disable_info + +--source include/restart_mysqld.inc + +UPDATE t1 SET a=2; +SELECT COUNT(*) FROM t1 FOR SYSTEM_TIME ALL; + +UPDATE t2 SET a=2; +SELECT COUNT(*) FROM t2 FOR SYSTEM_TIME ALL; + +DROP TABLE t1, t2; + +--echo # rollback ALTER TABLE: nothing should change +CREATE TABLE t ( + a INT, + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +INSERT INTO t VALUES (1, 1); + +SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C + JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID + WHERE t.NAME='test/t' AND C.NAME='b'; + +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; + +SET @SAVED_DEBUG_DBUG = @@SESSION.DEBUG_DBUG; +SET DEBUG_DBUG='+d,ib_commit_inplace_fail_1'; +--error ER_INTERNAL_ERROR +ALTER TABLE t + CHANGE b b INT WITHOUT SYSTEM VERSIONING; +SET DEBUG_DBUG = @SAVED_DEBUG_DBUG; + +SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C + JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID + WHERE t.NAME='test/t' AND C.NAME='b'; + +SHOW CREATE TABLE t; + +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; +UPDATE t SET b=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +DROP TABLE t; diff --git a/mysql-test/suite/wsrep/r/variables.result b/mysql-test/suite/wsrep/r/variables.result index 30b97e02af3..b6f22828532 100644 --- a/mysql-test/suite/wsrep/r/variables.result +++ b/mysql-test/suite/wsrep/r/variables.result @@ -207,6 +207,16 @@ Threads_connected 1 SHOW STATUS LIKE 'wsrep_thread_count'; Variable_name Value wsrep_thread_count 11 +set wsrep_on=0; +set wsrep_on=1; +create user test@localhost; +connect con1,localhost,test; +set auto_increment_increment=10; +set wsrep_on=0; +ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation +disconnect con1; +connection default; +drop user test@localhost; # # MDEV#6411: Setting set @@global.wsrep_sst_auth=NULL causes crash # diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test index 1769f567848..1315f090d5c 100644 --- a/mysql-test/suite/wsrep/t/variables.test +++ b/mysql-test/suite/wsrep/t/variables.test @@ -118,6 +118,20 @@ sleep 3; SHOW STATUS LIKE 'threads_connected'; SHOW STATUS LIKE 'wsrep_thread_count'; +# +# privileges for wsrep_on +# +set wsrep_on=0; +set wsrep_on=1; +create user test@localhost; +connect con1,localhost,test; +set auto_increment_increment=10; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +set wsrep_on=0; +disconnect con1; +connection default; +drop user test@localhost; + --echo # --echo # MDEV#6411: Setting set @@global.wsrep_sst_auth=NULL causes crash --echo # diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index dea3f3c2764..d97792355b4 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,525 +23,781 @@ # ############################################################################## -# Based on bb-10.3-release 037df4189f1adf53e87d6b7134408a547e83bbae - -main.alter_table : Modified in 10.3.7 -main.alter_table_errors : Added in 10.3.7 -main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result -main.ansi : Modified in 10.3.7 -main.assign_key_cache : Added in 10.2.15 -main.assign_key_cache_debug : Added in 10.2.15 -main.auth_named_pipe : MDEV-14724 - System error 2 -main.check_constraint : Modified in 10.3.7 -main.connect : MDEV-16270 - Wrong result; modified in 10.2.15 -main.connect_debug : Added in 10.2.15 -main.connect2 : MDEV-13885 - Server crash -main.create_drop_event : MDEV-16271 - Wrong result -main.create_or_replace : Modified in 10.3.7 -main.cte_recursive : Modified in 10.3.7 -main.ctype_ucs : Modified in 10.2.15 -main.ctype_utf8mb4 : Modified in 10.2.15 -main.custom_aggregate_functions : Modified in 10.3.7 -main.derived_cond_pushdown : Modified in 10.3.7 -main.distinct : MDEV-14194 - Crash; modified in 10.3.7 -main.drop_bad_db_type : MDEV-15676 - Wrong result -main.events_2 : MDEV-13277 - Crash -main.events_slowlog : MDEV-12821 - Wrong result -main.explain_slowquerylog : Modified in 10.3.7 -main.func_str : Modified in 10.2.15 -main.grant_not_windows : Added in 10.3.7 -main.index_merge_innodb : MDEV-7142 - Plan mismatch -main.innodb_mysql_lock : MDEV-7861 - Wrong result -main.insert_select : Modified in 10.3.7 -main.invisible_field_grant_completely : Added in 10.3.7 -main.invisible_field_grant_system : Added in 10.3.7 -main.kill-2 : MDEV-13257 - Wrong result -main.kill_processlist-6619 : MDEV-10793 - Wrong result -main.lock : Modified in 10.2.15 -main.log_slow : MDEV-13263 - Wrong result -main.mdev375 : Modified in 10.2.15 -main.mdev-504 : MDEV-15171 - warning -main.multi_update : Modified in 10.3.7 -main.myisam : Modified in 10.2.15 -main.myisam_recover : Modified in 10.2.15 -main.mysql : Modified in 10.3.7 -main.mysql_client_test_nonblock : CONC-208 - Error on Power; MDEV-15096 - exec failed -main.mysql_cp932 : Modified in 10.3.7 -main.mysql_upgrade_noengine : MDEV-14355 - Wrong result -main.mysql_upgrade_ssl : MDEV-13492 - Unknown SSL error -main.mysqldump : MDEV-14800 - Stack smashing detected -main.mysqld_option_err : MDEV-12747 - Timeout -main.mysqlhotcopy_myisam : MDEV-10995 - Hang on debug -main.mysqltest : MDEV-13887 - Wrong result -main.openssl_1 : MDEV-13492 - Unknown SSL error -main.order_by_optimizer_innodb : MDEV-10683 - Wrong result -main.parser : Modified in 10.3.7 -main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock -main.partition_innodb : Modified in 10.3.7 -main.partition_list : Modified in 10.2.15 -main.ps : MDEV-11017 - Wrong result; modified in 10.2.15 -main.query_cache : MDEV-16180 - Wrong result -main.query_cache_debug : MDEV-15281 - Query cache is disabled -main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away -main.read_only_innodb : Modified in 10.2.15 -main.select : MDEV-15430 - Wrong result with clang-4 -main.select_jcl6 : MDEV-15430 - Wrong result with clang-4 -main.select_pkeycache : MDEV-15430 - Wrong result with clang-4 -main.set_statement : MDEV-13183 - Wrong result -main.shm : MDEV-12727 - Mismatch, ERROR 2013 -main.show_explain : MDEV-10674 - Wrong result code -main.sp : MDEV-7866 - Mismatch; modified in 10.3.7 -main.sp-code : Modified in 10.3.7 -main.sp-destruct : Modified in 10.2.15 -main.sp-innodb : Modified in 10.2.15 -main.ssl_ca : MDEV-10895 - SSL connection error on Power -main.ssl_cert_verify : MDEV-13735 - Server crash -main.ssl_connect : MDEV-13492 - Unknown SSL error -main.ssl_timeout : MDEV-11244 - Crash -main.stat_tables_par : MDEV-13266 - Wrong result -main.statistics : Modified in 10.2.15 -main.status : MDEV-13255 - Wrong result -main.subselect4 : Modified in 10.2.15 -main.subselect-crash_15755 : Added in 10.3.7 -main.subselect_innodb : MDEV-10614 - Wrong result -main.subselect_sj : Modified in 10.2.15 -main.symlink-myisam-11902 : MDEV-15098 - Error 40 from storage engine -main.tc_heuristic_recover : MDEV-14189 - Wrong result -main.type_blob : MDEV-15195 - Wrong result -main.type_datetime_hires : MDEV-15430 - Wrong result with clang-4 -main.type_float : MDEV-15430 - Wrong result with clang-4 -main.type_time_hires : MDEV-15430 - Wrong result with clang-4 -main.type_timestamp_hires : MDEV-15430 - Wrong result with clang-4 -main.userstat : MDEV-12904 - SSL errors -main.variables : Modified in 10.2.15 -main.view : Modified in 10.2.15 -main.win : Modified in 10.2.15 - -#---------------------------------------------------------------- - -archive.archive_bitfield : MDEV-11771 - table is marked as crashed -archive.mysqlhotcopy_archive : MDEV-10995 - Hang on debug - -#---------------------------------------------------------------- - -binlog.binlog_commit_wait : MDEV-10150 - Mismatch -binlog.binlog_flush_binlogs_delete_domain : MDEV-14431 - Wrong exit code -binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint - -#---------------------------------------------------------------- - -binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint -binlog_encryption.encrypted_master : MDEV-14201 - Extra warnings -binlog_encryption.encrypted_master_switch_to_unencrypted : MDEV-14190 - Can't init tc log -binlog_encryption.encryption_combo : MDEV-14199 - Table is marked as crashed -binlog_encryption.rpl_binlog_errors : MDEV-12742 - Crash -binlog_encryption.rpl_parallel : MDEV-10653 - Timeout in include -binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout -binlog_encryption.rpl_semi_sync : MDEV-11673 - Valgrind -binlog_encryption.rpl_skip_replication : MDEV-13571 - Unexpected warning -binlog_encryption.rpl_ssl : MDEV-14507 - Timeouts -binlog_encryption.rpl_stm_relay_ign_space : MDEV-13278 - Wrong result (test assertion) -binlog_encryption.rpl_sync : MDEV-13830 - Assertion failure -binlog_encryption.rpl_typeconv : Include file modified in 10.2.15 - -#---------------------------------------------------------------- - -compat/oracle.column_compression : Added in 10.3.7 -compat/oracle.func_concat : Modified in 10.3.7 -compat/oracle.gis : Added in 10.3.7 -compat/oracle.parser : Modified in 10.3.7 -compat/oracle.table_value_constr : Added in 10.3.7 -compat/oracle.versioning : Added in 10.3.7 -compat/oracle.win : Added in 10.3.7 - -#---------------------------------------------------------------- - -connect.pivot : MDEV-14803 - Failed to discover table -connect.vcol : MDEV-12374 - Fails on Windows - -#---------------------------------------------------------------- - -encryption.create_or_replace : MDEV-12694 - Timeout; MDEV-16115 - Trying to access tablespace -encryption.debug_key_management : MDEV-13841 - Timeout -encryption.encrypt_and_grep : MDEV-13765 - Wrong result -encryption.innochecksum : MDEV-13644 - Assertion failure -encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate -encryption.innodb_encrypt_log : MDEV-13725 - Wrong result -encryption.innodb_encryption : MDEV-15675 - Timeout -encryption.innodb-encryption-alter : MDEV-13566 - Lock wait timeout -encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result; modified in 10.2.15 -encryption.innodb_encryption_filekeys : MDEV-15673 - Timeout; modified in 10.2.15 -encryption.innodb_encryption-page-compression : MDEV-12630 - crash or assertion failure -encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash -encryption.innodb-first-page-read : MDEV-14356 - Timeout in wait condition -encryption.innodb_lotoftables : Modified in 10.2.15 -encryption.innodb-redo-badkey : MDEV-13893 - Page cannot be decrypted; include file modified in 10.2.15 -encryption.innodb-redo-nokeys : Include file modified in 10.2.15 -encryption.innodb-remove-encryption : Added in 10.2.15 -encryption.innodb-spatial-index : MDEV-13746 - Wrong result - -#---------------------------------------------------------------- - -engines/rr_trx.* : MDEV-10998 - Not maintained - -#---------------------------------------------------------------- - -federated.assisted_discovery : Modified in 10.3.7 -federated.federated_bug_585688 : MDEV-14805 - Server crash, MDEV-12907 - Valgrind -federated.federated_innodb : MDEV-10617 - Wrong checksum -federated.federated_transactions : MDEV-10617 - Wrong checksum -federated.federatedx : MDEV-10617 - Wrong checksum -federated.federatedx_versioning : Added in 10.3.7 -federated.timestamps : Added in 10.3.7 - -#---------------------------------------------------------------- - -funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result - -funcs_2/charset.* : MDEV-10999 - Not maintained - -#---------------------------------------------------------------- - -galera.* : Suite is not stable yet -galera_3nodes.* : Suite is not stable yet - -#---------------------------------------------------------------- - -gcol.innodb_virtual_debug : MDEV-14134 - Crash, assertion failure -gcol.innodb_virtual_fk : Modified in 10.2.15 -gcol.innodb_virtual_index : Modified in 10.3.7 - -#---------------------------------------------------------------- - -handler.heap : Modified in 10.3.7 -handler.innodb : Modified in 10.3.7 -handler.interface : Modified in 10.3.7 - -#---------------------------------------------------------------- - -innodb.101_compatibility : MDEV-13891 - Wrong result -innodb.alter_copy : MDEV-16181 - Assertion failure -innodb.alter_foreign_crash : Added in 10.3.7 -innodb.alter_kill : MDEV-16273 - Unknown storage engine 'InnoDB'; added in 10.3.7 -innodb.alter_missing_tablespace : Modified in 10.2.15 -innodb.alter_partitioned : Added in 10.3.7 -innodb.alter_partitioned_debug : Added in 10.2.15 -innodb.alter_partitioned_xa : Added in 10.2.15 -innodb.alter_rename_files : Added in 10.3.7 -innodb.analyze_table : Added in 10.3.7 -innodb.autoinc_persist : MDEV-15282 - Assertion failure -innodb.doublewrite : MDEV-12905 - Server crash; include file modified in 10.2.15 -innodb.foreign_key : Modified in 10.2.15 -innodb.group_commit_crash : MDEV-14191 - InnoDB registration failed -innodb.group_commit_crash_no_optimize_thread : MDEV-13830 - Assertion failure -innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup -innodb.innodb-alter : Modified in 10.2.15 -innodb.innodb-alter-nullable : Modified in 10.2.15 -innodb.innodb-alter-tempfile : MDEV-15285 - Table already exists -innodb.innodb_bug13510739 : Modified in 10.3.7 -innodb.innodb_bug14147491 : MDEV-11808 - Index is corrupt -innodb.innodb_bug27216817 : Added in 10.2.15 -innodb.innodb_bug30423 : MDEV-7311 - Wrong result -innodb.innodb_bug48024 : MDEV-14352 - Assertion failure -innodb.innodb_bug54044 : Modified in 10.3.7 -innodb.innodb_bug59641 : MDEV-13830 - Assertion failure -innodb.innodb_bulk_create_index_replication : MDEV-15273 - Slave failed to start -innodb.innodb_defrag_stats_many_tables : MDEV-14198 - Table is full -innodb.innodb-get-fk : MDEV-13276 - Server crash -innodb.innodb-index : Modified in 10.2.15 -innodb.innodb-index-online : MDEV-14809 - Cannot save statistics -innodb.innodb_information_schema : MDEV-8851 - Wrong result -innodb.innodb_information_schema_buffer : MDEV-16267 - Wrong result -innodb.innodb-isolation : Modified in 10.2.15 -innodb.innodb_max_recordsize_32k : MDEV-14801 - Operation failed -innodb.innodb_max_recordsize_64k : MDEV-15203 - Wrong result -innodb.innodb-online-alter-gis : Modified in 10.3.7 -innodb.innodb-page_compression_default : MDEV-13644 - Assertion failure -innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result -innodb.innodb_prefix_index_restart_server : Modified in 10.2.15 -innodb.innodb_stats_persistent_debug : MDEV-14801 - Operation failed -innodb.innodb-table-online : MDEV-13894 - Wrong result -innodb.innodb_sys_semaphore_waits : MDEV-10331 - Semaphore wait -innodb.innodb-wl5522-debug : MDEV-14200 - Wrong errno -innodb.innodb_zip_innochecksum2 : MDEV-13882 - Extra warnings -innodb.innodb_zip_innochecksum3 : MDEV-14486 - Resource temporarily unavailable -innodb.log_alter_table : Include file modified in 10.2.15 -innodb.log_corruption : MDEV-13251 - Wrong result -innodb.log_data_file_size : MDEV-14204 - Server failed to start; include file modified in 10.2.15 -innodb.log_file_name : MDEV-14193 - Exception; include file modified in 10.2.15 -innodb.log_file_name_debug : Include file modified in 10.2.15 -innodb.log_file_size : MDEV-15668 - Not found pattern -innodb.mdev-15707 : Added in 10.2.15 -innodb.monitor : MDEV-16179 - Wrong result -innodb.purge_secondary : MDEV-15681 - Wrong result -innodb.purge_thread_shutdown : MDEV-13792 - Wrong result -innodb.read_only_recovery : MDEV-13886 - Server crash -innodb.recovery_shutdown : MDEV-15671 - Checksum mismatch in datafile -innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace -innodb.stored_fk : Added in 10.2.15 -innodb.table_definition_cache_debug : MDEV-14206 - Extra warning -innodb.table_flags : MDEV-13572 - Wrong result -innodb.temp_table_savepoint : MDEV-16182 - Wrong result -innodb.temporary_table : MDEV-13265 - Wrong result; modified in 10.3.7 -innodb.tmpdir : Modified in 10.3.7 -innodb.undo_log : Modified in 10.2.15 -innodb.update_time : MDEV-14804 - Wrong result -innodb.xa_recovery : MDEV-15279 - mysqld got exception - -innodb_fts.basic : Added in 10.2.15 -innodb_fts.fulltext2 : MDEV-14727 - Long semaphore wait; modified in 10.3.7 -innodb_fts.fulltext_misc : MDEV-12636 - Valgrind -innodb_fts.fulltext_table_evict : Added in 10.2.15 -innodb_fts.fulltext_var : Modified in 10.3.7 -innodb_fts.innodb_fts_misc : Modified in 10.3.7 -innodb_fts.innodb_fts_plugin : MDEV-13888 - Errors in server log -innodb_fts.innodb_fts_stopword_charset : MDEV-13259 - Table crashed -innodb_fts.sync : MDEV-14808 - Wrong result - -innodb_gis.rtree_compress2 : MDEV-16269 - Wrong result -innodb_gis.rtree_concurrent_srch : MDEV-15284 - Wrong result with embedded -innodb_gis.rtree_purge : MDEV-15275 - Timeout -innodb_gis.rtree_recovery : MDEV-15274 - Error on check -innodb_gis.rtree_split : MDEV-14208 - Too many arguments -innodb_gis.rtree_undo : MDEV-14456 - Timeout in include file -innodb_gis.types : MDEV-15679 - Table is marked as crashed; modified in 10.2.15 - -innodb_zip.cmp_per_index : MDEV-14490 - Table is marked as crashed; modified in 10.2.15 -innodb_zip.innochecksum_3 : MDEV-13279 - Extra warnings -innodb_zip.wl6470_1 : MDEV-14240 - Assertion failure -innodb_zip.wl6501_1 : MDEV-10891 - Can't create UNIX socket -innodb_zip.wl5522_debug_zip : MDEV-11600 - Operating system error number 2 -innodb_zip.wl6501_scale_1 : MDEV-13254 - Timeout, MDEV-14104 - Error 192 - -#---------------------------------------------------------------- - -maria.alter : Modified in 10.3.7 -maria.insert_select : MDEV-12757 - Timeout -maria.lock : Modified in 10.3.7 -maria.maria : MDEV-14430 - Extra warning - -#---------------------------------------------------------------- - -mariabackup.absolute_ibdata_paths : Added in 10.2.15 -mariabackup.apply-log-only : MDEV-14192 - Assertion failure -mariabackup.apply-log-only-incr : MDEV-14192 - Assertion failure -mariabackup.backup_ssl : Added in 10.2.15 -mariabackup.data_directory : MDEV-15270 - Error on exec -mariabackup.incremental_backup : MDEV-14192 - Assertion failure -mariabackup.incremental_encrypted : MDEV-14188 - Wrong result, MDEV-15667 - timeout -mariabackup.mdev-14447 : MDEV-15201 - Timeout -mariabackup.partial_exclude : MDEV-15270 - Error on exec -mariabackup.unsupported_redo : Modified in 10.2.15 -mariabackup.xbstream : MDEV-14192 - Crash -mariabackup.xb_aws_key_management : MDEV-15680 - Error: xtrabackup_copy_logfile() failed -mariabackup.xb_compressed_encrypted : MDEV-14812 - Segmentation fault -mariabackup.xb_history : MDEV-16268 - Error on exec -mariabackup.xb_page_compress : MDEV-14810 - status: 1, errno: 11 - -#---------------------------------------------------------------- - -mroonga/storage.* : MDEV-16275 - Wrong result - -mroonga/storage.index_multiple_column_unique_datetime_index_read : MDEV-8643 - Valgrind - -#---------------------------------------------------------------- - -multi_source.gtid : MDEV-14202 - Crash -multi_source.info_logs : MDEV-12629 - Valgrind, MDEV-10042 - wrong result -multi_source.reset_slave : MDEV-10690 - Wrong result -multi_source.simple : MDEV-4633 - Wrong result - -#---------------------------------------------------------------- - -parts.partition_alter_innodb : Include file modified in 10.2.15 -parts.partition_alter_maria : Include file modified in 10.2.15 -parts.partition_alter_myisam : Include file modified in 10.2.15 -parts.partition_auto_increment_maria : MDEV-14430 - Extra warning -parts.partition_debug_innodb : MDEV-10891 - Can't create UNIX socket; MDEV-15095 - Table doesn't exist -parts.show_create : Added in 10.3.7 - -#---------------------------------------------------------------- - -percona.* : MDEV-10997 - Not maintained - -#---------------------------------------------------------------- - -perfschema.bad_option_1 : MDEV-13892 - Timeout -perfschema.bad_option_3 : MDEV-12728 - Timeout on Power -perfschema.bad_option_5 : MDEV-14197 - Timeout -perfschema.dml_file_instances : MDEV-15179 - Wrong result -perfschema.hostcache_ipv4_addrinfo_again_allow : MDEV-12759 - Crash -perfschema.hostcache_ipv4_max_con : Modified in 10.2.15 -perfschema.hostcache_ipv6_addrinfo_again_allow : MDEV-12752 - Crash -perfschema.hostcache_ipv6_addrinfo_bad_allow : MDEV-13260 - Crash -perfschema.hostcache_ipv6_max_con : Modified in 10.2.15 -perfschema.hostcache_ipv6_ssl : MDEV-10696 - Crash -perfschema.setup_actors : MDEV-10679 - Crash -perfschema.socket_connect : MDEV-15677 - Wrong result -perfschema.socket_summary_by_event_name_func : MDEV-10622 - Wrong result -perfschema.stage_mdl_procedure : MDEV-11545 - Missing row -perfschema.threads_mysql : MDEV-10677 - Wrong result - -#---------------------------------------------------------------- - -perfschema_stress.* : MDEV-10996 - Not maintained - -#---------------------------------------------------------------- - -plugins.feedback_plugin_send : MDEV-7932, MDEV-11118 - Connection problems and such -plugins.server_audit : Modified in 10.2.15 -plugins.thread_pool_server_audit : MDEV-14295 - Wrong result - -#---------------------------------------------------------------- - -rocksdb.* : MDEV-12474 and more, tests are unstable - -#---------------------------------------------------------------- - -rpl.rpl_binlog_errors : MDEV-12742 - Crash -rpl.rpl_binlog_index : MDEV-9501 - Failed registering on master -rpl.rpl_colSize : MDEV-16112 - Server crash -rpl.rpl_ctype_latin1 : MDEV-14813 - Wrong result on Mac -rpl.rpl_domain_id_filter_io_crash : MDEV-12729 - Timeout in include file, MDEV-13677 - Server crash -rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result -rpl.rpl_extra_col_master_myisam : MDEV-14203 - Extra warning -rpl.rpl_gtid_crash : MDEV-9501 - Failed registering on master, MDEV-13643 - Lost connection -rpl.rpl_gtid_delete_domain : MDEV-14463 - Timeout -rpl.rpl_gtid_errorhandling : MDEV-13261 - Crash -rpl.rpl_gtid_reconnect : MDEV-14497 - Crash -rpl.rpl_insert_id : MDEV-15197 - Wrong result -rpl.rpl_mariadb_slave_capability : MDEV-11018 - Extra lines in binlog -rpl.rpl_mdev12179 : Modified in 10.3.7 -rpl.rpl_mdev382 : Modified in 10.3.7 -rpl.rpl_mdev6020 : MDEV-15272 - Server crash -rpl.rpl_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed -rpl.rpl_non_direct_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed -rpl.rpl_non_direct_row_mixing_engines : MDEV-14491 - Long semaphore wait -rpl.rpl_non_direct_stm_mixing_engines : MDEV-14489 - Failed sync_slave_with_master -rpl.rpl_parallel : MDEV-10653 - Timeouts -rpl.rpl_parallel_conflicts : MDEV-15272 - Server crash -rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure -rpl.rpl_parallel_optimistic : MDEV-15278 - Failed to sync with master -rpl.rpl_parallel_optimistic_nobinlog : MDEV-15278 - Failed to sync with master -rpl.rpl_parallel_retry : MDEV-11119 - Crash -rpl.rpl_parallel_temptable : MDEV-10356 - Crash -rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed -rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result -rpl.rpl_row_img_eng_min : MDEV-13875 - diff_files failed -rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed -rpl.rpl_row_index_choice : MDEV-15196 - Slave crash -rpl.rpl_row_mixing_engines : MDEV-14491 - Long semaphore wait -rpl.rpl_row_until : MDEV-14052 - Master will not send events with checksum -rpl.rpl_semi_sync : MDEV-11220 - Wrong result -rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result -rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result -rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Assorted failures -rpl.rpl_semisync_ali_issues : MDEV-16272 - Wrong result -rpl.rpl_set_statement_default_master : MDEV-13258 - Extra warning -rpl.rpl_show_slave_hosts : MDEV-10681 - Crash -rpl.rpl_skip_replication : MDEV-13258 - Extra warning -rpl.rpl_slave_grp_exec : MDEV-10514 - Deadlock -rpl.rpl_slave_load_tmpdir_not_exist : MDEV-14203 - Extra warning -rpl.rpl_slow_query_log : MDEV-13250 - Test abort -rpl.rpl_sp_effects : MDEV-13249 - Crash -rpl.rpl_start_stop_slave : MDEV-13567 - Sync slave timeout -rpl.rpl_stm_reset_slave : MDEV-16274 - Connection attributes were truncated -rpl.rpl_mixed_implicit_commit_binlog : Include file modified in 10.2.15 -rpl.rpl_row_implicit_commit_binlog : Include file modified in 10.2.15 -rpl.rpl_stm_implicit_commit_binlog : Include file modified in 10.2.15 -rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master failed -rpl.rpl_stm_multi_query : MDEV-9501 - Failed registering on master -rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion -rpl.rpl_stm_stop_middle_group : MDEV-13791 - Server crash -rpl.rpl_sync : MDEV-13830 - Assertion failure -rpl.rpl_temporal_mysql56_to_mariadb53 : MDEV-9501 - Failed registering on master -rpl.rpl_typeconv : Include file modified in 10.2.15 -rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result - -rpl/extra/rpl_tests.* : MDEV-10994 - Not maintained - -#---------------------------------------------------------------- - -spider.basic_sql : MDEV-11186 - Internal check fails - -spider/bg.direct_aggregate : MDEV-7098 - Packets out of order -spider/bg.ha_part : MDEV-7914 - Crash (only fixed in 10.3) -spider/bg.spider3_fixes : MDEV-12639 - Syntax error - -spider/handler.* : MDEV-10990 - Not maintained - -#---------------------------------------------------------------- - -sphinx.sphinx : MDEV-10986 - Sporadic failures -sphinx.union-5539 : MDEV-10986 - Sporadic failures - -#---------------------------------------------------------------- - -storage_engine.* : Not always timely maintained - -#---------------------------------------------------------------- - -sys_vars.innodb_buffer_pool_dump_at_shutdown_basic : MDEV-14280 - Unexpected error -sys_vars.innodb_stats_include_delete_marked_basic : Modified in 10.3.7 -sys_vars.max_prepared_stmt_count_basic : Modified in 10.2.15 -sys_vars.rpl_init_slave_func : MDEV-10149 - Test assertion -sys_vars.slow_query_log_func : MDEV-14273 - Wrong result -sys_vars.sysvars_innodb : Modified in 10.3.7 -sys_vars.sysvars_server_embedded : Opt file added in 10.2.15 -sys_vars.sysvars_server_notembedded : Opt file added in 10.2.15 -sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result - -#---------------------------------------------------------------- - -tokudb.change_column_all_1000_10 : MDEV-12640 - Lost connection -tokudb.change_column_bin : MDEV-12640 - Lost connection -tokudb.change_column_char : MDEV-12822 - Lost connection -tokudb.dir_per_db : MDEV-11537 - Wrong result -tokudb.hotindex-insert-0 : MDEV-15271 - Timeout -tokudb.hotindex-insert-2 : MDEV-15271 - Timeout -tokudb.hotindex-insert-bigchar : MDEV-12640 - Crash -tokudb.hotindex-update-0 : MDEV-15198 - Timeout -tokudb.hotindex-update-1 : MDEV-12640 - Crash -tokudb.rows-32m-rand-insert : MDEV-12640 - Crash -tokudb.rows-32m-seq-insert : MDEV-12640 - Crash -tokudb.savepoint-5 : MDEV-15280 - Wrong result -tokudb.type_datetime : MDEV-15193 - Wrong result - -tokudb_alter_table.hcad_all_add2 : MDEV-15269 - Timeout - -tokudb_bugs.db917 : Modified in 10.2.15 -tokudb_bugs.xa : MDEV-11804 - Lock wait timeout - -tokudb_backup.* : MDEV-11001 - Missing include file -tokudb_sys_vars.* : MDEV-11001 - Missing include file -tokudb_rpl.* : MDEV-11001 - Missing include file - -tokudb_parts.partition_alter4_tokudb : MDEV-12640 - Lost connection - -#---------------------------------------------------------------- - -unit.conc_basic-t : MDEV-15286 - not ok 7 - test_reconnect_maxpackage -unit.conc_misc : MDEV-14811 - not ok 12 - test_conc49 -unit.conc_ps_bugs : MDEV-13252 - not ok 44 test_bug4236 -unit.lf : MDEV-12897 - Signal 11 thrown -unit.my_atomic : MDEV-15670 - Signal 11 thrown - -#---------------------------------------------------------------- - -vcol.partition : Modified in 10.2.15 - -#---------------------------------------------------------------- - -versioning.partition : Modified in 10.3.7 -versioning.truncate : Modified in 10.3.7 +# Based on bb-10.3-release 36e59752e7fc70bc5179a3d730b5ce3ee58e4e30 + +#----------------------------------------------------------------------- + +archive.archive_bitfield : MDEV-11771 - table is marked as crashed +archive.archive_symlink : MDEV-12170 - unexpected error on rmdir +archive.discover : MDEV-10510 - Table is marked as crashed +archive.mysqlhotcopy_archive : MDEV-10995 - Hang on debug + +#----------------------------------------------------------------------- + +binlog.binlog_commit_wait : MDEV-10150 - Mismatch +binlog.binlog_flush_binlogs_delete_domain : MDEV-14431 - Wrong exit code +binlog.binlog_killed : MDEV-12925 - Wrong result +binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint + +#----------------------------------------------------------------------- + +binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint +binlog_encryption.encrypted_master : MDEV-14201 - Extra warnings; modified in 10.3.8 +binlog_encryption.encrypted_master_switch_to_unencrypted : MDEV-14190 - Can't init tc log +binlog_encryption.encrypted_slave : Modified in 10.3.8 +binlog_encryption.encryption_combo : MDEV-14199 - Table is marked as crashed +binlog_encryption.rpl_binlog_errors : MDEV-12742 - Crash +binlog_encryption.rpl_loadfile : MDEV-16645 - Timeout in include +binlog_encryption.rpl_parallel : MDEV-10653 - Timeout in include +binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout +binlog_encryption.rpl_semi_sync : MDEV-11673 - Valgrind +binlog_encryption.rpl_skip_replication : MDEV-13571 - Unexpected warning +binlog_encryption.rpl_ssl : MDEV-14507 - Timeouts +binlog_encryption.rpl_stm_relay_ign_space : MDEV-13278 - Wrong result (test assertion) +binlog_encryption.rpl_sync : MDEV-13830 - Assertion failure + +#----------------------------------------------------------------------- + +compat/oracle.column_compression : Added in 10.3.7 +compat/oracle.func_concat : Modified in 10.3.7 +compat/oracle.gis : Added in 10.3.7 +compat/oracle.parser : Modified in 10.3.8 +compat/oracle.sp-cursor-rowtype : Modified in 10.3.8 +compat/oracle.table_value_constr : Added in 10.3.7 +compat/oracle.versioning : Added in 10.3.7 +compat/oracle.win : Added in 10.3.7 + +#----------------------------------------------------------------------- + +connect.pivot : MDEV-14803 - Failed to discover table +connect.vcol : MDEV-12374 - Fails on Windows +connect.zip : MDEV-13884 - Wrong result + +#----------------------------------------------------------------------- + +encryption.create_or_replace : MDEV-12694 - Timeout; MDEV-16115 - Trying to access tablespace +encryption.debug_key_management : MDEV-13841 - Timeout +encryption.encrypt_and_grep : MDEV-13765 - Wrong result +encryption.innochecksum : MDEV-13644 - Assertion failure +encryption.innodb-checksum-algorithm : MDEV-12898 - Deadlock of threads +encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate +encryption.innodb-discard-import : Modified in 10.3.8 +encryption.innodb-encryption-alter : MDEV-13566 - Lock wait timeout +encryption.innodb-first-page-read : MDEV-14356 - Timeout in wait condition +encryption.innodb-page_encryption : MDEV-10641 - mutex problem +encryption.innodb-read-only : MDEV-16563 - Crash on startup +encryption.innodb-redo-badkey : MDEV-13893 - Page cannot be decrypted +encryption.innodb-redo-nokeys : Modified in 10.3.8 +encryption.innodb-remove-encryption : MDEV-16493 - Timeout in wait condition +encryption.innodb-spatial-index : MDEV-13746 - Wrong result +encryption.innodb_encrypt_log : MDEV-13725 - Wrong result +encryption.innodb_encryption : MDEV-15675 - Timeout +encryption.innodb_encryption-page-compression : MDEV-12630 - crash or assertion failure +encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result +encryption.innodb_encryption_filekeys : MDEV-15673 - Timeout +encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash +encryption.innodb_first_page : MDEV-10689 - Crash +encryption.innodb_scrub : MDEV-8139 - scrubbing tests need fixing +encryption.innodb_scrub_background : MDEV-8139 - scrubbing tests need fixing +encryption.innodb_scrub_compressed : MDEV-8139 - scrubbing tests need fixing + +#----------------------------------------------------------------------- + +engines/funcs.* : Not maintained in timely manner +engines/iuds.* : Not maintained in timely manner +engines/rr_trx.* : MDEV-10998 - Not maintained + +#----------------------------------------------------------------------- + +federated.assisted_discovery : Modified in 10.3.7 +federated.federated_bug_35333 : MDEV-13410 - Wrong result +federated.federated_bug_585688 : MDEV-14805 - Server crash, MDEV-12907 - Valgrind +federated.federated_innodb : MDEV-10617 - Wrong checksum +federated.federated_partition : MDEV-10417 - Fails on Mips +federated.federated_transactions : MDEV-10617 - Wrong checksum +federated.federatedx : MDEV-10617 - Wrong checksum +federated.federatedx_versioning : Added in 10.3.7 +federated.timestamps : Added in 10.3.7 + +#----------------------------------------------------------------------- + +funcs_1.memory_views : MDEV-11773 - timeout +funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result +funcs_1.processlist_val_ps : MDEV-12175 - Wrong plan + +#----------------------------------------------------------------------- + +funcs_2.memory_charset : MDEV-10290 - Timeout +funcs_2.myisam_charset : MDEV-11535 - Timeout +funcs_2/charset.* : MDEV-10999 - Not maintained + +#----------------------------------------------------------------------- + +galera.* : Suite is not stable yet + +galera.MW-328A : MDEV-13876 - Wrong result +galera.galera_applier_ftwrl_table_alter : MDEV-13738 - MySQL server has gone away +galera.galera_gcs_fc_limit : MDEV-13877 - Timeout +galera.galera_suspend_slave : MDEV-13873 - Wrong error code +galera.galera_toi_truncate : MDEV-13743 - query 'reap' succeeded +galera.galera_unicode_identifiers : MDEV-13871 - Unknown database +galera.galera_var_node_address : MDEV-13880 - Failed to start mysqld +galera.galera_wan : MDEV-13879 - Stray state UUID msg warnings +galera.galera_wsrep_log_conficts : MDEV-13874 - check-testcase failed +galera.partition : MDEV-13881 - Wrong result +galera.query_cache : MDEV-13883 - Wrong result + +#----------------------------------------------------------------------- + +galera_3nodes.* : Suite is not stable yet + +#----------------------------------------------------------------------- + +gcol.innodb_virtual_debug : MDEV-14134 - Crash, assertion failure; modified in 10.3.8 +gcol.innodb_virtual_index : Modified in 10.3.7 + +#----------------------------------------------------------------------- + +handler.heap : Modified in 10.3.7 +handler.innodb : Modified in 10.3.7 +handler.interface : Modified in 10.3.7 +handler.ps : Added in 10.3.8 + +#----------------------------------------------------------------------- + +heap.heap_auto_increment : MDEV-16652 - Out of range, modified in 10.3.8 + +#----------------------------------------------------------------------- + +innodb.101_compatibility : MDEV-13891 - Wrong result +innodb.alter_copy : MDEV-16181 - Assertion failure +innodb.alter_foreign_crash : Added in 10.3.7 +innodb.alter_kill : MDEV-16273 - Unknown storage engine 'InnoDB'; added in 10.3.7 +innodb.alter_non_null : Added in 10.3.8 +innodb.alter_non_null_debug : Added in 10.3.8 +innodb.alter_not_null : Modified in 10.3.8 +innodb.alter_partitioned : Added in 10.3.7 +innodb.alter_rename_files : Added in 10.3.7 +innodb.alter_sql_mode : Combinations added in 10.3.8 +innodb.analyze_table : Added in 10.3.7 +innodb.autoinc_persist : MDEV-15282 - Assertion failure +innodb.binlog_consistent : MDEV-10618 - Server fails to start +innodb.doublewrite : MDEV-12905 - Server crash +innodb.group_commit_crash : MDEV-14191 - InnoDB registration failed +innodb.group_commit_crash_no_optimize_thread : MDEV-13830 - Assertion failure +innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup +innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS +innodb.innodb-alter-table : MDEV-10619 - Testcase timeout +innodb.innodb-alter-tempfile : MDEV-15285 - Table already exists +innodb.innodb-alter-timestamp : Modified in 10.3.8 +innodb.innodb-autoinc : Modified in 10.3.8 +innodb.innodb-blob : Modified in 10.3.8 +innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown +innodb.innodb-get-fk : MDEV-13276 - Server crash +innodb.innodb-index-online : MDEV-14809 - Cannot save statistics +innodb.innodb-mdev7046 : Modified in 10.3.8 +innodb.innodb-online-alter-gis : Modified in 10.3.7 +innodb.innodb-page_compression_default : MDEV-13644 - Assertion failure; modified in 10.3.8 +innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result +innodb.innodb-page_compression_snappy : /MDEV-13644 - Assertion failure; modified in 10.3.8 +innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem +innodb.innodb-table-online : MDEV-13894 - Wrong result; modified in 10.3.8 +innodb.innodb-wl5522 : MDEV-13644 - Assertion failure +innodb.innodb-wl5522-debug : MDEV-14200 - Wrong errno +innodb.innodb_bug13510739 : Modified in 10.3.7 +innodb.innodb_bug14147491 : MDEV-11808 - Index is corrupt +innodb.innodb_bug30423 : MDEV-7311 - Wrong result +innodb.innodb_bug48024 : MDEV-14352 - Assertion failure +innodb.innodb_bug54044 : Modified in 10.3.7 +innodb.innodb_bug59641 : MDEV-13830 - Assertion failure +innodb.innodb_bulk_create_index_replication : MDEV-15273 - Slave failed to start +innodb.innodb_defrag_stats_many_tables : MDEV-14198 - Table is full +innodb.innodb_defragment_small : Modified in 10.3.8 +innodb.innodb_information_schema : MDEV-8851 - Wrong result +innodb.innodb_max_recordsize_32k : MDEV-14801 - Operation failed +innodb.innodb_max_recordsize_64k : MDEV-15203 - Wrong result +innodb.innodb_monitor : MDEV-10939 - Testcase timeout +innodb.innodb_query_cache : Added in 10.3.8 +innodb.innodb_stats : MDEV-10682 - wrong result +innodb.innodb_stats_persistent_debug : MDEV-14801 - Operation failed +innodb.innodb_sys_semaphore_waits : MDEV-10331 - Semaphore wait +innodb.innodb_zip_innochecksum2 : MDEV-13882 - Extra warnings +innodb.innodb_zip_innochecksum3 : MDEV-14486 - Resource temporarily unavailable +innodb.log_corruption : MDEV-13251 - Wrong result +innodb.log_data_file_size : MDEV-14204 - Server failed to start +innodb.log_file_name : MDEV-14193 - Exception +innodb.log_file_size : MDEV-15668 - Not found pattern +innodb.monitor : MDEV-16179 - Wrong result +innodb.purge_secondary : MDEV-15681 - Wrong result +innodb.purge_thread_shutdown : MDEV-13792 - Wrong result +innodb.read_only_recovery : MDEV-13886 - Server crash +innodb.recovery_shutdown : MDEV-15671 - Checksum mismatch in datafile +innodb.rename_table : Modified in 10.3.8 +innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace +innodb.sp_temp_table : MDEV-16647 - Could not remove temporary table +innodb.table_definition_cache_debug : MDEV-14206 - Extra warning +innodb.table_flags : MDEV-13572 - Wrong result +innodb.temp_table_savepoint : MDEV-16182 - Wrong result +innodb.temporary_table : MDEV-13265 - Wrong result; modified in 10.3.7 +innodb.tmpdir : Modified in 10.3.7 +innodb.update_time : MDEV-14804 - Wrong result +innodb.xa_recovery : MDEV-15279 - mysqld got exception + +#----------------------------------------------------------------------- + +innodb_fts.fulltext2 : Modified in 10.3.7 +innodb_fts.fulltext_var : Modified in 10.3.7 +innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure +innodb_fts.innodb_fts_misc : Modified in 10.3.7 +innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning +innodb_fts.innodb_fts_plugin : MDEV-13888 - Errors in server log +innodb_fts.innodb_fts_stopword_charset : MDEV-13259 - Table crashed +innodb_fts.sync : MDEV-14808 - Wrong result + +#----------------------------------------------------------------------- + +innodb_gis.rtree_compress2 : MDEV-16269 - Wrong result +innodb_gis.rtree_concurrent_srch : MDEV-15284 - Wrong result with embedded +innodb_gis.rtree_purge : MDEV-15275 - Timeout +innodb_gis.rtree_recovery : MDEV-15274 - Error on check +innodb_gis.rtree_split : MDEV-14208 - Too many arguments +innodb_gis.rtree_undo : MDEV-14456 - Timeout in include file +innodb_gis.types : MDEV-15679 - Table is marked as crashed + +#----------------------------------------------------------------------- + +innodb_zip.cmp_per_index : MDEV-14490 - Table is marked as crashed +innodb_zip.innochecksum_3 : MDEV-13279 - Extra warnings +innodb_zip.wl5522_debug_zip : MDEV-11600 - Operating system error number 2 +innodb_zip.wl6470_1 : MDEV-14240 - Assertion failure +innodb_zip.wl6501_1 : MDEV-10891 - Can't create UNIX socket +innodb_zip.wl6501_scale_1 : MDEV-13254 - Timeout, MDEV-14104 - Error 192 + +#----------------------------------------------------------------------- + +main.alter_table : Modified in 10.3.8 +main.alter_table_errors : Added in 10.3.7 +main.alter_table_trans : MDEV-12084 - timeout +main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result +main.ansi : Modified in 10.3.7 +main.auth_named_pipe : MDEV-14724 - System error 2 +main.auto_increment : MDEV-16652 - Out of range, modified in 10.3.8 +main.check : Modified in 10.3.8 +main.check_constraint : Modified in 10.3.7 +main.connect : MDEV-16270 - Wrong result +main.connect2 : MDEV-13885 - Server crash +main.count_distinct2 : MDEV-11768 - timeout +main.create_delayed : MDEV-10605 - failed with timeout +main.create_drop_event : MDEV-16271 - Wrong result +main.create_or_replace : Modified in 10.3.7 +main.cte_nonrecursive : Modified in 10.3.8 +main.cte_recursive : Modified in 10.3.7 +main.ctype_utf16le : MDEV-10675: timeout or extra warnings +main.custom_aggregate_functions : Modified in 10.3.7 +main.debug_sync : MDEV-10607 - internal error +main.derived_cond_pushdown : Modified in 10.3.8 +main.derived_opt : MDEV-11768 - timeout +main.derived_view : Modified in 10.3.8 +main.distinct : MDEV-14194 - Crash; modified in 10.3.7 +main.drop_bad_db_type : MDEV-15676 - Wrong result +main.events_2 : MDEV-13277 - Crash +main.events_bugs : MDEV-12892 - Crash +main.events_restart : MDEV-12236 - Server shutdown problem +main.events_slowlog : MDEV-12821 - Wrong result +main.explain_slowquerylog : Modified in 10.3.7 +main.func_json : Modified in 10.3.8 +main.func_misc : Modified in 10.3.8 +main.func_time : Modified in 10.3.8 +main.func_time_hires : Modified in 10.3.8 +main.gis : MDEV-13411 - wrong result on P8 +main.grant : Modified in 10.3.8 +main.grant2 : Modified in 10.3.8 +main.grant_not_windows : Added in 10.3.7 +main.having : Modified in 10.3.8 +main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown +main.index_intersect_innodb : MDEV-10643 - failed with timeout +main.index_merge_innodb : MDEV-7142 - Plan mismatch +main.innodb_mysql_lock : MDEV-7861 - Wrong result +main.insert_select : Modified in 10.3.7 +main.invisible_field_grant_completely : Added in 10.3.7 +main.invisible_field_grant_system : Added in 10.3.7 +main.kill-2 : MDEV-13257 - Wrong result +main.kill_processlist-6619 : MDEV-10793 - Wrong result +main.limit : Modified in 10.3.8 +main.lock : Modified in 10.3.8 +main.log_slow : MDEV-13263 - Wrong result +main.log_tables-big : MDEV-13408 - wrong result +main.max_statement_time : Modified in 10.3.8 +main.mdev-504 : MDEV-15171 - warning +main.merge : MDEV-10607 - sporadic "can't connect" +main.multi_update : Modified in 10.3.7 +main.mysql : Modified in 10.3.7 +main.mysql_client_test_comp : MDEV-16641 - exec failed +main.mysql_client_test_nonblock : CONC-208 - Error on Power; MDEV-15096 - exec failed +main.mysql_cp932 : Modified in 10.3.7 +main.mysql_upgrade_noengine : MDEV-14355 - Wrong result +main.mysql_upgrade_ssl : MDEV-13492 - Unknown SSL error +main.mysqld_option_err : MDEV-12747 - Timeout +main.mysqldump : MDEV-14800 - Stack smashing detected; modified in 10.3.8 +main.mysqlhotcopy_myisam : MDEV-10995 - Hang on debug +main.mysqlslap : Modified in 10.3.8 +main.mysqltest : MDEV-13887 - Wrong result +main.mysqltest_tracking_info : Added in 10.3.8 +main.olap : Modified in 10.3.8 +main.openssl_1 : MDEV-13492 - Unknown SSL error +main.order_by_optimizer_innodb : MDEV-10683 - Wrong result +main.parser : Modified in 10.3.7 +main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock +main.partition_innodb : Modified in 10.3.7 +main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings +main.partition_open_files_limit : Modified in 10.3.8 +main.ps : MDEV-11017 - Wrong result; modified in 10.3.8 +main.query_cache : MDEV-16180 - Wrong result +main.query_cache_debug : MDEV-15281 - Query cache is disabled +main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away +main.read_only_innodb : Modified in 10.3.8 +main.rename : Modified in 10.3.8 +main.reset_connection : Added in 10.3.8 +main.select : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.select_jcl6 : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.select_pkeycache : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.selectivity : Modified in 10.3.8 +main.session_tracker_last_gtid : Added in 10.3.8 +main.set_password : Added in 10.3.8 +main.set_statement : MDEV-13183 - Wrong result +main.shm : MDEV-12727 - Mismatch, ERROR 2013 +main.show_explain : MDEV-10674 - Wrong result code +main.show_grants_with_plugin-7985 : Modified in 10.3.8 +main.sp : MDEV-7866 - Mismatch; modified in 10.3.8 +main.sp-code : Modified in 10.3.7 +main.sp-condition-handler : Added in 10.3.8 +main.sp-cursor : Modified in 10.3.8 +main.sp-row : Modified in 10.3.8 +main.sp-security : Modified in 10.3.8 +main.sp_notembedded : MDEV-10607 - internal error +main.sql_mode : Modified in 10.3.8 +main.ssl_ca : MDEV-10895 - SSL connection error on Power +main.ssl_cert_verify : MDEV-13735 - Server crash +main.ssl_connect : MDEV-13492 - Unknown SSL error +main.ssl_timeout : MDEV-11244 - Crash +main.stat_tables_par : MDEV-13266 - Wrong result +main.stat_tables_par_innodb : MDEV-14155 - Wrong rounding +main.statistics : Modified in 10.3.8 +main.statistics_close : Added in 10.3.8 +main.status : MDEV-13255 - Wrong result +main.subselect-crash_15755 : Added in 10.3.7 +main.subselect_innodb : MDEV-10614 - Wrong result +main.subselect_sj2_mat : Modified in 10.3.8 +main.symlink-aria-11902 : MDEV-15098 - error 40 from storage engine +main.symlink-myisam-11902 : MDEV-15098 - Error 40 from storage engine +main.tc_heuristic_recover : MDEV-14189 - Wrong result +main.trigger : Modified in 10.3.8 +main.type_bit : Modified in 10.3.8 +main.type_blob : MDEV-15195 - Wrong result; modified in 10.3.8 +main.type_datetime : MDEV-14322 - wrong result +main.type_datetime_hires : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.type_decimal : Modified in 10.3.8 +main.type_float : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.type_int : Modified in 10.3.8 +main.type_time_hires : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.type_timestamp_hires : MDEV-15430 - Wrong result with clang-4 (compiler bug) +main.userstat : MDEV-12904 - SSL errors +main.win : Modified in 10.3.8 +main.xa : MDEV-11769 - lock wait timeout + +#----------------------------------------------------------------------- + +maria.alter : Modified in 10.3.7 +maria.insert_select : MDEV-12757 - Timeout +maria.insert_select-7314 : MDEV-16492 - Timeout +maria.lock : Modified in 10.3.8 +maria.maria : MDEV-14430 - Extra warning; modified in 10.3.8 +maria.maria-autoinc : MDEV-16652 - Out of range; added in 10.3.8 + +#----------------------------------------------------------------------- + +mariabackup.absolute_ibdata_paths : MDEV-16642 - Wrong result +mariabackup.apply-log-only : MDEV-14192 - Assertion failure +mariabackup.apply-log-only-incr : MDEV-14192 - Assertion failure; modified in 10.3.8 +mariabackup.backup_ssl : MDEV-14192 - Assertion failure +mariabackup.data_directory : MDEV-15270 - Error on exec +mariabackup.full_backup : MDEV-16571 - Wrong result +mariabackup.huge_lsn : MDEV-15662 - Sequence number is in the future +mariabackup.incremental_backup : MDEV-14192 - Assertion failure +mariabackup.incremental_encrypted : MDEV-14188 - Wrong result, MDEV-15667 - timeout +mariabackup.lock_ddl_per_table : Modified in 10.3.8 +mariabackup.mdev-14447 : MDEV-15201 - Timeout; modified in 10.3.8 +mariabackup.partial_exclude : MDEV-15270 - Error on exec +mariabackup.partition_datadir : Modified in 10.3.8 +mariabackup.rename_during_mdl_lock : Added in 10.3.8 +mariabackup.xb_aws_key_management : MDEV-15680 - Error: xtrabackup_copy_logfile() failed +mariabackup.xb_compressed_encrypted : MDEV-14812 - Segmentation fault +mariabackup.xb_file_key_management : MDEV-16650 - Wrong result +mariabackup.xb_history : MDEV-16268 - Error on exec +mariabackup.xb_page_compress : MDEV-14810 - status: 1, errno: 11 +mariabackup.xb_partition : MDEV-16643 - Table does not exist +mariabackup.xb_rocksdb : Added in 10.3.8 +mariabackup.xb_rocksdb_datadir : Added in 10.3.8 +mariabackup.xb_rocksdb_datadir_debug : Added in 10.3.8 +mariabackup.xbstream : MDEV-14192 - Crash + +#----------------------------------------------------------------------- + +mroonga/storage.* : MDEV-16127 - Wrong result + +mroonga/storage.column_datetime_32bit_2038 : Wrong result on Alpha +mroonga/storage.column_datetime_32bit_before_unix_epoch : Wrong result on Alpha +mroonga/storage.column_datetime_32bit_max : Wrong result on Alpha +mroonga/storage.column_datetime_32bit_out_of_range : Wrong result on Alpha +mroonga/storage.index_multiple_column_unique_date_32bit_equal : Wrong result on Alpha +mroonga/storage.index_multiple_column_unique_date_order_32bit_desc : Wrong result on Alpha +mroonga/storage.index_multiple_column_unique_datetime_index_read : MDEV-8643 - Valgrind +mroonga/storage.repair_table_no_index_file : MDEV-9364 - wrong result, MDEV-14807 - wrong error message + +mroonga/wrapper.repair_table_no_index_file : MDEV-14807 - Wrong error message + +#----------------------------------------------------------------------- + +multi_source.gtid : MDEV-14202 - Crash +multi_source.info_logs : MDEV-12629 - Valgrind, MDEV-10042 - wrong result +multi_source.multisource : MDEV-10417 - Fails on Mips +multi_source.reset_slave : MDEV-10690 - Wrong result +multi_source.simple : MDEV-4633 - Wrong result +multi_source.status_vars : MDEV-4632 - failed while waiting for Slave_received_heartbeats + +#----------------------------------------------------------------------- + +parts.alter_data_directory_innodb : Added in 10.3.8 +parts.partition_alter2_2_maria : MDEV-14364 - Lost connection to MySQL server during query +parts.partition_auto_increment_archive : MDEV-16491 - Marked as crashed and should be repaired +parts.partition_auto_increment_maria : MDEV-14430 - Extra warning +parts.partition_debug_innodb : MDEV-10891 - Can't create UNIX socket; MDEV-15095 - Table doesn't exist +parts.partition_exch_qa_10 : MDEV-11765 - wrong result +parts.partition_innodb_status_file : MDEV-12901 - Valgrind +parts.show_create : Added in 10.3.7 + +#----------------------------------------------------------------------- + +percona.* : MDEV-10997 - Not maintained + +#----------------------------------------------------------------------- + +perfschema.bad_option_1 : MDEV-13892 - Timeout +perfschema.bad_option_3 : MDEV-12728 - Timeout on Power +perfschema.bad_option_5 : MDEV-14197 - Timeout +perfschema.dml_file_instances : MDEV-15179 - Wrong result +perfschema.func_file_io : MDEV-5708 - fails for s390x +perfschema.func_mutex : MDEV-5708 - fails for s390x +perfschema.hostcache_ipv4_addrinfo_again_allow : MDEV-12759 - Crash +perfschema.hostcache_ipv6_addrinfo_again_allow : MDEV-12752 - Crash +perfschema.hostcache_ipv6_addrinfo_bad_allow : MDEV-13260 - Crash +perfschema.hostcache_ipv6_ssl : MDEV-10696 - Crash +perfschema.partition : Added in 10.3.8 +perfschema.privilege_table_io : MDEV-13184 - Extra lines +perfschema.socket_connect : MDEV-15677 - Wrong result +perfschema.socket_summary_by_event_name_func : MDEV-10622 - Wrong result +perfschema.stage_mdl_global : MDEV-11803 - wrong result on slow builders +perfschema.stage_mdl_procedure : MDEV-11545 - Missing row +perfschema.stage_mdl_table : MDEV-12638 - Wrong result +perfschema.threads_mysql : MDEV-10677 - Wrong result + +#----------------------------------------------------------------------- + +perfschema_stress.* : MDEV-10996 - Not maintained + +#----------------------------------------------------------------------- + +plugins.feedback_plugin_send : MDEV-7932, MDEV-11118 - Connection problems and such +plugins.processlist : MDEV-16574 - Wrong result; added in 10.3.8 +plugins.server_audit : MDEV-14295 - Wrong result +plugins.thread_pool_server_audit : MDEV-14295 - Wrong result + +#----------------------------------------------------------------------- + +rocksdb.* : Too many crashes in various tests + +rocksdb.2pc_group_commit : MDEV-14455 - Wrong result +rocksdb.add_index_inplace : MDEV-16648 - Crash +rocksdb.allow_no_primary_key : MDEV-16634 - Crash +rocksdb.allow_no_primary_key_with_sk : MDEV-16639 - Crash +rocksdb.analyze_table : Modified in 10.3.7 +rocksdb.autoinc_crash_safe : MDEV-16637 - Crash +rocksdb.autoinc_crash_safe_partition : MDEV-16639 - Crash +rocksdb.autoinc_debug : MDEV-16203 - Wrong result +rocksdb.autoinc_secondary : MDEV-16638 - Crash +rocksdb.autoinc_vars_thread : MDEV-16573 - Debug sync timed out +rocksdb.bloomfilter2 : MDEV-16564 - Wrong result +rocksdb.bloomfilter4 : MDEV-16649 - Crash +rocksdb.bulk_load_errors : MDEV-16575 - Wrong result +rocksdb.check_ignore_unknown_options : MDEV-16310 - Non-portable commands; modified in 10.3.8 +rocksdb.deadlock : MDEV-16033 - Timeout +rocksdb.drop_index_inplace : MDEV-14162 - Crash on shutdown +rocksdb.drop_table : MDEV-14308 - Timeout +rocksdb.drop_table2 : MDEV-16631 - Crash +rocksdb.issue255 : MDEV-16577 - Wrong plan; modified in 10.3.8 +rocksdb.locking_issues : MDEV-14464 - Wrong result +rocksdb.mariadb_ignore_dirs : MDEV-16639 - Crash +rocksdb.mariadb_port_fixes : MDEV-16387 - Wrong plan; modified in 10.3.8 +rocksdb.max_open_files : MDEV-16639 - Crash +rocksdb.read_only_tx : MDEV-16565 - Server crash +rocksdb.rocksdb_cf_options : MDEV-16639 - Crash +rocksdb.rocksdb_cf_per_partition : MDEV-16636 - Wrong result +rocksdb.rocksdb_parts : MDEV-13843 - Wrong result +rocksdb.singledelete : MDEV-16633 - Crash +rocksdb.truncate_table3 : MDEV-14506 - Lost connection to server +rocksdb.ttl_primary_read_filtering : MDEV-16560 - Wrong result +rocksdb.ttl_secondary_read_filtering : MDEV-16560 - Wrong result +rocksdb.unique_check : MDEV-16576 - Wrong errno +rocksdb.use_direct_reads_writes : MDEV-16646 - Crash + +#----------------------------------------------------------------------- + +rocksdb_rpl.mdev12179 : MDEV-16632 - Crash +rocksdb_rpl.rpl_binlog_xid_count : MDEV-16644 - Crash + +#----------------------------------------------------------------------- + +rocksdb_sys_vars.rocksdb_remove_mariabackup_checkpoint_basic : Added in 10.3.8 + +#----------------------------------------------------------------------- + +roles.acl_load_mutex-5170 : Modified in 10.2.16 +roles.create_and_grant_role : MDEV-11772 - wrong result +roles.grant_revoke_current : Modified in 10.3.8 +roles.set_default_role_ps-6960 : Modified in 10.3.8 + +#----------------------------------------------------------------------- + +rpl-tokudb.* : MDEV-14354 - Tests fail with tcmalloc + +rpl.last_insert_id : MDEV-10625 - warnings in error log +rpl.rename : Added in 10.3.8 +rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips +rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips +rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log +rpl.rpl_binlog_errors : MDEV-12742 - Crash +rpl.rpl_binlog_index : MDEV-9501 - Failed registering on master +rpl.rpl_colSize : MDEV-16112 - Server crash +rpl.rpl_ctype_latin1 : MDEV-14813 - Wrong result on Mac +rpl.rpl_ddl : MDEV-10417 - Fails on Mips +rpl.rpl_do_grant : Modified in 10.3.8 +rpl.rpl_domain_id_filter_io_crash : MDEV-12729 - Timeout in include file, MDEV-13677 - Server crash +rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result +rpl.rpl_extra_col_master_innodb : MDEV-16570 - Extra warning +rpl.rpl_extra_col_master_myisam : MDEV-14203 - Extra warning +rpl.rpl_gtid_basic : MDEV-10681 - server startup problem +rpl.rpl_gtid_crash : MDEV-9501 - Failed registering on master, MDEV-13643 - Lost connection +rpl.rpl_gtid_delete_domain : MDEV-14463 - Timeout +rpl.rpl_gtid_errorhandling : MDEV-13261 - Crash +rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings +rpl.rpl_gtid_reconnect : MDEV-14497 - Crash +rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown, MDEV-12629 - Valgrind warnings +rpl.rpl_gtid_until : MDEV-10625 - warnings in error log +rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips +rpl.rpl_innodb_mixed_dml : Include file modified in 10.3.8 +rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x +rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x +rpl.rpl_insert_id : MDEV-15197 - Wrong result +rpl.rpl_insert_id_pk : MDEV-16567 - Assertion failure +rpl.rpl_insert_ignore : MDEV-14365 - Lost connection to MySQL server during query +rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips +rpl.rpl_mariadb_slave_capability : MDEV-11018 - Extra lines in binlog +rpl.rpl_mdev12179 : Modified in 10.3.7 +rpl.rpl_mdev382 : Modified in 10.3.7 +rpl.rpl_mdev6020 : MDEV-15272 - Server crash +rpl.rpl_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed +rpl.rpl_non_direct_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed +rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master_pos_wait +rpl.rpl_non_direct_stm_mixing_engines : MDEV-14489 - Failed sync_slave_with_master +rpl.rpl_parallel : MDEV-10653 - Timeouts +rpl.rpl_parallel_conflicts : MDEV-15272 - Server crash +rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure +rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout +rpl.rpl_parallel_optimistic : MDEV-15278 - Failed to sync with master; modified in 10.3.8 +rpl.rpl_parallel_optimistic_nobinlog : MDEV-15278 - Failed to sync with master +rpl.rpl_parallel_retry : MDEV-11119 - Crash +rpl.rpl_parallel_temptable : MDEV-10356 - Crash +rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips +rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings +rpl.rpl_row_001 : MDEV-16653 - MTR's internal check fails +rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start +rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed +rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result +rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed +rpl.rpl_row_img_eng_min : MDEV-13875 - diff_files failed +rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed +rpl.rpl_row_index_choice : MDEV-15196 - Slave crash +rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x +rpl.rpl_row_until : MDEV-14052 - Master will not send events with checksum +rpl.rpl_semi_sync : MDEV-11220 - Wrong result +rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result +rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result +rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings +rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Assorted failures +rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition +rpl.rpl_semisync_ali_issues : MDEV-16272 - Wrong result +rpl.rpl_set_statement_default_master : MDEV-13258 - Extra warning +rpl.rpl_show_slave_hosts : MDEV-10681 - Crash +rpl.rpl_skip_replication : MDEV-13258 - Extra warning +rpl.rpl_slave_grp_exec : MDEV-10514 - Deadlock +rpl.rpl_slave_load_tmpdir_not_exist : MDEV-14203 - Extra warning +rpl.rpl_slow_query_log : MDEV-13250 - Test abort +rpl.rpl_sp_effects : MDEV-13249 - Crash +rpl.rpl_start_stop_slave : MDEV-13567 - Sync slave timeout +rpl.rpl_stm_000001 : MDEV-16274 - Connection attributes were truncated +rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master failed +rpl.rpl_stm_multi_query : MDEV-9501 - Failed registering on master +rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion +rpl.rpl_stm_reset_slave : MDEV-16274 - Connection attributes were truncated +rpl.rpl_stm_stop_middle_group : MDEV-13791 - Server crash +rpl.rpl_sync : MDEV-13830 - Assertion failure +rpl.rpl_temporal_mysql56_to_mariadb53 : MDEV-9501 - Failed registering on master +rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries +rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result + +rpl/extra/rpl_tests.* : MDEV-10994 - Not maintained + +#----------------------------------------------------------------------- + +sphinx.* : MDEV-10986 - Tests have not been maintained + +sphinx.sphinx : MDEV-10986 - Sporadic failures +sphinx.union-5539 : MDEV-10986 - Sporadic failures + +#----------------------------------------------------------------------- + +spider.* : MDEV-9329 - tests are too memory-consuming +spider.basic_sql : MDEV-11186 - Internal check fails +spider.spider_fixes_part : Modified in 10.3.8 + +spider/bg.direct_aggregate : MDEV-7098 - Packets out of order +spider/bg.direct_aggregate_part : MDEV-7098 - Trying to unlock mutex that wasn't locked +spider/bg.ha : MDEV-9329 - failures on s390x +spider/bg.ha_part : MDEV-9329 - Fails on Ubuntu/s390x +spider/bg.spider3_fixes : MDEV-12639 - Syntax error +spider/bg.spider_fixes : MDEV-7098 -Mutex problem, MDEV-9329 - failures on s390x +spider/bg.spider_fixes_part : MDEV-7098 - Trying to unlock mutex that wasn't locked +spider/bg.vp_fixes : MDEV-9329 - Fails on Ubuntu/s390x + +spider/handler.* : MDEV-10987, MDEV-10990 - Tests have not been maintained + +#----------------------------------------------------------------------- + +sql_sequence.concurrent_create : MDEV-16635 - Server crash +sql_sequence.replication_mixed : Added in 10.3.8 + +#----------------------------------------------------------------------- + +storage_engine* : Tests are not always timely maintained +storage_engine.* : Not always timely maintained + +#----------------------------------------------------------------------- + +stress.ddl_innodb : MDEV-10635 - Testcase timeout + +#----------------------------------------------------------------------- + +sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x +sys_vars.innodb_buffer_pool_dump_at_shutdown_basic : MDEV-14280 - Unexpected error +sys_vars.innodb_stats_include_delete_marked_basic : Modified in 10.3.7 +sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout +sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash +sys_vars.maximum_basic : Modified in 10.3.8 +sys_vars.rpl_init_slave_func : MDEV-10149 - Test assertion +sys_vars.slow_query_log_func : MDEV-14273 - Wrong result +sys_vars.sysvars_innodb : Modified in 10.3.8 +sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result +sys_vars.wait_timeout_func : MDEV-12896 - Wrong result + +#----------------------------------------------------------------------- + +tokudb.change_column_all_1000_10 : MDEV-12640 - Lost connection +tokudb.change_column_bin : MDEV-12640 - Lost connection +tokudb.change_column_char : MDEV-12822 - Lost connection +tokudb.cluster_filter : MDEV-10678 - Wrong execution plan +tokudb.cluster_filter_hidden : MDEV-10678 - Wrong execution plan +tokudb.cluster_filter_unpack_varchar : MDEV-10636 - Wrong execution plan +tokudb.dir_per_db : MDEV-11537 - Wrong result +tokudb.dir_per_db_rename_to_nonexisting_schema : MDEV-14359 - Directory not empty +tokudb.hotindex-del-0 : MDEV-16559 - Timeout +tokudb.hotindex-insert-0 : MDEV-15271 - Timeout +tokudb.hotindex-insert-1 : MDEV-13870 - Lost connection to MySQL server +tokudb.hotindex-insert-2 : MDEV-15271 - Timeout +tokudb.hotindex-insert-bigchar : MDEV-12640 - Crash +tokudb.hotindex-update-0 : MDEV-15198 - Timeout +tokudb.hotindex-update-1 : MDEV-12640 - Crash +tokudb.locks-select-update-1 : MDEV-13406 - Lock wait timeout +tokudb.rows-32m-rand-insert : MDEV-12640 - Crash +tokudb.rows-32m-seq-insert : MDEV-12640 - Crash +tokudb.savepoint-5 : MDEV-15280 - Wrong result +tokudb.type_datetime : MDEV-15193 - Wrong result + +#----------------------------------------------------------------------- + +tokudb_alter_table.hcad_all_add2 : MDEV-15269 - Timeout + +#----------------------------------------------------------------------- + +tokudb_backup.* : MDEV-11001 - Missing include file -#---------------------------------------------------------------- +#----------------------------------------------------------------------- -wsrep.binlog_format : MDEV-11532 - Could not execute check-testcase -wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node -wsrep.mdev_6832 : MDEV-14195 - Check testcase failed -wsrep.pool_of_threads : MDEV-12234 - GLIBCXX_3.4.20 not found -wsrep.variables : MDEV-14311 - Wrong result +tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output +tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output +tokudb_bugs.frm_store : MDEV-12823 - Valgrind +tokudb_bugs.frm_store2 : MDEV-12823 - Valgrind +tokudb_bugs.frm_store3 : MDEV-12823 - Valgrind +tokudb_bugs.xa : MDEV-11804 - Lock wait timeout -wsrep_info.plugin : MDEV-13569 - No nodes coming from prim view +#----------------------------------------------------------------------- +tokudb_parts.partition_alter4_tokudb : MDEV-12640 - Lost connection + +#----------------------------------------------------------------------- + +tokudb_rpl.* : MDEV-11001 - Missing include file + +#----------------------------------------------------------------------- + +tokudb_sys_vars.* : MDEV-11001 - Missing include file + +#----------------------------------------------------------------------- + +unit.conc_basic-t : MDEV-15286 - not ok 7 - test_reconnect_maxpackage +unit.conc_misc : MDEV-14811 - not ok 12 - test_conc49 +unit.conc_ps_bugs : MDEV-13252 - not ok 44 test_bug4236 +unit.lf : MDEV-12897 - Signal 11 thrown +unit.ma_test_loghandler : MDEV-10638 - record read not ok +unit.my_atomic : MDEV-15670 - Signal 11 thrown + +#----------------------------------------------------------------------- + +vcol.binlog : Added in 10.3.8 +vcol.index : Added in 10.3.8 +vcol.not_supported : MDEV-10639 - Testcase timeout +vcol.update : Modified in 10.3.8 +vcol.update_binlog : Added in 10.3.8 +vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout +vcol.vcol_misc : MDEV-16651 - Wrong error message; modified in 10.3.8 + +#----------------------------------------------------------------------- + +versioning.alter : Modified in 10.3.8 +versioning.partition : Modified in 10.3.7 +versioning.replace : Modified in 10.3.8 +versioning.select : Modified in 10.3.8 +versioning.truncate : Modified in 10.3.7 +versioning.trx_id : Modified in 10.3.8 +versioning.trx_id_versioning_attribute_persistence : Added in 10.3.8 + +#----------------------------------------------------------------------- + +wsrep.binlog_format : MDEV-11532 - Could not execute check-testcase +wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node +wsrep.mdev_6832 : MDEV-14195 - Check testcase failed +wsrep.pool_of_threads : MDEV-12234 - GLIBCXX_3.4.20 not found +wsrep.variables : MDEV-14311 - Wrong result; modified in 10.3.8 + +#----------------------------------------------------------------------- + +wsrep_info.plugin : MDEV-13569 - No nodes coming from prim view diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 06f6a29e4a0..8580fac3595 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -244,7 +244,7 @@ const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd) return pathname + (s - buf); } - fd = openat(dfd, s, O_NOFOLLOW | O_PATH); + fd = openat(dfd, s, O_NOFOLLOW | O_PATH | O_CLOEXEC); if (fd < 0) goto err; diff --git a/plugin/auth_ed25519/server_ed25519.c b/plugin/auth_ed25519/server_ed25519.c index e3f00409ae3..8870c271b18 100644 --- a/plugin/auth_ed25519/server_ed25519.c +++ b/plugin/auth_ed25519/server_ed25519.c @@ -101,7 +101,7 @@ maria_declare_plugin(ed25519) NULL, NULL, "1.0-alpha", - MariaDB_PLUGIN_MATURITY_BETA + MariaDB_PLUGIN_MATURITY_STABLE } maria_declare_plugin_end; diff --git a/plugin/auth_gssapi/gssapi_server.cc b/plugin/auth_gssapi/gssapi_server.cc index 49d0262690e..a498aba982d 100644 --- a/plugin/auth_gssapi/gssapi_server.cc +++ b/plugin/auth_gssapi/gssapi_server.cc @@ -43,21 +43,21 @@ static char* get_default_principal_name() if(krb5_init_context(&context)) { - my_printf_error(0, "GSSAPI plugin : krb5_init_context failed", + my_printf_error(1, "GSSAPI plugin : krb5_init_context failed", ME_ERROR_LOG | ME_WARNING); goto cleanup; } if (krb5_sname_to_principal(context, NULL, "mariadb", KRB5_NT_SRV_HST, &principal)) { - my_printf_error(0, "GSSAPI plugin : krb5_sname_to_principal failed", + my_printf_error(1, "GSSAPI plugin : krb5_sname_to_principal failed", ME_ERROR_LOG | ME_WARNING); goto cleanup; } if (krb5_unparse_name(context, principal, &unparsed_name)) { - my_printf_error(0, "GSSAPI plugin : krb5_unparse_name failed", + my_printf_error(1, "GSSAPI plugin : krb5_unparse_name failed", ME_ERROR_LOG | ME_WARNING); goto cleanup; } @@ -65,7 +65,7 @@ static char* get_default_principal_name() /* Check for entry in keytab */ if (krb5_kt_read_service_key(context, NULL, principal, 0, (krb5_enctype)0, &key)) { - my_printf_error(0, "GSSAPI plugin : default principal '%s' not found in keytab", + my_printf_error(1, "GSSAPI plugin : default principal '%s' not found in keytab", ME_ERROR_LOG | ME_WARNING, unparsed_name); goto cleanup; } @@ -103,7 +103,7 @@ int plugin_init() /* import service principal from plain text */ if(srv_principal_name && srv_principal_name[0]) { - my_printf_error(0, "GSSAPI plugin : using principal name '%s'", + my_printf_error(1, "GSSAPI plugin : using principal name '%s'", ME_ERROR_LOG | ME_NOTE, srv_principal_name); principal_name_buf.length= strlen(srv_principal_name); principal_name_buf.value= srv_principal_name; diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index d7f7906f713..fe14edba139 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -175,6 +175,7 @@ IF(INSTALL_LAYOUT MATCHES "STANDALONE") SET(scriptdir ${prefix}/${INSTALL_BINDIR}) SET(libexecdir ${prefix}/${INSTALL_SBINDIR}) SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR}) + SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR}) SET(localstatedir ${prefix}/data) ELSE() SET(prefix "${CMAKE_INSTALL_PREFIX}") @@ -183,6 +184,7 @@ ELSE() SET(scriptdir ${INSTALL_BINDIRABS}) SET(libexecdir ${INSTALL_SBINDIRABS}) SET(pkgdatadir ${INSTALL_MYSQLSHAREDIRABS}) + SET(pkgplugindir ${INSTALL_PLUGINDIRABS}) SET(localstatedir ${MYSQL_DATADIR}) ENDIF() @@ -330,6 +332,22 @@ ELSE() COMPONENT ${${file}_COMPONENT} ) ENDFOREACH() + SET (wsrep_sst_rsync_wan ${CMAKE_CURRENT_BINARY_DIR}/wsrep_sst_rsync_wan) + ADD_CUSTOM_COMMAND( + OUTPUT ${wsrep_sst_rsync_wan} + COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink + wsrep_sst_rsync + wsrep_sst_rsync_wan + ) + ADD_CUSTOM_TARGET(symlink_wsrep_sst_rsync + ALL + DEPENDS ${wsrep_sst_rsync_wan} + ) + INSTALL( + FILES ${wsrep_sst_rsync_wan} + DESTINATION ${INSTALL_BINDIR} + COMPONENT Server + ) FOREACH(file ${WSREP_SOURCE}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh @@ -343,7 +361,6 @@ ELSE() COMPONENT ${${file}_COMPONENT} ) ENDFOREACH() - ENDIF() # Install libgcc as mylibgcc.a diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 8d706e4c5ad..ad7c028a7af 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -307,6 +307,7 @@ then langdir="$basedir/sql/share/english" srcpkgdatadir="$srcdir/scripts" buildpkgdatadir="$builddir/scripts" + plugindir="$builddir/plugin/auth_socket" elif test -n "$basedir" then bindir="$basedir/bin" # only used in the help text @@ -335,6 +336,7 @@ then cannot_find_file fill_help_tables.sql @pkgdata_locations@ exit 1 fi + plugindir=`find_in_dirs --dir auth_socket.so $basedir/lib*/plugin $basedir/lib*/mysql/plugin` else basedir="@prefix@" bindir="@bindir@" @@ -342,6 +344,7 @@ else mysqld="@libexecdir@/mysqld" srcpkgdatadir="@pkgdatadir@" buildpkgdatadir="@pkgdatadir@" + plugindir="@pkgplugindir@" fi # Set up paths to SQL scripts required for bootstrap @@ -461,6 +464,7 @@ mysqld_install_cmd_line() { "$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\ "--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \ + "--plugin-dir=${plugindir}" \ $args --max_allowed_packet=8M \ --net_buffer_length=16K } @@ -538,19 +542,24 @@ then s_echo "To start mysqld at boot time you have to copy" s_echo "support-files/mysql.server to the right place for your system" - echo - echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !" - echo "To do so, start the server, then issue the following commands:" - echo - echo "'$bindir/mysqladmin' -u root password 'new-password'" - echo "'$bindir/mysqladmin' -u root -h $hostname password 'new-password'" - echo - echo "Alternatively you can run:" - echo "'$bindir/mysql_secure_installation'" - echo - echo "which will also give you the option of removing the test" - echo "databases and anonymous user created by default. This is" - echo "strongly recommended for production servers." + if test "$auth_root_authentication_method" = normal + then + echo + echo + echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !" + echo "To do so, start the server, then issue the following commands:" + echo + echo "'$bindir/mysqladmin' -u root password 'new-password'" + echo "'$bindir/mysqladmin' -u root -h $hostname password 'new-password'" + echo + echo "Alternatively you can run:" + echo "'$bindir/mysql_secure_installation'" + echo + echo "which will also give you the option of removing the test" + echo "databases and anonymous user created by default. This is" + echo "strongly recommended for production servers." + fi + echo echo "See the MariaDB Knowledgebase at http://mariadb.com/kb or the" echo "MySQL manual for more instructions." diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql index 0fbbfe4701f..4761fe51dcc 100644 --- a/scripts/mysql_system_tables_data.sql +++ b/scripts/mysql_system_tables_data.sql @@ -35,8 +35,11 @@ INSERT INTO tmp_user_nopasswd VALUES ('localhost','root','','Y','Y','Y','Y','Y', REPLACE INTO tmp_user_nopasswd SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost'; REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0); REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0); --- More secure root account using unix sucket auth. +-- More secure root account using unix socket auth. INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0); +IF @auth_root_socket is not null THEN + IF not exists(select 1 from information_schema.plugins where plugin_name='unix_socket') THEN + INSTALL SONAME 'auth_socket'; END IF; END IF; INSERT INTO user SELECT * FROM tmp_user_nopasswd WHERE @had_user_table=0 AND @skip_auth_root_nopasswd IS NULL; INSERT INTO user SELECT * FROM tmp_user_socket WHERE @had_user_table=0 AND @auth_root_socket IS NOT NULL; diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 696ac552fad..5797bdc68d7 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB # This file is public domain and comes with NO WARRANTY of any kind # @@ -36,6 +36,7 @@ skip_err_log=0 syslog_tag_mysqld=mysqld syslog_tag_mysqld_safe=mysqld_safe +trap '' 1 2 3 15 # we shouldn't let anyone kill us # MySQL-specific environment variable. First off, it's not really a umask, # it's the desired mode. Second, it follows umask(2), not umask(3) in that @@ -159,7 +160,7 @@ eval_log_error () { # sed buffers output (only GNU sed supports a -u (unbuffered) option) # which means that messages may not get sent to syslog until the # mysqld process quits. - cmd="$cmd 2>&1 | logger -t '$syslog_tag_mysqld' -p daemon.error & wait" + cmd="$cmd 2>&1 | logger -t '$syslog_tag_mysqld' -p daemon.error" ;; *) echo "Internal program error (non-fatal):" \ @@ -877,13 +878,6 @@ then fi # -# From now on, we catch signals to do a proper shutdown of mysqld -# when signalled to do so. -# -trap '/usr/bin/mysqladmin --defaults-extra-file=/etc/mysql/debian.cnf refresh & wait' 1 # HUP -trap '/usr/bin/mysqladmin --defaults-extra-file=/etc/mysql/debian.cnf shutdown' 2 3 15 # INT QUIT and TERM - -# # Uncomment the following lines if you want all tables to be automatically # checked and repaired during startup. You should add sensible key_buffer # and sort_buffer values to my.cnf to improve check performance or require diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index e72b74ab6d1..21da52b015e 100755 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -35,12 +35,24 @@ case "$1" in # # Break address string into host:port/path parts # - readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*} - readonly WSREP_SST_OPT_HOST_UNESCAPED=`echo "$WSREP_SST_OPT_HOST"|awk '{if(match($0,/^\[.*\]$/)) $0=substr($0,2,RLENGTH-2);print}'` - readonly WSREP_SST_OPT_ADDR_PORT=$(echo $WSREP_SST_OPT_ADDR | \ - cut -d ']' -f 2 | cut -s -d ':' -f 2 | cut -d '/' -f 1) + case "${WSREP_SST_OPT_ADDR}" in + \[*) + # IPv6 + addr_no_bracket=${WSREP_SST_OPT_ADDR#\[} + readonly WSREP_SST_OPT_HOST_UNESCAPED=${addr_no_bracket%%\]*} + readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]" + ;; + *) + readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*} + readonly WSREP_SST_OPT_HOST_UNESCAPED=$WSREP_SST_OPT_HOST + ;; + esac + remain=${WSREP_SST_OPT_ADDR#${WSREP_SST_OPT_HOST}} + remain=${remain#:} + readonly WSREP_SST_OPT_ADDR_PORT=${remain%%/*} + remain=${remain#*/} + readonly WSREP_SST_OPT_MODULE=${remain%%/*} readonly WSREP_SST_OPT_PATH=${WSREP_SST_OPT_ADDR#*/} - readonly WSREP_SST_OPT_MODULE=${WSREP_SST_OPT_PATH%%/*} remain=${WSREP_SST_OPT_PATH#*/} readonly WSREP_SST_OPT_LSN=${remain%%/*} remain=${remain#*/} @@ -120,10 +132,10 @@ done readonly WSREP_SST_OPT_BYPASS readonly WSREP_SST_OPT_BINLOG -if [ -n "${WSREP_SST_OPT_ADDR:-}" ]; then +if [ -n "${WSREP_SST_OPT_ADDR_PORT:-}" ]; then if [ -n "${WSREP_SST_OPT_PORT:-}" ]; then - if [ -n "$WSREP_SST_OPT_ADDR_PORT" -a "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then - wsrep_log_error "port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" + if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then + echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 exit 2 fi else diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index cfe4838fbc4..faa3f10639b 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -108,11 +108,6 @@ then DROP PREPARE stmt;" fi -# Retrieve the donor's @@global.gtid_binlog_state. -GTID_BINLOG_STATE=$(echo "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_state'" |\ -$MYSQL_CLIENT $AUTH -S$WSREP_SST_OPT_SOCKET --disable-reconnect --connect_timeout=10 |\ -tail -1 | awk -F ' ' '{ print $2 }') - MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\ "$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED} "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" @@ -126,12 +121,16 @@ tail -1 | awk -F ' ' '{ print $2 }') SERVER_VERSION=$(echo "set statement wsrep_sync_wait=0 for SHOW VARIABLES LIKE 'version'" | $MYSQL |\ tail -1 | awk -F ' ' '{ print $2 }') +# Retrieve the donor's @@global.gtid_binlog_state. +GTID_BINLOG_STATE=$(echo "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_state'" | $MYSQL |\ +tail -1 | awk -F ' ' '{ print $2 }') + RESET_MASTER="" SET_GTID_BINLOG_STATE="" SQL_LOG_BIN_OFF="" # Safety check -if echo $SERVER_VERSION | grep '^10.' > /dev/null +if [ "${SERVER_VERSION%%.*}" != '5' ] then # If binary logging is enabled on the joiner node, we need to copy donor's # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be @@ -146,7 +145,7 @@ then fi # NOTE: we don't use --routines here because we're dumping mysql.proc table -MYSQLDUMP="$MYSQLDUMP $AUTH -S$WSREP_SST_OPT_SOCKET \ +MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF $AUTH -S$WSREP_SST_OPT_SOCKET \ --add-drop-database --add-drop-table --skip-add-locks --create-options \ --disable-keys --extended-insert --skip-lock-tables --quick --set-charset \ --skip-comments --flush-privileges --all-databases --events" diff --git a/sql-common/client.c b/sql-common/client.c index ad85738b0cb..088377f8c52 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2515,6 +2515,10 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, mysql->client_flag|= CLIENT_MULTI_RESULTS; #ifdef HAVE_OPENSSL + if (mysql->options.ssl_key || mysql->options.ssl_cert || + mysql->options.ssl_ca || mysql->options.ssl_capath || + mysql->options.ssl_cipher) + mysql->options.use_ssl = 1; if (mysql->options.use_ssl) mysql->client_flag|= CLIENT_SSL; #endif /* HAVE_OPENSSL */ diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 7253f7ba447..0037ff23153 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -45,23 +45,10 @@ ${CMAKE_BINARY_DIR}/sql ${WSREP_INCLUDES} ) -SET(GEN_SOURCES -${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h -${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc -${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.h -${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc -${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h -${CMAKE_CURRENT_BINARY_DIR}/lex_token.h -) -SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES} - PROPERTIES GENERATED 1) -IF(NOT CMAKE_CROSSCOMPILING) - ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h) -ENDIF() + ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h @@ -151,7 +138,10 @@ SET (SQL_SOURCE table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc - ${GEN_SOURCES} + ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc + ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc + ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h + ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h ${MYSYS_LIBWRAP_SOURCE} ) @@ -173,7 +163,6 @@ MYSQL_ADD_PLUGIN(sql_sequence ha_sequence.cc STORAGE_ENGINE MANDATORY STATIC_ONL RECOMPILE_FOR_EMBEDDED) ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) -ADD_DEPENDENCIES(sql GenServerSource) DTRACE_INSTRUMENT(sql) TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} mysys mysys_ssl dbug strings vio pcre @@ -339,40 +328,48 @@ IF(WITH_MYSQLD_LDFLAGS) "${MYSQLD_LINK_FLAGS} ${WITH_MYSQLD_LDFLAGS}") ENDIF() -INCLUDE(${CMAKE_SOURCE_DIR}/cmake/bison.cmake) + +FIND_PACKAGE(BISON 2.0) + # Handle out-of-source build from source package with possibly broken # bison. Copy bison output to from source to build directory, if not already # there -IF (NOT BISON_USABLE) -IF (NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) - IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.cc) - IF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.cc - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc COPYONLY) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.h - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h COPYONLY) +IF (NOT BISON_FOUND) + IF (NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + FOREACH(file sql_yacc.cc sql_yacc.hh sql_yacc_ora.cc sql_yacc_ora.hh) + IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file} AND (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${file})) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file} + ${CMAKE_CURRENT_BINARY_DIR}/${file} COPYONLY) ENDIF() + ENDFOREACH() ENDIF() -ENDIF() -ENDIF() -RUN_BISON( - ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h - MYSQL -) + IF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc) + # Output files are missing, bail out. + SET(ERRMSG + "Bison (GNU parser generator) is required to build MySQL." + "Please install bison." + ) + IF(WIN32) + SET(ERRMSG ${ERRMSG} + "You can download bison from http://gnuwin32.sourceforge.net/packages/bison.htm " + "Choose 'Complete package, except sources' installation. We recommend to " + "install bison into a directory without spaces, e.g C:\\GnuWin32.") + ENDIF() + MESSAGE(FATAL_ERROR ${ERRMSG}) + ENDIF() +ELSE() + BISON_TARGET(gen_sql_yacc ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc + COMPILE_FLAGS "-p MYSQL") -RUN_BISON( - ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc_ora.yy - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc - ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.h - ORA -) + BISON_TARGET(gen_sql_yacc_ora ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc_ora.yy ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc + COMPILE_FLAGS "-p ORA") +ENDIF() -# Gen_lex_hash IF(NOT CMAKE_CROSSCOMPILING) + ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc + ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.hh) ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc) ENDIF() @@ -388,12 +385,12 @@ TARGET_LINK_LIBRARIES(mysql_tzinfo_to_sql mysys mysys_ssl) ADD_CUSTOM_TARGET( GenServerSource - DEPENDS ${GEN_SOURCES} + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h + ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h + ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc ) -#Need this only for embedded -SET_TARGET_PROPERTIES(GenServerSource PROPERTIES EXCLUDE_FROM_ALL TRUE) - IF(WIN32 OR HAVE_DLOPEN AND NOT DISABLE_SHARED) ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def) SET_TARGET_PROPERTIES(udf_example PROPERTIES PREFIX "") @@ -406,8 +403,8 @@ CONFIGURE_FILE( ADD_CUSTOM_TARGET(dist COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/make_dist.cmake - DEPENDS ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc ${CMAKE_BINARY_DIR}/sql/sql_yacc.h - DEPENDS ${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.cc ${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.h + DEPENDS ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc ${CMAKE_BINARY_DIR}/sql/sql_yacc.hh + DEPENDS ${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.cc ${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.hh WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) diff --git a/sql/events.cc b/sql/events.cc index 49ac4b71100..c13582e634c 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -463,8 +463,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); - - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); if (lock_object_name(thd, MDL_key::EVENT, parse_data->dbname.str, parse_data->name.str)) @@ -594,8 +593,7 @@ Events::drop_event(THD *thd, const LEX_CSTRING *dbname, if (check_access(thd, EVENT_ACL, dbname->str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); - - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* Turn off row binlogging of this statement and use statement-based so @@ -621,7 +619,7 @@ Events::drop_event(THD *thd, const LEX_CSTRING *dbname, #ifdef WITH_WSREP error: DBUG_RETURN(TRUE); -#endif +#endif /* WITH_WSREP */ } diff --git a/sql/field.cc b/sql/field.cc index dc854826ed6..2b8bd0a3fb3 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3093,6 +3093,23 @@ void Field_decimal::sql_type(String &res) const } +Field *Field_decimal::make_new_field(MEM_ROOT *root, TABLE *new_table, + bool keep_type) +{ + if (keep_type) + return Field_real::make_new_field(root, new_table, keep_type); + + Field *field= new (root) Field_new_decimal(NULL, field_length, + maybe_null() ? (uchar*) "" : 0, 0, + NONE, &field_name, + dec, flags & ZEROFILL_FLAG, + unsigned_flag); + if (field) + field->init_for_make_new_field(new_table, orig_table); + return field; +} + + /**************************************************************************** ** Field_new_decimal ****************************************************************************/ @@ -3386,6 +3403,16 @@ longlong Field_new_decimal::val_int(void) } +ulonglong Field_new_decimal::val_uint(void) +{ + ASSERT_COLUMN_MARKED_FOR_READ; + longlong i; + my_decimal decimal_value; + my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), true, &i); + return i; +} + + my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value) { ASSERT_COLUMN_MARKED_FOR_READ; @@ -7503,15 +7530,7 @@ Field *Field_string::make_new_field(MEM_ROOT *root, TABLE *new_table, This is done to ensure that ALTER TABLE will convert old VARCHAR fields to now VARCHAR fields. */ - field->init(new_table); - /* - Normally orig_table is different from table only if field was - created via ::make_new_field. Here we alter the type of field, - so ::make_new_field is not applicable. But we still need to - preserve the original field metadata for the client-server - protocol. - */ - field->orig_table= orig_table; + field->init_for_make_new_field(new_table, orig_table); } return field; } @@ -10931,6 +10950,7 @@ uint32 Field_blob::max_display_length() const @param level - level of message (Note/Warning/Error) @param code - error code of message to be produced @param cut_increment - whenever we should increase cut fields count + @current_row - current row number @note This function won't produce warning or notes or increase cut fields counter @@ -10948,7 +10968,7 @@ uint32 Field_blob::max_display_length() const bool Field::set_warning(Sql_condition::enum_warning_level level, uint code, - int cut_increment) const + int cut_increment, ulong current_row) const { /* If this field was created only for type conversion purposes it @@ -10959,7 +10979,8 @@ Field::set_warning(Sql_condition::enum_warning_level level, uint code, { thd->cuted_fields+= cut_increment; push_warning_printf(thd, level, code, ER_THD(thd, code), field_name.str, - thd->get_stmt_da()->current_row_for_warning()); + current_row ? current_row + : thd->get_stmt_da()->current_row_for_warning()); return 0; } return level >= Sql_condition::WARN_LEVEL_WARN; diff --git a/sql/field.h b/sql/field.h index b6f28808e2e..a7335d3f018 100644 --- a/sql/field.h +++ b/sql/field.h @@ -800,9 +800,14 @@ public: } virtual double val_real(void)=0; virtual longlong val_int(void)=0; + /* + Get ulonglong representation. + Negative values are truncated to 0. + */ virtual ulonglong val_uint(void) { - return (ulonglong) val_int(); + longlong nr= val_int(); + return nr < 0 ? 0 : (ulonglong) nr; } virtual bool val_bool(void)= 0; virtual my_decimal *val_decimal(my_decimal *); @@ -1343,7 +1348,7 @@ public: virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; } virtual int set_time() { return 1; } bool set_warning(Sql_condition::enum_warning_level, unsigned int code, - int cuted_increment) const; + int cuted_increment, ulong current_row=0) const; protected: bool set_warning(unsigned int code, int cuted_increment) const { @@ -1393,6 +1398,19 @@ public: org_field->type() == MYSQL_TYPE_VARCHAR) new_table->s->db_create_options|= HA_OPTION_PACK_RECORD; } + void init_for_make_new_field(TABLE *new_table_arg, TABLE *orig_table_arg) + { + init(new_table_arg); + /* + Normally orig_table is different from table only if field was + created via ::make_new_field. Here we alter the type of field, + so ::make_new_field is not applicable. But we still need to + preserve the original field metadata for the client-server + protocol. + */ + orig_table= orig_table_arg; + } + /* maximum possible display length */ virtual uint32 max_display_length() const= 0; /** @@ -1663,6 +1681,8 @@ public: bool eq_def(const Field *field) const; Copy_func *get_copy_func(const Field *from) const { + if (unsigned_flag && from->cmp_type() == DECIMAL_RESULT) + return do_field_decimal; return do_field_int; } int save_in_field(Field *to) @@ -1877,6 +1897,7 @@ public: unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) {} + Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type); const Type_handler *type_handler() const { return &type_handler_olddecimal; } enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } @@ -1957,6 +1978,7 @@ public: int store_decimal(const my_decimal *); double val_real(void); longlong val_int(void); + ulonglong val_uint(void); my_decimal *val_decimal(my_decimal *); String *val_str(String*, String *); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); @@ -2003,6 +2025,11 @@ public: int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); bool val_bool() { return val_int() != 0; } + ulonglong val_uint() + { + longlong nr= val_int(); + return nr < 0 && !unsigned_flag ? 0 : (ulonglong) nr; + } int store_time_dec(const MYSQL_TIME *ltime, uint dec); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); virtual const Type_limits_int *type_limits_int() const= 0; @@ -3747,6 +3774,10 @@ public: uint32 char_length() const; uint32 octet_length() const; uint is_equal(Create_field *new_field); + + friend void TABLE::remember_blob_values(String *blob_storage); + friend void TABLE::restore_blob_values(String *blob_storage); + private: int save_field_metadata(uchar *first_byte); }; @@ -4044,6 +4075,8 @@ public: } Copy_func *get_copy_func(const Field *from) const { + if (from->cmp_type() == DECIMAL_RESULT) + return do_field_decimal; return do_field_int; } int save_in_field(Field *to) { return to->store(val_int(), true); } @@ -4344,7 +4377,7 @@ public: length*= charset->mbmaxlen; if (real_field_type() == MYSQL_TYPE_VARCHAR && compression_method()) length++; - DBUG_ASSERT(length <= UINT_MAX32); + set_if_smaller(length, UINT_MAX32); key_length= (uint) length; pack_length= type_handler()->calc_pack_length((uint32) length); } diff --git a/sql/gen_lex_token.cc b/sql/gen_lex_token.cc index b36df5e94be..c03bfe66f47 100644 --- a/sql/gen_lex_token.cc +++ b/sql/gen_lex_token.cc @@ -19,7 +19,7 @@ /* We only need the tokens here */ #define YYSTYPE_IS_DECLARED -#include <sql_yacc.h> +#include <sql_yacc.hh> #include <lex.h> #include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 58247234eec..18a6a15c766 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5201,7 +5201,8 @@ int ha_partition::rnd_pos_by_record(uchar *record) if (unlikely(get_part_for_buf(record, m_rec0, m_part_info, &m_last_part))) DBUG_RETURN(1); - DBUG_RETURN(handler::rnd_pos_by_record(record)); + int err= m_file[m_last_part]->rnd_pos_by_record(record); + DBUG_RETURN(err); } diff --git a/sql/handler.cc b/sql/handler.cc index b77b2a3fa2c..b3481c7e429 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3597,8 +3597,8 @@ void handler::print_error(int error, myf errflag) break; case HA_ERR_ABORTED_BY_USER: { - DBUG_ASSERT(table->in_use->killed); - table->in_use->send_kill_message(); + DBUG_ASSERT(ha_thd()->killed); + ha_thd()->send_kill_message(); DBUG_VOID_RETURN; } case HA_ERR_WRONG_MRG_TABLE_DEF: @@ -3839,7 +3839,7 @@ void handler::print_error(int error, myf errflag) */ errflag|= ME_ERROR_LOG; } - } + } /* if we got an OS error from a file-based engine, specify a path of error */ if (error < HA_ERR_FIRST && bas_ext()[0]) @@ -4579,6 +4579,7 @@ handler::ha_create_partitioning_metadata(const char *name, DBUG_ASSERT(m_lock_type == F_UNLCK || (!old_name && strcmp(name, table_share->path.str))); + return create_partitioning_metadata(name, old_name, action_flag); } @@ -6505,6 +6506,12 @@ void ha_fake_trx_id(THD *thd) DBUG_VOID_RETURN; } + if (thd->wsrep_ws_handle.trx_id != WSREP_UNDEFINED_TRX_ID) + { + WSREP_DEBUG("fake trx id skipped: %lu", thd->wsrep_ws_handle.trx_id); + DBUG_VOID_RETURN; + } + /* Try statement transaction if standard one is not set. */ THD_TRANS *trans= (thd->transaction.all.ha_list) ? &thd->transaction.all : &thd->transaction.stmt; diff --git a/sql/handler.h b/sql/handler.h index 3d1b764bd14..54df7941526 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3556,9 +3556,17 @@ public: */ virtual int rnd_pos_by_record(uchar *record) { + int error; DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION); + + error = ha_rnd_init(false); + if (error != 0) + return error; + position(record); - return rnd_pos(record, ref); + error = ha_rnd_pos(record, ref); + ha_rnd_end(); + return error; } virtual int read_first_row(uchar *buf, uint primary_key); public: diff --git a/sql/item.cc b/sql/item.cc index 68aed25a580..878b4c91439 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -202,6 +202,19 @@ String *Item::val_str_ascii(String *str) } +String *Item::val_str_ascii_revert_empty_string_is_null(THD *thd, String *str) +{ + String *res= val_str_ascii(str); + if (!res && (thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL)) + { + null_value= false; + str->set("", 0, &my_charset_latin1); + return str; + } + return res; +} + + String *Item::val_str(String *str, String *converter, CHARSET_INFO *cs) { String *res= val_str(str); @@ -2253,6 +2266,7 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) collation.set(value_item->collation.collation, DERIVATION_IMPLICIT); max_length= value_item->max_length; decimals= value_item->decimals; + unsigned_flag= value_item->unsigned_flag; fixed= 1; return FALSE; } @@ -5515,9 +5529,11 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) in the SELECT clause of Q. - Search for a column named col_ref_i [in table T_j] in the GROUP BY clause of Q. - - If found different columns with the same name in GROUP BY and SELECT - - issue a warning and return the GROUP BY column, - - otherwise + - If found different columns with the same name in GROUP BY and SELECT: + - if the condition that uses this column name is pushed down into + the HAVING clause return the SELECT column + - else issue a warning and return the GROUP BY column. + - Otherwise - if the MODE_ONLY_FULL_GROUP_BY mode is enabled return error - else return the found SELECT column. @@ -5556,7 +5572,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) /* Check if the fields found in SELECT and GROUP BY are the same field. */ if (group_by_ref && (select_ref != not_found_item) && - !((*group_by_ref)->eq(*select_ref, 0))) + !((*group_by_ref)->eq(*select_ref, 0)) && + (!select->having_fix_field_for_pushed_cond)) { ambiguous_fields= TRUE; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, diff --git a/sql/item.h b/sql/item.h index f6f4684f643..29e5b6455cc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1320,7 +1320,13 @@ public: Similar to val_str() */ virtual String *val_str_ascii(String *str); - + + /* + Returns the result of val_str_ascii(), translating NULLs back + to empty strings (if MODE_EMPTY_STRING_IS_NULL is set). + */ + String *val_str_ascii_revert_empty_string_is_null(THD *thd, String *str); + /* Returns the val_str() value converted to the given character set. */ @@ -4993,7 +4999,7 @@ public: also to make printing of items inherited from Item_sum uniform. */ virtual const char *func_name() const= 0; - virtual void fix_length_and_dec()= 0; + virtual bool fix_length_and_dec()= 0; bool const_item() const { return const_item_cache; } table_map used_tables() const { return used_tables_cache; } Item* build_clone(THD *thd); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4fa3cdce618..afe05445f38 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -426,7 +426,7 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) } -void Item_bool_rowready_func2::fix_length_and_dec() +bool Item_bool_rowready_func2::fix_length_and_dec() { max_length= 1; // Function returns 0 or 1 @@ -435,8 +435,8 @@ void Item_bool_rowready_func2::fix_length_and_dec() we have to check for out of memory conditions here */ if (!args[0] || !args[1]) - return; - setup_args_and_comparator(current_thd, &cmp); + return FALSE; + return setup_args_and_comparator(current_thd, &cmp); } @@ -1084,12 +1084,13 @@ int Arg_comparator::compare_e_str_json() } -void Item_func_truth::fix_length_and_dec() +bool Item_func_truth::fix_length_and_dec() { maybe_null= 0; null_value= 0; decimals= 0; max_length= 1; + return FALSE; } @@ -1708,10 +1709,11 @@ longlong Item_func_eq::val_int() /** Same as Item_func_eq, but NULL = NULL. */ -void Item_func_equal::fix_length_and_dec() +bool Item_func_equal::fix_length_and_dec() { - Item_bool_rowready_func2::fix_length_and_dec(); + bool rc= Item_bool_rowready_func2::fix_length_and_dec(); maybe_null=null_value=0; + return rc; } longlong Item_func_equal::val_int() @@ -1808,7 +1810,7 @@ bool Item_func_interval::fix_fields(THD *thd, Item **ref) } -void Item_func_interval::fix_length_and_dec() +bool Item_func_interval::fix_length_and_dec() { uint rows= row->cols(); @@ -1826,10 +1828,13 @@ void Item_func_interval::fix_length_and_dec() not_null_consts&= el->const_item() && !el->is_null(); } - if (not_null_consts && - (intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) * - (rows - 1)))) + if (not_null_consts) { + intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) * + (rows - 1)); + if (!intervals) + return TRUE; + if (use_decimal_comparison) { for (uint i= 1; i < rows; i++) @@ -1870,6 +1875,7 @@ void Item_func_interval::fix_length_and_dec() join_with_sum_func(row); with_param= with_param || row->with_param; with_field= with_field || row->with_field; + return FALSE; } @@ -2030,7 +2036,7 @@ void Item_func_between::fix_after_pullout(st_select_lex *new_parent, eval_not_null_tables(NULL); } -void Item_func_between::fix_length_and_dec() +bool Item_func_between::fix_length_and_dec() { max_length= 1; @@ -2039,15 +2045,16 @@ void Item_func_between::fix_length_and_dec() we have to check for out of memory conditions here */ if (!args[0] || !args[1] || !args[2]) - return; + return TRUE; if (m_comparator.aggregate_for_comparison(Item_func_between::func_name(), args, 3, true)) { DBUG_ASSERT(current_thd->is_error()); - return; + return TRUE; } - m_comparator.type_handler()->Item_func_between_fix_length_and_dec(this); + return m_comparator.type_handler()-> + Item_func_between_fix_length_and_dec(this); } @@ -2070,7 +2077,7 @@ bool Item_func_between::fix_length_and_dec_numeric(THD *thd) } } } - return false; + return FALSE; } @@ -2438,7 +2445,7 @@ void Item_func_nullif::update_used_tables() -void +bool Item_func_nullif::fix_length_and_dec() { /* @@ -2588,6 +2595,8 @@ Item_func_nullif::fix_length_and_dec() m_cache= args[0]->cmp_type() == STRING_RESULT ? new (thd->mem_root) Item_cache_str_for_nullif(thd, args[0]) : args[0]->get_cache(thd); + if (!m_cache) + return TRUE; m_cache->setup(thd, args[0]); m_cache->store(args[0]); m_cache->set_used_tables(args[0]->used_tables()); @@ -2601,7 +2610,8 @@ Item_func_nullif::fix_length_and_dec() fix_char_length(args[2]->max_char_length()); maybe_null=1; m_arg0= args[0]; - setup_args_and_comparator(thd, &cmp); + if (setup_args_and_comparator(thd, &cmp)) + return TRUE; /* A special code for EXECUTE..PREPARE. @@ -2641,6 +2651,7 @@ Item_func_nullif::fix_length_and_dec() */ if (args[0] == m_arg0) m_arg0= NULL; + return FALSE; } @@ -3036,26 +3047,26 @@ bool Item_func_case_simple::prepare_predicant_and_values(THD *thd, } -void Item_func_case_searched::fix_length_and_dec() +bool Item_func_case_searched::fix_length_and_dec() { THD *thd= current_thd; - aggregate_then_and_else_arguments(thd, when_count()); + return aggregate_then_and_else_arguments(thd, when_count()); } -void Item_func_case_simple::fix_length_and_dec() +bool Item_func_case_simple::fix_length_and_dec() { THD *thd= current_thd; - if (!aggregate_then_and_else_arguments(thd, when_count() + 1)) - aggregate_switch_and_when_arguments(thd, false); + return (aggregate_then_and_else_arguments(thd, when_count() + 1) || + aggregate_switch_and_when_arguments(thd, false)); } -void Item_func_decode_oracle::fix_length_and_dec() +bool Item_func_decode_oracle::fix_length_and_dec() { THD *thd= current_thd; - if (!aggregate_then_and_else_arguments(thd, when_count() + 1)) - aggregate_switch_and_when_arguments(thd, true); + return (aggregate_then_and_else_arguments(thd, when_count() + 1) || + aggregate_switch_and_when_arguments(thd, true)); } @@ -4138,7 +4149,7 @@ bool Item_func_in::prepare_predicant_and_values(THD *thd, uint *found_types) } -void Item_func_in::fix_length_and_dec() +bool Item_func_in::fix_length_and_dec() { THD *thd= current_thd; uint found_types; @@ -4148,18 +4159,20 @@ void Item_func_in::fix_length_and_dec() if (prepare_predicant_and_values(thd, &found_types)) { DBUG_ASSERT(thd->is_error()); // Must set error - return; + return TRUE; } if (arg_types_compatible) // Bisection condition #1 { - m_comparator.type_handler()-> - Item_func_in_fix_comparator_compatible_types(thd, this); + if (m_comparator.type_handler()-> + Item_func_in_fix_comparator_compatible_types(thd, this)) + return TRUE; } else { DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT); - fix_for_scalar_comparison_using_cmp_items(thd, found_types); + if ( fix_for_scalar_comparison_using_cmp_items(thd, found_types)) + return TRUE; } DBUG_EXECUTE_IF("Item_func_in", @@ -4167,6 +4180,7 @@ void Item_func_in::fix_length_and_dec() ER_UNKNOWN_ERROR, "DBUG: types_compatible=%s bisect=%s", arg_types_compatible ? "yes" : "no", array != NULL ? "yes" : "no");); + return FALSE; } @@ -4643,7 +4657,8 @@ Item_cond::fix_fields(THD *thd, Item **ref) with_window_func|= item->with_window_func; maybe_null|= item->maybe_null; } - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; fixed= 1; return FALSE; } @@ -5678,16 +5693,16 @@ bool Item_func_regex::fix_fields(THD *thd, Item **ref) return Item_bool_func::fix_fields(thd, ref); } -void +bool Item_func_regex::fix_length_and_dec() { - Item_bool_func::fix_length_and_dec(); - - if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) - return; + if (Item_bool_func::fix_length_and_dec() || + agg_arg_charsets_for_comparison(cmp_collation, args, 2)) + return TRUE; re.init(cmp_collation.collation, 0); re.fix_owner(this, args[0], args[1]); + return FALSE; } @@ -5711,15 +5726,16 @@ bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref) } -void +bool Item_func_regexp_instr::fix_length_and_dec() { if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) - return; + return TRUE; re.init(cmp_collation.collation, 0); re.fix_owner(this, args[0], args[1]); max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate + return FALSE; } @@ -6639,7 +6655,8 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) } if (prev_equal_field && last_equal_field != first_equal_field) last_equal_field->next_equal_field= first_equal_field; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; fixed= 1; return FALSE; } @@ -6725,11 +6742,12 @@ longlong Item_equal::val_int() } -void Item_equal::fix_length_and_dec() +bool Item_equal::fix_length_and_dec() { Item *item= get_first(NO_PARTICULAR_TAB, NULL); const Type_handler *handler= item->type_handler(); eval_item= handler->make_cmp_item(current_thd, item->collation.collation); + return eval_item == NULL; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 08a462b0903..3b2e58dab89 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -219,7 +219,7 @@ public: const Type_handler *type_handler() const { return &type_handler_bool; } const Type_handler *fixed_type_handler() const { return &type_handler_bool; } CHARSET_INFO *compare_collation() const { return NULL; } - void fix_length_and_dec() { decimals=0; max_length=1; } + bool fix_length_and_dec() { decimals=0; max_length=1; return FALSE; } uint decimal_precision() const { return 1; } bool need_parentheses_in_default() { return true; } }; @@ -235,7 +235,7 @@ class Item_func_truth : public Item_bool_func public: virtual bool val_bool(); virtual longlong val_int(); - virtual void fix_length_and_dec(); + virtual bool fix_length_and_dec(); virtual void print(String *str, enum_query_type query_type); enum precedence precedence() const { return CMP_PRECEDENCE; } @@ -522,7 +522,7 @@ public: cond); return this; } - void fix_length_and_dec(); + bool fix_length_and_dec(); int set_cmp_func() { return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true); @@ -735,7 +735,7 @@ public: Item_func_equal(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {} longlong val_int(); - void fix_length_and_dec(); + bool fix_length_and_dec(); table_map not_null_tables() const { return 0; } enum Functype functype() const { return EQUAL_FUNC; } enum Functype rev_functype() const { return EQUAL_FUNC; } @@ -905,7 +905,7 @@ public: enum Functype functype() const { return BETWEEN; } const char *func_name() const { return "between"; } enum precedence precedence() const { return BETWEEN_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_length_and_dec_string(THD *) { return agg_arg_charsets_for_comparison(cmp_collation, args, 3); @@ -953,10 +953,12 @@ public: longlong val_int(); uint decimal_precision() const { return 1; } const char *func_name() const { return "strcmp"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) + return TRUE; fix_char_length(2); // returns "1" or "0" or "-1" + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_strcmp>(thd, this); } @@ -985,7 +987,7 @@ public: { } bool fix_fields(THD *, Item **); longlong val_int(); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "interval"; } uint decimal_precision() const { return 2; } void print(String *str, enum_query_type query_type) @@ -1011,10 +1013,12 @@ public: my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate); bool time_op(MYSQL_TIME *ltime); - void fix_length_and_dec() + bool fix_length_and_dec() { - if (!aggregate_for_result(func_name(), args, arg_count, true)) - fix_attributes(args, arg_count); + if (aggregate_for_result(func_name(), args, arg_count, true)) + return TRUE; + fix_attributes(args, arg_count); + return FALSE; } const char *func_name() const { return "coalesce"; } table_map not_null_tables() const { return 0; } @@ -1032,10 +1036,12 @@ public: class Item_func_case_abbreviation2 :public Item_func_case_expression { protected: - void fix_length_and_dec2(Item **items) + bool fix_length_and_dec2(Item **items) { - if (!aggregate_for_result(func_name(), items, 2, true)) - fix_attributes(items, 2); + if (aggregate_for_result(func_name(), items, 2, true)) + return TRUE; + fix_attributes(items, 2); + return FALSE; } void cache_type_info(const Item *source, bool maybe_null_arg) @@ -1045,7 +1051,7 @@ protected: maybe_null= maybe_null_arg; } - void fix_length_and_dec2_eliminate_null(Item **items) + bool fix_length_and_dec2_eliminate_null(Item **items) { // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr. if (items[0]->type() == NULL_ITEM) @@ -1061,8 +1067,10 @@ protected: } else { - fix_length_and_dec2(items); + if (fix_length_and_dec2(items)) + return TRUE; } + return FALSE; } public: @@ -1084,10 +1092,12 @@ public: my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate); bool time_op(MYSQL_TIME *ltime); - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_case_abbreviation2::fix_length_and_dec2(args); + if (Item_func_case_abbreviation2::fix_length_and_dec2(args)) + return TRUE; maybe_null= args[1]->maybe_null; + return FALSE; } const char *func_name() const { return "ifnull"; } @@ -1153,9 +1163,9 @@ public: Item_func_case_abbreviation2_switch(thd, a, b, c) {} bool fix_fields(THD *, Item **); - void fix_length_and_dec() + bool fix_length_and_dec() { - fix_length_and_dec2_eliminate_null(args + 1); + return fix_length_and_dec2_eliminate_null(args + 1); } const char *func_name() const { return "if"; } bool eval_not_null_tables(void *opt_arg); @@ -1177,9 +1187,9 @@ public: Item_func_case_abbreviation2_switch(thd, a, b, c) {} const char *func_name() const { return "nvl2"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - fix_length_and_dec2_eliminate_null(args + 1); + return fix_length_and_dec2_eliminate_null(args + 1); } Item *get_copy(THD *thd) { return get_item_copy<Item_func_nvl2>(thd, this); } @@ -1239,7 +1249,7 @@ public: longlong int_op(); String *str_op(String *str); my_decimal *decimal_op(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool walk(Item_processor processor, bool walk_subquery, void *arg); const char *func_name() const { return "nullif"; } void print(String *str, enum_query_type query_type); @@ -2151,7 +2161,7 @@ public: reorder_args(0); } void print(String *str, enum_query_type query_type); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) { // None of the arguments are in a comparison context @@ -2203,7 +2213,7 @@ public: DBUG_VOID_RETURN; } void print(String *str, enum_query_type query_type); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond); Item *find_item(); Item *build_clone(THD *thd) @@ -2228,7 +2238,7 @@ public: { } const char *func_name() const { return "decode_oracle"; } void print(String *str, enum_query_type query_type); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *find_item(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_decode_oracle>(thd, this); } @@ -2316,7 +2326,7 @@ public: { } longlong val_int(); bool fix_fields(THD *, Item **); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool compatible_types_scalar_bisection_possible() { DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT); @@ -2482,7 +2492,11 @@ public: } CHARSET_INFO *compare_collation() const { return args[0]->collation.collation; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; } + bool fix_length_and_dec() + { + decimals=0; max_length=1; maybe_null=0; + return FALSE; + } bool count_sargable_conds(void *arg); }; @@ -2706,10 +2720,10 @@ public: const char *func_name() const { return "like"; } enum precedence precedence() const { return CMP_PRECEDENCE; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 1; - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } void cleanup(); @@ -2830,7 +2844,7 @@ public: } longlong val_int(); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp"; } enum precedence precedence() const { return CMP_PRECEDENCE; } Item *get_copy(THD *thd) @@ -2880,7 +2894,7 @@ public: } longlong val_int(); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp_instr"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_regexp_instr>(thd, this); } @@ -3115,7 +3129,7 @@ public: longlong val_int(); const char *func_name() const { return "multiple equal"; } void sort(Item_field_cmpfunc compare, void *arg); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); void cleanup() { diff --git a/sql/item_func.cc b/sql/item_func.cc index ca616566f51..d904af7c56b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -377,8 +377,7 @@ Item_func::fix_fields(THD *thd, Item **ref) } if (check_arguments()) return true; - fix_length_and_dec(); - if (unlikely(thd->is_error())) // An error inside fix_length_and_dec occurred + if (fix_length_and_dec()) return TRUE; fixed= 1; return FALSE; @@ -762,10 +761,12 @@ String *Item_int_func::val_str(String *str) } -void Item_func_connection_id::fix_length_and_dec() +bool Item_func_connection_id::fix_length_and_dec() { - Item_long_func::fix_length_and_dec(); + if (Item_long_func::fix_length_and_dec()) + return TRUE; max_length= 10; + return FALSE; } @@ -792,19 +793,19 @@ bool Item_num_op::fix_type_handler(const Type_aggregator *aggregator) } -void Item_func_plus::fix_length_and_dec(void) +bool Item_func_plus::fix_length_and_dec(void) { DBUG_ENTER("Item_func_plus::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_plus; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_for_result;); DBUG_ASSERT(aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_plus::type_handler()->Item_func_plus_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_plus::type_handler()->Item_func_plus_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1319,19 +1320,19 @@ void Item_func_minus::fix_unsigned_flag() } -void Item_func_minus::fix_length_and_dec() +bool Item_func_minus::fix_length_and_dec() { DBUG_ENTER("Item_func_minus::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_minus; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;); DBUG_ASSERT(!aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_minus::type_handler()->Item_func_minus_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_minus::type_handler()->Item_func_minus_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1551,19 +1552,19 @@ void Item_func_mul::result_precision() } -void Item_func_mul::fix_length_and_dec(void) +bool Item_func_mul::fix_length_and_dec(void) { DBUG_ENTER("Item_func_mul::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_mul; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_for_result;); DBUG_ASSERT(aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_mul::type_handler()->Item_func_mul_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_mul::type_handler()->Item_func_mul_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1658,7 +1659,7 @@ void Item_func_div::fix_length_and_dec_int(void) } -void Item_func_div::fix_length_and_dec(void) +bool Item_func_div::fix_length_and_dec() { DBUG_ENTER("Item_func_div::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); @@ -1668,12 +1669,12 @@ void Item_func_div::fix_length_and_dec(void) const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_div; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;); DBUG_ASSERT(!aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_div::type_handler()->Item_func_div_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_div::type_handler()->Item_func_div_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1749,7 +1750,7 @@ longlong Item_func_int_div::val_int() } -void Item_func_int_div::fix_length_and_dec() +bool Item_func_int_div::fix_length_and_dec() { Item_result argtype= args[0]->result_type(); /* use precision ony for the data type it is applicable for and valid */ @@ -1760,6 +1761,7 @@ void Item_func_int_div::fix_length_and_dec() MY_INT64_NUM_DECIMAL_DIGITS : char_length); maybe_null=1; unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; + return false; } @@ -1843,7 +1845,7 @@ void Item_func_mod::result_precision() } -void Item_func_mod::fix_length_and_dec() +bool Item_func_mod::fix_length_and_dec() { DBUG_ENTER("Item_func_mod::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); @@ -1851,12 +1853,12 @@ void Item_func_mod::fix_length_and_dec() const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_mod; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;); DBUG_ASSERT(!aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_mod::type_handler()->Item_func_mod_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_mod::type_handler()->Item_func_mod_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1954,13 +1956,15 @@ void Item_func_neg::fix_length_and_dec_decimal() } -void Item_func_neg::fix_length_and_dec() +bool Item_func_neg::fix_length_and_dec() { DBUG_ENTER("Item_func_neg::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); - args[0]->cast_to_int_type_handler()->Item_func_neg_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_func_neg_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1999,7 +2003,6 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value) return 0; } - void Item_func_abs::fix_length_and_dec_int() { max_length= args[0]->max_length; @@ -2026,13 +2029,15 @@ void Item_func_abs::fix_length_and_dec_decimal() } -void Item_func_abs::fix_length_and_dec() +bool Item_func_abs::fix_length_and_dec() { DBUG_ENTER("Item_func_abs::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); - args[0]->cast_to_int_type_handler()->Item_func_abs_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_func_abs_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2298,14 +2303,15 @@ void Item_func_int_val::fix_length_and_dec_double() } -void Item_func_int_val::fix_length_and_dec() +bool Item_func_int_val::fix_length_and_dec() { DBUG_ENTER("Item_func_int_val::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); - args[0]->cast_to_int_type_handler()-> - Item_func_int_val_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_func_int_val_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2485,7 +2491,6 @@ void Item_func_round::fix_arg_int() } else fix_length_and_dec_double(args[0]->decimals); - } @@ -3042,14 +3047,15 @@ longlong Item_func_field::val_int() } -void Item_func_field::fix_length_and_dec() +bool Item_func_field::fix_length_and_dec() { maybe_null=0; max_length=3; cmp_type= args[0]->result_type(); for (uint i=1; i < arg_count ; i++) cmp_type= item_cmp_type(cmp_type, args[i]->result_type()); if (cmp_type == STRING_RESULT) - agg_arg_charsets_for_comparison(cmp_collation, args, arg_count); + return agg_arg_charsets_for_comparison(cmp_collation, args, arg_count); + return FALSE; } @@ -3096,7 +3102,7 @@ longlong Item_func_ord::val_int() /* Returns number of found type >= 1 or 0 if not found */ /* This optimizes searching in enums to bit testing! */ -void Item_func_find_in_set::fix_length_and_dec() +bool Item_func_find_in_set::fix_length_and_dec() { decimals=0; max_length=3; // 1-999 @@ -3118,7 +3124,7 @@ void Item_func_find_in_set::fix_length_and_dec() } } } - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } static const char separator=','; @@ -3321,7 +3327,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, DBUG_RETURN(TRUE); } } - func->fix_length_and_dec(); + if (func->fix_length_and_dec()) + DBUG_RETURN(TRUE); initid.max_length=func->max_length; initid.maybe_null=func->maybe_null; initid.const_item=func->const_item_cache; @@ -3661,13 +3668,13 @@ String *Item_func_udf_decimal::val_str(String *str) /* Default max_length is max argument length */ -void Item_func_udf_str::fix_length_and_dec() +bool Item_func_udf_str::fix_length_and_dec() { DBUG_ENTER("Item_func_udf_str::fix_length_and_dec"); max_length=0; for (uint i = 0; i < arg_count; i++) set_if_bigger(max_length,args[i]->max_length); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } String *Item_func_udf_str::val_str(String *str) @@ -4575,7 +4582,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) } -void +bool Item_func_set_user_var::fix_length_and_dec() { maybe_null=args[0]->maybe_null; @@ -4589,6 +4596,7 @@ Item_func_set_user_var::fix_length_and_dec() args[0]->collation.collation); } unsigned_flag= args[0]->unsigned_flag; + return FALSE; } @@ -5428,7 +5436,7 @@ err: return 1; } -void Item_func_get_user_var::fix_length_and_dec() +bool Item_func_get_user_var::fix_length_and_dec() { THD *thd=current_thd; int error; @@ -5477,6 +5485,7 @@ void Item_func_get_user_var::fix_length_and_dec() set_handler(&type_handler_long_blob); max_length= MAX_BLOB_WIDTH; } + return false; } @@ -5628,7 +5637,7 @@ void Item_func_get_system_var::update_null_value() } -void Item_func_get_system_var::fix_length_and_dec() +bool Item_func_get_system_var::fix_length_and_dec() { char *cptr; maybe_null= TRUE; @@ -5640,7 +5649,7 @@ void Item_func_get_system_var::fix_length_and_dec() { my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name.str, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); - return; + return TRUE; } /* As there was no local variable, return the global value */ var_type= OPT_GLOBAL; @@ -5704,6 +5713,7 @@ void Item_func_get_system_var::fix_length_and_dec() my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); break; } + return FALSE; } @@ -6363,7 +6373,7 @@ bool Item_func_sp::is_expensive() @note called from Item::fix_fields. */ -void Item_func_sp::fix_length_and_dec() +bool Item_func_sp::fix_length_and_dec() { DBUG_ENTER("Item_func_sp::fix_length_and_dec"); @@ -6373,7 +6383,7 @@ void Item_func_sp::fix_length_and_dec() collation.derivation= DERIVATION_COERCIBLE; maybe_null= 1; - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -6688,11 +6698,12 @@ bool Item_func_last_value::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) } -void Item_func_last_value::fix_length_and_dec() +bool Item_func_last_value::fix_length_and_dec() { last_value= args[arg_count -1]; Type_std_attributes::set(last_value); maybe_null= last_value->maybe_null; + return FALSE; } diff --git a/sql/item_func.h b/sql/item_func.h index 3b6cb4ceeac..083b49bdda5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -398,8 +398,12 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date_from_real(ltime, fuzzydate); } const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() - { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } + bool fix_length_and_dec() + { + decimals= NOT_FIXED_DEC; + max_length= float_length(decimals); + return FALSE; + } }; @@ -785,7 +789,7 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date_from_int(ltime, fuzzydate); } const Type_handler *type_handler() const= 0; - void fix_length_and_dec() {} + bool fix_length_and_dec() { return FALSE; } }; @@ -799,7 +803,7 @@ public: Item_long_func(THD *thd, List<Item> &list): Item_int_func(thd, list) { } Item_long_func(THD *thd, Item_long_func *item) :Item_int_func(thd, item) {} const Type_handler *type_handler() const { return &type_handler_long; } - void fix_length_and_dec() { max_length= 11; } + bool fix_length_and_dec() { max_length= 11; return FALSE; } }; @@ -861,7 +865,7 @@ class Item_func_connection_id :public Item_long_func public: Item_func_connection_id(THD *thd): Item_long_func(thd) { unsigned_flag=1; } const char *func_name() const { return "connection_id"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } bool check_vcol_func_processor(void *arg) @@ -918,9 +922,9 @@ public: set_if_bigger(char_length, 1U + (unsigned_flag ? 0 : 1)); fix_char_length(char_length); } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_func_signed_fix_length_and_dec(this); + return args[0]->type_handler()->Item_func_signed_fix_length_and_dec(this); } virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } @@ -950,9 +954,9 @@ public: null_value= args[0]->null_value; return value; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this); + return args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this); } uint decimal_precision() const { return max_length; } virtual void print(String *str, enum_query_type query_type); @@ -981,9 +985,10 @@ public: { return get_date_from_decimal(ltime, fuzzydate); } const Type_handler *type_handler() const { return &type_handler_newdecimal; } void fix_length_and_dec_generic() {} - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_decimal_typecast_fix_length_and_dec(this); + return + args[0]->type_handler()->Item_decimal_typecast_fix_length_and_dec(this); } const char *func_name() const { return "decimal_typecast"; } virtual void print(String *str, enum_query_type query_type); @@ -1004,9 +1009,10 @@ public: } double val_real(); void fix_length_and_dec_generic() { maybe_null= 1; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_double_typecast_fix_length_and_dec(this); + return + args[0]->type_handler()->Item_double_typecast_fix_length_and_dec(this); } const char *func_name() const { return "double_typecast"; } virtual void print(String *str, enum_query_type query_type); @@ -1033,7 +1039,7 @@ public: Item_func_additive_op(thd, a, b) {} const char *func_name() const { return "+"; } enum precedence precedence() const { return ADD_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); @@ -1051,7 +1057,7 @@ public: longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_unsigned_flag(); void fix_length_and_dec_double() { @@ -1084,7 +1090,7 @@ public: double real_op(); my_decimal *decimal_op(my_decimal *); void result_precision(); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} Item *get_copy(THD *thd) @@ -1102,7 +1108,7 @@ public: my_decimal *decimal_op(my_decimal *); const char *func_name() const { return "/"; } enum precedence precedence() const { return MUL_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_length_and_dec_double(); void fix_length_and_dec_int(); void result_precision(); @@ -1121,7 +1127,7 @@ public: enum precedence precedence() const { return MUL_PRECEDENCE; } const Type_handler *type_handler() const { return type_handler_long_or_longlong(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type) { print_op(str, query_type); @@ -1145,7 +1151,7 @@ public: const char *func_name() const { return "MOD"; } enum precedence precedence() const { return MUL_PRECEDENCE; } void result_precision(); - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_length_and_dec_double() { Item_num_op::fix_length_and_dec_double(); @@ -1188,7 +1194,7 @@ public: void fix_length_and_dec_int(); void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); uint decimal_precision() const { return args[0]->decimal_precision(); } bool need_parentheses_in_default() { return true; } Item *get_copy(THD *thd) @@ -1207,7 +1213,7 @@ public: void fix_length_and_dec_int(); void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_abs>(thd, this); } }; @@ -1221,10 +1227,11 @@ class Item_dec_func :public Item_real_func public: Item_dec_func(THD *thd, Item *a): Item_real_func(thd, a) {} Item_dec_func(THD *thd, Item *a, Item *b): Item_real_func(thd, a, b) {} - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); maybe_null=1; + return FALSE; } }; @@ -1384,7 +1391,7 @@ public: Item_func_int_val(THD *thd, Item *a): Item_func_num1(thd, a) {} void fix_length_and_dec_double(); void fix_length_and_dec_int_or_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -1430,9 +1437,9 @@ public: void fix_arg_decimal(); void fix_arg_int(); void fix_arg_double(); - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_func_round_fix_length_and_dec(this); + return args[0]->type_handler()->Item_func_round_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_func_round>(thd, this); } @@ -1474,7 +1481,7 @@ public: Item_func_sign(THD *thd, Item *a): Item_long_func(thd, a) {} const char *func_name() const { return "sign"; } uint decimal_precision() const { return 1; } - void fix_length_and_dec() { fix_char_length(2); } + bool fix_length_and_dec() { fix_char_length(2); return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_sign>(thd, this); } @@ -1493,8 +1500,12 @@ public: Item_real_func(thd, a), name(name_arg), mul(mul_arg), add(add_arg) {} double val_real(); const char *func_name() const { return name; } - void fix_length_and_dec() - { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } + bool fix_length_and_dec() + { + decimals= NOT_FIXED_DEC; + max_length= float_length(decimals); + return FALSE; + } Item *get_copy(THD *thd) { return get_item_copy<Item_func_units>(thd, this); } }; @@ -1578,11 +1589,12 @@ public: Item_func::aggregate_attributes_real(items, nitems); max_length= float_length(decimals); } - void fix_length_and_dec() + bool fix_length_and_dec() { if (aggregate_for_min_max(func_name(), args, arg_count)) - return; + return true; fix_attributes(args, arg_count); + return false; } }; @@ -1627,11 +1639,12 @@ public: const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } const Type_handler *type_handler() const { return args[0]->type_handler(); } - void fix_length_and_dec() + bool fix_length_and_dec() { collation= args[0]->collation; max_length= args[0]->max_length; decimals=args[0]->decimals; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_rollup_const>(thd, this); } @@ -1644,7 +1657,7 @@ class Item_long_func_length: public Item_long_func { return args[0]->check_type_can_return_str(func_name()); } public: Item_long_func_length(THD *thd, Item *a): Item_long_func(thd, a) {} - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } }; @@ -1664,9 +1677,10 @@ class Item_func_bit_length :public Item_longlong_func String value; public: Item_func_bit_length(THD *thd, Item *a): Item_longlong_func(thd, a) {} - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 11; // 0x100000000*8 = 34,359,738,368 + return FALSE; } longlong val_int(); const char *func_name() const { return "bit_length"; } @@ -1693,7 +1707,7 @@ public: Item_func_coercibility(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "coercibility"; } - void fix_length_and_dec() { max_length=10; maybe_null= 0; } + bool fix_length_and_dec() { max_length=10; maybe_null= 0; return FALSE; } bool eval_not_null_tables(void *) { not_null_tables_cache= 0; @@ -1729,10 +1743,10 @@ public: :Item_long_func(thd, a, b, c) {} const char *func_name() const { return "locate"; } longlong val_int(); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MY_INT32_NUM_DECIMAL_DIGITS; - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1749,7 +1763,7 @@ public: Item_func_field(THD *thd, List<Item> &list): Item_long_func(thd, list) {} longlong val_int(); const char *func_name() const { return "field"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_field>(thd, this); } }; @@ -1764,7 +1778,7 @@ public: Item_func_ascii(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "ascii"; } - void fix_length_and_dec() { max_length=3; } + bool fix_length_and_dec() { max_length=3; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_ascii>(thd, this); } }; @@ -1776,7 +1790,7 @@ class Item_func_ord :public Item_long_func String value; public: Item_func_ord(THD *thd, Item *a): Item_long_func(thd, a) {} - void fix_length_and_dec() { fix_char_length(7); } + bool fix_length_and_dec() { fix_char_length(7); return FALSE; } longlong val_int(); const char *func_name() const { return "ord"; } Item *get_copy(THD *thd) @@ -1796,7 +1810,7 @@ public: Item_long_func(thd, a, b), enum_value(0) {} longlong val_int(); const char *func_name() const { return "find_in_set"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_find_in_set>(thd, this); } }; @@ -1810,7 +1824,7 @@ class Item_func_bit: public Item_longlong_func public: Item_func_bit(THD *thd, Item *a, Item *b): Item_longlong_func(thd, a, b) {} Item_func_bit(THD *thd, Item *a): Item_longlong_func(thd, a) {} - void fix_length_and_dec() { unsigned_flag= 1; } + bool fix_length_and_dec() { unsigned_flag= 1; return FALSE; } virtual inline void print(String *str, enum_query_type query_type) { @@ -1849,7 +1863,7 @@ public: Item_func_bit_count(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "bit_count"; } - void fix_length_and_dec() { max_length=2; } + bool fix_length_and_dec() { max_length=2; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_bit_count>(thd, this); } }; @@ -1902,11 +1916,12 @@ public: Item_func_last_insert_id(THD *thd, Item *a): Item_longlong_func(thd, a) {} longlong val_int(); const char *func_name() const { return "last_insert_id"; } - void fix_length_and_dec() + bool fix_length_and_dec() { unsigned_flag= true; if (arg_count) max_length= args[0]->max_length; + return FALSE; } bool fix_fields(THD *thd, Item **ref); bool check_vcol_func_processor(void *arg) @@ -1931,7 +1946,7 @@ public: {} longlong val_int(); const char *func_name() const { return "benchmark"; } - void fix_length_and_dec() { max_length=1; maybe_null=0; } + bool fix_length_and_dec() { max_length=1; maybe_null=0; return FALSE; } virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(void *arg) { @@ -1951,7 +1966,7 @@ class Item_func_sleep :public Item_long_func { return args[0]->check_type_can_return_real(func_name()); } public: Item_func_sleep(THD *thd, Item *a): Item_long_func(thd, a) {} - void fix_length_and_dec() { fix_char_length(1); } + bool fix_length_and_dec() { fix_char_length(1); return FALSE; } bool const_item() const { return 0; } const char *func_name() const { return "sleep"; } table_map used_tables() const @@ -2095,7 +2110,7 @@ class Item_func_udf_float :public Item_udf_func double val_real(); String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_float>(thd, this); } }; @@ -2113,7 +2128,7 @@ public: double val_real() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_longlong; } - void fix_length_and_dec() { decimals= 0; max_length= 21; } + bool fix_length_and_dec() { decimals= 0; max_length= 21; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_int>(thd, this); } }; @@ -2131,7 +2146,7 @@ public: my_decimal *val_decimal(my_decimal *); String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_newdecimal; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_decimal>(thd, this); } }; @@ -2170,7 +2185,7 @@ public: return dec_buf; } const Type_handler *type_handler() const { return string_type_handler(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_str>(thd, this); } }; @@ -2223,7 +2238,7 @@ public: { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - void fix_length_and_dec() { maybe_null=1; max_length=0; } + bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; } }; #endif /* HAVE_DLOPEN */ @@ -2243,7 +2258,7 @@ class Item_func_get_lock :public Item_long_func Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "get_lock"; } - void fix_length_and_dec() { max_length=1; maybe_null=1;} + bool fix_length_and_dec() { max_length=1; maybe_null=1; return FALSE; } table_map used_tables() const { return used_tables_cache | RAND_TABLE_BIT; @@ -2267,7 +2282,7 @@ public: Item_func_release_lock(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "release_lock"; } - void fix_length_and_dec() { max_length= 1; maybe_null= 1;} + bool fix_length_and_dec() { max_length= 1; maybe_null= 1; return FALSE; } table_map used_tables() const { return used_tables_cache | RAND_TABLE_BIT; @@ -2304,7 +2319,7 @@ public: Item_longlong_func(thd, a, b, c, d) {} longlong val_int(); const char *func_name() const { return "master_pos_wait"; } - void fix_length_and_dec() { max_length=21; maybe_null=1;} + bool fix_length_and_dec() { max_length=21; maybe_null=1; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2329,7 +2344,7 @@ public: :Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "master_gtid_wait"; } - void fix_length_and_dec() { max_length=2; } + bool fix_length_and_dec() { max_length=2; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2426,7 +2441,7 @@ public: void save_item_result(Item *item); bool update(); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); enum precedence precedence() const { return ASSIGN_PRECEDENCE; } void print_as_stmt(String *str, enum_query_type query_type); @@ -2461,7 +2476,7 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal*); String *val_str(String* str); - void fix_length_and_dec(); + bool fix_length_and_dec(); virtual void print(String *str, enum_query_type query_type); /* We must always return variables as strings to guard against selects of type @@ -2584,7 +2599,7 @@ public: size_t name_len_arg); enum Functype functype() const { return GSYSVAR_FUNC; } void update_null_value(); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); bool const_item() const { return true; } table_map used_tables() const { return 0; } @@ -2728,7 +2743,11 @@ public: Item_func_is_free_lock(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "is_free_lock"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} + bool fix_length_and_dec() + { + decimals=0; max_length=1; maybe_null=1; + return FALSE; + } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2746,7 +2765,11 @@ public: Item_func_is_used_lock(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "is_used_lock"; } - void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} + bool fix_length_and_dec() + { + decimals=0; max_length=10; maybe_null=1; + return FALSE; + } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2795,7 +2818,7 @@ public: Item_func_row_count(THD *thd): Item_longlong_func(thd) {} longlong val_int(); const char *func_name() const { return "row_count"; } - void fix_length_and_dec() { decimals= 0; maybe_null=0; } + bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2915,7 +2938,7 @@ public: virtual enum Functype functype() const { return FUNC_SP; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(void); + bool fix_length_and_dec(void); bool is_expensive(); inline Field *get_sp_result_field() @@ -2955,7 +2978,7 @@ public: Item_func_found_rows(THD *thd): Item_longlong_func(thd) {} longlong val_int(); const char *func_name() const { return "found_rows"; } - void fix_length_and_dec() { decimals= 0; maybe_null=0; } + bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2998,10 +3021,11 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null= null_value= false; max_length= 11; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sqlcode>(thd, this); } @@ -3017,8 +3041,8 @@ public: const char *func_name() const { return "uuid_short"; } longlong val_int(); bool const_item() const { return false; } - void fix_length_and_dec() - { max_length= 21; unsigned_flag=1; } + bool fix_length_and_dec() + { max_length= 21; unsigned_flag=1; return FALSE; } table_map used_tables() const { return RAND_TABLE_BIT; } bool check_vcol_func_processor(void *arg) { @@ -3040,7 +3064,7 @@ public: String *val_str(String *); my_decimal *val_decimal(my_decimal *); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "last_value"; } const Type_handler *type_handler() const { return last_value->type_handler(); } bool eval_not_null_tables(void *) @@ -3072,11 +3096,12 @@ public: Item_longlong_func(thd), table_list(table_list_arg) {} longlong val_int(); const char *func_name() const { return "nextval"; } - void fix_length_and_dec() + bool fix_length_and_dec() { unsigned_flag= 0; max_length= MAX_BIGINT_WIDTH; maybe_null= 1; /* In case of errors */ + return FALSE; } /* update_table() function must be called during the value function diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index aee44a7a01f..4c2a2fa8b11 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -40,12 +40,13 @@ #include "opt_range.h" -void Item_geometry_func::fix_length_and_dec() +bool Item_geometry_func::fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; max_length= (uint32) UINT_MAX32; maybe_null= 1; + return FALSE; } @@ -214,11 +215,12 @@ String *Item_func_as_wkt::val_str_ascii(String *str) } -void Item_func_as_wkt::fix_length_and_dec() +bool Item_func_as_wkt::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length= (uint32) UINT_MAX32; maybe_null= 1; + return FALSE; } @@ -240,11 +242,12 @@ String *Item_func_as_wkb::val_str(String *str) } -void Item_func_as_geojson::fix_length_and_dec() +bool Item_func_as_geojson::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length=MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index ede118cc4f3..e6c198fb8b2 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -38,7 +38,7 @@ public: Item_geometry_func(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {} Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); const Type_handler *type_handler() const { return &type_handler_geometry; } }; @@ -253,7 +253,7 @@ public: :Item_str_ascii_func_args_geometry(thd, a) {} const char *func_name() const { return "st_astext"; } String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_as_wkt>(thd, this); } }; @@ -266,12 +266,13 @@ public: const char *func_name() const { return "st_aswkb"; } String *val_str(String *); const Type_handler *type_handler() const { return &type_handler_long_blob; } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; max_length= (uint32) UINT_MAX32; maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_as_wkb>(thd, this); } @@ -294,7 +295,7 @@ public: Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits, Item *opt) :Item_str_ascii_func_args_geometry(thd, js, max_dec_digits, opt) {} const char *func_name() const { return "st_asgeojson"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str_ascii(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_as_geojson>(thd, this); } @@ -308,11 +309,12 @@ public: :Item_str_ascii_func_args_geometry(thd, a) {} String *val_str_ascii(String *); const char *func_name() const { return "st_geometrytype"; } - void fix_length_and_dec() + bool fix_length_and_dec() { // "GeometryCollection" is the longest fix_length_and_charset(20, default_charset()); maybe_null= 1; + return FALSE; }; Item *get_copy(THD *thd) { return get_item_copy<Item_func_geometry_type>(thd, this); } @@ -504,9 +506,10 @@ public: item_type=it; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_geometry_func::fix_length_and_dec(); + if (Item_geometry_func::fix_length_and_dec()) + return TRUE; for (unsigned int i= 0; i < arg_count; ++i) { if (args[i]->is_fixed() && args[i]->field_type() != MYSQL_TYPE_GEOMETRY) @@ -516,8 +519,10 @@ public: str.append('\0'); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric", str.ptr()); + return TRUE; } } + return FALSE; } const char *func_name() const { return "geometrycollection"; } @@ -727,7 +732,7 @@ public: :Item_bool_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_isempty"; } - void fix_length_and_dec() { maybe_null= 1; } + bool fix_length_and_dec() { maybe_null= 1; return FALSE; } bool need_parentheses_in_default() { return false; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_isempty>(thd, this); } @@ -744,7 +749,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_issimple"; } - void fix_length_and_dec() { decimals=0; max_length=2; } + bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; } uint decimal_precision() const { return 1; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_issimple>(thd, this); } @@ -757,7 +762,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_isclosed"; } - void fix_length_and_dec() { decimals=0; max_length=2; } + bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; } uint decimal_precision() const { return 1; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_isclosed>(thd, this); } @@ -780,7 +785,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_dimension"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_dimension>(thd, this); } }; @@ -792,10 +797,12 @@ public: Item_func_x(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_x"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_x>(thd, this); } @@ -808,10 +815,12 @@ public: Item_func_y(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_y"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_y>(thd, this); } @@ -825,7 +834,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_numgeometries"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_numgeometries>(thd, this); } }; @@ -838,7 +847,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_numinteriorrings"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_numinteriorring>(thd, this); } }; @@ -851,7 +860,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_numpoints"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_numpoints>(thd, this); } }; @@ -863,10 +872,12 @@ public: Item_func_area(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_area"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_area>(thd, this); } @@ -881,10 +892,12 @@ public: :Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_length"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_glength>(thd, this); } @@ -898,7 +911,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "srid"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_srid>(thd, this); } }; @@ -944,7 +957,7 @@ class Item_func_gis_debug: public Item_long_func public: Item_func_gis_debug(THD *thd, Item *a): Item_long_func(thd, a) { null_value= false; } - void fix_length_and_dec() { fix_char_length(10); } + bool fix_length_and_dec() { fix_char_length(10); return FALSE; } const char *func_name() const { return "st_gis_debug"; } longlong val_int(); bool check_vcol_func_processor(void *arg) diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h index d934cef43dd..024ff8ce4f0 100644 --- a/sql/item_inetfunc.h +++ b/sql/item_inetfunc.h @@ -32,12 +32,13 @@ public: Item_func_inet_aton(THD *thd, Item *a): Item_longlong_func(thd, a) {} longlong val_int(); const char *func_name() const { return "inet_aton"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet_aton>(thd, this); } @@ -55,11 +56,12 @@ public: { } String* val_str(String* str); const char *func_name() const { return "inet_ntoa"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals= 0; fix_length_and_charset(3 * 8 + 7, default_charset()); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet_ntoa>(thd, this); } @@ -124,11 +126,12 @@ public: virtual const char *func_name() const { return "inet6_aton"; } - virtual void fix_length_and_dec() + virtual bool fix_length_and_dec() { decimals= 0; fix_length_and_charset(16, &my_charset_bin); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet6_aton>(thd, this); } @@ -153,7 +156,7 @@ public: virtual const char *func_name() const { return "inet6_ntoa"; } - virtual void fix_length_and_dec() + virtual bool fix_length_and_dec() { decimals= 0; @@ -163,6 +166,7 @@ public: fix_length_and_charset(8 * 4 + 7, default_charset()); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet6_ntoa>(thd, this); } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index a45baec8e92..8d8a0d4e5db 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -388,11 +388,13 @@ longlong Item_func_json_valid::val_int() } -void Item_func_json_exists::fix_length_and_dec() +bool Item_func_json_exists::fix_length_and_dec() { - Item_bool_func::fix_length_and_dec(); + if (Item_bool_func::fix_length_and_dec()) + return TRUE; maybe_null= 1; path.set_constant_flag(args[1]->const_item()); + return FALSE; } @@ -439,12 +441,13 @@ err_return: } -void Item_func_json_value::fix_length_and_dec() +bool Item_func_json_value::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length; path.set_constant_flag(args[1]->const_item()); maybe_null= 1; + return FALSE; } @@ -510,6 +513,10 @@ err_return: bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res, int *error) { + CHARSET_INFO *json_cs; + const uchar *js; + uint js_len; + if (!json_value_scalar(je)) { /* We only look for scalar values! */ @@ -518,7 +525,22 @@ bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res, return true; } - return st_append_json(res, je->s.cs, je->value, je->value_len); + if (je->value_type == JSON_VALUE_TRUE || + je->value_type == JSON_VALUE_FALSE) + { + json_cs= &my_charset_utf8mb4_bin; + js= (const uchar *) ((je->value_type == JSON_VALUE_TRUE) ? "1" : "0"); + js_len= 1; + } + else + { + json_cs= je->s.cs; + js= je->value; + js_len= je->value_len; + } + + + return st_append_json(res, json_cs, js, js_len); } @@ -546,7 +568,7 @@ bool Item_func_json_query::check_and_get_value(json_engine_t *je, String *res, } -void Item_func_json_quote::fix_length_and_dec() +bool Item_func_json_quote::fix_length_and_dec() { collation.set(&my_charset_utf8mb4_bin); /* @@ -554,6 +576,7 @@ void Item_func_json_quote::fix_length_and_dec() of the argument turn into '\uXXXX\uXXXX', which is 12. */ max_length= args[0]->max_length * 12 + 2; + return FALSE; } @@ -581,12 +604,13 @@ String *Item_func_json_quote::val_str(String *str) } -void Item_func_json_unquote::fix_length_and_dec() +bool Item_func_json_unquote::fix_length_and_dec() { collation.set(&my_charset_utf8_general_ci, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length= args[0]->max_length; maybe_null= 1; + return FALSE; } @@ -702,13 +726,14 @@ void Item_json_str_multipath::cleanup() } -void Item_func_json_extract::fix_length_and_dec() +bool Item_func_json_extract::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length * (arg_count - 1); mark_constant_paths(paths, args+1, arg_count-1); maybe_null= 1; + return FALSE; } @@ -937,14 +962,14 @@ double Item_func_json_extract::val_real() } -void Item_func_json_contains::fix_length_and_dec() +bool Item_func_json_contains::fix_length_and_dec() { a2_constant= args[1]->const_item(); a2_parsed= FALSE; maybe_null= 1; if (arg_count > 2) path.set_constant_flag(args[2]->const_item()); - Item_bool_func::fix_length_and_dec(); + return Item_bool_func::fix_length_and_dec(); } @@ -1190,13 +1215,13 @@ bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref) } -void Item_func_json_contains_path::fix_length_and_dec() +bool Item_func_json_contains_path::fix_length_and_dec() { ooa_constant= args[1]->const_item(); ooa_parsed= FALSE; maybe_null= 1; mark_constant_paths(paths, args+2, arg_count-2); - Item_bool_func::fix_length_and_dec(); + return Item_bool_func::fix_length_and_dec(); } @@ -1455,7 +1480,7 @@ append_null: } -void Item_func_json_array::fix_length_and_dec() +bool Item_func_json_array::fix_length_and_dec() { ulonglong char_length= 2; uint n_arg; @@ -1468,17 +1493,18 @@ void Item_func_json_array::fix_length_and_dec() DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); tmp_val.set_charset(&my_charset_utf8_general_ci); max_length= 2; - return; + return FALSE; } if (agg_arg_charsets_for_string_result(collation, args, arg_count)) - return; + return TRUE; for (n_arg=0 ; n_arg < arg_count ; n_arg++) char_length+= args[n_arg]->max_char_length() + 4; fix_char_length_ulonglong(char_length); tmp_val.set_charset(collation.collation); + return FALSE; } @@ -1522,7 +1548,7 @@ err_return: } -void Item_func_json_array_append::fix_length_and_dec() +bool Item_func_json_array_append::fix_length_and_dec() { uint n_arg; ulonglong char_length; @@ -1537,6 +1563,7 @@ void Item_func_json_array_append::fix_length_and_dec() } fix_char_length_ulonglong(char_length); + return FALSE; } @@ -2124,12 +2151,13 @@ null_return: } -void Item_func_json_length::fix_length_and_dec() +bool Item_func_json_length::fix_length_and_dec() { if (arg_count > 1) path.set_constant_flag(args[1]->const_item()); maybe_null= 1; max_length= 10; + return FALSE; } @@ -2269,11 +2297,12 @@ longlong Item_func_json_depth::val_int() } -void Item_func_json_type::fix_length_and_dec() +bool Item_func_json_type::fix_length_and_dec() { collation.set(&my_charset_utf8_general_ci); max_length= 12; maybe_null= 1; + return FALSE; } @@ -2326,7 +2355,7 @@ error: } -void Item_func_json_insert::fix_length_and_dec() +bool Item_func_json_insert::fix_length_and_dec() { uint n_arg; ulonglong char_length; @@ -2342,6 +2371,7 @@ void Item_func_json_insert::fix_length_and_dec() fix_char_length_ulonglong(char_length); maybe_null= 1; + return FALSE; } @@ -2586,13 +2616,14 @@ return_null: } -void Item_func_json_remove::fix_length_and_dec() +bool Item_func_json_remove::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length; mark_constant_paths(paths, args+1, arg_count-1); maybe_null= 1; + return FALSE; } @@ -2772,13 +2803,14 @@ null_return: } -void Item_func_json_keys::fix_length_and_dec() +bool Item_func_json_keys::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length; maybe_null= 1; if (arg_count > 1) path.set_constant_flag(args[1]->const_item()); + return FALSE; } @@ -2939,7 +2971,7 @@ bool Item_func_json_search::fix_fields(THD *thd, Item **ref) static const uint SQR_MAX_BLOB_WIDTH= (uint) sqrt(MAX_BLOB_WIDTH); -void Item_func_json_search::fix_length_and_dec() +bool Item_func_json_search::fix_length_and_dec() { collation.set(args[0]->collation); @@ -2961,6 +2993,7 @@ void Item_func_json_search::fix_length_and_dec() if (arg_count > 4) mark_constant_paths(paths, args+4, arg_count-4); maybe_null= 1; + return FALSE; } @@ -3138,11 +3171,12 @@ const char *Item_func_json_format::func_name() const } -void Item_func_json_format::fix_length_and_dec() +bool Item_func_json_format::fix_length_and_dec() { decimals= 0; max_length= args[0]->max_length; maybe_null= 1; + return FALSE; } @@ -3198,34 +3232,44 @@ String *Item_func_json_format::val_json(String *str) int Arg_comparator::compare_json_str_basic(Item *j, Item *s) { - String *res1,*res2; - json_value_types type; - char *value; - int value_len, c_len; - Item_func_json_extract *e= (Item_func_json_extract *) j; - - if ((res1= e->read_json(&value1, &type, &value, &value_len))) - { - if ((res2= s->val_str(&value2))) - { - if (type == JSON_VALUE_STRING) - { - if (value1.realloc_with_extra_if_needed(value_len) || - (c_len= json_unescape(value1.charset(), (uchar *) value, - (uchar *) value+value_len, - &my_charset_utf8_general_ci, - (uchar *) value1.ptr(), - (uchar *) (value1.ptr() + value_len))) < 0) - goto error; - value1.length(c_len); - res1= &value1; - } + String *js,*str; + int c_len; + json_engine_t je; - if (set_null) - owner->null_value= 0; - return sortcmp(res1, res2, compare_collation()); - } + if ((js= j->val_str(&value1))) + { + json_scan_start(&je, js->charset(), (const uchar *) js->ptr(), + (const uchar *) js->ptr()+js->length()); + if (json_read_value(&je)) + goto error; + if (je.value_type == JSON_VALUE_STRING) + { + if (value2.realloc_with_extra_if_needed(je.value_len) || + (c_len= json_unescape(js->charset(), je.value, + je.value + je.value_len, + &my_charset_utf8_general_ci, + (uchar *) value2.ptr(), + (uchar *) (value2.ptr() + je.value_len))) < 0) + goto error; + + value2.length(c_len); + js= &value2; + str= &value1; + } + else + { + str= &value2; + } + + + if ((str= s->val_str(str))) + { + if (set_null) + owner->null_value= 0; + return sortcmp(js, str, compare_collation()); + } } + error: if (set_null) owner->null_value= 1; diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 354de69eee4..af0995b9605 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -49,10 +49,12 @@ public: Item_func_json_valid(THD *thd, Item *json) : Item_bool_func(thd, json) {} longlong val_int(); const char *func_name() const { return "json_valid"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_bool_func::fix_length_and_dec(); + if (Item_bool_func::fix_length_and_dec()) + return TRUE; maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_valid>(thd, this); } @@ -69,7 +71,7 @@ public: Item_func_json_exists(THD *thd, Item *js, Item *i_path): Item_bool_func(thd, js, i_path) {} const char *func_name() const { return "json_exists"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_exists>(thd, this); } longlong val_int(); @@ -86,7 +88,7 @@ public: Item_func_json_value(THD *thd, Item *js, Item *i_path): Item_str_func(thd, js, i_path) {} const char *func_name() const { return "json_value"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); virtual bool check_and_get_value(json_engine_t *je, String *res, int *error); Item *get_copy(THD *thd) @@ -115,7 +117,7 @@ protected: public: Item_func_json_quote(THD *thd, Item *s): Item_str_func(thd, s) {} const char *func_name() const { return "json_quote"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_quote>(thd, this); } @@ -130,7 +132,7 @@ protected: public: Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {} const char *func_name() const { return "json_unquote"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_unquote>(thd, this); } @@ -163,7 +165,7 @@ public: Item_json_str_multipath(thd, list) {} const char *func_name() const { return "json_extract"; } enum Functype functype() const { return JSON_EXTRACT_FUNC; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); longlong val_int(); double val_real(); @@ -185,7 +187,7 @@ public: Item_func_json_contains(THD *thd, List<Item> &list): Item_bool_func(thd, list) {} const char *func_name() const { return "json_contains"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_contains>(thd, this); } @@ -207,7 +209,7 @@ public: Item_bool_func(thd, list), tmp_paths(0) {} const char *func_name() const { return "json_contains_path"; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void cleanup(); longlong val_int(); Item *get_copy(THD *thd) @@ -227,7 +229,7 @@ public: Item_str_func(thd, list) {} String *val_str(String *); bool is_json_type() { return true; } - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "json_array"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_array>(thd, this); } @@ -242,7 +244,7 @@ protected: public: Item_func_json_array_append(THD *thd, List<Item> &list): Item_json_str_multipath(thd, list) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count/2; } const char *func_name() const { return "json_array_append"; } @@ -309,7 +311,7 @@ public: Item_func_json_length(THD *thd, List<Item> &list): Item_long_func(thd, list) {} const char *func_name() const { return "json_length"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_length>(thd, this); } @@ -325,7 +327,7 @@ protected: public: Item_func_json_depth(THD *thd, Item *js): Item_long_func(thd, js) {} const char *func_name() const { return "json_depth"; } - void fix_length_and_dec() { max_length= 10; } + bool fix_length_and_dec() { max_length= 10; return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_depth>(thd, this); } @@ -339,7 +341,7 @@ protected: public: Item_func_json_type(THD *thd, Item *js): Item_str_func(thd, js) {} const char *func_name() const { return "json_type"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_type>(thd, this); } @@ -356,7 +358,7 @@ public: Item_func_json_insert(bool i_mode, bool r_mode, THD *thd, List<Item> &list): Item_json_str_multipath(thd, list), mode_insert(i_mode), mode_replace(r_mode) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count/2; } const char *func_name() const @@ -376,7 +378,7 @@ protected: public: Item_func_json_remove(THD *thd, List<Item> &list): Item_json_str_multipath(thd, list) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count - 1; } const char *func_name() const { return "json_remove"; } @@ -395,7 +397,7 @@ public: Item_func_json_keys(THD *thd, List<Item> &list): Item_str_func(thd, list) {} const char *func_name() const { return "json_keys"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_keys>(thd, this); } @@ -419,7 +421,7 @@ public: Item_json_str_multipath(thd, list) {} const char *func_name() const { return "json_search"; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count > 4 ? arg_count - 4 : 0; } Item *get_copy(THD *thd) @@ -447,7 +449,7 @@ public: Item_str_func(thd, list), fmt(DETAILED) {} const char *func_name() const; - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *str); String *val_json(String *str); bool is_json_type() { return true; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6af49d494d4..c914c6cbdf8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -188,10 +188,11 @@ String *Item_func_sha::val_str_ascii(String *str) return 0; } -void Item_func_sha::fix_length_and_dec() +bool Item_func_sha::fix_length_and_dec() { // size of hex representation of hash fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset()); + return FALSE; } String *Item_func_sha2::val_str_ascii(String *str) @@ -267,7 +268,7 @@ String *Item_func_sha2::val_str_ascii(String *str) } -void Item_func_sha2::fix_length_and_dec() +bool Item_func_sha2::fix_length_and_dec() { maybe_null= 1; max_length = 0; @@ -292,6 +293,7 @@ void Item_func_sha2::fix_length_and_dec() ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2"); } + return FALSE; } /* Implementation of AES encryption routines */ @@ -344,23 +346,25 @@ String *Item_aes_crypt::val_str(String *str2) return 0; } -void Item_func_aes_encrypt::fix_length_and_dec() +bool Item_func_aes_encrypt::fix_length_and_dec() { max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length); what= ENCRYPTION_FLAG_ENCRYPT; + return FALSE; } -void Item_func_aes_decrypt::fix_length_and_dec() +bool Item_func_aes_decrypt::fix_length_and_dec() { max_length=args[0]->max_length; maybe_null= 1; what= ENCRYPTION_FLAG_DECRYPT; + return FALSE; } -void Item_func_to_base64::fix_length_and_dec() +bool Item_func_to_base64::fix_length_and_dec() { maybe_null= args[0]->maybe_null; collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); @@ -375,6 +379,7 @@ void Item_func_to_base64::fix_length_and_dec() DBUG_ASSERT(length > 0); fix_char_length_ulonglong((ulonglong) length - 1); } + return FALSE; } @@ -410,7 +415,7 @@ String *Item_func_to_base64::val_str_ascii(String *str) } -void Item_func_from_base64::fix_length_and_dec() +bool Item_func_from_base64::fix_length_and_dec() { if (args[0]->max_length > (uint) my_base64_decode_max_arg_length()) { @@ -422,6 +427,7 @@ void Item_func_from_base64::fix_length_and_dec() fix_char_length_ulonglong((ulonglong) length); } maybe_null= 1; // Can be NULL, e.g. in case of badly formed input string + return FALSE; } @@ -670,17 +676,18 @@ bool Item_func_concat::append_value(THD *thd, String *res, const String *app) } -void Item_func_concat::fix_length_and_dec() +bool Item_func_concat::fix_length_and_dec() { ulonglong char_length= 0; if (agg_arg_charsets_for_string_result(collation, args, arg_count)) - return; + return TRUE; for (uint i=0 ; i < arg_count ; i++) char_length+= args[i]->max_char_length(); fix_char_length_ulonglong(char_length); + return FALSE; } /** @@ -1032,12 +1039,12 @@ null: } -void Item_func_concat_ws::fix_length_and_dec() +bool Item_func_concat_ws::fix_length_and_dec() { ulonglong char_length; if (agg_arg_charsets_for_string_result(collation, args, arg_count)) - return; + return TRUE; /* arg_count cannot be less than 2, @@ -1049,6 +1056,7 @@ void Item_func_concat_ws::fix_length_and_dec() char_length+= args[i]->max_char_length(); fix_char_length_ulonglong(char_length); + return FALSE; } @@ -1102,11 +1110,13 @@ String *Item_func_reverse::val_str(String *str) } -void Item_func_reverse::fix_length_and_dec() +bool Item_func_reverse::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); fix_char_length(args[0]->max_char_length()); + return FALSE; } /** @@ -1259,7 +1269,7 @@ null: } -void Item_func_replace::fix_length_and_dec() +bool Item_func_replace::fix_length_and_dec() { ulonglong char_length= (ulonglong) args[0]->max_char_length(); int diff=(int) (args[2]->max_char_length() - args[1]->max_char_length()); @@ -1270,8 +1280,9 @@ void Item_func_replace::fix_length_and_dec() } if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) - return; + return TRUE; fix_char_length_ulonglong(char_length); + return FALSE; } @@ -1283,13 +1294,14 @@ bool Item_func_regexp_replace::fix_fields(THD *thd, Item **ref) } -void Item_func_regexp_replace::fix_length_and_dec() +bool Item_func_regexp_replace::fix_length_and_dec() { if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) - return; + return TRUE; max_length= MAX_BLOB_WIDTH; re.init(collation.collation, 0); re.fix_owner(this, args[0], args[1]); + return FALSE; } @@ -1425,13 +1437,14 @@ bool Item_func_regexp_substr::fix_fields(THD *thd, Item **ref) } -void Item_func_regexp_substr::fix_length_and_dec() +bool Item_func_regexp_substr::fix_length_and_dec() { if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) - return; + return TRUE; fix_char_length(args[0]->max_char_length()); re.init(collation.collation, 0); re.fix_owner(this, args[0], args[1]); + return FALSE; } @@ -1539,16 +1552,17 @@ null: } -void Item_func_insert::fix_length_and_dec() +bool Item_func_insert::fix_length_and_dec() { ulonglong char_length; // Handle character set for args[0] and args[3]. if (agg_arg_charsets_for_string_result(collation, args, 2, 3)) - return; + return TRUE; char_length= ((ulonglong) args[0]->max_char_length() + (ulonglong) args[3]->max_char_length()); fix_char_length_ulonglong(char_length); + return FALSE; } @@ -1585,22 +1599,26 @@ String *Item_str_conv::val_str(String *str) } -void Item_func_lcase::fix_length_and_dec() +bool Item_func_lcase::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); multiply= collation.collation->casedn_multiply; converter= collation.collation->cset->casedn; fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply); + return FALSE; } -void Item_func_ucase::fix_length_and_dec() +bool Item_func_ucase::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); multiply= collation.collation->caseup_multiply; converter= collation.collation->cset->caseup; fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply); + return FALSE; } @@ -1643,11 +1661,13 @@ void Item_str_func::left_right_max_length() } -void Item_func_left::fix_length_and_dec() +bool Item_func_left::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); left_right_max_length(); + return FALSE; } @@ -1677,11 +1697,13 @@ String *Item_func_right::val_str(String *str) } -void Item_func_right::fix_length_and_dec() +bool Item_func_right::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); left_right_max_length(); + return FALSE; } @@ -1732,11 +1754,12 @@ String *Item_func_substr::val_str(String *str) } -void Item_func_substr::fix_length_and_dec() +bool Item_func_substr::fix_length_and_dec() { max_length=args[0]->max_length; - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); if (args[1]->const_item()) { @@ -1757,14 +1780,16 @@ void Item_func_substr::fix_length_and_dec() set_if_smaller(max_length,(uint) length); } max_length*= collation.collation->mbmaxlen; + return FALSE; } -void Item_func_substr_index::fix_length_and_dec() -{ +bool Item_func_substr_index::fix_length_and_dec() +{ if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) - return; + return TRUE; fix_char_length(args[0]->max_char_length()); + return FALSE; } @@ -2088,11 +2113,12 @@ String *Item_func_trim::val_str(String *str) return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr)); } -void Item_func_trim::fix_length_and_dec() +bool Item_func_trim::fix_length_and_dec() { if (arg_count == 1) { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); remove.set_charset(collation.collation); remove.set_ascii(" ",1); @@ -2103,9 +2129,10 @@ void Item_func_trim::fix_length_and_dec() // Note that we pass args[1] as the first item, and args[0] as the second. if (agg_arg_charsets_for_string_result_with_comparison(collation, &args[1], 2, -1)) - return; + return TRUE; } fix_char_length(args[0]->max_char_length()); + return FALSE; } void Item_func_trim::print(String *str, enum_query_type query_type) @@ -2245,7 +2272,7 @@ bool Item_func_encode::seed() return FALSE; } -void Item_func_encode::fix_length_and_dec() +bool Item_func_encode::fix_length_and_dec() { max_length=args[0]->max_length; maybe_null=args[0]->maybe_null || args[1]->maybe_null; @@ -2253,6 +2280,7 @@ void Item_func_encode::fix_length_and_dec() /* Precompute the seed state if the item is constant. */ seeded= args[1]->const_item() && (args[1]->result_type() == STRING_RESULT) && !seed(); + return FALSE; } String *Item_func_encode::val_str(String *str) @@ -2417,13 +2445,15 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref) return 0; } -void Item_func_soundex::fix_length_and_dec() +bool Item_func_soundex::fix_length_and_dec() { uint32 char_length= args[0]->max_char_length(); - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); set_if_bigger(char_length, 4); fix_char_length(char_length); + return FALSE; } @@ -2581,7 +2611,7 @@ String *Item_func_soundex::val_str(String *str) const int FORMAT_MAX_DECIMALS= 30; -void Item_func_format::fix_length_and_dec() +bool Item_func_format::fix_length_and_dec() { uint32 char_length= args[0]->max_char_length(); uint32 max_sep_count= (char_length / 3) + (decimals ? 1 : 0) + /*sign*/1; @@ -2591,6 +2621,7 @@ void Item_func_format::fix_length_and_dec() locale= args[2]->basic_const_item() ? args[2]->locale_from_val_str() : NULL; else locale= &my_locale_en_US; /* Two arguments */ + return FALSE; } @@ -2704,13 +2735,13 @@ String *Item_func_format::val_str_ascii(String *str) } -void Item_func_elt::fix_length_and_dec() +bool Item_func_elt::fix_length_and_dec() { uint32 char_length= 0; decimals=0; if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1)) - return; + return TRUE; for (uint i= 1 ; i < arg_count ; i++) { @@ -2719,6 +2750,7 @@ void Item_func_elt::fix_length_and_dec() } fix_char_length(char_length); maybe_null=1; // NULL if wrong first arg + return FALSE; } @@ -2765,16 +2797,17 @@ String *Item_func_elt::val_str(String *str) } -void Item_func_make_set::fix_length_and_dec() +bool Item_func_make_set::fix_length_and_dec() { uint32 char_length= arg_count - 2; /* Separators */ if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1)) - return; + return TRUE; for (uint i=1 ; i < arg_count ; i++) char_length+= args[i]->max_char_length(); fix_char_length(char_length); + return FALSE; } @@ -2927,9 +2960,10 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value, } -void Item_func_repeat::fix_length_and_dec() +bool Item_func_repeat::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); if (args[1]->const_item()) { @@ -2951,6 +2985,7 @@ void Item_func_repeat::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } /** @@ -3012,7 +3047,7 @@ err: } -void Item_func_space::fix_length_and_dec() +bool Item_func_space::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); if (args[0]->const_item()) @@ -3028,12 +3063,13 @@ void Item_func_space::fix_length_and_dec() if (count > INT_MAX32) count= INT_MAX32; fix_char_length_ulonglong(count); - return; + return FALSE; } end: max_length= MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } @@ -3083,11 +3119,12 @@ err: } -void Item_func_binlog_gtid_pos::fix_length_and_dec() +bool Item_func_binlog_gtid_pos::fix_length_and_dec() { collation.set(system_charset_info); max_length= MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } @@ -3123,18 +3160,18 @@ err: } -void Item_func_pad::fix_length_and_dec() +bool Item_func_pad::fix_length_and_dec() { if (arg_count == 3) { // Handle character set for args[0] and args[2]. if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2)) - return; + return TRUE; } else { if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1)) - return; + return TRUE; pad_str.set_charset(collation.collation); pad_str.length(0); pad_str.append(" ", 1); @@ -3157,6 +3194,7 @@ void Item_func_pad::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } @@ -3411,10 +3449,11 @@ String *Item_func_conv_charset::val_str(String *str) 0 : str; } -void Item_func_conv_charset::fix_length_and_dec() +bool Item_func_conv_charset::fix_length_and_dec() { DBUG_ASSERT(collation.derivation == DERIVATION_IMPLICIT); fix_char_length(args[0]->max_char_length()); + return FALSE; } void Item_func_conv_charset::print(String *str, enum_query_type query_type) @@ -3436,17 +3475,18 @@ String *Item_func_set_collation::val_str(String *str) return str; } -void Item_func_set_collation::fix_length_and_dec() +bool Item_func_set_collation::fix_length_and_dec() { if (!my_charset_same(args[0]->collation.collation, m_set_collation)) { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), m_set_collation->name, args[0]->collation.collation->csname); - return; + return TRUE; } collation.set(m_set_collation, DERIVATION_EXPLICIT, args[0]->collation.repertoire); max_length= args[0]->max_length; + return FALSE; } @@ -3489,7 +3529,7 @@ String *Item_func_collation::val_str(String *str) } -void Item_func_weight_string::fix_length_and_dec() +bool Item_func_weight_string::fix_length_and_dec() { CHARSET_INFO *cs= args[0]->collation.collation; collation.set(&my_charset_bin, args[0]->collation.derivation); @@ -3507,6 +3547,7 @@ void Item_func_weight_string::fix_length_and_dec() max_length= (uint32)cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen); } maybe_null= 1; + return FALSE; } @@ -3878,15 +3919,16 @@ String* Item_func_export_set::val_str(String* str) return str; } -void Item_func_export_set::fix_length_and_dec() +bool Item_func_export_set::fix_length_and_dec() { uint32 length= MY_MAX(args[1]->max_char_length(), args[2]->max_char_length()); uint32 sep_length= (arg_count > 3 ? args[3]->max_char_length() : 1); if (agg_arg_charsets_for_string_result(collation, args + 1, MY_MIN(4, arg_count) - 1)) - return; + return TRUE; fix_char_length(length * 64 + sep_length * 63); + return FALSE; } @@ -4286,12 +4328,13 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref) } -void Item_func_dyncol_create::fix_length_and_dec() +bool Item_func_dyncol_create::fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; maybe_null= TRUE; collation.set(&my_charset_bin); decimals= 0; + return FALSE; } bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg) @@ -5211,10 +5254,11 @@ Item_temptable_rowid::Item_temptable_rowid(TABLE *table_arg) max_length= table->file->ref_length; } -void Item_temptable_rowid::fix_length_and_dec() +bool Item_temptable_rowid::fix_length_and_dec() { used_tables_cache= table->map; const_item_cache= false; + return FALSE; } String *Item_temptable_rowid::val_str(String *str) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index eb084c3f58d..29af0b43d9d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -144,9 +144,10 @@ class Item_func_md5 :public Item_str_ascii_checksum_func public: Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { fix_length_and_charset(32, default_charset()); + return FALSE; } const char *func_name() const { return "md5"; } Item *get_copy(THD *thd) @@ -159,7 +160,7 @@ class Item_func_sha :public Item_str_ascii_checksum_func public: Item_func_sha(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "sha"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sha>(thd, this); } @@ -171,7 +172,7 @@ public: Item_func_sha2(THD *thd, Item *a, Item *b) :Item_str_ascii_checksum_func(thd, a, b) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "sha2"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sha2>(thd, this); } @@ -184,7 +185,7 @@ public: Item_func_to_base64(THD *thd, Item *a) :Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "to_base64"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_to_base64>(thd, this); } @@ -197,7 +198,7 @@ public: Item_func_from_base64(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) { } String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "from_base64"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_from_base64>(thd, this); } @@ -224,7 +225,7 @@ class Item_func_aes_encrypt :public Item_aes_crypt public: Item_func_aes_encrypt(THD *thd, Item *a, Item *b) :Item_aes_crypt(thd, a, b) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "aes_encrypt"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_aes_encrypt>(thd, this); } @@ -235,7 +236,7 @@ class Item_func_aes_decrypt :public Item_aes_crypt public: Item_func_aes_decrypt(THD *thd, Item *a, Item *b): Item_aes_crypt(thd, a, b) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "aes_decrypt"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_aes_decrypt>(thd, this); } @@ -259,7 +260,7 @@ public: Item_func_concat(THD *thd, List<Item> &list): Item_str_func(thd, list) {} Item_func_concat(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "concat"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_concat>(thd, this); } @@ -294,11 +295,12 @@ public: Item_func_decode_histogram(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(system_charset_info); max_length= MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } const char *func_name() const { return "decode_histogram"; } Item *get_copy(THD *thd) @@ -311,7 +313,7 @@ class Item_func_concat_ws :public Item_str_func public: Item_func_concat_ws(THD *thd, List<Item> &list): Item_str_func(thd, list) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "concat_ws"; } table_map not_null_tables() const { return 0; } Item *get_copy(THD *thd) @@ -324,7 +326,7 @@ class Item_func_reverse :public Item_str_func public: Item_func_reverse(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "reverse"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_reverse>(thd, this); } @@ -338,7 +340,7 @@ public: Item_func_replace(THD *thd, Item *org, Item *find, Item *replace): Item_str_func(thd, org, find, replace) {} String *val_str(String *to) { return val_str_internal(to, NULL); }; - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str_internal(String *str, String *empty_string_for_null); const char *func_name() const { return "replace"; } Item *get_copy(THD *thd) @@ -378,7 +380,7 @@ public: } String *val_str(String *str); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp_replace"; } Item *get_copy(THD *thd) { return 0;} }; @@ -400,7 +402,7 @@ public: } String *val_str(String *str); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp_substr"; } Item *get_copy(THD *thd) { return 0; } }; @@ -414,7 +416,7 @@ public: Item *new_str): Item_str_func(thd, org, start, length, new_str) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "insert"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_insert>(thd, this); } @@ -438,7 +440,7 @@ class Item_func_lcase :public Item_str_conv public: Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {} const char *func_name() const { return "lcase"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_lcase>(thd, this); } }; @@ -448,7 +450,7 @@ class Item_func_ucase :public Item_str_conv public: Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {} const char *func_name() const { return "ucase"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_ucase>(thd, this); } }; @@ -460,7 +462,7 @@ class Item_func_left :public Item_str_func public: Item_func_left(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "left"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_left>(thd, this); } @@ -473,7 +475,7 @@ class Item_func_right :public Item_str_func public: Item_func_right(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "right"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_right>(thd, this); } @@ -490,7 +492,7 @@ public: Item_func_substr(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "substr"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_substr>(thd, this); } @@ -508,10 +510,11 @@ public: Item_func_substr(thd, a, b) {} Item_func_substr_oracle(THD *thd, Item *a, Item *b, Item *c): Item_func_substr(thd, a, b, c) {} - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_substr::fix_length_and_dec(); + bool res= Item_func_substr::fix_length_and_dec(); maybe_null= true; + return res; } const char *func_name() const { return "substr_oracle"; } Item *get_copy(THD *thd) @@ -525,7 +528,7 @@ public: Item_func_substr_index(THD *thd, Item *a,Item *b,Item *c): Item_str_func(thd, a, b, c) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "substring_index"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_substr_index>(thd, this); } @@ -561,7 +564,7 @@ public: Item_func_trim(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} Item_func_trim(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "trim"; } void print(String *str, enum_query_type query_type); virtual const char *mode_name() const { return "both"; } @@ -581,10 +584,11 @@ public: Item_func_trim(thd, a, b) {} Item_func_trim_oracle(THD *thd, Item *a): Item_func_trim(thd, a) {} const char *func_name() const { return "trim_oracle"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_trim::fix_length_and_dec(); + bool res= Item_func_trim::fix_length_and_dec(); maybe_null= true; + return res; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_trim_oracle>(thd, this); } @@ -615,10 +619,11 @@ public: Item_func_ltrim(thd, a, b) {} Item_func_ltrim_oracle(THD *thd, Item *a): Item_func_ltrim(thd, a) {} const char *func_name() const { return "ltrim_oracle"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_ltrim::fix_length_and_dec(); + bool res= Item_func_ltrim::fix_length_and_dec(); maybe_null= true; + return res; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_ltrim_oracle>(thd, this); } @@ -649,10 +654,11 @@ public: Item_func_rtrim(thd, a, b) {} Item_func_rtrim_oracle(THD *thd, Item *a): Item_func_rtrim(thd, a) {} const char *func_name() const { return "rtrim_oracle"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_rtrim::fix_length_and_dec(); + bool res= Item_func_rtrim::fix_length_and_dec(); maybe_null= true; + return res; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_rtrim_oracle>(thd, this); } @@ -681,12 +687,13 @@ public: Item_str_ascii_checksum_func(thd, a), alg(al), deflt(0) {} String *val_str_ascii(String *str); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() + bool fix_length_and_dec() { fix_length_and_charset((alg == 1 ? SCRAMBLED_PASSWORD_CHAR_LENGTH : SCRAMBLED_PASSWORD_CHAR_LENGTH_323), default_charset()); + return FALSE; } const char *func_name() const { return ((deflt || alg == 1) ? "password" : "old_password"); } @@ -707,11 +714,12 @@ public: Item_func_des_encrypt(THD *thd, Item *a, Item *b) :Item_str_binary_checksum_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null=1; /* 9 = MAX ((8- (arg_len % 8)) + 1) */ max_length = args[0]->max_length + 9; + return FALSE; } const char *func_name() const { return "des_encrypt"; } Item *get_copy(THD *thd) @@ -727,13 +735,14 @@ public: Item_func_des_decrypt(THD *thd, Item *a, Item *b) :Item_str_binary_checksum_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null=1; /* 9 = MAX ((8- (arg_len % 8)) + 1) */ max_length= args[0]->max_length; if (max_length >= 9U) max_length-= 9U; + return FALSE; } const char *func_name() const { return "des_decrypt"; } Item *get_copy(THD *thd) @@ -766,7 +775,7 @@ public: constructor_helper(); } String *val_str(String *); - void fix_length_and_dec() { maybe_null=1; max_length = 13; } + bool fix_length_and_dec() { maybe_null=1; max_length = 13; return FALSE; } const char *func_name() const { return "encrypt"; } bool check_vcol_func_processor(void *arg) { @@ -790,7 +799,7 @@ public: Item_func_encode(THD *thd, Item *a, Item *seed_arg): Item_str_binary_checksum_func(thd, a, seed_arg) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "encode"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_encode>(thd, this); } @@ -840,10 +849,11 @@ class Item_func_database :public Item_func_sysconst public: Item_func_database(THD *thd): Item_func_sysconst(thd) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen; maybe_null=1; + return FALSE; } const char *func_name() const { return "database"; } const char *fully_qualified_func_name() const { return "database()"; } @@ -863,10 +873,11 @@ public: { str->append(func_name()); } - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 512 * system_charset_info->mbmaxlen; null_value= maybe_null= false; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sqlerrm>(thd, this); } @@ -889,10 +900,11 @@ public: return (null_value ? 0 : &str_value); } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= (uint32) (username_char_length + HOSTNAME_LENGTH + 1) * SYSTEM_CHARSET_MBMAXLEN; + return FALSE; } const char *func_name() const { return "user"; } const char *fully_qualified_func_name() const { return "user()"; } @@ -932,8 +944,11 @@ public: Item_func_current_role(THD *thd, Name_resolution_context *context_arg): Item_func_sysconst(thd), context(context_arg) {} bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() - { max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN; } + bool fix_length_and_dec() + { + max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN; + return FALSE; + } int save_in_field(Field *field, bool no_conversions) { return save_str_value_in_field(field, &str_value); } const char *func_name() const { return "current_role"; } @@ -961,7 +976,7 @@ class Item_func_soundex :public Item_str_func public: Item_func_soundex(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "soundex"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_soundex>(thd, this); } @@ -975,7 +990,7 @@ public: double val_real(); longlong val_int(); String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "elt"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_elt>(thd, this); } @@ -989,7 +1004,7 @@ class Item_func_make_set :public Item_str_func public: Item_func_make_set(THD *thd, List<Item> &list): Item_str_func(thd, list) {} String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "make_set"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_make_set>(thd, this); } @@ -1006,7 +1021,7 @@ public: Item_str_ascii_func(thd, org, dec, lang) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "format"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_format>(thd, this); } @@ -1026,9 +1041,10 @@ public: { collation.set(cs); } String *val_str(String *); void append_char(String * str, int32 num); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= arg_count * 4; + return FALSE; } const char *func_name() const { return "char"; } void print(String *str, enum_query_type query_type); @@ -1042,9 +1058,10 @@ public: Item_func_chr(THD *thd, Item *arg1, CHARSET_INFO *cs): Item_func_char(thd, arg1, cs) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 4; + return FALSE; } const char *func_name() const { return "chr"; } Item *get_copy(THD *thd) @@ -1058,7 +1075,7 @@ public: Item_func_repeat(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "repeat"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_repeat>(thd, this); } @@ -1070,7 +1087,7 @@ class Item_func_space :public Item_str_func public: Item_func_space(THD *thd, Item *arg1): Item_str_func(thd, arg1) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "space"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_space>(thd, this); } @@ -1083,7 +1100,7 @@ public: Item_func_binlog_gtid_pos(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "binlog_gtid_pos"; } bool check_vcol_func_processor(void *arg) { @@ -1103,7 +1120,7 @@ public: Item_str_func(thd, arg1, arg2, arg3) {} Item_func_pad(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -1130,10 +1147,11 @@ public: Item_func_rpad(thd, arg1, arg2, arg3) {} Item_func_rpad_oracle(THD *thd, Item *arg1, Item *arg2): Item_func_rpad(thd, arg1, arg2) {} - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_rpad::fix_length_and_dec(); + bool res= Item_func_rpad::fix_length_and_dec(); maybe_null= true; + return res; } const char *func_name() const { return "rpad_oracle"; } Item *get_copy(THD *thd) @@ -1164,10 +1182,11 @@ public: Item_func_lpad(thd, arg1, arg2, arg3) {} Item_func_lpad_oracle(THD *thd, Item *arg1, Item *arg2): Item_func_lpad(thd, arg1, arg2) {} - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_lpad::fix_length_and_dec(); + bool res= Item_func_lpad::fix_length_and_dec(); maybe_null= true; + return res; } const char *func_name() const { return "lpad_oracle"; } Item *get_copy(THD *thd) @@ -1182,11 +1201,12 @@ public: Item_str_func(thd, a, b, c) {} const char *func_name() const { return "conv"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(default_charset()); max_length=64; maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_conv>(thd, this); } @@ -1216,12 +1236,13 @@ public: DBUG_ASSERT(fixed); return m_arg0_type_handler->Item_func_hex_val_str_ascii(this, str); } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); decimals=0; fix_char_length(args[0]->max_length * 2); m_arg0_type_handler= args[0]->type_handler(); + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_hex>(thd, this); } @@ -1238,11 +1259,12 @@ public: } const char *func_name() const { return "unhex"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; max_length=(1+args[0]->max_length)/2; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_unhex>(thd, this); } @@ -1261,11 +1283,12 @@ public: Item_str_func(thd, a, b), is_min(is_min_arg) { maybe_null= 1; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(args[0]->collation); decimals=0; max_length= MAX_BLOB_WIDTH; + return FALSE; } }; @@ -1306,10 +1329,11 @@ public: tmp->set_charset(&my_charset_bin); return tmp; } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin); max_length=args[0]->max_length; + return FALSE; } void print(String *str, enum_query_type query_type); const char *func_name() const { return "cast_as_binary"; } @@ -1326,11 +1350,12 @@ public: Item_load_file(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); const char *func_name() const { return "load_file"; } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin, DERIVATION_COERCIBLE); maybe_null=1; max_length=MAX_BLOB_WIDTH; + return FALSE; } bool check_vcol_func_processor(void *arg) { @@ -1351,7 +1376,7 @@ class Item_func_export_set: public Item_str_func Item_func_export_set(THD *thd, Item *a, Item *b, Item* c, Item* d, Item* e): Item_str_func(thd, a, b, c, d, e) {} String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "export_set"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_export_set>(thd, this); } @@ -1365,12 +1390,13 @@ public: Item_func_quote(THD *thd, Item *a): Item_str_func(thd, a) {} const char *func_name() const { return "quote"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(args[0]->collation); ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2 * collation.collation->mbmaxlen; max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH); + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_quote>(thd, this); } @@ -1453,7 +1479,7 @@ public: return 1; return res; } - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "convert"; } void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1467,7 +1493,7 @@ public: Item_func_set_collation(THD *thd, Item *a, CHARSET_INFO *set_collation): Item_str_func(thd, a), m_set_collation(set_collation) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "collate"; } enum precedence precedence() const { return COLLATE_PRECEDENCE; } @@ -1488,11 +1514,12 @@ class Item_func_expr_str_metadata :public Item_str_func { public: Item_func_expr_str_metadata(THD *thd, Item *a): Item_str_func(thd, a) { } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(system_charset_info); max_length= 64 * collation.collation->mbmaxlen; // should be enough maybe_null= 0; + return FALSE; }; table_map not_null_tables() const { return 0; } Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) @@ -1542,7 +1569,7 @@ public: } const char *func_name() const { return "weight_string"; } String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const { if (!Item_str_func::eq(item, binary_cmp)) @@ -1568,7 +1595,7 @@ public: Item_func_crc32(THD *thd, Item *a): Item_long_func(thd, a) { unsigned_flag= 1; } const char *func_name() const { return "crc32"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_crc32>(thd, this); } @@ -1581,7 +1608,7 @@ public: Item_func_uncompressed_length(THD *thd, Item *a) :Item_long_func_length(thd, a) {} const char *func_name() const{return "uncompressed_length";} - void fix_length_and_dec() { max_length=10; maybe_null= true; } + bool fix_length_and_dec() { max_length=10; maybe_null= true; return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_uncompressed_length>(thd, this); } @@ -1599,7 +1626,11 @@ class Item_func_compress: public Item_str_binary_checksum_func public: Item_func_compress(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) {} - void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;} + bool fix_length_and_dec() + { + max_length= (args[0]->max_length * 120) / 100 + 12; + return FALSE; + } const char *func_name() const{return "compress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION Item *get_copy(THD *thd) @@ -1612,7 +1643,11 @@ class Item_func_uncompress: public Item_str_binary_checksum_func public: Item_func_uncompress(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) {} - void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } + bool fix_length_and_dec() + { + maybe_null= 1; max_length= MAX_BLOB_WIDTH; + return FALSE; + } const char *func_name() const{return "uncompress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION Item *get_copy(THD *thd) @@ -1624,11 +1659,12 @@ class Item_func_uuid: public Item_str_func { public: Item_func_uuid(THD *thd): Item_str_func(thd) {} - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(system_charset_info, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); fix_char_length(MY_UUID_STRING_LENGTH); + return FALSE; } bool const_item() const { return false; } table_map used_tables() const { return RAND_TABLE_BIT; } @@ -1656,7 +1692,7 @@ protected: public: Item_func_dyncol_create(THD *thd, List<Item> &args, DYNCALL_CREATE_DEF *dfs); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const{ return "column_create"; } String *val_str(String *); void print(String *str, enum_query_type query_type); @@ -1686,11 +1722,12 @@ public: {collation.set(DYNCOL_UTF);} const char *func_name() const{ return "column_json"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; maybe_null= 1; decimals= 0; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_dyncol_json>(thd, this); } @@ -1705,8 +1742,8 @@ class Item_dyncol_get: public Item_str_func public: Item_dyncol_get(THD *thd, Item *str, Item *num): Item_str_func(thd, str, num) {} - void fix_length_and_dec() - { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; } + bool fix_length_and_dec() + { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; return FALSE; } /* Mark that collation can change between calls */ bool dynamic_result() { return 1; } @@ -1744,7 +1781,8 @@ class Item_func_dyncol_list: public Item_str_func public: Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) {collation.set(DYNCOL_UTF);} - void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; }; + bool fix_length_and_dec() + { maybe_null= 1; max_length= MAX_BLOB_WIDTH; return FALSE; }; const char *func_name() const{ return "column_list"; } String *val_str(String *); Item *get_copy(THD *thd) @@ -1767,7 +1805,7 @@ public: String *val_str(String *str); enum Functype functype() const { return TEMPTABLE_ROWID; } const char *func_name() const { return "<rowid>"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_temptable_rowid>(thd, this); } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ca3316a1b5d..9b513ac9795 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -310,10 +310,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) if (engine->cols() > max_columns) { my_error(ER_OPERAND_COLUMNS, MYF(0), 1); - + res= TRUE; + goto end; + } + if (fix_length_and_dec()) + { + res= TRUE; goto end; } - fix_length_and_dec(); } else goto end; @@ -910,9 +914,11 @@ Item::Type Item_subselect::type() const } -void Item_subselect::fix_length_and_dec() +bool Item_subselect::fix_length_and_dec() { - engine->fix_length_and_dec(0); + if (engine->fix_length_and_dec(0)) + return TRUE; + return FALSE; } @@ -1186,18 +1192,19 @@ const Type_handler *Item_singlerow_subselect::type_handler() const return engine->type_handler(); } -void Item_singlerow_subselect::fix_length_and_dec() +bool Item_singlerow_subselect::fix_length_and_dec() { if ((max_columns= engine->cols()) == 1) { - engine->fix_length_and_dec(row= &value); + if (engine->fix_length_and_dec(row= &value)) + return TRUE; } else { if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) * - max_columns))) - return; - engine->fix_length_and_dec(row); + max_columns)) || + engine->fix_length_and_dec(row)) + return TRUE; value= *row; } unsigned_flag= value->unsigned_flag; @@ -1213,6 +1220,7 @@ void Item_singlerow_subselect::fix_length_and_dec() for (uint i= 0; i < max_columns; i++) row[i]->maybe_null= TRUE; } + return FALSE; } @@ -1497,7 +1505,7 @@ void Item_exists_subselect::init_length_and_dec() } -void Item_exists_subselect::fix_length_and_dec() +bool Item_exists_subselect::fix_length_and_dec() { DBUG_ENTER("Item_exists_subselect::fix_length_and_dec"); init_length_and_dec(); @@ -1505,14 +1513,17 @@ void Item_exists_subselect::fix_length_and_dec() We need only 1 row to determine existence (i.e. any EXISTS that is not an IN always requires LIMIT 1) */ + Item *item= new (thd->mem_root) Item_int(thd, (int32) 1); + if (!item) + DBUG_RETURN(TRUE); thd->change_item_tree(&unit->global_parameters()->select_limit, - new (thd->mem_root) Item_int(thd, (int32) 1)); + item); DBUG_PRINT("info", ("Set limit to 1")); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } -void Item_in_subselect::fix_length_and_dec() +bool Item_in_subselect::fix_length_and_dec() { DBUG_ENTER("Item_in_subselect::fix_length_and_dec"); init_length_and_dec(); @@ -1520,7 +1531,7 @@ void Item_in_subselect::fix_length_and_dec() Unlike Item_exists_subselect, LIMIT 1 is set later for Item_in_subselect, depending on the chosen strategy. */ - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -3705,11 +3716,11 @@ bool subselect_single_select_engine::no_rows() } -/* - makes storage for the output values for the subquery and calcuates +/** + Makes storage for the output values for the subquery and calcuates their data and column types and their nullability. -*/ -void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) +*/ +bool subselect_engine::set_row(List<Item> &item_list, Item_cache **row) { Item *sel_item; List_iterator_fast<Item> li(item_list); @@ -3722,44 +3733,51 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) item->unsigned_flag= sel_item->unsigned_flag; maybe_null= sel_item->maybe_null; if (!(row[i]= sel_item->get_cache(thd))) - return; + return TRUE; row[i]->setup(thd, sel_item); //psergey-backport-timours: row[i]->store(sel_item); } if (item_list.elements > 1) set_handler(&type_handler_row); + return FALSE; } -void subselect_single_select_engine::fix_length_and_dec(Item_cache **row) +bool subselect_single_select_engine::fix_length_and_dec(Item_cache **row) { DBUG_ASSERT(row || select_lex->item_list.elements==1); - set_row(select_lex->item_list, row); + if (set_row(select_lex->item_list, row)) + return TRUE; item->collation.set(row[0]->collation); if (cols() != 1) maybe_null= 0; + return FALSE; } -void subselect_union_engine::fix_length_and_dec(Item_cache **row) +bool subselect_union_engine::fix_length_and_dec(Item_cache **row) { DBUG_ASSERT(row || unit->first_select()->item_list.elements==1); if (unit->first_select()->item_list.elements == 1) { - set_row(unit->types, row); + if (set_row(unit->types, row)) + return TRUE; item->collation.set(row[0]->collation); } else { bool maybe_null_saved= maybe_null; - set_row(unit->types, row); + if (set_row(unit->types, row)) + return TRUE; maybe_null= maybe_null_saved; } + return FALSE; } -void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row) +bool subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row) { //this never should be called DBUG_ASSERT(0); + return FALSE; } int read_first_record_seq(JOIN_TAB *tab); @@ -5586,9 +5604,10 @@ void subselect_hash_sj_engine::print(String *str, enum_query_type query_type) )); } -void subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row) +bool subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row) { DBUG_ASSERT(FALSE); + return FALSE; } void subselect_hash_sj_engine::exclude() diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 5b27181743f..084abf787af 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -201,7 +201,7 @@ public: const_item_cache= 0; forced_const= TRUE; } - virtual void fix_length_and_dec(); + virtual bool fix_length_and_dec(); table_map used_tables() const; table_map not_null_tables() const { return 0; } bool const_item() const; @@ -310,7 +310,7 @@ public: bool val_bool(); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); const Type_handler *type_handler() const; - void fix_length_and_dec(); + bool fix_length_and_dec(); uint cols() const; Item* element_index(uint i) { return reinterpret_cast<Item*>(row[i]); } @@ -408,7 +408,7 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date_from_int(ltime, fuzzydate); } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); bool select_transformer(JOIN *join); void top_level_item() { abort_on_null=1; } @@ -633,7 +633,7 @@ public: void print(String *str, enum_query_type query_type); enum precedence precedence() const { return CMP_PRECEDENCE; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool const_item() const { @@ -816,7 +816,7 @@ public: void set_thd(THD *thd_arg); THD * get_thd() { return thd ? thd : current_thd; } virtual int prepare(THD *)= 0; - virtual void fix_length_and_dec(Item_cache** row)= 0; + virtual bool fix_length_and_dec(Item_cache** row)= 0; /* Execute the engine @@ -857,7 +857,7 @@ public: virtual int get_identifier() { DBUG_ASSERT(0); return 0; } virtual void force_reexecution() {} protected: - void set_row(List<Item> &item_list, Item_cache **row); + bool set_row(List<Item> &item_list, Item_cache **row); }; class subselect_single_select_engine: public subselect_engine @@ -872,7 +872,7 @@ public: Item_subselect *item); void cleanup(); int prepare(THD *thd); - void fix_length_and_dec(Item_cache** row); + bool fix_length_and_dec(Item_cache** row); int exec(); uint cols() const; uint8 uncacheable(); @@ -909,7 +909,7 @@ public: Item_subselect *item); void cleanup(); int prepare(THD *); - void fix_length_and_dec(Item_cache** row); + bool fix_length_and_dec(Item_cache** row); int exec(); uint cols() const; uint8 uncacheable(); @@ -967,7 +967,7 @@ public: ~subselect_uniquesubquery_engine(); void cleanup(); int prepare(THD *); - void fix_length_and_dec(Item_cache** row); + bool fix_length_and_dec(Item_cache** row); int exec(); uint cols() const { return 1; } uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; } @@ -1116,7 +1116,7 @@ public: TODO: factor out all these methods in a base subselect_index_engine class because all of them have dummy implementations and should never be called. */ - void fix_length_and_dec(Item_cache** row);//=>base class + bool fix_length_and_dec(Item_cache** row);//=>base class void exclude(); //=>base class //=>base class bool change_result(Item_subselect *si, @@ -1389,7 +1389,7 @@ public: uint count_columns_with_nulls_arg); int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; } int exec(); - void fix_length_and_dec(Item_cache**) {} + bool fix_length_and_dec(Item_cache**) { return FALSE; } uint cols() const { /* TODO: what is the correct value? */ return 1; } uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; } void exclude() {} diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 69e228ec384..3e26e70ee6e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -72,14 +72,14 @@ size_t Item_sum::ram_limitation(THD *thd) bool Item_sum::init_sum_func_check(THD *thd) { SELECT_LEX *curr_sel= thd->lex->current_select; - if (!curr_sel->name_visibility_map) + if (curr_sel && !curr_sel->name_visibility_map) { for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select()) { curr_sel->name_visibility_map|= (1 << sl-> nest_level); } } - if (!(thd->lex->allow_sum_func & curr_sel->name_visibility_map)) + if (!curr_sel || !(thd->lex->allow_sum_func & curr_sel->name_visibility_map)) { my_message(ER_INVALID_GROUP_FUNC_USE, ER_THD(thd, ER_INVALID_GROUP_FUNC_USE), MYF(0)); @@ -1138,9 +1138,8 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) result_field=0; max_length=float_length(decimals); null_value=1; - fix_length_and_dec(); - - if (check_sum_func(thd, ref)) + if (fix_length_and_dec() || + check_sum_func(thd, ref)) return TRUE; memcpy (orig_args, args, sizeof (Item *) * arg_count); @@ -1166,7 +1165,9 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) with_param= args[0]->with_param; with_window_func|= args[0]->with_window_func; - fix_length_and_dec(); + if (fix_length_and_dec()) + DBUG_RETURN(TRUE); + if (!is_window_func_sum_expr()) setup_hybrid(thd, args[0], NULL); result_field=0; @@ -1180,11 +1181,11 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) } -void Item_sum_hybrid::fix_length_and_dec() +bool Item_sum_hybrid::fix_length_and_dec() { DBUG_ASSERT(args[0]->field_type() == args[0]->real_item()->field_type()); DBUG_ASSERT(args[0]->result_type() == args[0]->real_item()->result_type()); - (void) args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this); + return args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this); } @@ -1305,7 +1306,8 @@ Item_sum_sp::fix_fields(THD *thd, Item **ref) result_field= NULL; max_length= float_length(decimals); null_value= 1; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; if (check_sum_func(thd, ref)) return TRUE; @@ -1387,14 +1389,14 @@ Item_sum_sp::cleanup() @note called from Item::fix_fields. */ -void +bool Item_sum_sp::fix_length_and_dec() { DBUG_ENTER("Item_sum_sp::fix_length_and_dec"); DBUG_ASSERT(sp_result_field); Type_std_attributes::set(sp_result_field->type_std_attributes()); - Item_sum::fix_length_and_dec(); - DBUG_VOID_RETURN; + bool res= Item_sum::fix_length_and_dec(); + DBUG_RETURN(res); } const char * @@ -1490,14 +1492,16 @@ void Item_sum_sum::fix_length_and_dec_decimal() } -void Item_sum_sum::fix_length_and_dec() +bool Item_sum_sum::fix_length_and_dec() { DBUG_ENTER("Item_sum_sum::fix_length_and_dec"); maybe_null=null_value=1; - args[0]->cast_to_int_type_handler()->Item_sum_sum_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_sum_sum_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s (%d, %d)", type_handler()->name().ptr(), max_length, (int) decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1914,15 +1918,17 @@ void Item_sum_avg::fix_length_and_dec_double() } -void Item_sum_avg::fix_length_and_dec() +bool Item_sum_avg::fix_length_and_dec() { DBUG_ENTER("Item_sum_avg::fix_length_and_dec"); prec_increment= current_thd->variables.div_precincrement; maybe_null=null_value=1; - args[0]->cast_to_int_type_handler()->Item_sum_avg_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_sum_avg_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s (%d, %d)", type_handler()->name().ptr(), max_length, (int) decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2134,7 +2140,7 @@ void Item_sum_variance::fix_length_and_dec_decimal() } -void Item_sum_variance::fix_length_and_dec() +bool Item_sum_variance::fix_length_and_dec() { DBUG_ENTER("Item_sum_variance::fix_length_and_dec"); maybe_null= null_value= 1; @@ -2146,11 +2152,11 @@ void Item_sum_variance::fix_length_and_dec() type of the result is an implementation-defined aproximate numeric type. */ - - args[0]->type_handler()->Item_sum_variance_fix_length_and_dec(this); + if (args[0]->type_handler()->Item_sum_variance_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s (%d, %d)", type_handler()->name().ptr(), max_length, (int)decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -3376,13 +3382,13 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec) /** Default max_length is max argument length. */ -void Item_sum_udf_str::fix_length_and_dec() +bool Item_sum_udf_str::fix_length_and_dec() { DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec"); max_length=0; for (uint i = 0; i < arg_count; i++) set_if_bigger(max_length,args[i]->max_length); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 89ebb04366a..769d4f2f26c 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -457,7 +457,8 @@ public: Updated value is then saved in the field. */ virtual void update_field()=0; - virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } + virtual bool fix_length_and_dec() + { maybe_null=1; null_value=1; return FALSE; } virtual Item *result_item(THD *thd, Field *field); void update_used_tables (); @@ -760,8 +761,8 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_longlong; } - void fix_length_and_dec() - { decimals=0; max_length=21; maybe_null=null_value=0; } + bool fix_length_and_dec() + { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; } }; @@ -777,7 +778,7 @@ protected: my_decimal direct_sum_decimal; my_decimal dec_buffs[2]; uint curr_dec_buff; - void fix_length_and_dec(); + bool fix_length_and_dec(); public: Item_sum_sum(THD *thd, Item *item_par, bool distinct): @@ -912,7 +913,7 @@ public: void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); enum Sumfunctype sum_func () const { return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; @@ -972,7 +973,7 @@ But, this falls prey to catastrophic cancellation. Instead, use the recurrence class Item_sum_variance : public Item_sum_num { - void fix_length_and_dec(); + bool fix_length_and_dec(); public: double recurrence_m, recurrence_s; /* Used in recurrence relation. */ @@ -1059,7 +1060,7 @@ protected: cmp_sign(item->cmp_sign), was_values(item->was_values) { } bool fix_fields(THD *, Item **); - void fix_length_and_dec(); + bool fix_length_and_dec(); void setup_hybrid(THD *thd, Item *item, Item *value_arg); void clear(); void direct_add(Item *item); @@ -1139,8 +1140,11 @@ public: longlong val_int(); void reset_field(); void update_field(); - void fix_length_and_dec() - { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; } + bool fix_length_and_dec() + { + decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; + return FALSE; + } void cleanup() { bits= reset_bits; @@ -1309,7 +1313,7 @@ public: { return create_table_field_from_handler(table); } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); const char *func_name() const; const Type_handler *type_handler() const; @@ -1573,7 +1577,7 @@ class Item_sum_udf_float :public Item_udf_sum String *val_str(String*str); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_float>(thd, this); } @@ -1595,7 +1599,7 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_longlong; } - void fix_length_and_dec() { decimals=0; max_length=21; } + bool fix_length_and_dec() { decimals=0; max_length=21; return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_int>(thd, this); } @@ -1636,7 +1640,7 @@ public: } my_decimal *val_decimal(my_decimal *dec); const Type_handler *type_handler() const { return string_type_handler(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_str>(thd, this); } @@ -1657,7 +1661,7 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_newdecimal; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_decimal>(thd, this); } @@ -1731,7 +1735,7 @@ public: { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - void fix_length_and_dec() { maybe_null=1; max_length=0; } + bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } void clear() {} bool add() { return 0; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e01114fb0ad..b4d929e0f70 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -954,7 +954,7 @@ longlong Item_func_month::val_int() } -void Item_func_monthname::fix_length_and_dec() +bool Item_func_monthname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; @@ -962,7 +962,8 @@ void Item_func_monthname::fix_length_and_dec() collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_month_name_length * collation.collation->mbmaxlen; - maybe_null=1; + maybe_null=1; + return FALSE; } @@ -1102,7 +1103,7 @@ longlong Item_func_weekday::val_int() odbc_type) + MY_TEST(odbc_type); } -void Item_func_dayname::fix_length_and_dec() +bool Item_func_dayname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; @@ -1110,7 +1111,8 @@ void Item_func_dayname::fix_length_and_dec() collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_day_name_length * collation.collation->mbmaxlen; - maybe_null=1; + maybe_null=1; + return FALSE; } @@ -1842,7 +1844,7 @@ overflow: return 0; } -void Item_func_date_format::fix_length_and_dec() +bool Item_func_date_format::fix_length_and_dec() { THD* thd= current_thd; if (!is_time_format) @@ -1881,6 +1883,7 @@ void Item_func_date_format::fix_length_and_dec() set_if_smaller(max_length,MAX_BLOB_WIDTH); } maybe_null=1; // If wrong date + return FALSE; } @@ -2034,13 +2037,14 @@ null_date: } -void Item_func_from_unixtime::fix_length_and_dec() -{ +bool Item_func_from_unixtime::fix_length_and_dec() +{ THD *thd= current_thd; thd->time_zone_used= 1; tz= thd->variables.time_zone; fix_attributes_datetime_not_fixed_dec(args[0]->decimals); maybe_null= true; + return FALSE; } @@ -2112,7 +2116,7 @@ void Item_func_convert_tz::cleanup() } -void Item_date_add_interval::fix_length_and_dec() +bool Item_date_add_interval::fix_length_and_dec() { enum_field_types arg0_field_type; @@ -2121,7 +2125,7 @@ void Item_date_add_interval::fix_length_and_dec() my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), args[0]->type_handler()->name().ptr(), "interval", func_name()); - return; + return TRUE; } /* The field type for the result of an Item_datefunc is defined as @@ -2189,6 +2193,7 @@ void Item_date_add_interval::fix_length_and_dec() fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec); } maybe_null= true; + return FALSE; } @@ -2259,7 +2264,7 @@ void Item_extract::print(String *str, enum_query_type query_type) str->append(')'); } -void Item_extract::fix_length_and_dec() +bool Item_extract::fix_length_and_dec() { maybe_null=1; // If wrong date switch (int_type) { @@ -2285,6 +2290,7 @@ void Item_extract::fix_length_and_dec() case INTERVAL_SECOND_MICROSECOND: set_time_length(8); break; // ssffffff case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */ } + return FALSE; } @@ -2688,7 +2694,7 @@ err: } -void Item_func_add_time::fix_length_and_dec() +bool Item_func_add_time::fix_length_and_dec() { enum_field_types arg0_field_type; @@ -2698,7 +2704,7 @@ void Item_func_add_time::fix_length_and_dec() my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), args[0]->type_handler()->name().ptr(), args[1]->type_handler()->name().ptr(), func_name()); - return; + return TRUE; } /* The field type for the result of an Item_func_add_time function is defined @@ -2734,6 +2740,7 @@ void Item_func_add_time::fix_length_and_dec() fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec); } maybe_null= true; + return FALSE; } /** @@ -3220,7 +3227,7 @@ get_date_time_result_type(const char *format, uint length) } -void Item_func_str_to_date::fix_length_and_dec() +bool Item_func_str_to_date::fix_length_and_dec() { if (!args[0]->type_handler()->is_traditional_type() || !args[1]->type_handler()->is_traditional_type()) @@ -3228,10 +3235,10 @@ void Item_func_str_to_date::fix_length_and_dec() my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), args[0]->type_handler()->name().ptr(), args[1]->type_handler()->name().ptr(), func_name()); - return; + return TRUE; } if (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1)) - return; + return TRUE; if (collation.collation->mbminlen > 1) internal_charset= &my_charset_utf8mb4_general_ci; @@ -3275,6 +3282,7 @@ void Item_func_str_to_date::fix_length_and_dec() } } cached_timestamp_type= mysql_timestamp_type(); + return FALSE; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 30d5018ff36..51ce3bf2988 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -62,9 +62,10 @@ public: Item_func_period_add(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "period_add"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { max_length=6*MY_CHARSET_BIN_MB_MAXLEN; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_period_add>(thd, this); } @@ -79,10 +80,11 @@ public: Item_func_period_diff(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "period_diff"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_period_diff>(thd, this); } @@ -95,11 +97,12 @@ public: Item_func_to_days(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "to_days"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + maybe_null=1; + return FALSE; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); @@ -122,11 +125,12 @@ public: Item_func_to_seconds(THD *thd, Item *a): Item_longlong_func(thd, a) {} longlong val_int(); const char *func_name() const { return "to_seconds"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; fix_char_length(12); maybe_null= 1; + return FALSE; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); @@ -148,11 +152,12 @@ public: Item_func_dayofmonth(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "dayofmonth"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -187,11 +192,12 @@ public: } const char *func_name() const { return "month"; } const Type_handler *type_handler() const { return &type_handler_long; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals= 0; fix_char_length(2); maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -211,7 +217,7 @@ public: Item_func_monthname(THD *thd, Item *a): Item_str_func(thd, a) {} const char *func_name() const { return "monthname"; } String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool check_partition_func_processor(void *int_arg) {return TRUE;} bool check_valid_arguments_processor(void *int_arg) { @@ -232,11 +238,12 @@ public: Item_func_dayofyear(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "dayofyear"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals= 0; fix_char_length(3); maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -255,11 +262,12 @@ public: Item_func_hour(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "hour"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -278,11 +286,12 @@ public: Item_func_minute(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "minute"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -301,11 +310,12 @@ public: Item_func_quarter(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "quarter"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -324,11 +334,12 @@ public: Item_func_second(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "second"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -353,11 +364,12 @@ public: Item_func_week(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "week"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_vcol_func_processor(void *arg) { @@ -385,11 +397,12 @@ public: :Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "yearweek"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -410,11 +423,12 @@ public: const char *func_name() const { return "year"; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=4*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -450,11 +464,12 @@ public: return type_handler()->Item_get_date(this, ltime, fuzzydate); } const Type_handler *type_handler() const { return &type_handler_long; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals= 0; fix_char_length(1); maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -474,7 +489,7 @@ class Item_func_dayname :public Item_func_weekday const char *func_name() const { return "dayname"; } String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_varchar; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool check_partition_func_processor(void *int_arg) {return TRUE;} bool check_vcol_func_processor(void *arg) { @@ -535,9 +550,10 @@ public: return FALSE; return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC); } - void fix_length_and_dec() + bool fix_length_and_dec() { - fix_length_and_dec_generic(arg_count ? args[0]->datetime_precision() : 0); + fix_length_and_dec_generic(arg_count ? args[0]->datetime_precision() : 0); + return FALSE; } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); @@ -558,9 +574,10 @@ public: { return !has_time_args(); } - void fix_length_and_dec() + bool fix_length_and_dec() { fix_length_and_dec_generic(args[0]->time_precision()); + return FALSE; } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); @@ -629,10 +646,11 @@ public: Item_datefunc(THD *thd, Item *a): Item_temporal_func(thd, a) { } Item_datefunc(THD *thd, Item *a, Item *b): Item_temporal_func(thd, a, b) { } const Type_handler *type_handler() const { return &type_handler_newdate; } - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_date(); maybe_null= (arg_count > 0); + return FALSE; } }; @@ -670,7 +688,7 @@ public: Item_func_curtime(THD *thd, uint dec): Item_timefunc(thd), last_query_id(0) { decimals= dec; } bool fix_fields(THD *, Item **); - void fix_length_and_dec() { fix_attributes_time(decimals); } + bool fix_length_and_dec() { fix_attributes_time(decimals); return FALSE; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); /* Abstract method that defines which time zone is used for conversion. @@ -757,7 +775,8 @@ public: Item_func_now(THD *thd, uint dec): Item_datetimefunc(thd), last_query_id(0) { decimals= dec; } bool fix_fields(THD *, Item **); - void fix_length_and_dec() { fix_attributes_datetime(decimals); } + bool fix_length_and_dec() + { fix_attributes_datetime(decimals); return FALSE;} bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)=0; bool check_vcol_func_processor(void *arg) @@ -864,7 +883,7 @@ public: Item_str_func(thd, a, b, c), locale(0), is_time_format(false) {} String *val_str(String *str); const char *func_name() const { return "date_format"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); uint format_length(const String *format); bool eq(const Item *item, bool binary_cmp) const; bool check_vcol_func_processor(void *arg) @@ -897,7 +916,7 @@ class Item_func_from_unixtime :public Item_datetimefunc public: Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {} const char *func_name() const { return "from_unixtime"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); Item *get_copy(THD *thd) { return get_item_copy<Item_func_from_unixtime>(thd, this); } @@ -937,10 +956,11 @@ class Item_func_convert_tz :public Item_datetimefunc Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c): Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {} const char *func_name() const { return "convert_tz"; } - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_datetime(args[0]->datetime_precision()); maybe_null= true; + return FALSE; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void cleanup(); @@ -956,10 +976,11 @@ class Item_func_sec_to_time :public Item_timefunc public: Item_func_sec_to_time(THD *thd, Item *item): Item_timefunc(thd, item) {} bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_time(args[0]->decimals); maybe_null= true; + return FALSE; } const char *func_name() const { return "sec_to_time"; } Item *get_copy(THD *thd) @@ -977,7 +998,7 @@ public: Item_temporal_hybrid_func(thd, a, b),int_type(type_arg), date_sub_interval(neg_arg) {} const char *func_name() const { return "date_add_interval"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; void print(String *str, enum_query_type query_type); @@ -1045,7 +1066,7 @@ class Item_extract :public Item_int_func longlong val_int(); enum Functype functype() const { return EXTRACT_FUNC; } const char *func_name() const { return "extract"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; void print(String *str, enum_query_type query_type); bool check_partition_func_processor(void *int_arg) {return FALSE;} @@ -1125,9 +1146,9 @@ public: fix_length_and_dec_generic(); m_suppress_warning_to_error_escalation= true; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_char_typecast_fix_length_and_dec(this); + return args[0]->type_handler()->Item_char_typecast_fix_length_and_dec(this); } void print(String *str, enum_query_type query_type); bool need_parentheses_in_default() { return true; } @@ -1152,9 +1173,9 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "date"; } const Type_handler *type_handler() const { return &type_handler_newdate; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this); + return args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_date_typecast>(thd, this); } @@ -1170,9 +1191,10 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "time"; } const Type_handler *type_handler() const { return &type_handler_time2; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_time_typecast_fix_length_and_dec(this); + return args[0]->type_handler()-> + Item_time_typecast_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_time_typecast>(thd, this); } @@ -1188,9 +1210,10 @@ public: const char *cast_type() const { return "datetime"; } const Type_handler *type_handler() const { return &type_handler_datetime2; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_datetime_typecast_fix_length_and_dec(this); + return args[0]->type_handler()-> + Item_datetime_typecast_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_datetime_typecast>(thd, this); } @@ -1220,7 +1243,7 @@ public: Item_func_add_time(THD *thd, Item *a, Item *b, bool type_arg, bool neg_arg): Item_temporal_hybrid_func(thd, a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); void print(String *str, enum_query_type query_type); const char *func_name() const { return "add_time"; } @@ -1235,11 +1258,12 @@ class Item_func_timediff :public Item_timefunc public: Item_func_timediff(THD *thd, Item *a, Item *b): Item_timefunc(thd, a, b) {} const char *func_name() const { return "timediff"; } - void fix_length_and_dec() + bool fix_length_and_dec() { uint dec= MY_MAX(args[0]->time_precision(), args[1]->time_precision()); fix_attributes_time(dec); maybe_null= true; + return FALSE; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); Item *get_copy(THD *thd) @@ -1257,10 +1281,11 @@ public: Item_func_maketime(THD *thd, Item *a, Item *b, Item *c): Item_timefunc(thd, a, b, c) {} - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_time(args[2]->decimals); maybe_null= true; + return FALSE; } const char *func_name() const { return "maketime"; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); @@ -1275,11 +1300,12 @@ public: Item_func_microsecond(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "microsecond"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; maybe_null=1; fix_char_length(6); + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -1302,10 +1328,11 @@ public: Item_longlong_func(thd, a, b), int_type(type_arg) {} const char *func_name() const { return "timestampdiff"; } longlong val_int(); - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=0; maybe_null=1; + return FALSE; } virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1327,11 +1354,12 @@ public: {} String *val_str_ascii(String *str); const char *func_name() const { return "get_format"; } - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null= 1; decimals=0; fix_length_and_charset(17, default_charset()); + return FALSE; } virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1353,7 +1381,7 @@ public: {} bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *func_name() const { return "str_to_date"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_str_to_date>(thd, this); } }; diff --git a/sql/item_vers.h b/sql/item_vers.h index 17ad3daa73c..8b9c0e6056c 100644 --- a/sql/item_vers.h +++ b/sql/item_vers.h @@ -38,7 +38,8 @@ public: bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); Item *get_copy(THD *thd) { return get_item_copy<Item_func_trt_ts>(thd, this); } - void fix_length_and_dec() { fix_attributes_datetime(decimals); } + bool fix_length_and_dec() + { fix_attributes_datetime(decimals); return FALSE; } }; class Item_func_trt_id : public Item_longlong_func @@ -69,10 +70,11 @@ public: return NULL; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_int_func::fix_length_and_dec(); + bool res= Item_int_func::fix_length_and_dec(); max_length= 20; + return res; } longlong val_int(); diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index a3a9fc120bc..49ee14bed20 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -86,9 +86,9 @@ Item_window_func::fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); - enum_parsing_place place= thd->lex->current_select->context_analysis_place; - - if (!(place == SELECT_LIST || place == IN_ORDER_BY)) + if (!thd->lex->current_select || + (thd->lex->current_select->context_analysis_place != SELECT_LIST && + thd->lex->current_select->context_analysis_place != IN_ORDER_BY)) { my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0)); return true; @@ -121,7 +121,8 @@ Item_window_func::fix_fields(THD *thd, Item **ref) const_item_cache= false; with_window_func= true; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; max_length= window_func()->max_length; maybe_null= window_func()->maybe_null; @@ -361,7 +362,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref) maybe_null= 1; result_field=0; null_value=1; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; if (check_sum_func(thd, ref)) return TRUE; @@ -441,7 +443,7 @@ bool Item_sum_hybrid_simple::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { DBUG_ASSERT(fixed == 1); if (null_value) - return 0; + return true; bool retval= value->get_date(ltime, fuzzydate); if ((null_value= value->null_value)) DBUG_ASSERT(retval == true); diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index cb85a2c06d1..48851da7d96 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -526,10 +526,11 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count bool add(); const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } void setup_window_func(THD *thd, Window_spec *window_spec); @@ -614,10 +615,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count void update_field() {} const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } Item *get_copy(THD *thd) @@ -820,10 +822,11 @@ public: const Type_handler *type_handler() const {return Type_handler_hybrid_field_type::type_handler();} - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } Item *get_copy(THD *thd) @@ -950,10 +953,11 @@ public: const Type_handler *type_handler() const {return Type_handler_hybrid_field_type::type_handler();} - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } Item *get_copy(THD *thd) @@ -1292,9 +1296,10 @@ public: void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, List<Item> &fields, uint flags); - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = window_func()->decimals; + return FALSE; } const char* func_name() const { return "WF"; } diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index c2b09e4f564..146c5aa57fe 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -236,13 +236,14 @@ public: return str; } enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; collation.collation= pxml->charset(); // To avoid premature evaluation, mark all nodeset functions as non-const. used_tables_cache= RAND_TABLE_BIT; const_item_cache= false; + return FALSE; } const char *func_name() const { return "nodeset"; } bool check_vcol_func_processor(void *arg) @@ -470,7 +471,7 @@ public: Item_nodeset_func(thd, pxml), string_cache(str_arg) { } String *val_raw(String *res) { return string_cache; } - void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; } + bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH;; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_nodeset_context_cache>(thd, this); } }; @@ -484,7 +485,7 @@ public: Item_func_xpath_position(THD *thd, Item *a, String *p): Item_long_func(thd, a), pxml(p) {} const char *func_name() const { return "xpath_position"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int() { String *flt= args[0]->val_raw(&tmp_value); @@ -505,7 +506,7 @@ public: Item_func_xpath_count(THD *thd, Item *a, String *p): Item_long_func(thd, a), pxml(p) {} const char *func_name() const { return "xpath_count"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int() { uint predicate_supplied_context_size; @@ -2749,10 +2750,10 @@ my_xpath_parse(MY_XPATH *xpath, const char *str, const char *strend) } -void Item_xml_str_func::fix_length_and_dec() +bool Item_xml_str_func::fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; - agg_arg_charsets_for_comparison(collation, args, arg_count); + return agg_arg_charsets_for_comparison(collation, args, arg_count); } diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index 33e85ba5628..6846063aab7 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -82,7 +82,7 @@ public: maybe_null= TRUE; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool const_item() const { return const_item_cache && (!nodeset_func || nodeset_func->const_item()); diff --git a/sql/log.cc b/sql/log.cc index afd6c90e386..5019760cdbc 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -44,6 +44,8 @@ #include <my_dir.h> #include <m_ctype.h> // For test_if_number +#include <set_var.h> // for Sys_last_gtid_ptr + #ifdef _WIN32 #include "message.h" #endif @@ -2606,7 +2608,7 @@ bool MYSQL_LOG::open( File file= -1; my_off_t seek_offset; bool is_fifo = false; - int open_flags= O_CREAT | O_BINARY; + int open_flags= O_CREAT | O_BINARY | O_CLOEXEC; DBUG_ENTER("MYSQL_LOG::open"); DBUG_PRINT("enter", ("log_type: %d", (int) log_type_arg)); @@ -3343,7 +3345,7 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, ".index", opt); if ((index_file_nr= mysql_file_open(m_key_file_log_index, index_file_name, - O_RDWR | O_CREAT | O_BINARY, + O_RDWR | O_CREAT | O_BINARY | O_CLOEXEC, MYF(MY_WME))) < 0 || mysql_file_sync(index_file_nr, MYF(MY_WME)) || init_io_cache(&index_file, index_file_nr, @@ -6010,7 +6012,8 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, } if (err) DBUG_RETURN(true); - thd->last_commit_gtid= gtid; + + thd->set_last_commit_gtid(gtid); Gtid_log_event gtid_event(thd, seq_no, domain_id, standalone, LOG_EVENT_SUPPRESS_USE_F, is_transactional, @@ -9007,14 +9010,14 @@ int TC_LOG_MMAP::open(const char *opt_name) tc_log_page_size= my_getpagesize(); fn_format(logname,opt_name,mysql_data_home,"",MY_UNPACK_FILENAME); - if ((fd= mysql_file_open(key_file_tclog, logname, O_RDWR, MYF(0))) < 0) + if ((fd= mysql_file_open(key_file_tclog, logname, O_RDWR | O_CLOEXEC, MYF(0))) < 0) { if (my_errno != ENOENT) goto err; if (using_heuristic_recover()) return 1; if ((fd= mysql_file_create(key_file_tclog, logname, CREATE_MODE, - O_RDWR, MYF(MY_WME))) < 0) + O_RDWR | O_CLOEXEC, MYF(MY_WME))) < 0) goto err; inited=1; file_length= opt_tc_log_size; diff --git a/sql/log_event.cc b/sql/log_event.cc index 7a6d0a1821b..c550adea26b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5550,22 +5550,6 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, else thd->variables.collation_database= thd->db_charset; - { - const CHARSET_INFO *cs= thd->charset(); - /* - We cannot ask for parsing a statement using a character set - without state_maps (parser internal data). - */ - if (!cs->state_map) - { - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, - ER_THD(thd, ER_SLAVE_FATAL_ERROR), - "character_set cannot be parsed"); - thd->is_slave_error= true; - goto end; - } - } - /* Record any GTID in the same transaction, so slave state is transactionally consistent. @@ -13155,8 +13139,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, } // Handle INSERT. - // Set vers fields when replicating from not system-versioned table. - if (m_type == WRITE_ROWS_EVENT_V1 && table->versioned(VERS_TIMESTAMP)) + if (table->versioned(VERS_TIMESTAMP)) { ulong sec_part; bitmap_set_bit(table->read_set, table->vers_start_field()->field_index); @@ -13637,6 +13620,16 @@ void issue_long_find_row_warning(Log_event_type type, } +/* + HA_ERR_KEY_NOT_FOUND is a fatal error normally, but it's an expected + error in speculate optimistic mode, so use something non-fatal instead +*/ +static int row_not_found_error(rpl_group_info *rgi) +{ + return rgi->speculation != rpl_group_info::SPECULATE_OPTIMISTIC + ? HA_ERR_KEY_NOT_FOUND : HA_ERR_RECORD_CHANGED; +} + /** Locate the current row in event's table. @@ -13734,14 +13727,12 @@ int Rows_log_event::find_row(rpl_group_info *rgi) int error; DBUG_PRINT("info",("locating record using primary key (position)")); - if (!table->file->inited && - (error= table->file->ha_rnd_init_with_error(0))) - DBUG_RETURN(error); - error= table->file->ha_rnd_pos_by_record(table->record[0]); if (unlikely(error)) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); + if (error == HA_ERR_KEY_NOT_FOUND) + error= row_not_found_error(rgi); table->file->print_error(error, MYF(0)); } DBUG_RETURN(error); @@ -13807,6 +13798,8 @@ int Rows_log_event::find_row(rpl_group_info *rgi) HA_READ_KEY_EXACT)))) { DBUG_PRINT("info",("no record matching the key found in the table")); + if (error == HA_ERR_KEY_NOT_FOUND) + error= row_not_found_error(rgi); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); goto end; diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 0483c7f5fbf..ce40b5edc2c 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -198,7 +198,7 @@ int main(int argc, char **argv) die("database creation failed"); } - printf("Creation of the database was successfull"); + printf("Creation of the database was successful"); return 0; } diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index 599f4a40ea0..1a3df4f5536 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -146,6 +146,11 @@ static void die(const char *fmt, ...) exit(1); } +#define WRITE_LOG(fmt,...) {\ + char log_buf[1024]; \ + snprintf(log_buf,sizeof(log_buf), fmt, __VA_ARGS__);\ + WriteFile(logfile_handle,log_buf, (DWORD)strlen(log_buf), 0 , 0);\ +} /* spawn-like function to run subprocesses. @@ -187,17 +192,22 @@ static intptr_t run_tool(int wait_flag, const char *program,...) { char tmpdir[FN_REFLEN]; GetTempPath(FN_REFLEN, tmpdir); - sprintf_s(logfile_path, "%s\\mysql_upgrade_service.%s.log", tmpdir, + sprintf_s(logfile_path, "%smysql_upgrade_service.%s.log", tmpdir, opt_service); - logfile_handle= CreateFile(logfile_path, GENERIC_WRITE, FILE_SHARE_READ, - NULL, TRUNCATE_EXISTING, 0, NULL); - if (!logfile_handle) + SECURITY_ATTRIBUTES attr= {0}; + attr.nLength= sizeof(SECURITY_ATTRIBUTES); + attr.bInheritHandle= TRUE; + logfile_handle= CreateFile(logfile_path, FILE_APPEND_DATA, + FILE_SHARE_READ|FILE_SHARE_WRITE, &attr, CREATE_ALWAYS, 0, NULL); + if (logfile_handle == INVALID_HANDLE_VALUE) { die("Cannot open log file %s, windows error %u", logfile_path, GetLastError()); } } + WRITE_LOG("Executing %s\r\n", cmdline); + /* Start child process */ STARTUPINFO si= {0}; si.cb= sizeof(si); @@ -458,7 +468,7 @@ int main(int argc, char **argv) log("Phase 3/8: Starting mysqld for upgrade"); mysqld_process= (HANDLE)run_tool(P_NOWAIT, mysqld_path, defaults_file_param, "--skip-networking", "--skip-grant-tables", - "--enable-named-pipe", socket_param, NULL); + "--enable-named-pipe", socket_param,"--skip-slave-start", NULL); if (mysqld_process == INVALID_HANDLE_VALUE) { diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 0d3aa12465d..576ef5009b5 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -47,6 +47,12 @@ #include "probes_mysql.h" #include "proxy_protocol.h" +#ifdef EMBEDDED_LIBRARY +#undef MYSQL_SERVER +#undef MYSQL_CLIENT +#define MYSQL_CLIENT +#endif /*EMBEDDED_LIBRARY */ + /* to reduce the number of ifdef's in the code */ diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 6f761c9c5d3..6879eb6bdcf 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -6528,6 +6528,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, if (ror_intersect_add(intersect, cpk_scan, TRUE) && (intersect->total_cost < min_cost)) intersect_best= intersect; //just set pointer here + else + cpk_scan= 0; // Don't use cpk_scan } else cpk_scan= 0; // Don't use cpk_scan diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 5051c26f4a3..ba57d9d3ca4 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -6291,6 +6291,7 @@ bool JOIN::choose_tableless_subquery_plan() functions produce empty subquery result. There is no need to further rewrite the subquery because it will not be executed at all. */ + exec_const_cond= 0; return FALSE; } @@ -6322,7 +6323,7 @@ bool JOIN::choose_tableless_subquery_plan() tmp_having= having; } } - exec_const_cond= conds; + exec_const_cond= zero_result_cause ? 0 : conds; return FALSE; } diff --git a/sql/set_var.cc b/sql/set_var.cc index c9dfeb3e211..8ab892068b3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -454,6 +454,22 @@ void sys_var::do_deprecated_warning(THD *thd) @retval true on error, false otherwise (warning or ok) */ + + +bool throw_bounds_warning(THD *thd, const char *name,const char *v) +{ + if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) + { + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, v); + return true; + } + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), name, v); + return false; +} + + bool throw_bounds_warning(THD *thd, const char *name, bool fixed, bool is_unsigned, longlong v) { @@ -471,9 +487,7 @@ bool throw_bounds_warning(THD *thd, const char *name, my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf); return true; } - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_TRUNCATED_WRONG_VALUE, - ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), name, buf); + return throw_bounds_warning(thd, name, buf); } return false; } @@ -491,9 +505,7 @@ bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v) my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf); return true; } - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_TRUNCATED_WRONG_VALUE, - ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), name, buf); + return throw_bounds_warning(thd, name, buf); } return false; } @@ -1006,24 +1018,12 @@ int set_var_collation_client::update(THD *thd) #ifndef EMBEDDED_LIBRARY if (thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->is_enabled()) { - sys_var *svar; - mysql_mutex_lock(&LOCK_plugin); - if ((svar= find_sys_var_ex(thd, "character_set_client", - sizeof("character_set_client") - 1, - false, true))) - thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> - mark_as_changed(thd, (LEX_CSTRING*)svar); - if ((svar= find_sys_var_ex(thd, "character_set_results", - sizeof("character_set_results") - 1, - false, true))) - thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> - mark_as_changed(thd, (LEX_CSTRING*)svar); - if ((svar= find_sys_var_ex(thd, "character_set_connection", - sizeof("character_set_connection") - 1, - false, true))) - thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> - mark_as_changed(thd, (LEX_CSTRING*)svar); - mysql_mutex_unlock(&LOCK_plugin); + thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> + mark_as_changed(thd, (LEX_CSTRING*)Sys_character_set_client_ptr); + thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> + mark_as_changed(thd, (LEX_CSTRING*)Sys_character_set_results_ptr); + thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> + mark_as_changed(thd, (LEX_CSTRING*)Sys_character_set_connection_ptr); } thd->session_tracker.mark_as_changed(thd, SESSION_STATE_CHANGE_TRACKER, NULL); #endif //EMBEDDED_LIBRARY diff --git a/sql/set_var.h b/sql/set_var.h index 82afb3ceea6..6097b28e76f 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -244,6 +244,12 @@ protected: uchar *global_var_ptr() { return ((uchar*)&global_system_variables) + offset; } + void *max_var_ptr() + { + return scope() == SESSION ? (((uchar*)&max_system_variables) + offset) : + 0; + } + friend class Session_sysvars_tracker; friend class Session_tracker; }; @@ -427,7 +433,9 @@ bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode, LEX_CSTRING *ls); int default_regex_flags_pcre(const THD *thd); -extern sys_var *Sys_autocommit_ptr; +extern sys_var *Sys_autocommit_ptr, *Sys_last_gtid_ptr, + *Sys_character_set_client_ptr, *Sys_character_set_connection_ptr, + *Sys_character_set_results_ptr; CHARSET_INFO *get_old_charset_by_name(const char *old_name); @@ -435,6 +443,7 @@ int sys_var_init(); uint sys_var_elements(); int sys_var_add_options(DYNAMIC_ARRAY *long_options, int parse_flags); void sys_var_end(void); +bool check_has_super(sys_var *self, THD *thd, set_var *var); plugin_ref *resolve_engine_list(THD *thd, const char *str_arg, size_t str_arg_len, bool error_on_unknown_engine, bool temp_copy); void free_engine_list(plugin_ref *list); @@ -443,4 +452,3 @@ plugin_ref *temp_copy_engine_list(THD *thd, plugin_ref *list); char *pretty_print_engine_list(THD *thd, plugin_ref *list); #endif - diff --git a/sql/slave.cc b/sql/slave.cc index 275db6165e9..bb1300d36e6 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -5663,7 +5663,7 @@ err_during_init: */ if (WSREP_ON && wsrep_node_dropped && wsrep_restart_slave) { - if (wsrep_ready) + if (wsrep_ready_get()) { WSREP_INFO("Slave error due to node temporarily non-primary" "SQL slave will continue"); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 12fb63925ce..0d5e1abfdf2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1379,7 +1379,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) /* Only pop cursors when we're done with group aggregate running. */ if (m_chistics.agg_type != GROUP_AGGREGATE || (m_chistics.agg_type == GROUP_AGGREGATE && thd->spcont->quit_func)) - thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error + thd->spcont->pop_all_cursors(thd); // To avoid memory leaks after an error /* Restore all saved */ if (m_chistics.agg_type == GROUP_AGGREGATE) @@ -2709,7 +2709,6 @@ sp_head::restore_thd_mem_root(THD *thd) Item *flist= free_list; // The old list set_query_arena(thd); // Get new free_list and mem_root state= STMT_INITIALIZED_FOR_SP; - is_stored_procedure= true; DBUG_PRINT("info", ("mem_root %p returned from thd mem root %p", &mem_root, &thd->mem_root)); @@ -4001,7 +4000,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_hpush_jump::execute"); - int ret= thd->spcont->push_handler(m_handler, m_ip + 1); + int ret= thd->spcont->push_handler(this); *nextp= m_dest; @@ -4160,11 +4159,13 @@ sp_instr_cpush::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_cpush::execute"); - int ret= thd->spcont->push_cursor(thd, &m_lex_keeper); + sp_cursor::reset(thd, &m_lex_keeper); + m_lex_keeper.disable_query_cache(); + thd->spcont->push_cursor(this); *nextp= m_ip+1; - DBUG_RETURN(ret); + DBUG_RETURN(false); } @@ -4198,7 +4199,7 @@ int sp_instr_cpop::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_cpop::execute"); - thd->spcont->pop_cursors(m_count); + thd->spcont->pop_cursors(thd, m_count); *nextp= m_ip+1; DBUG_RETURN(0); } @@ -4479,7 +4480,7 @@ void sp_instr_cursor_copy_struct::print(String *str) { sp_variable *var= m_ctx->find_variable(m_var); - const LEX_CSTRING *name= m_lex_keeper.cursor_name(); + const LEX_CSTRING *name= m_ctx->find_cursor(m_cursor); str->append(STRING_WITH_LEN("cursor_copy_struct ")); str->append(name); str->append(' '); @@ -4974,7 +4975,8 @@ bool sp_head::add_for_loop_open_cursor(THD *thd, sp_pcontext *spcont, sp_instr *instr_copy_struct= new (thd->mem_root) sp_instr_cursor_copy_struct(instructions(), - spcont, pcursor->lex(), + spcont, coffset, + pcursor->lex(), index->offset); if (instr_copy_struct == NULL || add_instr(instr_copy_struct)) return true; diff --git a/sql/sp_head.h b/sql/sp_head.h index 5c9183f79ab..3ec8bba1b50 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1001,12 +1001,10 @@ public: class sp_lex_cursor: public sp_lex_local, public Query_arena { - LEX_CSTRING m_cursor_name; public: sp_lex_cursor(THD *thd, const LEX *oldlex, MEM_ROOT *mem_root_arg) :sp_lex_local(thd, oldlex), - Query_arena(mem_root_arg, STMT_INITIALIZED_FOR_SP), - m_cursor_name(null_clex_str) + Query_arena(mem_root_arg, STMT_INITIALIZED_FOR_SP) { } sp_lex_cursor(THD *thd, const LEX *oldlex) :sp_lex_local(thd, oldlex), @@ -1034,8 +1032,6 @@ public: thd->free_list= NULL; return false; } - const LEX_CSTRING *cursor_name() const { return &m_cursor_name; } - void set_cursor_name(const LEX_CSTRING *name) { m_cursor_name= *name; } }; @@ -1210,10 +1206,6 @@ public: m_lex->safe_to_cache_query= 0; } - const LEX_CSTRING *cursor_name() const - { - return m_lex->cursor_name(); - } private: LEX *m_lex; @@ -1682,8 +1674,6 @@ public: { return m_handler; } private: - -private: /// Handler. sp_handler *m_handler; @@ -1762,7 +1752,8 @@ private: /** This is DECLARE CURSOR */ -class sp_instr_cpush : public sp_instr +class sp_instr_cpush : public sp_instr, + public sp_cursor { sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */ void operator=(sp_instr_cpush &); @@ -1861,11 +1852,14 @@ class sp_instr_cursor_copy_struct: public sp_instr sp_instr_cursor_copy_struct(const sp_instr_cursor_copy_struct &); void operator=(sp_instr_cursor_copy_struct &); sp_lex_keeper m_lex_keeper; + uint m_cursor; uint m_var; public: - sp_instr_cursor_copy_struct(uint ip, sp_pcontext *ctx, + sp_instr_cursor_copy_struct(uint ip, sp_pcontext *ctx, uint coffs, sp_lex_cursor *lex, uint voffs) - : sp_instr(ip, ctx), m_lex_keeper(lex, FALSE), m_var(voffs) + : sp_instr(ip, ctx), m_lex_keeper(lex, FALSE), + m_cursor(coffs), + m_var(voffs) {} virtual ~sp_instr_cursor_copy_struct() {} diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 6166d1d9615..24777abe1c3 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -425,44 +425,32 @@ bool sp_rcontext::set_return_value(THD *thd, Item **return_value_item) } -bool sp_rcontext::push_cursor(THD *thd, sp_lex_keeper *lex_keeper) +void sp_rcontext::push_cursor(sp_cursor *c) { - /* - We should create cursors in the callers arena, as - it could be (and usually is) used in several instructions. - */ - sp_cursor *c= new (callers_arena->mem_root) sp_cursor(thd, lex_keeper); + m_cstack[m_ccount++]= c; +} - if (c == NULL) - return true; - m_cstack[m_ccount++]= c; - return false; +void sp_rcontext::pop_cursor(THD *thd) +{ + DBUG_ASSERT(m_ccount > 0); + if (m_cstack[m_ccount - 1]->is_open()) + m_cstack[m_ccount - 1]->close(thd); + m_ccount--; } -void sp_rcontext::pop_cursors(size_t count) +void sp_rcontext::pop_cursors(THD *thd, size_t count) { DBUG_ASSERT(m_ccount >= count); - while (count--) - delete m_cstack[--m_ccount]; + pop_cursor(thd); } -bool sp_rcontext::push_handler(sp_handler *handler, uint first_ip) +bool sp_rcontext::push_handler(sp_instr_hpush_jump *entry) { - /* - We should create handler entries in the callers arena, as - they could be (and usually are) used in several instructions. - */ - sp_handler_entry *he= - new (callers_arena->mem_root) sp_handler_entry(handler, first_ip); - - if (he == NULL) - return true; - - return m_handlers.append(he); + return m_handlers.append(entry); } @@ -550,12 +538,12 @@ bool sp_rcontext::handle_sql_condition(THD *thd, DBUG_ASSERT(found_condition); - sp_handler_entry *handler_entry= NULL; + sp_instr_hpush_jump *handler_entry= NULL; for (size_t i= 0; i < m_handlers.elements(); ++i) { - sp_handler_entry *h= m_handlers.at(i); + sp_instr_hpush_jump *h= m_handlers.at(i); - if (h->handler == found_handler) + if (h->get_handler() == found_handler) { handler_entry= h; break; @@ -584,7 +572,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd, // Mark active conditions so that they can be deleted when the handler exits. da->mark_sql_conditions_for_removal(); - uint continue_ip= handler_entry->handler->type == sp_handler::CONTINUE ? + uint continue_ip= handler_entry->get_handler()->type == sp_handler::CONTINUE ? cur_spi->get_cont_dest() : 0; /* End aborted result set. */ @@ -603,7 +591,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd, new (callers_arena->mem_root) Handler_call_frame(cond_info, continue_ip); m_handler_call_stack.append(frame); - *ip= handler_entry->first_ip; + *ip= handler_entry->m_ip + 1; DBUG_RETURN(true); } @@ -733,22 +721,6 @@ bool sp_rcontext::set_case_expr(THD *thd, int case_expr_id, /////////////////////////////////////////////////////////////////////////// -sp_cursor::sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper): - result(thd_arg), - m_lex_keeper(lex_keeper), - server_side_cursor(NULL), - m_fetch_count(0), - m_row_count(0), - m_found(false) -{ - /* - currsor can't be stored in QC, so we should prevent opening QC for - try to write results which are absent. - */ - lex_keeper->disable_query_cache(); -} - - /* Open an SP cursor @@ -811,8 +783,7 @@ int sp_cursor::close(THD *thd) MYF(0)); return -1; } - m_row_count= m_fetch_count= 0; - m_found= false; + sp_cursor_statistics::reset(); destroy(); return 0; } @@ -851,9 +822,15 @@ int sp_cursor::fetch(THD *thd, List<sp_variable> *vars, bool error_on_no_data) result.set_spvar_list(vars); + DBUG_ASSERT(!thd->is_error()); + /* Attempt to fetch one row */ if (server_side_cursor->is_open()) + { server_side_cursor->fetch(1); + if (thd->is_error()) + return -1; // e.g. data type conversion failed + } /* If the cursor was pointing after the last row, the fetch will diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 33d76e1c85a..b02ba14b99b 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -31,6 +31,7 @@ class sp_cursor; class sp_lex_keeper; class sp_instr_cpush; +class sp_instr_hpush_jump; class Query_arena; class sp_head; class Item_cache; @@ -87,27 +88,6 @@ private: sp_rcontext(const sp_rcontext &); void operator=(sp_rcontext &); -private: - /// This is an auxillary class to store entering instruction pointer for an - /// SQL-handler. - class sp_handler_entry : public Sql_alloc - { - public: - /// Handler definition (from parsing context). - const sp_handler *handler; - - /// Instruction pointer to the first instruction. - uint first_ip; - - /// The constructor. - /// - /// @param _handler sp_handler object. - /// @param _first_ip first instruction pointer. - sp_handler_entry(const sp_handler *_handler, uint _first_ip) - :handler(_handler), first_ip(_first_ip) - { } - }; - public: /// This class stores basic information about SQL-condition, such as: /// - SQL error code; @@ -235,18 +215,16 @@ public: // SQL-handlers. ///////////////////////////////////////////////////////////////////////// - /// Create a new sp_handler_entry instance and push it to the handler call - /// stack. + /// Push an sp_instr_hpush_jump instance to the handler call stack. /// - /// @param handler SQL-handler object. - /// @param first_ip First instruction pointer of the handler. + /// @param entry The condition handler entry /// /// @return error flag. /// @retval false on success. /// @retval true on error. - bool push_handler(sp_handler *handler, uint first_ip); + bool push_handler(sp_instr_hpush_jump *entry); - /// Pop and delete given number of sp_handler_entry instances from the handler + /// Pop and delete given number of instances from the handler /// call stack. /// /// @param count Number of handler entries to pop & delete. @@ -293,23 +271,20 @@ public: // Cursors. ///////////////////////////////////////////////////////////////////////// - /// Create a new sp_cursor instance and push it to the cursor stack. + /// Push a cursor to the cursor stack. /// - /// @param lex_keeper SP-instruction execution helper. - /// @param i Cursor-push instruction. + /// @param cursor The cursor /// - /// @return error flag. - /// @retval false on success. - /// @retval true on error. - bool push_cursor(THD *thd, sp_lex_keeper *lex_keeper); + void push_cursor(sp_cursor *cur); + void pop_cursor(THD *thd); /// Pop and delete given number of sp_cursor instance from the cursor stack. /// /// @param count Number of cursors to pop & delete. - void pop_cursors(size_t count); + void pop_cursors(THD *thd, size_t count); - void pop_all_cursors() - { pop_cursors(m_ccount); } + void pop_all_cursors(THD *thd) + { pop_cursors(thd, m_ccount); } sp_cursor *get_cursor(uint i) const { return m_cstack[i]; } @@ -414,7 +389,7 @@ private: bool m_in_sub_stmt; /// Stack of visible handlers. - Dynamic_array<sp_handler_entry *> m_handlers; + Dynamic_array<sp_instr_hpush_jump *> m_handlers; /// Stack of caught SQL conditions. Dynamic_array<Handler_call_frame *> m_handler_call_stack; @@ -429,74 +404,4 @@ private: Bounds_checked_array<Item_cache *> m_case_expr_holders; }; // class sp_rcontext : public Sql_alloc -/////////////////////////////////////////////////////////////////////////// -// sp_cursor declaration. -/////////////////////////////////////////////////////////////////////////// - -class Server_side_cursor; -typedef class st_select_lex_unit SELECT_LEX_UNIT; - -/* A mediator between stored procedures and server side cursors */ - -class sp_cursor : public Sql_alloc -{ -private: - /// An interceptor of cursor result set used to implement - /// FETCH <cname> INTO <varlist>. - class Select_fetch_into_spvars: public select_result_interceptor - { - List<sp_variable> *spvar_list; - uint field_count; - bool send_data_to_variable_list(List<sp_variable> &vars, List<Item> &items); - public: - Select_fetch_into_spvars(THD *thd_arg): select_result_interceptor(thd_arg) {} - uint get_field_count() { return field_count; } - void set_spvar_list(List<sp_variable> *vars) { spvar_list= vars; } - - virtual bool send_eof() { return FALSE; } - virtual int send_data(List<Item> &items); - virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u); -}; - -public: - sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper); - - virtual ~sp_cursor() - { destroy(); } - - sp_lex_keeper *get_lex_keeper() { return m_lex_keeper; } - - int open(THD *thd); - - int open_view_structure_only(THD *thd); - - int close(THD *thd); - - my_bool is_open() - { return MY_TEST(server_side_cursor); } - - bool found() const - { return m_found; } - - ulonglong row_count() const - { return m_row_count; } - - ulonglong fetch_count() const - { return m_fetch_count; } - - int fetch(THD *, List<sp_variable> *vars, bool error_on_no_data); - - bool export_structure(THD *thd, Row_definition_list *list); - -private: - Select_fetch_into_spvars result; - sp_lex_keeper *m_lex_keeper; - Server_side_cursor *server_side_cursor; - ulonglong m_fetch_count; // Number of FETCH commands since last OPEN - ulonglong m_row_count; // Number of successful FETCH since last OPEN - bool m_found; // If last FETCH fetched a row - void destroy(); - -}; // class sp_cursor : public Sql_alloc - #endif /* _SP_RCONTEXT_H_ */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index aec15d38847..d00ee3e07ef 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3766,7 +3766,8 @@ bool hostname_requires_resolving(const char *hostname) void set_authentication_plugin_from_password(const User_table& user_table, const char* password, size_t password_length) { - if (password_length == SCRAMBLED_PASSWORD_CHAR_LENGTH) + if (password_length == SCRAMBLED_PASSWORD_CHAR_LENGTH || + password_length == 0) { user_table.plugin()->store(native_password_plugin_name.str, native_password_plugin_name.length, @@ -3821,13 +3822,16 @@ static bool update_user_table(THD *thd, const User_table& user_table, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); - /* If the password column is missing, we use the - authentication_string column. */ - if (user_table.password()) - user_table.password()->store(new_password, new_password_len, system_charset_info); - else + + if (user_table.plugin()) + { set_authentication_plugin_from_password(user_table, new_password, new_password_len); + new_password_len= 0; + } + + if (user_table.password()) + user_table.password()->store(new_password, new_password_len, system_charset_info); if (unlikely(error= table->file->ha_update_row(table->record[1], @@ -7540,7 +7544,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, INSERT_ACL : SELECT_ACL); } - if (tl->with || + if (tl->with || !tl->db.str || (tl->select_lex && (tl->with= tl->select_lex->find_table_def_in_with_clauses(tl)))) continue; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index bf78bd12192..a96b0a5a32b 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - Copyright (c) 2016, MariaDB Corporation + Copyright (c) 2016, 2018, 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 @@ -209,6 +209,35 @@ bool Alter_info::supports_lock(THD *thd, enum_alter_inplace_result result, return false; } +bool Alter_info::vers_prohibited(THD *thd) const +{ + if (thd->slave_thread || + thd->variables.vers_alter_history != VERS_ALTER_HISTORY_ERROR) + { + return false; + } + if (flags & ( + ALTER_PARSER_ADD_COLUMN | + ALTER_PARSER_DROP_COLUMN | + ALTER_CHANGE_COLUMN | + ALTER_COLUMN_ORDER)) + { + return true; + } + if (flags & ALTER_ADD_INDEX) + { + List_iterator_fast<Key> key_it(const_cast<List<Key> &>(key_list)); + Key *key; + while ((key= key_it++)) + { + if (key->type == Key::PRIMARY || key->type == Key::UNIQUE) + return true; + } + } + return false; +} + + Alter_table_ctx::Alter_table_ctx() : datetime_field(NULL), error_if_not_empty(false), tables_opened(0), diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 268dbc43abd..108b98afdd7 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -32,14 +32,7 @@ public: enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; - bool data_modifying() const - { - return flags & ( - ALTER_PARSER_ADD_COLUMN | - ALTER_PARSER_DROP_COLUMN | - ALTER_CHANGE_COLUMN | - ALTER_COLUMN_ORDER); - } + bool vers_prohibited(THD *thd) const; /** The different values of the ALGORITHM clause. diff --git a/sql/sql_analyze_stmt.cc b/sql/sql_analyze_stmt.cc index 2c09772bd66..b66d69334f0 100644 --- a/sql/sql_analyze_stmt.cc +++ b/sql/sql_analyze_stmt.cc @@ -45,7 +45,7 @@ void Filesort_tracker::print_json_members(Json_writer *writer) else if (r_limit == 0) writer->add_str(varied_str); else - writer->add_ll((longlong) rint(r_limit/get_r_loops())); + writer->add_ll((longlong) rint(r_limit)); } writer->add_member("r_used_priority_queue"); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 094a77e74a1..6aafdcd7a71 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1572,6 +1572,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) DBUG_RETURN(true); } + if (!table_list->db.str) + { + my_error(ER_NO_DB_ERROR, MYF(0)); + DBUG_RETURN(true); + } + key_length= get_table_def_key(table_list, &key); /* @@ -5585,6 +5591,9 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, si column reference. See create_view_field() for details. */ item= nj_col->create_item(thd); + if (!item) + DBUG_RETURN(NULL); + /* *ref != NULL means that *ref contains the item that we need to replace. If the item was aliased by the user, set the alias to diff --git a/sql/sql_class.cc b/sql/sql_class.cc index df9c60ba6f0..77bc6494732 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -519,100 +519,6 @@ extern "C" } -/** - Dumps a text description of a thread, its security context - (user, host) and the current query. - - @param thd thread context - @param buffer pointer to preferred result buffer - @param length length of buffer - @param max_query_len how many chars of query to copy (0 for all) - - @return Pointer to string -*/ - -extern "C" -char *thd_get_error_context_description(THD *thd, char *buffer, - unsigned int length, - unsigned int max_query_len) -{ - String str(buffer, length, &my_charset_latin1); - const Security_context *sctx= &thd->main_security_ctx; - char header[256]; - size_t len; - - /* - The pointers thd->query and thd->proc_info might change since they are - being modified concurrently. This is acceptable for proc_info since its - values doesn't have to very accurate and the memory it points to is static, - but we need to attempt a snapshot on the pointer values to avoid using NULL - values. The pointer to thd->query however, doesn't point to static memory - and has to be protected by thd->LOCK_thd_data or risk pointing to - uninitialized memory. - */ - const char *proc_info= thd->proc_info; - - len= my_snprintf(header, sizeof(header), - "MySQL thread id %u, OS thread handle %lu, query id %llu", - (uint)thd->thread_id, (ulong) thd->real_id, (ulonglong) thd->query_id); - str.length(0); - str.append(header, len); - - if (sctx->host) - { - str.append(' '); - str.append(sctx->host); - } - - if (sctx->ip) - { - str.append(' '); - str.append(sctx->ip); - } - - if (sctx->user) - { - str.append(' '); - str.append(sctx->user); - } - - if (proc_info) - { - str.append(' '); - str.append(proc_info); - } - - /* Don't wait if LOCK_thd_data is used as this could cause a deadlock */ - if (!mysql_mutex_trylock(&thd->LOCK_thd_data)) - { - if (thd->query()) - { - if (max_query_len < 1) - len= thd->query_length(); - else - len= MY_MIN(thd->query_length(), max_query_len); - str.append('\n'); - str.append(thd->query(), len); - } - mysql_mutex_unlock(&thd->LOCK_thd_data); - } - - if (str.c_ptr_safe() == buffer) - return buffer; - - /* - We have to copy the new string to the destination buffer because the string - was reallocated to a larger buffer to be able to fit. - */ - DBUG_ASSERT(buffer != NULL); - length= MY_MIN(str.length(), length-1); - memcpy(buffer, str.c_ptr_quick(), length); - /* Make sure that the new string is null terminated */ - buffer[length]= '\0'; - return buffer; -} - - #if MARIA_PLUGIN_INTERFACE_VERSION < 0x0200 /** TODO: This function is for API compatibility, remove it eventually. @@ -1305,7 +1211,7 @@ void THD::init(bool skip_lock) bzero((char *) &org_status_var, sizeof(org_status_var)); status_in_global= 0; start_bytes_received= 0; - last_commit_gtid.seq_no= 0; + m_last_commit_gtid.seq_no= 0; last_stmt= NULL; /* Reset status of last insert id */ arg_of_last_insert_id_function= FALSE; @@ -3809,7 +3715,6 @@ void Query_arena::set_query_arena(Query_arena *set) mem_root= set->mem_root; free_list= set->free_list; state= set->state; - is_stored_procedure= set->is_stored_procedure; } @@ -7353,6 +7258,21 @@ THD::signal_wakeup_ready() mysql_cond_signal(&COND_wakeup_ready); } +void THD::set_last_commit_gtid(rpl_gtid >id) +{ +#ifndef EMBEDDED_LIBRARY + bool changed_gtid= (m_last_commit_gtid.seq_no != gtid.seq_no); +#endif + m_last_commit_gtid= gtid; +#ifndef EMBEDDED_LIBRARY + if (changed_gtid && + session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)->is_enabled()) + { + session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)-> + mark_as_changed(this, (LEX_CSTRING*)Sys_last_gtid_ptr); + } +#endif +} void wait_for_commit::reinit() diff --git a/sql/sql_class.h b/sql/sql_class.h index 5adb5bf3823..359d5f93a1f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -974,10 +974,6 @@ public: enum_state state; -protected: - friend class sp_head; - bool is_stored_procedure; - public: /* We build without RTTI, so dynamic_cast can't be used. */ enum Type @@ -986,8 +982,7 @@ public: }; Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) : - free_list(0), mem_root(mem_root_arg), state(state_arg), - is_stored_procedure(state_arg == STMT_INITIALIZED_FOR_SP ? true : false) + free_list(0), mem_root(mem_root_arg), state(state_arg) { INIT_ARENA_DBUG_INFO; } /* This constructor is used only when Query_arena is created as @@ -3216,6 +3211,7 @@ public: query_id_t first_query_id; } binlog_evt_union; + mysql_cond_t COND_wsrep_thd; /** Internal parser state. Note that since the parser is not re-entrant, we keep only one parser @@ -3674,6 +3670,10 @@ public: lex_str->length= length; return lex_str; } + LEX_CSTRING *make_clex_string(const LEX_CSTRING from) + { + return make_clex_string(from.str, from.length); + } // Allocate LEX_STRING for character set conversion bool alloc_lex_string(LEX_STRING *dst, size_t length) @@ -4180,18 +4180,33 @@ public: { if (db.str == NULL) { - my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); - return TRUE; + /* + No default database is set. In this case if it's guaranteed that + no CTE can be used in the statement then we can throw an error right + now at the parser stage. Otherwise the decision about throwing such + a message must be postponed until a post-parser stage when we are able + to resolve all CTE names as we don't need this message to be thrown + for any CTE references. + */ + if (!lex->with_clauses_list) + { + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); + return TRUE; + } + /* This will allow to throw an error later for non-CTE references */ + to->str= NULL; + to->length= 0; + return FALSE; } + to->str= strmake(db.str, db.length); to->length= db.length; return to->str == NULL; /* True on error */ } /* Get db name or "". Use for printing current db */ const char *get_db() - { - return db.str ? db.str : ""; - } + { return safe_str(db.str); } + thd_scheduler event_scheduler; public: @@ -4558,7 +4573,13 @@ public: The GTID assigned to the last commit. If no GTID was assigned to any commit so far, this is indicated by last_commit_gtid.seq_no == 0. */ - rpl_gtid last_commit_gtid; +private: + rpl_gtid m_last_commit_gtid; + +public: + rpl_gtid get_last_commit_gtid() { return m_last_commit_gtid; } + void set_last_commit_gtid(rpl_gtid >id); + LF_PINS *tdc_hash_pins; LF_PINS *xid_hash_pins; @@ -4909,6 +4930,7 @@ public: */ virtual int send_data(List<Item> &items)=0; virtual ~select_result_sink() {}; + void reset(THD *thd_arg) { thd= thd_arg; } }; @@ -4986,6 +5008,11 @@ public: */ virtual void cleanup(); void set_thd(THD *thd_arg) { thd= thd_arg; } + void reset(THD *thd_arg) + { + select_result_sink::reset(thd_arg); + unit= NULL; + } #ifdef EMBEDDED_LIBRARY virtual void begin_dataset() {} #else @@ -5082,11 +5109,114 @@ public: elsewhere. (this is used by ANALYZE $stmt feature). */ void disable_my_ok_calls() { suppress_my_ok= true; } + void reset(THD *thd_arg) + { + select_result::reset(thd_arg); + suppress_my_ok= false; + } protected: bool suppress_my_ok; }; +class sp_cursor_statistics +{ +protected: + ulonglong m_fetch_count; // Number of FETCH commands since last OPEN + ulonglong m_row_count; // Number of successful FETCH since last OPEN + bool m_found; // If last FETCH fetched a row +public: + sp_cursor_statistics() + :m_fetch_count(0), + m_row_count(0), + m_found(false) + { } + bool found() const + { return m_found; } + + ulonglong row_count() const + { return m_row_count; } + + ulonglong fetch_count() const + { return m_fetch_count; } + void reset() { *this= sp_cursor_statistics(); } +}; + + +/* A mediator between stored procedures and server side cursors */ +class sp_lex_keeper; +class sp_cursor: public sp_cursor_statistics +{ +private: + /// An interceptor of cursor result set used to implement + /// FETCH <cname> INTO <varlist>. + class Select_fetch_into_spvars: public select_result_interceptor + { + List<sp_variable> *spvar_list; + uint field_count; + bool send_data_to_variable_list(List<sp_variable> &vars, List<Item> &items); + public: + Select_fetch_into_spvars(THD *thd_arg): select_result_interceptor(thd_arg) {} + void reset(THD *thd_arg) + { + select_result_interceptor::reset(thd_arg); + spvar_list= NULL; + field_count= 0; + } + uint get_field_count() { return field_count; } + void set_spvar_list(List<sp_variable> *vars) { spvar_list= vars; } + + virtual bool send_eof() { return FALSE; } + virtual int send_data(List<Item> &items); + virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u); +}; + +public: + sp_cursor() + :result(NULL), + m_lex_keeper(NULL), + server_side_cursor(NULL) + { } + sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper) + :result(thd_arg), + m_lex_keeper(lex_keeper), + server_side_cursor(NULL) + {} + + virtual ~sp_cursor() + { destroy(); } + + sp_lex_keeper *get_lex_keeper() { return m_lex_keeper; } + + int open(THD *thd); + + int open_view_structure_only(THD *thd); + + int close(THD *thd); + + my_bool is_open() + { return MY_TEST(server_side_cursor); } + + int fetch(THD *, List<sp_variable> *vars, bool error_on_no_data); + + bool export_structure(THD *thd, Row_definition_list *list); + + void reset(THD *thd_arg, sp_lex_keeper *lex_keeper) + { + sp_cursor_statistics::reset(); + result.reset(thd_arg); + m_lex_keeper= lex_keeper; + server_side_cursor= NULL; + } + +private: + Select_fetch_into_spvars result; + sp_lex_keeper *m_lex_keeper; + Server_side_cursor *server_side_cursor; + void destroy(); +}; + + class select_send :public select_result { /** True if we have sent result set metadata to the client. @@ -5950,6 +6080,7 @@ public: void prepare_to_read_rows(); }; +class my_var_sp; class my_var : public Sql_alloc { public: const LEX_CSTRING name; @@ -5958,7 +6089,7 @@ public: my_var(const LEX_CSTRING *j, enum type s) : name(*j), scope(s) { } virtual ~my_var() {} virtual bool set(THD *thd, Item *val) = 0; - virtual class my_var_sp *get_my_var_sp() { return NULL; } + virtual my_var_sp *get_my_var_sp() { return NULL; } }; class my_var_sp: public my_var { @@ -6244,8 +6375,6 @@ inline int handler::ha_ft_read(uchar *buf) inline int handler::ha_rnd_pos_by_record(uchar *buf) { int error= rnd_pos_by_record(buf); - if (!error) - update_rows_read(); table->status=error ? STATUS_NOT_FOUND: 0; return error; } diff --git a/sql/sql_digest.cc b/sql/sql_digest.cc index 54ed1c3f225..a8afd33c46a 100644 --- a/sql/sql_digest.cc +++ b/sql/sql_digest.cc @@ -32,7 +32,7 @@ #include "sql_get_diagnostics.h" /* Generated code */ -#include "sql_yacc.h" +#include "sql_yacc.hh" #define LEX_TOKEN_WITH_DEFINITION #include "lex_token.h" diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 5d977c6d5c2..1c45b05ccc5 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -1693,7 +1693,7 @@ void Explain_table_access::print_explain_json(Explain_query *query, { /* Get r_filtered value from filesort */ if (pre_join_sort->tracker.get_r_loops()) - writer->add_double(pre_join_sort->tracker.get_r_filtered()); + writer->add_double(pre_join_sort->tracker.get_r_filtered()*100); else writer->add_null(); } @@ -2516,4 +2516,3 @@ void Explain_range_checked_fer::print_json(Json_writer *writer, writer->end_object(); } } - diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 7c2ccf1b155..72df8367dc7 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -1029,6 +1029,7 @@ SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, if (!(handler= mysql_ha_find_handler(thd, &tables->alias))) DBUG_RETURN(0); tables->table= handler->table; // This is used by fix_fields + handler->table->pos_in_table_list= tables; if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, ha_rkey_mode, cond, 1)) DBUG_RETURN(0); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6eefa322bf2..e3c53e59d21 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1970,13 +1970,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) error= table->file->ha_delete_row(table->record[1]); else { - DBUG_ASSERT(table->insert_values); - store_record(table,insert_values); - restore_record(table,record[1]); + store_record(table, record[2]); + restore_record(table, record[1]); table->vers_update_end(); error= table->file->ha_update_row(table->record[1], table->record[0]); - restore_record(table,insert_values); + restore_record(table, record[2]); } if (unlikely(error)) goto err; @@ -4562,12 +4561,44 @@ bool select_create::send_eof() */ if (!table->s->tmp_table) { +#ifdef WITH_WSREP + if (WSREP_ON) + { + /* + append table level exclusive key for CTAS + */ + wsrep_key_arr_t key_arr= {0, 0}; + wsrep_prepare_keys_for_isolation(thd, + create_table->db.str, + create_table->table_name.str, + table_list, + &key_arr); + int rcode = wsrep->append_key( + wsrep, + &thd->wsrep_ws_handle, + key_arr.keys, //&wkey, + key_arr.keys_len, + WSREP_KEY_EXCLUSIVE, + false); + wsrep_keys_free(&key_arr); + if (rcode) { + DBUG_PRINT("wsrep", ("row key failed: %d", rcode)); + WSREP_ERROR("Appending table key for CTAS failed: %s, %d", + (wsrep_thd_query(thd)) ? + wsrep_thd_query(thd) : "void", rcode); + return true; + } + /* If commit fails, we should be able to reset the OK status. */ + thd->get_stmt_da()->set_overwrite_status(TRUE); + } +#endif /* WITH_WSREP */ trans_commit_stmt(thd); if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) trans_commit_implicit(thd); #ifdef WITH_WSREP if (WSREP_ON) { + thd->get_stmt_da()->set_overwrite_status(FALSE); mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state != NO_CONFLICT) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9922bdf7e59..ec38baa219a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2255,6 +2255,7 @@ void st_select_lex::init_query() cond_pushed_into_where= cond_pushed_into_having= 0; olap= UNSPECIFIED_OLAP_TYPE; having_fix_field= 0; + having_fix_field_for_pushed_cond= 0; context.select_lex= this; context.init(); /* @@ -5480,7 +5481,8 @@ LEX::sp_variable_declarations_cursor_rowtype_finalize(THD *thd, int nvars, spvar->field_def.set_cursor_rowtype_ref(offset); sp_instr_cursor_copy_struct *instr= new (thd->mem_root) sp_instr_cursor_copy_struct(sphead->instructions(), - spcont, pcursor->lex(), + spcont, offset, + pcursor->lex(), spvar->offset); if (instr == NULL || sphead->add_instr(instr)) return true; @@ -5887,6 +5889,26 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop) return sp_while_loop_finalize(thd); } +bool LEX::sp_for_loop_outer_block_finalize(THD *thd, + const Lex_for_loop_st &loop) +{ + Lex_spblock tmp; + tmp.curs= MY_TEST(loop.m_implicit_cursor); + if (unlikely(sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END + return true; + if (!loop.is_for_loop_explicit_cursor()) + return false; + /* + Explicit cursor FOR loop must close the cursor automatically. + Note, implicit cursor FOR loop does not need to close the cursor, + it's closed by sp_instr_cpop. + */ + sp_instr_cclose *ic= new (thd->mem_root) + sp_instr_cclose(sphead->instructions(), spcont, + loop.m_cursor_offset); + return ic == NULL || sphead->add_instr(ic); +} + /***************************************************************************/ bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name, @@ -5901,7 +5923,6 @@ bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name, my_error(ER_SP_DUP_CURS, MYF(0), name->str); return true; } - cursor_stmt->set_cursor_name(name); if (unlikely(spcont->add_cursor(name, param_ctx, cursor_stmt))) return true; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ebf643a5aa1..5cc46aa8615 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -269,10 +269,10 @@ struct LEX_TYPE #else #include "lex_symbol.h" #ifdef MYSQL_LEX -#include "item_func.h" /* Cast_target used in sql_yacc.h */ -#include "sql_get_diagnostics.h" /* Types used in sql_yacc.h */ +#include "item_func.h" /* Cast_target used in sql_yacc.hh */ +#include "sql_get_diagnostics.h" /* Types used in sql_yacc.hh */ #include "sp_pcontext.h" -#include "sql_yacc.h" +#include "sql_yacc.hh" #define LEX_YYSTYPE YYSTYPE * #else #define LEX_YYSTYPE void * @@ -1064,6 +1064,11 @@ public: bool automatic_brackets; /* dummy select for INTERSECT precedence */ /* TRUE when having fix field called in processing of this SELECT */ bool having_fix_field; + /* + TRUE when fix field is called for a new condition pushed into the + HAVING clause of this SELECT + */ + bool having_fix_field_for_pushed_cond; /* List of references to fields referenced from inner selects */ List<Item_outer_ref> inner_refs_list; /* Number of Item_sum-derived objects in this SELECT */ @@ -3177,8 +3182,6 @@ public: return NULL; } - virtual const LEX_CSTRING *cursor_name() const { return &null_clex_str; } - void start(THD *thd); inline bool is_ps_or_view_context_analysis() @@ -3802,6 +3805,7 @@ public: sp_for_loop_cursor_finalize(thd, loop) : sp_for_loop_intrange_finalize(thd, loop); } + bool sp_for_loop_outer_block_finalize(THD *thd, const Lex_for_loop_st &loop); /* End of FOR LOOP methods */ bool add_signal_statement(THD *thd, const class sp_condition_value *value); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index cc5a5c7c794..ddb5029c78a 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -431,13 +431,6 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, is_concurrent= (table_list->lock_type == TL_WRITE_CONCURRENT_INSERT); #endif - if (table->versioned(VERS_TIMESTAMP) && handle_duplicates == DUP_REPLACE) - { - // Additional memory may be required to create historical items. - if (table_list->set_insert_values(thd->mem_root)) - DBUG_RETURN(TRUE); - } - if (!fields_vars.elements) { Field_iterator_table_ref field_iterator; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a722bebe7bc..e981ed6d3f1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3689,6 +3689,7 @@ mysql_execute_command(THD *thd) { WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); execute_show_status(thd, all_tables); + break; } case SQLCOM_SHOW_EXPLAIN: @@ -4753,7 +4754,7 @@ end_with_restore_list: case SQLCOM_INSERT_SELECT: { WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE); - select_result *sel_result; + select_insert *sel_result; bool explain= MY_TEST(lex->describe); DBUG_ASSERT(first_table == all_tables && first_table != 0); if (WSREP_CLIENT(thd) && @@ -6753,11 +6754,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, THD_STAGE_INFO(thd, stage_checking_permissions); if (unlikely((!db || !db[0]) && !thd->db.str && !dont_check_global_grants)) { - DBUG_PRINT("error",("No database")); - if (!no_errors) - my_message(ER_NO_DB_ERROR, ER_THD(thd, ER_NO_DB_ERROR), - MYF(0)); /* purecov: tested */ - DBUG_RETURN(TRUE); /* purecov: tested */ + DBUG_RETURN(FALSE); // CTE reference or an error later } if (likely((db != NULL) && (db != any_db))) @@ -8384,7 +8381,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, lex->add_to_query_tables(ptr); // Pure table aliases do not need to be locked: - if (!MY_TEST(table_options & TL_OPTION_ALIAS)) + if (ptr->db.str && !(table_options & TL_OPTION_ALIAS)) { ptr->mdl_request.init(MDL_key::TABLE, ptr->db.str, ptr->table_name.str, mdl_type, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index ac1524381c7..8c231d9b8f7 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2156,8 +2156,7 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name, tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PLUGIN_NAME, 0, TL_WRITE); if (!opt_noacl && check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); - - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* need to open before acquiring LOCK_plugin or it will deadlock */ if (! (table = open_ltable(thd, &tables, TL_WRITE, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index aa07dc07aa2..2ee175293de 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2572,6 +2572,7 @@ static int send_events(binlog_send_info *info, IO_CACHE* log, LOG_INFO* linfo, linfo->pos= my_b_tell(log); info->last_pos= my_b_tell(log); + log->end_of_file= end_pos; while (linfo->pos < end_pos) { if (should_stop(info)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 25b01e49a2f..536c14798d1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -822,8 +822,10 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway } - const LEX_CSTRING *fstart= &table->table->vers_start_field()->field_name; - const LEX_CSTRING *fend= &table->table->vers_end_field()->field_name; + const LEX_CSTRING *fstart= + thd->make_clex_string(table->table->vers_start_field()->field_name); + const LEX_CSTRING *fend= + thd->make_clex_string(table->table->vers_end_field()->field_name); Item *row_start= newx Item_field(thd, &this->context, table->db.str, table->alias.str, fstart); @@ -1674,9 +1676,11 @@ JOIN::optimize_inner() if (having) { select_lex->having_fix_field= 1; + select_lex->having_fix_field_for_pushed_cond= 1; if (having->fix_fields(thd, &having)) DBUG_RETURN(1); select_lex->having_fix_field= 0; + select_lex->having_fix_field_for_pushed_cond= 0; } } @@ -1780,10 +1784,18 @@ JOIN::optimize_inner() if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) { /* Impossible cond */ - DBUG_PRINT("info", (having_value == Item::COND_FALSE ? - "Impossible HAVING" : "Impossible WHERE")); - zero_result_cause= having_value == Item::COND_FALSE ? - "Impossible HAVING" : "Impossible WHERE"; + if (unit->select_limit_cnt) + { + DBUG_PRINT("info", (having_value == Item::COND_FALSE ? + "Impossible HAVING" : "Impossible WHERE")); + zero_result_cause= having_value == Item::COND_FALSE ? + "Impossible HAVING" : "Impossible WHERE"; + } + else + { + DBUG_PRINT("info", ("Zero limit")); + zero_result_cause= "Zero limit"; + } table_count= top_join_tab_count= 0; error= 0; subq_exit_fl= true; @@ -10432,7 +10444,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) table_map current_map; i= join->const_tables; for (tab= first_depth_first_tab(join); tab; - tab= next_depth_first_tab(join, tab), i++) + tab= next_depth_first_tab(join, tab)) { bool is_hj; @@ -10917,6 +10929,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } first_inner_tab= first_inner_tab->first_upper; } + if (!tab->bush_children) + i++; } } DBUG_RETURN(0); @@ -14077,7 +14091,8 @@ COND *Item_func_eq::build_equal_items(THD *thd, List_iterator_fast<Item_equal> it(cond_equal.current_level); while ((item_equal= it++)) { - item_equal->fix_length_and_dec(); + if (item_equal->fix_length_and_dec()) + return NULL; item_equal->update_used_tables(); set_if_bigger(thd->lex->current_select->max_equal_elems, item_equal->n_field_items()); @@ -16687,7 +16702,8 @@ Item_field::create_tmp_field_from_item_field(TABLE *new_table, Record_addr rec(orig_item ? orig_item->maybe_null : maybe_null); const Type_handler *handler= type_handler()-> type_handler_for_tmp_table(this); - result= handler->make_and_init_table_field(&name, rec, *this, new_table); + result= handler->make_and_init_table_field(orig_item ? &orig_item->name : &name, + rec, *this, new_table); } else if (param->table_cant_handle_bit_fields() && field->type() == MYSQL_TYPE_BIT) @@ -26276,21 +26292,18 @@ void JOIN::set_allowed_join_cache_types() void JOIN::save_query_plan(Join_plan_state *save_to) { - if (keyuse.elements) - { - DYNAMIC_ARRAY tmp_keyuse; - /* Swap the current and the backup keyuse internal arrays. */ - tmp_keyuse= keyuse; - keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */ - save_to->keyuse= tmp_keyuse; + DYNAMIC_ARRAY tmp_keyuse; + /* Swap the current and the backup keyuse internal arrays. */ + tmp_keyuse= keyuse; + keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */ + save_to->keyuse= tmp_keyuse; - for (uint i= 0; i < table_count; i++) - { - save_to->join_tab_keyuse[i]= join_tab[i].keyuse; - join_tab[i].keyuse= NULL; - save_to->join_tab_checked_keys[i]= join_tab[i].checked_keys; - join_tab[i].checked_keys.clear_all(); - } + for (uint i= 0; i < table_count; i++) + { + save_to->join_tab_keyuse[i]= join_tab[i].keyuse; + join_tab[i].keyuse= NULL; + save_to->join_tab_checked_keys[i]= join_tab[i].checked_keys; + join_tab[i].checked_keys.clear_all(); } memcpy((uchar*) save_to->best_positions, (uchar*) best_positions, sizeof(POSITION) * (table_count + 1)); @@ -26328,20 +26341,17 @@ void JOIN::reset_query_plan() void JOIN::restore_query_plan(Join_plan_state *restore_from) { - if (restore_from->keyuse.elements) - { - DYNAMIC_ARRAY tmp_keyuse; - tmp_keyuse= keyuse; - keyuse= restore_from->keyuse; - restore_from->keyuse= tmp_keyuse; - - for (uint i= 0; i < table_count; i++) - { - join_tab[i].keyuse= restore_from->join_tab_keyuse[i]; - join_tab[i].checked_keys= restore_from->join_tab_checked_keys[i]; - } + DYNAMIC_ARRAY tmp_keyuse; + tmp_keyuse= keyuse; + keyuse= restore_from->keyuse; + restore_from->keyuse= tmp_keyuse; + for (uint i= 0; i < table_count; i++) + { + join_tab[i].keyuse= restore_from->join_tab_keyuse[i]; + join_tab[i].checked_keys= restore_from->join_tab_checked_keys[i]; } + memcpy((uchar*) best_positions, (uchar*) restore_from->best_positions, sizeof(POSITION) * (table_count + 1)); /* Restore SJM nests */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4923c628bf9..2484b5039ad 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2707,6 +2707,9 @@ static const char *thread_state_info(THD *tmp) return ""; return "Reading from net"; } +#else + if (tmp->get_command() == COM_SLEEP) + return ""; #endif if (tmp->proc_info) @@ -10316,3 +10319,85 @@ static void get_cs_converted_string_value(THD *thd, return; } #endif + +/** + Dumps a text description of a thread, its security context + (user, host) and the current query. + + @param thd thread context + @param buffer pointer to preferred result buffer + @param length length of buffer + @param max_query_len how many chars of query to copy (0 for all) + + @return Pointer to string +*/ + +extern "C" +char *thd_get_error_context_description(THD *thd, char *buffer, + unsigned int length, + unsigned int max_query_len) +{ + String str(buffer, length, &my_charset_latin1); + const Security_context *sctx= &thd->main_security_ctx; + char header[256]; + size_t len; + + len= my_snprintf(header, sizeof(header), + "MySQL thread id %u, OS thread handle %lu, query id %llu", + (uint)thd->thread_id, (ulong) thd->real_id, (ulonglong) thd->query_id); + str.length(0); + str.append(header, len); + + if (sctx->host) + { + str.append(' '); + str.append(sctx->host); + } + + if (sctx->ip) + { + str.append(' '); + str.append(sctx->ip); + } + + if (sctx->user) + { + str.append(' '); + str.append(sctx->user); + } + + /* Don't wait if LOCK_thd_data is used as this could cause a deadlock */ + if (!mysql_mutex_trylock(&thd->LOCK_thd_data)) + { + if (const char *info= thread_state_info(thd)) + { + str.append(' '); + str.append(info); + } + + if (thd->query()) + { + if (max_query_len < 1) + len= thd->query_length(); + else + len= MY_MIN(thd->query_length(), max_query_len); + str.append('\n'); + str.append(thd->query(), len); + } + mysql_mutex_unlock(&thd->LOCK_thd_data); + } + + if (str.c_ptr_safe() == buffer) + return buffer; + + /* + We have to copy the new string to the destination buffer because the string + was reallocated to a larger buffer to be able to fit. + */ + DBUG_ASSERT(buffer != NULL); + length= MY_MIN(str.length(), length-1); + memcpy(buffer, str.c_ptr_quick(), length); + /* Make sure that the new string is null terminated */ + buffer[length]= '\0'; + return buffer; +} diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 4edcb779379..00ed7fb0202 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3095,7 +3095,7 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (!tl->is_view_or_derived() && tl->table) + if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && @@ -3107,7 +3107,7 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (!tl->is_view_or_derived() && tl->table) + if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && @@ -3236,7 +3236,7 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (!tl->is_view_or_derived() && tl->table) + if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4ac8b102d79..04fd7bf6e32 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4961,7 +4961,12 @@ int create_table_impl(THD *thd, file= mysql_create_frm_image(thd, orig_db, orig_table_name, create_info, alter_info, create_table_mode, key_info, key_count, frm); - if (!file) + /* + TODO: remove this check of thd->is_error() (now it intercept + errors in some val_*() methoids and bring some single place to + such error interception). + */ + if (!file || thd->is_error()) goto err; if (rea_create_table(thd, frm, path, db->str, table_name->str, create_info, file, frm_only)) @@ -6232,8 +6237,11 @@ drop_create_field: continue; /* Check if the table already has a PRIMARY KEY */ - bool dup_primary_key= key->type == Key::PRIMARY && - table->s->primary_key != MAX_KEY; + bool dup_primary_key= + key->type == Key::PRIMARY && + table->s->primary_key != MAX_KEY && + (keyname= table->s->key_info[table->s->primary_key].name.str) && + my_strcasecmp(system_charset_info, keyname, primary_key_name) == 0; if (dup_primary_key) goto remove_key; @@ -6332,7 +6340,6 @@ remove_key: } #ifdef WITH_PARTITION_STORAGE_ENGINE - DBUG_ASSERT(thd->work_part_info == 0); partition_info *tab_part_info= table->part_info; thd->work_part_info= thd->lex->part_info; if (tab_part_info) @@ -6530,15 +6537,15 @@ static bool fill_alter_inplace_info(THD *thd, ALTER_DROP_INDEX are replaced with versions that have higher granuality. */ - ha_alter_info->handler_flags|= (alter_info->flags & - ~(ALTER_ADD_INDEX | - ALTER_DROP_INDEX | - ALTER_PARSER_ADD_COLUMN | - ALTER_PARSER_DROP_COLUMN | - ALTER_COLUMN_ORDER | - ALTER_RENAME_COLUMN | - ALTER_CHANGE_COLUMN | - ALTER_COLUMN_UNVERSIONED)); + alter_table_operations flags_to_remove= + ALTER_ADD_INDEX | ALTER_DROP_INDEX | ALTER_PARSER_ADD_COLUMN | + ALTER_PARSER_DROP_COLUMN | ALTER_COLUMN_ORDER | ALTER_RENAME_COLUMN | + ALTER_CHANGE_COLUMN; + + if (!table->file->native_versioned()) + flags_to_remove|= ALTER_COLUMN_UNVERSIONED; + + ha_alter_info->handler_flags|= (alter_info->flags & ~flags_to_remove); /* Comparing new and old default values of column is cumbersome. So instead of using such a comparison for detecting if default @@ -7407,6 +7414,11 @@ static bool mysql_inplace_alter_table(THD *thd, bool reopen_tables= false; bool res; + /* + Set the truncated column values of thd as warning + for alter table. + */ + thd->count_cuted_fields = CHECK_FIELD_WARN; DBUG_ENTER("mysql_inplace_alter_table"); /* @@ -7621,10 +7633,15 @@ static bool mysql_inplace_alter_table(THD *thd, /* Replace the old .FRM with the new .FRM, but keep the old name for now. Rename to the new name (if needed) will be handled separately below. + + TODO: remove this check of thd->is_error() (now it intercept + errors in some val_*() methoids and bring some single place to + such error interception). */ if (mysql_rename_table(db_type, &alter_ctx->new_db, &alter_ctx->tmp_name, &alter_ctx->db, &alter_ctx->alias, - FN_FROM_IS_TMP | NO_HA_TABLE)) + FN_FROM_IS_TMP | NO_HA_TABLE) || + thd->is_error()) { // Since changes were done in-place, we can't revert them. (void) quick_rm_table(thd, db_type, @@ -9039,10 +9056,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, { DBUG_ENTER("mysql_alter_table"); -#ifdef WITH_PARTITION_STORAGE_ENGINE - thd->work_part_info= 0; // Used by partitioning -#endif - /* Check if we attempt to alter mysql.slow_log or mysql.general_log table and return an error if @@ -9115,8 +9128,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, DBUG_RETURN(true); } } - if (alter_info->data_modifying() && !thd->slave_thread && - thd->variables.vers_alter_history == VERS_ALTER_HISTORY_ERROR) + if (alter_info->vers_prohibited(thd)) { my_error(ER_VERS_ALTER_NOT_ALLOWED, MYF(0), table_list->db.str, table_list->table_name.str); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 7db4c6c3821..9f26bff3321 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -454,7 +454,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0)); DBUG_RETURN(TRUE); } - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!create) { @@ -516,6 +515,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (err_status) goto end; } + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* We should have only one table in table list. */ DBUG_ASSERT(tables->next_global == 0); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 761349c0a95..10c2e7ebcb2 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -377,7 +377,7 @@ select_unit::create_result_table(THD *thd_arg, List<Item> *column_types, table->keys_in_use_for_query.clear_all(); for (uint i=0; i < table->s->fields; i++) - table->field[i]->flags &= ~PART_KEY_FLAG; + table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); if (create_table) { @@ -413,7 +413,7 @@ select_union_recursive::create_result_table(THD *thd_arg, incr_table->keys_in_use_for_query.clear_all(); for (uint i=0; i < table->s->fields; i++) - incr_table->field[i]->flags &= ~PART_KEY_FLAG; + incr_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); TABLE *rec_table= 0; if (! (rec_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, @@ -424,7 +424,7 @@ select_union_recursive::create_result_table(THD *thd_arg, rec_table->keys_in_use_for_query.clear_all(); for (uint i=0; i < table->s->fields; i++) - rec_table->field[i]->flags &= ~PART_KEY_FLAG; + rec_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); if (rec_tables.push_back(rec_table)) return true; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 783c655d007..f262daad89d 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -435,7 +435,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, goto err; } - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* ignore lock specs for CREATE statement @@ -711,14 +711,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, lex->link_first_table_back(view, link_to_local); DBUG_RETURN(0); +#ifdef WITH_WSREP + error: + res= TRUE; +#endif /* WITH_WSREP */ err: lex->link_first_table_back(view, link_to_local); unit->cleanup(); DBUG_RETURN(res || thd->is_error()); -#ifdef WITH_WSREP - error: - DBUG_RETURN(true); -#endif /* WITH_WSREP */ } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0043f6495e7..dffc91ea465 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1213,7 +1213,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); Keywords that have different reserved status in std/oracle modes. */ %token <kwd> BODY_SYM /* Oracle-R */ -%token <kwd> COMMENT_SYM %token <kwd> ELSIF_SYM /* Oracle, reserved in PL/SQL*/ %token <kwd> GOTO_SYM /* Oracle, reserved in PL/SQL*/ %token <kwd> OTHERS_SYM /* SQL-2011-N */ @@ -1276,6 +1275,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> COLUMN_GET_SYM %token <kwd> COLUMN_SYM /* SQL-2003-R */ %token <kwd> COLUMN_NAME_SYM /* SQL-2003-N */ +%token <kwd> COMMENT_SYM /* Oracle-R */ %token <kwd> COMMITTED_SYM /* SQL-2003-N */ %token <kwd> COMMIT_SYM /* SQL-2003-R */ %token <kwd> COMPACT_SYM @@ -4729,9 +4729,7 @@ sp_labeled_control: } pop_sp_loop_label // The inner WHILE block { - Lex_spblock tmp; - tmp.curs= MY_TEST($4.m_implicit_cursor); - if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $4))) MYSQL_YYABORT; } | sp_label REPEAT_SYM @@ -4781,12 +4779,10 @@ sp_unlabeled_control: sp_proc_stmts1 END FOR_SYM { - Lex_spblock tmp; - tmp.curs= MY_TEST($3.m_implicit_cursor); if (unlikely(Lex->sp_for_loop_finalize(thd, $3))) MYSQL_YYABORT; Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block - if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $3))) MYSQL_YYABORT; } | REPEAT_SYM diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index d9c3ee22faf..933b9dd2429 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -607,7 +607,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); Keywords that have different reserved status in std/oracle modes. */ %token BODY_SYM /* Oracle-R */ -%token COMMENT_SYM %token ELSIF_SYM /* Oracle, reserved in PL/SQL*/ %token GOTO_SYM /* Oracle, reserved in PL/SQL*/ %token OTHERS_SYM /* SQL-2011-N */ @@ -670,6 +669,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> COLUMN_GET_SYM %token <kwd> COLUMN_SYM /* SQL-2003-R */ %token <kwd> COLUMN_NAME_SYM /* SQL-2003-N */ +%token <kwd> COMMENT_SYM /* Oracle-R */ %token <kwd> COMMITTED_SYM /* SQL-2003-N */ %token <kwd> COMMIT_SYM /* SQL-2003-R */ %token <kwd> COMPACT_SYM @@ -4676,9 +4676,7 @@ sp_labeled_control: } pop_sp_loop_label // The inner WHILE block { - Lex_spblock tmp; - tmp.curs= MY_TEST($4.m_implicit_cursor); - if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $4))) MYSQL_YYABORT; } | labels_declaration_oracle REPEAT_SYM @@ -4728,12 +4726,10 @@ sp_unlabeled_control: sp_proc_stmts1 END LOOP_SYM { - Lex_spblock tmp; - tmp.curs= MY_TEST($3.m_implicit_cursor); if (unlikely(Lex->sp_for_loop_finalize(thd, $3))) MYSQL_YYABORT; Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block - if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $3))) MYSQL_YYABORT; } | REPEAT_SYM @@ -15586,6 +15582,7 @@ keyword_sp_var_not_label: | COLUMN_CREATE_SYM | COLUMN_DELETE_SYM | COLUMN_GET_SYM + | COMMENT_SYM | DEALLOCATE_SYM | EXAMINED_SYM | EXCLUDE_SYM diff --git a/sql/structs.h b/sql/structs.h index d530dd73b7c..d8b95a3509a 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -720,6 +720,10 @@ public: *this= other; } bool is_for_loop_cursor() const { return m_upper_bound == NULL; } + bool is_for_loop_explicit_cursor() const + { + return is_for_loop_cursor() && !m_implicit_cursor; + } }; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 658bb0e2d1c..3ac84fb61cc 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -458,7 +458,7 @@ error_if_in_trans_or_substatement(THD *thd, int in_substatement_error, return false; } -static bool check_has_super(sys_var *self, THD *thd, set_var *var) +bool check_has_super(sys_var *self, THD *thd, set_var *var) { DBUG_ASSERT(self->scope() != sys_var::GLOBAL);// don't abuse check_has_super() #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -702,6 +702,8 @@ static Sys_var_struct Sys_character_set_client( offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_cs_client), ON_UPDATE(fix_thd_charset)); +// for check changing +export sys_var *Sys_character_set_client_ptr= &Sys_character_set_client; static Sys_var_struct Sys_character_set_connection( "character_set_connection", "The character set used for " @@ -711,6 +713,8 @@ static Sys_var_struct Sys_character_set_connection( offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_not_null), ON_UPDATE(fix_thd_charset)); +// for check changing +export sys_var *Sys_character_set_connection_ptr= &Sys_character_set_connection; static Sys_var_struct Sys_character_set_results( "character_set_results", "The character set used for returning " @@ -718,6 +722,8 @@ static Sys_var_struct Sys_character_set_results( SESSION_VAR(character_set_results), NO_CMD_LINE, offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_charset)); +// for check changing +export sys_var *Sys_character_set_results_ptr= &Sys_character_set_results; static Sys_var_struct Sys_character_set_filesystem( "character_set_filesystem", "The filesystem character set", @@ -1907,6 +1913,8 @@ static Sys_var_last_gtid Sys_last_gtid( "or the empty string if none.", READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE); +export sys_var *Sys_last_gtid_ptr= &Sys_last_gtid; // for check changing + uchar * Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base) @@ -1917,8 +1925,9 @@ Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base) bool first= true; str.length(0); - if ((thd->last_commit_gtid.seq_no > 0 && - rpl_slave_state_tostring_helper(&str, &thd->last_commit_gtid, &first)) || + rpl_gtid gtid= thd->get_last_commit_gtid(); + if ((gtid.seq_no > 0 && + rpl_slave_state_tostring_helper(&str, >id, &first)) || !(p= thd->strmake(str.ptr(), str.length()))) { my_error(ER_OUT_OF_RESOURCES, MYF(0)); diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index 498204deb92..373df354268 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -147,9 +147,10 @@ public: option.min_value= min_val; option.max_value= max_val; option.block_size= block_size; - option.u_max_value= (uchar**)max_var_ptr(); - if (max_var_ptr()) - *max_var_ptr()= max_val; + if ((option.u_max_value= (uchar**) max_var_ptr())) + { + *((T*) option.u_max_value)= max_val; + } global_var(T)= def_val; SYSVAR_ASSERT(size == sizeof(T)); @@ -181,8 +182,8 @@ public: var->save_result.ulonglong_value= getopt_ull_limit_value(uv, &option, &unused); - if (max_var_ptr() && (T)var->save_result.ulonglong_value > *max_var_ptr()) - var->save_result.ulonglong_value= *max_var_ptr(); + if (max_var_ptr() && (T)var->save_result.ulonglong_value > get_max_var()) + var->save_result.ulonglong_value= get_max_var(); fixed= fixed || var->save_result.ulonglong_value != uv; } @@ -198,8 +199,8 @@ public: var->save_result.longlong_value= getopt_ll_limit_value(v, &option, &unused); - if (max_var_ptr() && (T)var->save_result.longlong_value > *max_var_ptr()) - var->save_result.longlong_value= *max_var_ptr(); + if (max_var_ptr() && (T)var->save_result.longlong_value > get_max_var()) + var->save_result.longlong_value= get_max_var(); fixed= fixed || var->save_result.longlong_value != v; } @@ -221,11 +222,7 @@ public: void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } private: - T *max_var_ptr() - { - return scope() == SESSION ? (T*)(((uchar*)&max_system_variables) + offset) - : 0; - } + T get_max_var() { return *((T*) max_var_ptr()); } uchar *default_value_ptr(THD *thd) { return (uchar*) &option.def_value; } }; @@ -269,6 +266,9 @@ class Sys_var_typelib: public sys_var { protected: TYPELIB typelib; + virtual bool check_maximum(THD *thd, set_var *var, + const char *c_val, longlong i_val) + { return FALSE; } public: Sys_var_typelib(const char *name_arg, const char *comment, int flag_args, ptrdiff_t off, @@ -304,17 +304,14 @@ public: return true; else var->save_result.ulonglong_value--; - } - else - { - longlong tmp=var->value->val_int(); - if (tmp < 0 || tmp >= typelib.count) - return true; - else - var->save_result.ulonglong_value= tmp; + return check_maximum(thd, var, res->ptr(), 0); } - return false; + longlong tmp=var->value->val_int(); + if (tmp < 0 || tmp >= typelib.count) + return true; + var->save_result.ulonglong_value= tmp; + return check_maximum(thd, var, 0, tmp); } }; @@ -349,10 +346,28 @@ public: substitute) { option.var_type|= GET_ENUM; + option.min_value= 0; + option.max_value= ULONG_MAX; global_var(ulong)= def_val; + if ((option.u_max_value= (uchar**)max_var_ptr())) + { + *((ulong *) option.u_max_value)= ULONG_MAX; + } SYSVAR_ASSERT(def_val < typelib.count); SYSVAR_ASSERT(size == sizeof(ulong)); } + bool check_maximum(THD *thd, set_var *var, + const char *c_val, longlong i_val) + { + if (!max_var_ptr() || + var->save_result.ulonglong_value <= get_max_var()) + return FALSE; + var->save_result.ulonglong_value= get_max_var(); + + return c_val ? throw_bounds_warning(thd, name.str, c_val) : + throw_bounds_warning(thd, name.str, TRUE, + var->value->unsigned_flag, i_val); + } bool session_update(THD *thd, set_var *var) { session_var(thd, ulong)= static_cast<ulong>(var->save_result.ulonglong_value); @@ -375,6 +390,8 @@ public: { return valptr(thd, global_var(ulong)); } uchar *default_value_ptr(THD *thd) { return valptr(thd, (ulong)option.def_value); } + + ulong get_max_var() { return *((ulong *) max_var_ptr()); } }; /** @@ -1341,12 +1358,30 @@ public: substitute) { option.var_type|= GET_SET; + option.min_value= 0; + option.max_value= ~0ULL; global_var(ulonglong)= def_val; + if ((option.u_max_value= (uchar**)max_var_ptr())) + { + *((ulonglong*) option.u_max_value)= ~0ULL; + } SYSVAR_ASSERT(typelib.count > 0); SYSVAR_ASSERT(typelib.count <= 64); SYSVAR_ASSERT(def_val <= my_set_bits(typelib.count)); SYSVAR_ASSERT(size == sizeof(ulonglong)); } + bool check_maximum(THD *thd, set_var *var, + const char *c_val, longlong i_val) + { + if (!max_var_ptr() || + (var->save_result.ulonglong_value & ~(get_max_var())) == 0) + return FALSE; + var->save_result.ulonglong_value&= get_max_var(); + + return c_val ? throw_bounds_warning(thd, name.str, c_val) : + throw_bounds_warning(thd, name.str, TRUE, + var->value->unsigned_flag, i_val); + } bool do_check(THD *thd, set_var *var) { char buff[STRING_BUFFER_USUAL_SIZE]; @@ -1354,41 +1389,38 @@ public: if (var->value->result_type() == STRING_RESULT) { - if (!(res=var->value->val_str_ascii(&str))) + char *error; + uint error_len; + bool not_used; + + if (!(res= var->value->val_str_ascii_revert_empty_string_is_null(thd, + &str))) return true; - else - { - char *error; - uint error_len; - bool not_used; - var->save_result.ulonglong_value= - find_set(&typelib, res->ptr(), res->length(), NULL, - &error, &error_len, ¬_used); - /* - note, we only issue an error if error_len > 0. - That is even while empty (zero-length) values are considered - errors by find_set(), these errors are ignored here - */ - if (unlikely(error_len)) - { - ErrConvString err(error, error_len, res->charset()); - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); - return true; - } - } - } - else - { - longlong tmp=var->value->val_int(); - if ((tmp < 0 && ! var->value->unsigned_flag) - || (ulonglong)tmp > my_set_bits(typelib.count)) + var->save_result.ulonglong_value= + find_set(&typelib, res->ptr(), res->length(), NULL, + &error, &error_len, ¬_used); + /* + note, we only issue an error if error_len > 0. + That is even while empty (zero-length) values are considered + errors by find_set(), these errors are ignored here + */ + if (error_len) + { + ErrConvString err(error, error_len, res->charset()); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); return true; - else - var->save_result.ulonglong_value= tmp; + } + return check_maximum(thd, var, res->ptr(), 0); } - return false; + longlong tmp=var->value->val_int(); + if ((tmp < 0 && ! var->value->unsigned_flag) + || (ulonglong)tmp > my_set_bits(typelib.count)) + return true; + + var->save_result.ulonglong_value= tmp; + return check_maximum(thd, var, 0, tmp); } bool session_update(THD *thd, set_var *var) { @@ -1412,6 +1444,8 @@ public: { return valptr(thd, global_var(ulonglong)); } uchar *default_value_ptr(THD *thd) { return valptr(thd, option.def_value); } + + ulonglong get_max_var() { return *((ulonglong*) max_var_ptr()); } }; /** diff --git a/sql/sys_vars_shared.h b/sql/sys_vars_shared.h index 48154c95a72..69382974175 100644 --- a/sql/sys_vars_shared.h +++ b/sql/sys_vars_shared.h @@ -28,6 +28,7 @@ #include <sql_priv.h> #include "set_var.h" +extern bool throw_bounds_warning(THD *thd, const char *name,const char *v); extern bool throw_bounds_warning(THD *thd, const char *name, bool fixed, bool is_unsigned, longlong v); extern bool throw_bounds_warning(THD *thd, const char *name, bool fixed, diff --git a/sql/table.cc b/sql/table.cc index 73b1a6bd9b2..3d3bc3336ef 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1896,7 +1896,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, */ uint vcol_info_length= (uint) strpos[12]; - DBUG_ASSERT(vcol_info_length); // Expect non-null expression + if (!vcol_info_length) // Expect non-null expression + goto err; attr.frm_unpack_basic(strpos); if (attr.frm_unpack_charset(share, strpos)) @@ -2575,6 +2576,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, reg_field->vcol_info= vcol_info; share->virtual_fields++; share->stored_fields--; + if (reg_field->flags & BLOB_FLAG) + share->virtual_not_stored_blob_fields++; /* Correct stored_rec_length as non stored fields are last */ recpos= (uint) (reg_field->ptr - record); if (share->stored_rec_length >= recpos) @@ -3523,7 +3526,7 @@ partititon_err: } } - outparam->mark_columns_used_by_check_constraints(); + outparam->mark_columns_used_by_virtual_fields(); if (db_stat) { @@ -5260,6 +5263,8 @@ int TABLE::verify_constraints(bool ignore_failure) if (check_constraints && !(in_use->variables.option_bits & OPTION_NO_CHECK_CONSTRAINT_CHECKS)) { + if (versioned() && !vers_end_field()->is_max()) + return VIEW_CHECK_OK; for (Virtual_column_info **chk= check_constraints ; *chk ; chk++) { /* @@ -5271,7 +5276,7 @@ int TABLE::verify_constraints(bool ignore_failure) { my_error(ER_CONSTRAINT_FAILED, MYF(ignore_failure ? ME_WARNING : 0), (*chk)->name.str, - s->db.str, s->table_name.str); + s->db.str, s->error_table_name()); return ignore_failure ? VIEW_CHECK_SKIP : VIEW_CHECK_ERROR; } } @@ -5951,6 +5956,8 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref, Item *item= (new (thd->mem_root) Item_direct_view_ref(thd, context, field_ref, view->alias.str, name, view)); + if (!item) + return NULL; /* Force creation of nullable item for the result tmp table for outer joined views/derived tables. @@ -6420,7 +6427,7 @@ void TABLE::mark_columns_needed_for_delete() Field **reg_field; for (reg_field= field ; *reg_field ; reg_field++) { - if ((*reg_field)->flags & PART_KEY_FLAG) + if ((*reg_field)->flags & (PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG)) mark_column_with_deps(*reg_field); } need_signal= true; @@ -6746,7 +6753,8 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl if (bitmap_is_set(write_set, tmp_vfield->field_index)) bitmap_updated|= mark_virtual_column_with_deps(tmp_vfield); else if (tmp_vfield->vcol_info->stored_in_db || - (tmp_vfield->flags & (PART_KEY_FLAG | FIELD_IN_PART_FUNC_FLAG))) + (tmp_vfield->flags & (PART_KEY_FLAG | FIELD_IN_PART_FUNC_FLAG | + PART_INDIRECT_KEY_FLAG))) { bitmap_set_bit(write_set, tmp_vfield->field_index); mark_virtual_column_with_deps(tmp_vfield); @@ -6811,27 +6819,64 @@ bool TABLE::check_virtual_columns_marked_for_write() /* - Mark fields used by check constraints. + Mark fields used by check constraints into s->check_set. + Mark all fields used in an expression that is part of an index + with PART_INDIRECT_KEY_FLAG + This is done once for the TABLE_SHARE the first time the table is opened. The marking must be done non-destructively to handle the case when this could be run in parallely by two threads */ -void TABLE::mark_columns_used_by_check_constraints(void) +void TABLE::mark_columns_used_by_virtual_fields(void) { MY_BITMAP *save_read_set; - /* If there is no check constraints or if check_set is already initialized */ - if (!s->check_set || s->check_set_initialized) + Field **vfield_ptr; + + /* If there is virtual fields are already initialized */ + if (s->check_set_initialized) return; - save_read_set= read_set; - read_set= s->check_set; + if (s->tmp_table == NO_TMP_TABLE) + mysql_mutex_lock(&s->LOCK_share); + if (s->check_set) + { + /* Mark fields used by check constraint */ + save_read_set= read_set; + read_set= s->check_set; + + for (Virtual_column_info **chk= check_constraints ; *chk ; chk++) + (*chk)->expr->walk(&Item::register_field_in_read_map, 1, 0); + read_set= save_read_set; + } - for (Virtual_column_info **chk= check_constraints ; *chk ; chk++) - (*chk)->expr->walk(&Item::register_field_in_read_map, 1, 0); + /* + mark all fields that part of a virtual indexed field with + PART_INDIRECT_KEY_FLAG. This is used to ensure that all fields + that are part of an index exits before write/delete/update. - read_set= save_read_set; + As this code is only executed once per open share, it's reusing + existing functionality instead of adding an extra argument to + add_field_to_set_processor or adding another processor. + */ + if (vfield) + { + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) + { + if ((*vfield_ptr)->flags & PART_KEY_FLAG) + (*vfield_ptr)->vcol_info->expr->walk(&Item::add_field_to_set_processor, + 1, this); + } + for (uint i= 0 ; i < s->fields ; i++) + { + if (bitmap_is_set(&tmp_set, i)) + field[i]->flags|= PART_INDIRECT_KEY_FLAG; + } + bitmap_clear_all(&tmp_set); + } s->check_set_initialized= 1; + if (s->tmp_table == NO_TMP_TABLE) + mysql_mutex_unlock(&s->LOCK_share); } /* Add fields used by CHECK CONSTRAINT to read map */ @@ -6879,6 +6924,52 @@ void TABLE::move_fields(Field **ptr, const uchar *to, const uchar *from) } +/* + Store all allocated virtual fields blob values + Used by InnoDB when calculating virtual fields for it's own internal + records +*/ + +void TABLE::remember_blob_values(String *blob_storage) +{ + Field **vfield_ptr; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) + { + if ((*vfield_ptr)->type() == MYSQL_TYPE_BLOB && + !(*vfield_ptr)->vcol_info->stored_in_db) + { + Field_blob *blob= ((Field_blob*) *vfield_ptr); + memcpy((void*) blob_storage, (void*) &blob->value, sizeof(blob->value)); + blob_storage++; + blob->value.release(); + } + } +} + + +/* + Restore all allocated virtual fields blob values + Used by InnoDB when calculating virtual fields for it's own internal + records +*/ + +void TABLE::restore_blob_values(String *blob_storage) +{ + Field **vfield_ptr; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) + { + if ((*vfield_ptr)->type() == MYSQL_TYPE_BLOB && + !(*vfield_ptr)->vcol_info->stored_in_db) + { + Field_blob *blob= ((Field_blob*) *vfield_ptr); + blob->value.free(); + memcpy((void*) &blob->value, (void*) blob_storage, sizeof(blob->value)); + blob_storage++; + } + } +} + + /** @brief Allocate space for keys @@ -7622,7 +7713,8 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) update= bitmap_is_set(read_set, vf->field_index); break; case VCOL_UPDATE_FOR_REPLACE: - update= ((!vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) && + update= ((!vcol_info->stored_in_db && + (vf->flags & (PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG)) && bitmap_is_set(read_set, vf->field_index)) || update_all_columns); if (update && (vf->flags & BLOB_FLAG)) @@ -7641,7 +7733,8 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) case VCOL_UPDATE_INDEXED: case VCOL_UPDATE_INDEXED_FOR_UPDATE: /* Read indexed fields that was not updated in VCOL_UPDATE_FOR_READ */ - update= (!vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) && + update= (!vcol_info->stored_in_db && + (vf->flags & (PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG)) && !bitmap_is_set(read_set, vf->field_index)); swap_values= 1; break; @@ -7777,6 +7870,7 @@ void TABLE::vers_update_fields() } vers_end_field()->set_max(); + bitmap_set_bit(read_set, vers_end_field()->field_index); } @@ -8206,7 +8300,15 @@ int TABLE_LIST::fetch_number_of_rows() { int error= 0; if (jtbm_subselect) + { + if (jtbm_subselect->is_jtbm_merged) + { + table->file->stats.records= (ha_rows)jtbm_subselect->jtbm_record_count; + set_if_bigger(table->file->stats.records, 2); + table->used_stat_records= table->file->stats.records; + } return 0; + } if (is_materialized_derived() && !fill_me) { table->file->stats.records= ((select_unit*)(get_unit()->result))->records; diff --git a/sql/table.h b/sql/table.h index 785fd9f3427..b75fa9074a4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -687,8 +687,11 @@ struct TABLE_SHARE */ uint null_bytes_for_compare; uint fields; /* number of fields */ - uint stored_fields; /* number of stored fields, purely virtual not included */ + /* number of stored fields, purely virtual not included */ + uint stored_fields; uint virtual_fields; /* number of purely virtual fields */ + /* number of purely virtual not stored blobs */ + uint virtual_not_stored_blob_fields; uint null_fields; /* number of null fields */ uint blob_fields; /* number of blob fields */ uint varchar_fields; /* number of varchar fields */ @@ -1377,7 +1380,7 @@ public: bool check_virtual_columns_marked_for_read(); bool check_virtual_columns_marked_for_write(); void mark_default_fields_for_write(bool insert_fl); - void mark_columns_used_by_check_constraints(void); + void mark_columns_used_by_virtual_fields(void); void mark_check_constraint_columns_for_read(void); int verify_constraints(bool ignore_failure); inline void column_bitmaps_set(MY_BITMAP *read_set_arg) @@ -1459,6 +1462,8 @@ public: { return (my_ptrdiff_t) (s->default_values - record[0]); } void move_fields(Field **ptr, const uchar *to, const uchar *from); + void remember_blob_values(String *blob_storage); + void restore_blob_values(String *blob_storage); uint actual_n_key_parts(KEY *keyinfo); ulong actual_key_flags(KEY *keyinfo); diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 3ffd5d7706b..d4d35d752be 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -119,7 +119,7 @@ void wsrep_post_commit(THD* thd, bool all) switch (thd->wsrep_exec_mode) { - case LOCAL_COMMIT: + case LOCAL_COMMIT: { DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED); if (wsrep && wsrep->post_commit(wsrep, &thd->wsrep_ws_handle)) @@ -131,18 +131,30 @@ void wsrep_post_commit(THD* thd, bool all) wsrep_cleanup_transaction(thd); break; } - case LOCAL_STATE: - { - /* - Non-InnoDB statements may have populated events in stmt cache => cleanup - */ - WSREP_DEBUG("cleanup transaction for LOCAL_STATE: %s", thd->query()); - wsrep_cleanup_transaction(thd); - break; - } - default: break; + case LOCAL_STATE: + { + /* non-InnoDB statements may have populated events in stmt cache + => cleanup + */ + WSREP_DEBUG("cleanup transaction for LOCAL_STATE"); + /* + Run post-rollback hook to clean up in the case if + some keys were populated for the transaction in provider + but during commit time there was no write set to replicate. + This may happen when client sets the SAVEPOINT and immediately + rolls back to savepoint after first operation. + */ + if (all && thd->wsrep_conflict_state != MUST_REPLAY && + wsrep && wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle)) + { + WSREP_WARN("post_rollback fail: %llu %d", + (long long)thd->thread_id, thd->get_stmt_da()->status()); + } + wsrep_cleanup_transaction(thd); + break; + } + default: break; } - } /* diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 0c051d384c9..7a90373e252 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -13,7 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include "mariadb.h" +#include "sql_plugin.h" /* wsrep_plugins_pre_init() */ #include <mysqld.h> #include <sql_class.h> #include <sql_parse.h> @@ -38,7 +38,6 @@ #include <cstdlib> #include "log_event.h" #include <slave.h> -#include "sql_plugin.h" /* wsrep_plugins_pre_init() */ wsrep_t *wsrep = NULL; /* @@ -313,8 +312,7 @@ wsrep_view_handler_cb (void* app_ctx, if (memcmp(&cluster_uuid, &view->state_id.uuid, sizeof(wsrep_uuid_t))) { - memcpy((wsrep_uuid_t*)&cluster_uuid, &view->state_id.uuid, - sizeof(cluster_uuid)); + memcpy(&cluster_uuid, &view->state_id.uuid, sizeof(cluster_uuid)); wsrep_uuid_print (&cluster_uuid, cluster_uuid_str, sizeof(cluster_uuid_str)); @@ -360,7 +358,7 @@ wsrep_view_handler_cb (void* app_ctx, // version change if (view->proto_ver != wsrep_protocol_version) { - my_bool wsrep_ready_saved= wsrep_ready; + my_bool wsrep_ready_saved= wsrep_ready_get(); wsrep_ready_set(FALSE); WSREP_INFO("closing client connections for " "protocol change %ld -> %d", @@ -475,16 +473,34 @@ out: return WSREP_CB_SUCCESS; } -void wsrep_ready_set (my_bool x) +my_bool wsrep_ready_set (my_bool x) { WSREP_DEBUG("Setting wsrep_ready to %d", x); if (mysql_mutex_lock (&LOCK_wsrep_ready)) abort(); - if (wsrep_ready != x) + my_bool ret= (wsrep_ready != x); + if (ret) { wsrep_ready= x; mysql_cond_signal (&COND_wsrep_ready); } mysql_mutex_unlock (&LOCK_wsrep_ready); + return ret; +} + +my_bool wsrep_ready_get (void) +{ + if (mysql_mutex_lock (&LOCK_wsrep_ready)) abort(); + my_bool ret= wsrep_ready; + mysql_mutex_unlock (&LOCK_wsrep_ready); + return ret; +} + +int wsrep_show_ready(THD *thd, SHOW_VAR *var, char *buff) +{ + var->type= SHOW_MY_BOOL; + var->value= buff; + *((my_bool *)buff)= wsrep_ready_get(); + return 0; } // Wait until wsrep has reached ready state @@ -503,17 +519,8 @@ void wsrep_ready_wait () static void wsrep_synced_cb(void* app_ctx) { WSREP_INFO("Synchronized with group, ready for connections"); - bool signal_main= false; - if (mysql_mutex_lock (&LOCK_wsrep_ready)) abort(); - if (!wsrep_ready) - { - wsrep_ready= TRUE; - mysql_cond_signal (&COND_wsrep_ready); - signal_main= true; - - } + my_bool signal_main= wsrep_ready_set(TRUE); wsrep_config_state->set(WSREP_MEMBER_SYNCED); - mysql_mutex_unlock (&LOCK_wsrep_ready); if (signal_main) { @@ -995,6 +1002,8 @@ bool wsrep_must_sync_wait (THD* thd, uint mask) { return (thd->variables.wsrep_sync_wait & mask) && thd->variables.wsrep_on && + !(thd->variables.wsrep_dirty_reads && + !is_update_query(thd->lex->sql_command)) && !thd->in_active_multi_stmt_transaction() && thd->wsrep_conflict_state != REPLAYING && thd->wsrep_sync_wait_gtid.seqno == WSREP_SEQNO_UNDEFINED; @@ -1042,17 +1051,7 @@ bool wsrep_sync_wait (THD* thd, uint mask) return false; } -/* - * Helpers to deal with TOI key arrays - */ -typedef struct wsrep_key_arr -{ - wsrep_key_t* keys; - size_t keys_len; -} wsrep_key_arr_t; - - -static void wsrep_keys_free(wsrep_key_arr_t* key_arr) +void wsrep_keys_free(wsrep_key_arr_t* key_arr) { for (size_t i= 0; i < key_arr->keys_len; ++i) { @@ -1117,11 +1116,11 @@ static bool wsrep_prepare_key_for_isolation(const char* db, } /* Prepare key list from db/table and table_list */ -static bool wsrep_prepare_keys_for_isolation(THD* thd, - const char* db, - const char* table, - const TABLE_LIST* table_list, - wsrep_key_arr_t* ka) +bool wsrep_prepare_keys_for_isolation(THD* thd, + const char* db, + const char* table, + const TABLE_LIST* table_list, + wsrep_key_arr_t* ka) { ka->keys= 0; ka->keys_len= 0; @@ -1866,7 +1865,7 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx, if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE || request_thd->lex->sql_command == SQLCOM_DROP_SEQUENCE) { - WSREP_DEBUG("DROP caused BF abort"); + WSREP_DEBUG("DROP caused BF abort, conf %d", granted_thd->wsrep_conflict_state); } else if (granted_thd->wsrep_query_state == QUERY_COMMITTING) { diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 5a13575d904..699a4daf27a 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -228,6 +228,7 @@ void wsrep_log(void (*fun)(const char *, ...), const char *format, ...); #define WSREP_QUERY(thd) (thd->query()) +extern my_bool wsrep_ready_get(); extern void wsrep_ready_wait(); class Ha_trx_info; @@ -320,6 +321,18 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table, bool wsrep_node_is_donor(); bool wsrep_node_is_synced(); +typedef struct wsrep_key_arr +{ + wsrep_key_t* keys; + size_t keys_len; +} wsrep_key_arr_t; +bool wsrep_prepare_keys_for_isolation(THD* thd, + const char* db, + const char* table, + const TABLE_LIST* table_list, + wsrep_key_arr_t* ka); +void wsrep_keys_free(wsrep_key_arr_t* key_arr); + #define WSREP_BINLOG_FORMAT(my_format) \ ((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? \ wsrep_forced_binlog_format : my_format) @@ -353,6 +366,5 @@ bool wsrep_node_is_synced(); #define wsrep_thr_deinit() do {} while(0) #define wsrep_running_threads (0) #define WSREP_BINLOG_FORMAT(my_format) my_format - #endif /* WITH_WSREP */ #endif /* WSREP_MYSQLD_H */ diff --git a/sql/wsrep_priv.h b/sql/wsrep_priv.h index 97307fcc948..222a49cc2ab 100644 --- a/sql/wsrep_priv.h +++ b/sql/wsrep_priv.h @@ -26,7 +26,7 @@ #include <pthread.h> #include <cstdio> -void wsrep_ready_set (my_bool x); +my_bool wsrep_ready_set (my_bool x); ssize_t wsrep_sst_prepare (void** msg); wsrep_cb_status wsrep_sst_donate_cb (void* app_ctx, diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index d19bcafb8d6..d5b0344c456 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -29,6 +29,8 @@ #include <cstdio> #include <cstdlib> +#include <my_service_manager.h> + static char wsrep_defaults_file[FN_REFLEN * 2 + 10 + 30 + sizeof(WSREP_SST_OPT_CONF) + sizeof(WSREP_SST_OPT_CONF_SUFFIX) + @@ -176,6 +178,9 @@ bool wsrep_before_SE() static bool sst_complete = false; static bool sst_needed = false; +#define WSREP_EXTEND_TIMEOUT_INTERVAL 30 +#define WSREP_TIMEDWAIT_SECONDS 10 + void wsrep_sst_grab () { WSREP_INFO("wsrep_sst_grab()"); @@ -187,11 +192,25 @@ void wsrep_sst_grab () // Wait for end of SST bool wsrep_sst_wait () { - if (mysql_mutex_lock (&LOCK_wsrep_sst)) abort(); + struct timespec wtime = {WSREP_TIMEDWAIT_SECONDS, 0}; + uint32 total_wtime = 0; + + if (mysql_mutex_lock (&LOCK_wsrep_sst)) + abort(); + + WSREP_INFO("Waiting for SST to complete."); + while (!sst_complete) { - WSREP_INFO("Waiting for SST to complete."); - mysql_cond_wait (&COND_wsrep_sst, &LOCK_wsrep_sst); + mysql_cond_timedwait (&COND_wsrep_sst, &LOCK_wsrep_sst, &wtime); + + if (!sst_complete) + { + total_wtime += wtime.tv_sec; + WSREP_DEBUG("Waiting for SST to complete. waited %u secs.", total_wtime); + service_manager_extend_timeout(WSREP_EXTEND_TIMEOUT_INTERVAL, + "WSREP state transfer ongoing, current seqno: %ld", local_seqno); + } } if (local_seqno >= 0) @@ -604,11 +623,11 @@ static ssize_t sst_prepare_other (const char* method, ret= snprintf (cmd_str(), cmd_len, "wsrep_sst_%s " - WSREP_SST_OPT_ROLE" 'joiner' " - WSREP_SST_OPT_ADDR" '%s' " - WSREP_SST_OPT_DATA" '%s' " + WSREP_SST_OPT_ROLE " 'joiner' " + WSREP_SST_OPT_ADDR " '%s' " + WSREP_SST_OPT_DATA " '%s' " " %s " - WSREP_SST_OPT_PARENT" '%d'" + WSREP_SST_OPT_PARENT " '%d'" " %s '%s' ", method, addr_in, mysql_real_data_home, wsrep_defaults_file, @@ -890,13 +909,13 @@ static int sst_donate_mysqldump (const char* addr, int ret= snprintf (cmd_str(), cmd_len, "wsrep_sst_mysqldump " - WSREP_SST_OPT_ADDR" '%s' " - WSREP_SST_OPT_PORT" '%d' " - WSREP_SST_OPT_LPORT" '%u' " - WSREP_SST_OPT_SOCKET" '%s' " - " '%s' " - WSREP_SST_OPT_GTID" '%s:%lld' " - WSREP_SST_OPT_GTID_DOMAIN_ID" '%d'" + WSREP_SST_OPT_ADDR " '%s' " + WSREP_SST_OPT_PORT " '%d' " + WSREP_SST_OPT_LPORT " '%u' " + WSREP_SST_OPT_SOCKET " '%s' " + " %s " + WSREP_SST_OPT_GTID " '%s:%lld' " + WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" "%s", addr, port, mysqld_port, mysqld_unix_port, wsrep_defaults_file, uuid_str, @@ -1253,14 +1272,14 @@ static int sst_donate_other (const char* method, ret= snprintf (cmd_str(), cmd_len, "wsrep_sst_%s " - WSREP_SST_OPT_ROLE" 'donor' " - WSREP_SST_OPT_ADDR" '%s' " - WSREP_SST_OPT_SOCKET" '%s' " - WSREP_SST_OPT_DATA" '%s' " + WSREP_SST_OPT_ROLE " 'donor' " + WSREP_SST_OPT_ADDR " '%s' " + WSREP_SST_OPT_SOCKET " '%s' " + WSREP_SST_OPT_DATA " '%s' " " %s " " %s '%s' " - WSREP_SST_OPT_GTID" '%s:%lld' " - WSREP_SST_OPT_GTID_DOMAIN_ID" '%d'" + WSREP_SST_OPT_GTID " '%s:%lld' " + WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" "%s", method, addr, mysqld_unix_port, mysql_real_data_home, wsrep_defaults_file, @@ -1346,10 +1365,22 @@ void wsrep_SE_init_grab() void wsrep_SE_init_wait() { + struct timespec wtime = {WSREP_TIMEDWAIT_SECONDS, 0}; + uint32 total_wtime=0; + while (SE_initialized == false) { - mysql_cond_wait (&COND_wsrep_sst_init, &LOCK_wsrep_sst_init); + mysql_cond_timedwait (&COND_wsrep_sst_init, &LOCK_wsrep_sst_init, &wtime); + + if (!SE_initialized) + { + total_wtime += wtime.tv_sec; + WSREP_DEBUG("Waiting for SST to complete. waited %u secs.", total_wtime); + service_manager_extend_timeout(WSREP_EXTEND_TIMEOUT_INTERVAL, + "WSREP SE initialization ongoing."); + } } + mysql_mutex_unlock (&LOCK_wsrep_sst_init); } diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index d94ac240b76..7fe120beb8e 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -47,6 +47,7 @@ int wsrep_init_vars() linking will succeed even if the server is built with a dynamically linked InnoDB. */ ulong innodb_lock_schedule_algorithm __attribute__((weak)); +struct handlerton* innodb_hton_ptr __attribute__((weak)); bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type) { @@ -62,7 +63,10 @@ bool wsrep_on_check(sys_var *self, THD* thd, set_var* var) { bool new_wsrep_on= (bool)var->save_result.ulonglong_value; - if (new_wsrep_on && innodb_lock_schedule_algorithm != 0) { + if (check_has_super(self, thd, var)) + return true; + + if (new_wsrep_on && innodb_hton_ptr && innodb_lock_schedule_algorithm != 0) { my_message(ER_WRONG_ARGUMENTS, " WSREP (galera) can't be enabled " "if innodb_lock_schedule_algorithm=VATS. Please configure" " innodb_lock_schedule_algorithm=FCFS and restart.", MYF(0)); diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 7419bb329a3..bb15aa9297d 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1909,7 +1909,7 @@ maria_declare_plugin(archive) &archive_storage_engine, "ARCHIVE", "Brian Aker, MySQL AB", - "Archive storage engine", + "gzip-compresses tables for a low storage footprint", PLUGIN_LICENSE_GPL, archive_db_init, /* Plugin Init */ NULL, /* Plugin Deinit */ diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index 244acfdc5c8..a660461e9ee 100644 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -515,7 +515,8 @@ bool VCTFAM::AllocateBuffer(PGLOBAL g) for (; cp; cp = (PVCTCOL)cp->Next) cp->Blk = AllocValBlock(g, NewBlock + Nrec * cp->Deplac, cp->Buf_Type, Nrec, cp->Format.Length, - cp->Format.Prec, chk); + cp->Format.Prec, chk, true, + cp->IsUnsigned()); return InitInsert(g); // Initialize inserting } else { @@ -549,7 +550,8 @@ bool VCTFAM::AllocateBuffer(PGLOBAL g) for (; cp; cp = (PVCTCOL)cp->Next) if (!cp->IsSpecial()) // Not a pseudo column cp->Blk = AllocValBlock(g, NULL, cp->Buf_Type, Nrec, - cp->Format.Length, cp->Format.Prec); + cp->Format.Length, cp->Format.Prec, + true, true, cp->IsUnsigned()); } //endif mode @@ -1516,7 +1518,8 @@ bool VCMFAM::AllocateBuffer(PGLOBAL g) for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next) if (!cp->IsSpecial()) { // Not a pseudo column cp->Blk = AllocValBlock(g, (void*)1, cp->Buf_Type, Nrec, - cp->Format.Length, cp->Format.Prec); + cp->Format.Length, cp->Format.Prec, + true, true, cp->IsUnsigned()); cp->AddStatus(BUF_MAPPED); } // endif IsSpecial @@ -2067,7 +2070,7 @@ bool VECFAM::AllocateBuffer(PGLOBAL g) for (cp = (PVCTCOL)tdbp->Columns; cp; cp = (PVCTCOL)cp->Next) cp->Blk = AllocValBlock(g, To_Bufs[cp->Index - 1], cp->Buf_Type, Nrec, cp->Format.Length, - cp->Format.Prec, chk); + cp->Format.Prec, chk, true, cp->IsUnsigned()); return InitInsert(g); } else { @@ -2116,7 +2119,8 @@ bool VECFAM::AllocateBuffer(PGLOBAL g) for (cp = (PVCTCOL)tdbp->Columns; cp; cp = (PVCTCOL)cp->Next) if (!cp->IsSpecial()) // Not a pseudo column cp->Blk = AllocValBlock(g, NULL, cp->Buf_Type, Nrec, - cp->Format.Length, cp->Format.Prec); + cp->Format.Length, cp->Format.Prec, + true, true, cp->IsUnsigned()); } // endif mode @@ -2887,7 +2891,8 @@ bool VMPFAM::AllocateBuffer(PGLOBAL g) for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next) if (!cp->IsSpecial()) { // Not a pseudo column cp->Blk = AllocValBlock(g, (void*)1, cp->Buf_Type, Nrec, - cp->Format.Length, cp->Format.Prec); + cp->Format.Length, cp->Format.Prec, + true, true, cp->IsUnsigned()); cp->AddStatus(BUF_MAPPED); } // endif IsSpecial @@ -3669,7 +3674,7 @@ bool BGVFAM::AllocateBuffer(PGLOBAL g) for (; cp; cp = (PVCTCOL)cp->Next) cp->Blk = AllocValBlock(g, NewBlock + Nrec * cp->Deplac, cp->Buf_Type, Nrec, cp->Format.Length, - cp->Format.Prec, chk); + cp->Format.Prec, chk, true, cp->IsUnsigned()); InitInsert(g); // Initialize inserting @@ -3717,7 +3722,8 @@ bool BGVFAM::AllocateBuffer(PGLOBAL g) for (; cp; cp = (PVCTCOL)cp->Next) if (!cp->IsSpecial()) // Not a pseudo column cp->Blk = AllocValBlock(g, NULL, cp->Buf_Type, Nrec, - cp->Format.Length, cp->Format.Prec); + cp->Format.Length, cp->Format.Prec, + true, true, cp->IsUnsigned()); } //endif mode diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index 11b344ef652..40d020202ea 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -456,13 +456,11 @@ bool VCTCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) if (tdbp->Txfp->GetAmType() == TYPE_AM_VMP && ok) { Blk = AllocValBlock(g, (void*)1, Buf_Type, tdbp->Txfp->Nrec, - Format.Length, - Format.Prec, check); + Format.Length, Format.Prec, check, true, Unsigned); Status |= BUF_MAPPED; // Will point into mapped file } else Blk = AllocValBlock(g, NULL, Buf_Type, tdbp->Txfp->Nrec, - Format.Length, - Format.Prec, check); + Format.Length, Format.Prec, check, true, Unsigned); } // endif Mode return false; diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index ed76f395d6a..d5db465588a 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -1788,7 +1788,7 @@ maria_declare_plugin(csv) &csv_storage_engine, "CSV", "Brian Aker, MySQL AB", - "CSV storage engine", + "Stores tables as CSV files", PLUGIN_LICENSE_GPL, tina_init_func, /* Plugin Init */ tina_done_func, /* Plugin Deinit */ diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 98d4ef4d7f9..4aed06885e5 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -3410,7 +3410,7 @@ maria_declare_plugin(federated) &federated_storage_engine, "FEDERATED", "Patrick Galbraith and Brian Aker, MySQL AB", - "Federated MySQL storage engine", + "Allows to access tables on other MariaDB servers", PLUGIN_LICENSE_GPL, federated_db_init, /* Plugin Init */ federated_done, /* Plugin Deinit */ diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 57cf66f4b18..74d547cb674 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -3678,7 +3678,7 @@ maria_declare_plugin(federatedx) &federatedx_storage_engine, "FEDERATED", "Patrick Galbraith", - "FederatedX pluggable storage engine", + "Allows to access tables on other MariaDB servers, supports transactions and more", PLUGIN_LICENSE_GPL, federatedx_db_init, /* Plugin Init */ federatedx_done, /* Plugin Deinit */ diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index 847483ba9bf..46ac0270300 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -980,7 +980,7 @@ void heap_update_auto_increment(HP_INFO *info, const uchar *record) switch (info->s->auto_key_type) { case HA_KEYTYPE_INT8: - s_value= (longlong) *(char*)key; + s_value= (longlong) *(const signed char*) key; break; case HA_KEYTYPE_BINARY: value=(ulonglong) *(uchar*) key; diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 678668a7809..6f36198f129 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -40,57 +40,6 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com #include <list> -/**************************************************//** -Custom nullptr implementation for under g++ 4.6 -*******************************************************/ -// #pragma once -/* -namespace std -{ - // based on SC22/WG21/N2431 = J16/07-0301 - struct nullptr_t - { - template<typename any> operator any * () const - { - return 0; - } - template<class any, typename T> operator T any:: * () const - { - return 0; - } - -#ifdef _MSC_VER - struct pad {}; - pad __[sizeof(void*)/sizeof(pad)]; -#else - char __[sizeof(void*)]; -#endif -private: - // nullptr_t();// {} - // nullptr_t(const nullptr_t&); - // void operator = (const nullptr_t&); - void operator &() const; - template<typename any> void operator +(any) const - { - // I Love MSVC 2005! - } - template<typename any> void operator -(any) const - { - // I Love MSVC 2005! - } - }; -static const nullptr_t __nullptr = {}; -} - -#ifndef nullptr -#define nullptr std::__nullptr -#endif -*/ - -/**************************************************//** -End of Custom nullptr implementation for under g++ 4.6 -*******************************************************/ - /* When there's no work, either because defragment is disabled, or because no query is submitted, thread checks state every BTR_DEFRAGMENT_SLEEP_IN_USECS.*/ #define BTR_DEFRAGMENT_SLEEP_IN_USECS 1000000 @@ -829,7 +778,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*) err = dict_stats_save_defrag_stats(index); if (err != DB_SUCCESS) { ib::error() << "Saving defragmentation stats for table " - << index->table->name.m_name + << index->table->name << " index " << index->name() << " failed with error " << err; } else { @@ -837,7 +786,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*) if (err != DB_SUCCESS) { ib::error() << "Saving defragmentation summary for table " - << index->table->name.m_name + << index->table->name << " index " << index->name() << " failed with error " << err; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 064a0eff506..6e88e0f72ee 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -423,6 +423,53 @@ on the io_type */ ? (counter##_READ) \ : (counter##_WRITTEN)) + +/** Reserve a buffer slot for encryption, decryption or page compression. +@param[in,out] buf_pool buffer pool +@return reserved buffer slot */ +static buf_tmp_buffer_t* buf_pool_reserve_tmp_slot(buf_pool_t* buf_pool) +{ + for (ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { + buf_tmp_buffer_t* slot = &buf_pool->tmp_arr->slots[i]; + if (slot->acquire()) { + return slot; + } + } + + /* We assume that free slot is found */ + ut_error; + return NULL; +} + +/** Reserve a buffer for encryption, decryption or decompression. +@param[in,out] slot reserved slot */ +static void buf_tmp_reserve_crypt_buf(buf_tmp_buffer_t* slot) +{ + if (!slot->crypt_buf) { + slot->crypt_buf = static_cast<byte*>( + aligned_malloc(srv_page_size, srv_page_size)); + } +} + +/** Reserve a buffer for compression. +@param[in,out] slot reserved slot */ +static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) +{ + if (!slot->comp_buf) { + /* Both snappy and lzo compression methods require that + output buffer used for compression is bigger than input + buffer. Increase the allocated buffer size accordingly. */ + ulint size = srv_page_size; +#ifdef HAVE_LZO + size += LZO1X_1_15_MEM_COMPRESS; +#elif defined HAVE_SNAPPY + size = snappy_max_compressed_length(size); +#endif + slot->comp_buf = static_cast<byte*>( + aligned_malloc(size, srv_page_size)); + } +} + /** Registers a chunk to buf_pool_chunk_map @param[in] chunk chunk of buffers */ static @@ -438,10 +485,91 @@ buf_pool_register_chunk( @param[in,out] bpage Page control block @param[in,out] space tablespace @return whether the operation was successful */ -static -bool -buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) - MY_ATTRIBUTE((nonnull)); +static bool buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) +{ + ut_ad(space->pending_io()); + ut_ad(space->id == bpage->id.space()); + + byte* dst_frame = bpage->zip.data ? bpage->zip.data : + ((buf_block_t*) bpage)->frame; + bool page_compressed = fil_page_is_compressed(dst_frame); + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + + if (bpage->id.page_no() == 0) { + /* File header pages are not encrypted/compressed */ + return (true); + } + + /* Page is encrypted if encryption information is found from + tablespace and page contains used key_version. This is true + also for pages first compressed and then encrypted. */ + + buf_tmp_buffer_t* slot; + + if (page_compressed) { + /* the page we read is unencrypted */ + /* Find free slot from temporary memory array */ +decompress: + slot = buf_pool_reserve_tmp_slot(buf_pool); + /* For decompression, use crypt_buf. */ + buf_tmp_reserve_crypt_buf(slot); +decompress_with_slot: + ut_d(fil_page_type_validate(dst_frame)); + + bpage->write_size = fil_page_decompress(slot->crypt_buf, + dst_frame); + slot->release(); + + ut_ad(!bpage->write_size || fil_page_type_validate(dst_frame)); + ut_ad(space->pending_io()); + return bpage->write_size != 0; + } + + if (space->crypt_data + && mach_read_from_4(FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + + dst_frame)) { + /* Verify encryption checksum before we even try to + decrypt. */ + if (!fil_space_verify_crypt_checksum( + dst_frame, bpage->size, bpage->id.space(), + bpage->id.page_no())) { +decrypt_failed: + /* Mark page encrypted in case it should be. */ + if (space->crypt_data->type + != CRYPT_SCHEME_UNENCRYPTED) { + bpage->encrypted = true; + } + + return false; + } + + /* Find free slot from temporary memory array */ + slot = buf_pool_reserve_tmp_slot(buf_pool); + buf_tmp_reserve_crypt_buf(slot); + + ut_d(fil_page_type_validate(dst_frame)); + + /* decrypt using crypt_buf to dst_frame */ + if (!fil_space_decrypt(space, slot->crypt_buf, + dst_frame, &bpage->encrypted)) { + slot->release(); + goto decrypt_failed; + } + + ut_d(fil_page_type_validate(dst_frame)); + + if (fil_page_is_compressed_encrypted(dst_frame)) { + goto decompress_with_slot; + } + + slot->release(); + } else if (fil_page_is_compressed_encrypted(dst_frame)) { + goto decompress; + } + + ut_ad(space->pending_io()); + return true; +} /********************************************************************//** Gets the smallest oldest_modification lsn for any page in the pool. Returns @@ -5979,21 +6107,23 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) ulint read_page_no = 0; ulint read_space_id = 0; uint key_version = 0; - - ut_ad(bpage->zip.data != NULL || ((buf_block_t*)bpage)->frame != NULL); + byte* frame = bpage->zip.data + ? bpage->zip.data + : reinterpret_cast<buf_block_t*>(bpage)->frame; + ut_ad(frame); fil_space_t* space = fil_space_acquire_for_io( bpage->id.space()); if (!space) { return DB_TABLESPACE_DELETED; } - buf_page_decrypt_after_read(bpage, space); - - byte* frame = bpage->zip.data - ? bpage->zip.data - : reinterpret_cast<buf_block_t*>(bpage)->frame; dberr_t err; + if (!buf_page_decrypt_after_read(bpage, space)) { + err = DB_DECRYPTION_FAILED; + goto database_corrupted; + } + if (bpage->zip.data && uncompressed) { my_atomic_addlint(&buf_pool->n_pend_unzip, 1); ibool ok = buf_zip_decompress((buf_block_t*) bpage, @@ -6145,7 +6275,7 @@ database_corrupted: /* io_type == BUF_IO_WRITE */ if (bpage->slot) { /* Mark slot free */ - bpage->slot->reserved = false; + bpage->slot->release(); bpage->slot = NULL; } } @@ -7316,66 +7446,6 @@ operator<<( return(out); } -/********************************************************************//** -Reserve unused slot from temporary memory array and allocate necessary -temporary memory if not yet allocated. -@return reserved slot */ -UNIV_INTERN -buf_tmp_buffer_t* -buf_pool_reserve_tmp_slot( -/*======================*/ - buf_pool_t* buf_pool, /*!< in: buffer pool where to - reserve */ - bool compressed) /*!< in: is file space compressed */ -{ - buf_tmp_buffer_t *free_slot=NULL; - - /* Array is protected by buf_pool mutex */ - buf_pool_mutex_enter(buf_pool); - - for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { - buf_tmp_buffer_t *slot = &buf_pool->tmp_arr->slots[i]; - - if(slot->reserved == false) { - free_slot = slot; - break; - } - } - - /* We assume that free slot is found */ - ut_a(free_slot != NULL); - free_slot->reserved = true; - /* Now that we have reserved this slot we can release - buf_pool mutex */ - buf_pool_mutex_exit(buf_pool); - - /* Allocate temporary memory for encryption/decryption */ - if (free_slot->crypt_buf == NULL) { - free_slot->crypt_buf = static_cast<byte*>(aligned_malloc(srv_page_size, srv_page_size)); - memset(free_slot->crypt_buf, 0, srv_page_size); - } - - /* For page compressed tables allocate temporary memory for - compression/decompression */ - if (compressed && free_slot->comp_buf == NULL) { - ulint size = srv_page_size; - - /* Both snappy and lzo compression methods require that - output buffer used for compression is bigger than input - buffer. Increase the allocated buffer size accordingly. */ -#if defined(HAVE_SNAPPY) - size = snappy_max_compressed_length(size); -#endif -#if defined(HAVE_LZO) - size += LZO1X_1_15_MEM_COMPRESS; -#endif - free_slot->comp_buf = static_cast<byte*>(aligned_malloc(size, srv_page_size)); - memset(free_slot->comp_buf, 0, size); - } - - return (free_slot); -} - /** Encryption and page_compression hook that is called just before a page is written to disk. @param[in,out] space tablespace @@ -7424,15 +7494,18 @@ buf_page_encrypt_before_write( return src_frame; } + ut_ad(!bpage->size.is_compressed() || !page_compressed); buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); /* Find free slot from temporary memory array */ - buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool); slot->out_buf = NULL; bpage->slot = slot; + buf_tmp_reserve_crypt_buf(slot); byte *dst_frame = slot->crypt_buf; if (!page_compressed) { +not_compressed: /* Encrypt page content */ byte* tmp = fil_space_encrypt(space, bpage->id.page_no(), @@ -7440,33 +7513,30 @@ buf_page_encrypt_before_write( src_frame, dst_frame); + bpage->real_size = srv_page_size; slot->out_buf = dst_frame = tmp; ut_d(fil_page_type_validate(tmp)); } else { /* First we compress the page content */ - ulint out_len = 0; - - byte *tmp = fil_compress_page( - space, - (byte *)src_frame, - slot->comp_buf, - srv_page_size, + buf_tmp_reserve_compression_buf(slot); + byte* tmp = slot->comp_buf; + ulint out_len = fil_page_compress( + src_frame, tmp, fsp_flags_get_page_compression_level(space->flags), fil_space_get_block_size(space, bpage->id.page_no()), - encrypted, - &out_len); + encrypted); + if (!out_len) { + goto not_compressed; + } bpage->real_size = out_len; /* Workaround for MDEV-15527. */ memset(tmp + out_len, 0 , srv_page_size - out_len); -#ifdef UNIV_DEBUG - fil_page_type_validate(tmp); -#endif - - if(encrypted) { + ut_d(fil_page_type_validate(tmp)); + if (encrypted) { /* And then we encrypt the page content */ tmp = fil_space_encrypt(space, bpage->id.page_no(), @@ -7484,112 +7554,6 @@ buf_page_encrypt_before_write( return dst_frame; } -/** Decrypt a page. -@param[in,out] bpage Page control block -@param[in,out] space tablespace -@return whether the operation was successful */ -static -bool -buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) -{ - ut_ad(space->pending_io()); - ut_ad(space->id == bpage->id.space()); - - bool compressed = bpage->size.is_compressed(); - const page_size_t& size = bpage->size; - byte* dst_frame = compressed ? bpage->zip.data : - ((buf_block_t*) bpage)->frame; - unsigned key_version = - mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - bool page_compressed = fil_page_is_compressed(dst_frame); - bool page_compressed_encrypted = fil_page_is_compressed_encrypted(dst_frame); - buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); - bool success = true; - - if (bpage->id.page_no() == 0) { - /* File header pages are not encrypted/compressed */ - return (true); - } - - /* Page is encrypted if encryption information is found from - tablespace and page contains used key_version. This is true - also for pages first compressed and then encrypted. */ - if (!space->crypt_data) { - key_version = 0; - } - - if (page_compressed) { - /* the page we read is unencrypted */ - /* Find free slot from temporary memory array */ - buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); - - ut_d(fil_page_type_validate(dst_frame)); - - /* decompress using comp_buf to dst_frame */ - fil_decompress_page(slot->comp_buf, - dst_frame, - ulong(size.logical()), - &bpage->write_size); - - /* Mark this slot as free */ - slot->reserved = false; - key_version = 0; - - ut_d(fil_page_type_validate(dst_frame)); - } else { - buf_tmp_buffer_t* slot = NULL; - - if (key_version) { - /* Verify encryption checksum before we even try to - decrypt. */ - if (!fil_space_verify_crypt_checksum( - dst_frame, size, - bpage->id.space(), bpage->id.page_no())) { - if (space->crypt_data->type - != CRYPT_SCHEME_UNENCRYPTED) { - bpage->encrypted = true; - } - return (false); - } - - /* Find free slot from temporary memory array */ - slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); - - ut_d(fil_page_type_validate(dst_frame)); - - /* decrypt using crypt_buf to dst_frame */ - if (!fil_space_decrypt(space, slot->crypt_buf, - dst_frame, &bpage->encrypted)) { - success = false; - } - - ut_d(fil_page_type_validate(dst_frame)); - } - - if (page_compressed_encrypted && success) { - if (!slot) { - slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); - } - - ut_d(fil_page_type_validate(dst_frame)); - /* decompress using comp_buf to dst_frame */ - fil_decompress_page(slot->comp_buf, - dst_frame, - ulong(size.logical()), - &bpage->write_size); - ut_d(fil_page_type_validate(dst_frame)); - } - - /* Mark this slot as free */ - if (slot) { - slot->reserved = false; - } - } - - ut_ad(space->pending_io()); - return success; -} - /** Should we punch hole to deallocate unused portion of the page. @param[in] bpage Page control block @@ -7613,6 +7577,4 @@ buf_page_get_trim_length( { return (bpage->size.physical() - write_length); } - - #endif /* !UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index e219589c4a2..8c473b0c658 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -530,10 +530,11 @@ buf_dblwr_process() } unaligned_read_buf = static_cast<byte*>( - ut_malloc_nokey(2U << srv_page_size_shift)); + ut_malloc_nokey(3U << srv_page_size_shift)); read_buf = static_cast<byte*>( ut_align(unaligned_read_buf, srv_page_size)); + byte* const buf = read_buf + srv_page_size; for (recv_dblwr_t::list::iterator i = recv_dblwr.pages.begin(); i != recv_dblwr.pages.end(); @@ -601,24 +602,24 @@ buf_dblwr_process() ignore this page (there should be redo log records to initialize it). */ } else { - if (fil_page_is_compressed_encrypted(read_buf) || - fil_page_is_compressed(read_buf)) { - /* Decompress the page before - validating the checksum. */ - fil_decompress_page( - NULL, read_buf, srv_page_size, - NULL, true); + /* Decompress the page before + validating the checksum. */ + ulint decomp = fil_page_decompress(buf, read_buf); + if (!decomp || (decomp != srv_page_size + && page_size.is_compressed())) { + goto bad; } if (fil_space_verify_crypt_checksum( read_buf, page_size, space_id, page_no) - || !buf_page_is_corrupted( - true, read_buf, page_size, space)) { + || !buf_page_is_corrupted( + true, read_buf, page_size, space)) { /* The page is good; there is no need to consult the doublewrite buffer. */ continue; } +bad: /* We intentionally skip this message for is_all_zero pages. */ ib::info() @@ -626,19 +627,16 @@ buf_dblwr_process() << " from the doublewrite buffer."; } - /* Next, validate the doublewrite page. */ - if (fil_page_is_compressed_encrypted(page) || - fil_page_is_compressed(page)) { - /* Decompress the page before - validating the checksum. */ - fil_decompress_page( - NULL, page, srv_page_size, NULL, true); + ulint decomp = fil_page_decompress(buf, page); + if (!decomp || (decomp != srv_page_size + && page_size.is_compressed())) { + goto bad_doublewrite; } - if (!fil_space_verify_crypt_checksum(page, page_size, space_id, page_no) && buf_page_is_corrupted(true, page, page_size, space)) { if (!is_all_zero) { +bad_doublewrite: ib::warn() << "A doublewrite copy of page " << page_id << " is corrupted."; } diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 252f37b4495..bf0891840f8 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -353,9 +353,10 @@ next_page: ut_free(page_arr); } -/** Drop the adaptive hash index for a tablespace. -@param[in,out] table table */ -void buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table) +/** Try to drop the adaptive hash index for a tablespace. +@param[in,out] table table +@return whether anything was dropped */ +bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table) { for (dict_index_t* index = dict_table_get_first_index(table); index != NULL; @@ -366,13 +367,15 @@ void buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table) } } - return; + return false; drop_ahi: ulint id = table->space_id; for (ulint i = 0; i < srv_buf_pool_instances; i++) { buf_LRU_drop_page_hash_for_tablespace(buf_pool_from_array(i), id); } + + return true; } #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 9415624465f..31b78f94ab6 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -569,7 +569,7 @@ dict_table_close_and_drop( if (err != DB_SUCCESS) { ib::error() << "At " << __FILE__ << ":" << __LINE__ << " row_merge_drop_table returned error: " << err - << " table: " << table->name.m_name; + << " table: " << table->name; } } @@ -2589,12 +2589,11 @@ dict_index_remove_from_cache_low( zero. See also: dict_table_can_be_evicted() */ do { - if (!btr_search_info_get_ref_count(info, index)) { + if (!btr_search_info_get_ref_count(info, index) + || !buf_LRU_drop_page_hash_for_tablespace(table)) { break; } - buf_LRU_drop_page_hash_for_tablespace(table); - ut_a(++retries < 10000); } while (srv_shutdown_state == SRV_SHUTDOWN_NONE || !lru_evict); #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index b826d7ada19..76c65fca841 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -664,57 +664,38 @@ fil_space_encrypt( #ifdef UNIV_DEBUG if (tmp) { /* Verify that encrypted buffer is not corrupted */ - byte* tmp_mem = (byte *)malloc(srv_page_size); dberr_t err = DB_SUCCESS; byte* src = src_frame; bool page_compressed_encrypted = (mach_read_from_2(tmp+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); - byte* comp_mem = NULL; - byte* uncomp_mem = NULL; + byte uncomp_mem[UNIV_PAGE_SIZE_MAX]; + byte tmp_mem[UNIV_PAGE_SIZE_MAX]; if (page_compressed_encrypted) { - comp_mem = (byte *)malloc(srv_page_size); - uncomp_mem = (byte *)malloc(srv_page_size); - memcpy(comp_mem, src_frame, srv_page_size); - fil_decompress_page(uncomp_mem, comp_mem, - srv_page_size, NULL); - src = uncomp_mem; + memcpy(uncomp_mem, src, srv_page_size); + ulint unzipped1 = fil_page_decompress( + tmp_mem, uncomp_mem); + ut_ad(unzipped1); + if (unzipped1 != srv_page_size) { + src = uncomp_mem; + } } - bool corrupted1 = buf_page_is_corrupted(true, src, page_size, space); - bool ok = fil_space_decrypt(crypt_data, tmp_mem, page_size, tmp, &err); + ut_ad(!buf_page_is_corrupted(true, src, page_size, space)); + ut_ad(fil_space_decrypt(crypt_data, tmp_mem, page_size, tmp, + &err)); + ut_ad(err == DB_SUCCESS); /* Need to decompress the page if it was also compressed */ if (page_compressed_encrypted) { - memcpy(comp_mem, tmp_mem, srv_page_size); - fil_decompress_page(tmp_mem, comp_mem, - srv_page_size, NULL); - } - - bool corrupted = buf_page_is_corrupted(true, tmp_mem, page_size, space); - memcpy(tmp_mem+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, src+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8); - bool different = memcmp(src, tmp_mem, page_size.physical()); - - if (!ok || corrupted || corrupted1 || err != DB_SUCCESS || different) { - fprintf(stderr, "ok %d corrupted %d corrupted1 %d err %d different %d\n", - ok , corrupted, corrupted1, err, different); - fprintf(stderr, "src_frame\n"); - buf_page_print(src_frame, page_size); - fprintf(stderr, "encrypted_frame\n"); - buf_page_print(tmp, page_size); - fprintf(stderr, "decrypted_frame\n"); - buf_page_print(tmp_mem, page_size); - ut_ad(0); + byte buf[UNIV_PAGE_SIZE_MAX]; + memcpy(buf, tmp_mem, srv_page_size); + ulint unzipped2 = fil_page_decompress(tmp_mem, buf); + ut_ad(unzipped2); } - free(tmp_mem); - - if (comp_mem) { - free(comp_mem); - } - - if (uncomp_mem) { - free(uncomp_mem); - } + memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, + src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8); + ut_ad(!memcmp(src, tmp_mem, page_size.physical())); } #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 07482354683..82be0dbbf85 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1105,7 +1105,7 @@ fil_mutex_enter_and_prepare_for_io( /*===============================*/ ulint space_id) /*!< in: space id */ { - for (ulint count = 0, count2 = 0;;) { + for (ulint count = 0;;) { mutex_enter(&fil_system.mutex); if (space_id >= SRV_LOG_SPACE_FIRST_ID) { @@ -1119,41 +1119,6 @@ fil_mutex_enter_and_prepare_for_io( break; } - if (space->stop_ios) { - ut_ad(space->id != 0); - /* We are going to do a rename file and want to stop - new i/o's for a while. */ - - if (count2 > 20000) { - ib::warn() << "Tablespace " << space->name - << " has i/o ops stopped for a long" - " time " << count2; - } - - mutex_exit(&fil_system.mutex); - - /* Wake the i/o-handler threads to make sure pending - i/o's are performed */ - os_aio_simulated_wake_handler_threads(); - - /* The sleep here is just to give IO helper threads a - bit of time to do some work. It is not required that - all IO related to the tablespace being renamed must - be flushed here as we do fil_flush() in - fil_rename_tablespace() as well. */ - os_thread_sleep(20000); - - /* Flush tablespaces so that we can close modified - files in the LRU list */ - fil_flush_file_spaces(FIL_TYPE_TABLESPACE); - - os_thread_sleep(20000); - - count2++; - - continue; - } - fil_node_t* node = UT_LIST_GET_LAST(space->chain); ut_ad(space->id == 0 || node == UT_LIST_GET_FIRST(space->chain)); @@ -3026,86 +2991,33 @@ fil_rename_tablespace( const char* new_name, const char* new_path_in) { - bool sleep = false; - bool flush = false; fil_space_t* space; fil_node_t* node; - ulint count = 0; ut_a(id != 0); ut_ad(strchr(new_name, '/') != NULL); -retry: - count++; - - if (!(count % 1000)) { - ib::warn() << "Cannot rename file " << old_path - << " (space id " << id << "), retried " << count - << " times." - " There are either pending IOs or flushes or" - " the file is being extended."; - } mutex_enter(&fil_system.mutex); space = fil_space_get_by_id(id); - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_1", space = NULL; ); - if (space == NULL) { ib::error() << "Cannot find space id " << id << " in the tablespace memory cache, though the file '" << old_path << "' in a rename operation should have that id."; -func_exit: mutex_exit(&fil_system.mutex); return(false); } - if (count > 25000) { - space->stop_ios = false; - goto func_exit; - } - - /* We temporarily close the .ibd file because we do not trust that - operating systems can rename an open file. For the closing we have to - wait until there are no pending i/o's or flushes on the file. */ - - space->stop_ios = true; - /* The following code must change when InnoDB supports multiple datafiles per tablespace. */ ut_a(UT_LIST_GET_LEN(space->chain) == 1); node = UT_LIST_GET_FIRST(space->chain); - - if (node->n_pending > 0 - || node->n_pending_flushes > 0 - || node->being_extended) { - /* There are pending i/o's or flushes or the file is - currently being extended, sleep for a while and - retry */ - sleep = true; - } else if (node->modification_counter > node->flush_counter) { - /* Flush the space */ - sleep = flush = true; - } else if (node->is_open()) { - /* Close the file */ - - fil_node_close_file(node); - } + space->n_pending_ops++; mutex_exit(&fil_system.mutex); - if (sleep) { - os_thread_sleep(20000); - - if (flush) { - fil_flush(id); - } - - sleep = flush = false; - goto retry; - } - ut_ad(space->stop_ios); char* new_file_name = new_path_in == NULL ? fil_make_filepath(NULL, new_name, IBD, false) : mem_strdup(new_path_in); @@ -3124,20 +3036,14 @@ func_exit: /* log_sys.mutex is above fil_system.mutex in the latching order */ ut_ad(log_mutex_own()); mutex_enter(&fil_system.mutex); + ut_ad(space->n_pending_ops); + space->n_pending_ops--; ut_ad(space->name == old_space_name); ut_ad(node->name == old_file_name); - bool success; - - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_2", - goto skip_rename; ); - - success = os_file_rename( + bool success = os_file_rename( innodb_data_file_key, old_file_name, new_file_name); - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_2", - skip_rename: success = false; ); - ut_ad(node->name == old_file_name); if (success) { @@ -3158,8 +3064,6 @@ func_exit: old_space_name = new_space_name; } - ut_ad(space->stop_ios); - space->stop_ios = false; mutex_exit(&fil_system.mutex); ut_free(old_file_name); diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index 507f452aa20..ca5fc036c45 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2017, MariaDB Corporation. +Copyright (C) 2013, 2018, 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 the Free Software @@ -74,73 +74,26 @@ Updated 14/02/2015 #include "snappy-c.h" #endif -/* Used for debugging */ -//#define UNIV_PAGECOMPRESS_DEBUG 1 - -/****************************************************************//** -For page compressed pages compress the page before actual write -operation. -@return compressed page to be written*/ -UNIV_INTERN -byte* -fil_compress_page( -/*==============*/ - fil_space_t* space, /*!< in,out: tablespace (NULL during IMPORT) */ - byte* buf, /*!< in: buffer from which to write; in aio - this must be appropriately aligned */ - byte* out_buf, /*!< out: compressed buffer */ - ulint len, /*!< in: length of input buffer.*/ - ulint level, /* in: compression level */ - ulint block_size, /*!< in: block size */ - bool encrypted, /*!< in: is page also encrypted */ - ulint* out_len) /*!< out: actual length of compressed - page */ +/** Compress a page_compressed page before writing to a data file. +@param[in] buf page to be compressed +@param[out] out_buf compressed page +@param[in] level compression level +@param[in] block_size file system block size +@param[in] encrypted whether the page will be subsequently encrypted +@return actual length of compressed page +@retval 0 if the page was not compressed */ +ulint fil_page_compress(const byte* buf, byte* out_buf, ulint level, + ulint block_size, bool encrypted) { - int err = Z_OK; int comp_level = int(level); ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; - ulint write_size = 0; -#if defined(HAVE_LZO) - lzo_uint write_size_lzo = write_size; -#endif /* Cache to avoid change during function execution */ ulint comp_method = innodb_compression_algorithm; - bool allocated = false; - - /* page_compression does not apply to tables or tablespaces - that use ROW_FORMAT=COMPRESSED */ - ut_ad(!space || !FSP_FLAGS_GET_ZIP_SSIZE(space->flags)); if (encrypted) { header_len += FIL_PAGE_COMPRESSION_METHOD_SIZE; } - if (!out_buf) { - allocated = true; - ulint size = srv_page_size; - - /* Both snappy and lzo compression methods require that - output buffer used for compression is bigger than input - buffer. Increase the allocated buffer size accordingly. */ -#if defined(HAVE_SNAPPY) - if (comp_method == PAGE_SNAPPY_ALGORITHM) { - size = snappy_max_compressed_length(size); - } -#endif -#if defined(HAVE_LZO) - if (comp_method == PAGE_LZO_ALGORITHM) { - size += LZO1X_1_15_MEM_COMPRESS; - } -#endif - - out_buf = static_cast<byte *>(ut_malloc_nokey(size)); - } - - ut_ad(buf); - ut_ad(out_buf); - ut_ad(len); - ut_ad(out_len); - /* Let's not compress file space header or extent descriptor */ switch (fil_page_get_type(buf)) { @@ -148,8 +101,7 @@ fil_compress_page( case FIL_PAGE_TYPE_FSP_HDR: case FIL_PAGE_TYPE_XDES: case FIL_PAGE_PAGE_COMPRESSED: - *out_len = len; - goto err_exit; + return 0; } /* If no compression level was provided to this table, use system @@ -158,125 +110,113 @@ fil_compress_page( comp_level = int(page_zip_level); } - DBUG_LOG("compress", "Preparing for space " - << (space ? space->id : 0) << " '" - << (space ? space->name : "(import)") << "' len " << len); - - write_size = srv_page_size - header_len; + ulint write_size = srv_page_size - header_len; - switch(comp_method) { + switch (comp_method) { + default: + ut_ad(!"unknown compression method"); + /* fall through */ + case PAGE_UNCOMPRESSED: + return 0; + case PAGE_ZLIB_ALGORITHM: + { + ulong len = uLong(write_size); + if (Z_OK == compress2( + out_buf + header_len, &len, + buf, uLong(srv_page_size), comp_level)) { + write_size = len; + goto success; + } + } + break; #ifdef HAVE_LZ4 case PAGE_LZ4_ALGORITHM: - -#ifdef HAVE_LZ4_COMPRESS_DEFAULT - err = LZ4_compress_default((const char *)buf, - (char *)out_buf+header_len, len, write_size); -#else - err = LZ4_compress_limitedOutput((const char *)buf, - (char *)out_buf+header_len, len, write_size); -#endif /* HAVE_LZ4_COMPRESS_DEFAULT */ - write_size = err; - - if (err == 0) { - goto err_exit; +# ifdef HAVE_LZ4_COMPRESS_DEFAULT + write_size = LZ4_compress_default( + reinterpret_cast<const char*>(buf), + reinterpret_cast<char*>(out_buf) + header_len, + int(srv_page_size), int(write_size)); +# else + write_size = LZ4_compress_limitedOutput( + reinterpret_cast<const char*>(buf), + reinterpret_cast<char*>(out_buf) + header_len, + int(srv_page_size), int(write_size)); +# endif + + if (write_size) { + goto success; } break; #endif /* HAVE_LZ4 */ #ifdef HAVE_LZO - case PAGE_LZO_ALGORITHM: - err = lzo1x_1_15_compress( - buf, len, out_buf+header_len, &write_size_lzo, out_buf+srv_page_size); - - write_size = write_size_lzo; - - if (err != LZO_E_OK || write_size > srv_page_size-header_len) { - goto err_exit; + case PAGE_LZO_ALGORITHM: { + lzo_uint len = write_size; + + if (LZO_E_OK == lzo1x_1_15_compress( + buf, srv_page_size, + out_buf + header_len, &len, + out_buf + srv_page_size) + && len <= write_size) { + write_size = len; + goto success; } - break; + } #endif /* HAVE_LZO */ #ifdef HAVE_LZMA case PAGE_LZMA_ALGORITHM: { - size_t out_pos=0; - - err = lzma_easy_buffer_encode( - comp_level, - LZMA_CHECK_NONE, - NULL, /* No custom allocator, use malloc/free */ - reinterpret_cast<uint8_t*>(buf), - len, - reinterpret_cast<uint8_t*>(out_buf + header_len), - &out_pos, - (size_t)write_size); - - if (err != LZMA_OK || out_pos > srv_page_size-header_len) { + size_t out_pos = 0; + + if (LZMA_OK == lzma_easy_buffer_encode( + comp_level, LZMA_CHECK_NONE, NULL, + buf, srv_page_size, out_buf + header_len, + &out_pos, write_size) + && out_pos <= write_size) { write_size = out_pos; - goto err_exit; + goto success; } - - write_size = out_pos; - break; } #endif /* HAVE_LZMA */ #ifdef HAVE_BZIP2 case PAGE_BZIP2_ALGORITHM: { - - err = BZ2_bzBuffToBuffCompress( - (char *)(out_buf + header_len), - (unsigned int *)&write_size, - (char *)buf, - len, - 1, - 0, - 0); - - if (err != BZ_OK || write_size > srv_page_size-header_len) { - goto err_exit; + unsigned len = unsigned(write_size); + if (BZ_OK == BZ2_bzBuffToBuffCompress( + reinterpret_cast<char*>(out_buf + header_len), + &len, + const_cast<char*>( + reinterpret_cast<const char*>(buf)), + unsigned(srv_page_size), 1, 0, 0) + && len <= write_size) { + write_size = len; + goto success; } break; } #endif /* HAVE_BZIP2 */ #ifdef HAVE_SNAPPY - case PAGE_SNAPPY_ALGORITHM: - { - snappy_status cstatus; - write_size = snappy_max_compressed_length(srv_page_size); - - cstatus = snappy_compress( - (const char *)buf, - (size_t)len, - (char *)(out_buf+header_len), - (size_t*)&write_size); - - if (cstatus != SNAPPY_OK || write_size > srv_page_size-header_len) { - err = (int)cstatus; - goto err_exit; + case PAGE_SNAPPY_ALGORITHM: { + size_t len = snappy_max_compressed_length(srv_page_size); + + if (SNAPPY_OK == snappy_compress( + reinterpret_cast<const char*>(buf), + srv_page_size, + reinterpret_cast<char*>(out_buf) + header_len, + &len) + && len <= write_size) { + write_size = len; + goto success; } break; } #endif /* HAVE_SNAPPY */ - - case PAGE_ZLIB_ALGORITHM: - err = compress2(out_buf+header_len, (ulong*)&write_size, buf, - uLong(len), comp_level); - - if (err != Z_OK) { - goto err_exit; - } - break; - - case PAGE_UNCOMPRESSED: - *out_len = len; - return (buf); - break; - default: - ut_error; - break; } + srv_stats.pages_page_compression_error.inc(); + return 0; +success: /* Set up the page header */ memcpy(out_buf, buf, FIL_PAGE_DATA); /* Set up the checksum */ @@ -307,23 +247,12 @@ fil_compress_page( /* Verify that page can be decompressed */ { - byte *comp_page; - byte *uncomp_page; - - comp_page = static_cast<byte *>(ut_malloc_nokey(srv_page_size)); - uncomp_page = static_cast<byte *>(ut_malloc_nokey(srv_page_size)); - memcpy(comp_page, out_buf, srv_page_size); - - fil_decompress_page(uncomp_page, comp_page, ulong(len), NULL); - - if (buf_page_is_corrupted(false, uncomp_page, univ_page_size, - space)) { - buf_page_print(uncomp_page, univ_page_size); - ut_ad(0); - } - - ut_free(comp_page); - ut_free(uncomp_page); + page_t tmp_buf[UNIV_PAGE_SIZE_MAX]; + page_t page[UNIV_PAGE_SIZE_MAX]; + memcpy(page, out_buf, srv_page_size); + ut_ad(fil_page_decompress(tmp_buf, page)); + ut_ad(!buf_page_is_corrupted(false, page, univ_page_size, + NULL)); } #endif /* UNIV_DEBUG */ @@ -347,310 +276,137 @@ fil_compress_page( #endif } - DBUG_LOG("compress", "Succeeded for space " - << (space ? space->id : 0) << " '" - << (space ? space->name : "(import)") - << "' len " << len << " out_len " << write_size); - - srv_stats.page_compression_saved.add((len - write_size)); + srv_stats.page_compression_saved.add(srv_page_size - write_size); srv_stats.pages_page_compressed.inc(); - *out_len = write_size; - - if (allocated) { - /* TODO: reduce number of memcpy's */ - memcpy(buf, out_buf, len); - goto exit_free; - } else { - return(out_buf); - } - -err_exit: - /* If error we leave the actual page as it was */ - -#ifndef UNIV_PAGECOMPRESS_DEBUG - if (space && !space->printed_compression_failure) { - space->printed_compression_failure = true; -#endif - ib::warn() << "Compression failed for space: " - << space->id << " name: " - << space->name << " len: " - << len << " err: " << err << " write_size: " - << write_size - << " compression method: " - << fil_get_compression_alg_name(comp_method) - << "."; -#ifndef UNIV_PAGECOMPRESS_DEBUG - } -#endif - srv_stats.pages_page_compression_error.inc(); - *out_len = len; - -exit_free: - if (allocated) { - ut_free(out_buf); - } - - return (buf); - + return write_size; } -/****************************************************************//** -For page compressed pages decompress the page after actual read -operation. */ -UNIV_INTERN -void -fil_decompress_page( -/*================*/ - byte* page_buf, /*!< in: preallocated buffer or NULL */ - byte* buf, /*!< out: buffer from which to read; in aio - this must be appropriately aligned */ - ulong len, /*!< in: length of output buffer.*/ - ulint* write_size, /*!< in/out: Actual payload size of - the compressed data. */ - bool return_error) /*!< in: true if only an error should - be produced when decompression fails. - By default this parameter is false. */ +/** Decompress a page that may be subject to page_compressed compression. +@param[in,out] tmp_buf temporary buffer (of innodb_page_size) +@param[in,out] buf possibly compressed page buffer +@return size of the compressed data +@retval 0 if decompression failed +@retval srv_page_size if the page was not compressed */ +ulint fil_page_decompress(byte* tmp_buf, byte* buf) { - int err = 0; - ulint actual_size = 0; - ib_uint64_t compression_alg = 0; - byte *in_buf; - ulint ptype; + const unsigned ptype = mach_read_from_2(buf+FIL_PAGE_TYPE); ulint header_len; - - ut_ad(buf); - ut_ad(len); - - ptype = mach_read_from_2(buf+FIL_PAGE_TYPE); - + uint64_t compression_alg; switch (ptype) { case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED: header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE + FIL_PAGE_COMPRESSION_METHOD_SIZE; + compression_alg = mach_read_from_2( + FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE + buf); break; case FIL_PAGE_PAGE_COMPRESSED: header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; + compression_alg = mach_read_from_8( + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + buf); break; default: - /* The page is not in our format. */ - return; + return srv_page_size; } - // If no buffer was given, we need to allocate temporal buffer - if (page_buf == NULL) { - in_buf = static_cast<byte *>(ut_malloc_nokey(srv_page_size)); - memset(in_buf, 0, srv_page_size); - } else { - in_buf = page_buf; + if (mach_read_from_4(buf + FIL_PAGE_SPACE_OR_CHKSUM) + != BUF_NO_CHECKSUM_MAGIC) { + return 0; } - /* Before actual decompress, make sure that page type is correct */ + ulint actual_size = mach_read_from_2(buf + FIL_PAGE_DATA); - if (mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM) - != BUF_NO_CHECKSUM_MAGIC - || (ptype != FIL_PAGE_PAGE_COMPRESSED - && ptype != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)) { - ib::error() << "Corruption: We try to uncompress corrupted " - "page CRC " - << mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM) - << " type " << ptype << " len " << len << "."; - - if (return_error) { - goto error_return; - } - ut_error; - } - - /* Get compression algorithm */ - if (ptype == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - compression_alg = static_cast<ib_uint64_t>(mach_read_from_2(buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE)); - } else { - compression_alg = mach_read_from_8(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - } - - /* Get the actual size of compressed page */ - actual_size = mach_read_from_2(buf+FIL_PAGE_DATA); /* Check if payload size is corrupted */ - if (actual_size == 0 || actual_size > srv_page_size) { - ib::error() << "Corruption: We try to uncompress corrupted page" - << " actual size: " << actual_size - << " compression method: " - << fil_get_compression_alg_name(compression_alg) - << "."; - if (return_error) { - goto error_return; - } - ut_error; - } - - /* Store actual payload size of the compressed data. This pointer - points to buffer pool. */ - if (write_size) { - *write_size = actual_size; + if (actual_size == 0 || actual_size > srv_page_size - header_len) { + return 0; } - DBUG_LOG("compress", "Preparing for decompress for len " - << actual_size << "."); - - switch(compression_alg) { + switch (compression_alg) { + default: + ib::error() << "Unknown compression algorithm " + << compression_alg; + return 0; case PAGE_ZLIB_ALGORITHM: - err= uncompress(in_buf, &len, buf+header_len, (unsigned long)actual_size); - - /* If uncompress fails it means that page is corrupted */ - if (err != Z_OK) { - goto err_exit; - if (return_error) { - goto error_return; + { + uLong len = srv_page_size; + if (Z_OK != uncompress(tmp_buf, &len, + buf + header_len, + uLong(actual_size)) + && len != srv_page_size) { + return 0; } } break; - #ifdef HAVE_LZ4 case PAGE_LZ4_ALGORITHM: - err = LZ4_decompress_fast((const char *)buf+header_len, (char *)in_buf, len); - - if (err != (int)actual_size) { - goto err_exit; - if (return_error) { - goto error_return; - } + if (LZ4_decompress_safe(reinterpret_cast<const char*>(buf) + + header_len, + reinterpret_cast<char*>(tmp_buf), + actual_size, srv_page_size) + == int(srv_page_size)) { + break; } - break; + return 0; #endif /* HAVE_LZ4 */ #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: { - ulint olen = 0; - lzo_uint olen_lzo = olen; - err = lzo1x_decompress((const unsigned char *)buf+header_len, - actual_size,(unsigned char *)in_buf, &olen_lzo, NULL); - - olen = olen_lzo; - - if (err != LZO_E_OK || (olen == 0 || olen > srv_page_size)) { - len = olen; - goto err_exit; - if (return_error) { - goto error_return; - } + lzo_uint len_lzo = srv_page_size; + if (LZO_E_OK == lzo1x_decompress_safe( + buf + header_len, + actual_size, tmp_buf, &len_lzo, NULL) + && len_lzo == srv_page_size) { + break; } - break; + return 0; } #endif /* HAVE_LZO */ #ifdef HAVE_LZMA case PAGE_LZMA_ALGORITHM: { - - lzma_ret ret; size_t src_pos = 0; size_t dst_pos = 0; uint64_t memlimit = UINT64_MAX; - ret = lzma_stream_buffer_decode( - &memlimit, - 0, - NULL, - buf+header_len, - &src_pos, - actual_size, - in_buf, - &dst_pos, - len); - - - if (ret != LZMA_OK || (dst_pos == 0 || dst_pos > srv_page_size)) { - len = dst_pos; - goto err_exit; - if (return_error) { - goto error_return; - } + if (LZMA_OK == lzma_stream_buffer_decode( + &memlimit, 0, NULL, buf + header_len, + &src_pos, actual_size, tmp_buf, &dst_pos, + srv_page_size) + && dst_pos == srv_page_size) { + break; } - - break; + return 0; } #endif /* HAVE_LZMA */ #ifdef HAVE_BZIP2 case PAGE_BZIP2_ALGORITHM: { unsigned int dst_pos = srv_page_size; - - err = BZ2_bzBuffToBuffDecompress( - (char *)in_buf, - &dst_pos, - (char *)(buf+header_len), - actual_size, - 1, - 0); - - if (err != BZ_OK || (dst_pos == 0 || dst_pos > srv_page_size)) { - len = dst_pos; - goto err_exit; - if (return_error) { - goto error_return; - } + if (BZ_OK == BZ2_bzBuffToBuffDecompress( + reinterpret_cast<char*>(tmp_buf), + &dst_pos, + reinterpret_cast<char*>(buf) + header_len, + actual_size, 1, 0) + && dst_pos == srv_page_size) { + break; } - break; + return 0; } #endif /* HAVE_BZIP2 */ #ifdef HAVE_SNAPPY - case PAGE_SNAPPY_ALGORITHM: - { - snappy_status cstatus; - ulint olen = srv_page_size; - - cstatus = snappy_uncompress( - (const char *)(buf+header_len), - (size_t)actual_size, - (char *)in_buf, - (size_t*)&olen); - - if (cstatus != SNAPPY_OK || (olen == 0 || olen > srv_page_size)) { - err = (int)cstatus; - len = olen; - goto err_exit; - if (return_error) { - goto error_return; - } + case PAGE_SNAPPY_ALGORITHM: { + size_t olen = srv_page_size; + + if (SNAPPY_OK == snappy_uncompress( + reinterpret_cast<const char*>(buf) + header_len, + actual_size, + reinterpret_cast<char*>(tmp_buf), &olen) + && olen == srv_page_size) { + break; } - - break; + return 0; } #endif /* HAVE_SNAPPY */ - default: - goto err_exit; - if (return_error) { - goto error_return; - } - break; } srv_stats.pages_page_decompressed.inc(); - - /* Copy the uncompressed page to the buffer pool, not - really any other options. */ - memcpy(buf, in_buf, len); - -error_return: - if (page_buf != in_buf) { - ut_free(in_buf); - } - - return; - -err_exit: - /* Note that as we have found the page is corrupted, so - all this could be incorrect. */ - ulint space_id = mach_read_from_4(buf+FIL_PAGE_SPACE_ID); - fil_space_t* space = fil_space_acquire_for_io(space_id); - - ib::error() << "Corruption: Page is marked as compressed" - << " space: " << space_id << " name: " - << (space ? space->name : "NULL") - << " but uncompress failed with error: " << err - << " size: " << actual_size - << " len: " << len - << " compression method: " - << fil_get_compression_alg_name(compression_alg) << "."; - - buf_page_print(buf, univ_page_size); - space->release_for_io(); - ut_ad(0); + memcpy(buf, tmp_buf, srv_page_size); + return actual_size; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9297a9560e7..811c237062d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -209,7 +209,6 @@ static char* innobase_disable_monitor_counter; static char* innobase_reset_monitor_counter; static char* innobase_reset_all_monitor_counter; -static ulong innodb_change_buffering; static ulong innodb_flush_method; /* This variable can be set in the server configure file, specifying @@ -2444,7 +2443,11 @@ innobase_mysql_tmpfile( } return hDup; #else +#ifdef F_DUPFD_CLOEXEC + int fd2 = fcntl(fd, F_DUPFD_CLOEXEC, 0); +#else int fd2 = dup(fd); +#endif my_close(fd, MYF(MY_WME)); if (fd2 < 0) { set_my_errno(errno); @@ -3079,6 +3082,83 @@ AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer put restrictions on the use of the query cache. */ +/** Check if mysql can allow the transaction to read from/store to +the query cache. +@param[in] table table object +@param[in] trx transaction object +@return whether the storing or retrieving from the query cache is permitted */ +static bool innobase_query_caching_table_check_low( + const dict_table_t* table, + trx_t* trx) +{ + /* The following conditions will decide the query cache + retrieval or storing into: + + (1) There should not be any locks on the table. + (2) Someother trx shouldn't invalidate the cache before this + transaction started. + (3) Read view shouldn't exist. If exists then the view + low_limit_id should be greater than or equal to the transaction that + invalidates the cache for the particular table. + + For read-only transaction: should satisfy (1) and (3) + For read-write transaction: should satisfy (1), (2), (3) */ + + if (lock_table_get_n_locks(table)) { + return false; + } + + if (trx->id && trx->id < table->query_cache_inv_trx_id) { + return false; + } + + return !trx->read_view.is_open() + || trx->read_view.low_limit_id() + >= table->query_cache_inv_trx_id; +} + +/** Checks if MySQL at the moment is allowed for this table to retrieve a +consistent read result, or store it to the query cache. +@param[in,out] trx transaction +@param[in] norm_name concatenation of database name, + '/' char, table name +@return whether storing or retrieving from the query cache is permitted */ +static bool innobase_query_caching_table_check( + trx_t* trx, + const char* norm_name) +{ + dict_table_t* table = dict_table_open_on_name( + norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + + if (table == NULL) { + return false; + } + + /* Start the transaction if it is not started yet */ + trx_start_if_not_started(trx, false); + + bool allow = innobase_query_caching_table_check_low(table, trx); + + dict_table_close(table, FALSE, FALSE); + + if (allow) { + /* If the isolation level is high, assign a read view for the + transaction if it does not yet have one */ + + if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ + && !srv_read_only_mode + && !trx->read_view.is_open()) { + + /* Start the transaction if it is not started yet */ + trx_start_if_not_started(trx, false); + + trx->read_view.open(trx); + } + } + + return allow; +} + /******************************************************************//** The MySQL query cache uses this to check from InnoDB if the query cache at the moment is allowed to operate on an InnoDB table. The SQL query must @@ -3154,7 +3234,7 @@ innobase_query_caching_of_table_permitted( innobase_register_trx(innodb_hton_ptr, thd, trx); - return(row_search_check_if_query_cache_permitted(trx, norm_name)); + return innobase_query_caching_table_check(trx, norm_name); } /*****************************************************************//** @@ -3857,7 +3937,6 @@ static int innodb_init_params() } DBUG_ASSERT(innodb_change_buffering <= IBUF_USE_ALL); - ibuf_use = ibuf_use_t(innodb_change_buffering); /* Check that interdependent parameters have sane values. */ if (srv_max_buf_pool_modified_pct < srv_max_dirty_pages_pct_lwm) { @@ -8222,13 +8301,12 @@ report_error: error, m_prebuilt->table->flags, m_user_thd); #ifdef WITH_WSREP - if (!error_result && - wsrep_thd_exec_mode(m_user_thd) == LOCAL_STATE && - wsrep_on(m_user_thd) && - !wsrep_consistency_check(m_user_thd) && - !wsrep_thd_ignore_table(m_user_thd)) { - if (wsrep_append_keys(m_user_thd, false, record, NULL)) - { + if (!error_result + && wsrep_on(m_user_thd) + && wsrep_thd_exec_mode(m_user_thd) == LOCAL_STATE + && !wsrep_consistency_check(m_user_thd) + && !wsrep_thd_ignore_table(m_user_thd)) { + if (wsrep_append_keys(m_user_thd, false, record, NULL)) { DBUG_PRINT("wsrep", ("row key failed")); error_result = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -11342,10 +11420,11 @@ create_index( /* Even though we've defined max_supported_key_part_length, we still do our own checking using field_lengths to be absolutely sure we don't create too long indexes. */ + ulint flags = table->flags; error = convert_error_code_to_mysql( row_create_index_for_mysql(index, trx, field_lengths), - table->flags, NULL); + flags, NULL); my_free(field_lengths); @@ -12398,12 +12477,13 @@ create_table_info_t::create_table() /* Create an index which is used as the clustered index; order the rows by their row id which is internally generated by InnoDB */ + ulint flags = m_table->flags; dict_index_t* index = dict_mem_index_create( m_table, innobase_index_reserve_name, DICT_CLUSTERED, 0); error = convert_error_code_to_mysql( row_create_index_for_mysql(index, m_trx, NULL), - m_table->flags, m_thd); + flags, m_thd); if (error) { DBUG_RETURN(error); } @@ -14304,23 +14384,22 @@ ha_innobase::optimize( This works OK otherwise, but MySQL locks the entire table during calls to OPTIMIZE, which is undesirable. */ + bool try_alter = true; if (srv_defragment) { int err= defragment_table( m_prebuilt->table->name.m_name, NULL, false); if (err == 0) { - return (HA_ADMIN_OK); + try_alter = false; } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, uint(err), "InnoDB: Cannot defragment table %s: returned error code %d\n", m_prebuilt->table->name, err); - if (err == ER_SP_ALREADY_EXISTS) { - return (HA_ADMIN_OK); - } else { - return (HA_ADMIN_TRY_ALTER); + if(err == ER_SP_ALREADY_EXISTS) { + try_alter = false; } } } @@ -14331,11 +14410,10 @@ ha_innobase::optimize( fts_sync_table(m_prebuilt->table, false, true, false); fts_optimize_table(m_prebuilt->table); } - return(HA_ADMIN_OK); - } else { - - return(HA_ADMIN_TRY_ALTER); + try_alter = false; } + + return try_alter ? HA_ADMIN_TRY_ALTER : HA_ADMIN_OK; } /*******************************************************************//** @@ -18723,8 +18801,10 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd), victim_trx->id); - WSREP_DEBUG("Aborting query: %s", - (thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void"); + WSREP_DEBUG("Aborting query: %s conf %d trx: %lu", + (thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void", + wsrep_thd_conflict_state(thd, FALSE), + wsrep_thd_ws_handle(thd)->trx_id); wsrep_thd_LOCK(thd); DBUG_EXECUTE_IF("sync.wsrep_after_BF_victim_lock", @@ -18787,7 +18867,7 @@ wsrep_innobase_kill_one_trx( wsrep_t *wsrep= get_wsrep(); rcode = wsrep->abort_pre_commit( wsrep, bf_seqno, - (wsrep_trx_id_t)victim_trx->id + (wsrep_trx_id_t)wsrep_thd_ws_handle(thd)->trx_id ); switch (rcode) { @@ -18912,12 +18992,14 @@ wsrep_abort_transaction( my_bool signal) { DBUG_ENTER("wsrep_innobase_abort_thd"); - trx_t* victim_trx = thd_to_trx(victim_thd); - trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL; - WSREP_DEBUG("abort transaction: BF: %s victim: %s", - wsrep_thd_query(bf_thd), - wsrep_thd_query(victim_thd)); + trx_t* victim_trx = thd_to_trx(victim_thd); + trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL; + + WSREP_DEBUG("abort transaction: BF: %s victim: %s victim conf: %d", + wsrep_thd_query(bf_thd), + wsrep_thd_query(victim_thd), + wsrep_thd_conflict_state(victim_thd, FALSE)); if (victim_trx) { lock_mutex_enter(); @@ -20700,6 +20782,77 @@ innobase_get_field_from_update_vector( return (NULL); } + +/** + Allocate a heap and record for calculating virtual fields + Used mainly for virtual fields in indexes + +@param[in] thd MariaDB THD +@param[in] index Index in use +@param[out] heap Heap that holds temporary row +@param[in,out] mysql_table MariaDB table +@param[out] rec Pointer to allocated MariaDB record +@param[out] storage Internal storage for blobs etc + +@return FALSE ok +@return TRUE malloc failure +*/ + +bool innobase_allocate_row_for_vcol( + THD * thd, + dict_index_t* index, + mem_heap_t** heap, + TABLE** table, + byte** record, + VCOL_STORAGE** storage) +{ + TABLE *maria_table; + String *blob_value_storage; + if (!*table) + *table= innobase_find_mysql_table_for_vc(thd, index->table); + maria_table= *table; + if (!*heap && !(*heap= mem_heap_create(srv_page_size))) + { + *storage= 0; + return TRUE; + } + *record= static_cast<byte*>(mem_heap_alloc(*heap, + maria_table->s->reclength)); + *storage= static_cast<VCOL_STORAGE*> + (mem_heap_alloc(*heap, sizeof(**storage))); + blob_value_storage= static_cast<String*> + (mem_heap_alloc(*heap, + maria_table->s->virtual_not_stored_blob_fields * + sizeof(String))); + if (!*record || !*storage || !blob_value_storage) + { + *storage= 0; + return TRUE; + } + (*storage)->maria_table= maria_table; + (*storage)->innobase_record= *record; + (*storage)->maria_record= maria_table->field[0]->record_ptr(); + (*storage)->blob_value_storage= blob_value_storage; + + maria_table->move_fields(maria_table->field, *record, + (*storage)->maria_record); + maria_table->remember_blob_values(blob_value_storage); + + return FALSE; +} + + +/** Free memory allocated by innobase_allocate_row_for_vcol() */ + +void innobase_free_row_for_vcol(VCOL_STORAGE *storage) +{ + TABLE *maria_table= storage->maria_table; + maria_table->move_fields(maria_table->field, storage->maria_record, + storage->innobase_record); + maria_table->restore_blob_values(storage->blob_value_storage); +} + + /** Get the computed value by supplying the base column values. @param[in,out] row the data row @param[in] col virtual column @@ -20725,12 +20878,12 @@ innobase_get_computed_value( const dict_field_t* ifield, THD* thd, TABLE* mysql_table, + byte* mysql_rec, const dict_table_t* old_table, upd_t* parent_update, dict_foreign_t* foreign) { byte rec_buf2[REC_VERSION_56_MAX_INDEX_COL_LEN]; - byte* mysql_rec; byte* buf; dfield_t* field; ulint len; @@ -20743,6 +20896,7 @@ innobase_get_computed_value( ut_ad(index->table->vc_templ); ut_ad(thd != NULL); + ut_ad(mysql_table); const mysql_row_templ_t* vctempl = index->table->vc_templ->vtempl[ @@ -20760,14 +20914,6 @@ innobase_get_computed_value( buf = rec_buf2; } - if (!mysql_table) { - mysql_table = innobase_find_mysql_table_for_vc(thd, index->table); - } - - ut_ad(mysql_table); - - mysql_rec = mysql_table->record[0]; - for (ulint i = 0; i < col->num_base; i++) { dict_col_t* base_col = col->base_col[i]; const dfield_t* row_field = NULL; diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index d4fda9d43c5..f2bb8aa5ef2 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -749,6 +749,9 @@ public: ulint flags() const { return(m_flags); } + /** Update table flags. */ + void flags_set(ulint flags) { m_flags |= flags; } + /** Get table flags2. */ ulint flags2() const { return(m_flags2); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 0fb0b42b9dd..63695e8b4cf 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -87,7 +87,6 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD /* | ALTER_STORED_COLUMN_TYPE */ - | ALTER_COLUMN_UNVERSIONED | ALTER_ADD_SYSTEM_VERSIONING | ALTER_DROP_SYSTEM_VERSIONING ; @@ -128,6 +127,7 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT | ALTER_ADD_VIRTUAL_COLUMN | INNOBASE_FOREIGN_OPERATIONS | ALTER_COLUMN_EQUAL_PACK_LENGTH + | ALTER_COLUMN_UNVERSIONED | ALTER_DROP_VIRTUAL_COLUMN; struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx @@ -203,8 +203,12 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx /** original column names of the table */ const char* const old_col_names; - /** Whether alter ignore issued. */ - const bool ignore; + /** Allow non-null conversion. + (1) Alter ignore should allow the conversion + irrespective of sql mode. + (2) Don't allow the conversion in strict mode + (3) Allow the conversion only in non-strict mode. */ + const bool allow_not_null; ha_innobase_inplace_ctx(row_prebuilt_t*& prebuilt_arg, dict_index_t** drop_arg, @@ -222,7 +226,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ulint add_autoinc_arg, ulonglong autoinc_col_min_value_arg, ulonglong autoinc_col_max_value_arg, - bool ignore_flag) : + bool allow_not_null_flag) : inplace_alter_handler_ctx(), prebuilt (prebuilt_arg), add_index (0), add_key_numbers (0), num_to_add_index (0), @@ -250,7 +254,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx old_n_cols(prebuilt_arg->table->n_cols), old_cols(prebuilt_arg->table->cols), old_col_names(prebuilt_arg->table->col_names), - ignore(ignore_flag) + allow_not_null(allow_not_null_flag) { ut_ad(old_n_cols >= DATA_N_SYS_COLS); #ifdef UNIV_DEBUG @@ -919,18 +923,6 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_INSTANT); } - /* Only support NULL -> NOT NULL change if strict table sql_mode - is set. Fall back to COPY for conversion if not strict tables. - In-Place will fail with an error when trying to convert - NULL to a NOT NULL value. */ - if ((ha_alter_info->handler_flags - & ALTER_COLUMN_NOT_NULLABLE) - && !thd_is_strict_mode(m_user_thd)) { - ha_alter_info->unsupported_reason = my_get_err_msg( - ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL); - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - /* DROP PRIMARY KEY is only allowed in combination with ADD PRIMARY KEY. */ if ((ha_alter_info->handler_flags @@ -1253,20 +1245,6 @@ ha_innobase::check_if_supported_inplace_alter( } break; default: - /* Changing from NULL to NOT NULL and - set the default constant values. */ - if (f->real_maybe_null() - && !(*af)->real_maybe_null()) { - - if (is_non_const_value(*af)) { - break; - } - - if (!set_default_value(*af)) { - break; - } - } - /* For any other data type, NULL values are not converted. (An AUTO_INCREMENT attribute cannot @@ -3252,20 +3230,23 @@ innobase_check_foreigns( } /** Convert a default value for ADD COLUMN. - -@param heap Memory heap where allocated -@param dfield InnoDB data field to copy to -@param field MySQL value for the column -@param comp nonzero if in compact format */ -static MY_ATTRIBUTE((nonnull)) -void -innobase_build_col_map_add( -/*=======================*/ +@param[in,out] heap Memory heap where allocated +@param[out] dfield InnoDB data field to copy to +@param[in] field MySQL value for the column +@param[in] old_field Old field or NULL if new col is added +@param[in] comp nonzero if in compact format. */ +static void innobase_build_col_map_add( mem_heap_t* heap, dfield_t* dfield, const Field* field, + const Field* old_field, ulint comp) { + if (old_field && old_field->real_maybe_null() + && field->real_maybe_null()) { + return; + } + if (field->is_real_null()) { dfield_set_null(dfield); return; @@ -3275,7 +3256,7 @@ innobase_build_col_map_add( byte* buf = static_cast<byte*>(mem_heap_alloc(heap, size)); - const byte* mysql_data = field->ptr; + const byte* mysql_data = old_field ? old_field->ptr : field->ptr; row_mysql_store_col_in_innobase_format( dfield, buf, true, mysql_data, size, comp); @@ -3362,16 +3343,15 @@ innobase_build_col_map( const Field* altered_field = altered_table->field[i + num_v]; - if (field->real_maybe_null() - && !altered_field->real_maybe_null()) { - /* Don't consider virtual column. - NULL to NOT NULL is not applicable - for virtual column. */ + if (defaults) { innobase_build_col_map_add( - heap, dtuple_get_nth_field( + heap, + dtuple_get_nth_field( defaults, i), altered_field, - dict_table_is_comp(new_table)); + field, + dict_table_is_comp( + new_table)); } col_map[old_i - num_old_v] = i; @@ -3383,6 +3363,7 @@ innobase_build_col_map( innobase_build_col_map_add( heap, dtuple_get_nth_field(defaults, i), altered_table->field[i + num_v], + NULL, dict_table_is_comp(new_table)); found_col: if (is_v) { @@ -5611,7 +5592,8 @@ new_table_failed: !(ha_alter_info->handler_flags & ALTER_ADD_PK_INDEX), ctx->defaults, ctx->col_map, path, - ctx->ignore); + old_table, + ctx->allow_not_null); rw_lock_x_unlock(&clust_index->lock); if (!ok) { @@ -5669,7 +5651,9 @@ error_handling_drop_uncached: ctx->prebuilt->trx, index, NULL, true, NULL, NULL, - path, ctx->ignore); + path, old_table, + ctx->allow_not_null); + rw_lock_x_unlock(&index->lock); if (!ok) { @@ -6452,6 +6436,13 @@ check_if_ok_to_rename: goto err_exit_no_heap; } + if (info.flags2() & DICT_TF2_USE_FILE_PER_TABLE) { + /* Preserve the DATA DIRECTORY attribute, because it + currently cannot be changed during ALTER TABLE. */ + info.flags_set(m_prebuilt->table->flags + & 1U << DICT_TF_POS_DATA_DIR); + } + max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(info.flags()); /* Check each index's column length to make sure they do not @@ -6850,7 +6841,8 @@ err_exit: ha_alter_info->online, heap, indexed_table, col_names, ULINT_UNDEFINED, 0, 0, - ha_alter_info->ignore); + (ha_alter_info->ignore + || !thd_is_strict_mode(m_user_thd))); } DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); @@ -6978,7 +6970,8 @@ found_col: heap, m_prebuilt->table, col_names, add_autoinc_col_no, ha_alter_info->create_info->auto_increment_value, - autoinc_col_max_value, ha_alter_info->ignore); + autoinc_col_max_value, + ha_alter_info->ignore || !thd_is_strict_mode(m_user_thd)); DBUG_RETURN(prepare_inplace_alter_table_dict( ha_alter_info, altered_table, table, @@ -7210,7 +7203,7 @@ ok_exit: ctx->add_index, ctx->add_key_numbers, ctx->num_to_add_index, altered_table, ctx->defaults, ctx->col_map, ctx->add_autoinc, ctx->sequence, ctx->skip_pk_sort, - ctx->m_stage, add_v, eval_table); + ctx->m_stage, add_v, eval_table, ctx->allow_not_null); #ifndef DBUG_OFF oom: @@ -7219,7 +7212,7 @@ oom: DEBUG_SYNC_C("row_log_table_apply1_before"); error = row_log_table_apply( ctx->thr, m_prebuilt->table, altered_table, - ctx->m_stage); + ctx->m_stage, ctx->new_table); } /* Init online ddl status variables */ @@ -8433,6 +8426,188 @@ innobase_update_foreign_cache( DBUG_RETURN(err); } +/** Changes SYS_COLUMNS.PRTYPE for one column. +@param[in,out] trx transaction +@param[in] table_name table name +@param[in] tableid table ID as in SYS_TABLES +@param[in] pos column position +@param[in] prtype new precise type +@return boolean flag +@retval true on failure +@retval false on success */ +static +bool +change_field_versioning_try( + trx_t* trx, + const char* table_name, + const table_id_t tableid, + const ulint pos, + const ulint prtype) +{ + DBUG_ENTER("change_field_versioning_try"); + + pars_info_t* info = pars_info_create(); + + pars_info_add_int4_literal(info, "prtype", prtype); + pars_info_add_ull_literal(info,"tableid", tableid); + pars_info_add_int4_literal(info, "pos", pos); + + dberr_t error = que_eval_sql(info, + "PROCEDURE CHANGE_COLUMN_MTYPE () IS\n" + "BEGIN\n" + "UPDATE SYS_COLUMNS SET PRTYPE=:prtype\n" + "WHERE TABLE_ID=:tableid AND POS=:pos;\n" + "END;\n", + false, trx); + + if (error != DB_SUCCESS) { + my_error_innodb(error, table_name, 0); + trx->error_state = DB_SUCCESS; + trx->op_info = ""; + DBUG_RETURN(true); + } + + DBUG_RETURN(false); +} + +/** Changes fields WITH/WITHOUT SYSTEM VERSIONING property in SYS_COLUMNS. +@param[in] ha_alter_info alter info +@param[in] ctx alter inplace context +@param[in] trx transaction +@param[in] table old table +@return boolean flag +@retval true on failure +@retval false on success */ +static +bool +change_fields_versioning_try( + const Alter_inplace_info* ha_alter_info, + const ha_innobase_inplace_ctx* ctx, + trx_t* trx, + const TABLE* table) +{ + DBUG_ENTER("change_fields_versioning_try"); + + DBUG_ASSERT(ha_alter_info); + DBUG_ASSERT(ctx); + + if (!(ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED)){ + DBUG_RETURN(false); + } + + uint virtual_count = 0; + + List_iterator_fast<Create_field> it( + ha_alter_info->alter_info->create_list); + + for (uint i = 0; i < table->s->fields; i++) { + const Field* field = table->field[i]; + + if (innobase_is_v_fld(field)) { + virtual_count++; + continue; + } + + const Create_field* create_field = NULL; + while (const Create_field* cf = it++) { + if (cf->field == field) { + create_field = cf; + break; + } + } + it.rewind(); + DBUG_ASSERT(create_field); + + if (create_field->versioning + == Column_definition::VERSIONING_NOT_SET) { + continue; + } + + const dict_table_t* new_table = ctx->new_table; + ulint pos = i - virtual_count; + const dict_col_t* col = dict_table_get_nth_col(new_table, pos); + + DBUG_ASSERT(!col->vers_sys_start()); + DBUG_ASSERT(!col->vers_sys_end()); + + ulint new_prtype + = create_field->versioning + == Column_definition::WITHOUT_VERSIONING + ? col->prtype & ~DATA_VERSIONED + : col->prtype | DATA_VERSIONED; + + if (change_field_versioning_try(trx, table->s->table_name.str, + new_table->id, pos, + new_prtype)) { + DBUG_RETURN(true); + } + } + + DBUG_RETURN(false); +} + +/** Changes WITH/WITHOUT SYSTEM VERSIONING for fields +in the data dictionary cache. +@param ha_alter_info Data used during in-place alter +@param ctx In-place ALTER TABLE context +@param table MySQL table as it is before the ALTER operation */ +static +void +change_fields_versioning_cache( + Alter_inplace_info* ha_alter_info, + const ha_innobase_inplace_ctx* ctx, + const TABLE* table) +{ + DBUG_ENTER("change_fields_versioning"); + + DBUG_ASSERT(ha_alter_info); + DBUG_ASSERT(ctx); + DBUG_ASSERT(ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED); + + uint virtual_count = 0; + + List_iterator_fast<Create_field> it( + ha_alter_info->alter_info->create_list); + + for (uint i = 0; i < table->s->fields; i++) { + const Field* field = table->field[i]; + + if (innobase_is_v_fld(field)) { + virtual_count++; + continue; + } + + const Create_field* create_field = NULL; + while (const Create_field* cf = it++) { + if (cf->field == field) { + create_field = cf; + break; + } + } + it.rewind(); + DBUG_ASSERT(create_field); + + dict_col_t* col + = dict_table_get_nth_col(ctx->new_table, i - virtual_count); + + if (create_field->versioning + == Column_definition::WITHOUT_VERSIONING) { + + DBUG_ASSERT(!col->vers_sys_start()); + DBUG_ASSERT(!col->vers_sys_end()); + col->prtype &= ~DATA_VERSIONED; + } else if (create_field->versioning + == Column_definition::WITH_VERSIONING) { + + DBUG_ASSERT(!col->vers_sys_start()); + DBUG_ASSERT(!col->vers_sys_end()); + col->prtype |= DATA_VERSIONED; + } + } + + DBUG_VOID_RETURN; +} + /** Commit the changes made during prepare_inplace_alter_table() and inplace_alter_table() inside the data dictionary tables, when rebuilding the table. @@ -8517,7 +8692,8 @@ commit_try_rebuild( error = row_log_table_apply( ctx->thr, user_table, altered_table, static_cast<ha_innobase_inplace_ctx*>( - ha_alter_info->handler_ctx)->m_stage); + ha_alter_info->handler_ctx)->m_stage, + ctx->new_table); if (s_templ) { ut_ad(ctx->need_rebuild()); @@ -8742,6 +8918,10 @@ commit_try_norebuild( DBUG_RETURN(true); } + if (change_fields_versioning_try(ha_alter_info, ctx, trx, old_table)) { + DBUG_RETURN(true); + } + dberr_t error; /* We altered the table in place. Mark the indexes as committed. */ @@ -8947,6 +9127,10 @@ commit_cache_norebuild( ha_alter_info, table, ctx->new_table); } + if (ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED) { + change_fields_versioning_cache(ha_alter_info, ctx, table); + } + #ifdef MYSQL_RENAME_INDEX rename_indexes_in_cache(ctx, ha_alter_info); #endif @@ -9797,12 +9981,11 @@ foreign_fail: error = row_merge_drop_table(trx, ctx->old_table); if (error != DB_SUCCESS) { - ib::error() << "Inplace alter table " << ctx->old_table->name.m_name + ib::error() << "Inplace alter table " << ctx->old_table->name << " dropping copy of the old table failed error " << error << ". tmp_name " << (ctx->tmp_name ? ctx->tmp_name : "N/A") - << " new_table " << (ctx->new_table ? ctx->new_table->name.m_name - : "N/A"); + << " new_table " << ctx->new_table->name; } trx_commit_for_mysql(trx); diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 04cee74e6ea..13d58e45ee8 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -185,7 +185,7 @@ it uses synchronous aio, it can access any pages, as long as it obeys the access order rules. */ /** Operations that can currently be buffered. */ -ibuf_use_t ibuf_use = IBUF_USE_ALL; +ulong innodb_change_buffering; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG /** Flag to control insert buffer debugging. */ @@ -3695,9 +3695,9 @@ ibuf_insert( dberr_t err; ulint entry_size; ibool no_counter; - /* Read the settable global variable ibuf_use only once in + /* Read the settable global variable only once in this function, so that we will have a consistent view of it. */ - ibuf_use_t use = ibuf_use; + ibuf_use_t use = ibuf_use_t(innodb_change_buffering); DBUG_ENTER("ibuf_insert"); DBUG_PRINT("ibuf", ("op: %d, space: " UINT32PF ", page_no: " UINT32PF, @@ -5012,6 +5012,11 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space) continue; } + if (!bitmap_page) { + mutex_exit(&ibuf_mutex); + return DB_CORRUPTION; + } + for (i = FSP_IBUF_BITMAP_OFFSET + 1; i < page_size.physical(); i++) { diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 9136c25acfd..33612f85ed6 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -41,6 +41,7 @@ Created 11/5/1995 Heikki Tuuri #include "os0proc.h" #include "log0log.h" #include "srv0srv.h" +#include "my_atomic.h" #include <ostream> // Forward declaration @@ -1506,8 +1507,10 @@ NOTE! The definition appears here only for other modules of this directory (buf) to see it. Do not use from outside! */ typedef struct { - bool reserved; /*!< true if this slot is reserved +private: + int32 reserved; /*!< true if this slot is reserved */ +public: byte* crypt_buf; /*!< for encryption the data needs to be copied to a separate buffer before it's encrypted&written. this as a page can be @@ -1518,6 +1521,21 @@ typedef struct { byte* out_buf; /*!< resulting buffer after encryption/compression. This is a pointer and not allocated. */ + + /** Release the slot */ + void release() + { + my_atomic_store32_explicit(&reserved, false, + MY_MEMORY_ORDER_RELAXED); + } + + /** Acquire the slot + @return whether the slot was acquired */ + bool acquire() + { + return !my_atomic_fas32_explicit(&reserved, true, + MY_MEMORY_ORDER_RELAXED); + } } buf_tmp_buffer_t; /** The common buffer control block structure diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index f811b5a6811..dd7129a86ac 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -53,9 +53,11 @@ These are low-level functions #ifdef BTR_CUR_HASH_ADAPT struct dict_table_t; -/** Drop the adaptive hash index for a tablespace. -@param[in,out] table table */ -void buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table); +/** Try to drop the adaptive hash index for a tablespace. +@param[in,out] table table +@return whether anything was dropped */ +bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table) + MY_ATTRIBUTE((warn_unused_result,nonnull)); #else # define buf_LRU_drop_page_hash_for_tablespace(table) #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 154a503f1b3..948b244a7fc 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1737,8 +1737,8 @@ struct dict_table_t { /** Transactions whose view low limit is greater than this number are not allowed to store to the MySQL query cache or retrieve from it. When a trx with undo logs commits, it sets this to the value of the - current time. */ - trx_id_t query_cache_inv_id; + transaction id. */ + trx_id_t query_cache_inv_trx_id; /** Transaction id that last touched the table definition. Either when loading the definition or CREATE TABLE, or ALTER TABLE (prepare, diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 8f4e9d10fd9..968fd1573c6 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -85,10 +85,6 @@ struct fil_space_t { Protected by log_sys.mutex. If and only if this is nonzero, the tablespace will be in named_spaces. */ - bool stop_ios;/*!< true if we want to rename the - .ibd file of tablespace and want to - stop temporarily posting of new i/o - requests on the file */ bool stop_new_ops; /*!< we set this true when we start deleting a single-table tablespace. @@ -176,9 +172,6 @@ struct fil_space_t { /** MariaDB encryption data */ fil_space_crypt_t* crypt_data; - /** True if we have already printed compression failure */ - bool printed_compression_failure; - /** True if the device this filespace is on supports atomic writes */ bool atomic_write_supported; diff --git a/storage/innobase/include/fil0fil.ic b/storage/innobase/include/fil0fil.ic index 1dd4c64f73e..2a7d06e243f 100644 --- a/storage/innobase/include/fil0fil.ic +++ b/storage/innobase/include/fil0fil.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2018, 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 the Free Software diff --git a/storage/innobase/include/fil0pagecompress.h b/storage/innobase/include/fil0pagecompress.h index be10f99d0f0..1046d720102 100644 --- a/storage/innobase/include/fil0pagecompress.h +++ b/storage/innobase/include/fil0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2017 MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2018 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 the Free Software @@ -30,40 +30,24 @@ atomic writes information to table space. Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com ***********************************************************************/ -/****************************************************************//** -For page compressed pages compress the page before actual write -operation. -@return compressed page to be written*/ -UNIV_INTERN -byte* -fil_compress_page( -/*==============*/ - fil_space_t* space, /*!< in,out: tablespace (NULL during IMPORT) */ - byte* buf, /*!< in: buffer from which to write; in aio - this must be appropriately aligned */ - byte* out_buf, /*!< out: compressed buffer */ - ulint len, /*!< in: length of input buffer.*/ - ulint level, /* in: compression level */ - ulint block_size, /*!< in: block size */ - bool encrypted, /*!< in: is page also encrypted */ - ulint* out_len); /*!< out: actual length of compressed - page */ - -/****************************************************************//** -For page compressed pages decompress the page after actual read -operation. */ -UNIV_INTERN -void -fil_decompress_page( -/*================*/ - byte* page_buf, /*!< in: preallocated buffer or NULL */ - byte* buf, /*!< out: buffer from which to read; in aio - this must be appropriately aligned */ - ulong len, /*!< in: length of output buffer.*/ - ulint* write_size, /*!< in/out: Actual payload size of - the compressed data. */ - bool return_error=false); - /*!< in: true if only an error should - be produced when decompression fails. - By default this parameter is false. */ +/** Compress a page_compressed page before writing to a data file. +@param[in] buf page to be compressed +@param[out] out_buf compressed page +@param[in] level compression level +@param[in] block_size file system block size +@param[in] encrypted whether the page will be subsequently encrypted +@return actual length of compressed page +@retval 0 if the page was not compressed */ +ulint fil_page_compress(const byte* buf, byte* out_buf, ulint level, + ulint block_size, bool encrypted) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + +/** Decompress a page that may be subject to page_compressed compression. +@param[in,out] tmp_buf temporary buffer (of innodb_page_size) +@param[in,out] buf compressed page buffer +@return size of the compressed data +@retval 0 if decompression failed +@retval srv_page_size if the page was not compressed */ +ulint fil_page_decompress(byte* tmp_buf, byte* buf) + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index 161d7a30ea4..3222f1c761a 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -686,7 +686,7 @@ fsp_flags_convert_from_101(ulint flags) /* Bits 13..16 are the wrong position for PAGE_SSIZE, and they should contain one of the values 3,4,6,7, that is, be of the form - 0b0011 or 0b01xx (except 0b0110). + 0b0011 or 0b01xx (except 0b0101). In correct versions, these bits should be 0bc0se where c is the MariaDB COMPRESSED flag and e is the MySQL 5.7 ENCRYPTION flag diff --git a/storage/innobase/include/fsp0pagecompress.ic b/storage/innobase/include/fsp0pagecompress.ic index d1f2ea45fbd..5285a7c238f 100644 --- a/storage/innobase/include/fsp0pagecompress.ic +++ b/storage/innobase/include/fsp0pagecompress.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2018, 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 the Free Software @@ -39,18 +39,6 @@ fsp_flags_get_page_compression_level( /*******************************************************************//** -Find out wheather the page is index page or not -@return true if page type index page, false if not */ -UNIV_INLINE -bool -fil_page_is_index_page( -/*===================*/ - byte* buf) /*!< in: page */ -{ - return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_INDEX); -} - -/*******************************************************************//** Find out wheather the page is page compressed @return true if page is page compressed, false if not */ UNIV_INLINE @@ -73,59 +61,3 @@ fil_page_is_compressed_encrypted( { return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); } - -/****************************************************************//** -Get the name of the compression algorithm used for page -compression. -@return compression algorithm name or "UNKNOWN" if not known*/ -UNIV_INLINE -const char* -fil_get_compression_alg_name( -/*=========================*/ - ib_uint64_t comp_alg) /*!<in: compression algorithm number */ -{ - switch(comp_alg) { - case PAGE_UNCOMPRESSED: - return ("uncompressed"); - break; - case PAGE_ZLIB_ALGORITHM: - return ("ZLIB"); - break; - case PAGE_LZ4_ALGORITHM: - return ("LZ4"); - break; - case PAGE_LZO_ALGORITHM: - return ("LZO"); - break; - case PAGE_LZMA_ALGORITHM: - return ("LZMA"); - break; - case PAGE_BZIP2_ALGORITHM: - return ("BZIP2"); - break; - case PAGE_SNAPPY_ALGORITHM: - return ("SNAPPY"); - break; - /* No default to get compiler warning */ - } - - return ("NULL"); -} - -#ifndef UNIV_INNOCHECKSUM -/*******************************************************************//** -Find out wheather the page is page compressed with lzo method -@return true if page is page compressed with lzo method, false if not */ -UNIV_INLINE -bool -fil_page_is_lzo_compressed( -/*=======================*/ - byte* buf) /*!< in: page */ -{ - return((mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED && - mach_read_from_8(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) == PAGE_LZO_ALGORITHM) || - (mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED && - mach_read_from_2(buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE) == PAGE_LZO_ALGORITHM)); -} - -#endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index b5e3d1eddf7..8233a536abc 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -61,7 +61,7 @@ enum ibuf_use_t { }; /** Operations that can currently be buffered. */ -extern ibuf_use_t ibuf_use; +extern ulong innodb_change_buffering; /** The insert buffer control structure */ extern ibuf_t* ibuf; diff --git a/storage/innobase/include/ibuf0ibuf.ic b/storage/innobase/include/ibuf0ibuf.ic index f91ae5aee4a..355fad62f24 100644 --- a/storage/innobase/include/ibuf0ibuf.ic +++ b/storage/innobase/include/ibuf0ibuf.ic @@ -124,7 +124,7 @@ ibuf_should_try( a secondary index when we decide */ { - return(ibuf_use != IBUF_USE_NONE + return(innodb_change_buffering && ibuf->max_size != 0 && !dict_index_is_clust(index) && !dict_index_is_spatial(index) diff --git a/storage/innobase/include/row0log.h b/storage/innobase/include/row0log.h index 6974ce1b56b..723cf310f95 100644 --- a/storage/innobase/include/row0log.h +++ b/storage/innobase/include/row0log.h @@ -61,7 +61,9 @@ row_log_allocate( const ulint* col_map,/*!< in: mapping of old column numbers to new ones, or NULL if !table */ const char* path, /*!< in: where to create temporary file */ - bool ignore) /*!< in: Whether alter ignore issued */ + const TABLE* old_table, /*!< in:table definition before alter */ + bool allow_not_null) /*!< in: allow null to non-null + conversion */ MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /******************************************************//** @@ -209,13 +211,15 @@ row_log_table_blob_alloc( @param[in,out] stage performance schema accounting object, used by ALTER TABLE. stage->begin_phase_log_table() will be called initially and then stage->inc() will be called for each block of log that is applied. +@param[in] new_table Altered table @return DB_SUCCESS, or error code on failure */ dberr_t row_log_table_apply( que_thr_t* thr, dict_table_t* old_table, struct TABLE* table, - ut_stage_alter_t* stage) + ut_stage_alter_t* stage, + dict_table_t* new_table) MY_ATTRIBUTE((warn_unused_result)); /******************************************************//** diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index 7330031c186..ad4005239c3 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -322,6 +322,7 @@ this function and it will be passed to other functions for further accounting. @param[in] add_v new virtual columns added along with indexes @param[in] eval_table mysql table used to evaluate virtual column value, see innobase_get_computed_value(). +@param[in] allow_non_null allow the conversion from null to not-null @return DB_SUCCESS or error code */ dberr_t row_merge_build_indexes( @@ -340,7 +341,8 @@ row_merge_build_indexes( bool skip_pk_sort, ut_stage_alter_t* stage, const dict_add_v_col_t* add_v, - struct TABLE* eval_table) + struct TABLE* eval_table, + bool allow_non_null) MY_ATTRIBUTE((warn_unused_result)); /********************************************************************//** diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 7c0b5d3ece9..4d8b055e13f 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -879,6 +879,44 @@ struct SysIndexCallback { virtual void operator()(mtr_t* mtr, btr_pcur_t* pcur) throw() = 0; }; + +/** Storage for calculating virtual columns */ + +class String; +struct VCOL_STORAGE +{ + TABLE *maria_table; + byte *innobase_record; + byte *maria_record; + String *blob_value_storage; +}; + +/** + Allocate a heap and record for calculating virtual fields + Used mainly for virtual fields in indexes + +@param[in] thd MariaDB THD +@param[in] index Index in use +@param[out] heap Heap that holds temporary row +@param[in,out] mysql_table MariaDB table +@param[out] rec Pointer to allocated MariaDB record +@param[out] storage Internal storage for blobs etc + +@return FALSE ok +@return TRUE malloc failure +*/ + +bool innobase_allocate_row_for_vcol( + THD * thd, + dict_index_t* index, + mem_heap_t** heap, + TABLE** table, + byte** record, + VCOL_STORAGE** storage); + +/** Free memory allocated by innobase_allocate_row_for_vcol() */ +void innobase_free_row_for_vcol(VCOL_STORAGE *storage); + /** Get the computed value by supplying the base column values. @param[in,out] row the data row @param[in] col virtual column @@ -903,6 +941,7 @@ innobase_get_computed_value( const dict_field_t* ifield, THD* thd, TABLE* mysql_table, + byte* mysql_rec, const dict_table_t* old_table, upd_t* parent_update, dict_foreign_t* foreign); diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index 366c24acec8..ef0ccbbda9f 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -212,16 +212,6 @@ row_count_rtree_recs( ulint* n_rows); /*!< out: number of entries seen in the consistent read */ -/*******************************************************************//** -Checks if MySQL at the moment is allowed for this table to retrieve a -consistent read result, or store it to the query cache. -@return whether storing or retrieving from the query cache is permitted */ -bool -row_search_check_if_query_cache_permitted( -/*======================================*/ - trx_t* trx, /*!< in: transaction object */ - const char* norm_name); /*!< in: concatenation of database name, - '/' char, table name */ /** Read the max AUTOINC value from an index. @param[in] index index starting with an AUTO_INCREMENT column @return the largest AUTO_INCREMENT value diff --git a/storage/innobase/include/ut0timer.h b/storage/innobase/include/ut0timer.h index ea4dddec683..71bcd29cf48 100644 --- a/storage/innobase/include/ut0timer.h +++ b/storage/innobase/include/ut0timer.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, SkySQL Ab. All Rights Reserved. +Copyright (c) 2014, 2018, 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 the Free Software @@ -19,7 +19,7 @@ this program; if not, write to the Free Software Foundation, Inc., /********************************************************************//** @file include/ut0timer.h -Timer rountines +Timer routines Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 @@ -28,8 +28,6 @@ modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11 #define ut0timer_h #include "univ.i" -#include "data0type.h" -#include <my_rdtsc.h> /* Current timer stats */ extern struct my_timer_unit_info ut_timer; @@ -48,39 +46,6 @@ UNIV_INTERN void ut_init_timer(void); /**************************************************************//** -Return time passed since time then, automatically adjusted -for the estimated timer overhead. -@return time passed since "then" */ -UNIV_INLINE -ulonglong -ut_timer_since( -/*===========*/ - ulonglong then); /*!< in: time where to calculate */ -/**************************************************************//** -Get time passed since "then", and update then to now -@return time passed sinche "then" */ -UNIV_INLINE -ulonglong -ut_timer_since_and_update( -/*======================*/ - ulonglong *then); /*!< in: time where to calculate */ -/**************************************************************//** -Convert native timer units in a ulonglong into seconds in a double -@return time in a seconds */ -UNIV_INLINE -double -ut_timer_to_seconds( -/*=================*/ - ulonglong when); /*!< in: time where to calculate */ -/**************************************************************//** -Convert native timer units in a ulonglong into milliseconds in a double -@return time in milliseconds */ -UNIV_INLINE -double -ut_timer_to_milliseconds( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ -/**************************************************************//** Convert native timer units in a ulonglong into microseconds in a double @return time in microseconds */ UNIV_INLINE diff --git a/storage/innobase/include/ut0timer.ic b/storage/innobase/include/ut0timer.ic index 46dcd0cb718..34886481efa 100644 --- a/storage/innobase/include/ut0timer.ic +++ b/storage/innobase/include/ut0timer.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, SkySQL Ab. All Rights Reserved. +Copyright (c) 2014, 2018, 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 the Free Software @@ -19,70 +19,13 @@ this program; if not, write to the Free Software Foundation, Inc., /********************************************************************//** @file include/ut0timer.ic -Timer rountines +Timer routines Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 *************************************************************************/ /**************************************************************//** -Return time passed since time then, automatically adjusted -for the estimated timer overhead. -@return time passed since "then" */ -UNIV_INLINE -ulonglong -ut_timer_since( -/*===========*/ - ulonglong then) /*!< in: time where to calculate */ -{ - return (ut_timer_now() - then) - ut_timer.overhead; -} - -/**************************************************************//** -Get time passed since "then", and update then to now -@return time passed sinche "then" */ -UNIV_INLINE -ulonglong -ut_timer_since_and_update( -/*======================*/ - ulonglong *then) /*!< in: time where to calculate */ -{ - ulonglong now = ut_timer_now(); - ulonglong ret = (now - (*then)) - ut_timer.overhead; - *then = now; - return ret; -} - -/**************************************************************//** -Convert native timer units in a ulonglong into seconds in a double -@return time in a seconds */ -UNIV_INLINE -double -ut_timer_to_seconds( -/*=================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)(when); - ret /= (double)(ut_timer.frequency); - return ret; -} - -/**************************************************************//** -Convert native timer units in a ulonglong into milliseconds in a double -@return time in milliseconds */ -UNIV_INLINE -double -ut_timer_to_milliseconds( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)(when); - ret *= 1000.0; - ret /= (double)(ut_timer.frequency); - return ret; -} - -/**************************************************************//** Convert native timer units in a ulonglong into microseconds in a double @return time in microseconds */ UNIV_INLINE diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index b5494ef7313..4987d60dd5a 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -4325,7 +4325,7 @@ lock_release( block the use of the MySQL query cache for all currently active transactions. */ - table->query_cache_inv_id = max_trx_id; + table->query_cache_inv_trx_id = max_trx_id; } lock_table_dequeue(lock); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index b2c66bd389b..1f1829370c3 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1684,6 +1684,11 @@ recv_recover_page(bool just_read_in, buf_block_t* block) ut_ad(recv_needed_recovery); + if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) { + fprintf(stderr, "Applying log to page %u:%u\n", + recv_addr->space, recv_addr->page_no); + } + DBUG_LOG("ib_log", "Applying log to page " << block->page.id); recv_addr->state = RECV_BEING_PROCESSED; @@ -1779,6 +1784,13 @@ recv_recover_page(bool just_read_in, buf_block_t* block) start_lsn = recv->start_lsn; } + if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) { + fprintf(stderr, "apply " LSN_PF ":" + " %d len " ULINTPF " page %u:%u\n", + recv->start_lsn, recv->type, recv->len, + recv_addr->space, recv_addr->page_no); + } + DBUG_LOG("ib_log", "apply " << recv->start_lsn << ": " << get_mlog_string(recv->type) << " len " << recv->len @@ -2327,6 +2339,16 @@ loop: compile_time_assert(SIZE_OF_MLOG_CHECKPOINT == 1 + 8); lsn = mach_read_from_8(ptr + 1); + if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) { + fprintf(stderr, + "MLOG_CHECKPOINT(" LSN_PF ") %s at " + LSN_PF "\n", lsn, + lsn != checkpoint_lsn ? "ignored" + : recv_sys->mlog_checkpoint_lsn + ? "reread" : "read", + recv_sys->recovered_lsn); + } + DBUG_PRINT("ib_log", ("MLOG_CHECKPOINT(" LSN_PF ") %s at " LSN_PF, diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 8dcf936532a..5d9ad7bab67 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -749,6 +749,23 @@ os_file_handle_error_no_exit( name, operation, false, on_error_silent)); } +/** Handle RENAME error. +@param name old name of the file +@param new_name new name of the file */ +static void os_file_handle_rename_error(const char* name, const char* new_name) +{ + if (os_file_get_last_error(true) != OS_FILE_DISK_FULL) { + ib::error() << "Cannot rename file '" << name << "' to '" + << new_name << "'"; + } else if (!os_has_said_disk_full) { + os_has_said_disk_full = true; + /* Disk full error is reported irrespective of the + on_error_silent setting. */ + ib::error() << "Full disk prevents renaming file '" + << name << "' to '" << new_name << "'"; + } +} + /** Does simulated AIO. This function should be called by an i/o-handler thread. @@ -773,9 +790,7 @@ os_aio_simulated_handler( #ifdef _WIN32 static HANDLE win_get_syncio_event(); -#endif -#ifdef _WIN32 /** Wrapper around Windows DeviceIoControl() function. @@ -2688,7 +2703,7 @@ os_file_create_simple_func( bool retry; do { - file = open(name, create_flag, os_innodb_umask); + file = open(name, create_flag | O_CLOEXEC, os_innodb_umask); if (file == -1) { *success = false; @@ -2990,7 +3005,7 @@ os_file_create_func( bool retry; do { - file = open(name, create_flag, os_innodb_umask); + file = open(name, create_flag | O_CLOEXEC, os_innodb_umask); if (file == -1) { const char* operation; @@ -3124,7 +3139,7 @@ os_file_create_simple_no_error_handling_func( return(OS_FILE_CLOSED); } - file = open(name, create_flag, os_innodb_umask); + file = open(name, create_flag | O_CLOEXEC, os_innodb_umask); *success = (file != -1); @@ -3227,7 +3242,7 @@ os_file_rename_func( ret = rename(oldpath, newpath); if (ret != 0) { - os_file_handle_error_no_exit(oldpath, "rename", FALSE); + os_file_handle_rename_error(oldpath, newpath); return(false); } @@ -3844,7 +3859,8 @@ os_file_create_simple_func( /* Use default security attributes and no template file. */ file = CreateFile( - (LPCTSTR) name, access, FILE_SHARE_READ, NULL, + (LPCTSTR) name, access, + FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, create_flag, attributes, NULL); if (file == INVALID_HANDLE_VALUE) { @@ -4088,7 +4104,7 @@ os_file_create_func( DWORD create_flag; DWORD share_mode = srv_operation != SRV_OPERATION_NORMAL ? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE - : FILE_SHARE_READ; + : FILE_SHARE_READ | FILE_SHARE_DELETE; if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) { WAIT_ALLOW_WRITES(); @@ -4294,7 +4310,7 @@ os_file_create_simple_no_error_handling_func( DWORD attributes = 0; DWORD share_mode = srv_operation != SRV_OPERATION_NORMAL ? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE - : FILE_SHARE_READ; + : FILE_SHARE_READ | FILE_SHARE_DELETE; ut_a(name); @@ -4507,8 +4523,7 @@ os_file_rename_func( return(true); } - os_file_handle_error_no_exit(oldpath, "rename", false); - + os_file_handle_rename_error(oldpath, newpath); return(false); } @@ -4975,12 +4990,12 @@ os_file_write_func( << offset << ", " << n << " bytes should have been written," " only " << n_bytes << " were written." - " Operating system error number " << errno << "." + " Operating system error number " << IF_WIN(GetLastError(),errno) << "." " Check that your OS and file system" " support files of this size." " Check also that the disk is not full" " or a disk quota exceeded."; - +#ifndef _WIN32 if (strerror(errno) != NULL) { ib::error() @@ -4989,7 +5004,7 @@ os_file_write_func( } ib::info() << OPERATING_SYSTEM_ERROR_MSG; - +#endif os_has_said_disk_full = true; } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 4746eb0aab8..0357804f617 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -40,6 +40,12 @@ Created 2012-02-08 by Sunny Bains. #include "fil0pagecompress.h" #include "trx0undo.h" #include "ut0new.h" +#ifdef HAVE_LZO +#include "lzo/lzo1x.h" +#endif +#ifdef HAVE_SNAPPY +#include "snappy-c.h" +#endif #include <vector> @@ -406,12 +412,9 @@ public: updated then its state must be set to BUF_PAGE_NOT_USED. For compressed tables the page descriptor memory will be at offset: block->frame + srv_page_size; - @param offset - physical offset within the file - @param block - block read from file, note it is not from the buffer pool + @param block block read from file, note it is not from the buffer pool @retval DB_SUCCESS or error code. */ - virtual dberr_t operator()( - os_offset_t offset, - buf_block_t* block) UNIV_NOTHROW = 0; + virtual dberr_t operator()(buf_block_t* block) UNIV_NOTHROW = 0; /** @return the tablespace identifier */ ulint get_space_id() const { return m_space; } @@ -628,12 +631,9 @@ struct FetchIndexRootPages : public AbstractCallback { virtual ~FetchIndexRootPages() UNIV_NOTHROW { } /** Called for each block as it is read from the file. - @param offset physical offset in the file @param block block to convert, it is not from the buffer pool. @retval DB_SUCCESS or error code. */ - virtual dberr_t operator() ( - os_offset_t offset, - buf_block_t* block) UNIV_NOTHROW; + dberr_t operator()(buf_block_t* block) UNIV_NOTHROW; /** Update the import configuration that will be used to import the tablespace. */ @@ -650,13 +650,9 @@ struct FetchIndexRootPages : public AbstractCallback { determine the exact row format. We can't get that from the tablespace header flags alone. -@param offset physical offset in the file @param block block to convert, it is not from the buffer pool. @retval DB_SUCCESS or error code. */ -dberr_t -FetchIndexRootPages::operator() ( - os_offset_t offset, - buf_block_t* block) UNIV_NOTHROW +dberr_t FetchIndexRootPages::operator()(buf_block_t* block) UNIV_NOTHROW { if (is_interrupted()) return DB_INTERRUPTED; @@ -664,15 +660,7 @@ FetchIndexRootPages::operator() ( ulint page_type = fil_page_get_type(page); - if (block->page.id.page_no() * m_page_size.physical() != offset) { - - ib::error() << "Page offset doesn't match file offset:" - " page offset: " << block->page.id.page_no() - << ", file offset: " - << (offset / m_page_size.physical()); - - return DB_CORRUPTION; - } else if (page_type == FIL_PAGE_TYPE_XDES) { + if (page_type == FIL_PAGE_TYPE_XDES) { return set_current_xdes(block->page.id.page_no(), page); } else if (fil_page_index_page_check(page) && !is_free(block->page.id.page_no()) @@ -826,12 +814,9 @@ public: } /** Called for each block as it is read from the file. - @param offset physical offset in the file @param block block to convert, it is not from the buffer pool. @retval DB_SUCCESS or error code. */ - virtual dberr_t operator() ( - os_offset_t offset, - buf_block_t* block) UNIV_NOTHROW; + dberr_t operator()(buf_block_t* block) UNIV_NOTHROW; private: /** Update the page, set the space id, max trx id and index id. @param block block read from file @@ -1948,8 +1933,7 @@ PageConverter::update_page( updated then its state must be set to BUF_PAGE_NOT_USED. @param block block read from file, note it is not from the buffer pool @retval DB_SUCCESS or error code. */ -dberr_t -PageConverter::operator() (os_offset_t, buf_block_t* block) UNIV_NOTHROW +dberr_t PageConverter::operator()(buf_block_t* block) UNIV_NOTHROW { /* If we already had an old page with matching number in the buffer pool, evict it now, because @@ -3285,15 +3269,29 @@ fil_iterate( const ulint size = callback.get_page_size().physical(); ulint n_bytes = iter.n_io_buffers * size; + const ulint buf_size = srv_page_size +#ifdef HAVE_LZO + + LZO1X_1_15_MEM_COMPRESS +#elif defined HAVE_SNAPPY + + snappy_max_compressed_length(srv_page_size) +#endif + ; + byte* page_compress_buf = static_cast<byte*>(malloc(buf_size)); ut_ad(!srv_read_only_mode); + if (!page_compress_buf) { + return DB_OUT_OF_MEMORY; + } + /* TODO: For ROW_FORMAT=COMPRESSED tables we do a lot of useless copying for non-index pages. Unfortunately, it is required by buf_zip_decompress() */ + dberr_t err = DB_SUCCESS; for (offset = iter.start; offset < iter.end; offset += n_bytes) { if (callback.is_interrupted()) { - return DB_INTERRUPTED; + err = DB_INTERRUPTED; + goto func_exit; } byte* io_buffer = iter.io_buffer; @@ -3323,11 +3321,12 @@ fil_iterate( IORequest read_request(IORequest::READ); read_request.disable_partial_io_warnings(); - dberr_t err = os_file_read_no_error_handling( + err = os_file_read_no_error_handling( read_request, iter.file, readptr, offset, n_bytes, 0); if (err != DB_SUCCESS) { ib::error() << iter.filepath << ": os_file_read() failed"; + goto func_exit; } bool updated = false; @@ -3338,18 +3337,9 @@ fil_iterate( for (ulint i = 0; i < n_pages_read; block->page.id.set_page_no(block->page.id.page_no() + 1), ++i, page_off += size, block->frame += size) { - bool decrypted = false; - err = DB_SUCCESS; byte* src = readptr + i * size; - byte* dst = io_buffer + i * size; - bool frame_changed = false; - ulint page_type = mach_read_from_2(src+FIL_PAGE_TYPE); - const bool page_compressed - = page_type - == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED - || page_type == FIL_PAGE_PAGE_COMPRESSED; const ulint page_no = page_get_page_no(src); - if (!page_no && page_off) { + if (!page_no && block->page.id.page_no()) { const ulint* b = reinterpret_cast<const ulint*> (src); const ulint* const e = b + size / sizeof *b; @@ -3364,54 +3354,84 @@ fil_iterate( continue; } - if (page_no != page_off / size) { + if (page_no != block->page.id.page_no()) { +page_corrupted: + ib::warn() << callback.filename() + << ": Page " << (offset / size) + << " at offset " << offset + << " looks corrupted."; + err = DB_CORRUPTION; + goto func_exit; + } + + const bool page_compressed + = fil_page_is_compressed_encrypted(src) + || fil_page_is_compressed(src); + + if (page_compressed && block->page.zip.data) { goto page_corrupted; } - if (encrypted) { + bool decrypted = false; + byte* dst = io_buffer + i * size; + bool frame_changed = false; + + if (!encrypted) { + } else if (!mach_read_from_4( + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + + src)) { +not_encrypted: + if (!page_compressed + && !block->page.zip.data) { + block->frame = src; + frame_changed = true; + } else { + ut_ad(dst != src); + memcpy(dst, src, size); + } + } else { + if (!fil_space_verify_crypt_checksum( + src, callback.get_page_size(), + block->page.id.space(), + block->page.id.page_no())) { + goto page_corrupted; + } + decrypted = fil_space_decrypt( iter.crypt_data, dst, callback.get_page_size(), src, &err); if (err != DB_SUCCESS) { - return err; + goto func_exit; } - if (decrypted) { - updated = true; - } else { - if (!page_compressed - && !block->page.zip.data) { - block->frame = src; - frame_changed = true; - } else { - ut_ad(dst != src); - memcpy(dst, src, size); - } + if (!decrypted) { + goto not_encrypted; } + + updated = true; } /* If the original page is page_compressed, we need to decompress it before adjusting further. */ if (page_compressed) { - fil_decompress_page(NULL, dst, ulong(size), - NULL); + ulint compress_length = fil_page_decompress( + page_compress_buf, dst); + ut_ad(compress_length != srv_page_size); + if (compress_length == 0) { + goto page_corrupted; + } updated = true; } else if (buf_page_is_corrupted( false, encrypted && !frame_changed ? dst : src, callback.get_page_size(), NULL)) { -page_corrupted: - ib::warn() << callback.filename() - << ": Page " << (offset / size) - << " at offset " << offset - << " looks corrupted."; - return DB_CORRUPTION; + goto page_corrupted; } - if ((err = callback(page_off, block)) != DB_SUCCESS) { - return err; + if ((err = callback(block)) != DB_SUCCESS) { + goto func_exit; } else if (!updated) { updated = buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE; @@ -3461,20 +3481,18 @@ page_corrupted: src = io_buffer + (i * size); if (page_compressed) { - ulint len = 0; - - fil_compress_page( - NULL, - src, - NULL, - size, - 0,/* FIXME: compression level */ - 512,/* FIXME: use proper block size */ - encrypted, - &len); - ut_ad(len <= size); - memset(src + len, 0, size - len); updated = true; + if (ulint len = fil_page_compress( + src, + page_compress_buf, + 0,/* FIXME: compression level */ + 512,/* FIXME: proper block size */ + encrypted)) { + /* FIXME: remove memcpy() */ + memcpy(src, page_compress_buf, len); + memset(src + len, 0, + srv_page_size - len); + } } /* Encrypt the page if encryption was used. */ @@ -3506,12 +3524,14 @@ page_corrupted: writeptr, offset, n_bytes); if (err != DB_SUCCESS) { - return err; + goto func_exit; } } } - return DB_SUCCESS; +func_exit: + free(page_compress_buf); + return err; } /********************************************************************//** @@ -3853,6 +3873,23 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_reset_space_and_lsn_failure", err = DB_TOO_MANY_CONCURRENT_TRXS;); + /* On DISCARD TABLESPACE, we did not drop any adaptive hash + index entries. If we replaced the discarded tablespace with a + smaller one here, there could still be some adaptive hash + index entries that point to cached garbage pages in the buffer + pool, because PageConverter::operator() only evicted those + pages that were replaced by the imported pages. We must + discard all remaining adaptive hash index entries, because the + adaptive hash index must be a subset of the table contents; + false positives are not tolerated. */ + while (buf_LRU_drop_page_hash_for_tablespace(table)) { + if (trx_is_interrupted(trx) + || srv_shutdown_state != SRV_SHUTDOWN_NONE) { + err = DB_INTERRUPTED; + break; + } + } + if (err != DB_SUCCESS) { char table_name[MAX_FULL_NAME_LEN + 1]; @@ -3871,17 +3908,6 @@ row_import_for_mysql( return(row_import_cleanup(prebuilt, trx, err)); } - /* On DISCARD TABLESPACE, we did not drop any adaptive hash - index entries. If we replaced the discarded tablespace with a - smaller one here, there could still be some adaptive hash - index entries that point to cached garbage pages in the buffer - pool, because PageConverter::operator() only evicted those - pages that were replaced by the imported pages. We must - discard all remaining adaptive hash index entries, because the - adaptive hash index must be a subset of the table contents; - false positives are not tolerated. */ - buf_LRU_drop_page_hash_for_tablespace(table); - row_mysql_lock_data_dictionary(trx); /* If the table is stored in a remote tablespace, we need to diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 97b79b705b2..470d5a9bd15 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -944,6 +944,9 @@ row_ins_foreign_fill_virtual( rec_get_offsets(rec, index, offsets_, true, ULINT_UNDEFINED, &cascade->heap); mem_heap_t* v_heap = NULL; + TABLE* mysql_table= NULL; + VCOL_STORAGE* vcol_storage= NULL; + byte* record; upd_t* update = cascade->update; ulint n_v_fld = index->table->n_v_def; ulint n_diff; @@ -963,6 +966,14 @@ row_ins_foreign_fill_virtual( innobase_init_vc_templ(index->table); } + if (innobase_allocate_row_for_vcol(thd, index, &v_heap, + &mysql_table, + &record, &vcol_storage)) + { + *err = DB_OUT_OF_MEMORY; + goto func_exit; + } + for (ulint i = 0; i < n_v_fld; i++) { dict_v_col_t* col = dict_table_get_nth_v_col( @@ -976,8 +987,8 @@ row_ins_foreign_fill_virtual( dfield_t* vfield = innobase_get_computed_value( update->old_vrow, col, index, - &v_heap, update->heap, NULL, thd, NULL, - NULL, NULL, NULL); + &v_heap, update->heap, NULL, thd, mysql_table, + record, NULL, NULL, NULL); if (vfield == NULL) { *err = DB_COMPUTE_VALUE_FAILED; @@ -1007,7 +1018,8 @@ row_ins_foreign_fill_virtual( dfield_t* new_vfield = innobase_get_computed_value( update->old_vrow, col, index, &v_heap, update->heap, NULL, thd, - NULL, NULL, node->update, foreign); + mysql_table, record, NULL, + node->update, foreign); if (new_vfield == NULL) { *err = DB_COMPUTE_VALUE_FAILED; @@ -1025,6 +1037,8 @@ row_ins_foreign_fill_virtual( func_exit: if (v_heap) { + if (vcol_storage) + innobase_free_row_for_vcol(vcol_storage); mem_heap_free(v_heap); } } diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index bf20debbef6..7347f4f04c6 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -39,6 +39,7 @@ Created 2011-05-26 Marko Makela #include "ut0stage.h" #include "trx0rec.h" +#include <sql_class.h> #include <algorithm> #include <map> @@ -226,10 +227,13 @@ struct row_log_t { table could be emptied, so that table->is_instant() no longer holds, but all log records must be in the "instant" format. */ unsigned n_core_fields; - bool ignore; /*!< Whether the alter ignore is being used; + bool allow_not_null; /*!< Whether the alter ignore is being + used or if the sql mode is non-strict mode; if not, NULL values will not be converted to defaults */ + const TABLE* old_table; /*< Use old table in case of error. */ + uint64_t n_rows; /*< Number of rows read from the table */ /** Determine whether the log should be in the 'instant ADD' format @param[in] index the clustered index of the source table @return whether to use the 'instant ADD COLUMN' format */ @@ -1107,6 +1111,7 @@ table @param[in] i rec field corresponding to col @param[in] page_size page size of the old table @param[in] max_len maximum length of dfield +@param[in] log row log for the table @retval DB_INVALID_NULL if a NULL value is encountered @retval DB_TOO_BIG_INDEX_COL if the maximum prefix length is exceeded */ static @@ -1120,8 +1125,7 @@ row_log_table_get_pk_col( ulint i, const page_size_t& page_size, ulint max_len, - bool ignore, - const dtuple_t* defaults) + const row_log_t* log) { const byte* field; ulint len; @@ -1129,12 +1133,16 @@ row_log_table_get_pk_col( field = rec_get_nth_field(rec, offsets, i, &len); if (len == UNIV_SQL_NULL) { - if (!ignore || !defaults->fields[i].data) { + + if (!log->allow_not_null) { return(DB_INVALID_NULL); } - field = static_cast<const byte*>(defaults->fields[i].data); - len = defaults->fields[i].len; + ulint n_default_cols = i - DATA_N_SYS_COLS; + + field = static_cast<const byte*>( + log->defaults->fields[n_default_cols].data); + len = log->defaults->fields[i - DATA_N_SYS_COLS].len; } if (rec_offs_nth_extern(offsets, i)) { @@ -1298,8 +1306,7 @@ row_log_table_get_pk( log->error = row_log_table_get_pk_col( ifield, dfield, *heap, - rec, offsets, i, page_size, max_len, - log->ignore, log->defaults); + rec, offsets, i, page_size, max_len, log); if (log->error != DB_SUCCESS) { err_exit: @@ -1477,7 +1484,7 @@ row_log_table_apply_convert_mrec( const mrec_t* mrec, /*!< in: merge record */ dict_index_t* index, /*!< in: index of mrec */ const ulint* offsets, /*!< in: offsets of mrec */ - const row_log_t* log, /*!< in: rebuild context */ + row_log_t* log, /*!< in: rebuild context */ mem_heap_t* heap, /*!< in/out: memory heap */ dberr_t* error) /*!< out: DB_SUCCESS or DB_MISSING_HISTORY or @@ -1485,6 +1492,7 @@ row_log_table_apply_convert_mrec( { dtuple_t* row; + log->n_rows++; *error = DB_SUCCESS; /* This is based on row_build(). */ @@ -1613,8 +1621,12 @@ blob_done: const dfield_t& default_field = log->defaults->fields[col_no]; + Field* field = log->old_table->field[col_no]; + + field->set_warning(Sql_condition::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, 1, ulong(log->n_rows)); - if (!log->ignore || !default_field.data) { + if (!log->allow_not_null) { /* We got a NULL value for a NOT NULL column. */ *error = DB_INVALID_NULL; return NULL; @@ -1724,7 +1736,7 @@ row_log_table_apply_insert( row_merge_dup_t* dup) /*!< in/out: for reporting duplicate key errors */ { - const row_log_t*log = dup->index->online_log; + row_log_t*log = dup->index->online_log; dberr_t error; const dtuple_t* row = row_log_table_apply_convert_mrec( mrec, dup->index, offsets, log, heap, &error); @@ -1995,7 +2007,7 @@ row_log_table_apply_update( of the old value, or PRIMARY KEY if same_pk */ { - const row_log_t*log = dup->index->online_log; + row_log_t* log = dup->index->online_log; const dtuple_t* row; dict_index_t* index = dict_table_get_first_index(log->table); mtr_t mtr; @@ -3040,13 +3052,15 @@ func_exit: @param[in,out] stage performance schema accounting object, used by ALTER TABLE. stage->begin_phase_log_table() will be called initially and then stage->inc() will be called for each block of log that is applied. +@param[in] new_table Altered table @return DB_SUCCESS, or error code on failure */ dberr_t row_log_table_apply( que_thr_t* thr, dict_table_t* old_table, struct TABLE* table, - ut_stage_alter_t* stage) + ut_stage_alter_t* stage, + dict_table_t* new_table) { dberr_t error; dict_index_t* clust_index; @@ -3060,6 +3074,10 @@ row_log_table_apply( ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S)); clust_index = dict_table_get_first_index(old_table); + if (clust_index->online_log->n_rows == 0) { + clust_index->online_log->n_rows = new_table->stat_n_rows; + } + rw_lock_x_lock(dict_index_get_lock(clust_index)); if (!clust_index->online_log) { @@ -3109,7 +3127,9 @@ row_log_allocate( const ulint* col_map,/*!< in: mapping of old column numbers to new ones, or NULL if !table */ const char* path, /*!< in: where to create temporary file */ - const bool ignore) /*!< in: alter ignore issued */ + const TABLE* old_table, /*!< in: table definition before alter */ + const bool allow_not_null) /*!< in: allow null to not-null + conversion */ { row_log_t* log; DBUG_ENTER("row_log_allocate"); @@ -3150,7 +3170,9 @@ row_log_allocate( log->path = path; log->n_core_fields = index->n_core_fields; ut_ad(!table || log->is_instant(index) == index->is_instant()); - log->ignore=ignore; + log->allow_not_null = allow_not_null; + log->old_table = old_table; + log->n_rows = 0; dict_index_set_online_status(index, ONLINE_INDEX_CREATION); index->online_log = log; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index afa4ce208e9..be3c081562e 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -532,6 +532,8 @@ row_merge_buf_add( ulint bucket = 0; doc_id_t write_doc_id; ulint n_row_added = 0; + VCOL_STORAGE* vcol_storage= 0; + byte* record; DBUG_ENTER("row_merge_buf_add"); if (buf->n_tuples >= buf->max_tuples) { @@ -604,14 +606,21 @@ row_merge_buf_add( dict_index_t* clust_index = dict_table_get_first_index(new_table); + if (!vcol_storage && + innobase_allocate_row_for_vcol(trx->mysql_thd, clust_index, v_heap, &my_table, &record, &vcol_storage)) { + *err = DB_OUT_OF_MEMORY; + goto error; + } + row_field = innobase_get_computed_value( row, v_col, clust_index, v_heap, NULL, ifield, trx->mysql_thd, - my_table, old_table, NULL, NULL); + my_table, record, old_table, NULL, + NULL); if (row_field == NULL) { *err = DB_COMPUTE_VALUE_FAILED; - DBUG_RETURN(0); + goto error; } dfield_copy(field, row_field); } else { @@ -647,7 +656,7 @@ row_merge_buf_add( ib::warn() << "FTS Doc ID is" " zero. Record" " skipped"; - DBUG_RETURN(0); + goto error; } } @@ -795,7 +804,7 @@ row_merge_buf_add( /* If this is FTS index, we already populated the sort buffer, return here */ if (index->type & DICT_FTS) { - DBUG_RETURN(n_row_added); + goto end; } #ifdef UNIV_DEBUG @@ -829,7 +838,7 @@ row_merge_buf_add( /* Reserve bytes for the end marker of row_merge_block_t. */ if (buf->total_size + data_size >= srv_sort_buf_size) { - DBUG_RETURN(0); + goto error; } buf->total_size += data_size; @@ -848,7 +857,15 @@ row_merge_buf_add( mem_heap_empty(conv_heap); } +end: + if (vcol_storage) + innobase_free_row_for_vcol(vcol_storage); DBUG_RETURN(n_row_added); + +error: + if (vcol_storage) + innobase_free_row_for_vcol(vcol_storage); + DBUG_RETURN(0); } /*************************************************************//** @@ -1674,6 +1691,7 @@ stage->inc() will be called for each page read. @param[in,out] crypt_block crypted file buffer @param[in] eval_table mysql table used to evaluate virtual column value, see innobase_get_computed_value(). +@param[in] allow_not_null allow null to not-null conversion @return DB_SUCCESS or error */ static MY_ATTRIBUTE((warn_unused_result)) dberr_t @@ -1681,7 +1699,7 @@ row_merge_read_clustered_index( trx_t* trx, struct TABLE* table, const dict_table_t* old_table, - const dict_table_t* new_table, + dict_table_t* new_table, bool online, dict_index_t** index, dict_index_t* fts_sort_idx, @@ -1700,7 +1718,8 @@ row_merge_read_clustered_index( ut_stage_alter_t* stage, double pct_cost, row_merge_block_t* crypt_block, - struct TABLE* eval_table) + struct TABLE* eval_table, + bool allow_not_null) { dict_index_t* clust_index; /* Clustered index */ mem_heap_t* row_heap; /* Heap memory to create @@ -1914,6 +1933,7 @@ row_merge_read_clustered_index( mach_write_to_8(new_sys_trx_start, trx->id); mach_write_to_8(new_sys_trx_end, TRX_ID_MAX); + uint64_t n_rows = 0; /* Scan the clustered index. */ for (;;) { @@ -2174,15 +2194,24 @@ end_of_index: ut_ad(dfield_get_type(field)->prtype & DATA_NOT_NULL); if (dfield_is_null(field)) { - const dfield_t& default_field - = defaults->fields[nonnull[i]]; - if (default_field.data == NULL) { + Field* null_field = + table->field[nonnull[i]]; + + null_field->set_warning( + Sql_condition::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, 1, + ulong(n_rows + 1)); + + if (!allow_not_null) { err = DB_INVALID_NULL; trx->error_key_num = 0; goto func_exit; } + const dfield_t& default_field + = defaults->fields[nonnull[i]]; + *field = default_field; } } @@ -2315,6 +2344,7 @@ write_buffers: /* Build all entries for all the indexes to be created in a single scan of the clustered index. */ + n_rows++; ulint s_idx_cnt = 0; bool skip_sort = skip_pk_sort && dict_index_is_clust(merge_buf[0]->index); @@ -2695,6 +2725,10 @@ write_buffers: } if (row == NULL) { + if (old_table != new_table) { + new_table->stat_n_rows = n_rows; + } + goto all_done; } @@ -4547,6 +4581,7 @@ this function and it will be passed to other functions for further accounting. @param[in] add_v new virtual columns added along with indexes @param[in] eval_table mysql table used to evaluate virtual column value, see innobase_get_computed_value(). +@param[in] allow_not_null allow the conversion from null to not-null @return DB_SUCCESS or error code */ dberr_t row_merge_build_indexes( @@ -4565,7 +4600,8 @@ row_merge_build_indexes( bool skip_pk_sort, ut_stage_alter_t* stage, const dict_add_v_col_t* add_v, - struct TABLE* eval_table) + struct TABLE* eval_table, + bool allow_not_null) { merge_file_t* merge_files; row_merge_block_t* block; @@ -4729,7 +4765,7 @@ row_merge_build_indexes( fts_sort_idx, psort_info, merge_files, key_numbers, n_indexes, defaults, add_v, col_map, add_autoinc, sequence, block, skip_pk_sort, &tmpfd, stage, - pct_cost, crypt_block, eval_table); + pct_cost, crypt_block, eval_table, allow_not_null); stage->end_phase_read_pk(); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index b603292705a..49ac2638ef8 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -63,6 +63,7 @@ Created 9/17/2000 Heikki Tuuri #include "trx0rec.h" #include "trx0roll.h" #include "trx0undo.h" +#include "srv0start.h" #include "row0ext.h" #include "srv0start.h" #include "ut0new.h" @@ -3525,12 +3526,36 @@ row_drop_table_for_mysql( /* make sure background stats thread is not running on the table */ ut_ad(!(table->stats_bg_flag & BG_STAT_IN_PROGRESS)); - /* Delete the link file if used. */ - if (DICT_TF_HAS_DATA_DIR(table->flags)) { - RemoteDatafile::delete_link_file(name); - } - if (!table->no_rollback()) { + if (table->space != fil_system.sys_space) { + /* On DISCARD TABLESPACE, we would not drop the + adaptive hash index entries. If the tablespace is + missing here, delete-marking the record in SYS_INDEXES + would not free any pages in the buffer pool. Thus, + dict_index_remove_from_cache() would hang due to + adaptive hash index entries existing in the buffer + pool. To prevent this hang, and also to guarantee + that btr_search_drop_page_hash_when_freed() will avoid + calling btr_search_drop_page_hash_index() while we + hold the InnoDB dictionary lock, we will drop any + adaptive hash index entries upfront. */ + while (buf_LRU_drop_page_hash_for_tablespace(table)) { + if (trx_is_interrupted(trx) + || srv_shutdown_state + != SRV_SHUTDOWN_NONE) { + err = DB_INTERRUPTED; + table->to_be_dropped = false; + dict_table_close(table, true, false); + goto funct_exit; + } + } + + /* Delete the link file if used. */ + if (DICT_TF_HAS_DATA_DIR(table->flags)) { + RemoteDatafile::delete_link_file(name); + } + } + dict_stats_recalc_pool_del(table); dict_stats_defrag_pool_del(table, NULL); if (btr_defragment_thread_active) { @@ -3702,21 +3727,6 @@ defer: rw_lock_x_unlock(dict_index_get_lock(index)); } - if (table->space_id != TRX_SYS_SPACE) { - /* On DISCARD TABLESPACE, we would not drop the - adaptive hash index entries. If the tablespace is - missing here, delete-marking the record in SYS_INDEXES - would not free any pages in the buffer pool. Thus, - dict_index_remove_from_cache() would hang due to - adaptive hash index entries existing in the buffer - pool. To prevent this hang, and also to guarantee - that btr_search_drop_page_hash_when_freed() will avoid - calling btr_search_drop_page_hash_index() while we - hold the InnoDB dictionary lock, we will drop any - adaptive hash index entries upfront. */ - buf_LRU_drop_page_hash_for_tablespace(table); - } - /* Deleting a row from SYS_INDEXES table will invoke dict_drop_index_tree(). */ info = pars_info_create(); diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 3c081657e35..67fc30d526e 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -178,6 +178,8 @@ row_sel_sec_rec_is_for_clust_rec( ulint* clust_offs = clust_offsets_; ulint* sec_offs = sec_offsets_; ibool is_equal = TRUE; + VCOL_STORAGE* vcol_storage= 0; + byte* record; rec_offs_init(clust_offsets_); rec_offs_init(sec_offsets_); @@ -225,6 +227,17 @@ row_sel_sec_rec_is_for_clust_rec( dfield_t* vfield; row_ext_t* ext; + if (!vcol_storage) + { + TABLE *mysql_table= thr->prebuilt->m_mysql_table; + innobase_allocate_row_for_vcol(thr_get_trx(thr)->mysql_thd, + clust_index, + &heap, + &mysql_table, + &record, + &vcol_storage); + } + v_col = reinterpret_cast<const dict_v_col_t*>(col); row = row_build(ROW_COPY_POINTERS, @@ -236,8 +249,8 @@ row_sel_sec_rec_is_for_clust_rec( row, v_col, clust_index, &heap, NULL, NULL, thr_get_trx(thr)->mysql_thd, - thr->prebuilt->m_mysql_table, NULL, - NULL, NULL); + thr->prebuilt->m_mysql_table, + record, NULL, NULL, NULL); clust_len = vfield->len; clust_field = static_cast<byte*>(vfield->data); @@ -325,6 +338,8 @@ inequal: func_exit: if (UNIV_LIKELY_NULL(heap)) { + if (UNIV_LIKELY_NULL(vcol_storage)) + innobase_free_row_for_vcol(vcol_storage); mem_heap_free(heap); } return(is_equal); @@ -5864,57 +5879,6 @@ func_exit: } /*******************************************************************//** -Checks if MySQL at the moment is allowed for this table to retrieve a -consistent read result, or store it to the query cache. -@return whether storing or retrieving from the query cache is permitted */ -bool -row_search_check_if_query_cache_permitted( -/*======================================*/ - trx_t* trx, /*!< in: transaction object */ - const char* norm_name) /*!< in: concatenation of database name, - '/' char, table name */ -{ - dict_table_t* table = dict_table_open_on_name( - norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); - - if (table == NULL) { - - return(false); - } - - /* Start the transaction if it is not started yet */ - - trx_start_if_not_started(trx, false); - - /* If there are locks on the table or some trx has invalidated the - cache before this transaction started then this transaction cannot - read/write from/to the cache. - - If a read view has not been created for the transaction then it doesn't - really matter what this transaction sees. If a read view was created - then the view low_limit_id is the max trx id that this transaction - saw at the time of the read view creation. */ - - const bool ret = lock_table_get_n_locks(table) == 0 - && ((trx->id != 0 && trx->id >= table->query_cache_inv_id) - || !trx->read_view.is_open() - || trx->read_view.low_limit_id() - >= table->query_cache_inv_id); - if (ret) { - /* If the isolation level is high, assign a read view for the - transaction if it does not yet have one */ - - if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ) { - trx->read_view.open(trx); - } - } - - dict_table_close(table, FALSE, FALSE); - - return(ret); -} - -/*******************************************************************//** Read the AUTOINC column from the current row. If the value is less than 0 and the type is not unsigned then we reset the value to 0. @return value read from the column */ diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index bca7464bc66..39206e66d75 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1043,6 +1043,7 @@ row_upd_build_sec_rec_difference_binary( return(update); } + /** Builds an update vector from those fields, excluding the roll ptr and trx id fields, which in an index entry differ from a record that has the equal ordering fields. NOTE: we compare the fields as binary strings! @@ -1142,6 +1143,9 @@ row_upd_build_difference_binary( if (n_v_fld > 0) { row_ext_t* ext; mem_heap_t* v_heap = NULL; + byte* record; + VCOL_STORAGE* vcol_storage; + THD* thd; if (trx == NULL) { @@ -1152,6 +1156,10 @@ row_upd_build_difference_binary( ut_ad(!update->old_vrow); + innobase_allocate_row_for_vcol(thd, index, &v_heap, + &mysql_table, + &record, &vcol_storage); + for (i = 0; i < n_v_fld; i++) { const dict_v_col_t* col = dict_table_get_nth_v_col(index->table, i); @@ -1170,7 +1178,7 @@ row_upd_build_difference_binary( dfield_t* vfield = innobase_get_computed_value( update->old_vrow, col, index, - &v_heap, heap, NULL, thd, mysql_table, + &v_heap, heap, NULL, thd, mysql_table, record, NULL, NULL, NULL); if (!dfield_data_is_binary_equal( @@ -1196,6 +1204,8 @@ row_upd_build_difference_binary( } if (v_heap) { + if (vcol_storage) + innobase_free_row_for_vcol(vcol_storage); mem_heap_free(v_heap); } } @@ -2122,6 +2132,12 @@ row_upd_store_v_row( { mem_heap_t* heap = NULL; dict_index_t* index = dict_table_get_first_index(node->table); + byte* record= 0; + VCOL_STORAGE *vcol_storage= 0; + + if (!update) + innobase_allocate_row_for_vcol(thd, index, &heap, &mysql_table, + &record, &vcol_storage); for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(node->table); col_no++) { @@ -2174,7 +2190,7 @@ row_upd_store_v_row( innobase_get_computed_value( node->row, col, index, &heap, node->heap, NULL, - thd, mysql_table, NULL, + thd, mysql_table, record, NULL, NULL, NULL); } } @@ -2182,8 +2198,11 @@ row_upd_store_v_row( } if (heap) { + if (vcol_storage) + innobase_free_row_for_vcol(vcol_storage); mem_heap_free(heap); } + } /** Stores to the heap the row on which the node->pcur is positioned. diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index d585ef3a9d3..bfaa2721746 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -434,6 +434,19 @@ row_vers_build_clust_v_col( mem_heap_t* heap) { mem_heap_t* local_heap = NULL; + VCOL_STORAGE *vcol_storage= NULL; + THD* thd= current_thd; + TABLE* maria_table= 0; + byte* record= 0; + + ut_ad(dict_index_has_virtual(index)); + + innobase_allocate_row_for_vcol(thd, index, + &local_heap, + &maria_table, + &record, + &vcol_storage); + for (ulint i = 0; i < dict_index_get_n_fields(index); i++) { const dict_field_t* ind_field = dict_index_get_nth_field( index, i); @@ -446,15 +459,18 @@ row_vers_build_clust_v_col( innobase_get_computed_value( row, col, clust_index, &local_heap, - heap, NULL, current_thd, NULL, NULL, + heap, NULL, thd, maria_table, record, NULL, NULL, NULL); } } if (local_heap) { + if (vcol_storage) + innobase_free_row_for_vcol(vcol_storage); mem_heap_free(local_heap); } } + /** Build latest virtual column data from undo log @param[in] in_purge whether this is the purge thread @param[in] rec clustered index record diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 89070214a1b..08b21bcdd7d 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -834,6 +834,10 @@ srv_undo_tablespaces_init(bool create_new_db) ut_a(srv_undo_tablespaces <= TRX_SYS_N_RSEGS); ut_a(!create_new_db || srv_operation == SRV_OPERATION_NORMAL); + if (srv_undo_tablespaces == 1) { /* 1 is not allowed, make it 0 */ + srv_undo_tablespaces = 0; + } + memset(undo_tablespace_ids, 0x0, sizeof(undo_tablespace_ids)); /* Create the undo spaces only if we are creating a new diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index 2230fb6cbc3..3b7d2dd4850 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -277,7 +277,7 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, " file is probably in use by another process"; uint new_cf_create_time_size, new_cf_changeable_size, new_block_size; my_off_t file_size; - int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR; + int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR | O_CLOEXEC; int error= CONTROL_FILE_UNKNOWN_ERROR; DBUG_ENTER("ma_control_file_open"); diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index 703ce118843..dbdde1d5963 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -726,7 +726,7 @@ ulonglong ma_retrieve_auto_increment(const uchar *key, uint8 key_type) switch (key_type) { case HA_KEYTYPE_INT8: - s_value= (longlong) *(const char*)key; + s_value= (longlong) *(const signed char*) key; break; case HA_KEYTYPE_BINARY: value=(ulonglong) *key; diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index c81c7735df5..158904f6692 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -78,6 +78,32 @@ typedef union uchar buffer[TRANSLOG_PAGE_SIZE]; } TRANSLOG_PAGE_SIZE_BUFF; +#define MAX_TRUNSLOG_USED_BUFFERS 3 + +typedef struct +{ + struct st_translog_buffer *buff[MAX_TRUNSLOG_USED_BUFFERS]; + uint8 wrt_ptr; + uint8 unlck_ptr; +} TRUNSLOG_USED_BUFFERS; + +static void +used_buffs_init(TRUNSLOG_USED_BUFFERS *buffs) +{ + buffs->unlck_ptr= buffs->wrt_ptr= 0; +} + +static void +used_buffs_add(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff); + +static void +used_buffs_register_unlock(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff); + +static void +used_buffs_urgent_unlock(TRUNSLOG_USED_BUFFERS *buffs); + /* min chunk length */ #define TRANSLOG_MIN_CHUNK 3 /* @@ -156,7 +182,28 @@ struct st_translog_buffer TRANSLOG_FILE *file; /* Threads which are waiting for buffer filling/freeing */ mysql_cond_t waiting_filling_buffer; - /* Number of records which are in copy progress */ + /* + Number of records which are in copy progress. + + Controlled via translog_buffer_increase_writers() and + translog_buffer_decrease_writers(). + + 1 Simple case: translog_force_current_buffer_to_finish both called in + the same procedure. + + 2 Simple case: translog_write_variable_record_1group: + translog_advance_pointer() increase writer of the buffer and + translog_buffer_decrease_writers() decrease it. + + Usual case: + 1) translog_advance_pointer (i.e. reserve place for future writing) + increase writers for all buffers where place reserved. + Simpliest case: just all space reserved in one buffer + complex case: end of the first buffer, all second buffer, beginning + of the third buffer. + 2) When we finish with writing translog_chaser_page_next() will be + called and unlock the buffer by decreasing number of writers. + */ uint copy_to_buffer_in_progress; /* list of waiting buffer ready threads */ struct st_my_thread_var *waiting_flush; @@ -214,6 +261,7 @@ struct st_translog_buffer struct st_buffer_cursor { + TRUNSLOG_USED_BUFFERS buffs; /* pointer into the buffer */ uchar *ptr; /* current buffer */ @@ -935,7 +983,7 @@ static File create_logfile_by_number_no_cache(uint32 file_no) /* TODO: add O_DIRECT to open flags (when buffer is aligned) */ if ((file= mysql_file_create(key_file_translog, translog_filename_by_fileno(file_no, path), - 0, O_BINARY | O_RDWR, MYF(MY_WME))) < 0) + 0, O_BINARY | O_RDWR | O_CLOEXEC, MYF(MY_WME))) < 0) { DBUG_PRINT("error", ("Error %d during creating file '%s'", errno, path)); translog_stop_writing(); @@ -973,7 +1021,7 @@ static File open_logfile_by_number_no_cache(uint32 file_no) /* TODO: use mysql_file_create() */ if ((file= mysql_file_open(key_file_translog, translog_filename_by_fileno(file_no, path), - log_descriptor.open_flags, + log_descriptor.open_flags | O_CLOEXEC, MYF(MY_WME))) < 0) { DBUG_PRINT("error", ("Error %d during opening file '%s'", errno, path)); @@ -1648,15 +1696,12 @@ static my_bool translog_create_new_file() DBUG_PRINT("info", ("file_no: %lu", (ulong)file_no)); if (translog_write_file_header()) - DBUG_RETURN(1); + goto error; if (ma_control_file_write_and_force(last_checkpoint_lsn, file_no, max_trid_in_control_file, recovery_failures)) - { - translog_stop_writing(); - DBUG_RETURN(1); - } + goto error; DBUG_RETURN(0); @@ -1697,10 +1742,6 @@ static void translog_buffer_lock(struct st_translog_buffer *buffer) SYNOPSIS translog_buffer_unlock() buffer This buffer which should be unlocked - - RETURN - 0 OK - 1 Error */ static void translog_buffer_unlock(struct st_translog_buffer *buffer) @@ -1894,7 +1935,10 @@ static void translog_finish_page(TRANSLOG_ADDRESS *horizon, (uint) cursor->buffer->size, (uint) (cursor->ptr -cursor->buffer->buffer), (uint) cursor->current_page_fill, (uint) left)); - DBUG_ASSERT(LSN_FILE_NO(*horizon) == LSN_FILE_NO(cursor->buffer->offset)); + DBUG_ASSERT(LSN_FILE_NO(*horizon) == LSN_FILE_NO(cursor->buffer->offset) + || translog_status == TRANSLOG_UNINITED); + if ((LSN_FILE_NO(*horizon) != LSN_FILE_NO(cursor->buffer->offset))) + DBUG_VOID_RETURN; // everything wrong do not write to awoid more problems translog_check_cursor(cursor); if (cursor->protected) { @@ -3243,7 +3287,7 @@ static my_bool translog_get_last_page_addr(TRANSLOG_ADDRESS *addr, File fd; if ((fd= mysql_file_open(key_file_translog, translog_filename_by_fileno(file_no, path), - O_RDONLY, (no_errors ? MYF(0) : MYF(MY_WME)))) < 0) + O_RDONLY | O_CLOEXEC, (no_errors ? MYF(0) : MYF(MY_WME)))) < 0) { my_errno= errno; DBUG_PRINT("error", ("Error %d during opening file #%d", @@ -4588,6 +4632,7 @@ static my_bool translog_chaser_page_next(TRANSLOG_ADDRESS *horizon, { translog_buffer_lock(buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush); + used_buffs_register_unlock(&cursor->buffs, buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); translog_buffer_unlock(buffer_to_flush); @@ -4692,7 +4737,8 @@ translog_write_variable_record_chunk3_page(struct st_translog_parts *parts, 1 Error */ -static my_bool translog_advance_pointer(int pages, uint16 last_page_data) +static my_bool translog_advance_pointer(int pages, uint16 last_page_data, + TRUNSLOG_USED_BUFFERS *buffs) { translog_size_t last_page_offset= (log_descriptor.page_overhead + last_page_data); @@ -4709,6 +4755,8 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) (uint) last_page_data)); translog_lock_assert_owner(); + used_buffs_init(buffs); + if (pages == -1) { /* @@ -4786,8 +4834,10 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) translog_wait_for_buffer_free(new_buffer); #ifndef DBUG_OFF /* We keep the handler locked so nobody can start this new buffer */ - DBUG_ASSERT(offset == new_buffer->offset && new_buffer->file == NULL && - (file == NULL ? ver : (uint8)(ver + 1)) == new_buffer->ver); + DBUG_ASSERT((offset == new_buffer->offset && new_buffer->file == NULL && + (file == NULL ? ver : (uint8)(ver + 1)) == + new_buffer->ver) || + translog_status == TRANSLOG_READONLY); } #endif @@ -4808,6 +4858,8 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) DBUG_ASSERT(log_descriptor.bc.buffer->buffer_no == log_descriptor.bc.buffer_no); translog_buffer_increase_writers(log_descriptor.bc.buffer); + // register for case of error + used_buffs_add(buffs, log_descriptor.bc.buffer); if (file_end_offset <= buffer_end_offset) { @@ -4818,6 +4870,10 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) (ulong) LSN_FILE_NO(log_descriptor.horizon))); if (translog_create_new_file()) { + struct st_translog_buffer *ob= log_descriptor.bc.buffer; + translog_buffer_unlock(ob); + used_buffs_urgent_unlock(buffs); + translog_buffer_lock(ob); DBUG_RETURN(1); } } @@ -4839,6 +4895,7 @@ end: log_descriptor.bc.ptr+= offset; log_descriptor.bc.buffer->size+= offset; translog_buffer_increase_writers(log_descriptor.bc.buffer); + used_buffs_add(buffs, log_descriptor.bc.buffer); log_descriptor.horizon+= offset; /* offset increasing */ log_descriptor.bc.current_page_fill= last_page_offset; DBUG_PRINT("info", ("NewP buffer #%u: %p chaser: %d Size: %lu (%lu) " @@ -4859,6 +4916,56 @@ end: DBUG_RETURN(0); } +static void +used_buffs_add(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff) +{ + DBUG_ENTER("used_buffs_add"); + DBUG_PRINT("enter", ("ADD buffs: %p unlk %u (%p) wrt_ptr: %u (%p)" + " buff %p (%u)", + buffs, + buffs->wrt_ptr, buffs->buff[buffs->wrt_ptr], + buffs->unlck_ptr, buffs->buff[buffs->unlck_ptr], + buff, buff->buffer_no)); + DBUG_ASSERT(buffs->wrt_ptr < MAX_TRUNSLOG_USED_BUFFERS); + buffs->buff[buffs->wrt_ptr++]= buff; + DBUG_VOID_RETURN; +} + +static void +used_buffs_register_unlock(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff + __attribute__((unused)) ) +{ + DBUG_ENTER("used_buffs_register_unlock"); + DBUG_PRINT("enter", ("SUB buffs: %p unlk %u (%p) wrt_ptr: %u (%p)" + " buff %p (%u)", + buffs, + buffs->wrt_ptr, buffs->buff[buffs->wrt_ptr], + buffs->unlck_ptr, buffs->buff[buffs->unlck_ptr], + buff, buff->buffer_no)); + DBUG_ASSERT(buffs->buff[buffs->unlck_ptr] == buff); + buffs->unlck_ptr++; + DBUG_VOID_RETURN; +} +static void used_buffs_urgent_unlock(TRUNSLOG_USED_BUFFERS *buffs) +{ + uint i; + DBUG_ENTER("used_buffs_urgent_unlock"); + translog_lock(); + translog_stop_writing(); + translog_unlock(); + for (i= buffs->unlck_ptr; i < buffs->wrt_ptr; i++) + { + struct st_translog_buffer *buf= buffs->buff[i]; + translog_buffer_lock(buf); + translog_buffer_decrease_writers(buf); + translog_buffer_unlock(buf); + buffs->buff[i]= NULL; + } + used_buffs_init(buffs); + DBUG_VOID_RETURN; +} /* Get page rest @@ -4997,6 +5104,11 @@ translog_write_variable_record_1group(LSN *lsn, lsn, hook_arg))) { translog_unlock(); + if (buffer_to_flush != NULL) + { + translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + } DBUG_RETURN(1); } cursor= log_descriptor.bc; @@ -5027,8 +5139,9 @@ translog_write_variable_record_1group(LSN *lsn, (log_descriptor.page_capacity_chunk_2 - 1), record_rest, parts->record_length)); /* record_rest + 3 is chunk type 3 overhead + record_rest */ - rc|= translog_advance_pointer((int)(full_pages + additional_chunk3_page), - (record_rest ? record_rest + 3 : 0)); + rc= translog_advance_pointer((int)(full_pages + additional_chunk3_page), + (record_rest ? record_rest + 3 : 0), + &cursor.buffs); log_descriptor.bc.buffer->last_lsn= *lsn; DBUG_PRINT("info", ("last_lsn set to " LSN_FMT " buffer: %p", LSN_IN_PARTS(log_descriptor.bc.buffer->last_lsn), @@ -5047,7 +5160,11 @@ translog_write_variable_record_1group(LSN *lsn, translog_buffer_unlock(buffer_to_flush); } if (rc) + { + //translog_advance_pointer decreased writers so it is OK + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); DBUG_RETURN(1); + } translog_write_variable_record_1group_header(parts, type, short_trid, header_length, chunk0_header); @@ -5062,7 +5179,7 @@ translog_write_variable_record_1group(LSN *lsn, for (i= 0; i < full_pages; i++) { if (translog_write_variable_record_chunk2_page(parts, &horizon, &cursor)) - DBUG_RETURN(1); + goto error; DBUG_PRINT("info", ("absolute horizon: " LSN_FMT " local: " LSN_FMT, LSN_IN_PARTS(log_descriptor.horizon), @@ -5075,7 +5192,7 @@ translog_write_variable_record_1group(LSN *lsn, log_descriptor. page_capacity_chunk_2 - 2, &horizon, &cursor)) - DBUG_RETURN(1); + goto error; DBUG_PRINT("info", ("absolute horizon: " LSN_FMT " local: " LSN_FMT, LSN_IN_PARTS(log_descriptor.horizon), LSN_IN_PARTS(horizon))); @@ -5085,17 +5202,22 @@ translog_write_variable_record_1group(LSN *lsn, if (translog_write_variable_record_chunk3_page(parts, record_rest, &horizon, &cursor)) - DBUG_RETURN(1); - DBUG_PRINT("info", ("absolute horizon: " LSN_FMT " local: " LSN_FMT, - (uint) LSN_FILE_NO(log_descriptor.horizon), - (uint) LSN_OFFSET(log_descriptor.horizon), - (uint) LSN_FILE_NO(horizon), - (uint) LSN_OFFSET(horizon))); + goto error; + DBUG_PRINT("info", ("absolute horizon: " LSN_FMT " local: " LSN_FMT, + (uint) LSN_FILE_NO(log_descriptor.horizon), + (uint) LSN_OFFSET(log_descriptor.horizon), + (uint) LSN_FILE_NO(horizon), + (uint) LSN_OFFSET(horizon))); translog_buffer_lock(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer); + used_buffs_register_unlock(&cursor.buffs, cursor.buffer); translog_buffer_unlock(cursor.buffer); - DBUG_RETURN(rc); + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); + DBUG_RETURN(0); +error: + used_buffs_urgent_unlock(&cursor.buffs); + DBUG_RETURN(1); } @@ -5149,7 +5271,8 @@ translog_write_variable_record_1chunk(LSN *lsn, lsn, hook_arg))) { translog_unlock(); - DBUG_RETURN(1); + rc= 1; + goto err; } rc= translog_write_parts_on_page(&log_descriptor.horizon, @@ -5165,6 +5288,7 @@ translog_write_variable_record_1chunk(LSN *lsn, check if we switched buffer and need process it (current buffer is unlocked already => we will not delay other threads */ +err: if (buffer_to_flush != NULL) { if (!rc) @@ -5505,9 +5629,11 @@ translog_write_variable_record_mgroup(LSN *lsn, uint file_of_the_first_group; int pages_to_skip; struct st_translog_buffer *buffer_of_last_lsn; + my_bool external_buffer_to_flush= TRUE; DBUG_ENTER("translog_write_variable_record_mgroup"); translog_lock_assert_owner(); + used_buffs_init(&cursor.buffs); chunk2_header[0]= TRANSLOG_CHUNK_NOHDR; if (my_init_dynamic_array(&groups, @@ -5515,6 +5641,11 @@ translog_write_variable_record_mgroup(LSN *lsn, 10, 10, MYF(0))) { translog_unlock(); + if (buffer_to_flush != NULL) + { + translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + } DBUG_PRINT("error", ("init array failed")); DBUG_RETURN(1); } @@ -5541,6 +5672,7 @@ translog_write_variable_record_mgroup(LSN *lsn, translog_mark_file_unfinished(file_of_the_first_group); do { + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); group.addr= horizon= log_descriptor.horizon; cursor= log_descriptor.bc; cursor.chaser= 1; @@ -5573,21 +5705,26 @@ translog_write_variable_record_mgroup(LSN *lsn, (ulong)(parts->record_length - (first_page - 1 + buffer_rest) - done))); - rc|= translog_advance_pointer((int)full_pages, 0); + rc= translog_advance_pointer((int)full_pages, 0, &cursor.buffs); translog_unlock(); if (buffer_to_flush != NULL) { - translog_buffer_decrease_writers(buffer_to_flush); + if (!external_buffer_to_flush) + translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); translog_buffer_unlock(buffer_to_flush); buffer_to_flush= NULL; } + external_buffer_to_flush= FALSE; + if (rc) { DBUG_PRINT("error", ("flush of unlock buffer failed")); + //translog_advance_pointer decreased writers so it is OK + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); goto err; } @@ -5624,6 +5761,7 @@ translog_write_variable_record_mgroup(LSN *lsn, } translog_buffer_lock(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer); + used_buffs_register_unlock(&cursor.buffs, cursor.buffer); translog_buffer_unlock(cursor.buffer); translog_lock(); @@ -5638,6 +5776,11 @@ translog_write_variable_record_mgroup(LSN *lsn, first_page= translog_get_current_page_rest(); } buffer_rest= translog_get_current_group_size(); + + if (buffer_to_flush) + used_buffs_register_unlock(&cursor.buffs, + buffer_to_flush); // will be unlocked + } while ((translog_size_t)(first_page + buffer_rest) < (translog_size_t)(parts->record_length - done)); @@ -5733,17 +5876,21 @@ translog_write_variable_record_mgroup(LSN *lsn, (ulong) full_pages * log_descriptor.page_capacity_chunk_2, chunk3_pages, (uint) chunk3_size, (uint) record_rest)); + + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); rc= translog_advance_pointer(pages_to_skip + (int)(chunk0_pages - 1), record_rest + header_fixed_part + (groups.elements - ((page_capacity - header_fixed_part) / (7 + 1)) * - (chunk0_pages - 1)) * (7 + 1)); + (chunk0_pages - 1)) * (7 + 1), + &cursor.buffs); buffer_of_last_lsn= log_descriptor.bc.buffer; translog_unlock(); if (buffer_to_flush != NULL) { + DBUG_ASSERT(!external_buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); @@ -5907,8 +6054,10 @@ translog_write_variable_record_mgroup(LSN *lsn, } while (chunk0_pages != 0); translog_buffer_lock(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer); + used_buffs_register_unlock(&cursor.buffs, cursor.buffer); translog_buffer_unlock(cursor.buffer); rc= 0; + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); if (translog_set_lsn_for_files(file_of_the_first_group, LSN_FILE_NO(*lsn), *lsn, FALSE)) @@ -5917,17 +6066,22 @@ translog_write_variable_record_mgroup(LSN *lsn, translog_mark_file_finished(file_of_the_first_group); delete_dynamic(&groups); - DBUG_RETURN(rc); + DBUG_RETURN(0); err_unlock: translog_unlock(); err: + + if (cursor.buffs.unlck_ptr != cursor.buffs.wrt_ptr) + used_buffs_urgent_unlock(&cursor.buffs); + if (buffer_to_flush != NULL) { /* This is to prevent locking buffer forever in case of error */ - translog_buffer_decrease_writers(buffer_to_flush); + if (!external_buffer_to_flush) + translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); translog_buffer_unlock(buffer_to_flush); @@ -7481,7 +7635,8 @@ static void translog_force_current_buffer_to_finish() DBUG_ASSERT(log_descriptor.bc.ptr !=NULL); DBUG_ASSERT(LSN_FILE_NO(log_descriptor.horizon) == - LSN_FILE_NO(old_buffer->offset)); + LSN_FILE_NO(old_buffer->offset) || + translog_status == TRANSLOG_READONLY ); translog_check_cursor(&log_descriptor.bc); DBUG_ASSERT(left < TRANSLOG_PAGE_SIZE); if (left) diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 4139409d477..13f7a64e786 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -334,13 +334,13 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) }); DEBUG_SYNC_C("mi_open_kfile"); if ((kfile=mysql_file_open(key_file_kfile, name_buff, - (open_mode=O_RDWR) | O_SHARE | O_NOFOLLOW, + (open_mode=O_RDWR) | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_NOSYMLINKS))) < 0) { if ((errno != EROFS && errno != EACCES) || mode != O_RDONLY || (kfile=mysql_file_open(key_file_kfile, name_buff, - (open_mode=O_RDONLY) | O_SHARE | O_NOFOLLOW, + (open_mode=O_RDONLY) | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_NOSYMLINKS))) < 0) goto err; } @@ -1960,7 +1960,7 @@ int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share) DEBUG_SYNC_C("mi_open_datafile"); info->dfile.file= share->bitmap.file.file= mysql_file_open(key_file_dfile, share->data_file_name.str, - share->mode | O_SHARE, MYF(flags)); + share->mode | O_SHARE | O_CLOEXEC, MYF(flags)); return info->dfile.file >= 0 ? 0 : 1; } @@ -1974,7 +1974,7 @@ int _ma_open_keyfile(MARIA_SHARE *share) mysql_mutex_lock(&share->intern_lock); share->kfile.file= mysql_file_open(key_file_kfile, share->unique_file_name.str, - share->mode | O_SHARE | O_NOFOLLOW, + share->mode | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_WME | MY_NOSYMLINKS)); mysql_mutex_unlock(&share->intern_lock); return (share->kfile.file < 0); diff --git a/storage/mroonga/data/install.sql.in b/storage/mroonga/data/install.sql.in index d7d5f3c4ad6..0a2f308aef4 100644 --- a/storage/mroonga/data/install.sql.in +++ b/storage/mroonga/data/install.sql.in @@ -1,6 +1,6 @@ -DELETE IGNORE FROM mysql.plugin WHERE dl = 'ha_mroonga@MRN_PLUGIN_SUFFIX@'; - -INSTALL PLUGIN Mroonga SONAME 'ha_mroonga@MRN_PLUGIN_SUFFIX@'; +SET @inst=IF(EXISTS(SELECT * FROM mysql.plugin WHERE NAME='mroonga'),'DO 1', "INSTALL PLUGIN mroonga SONAME 'ha_mroonga'"); +PREPARE s FROM @inst; +EXECUTE s; DROP FUNCTION IF EXISTS last_insert_grn_id; CREATE FUNCTION last_insert_grn_id RETURNS INTEGER diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 3c4e154ee2d..a98615e5781 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2581,7 +2581,7 @@ maria_declare_plugin(myisam) &myisam_storage_engine, "MyISAM", "MySQL AB", - "MyISAM storage engine", + "Non-transactional engine with good performance and small data footprint", PLUGIN_LICENSE_GPL, myisam_init, /* Plugin Init */ NULL, /* Plugin Deinit */ diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index 43babb2968b..4bd01dcbfa0 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -551,7 +551,7 @@ ulonglong retrieve_auto_increment(MI_INFO *info,const uchar *record) switch (keyseg->type) { case HA_KEYTYPE_INT8: - s_value= (longlong) *(char*)key; + s_value= (longlong) *(const signed char*) key; break; case HA_KEYTYPE_BINARY: value=(ulonglong) *(uchar*) key; diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index a50fe0879c3..4e8920395d5 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -139,13 +139,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) DEBUG_SYNC_C("mi_open_kfile"); if ((kfile= mysql_file_open(mi_key_file_kfile, name_buff, - (open_mode= O_RDWR) | O_SHARE | O_NOFOLLOW, + (open_mode= O_RDWR) | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_NOSYMLINKS))) < 0) { if ((errno != EROFS && errno != EACCES) || mode != O_RDONLY || (kfile= mysql_file_open(mi_key_file_kfile, name_buff, - (open_mode= O_RDONLY) | O_SHARE| O_NOFOLLOW, + (open_mode= O_RDONLY) | O_SHARE| O_NOFOLLOW | O_CLOEXEC, MYF(MY_NOSYMLINKS))) < 0) goto err; } @@ -1270,7 +1270,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share) myf flags= MY_WME | (share->mode & O_NOFOLLOW ? MY_NOSYMLINKS: 0); DEBUG_SYNC_C("mi_open_datafile"); info->dfile= mysql_file_open(mi_key_file_dfile, share->data_file_name, - share->mode | O_SHARE, MYF(flags)); + share->mode | O_SHARE | O_CLOEXEC, MYF(flags)); return info->dfile >= 0 ? 0 : 1; } @@ -1279,7 +1279,7 @@ int mi_open_keyfile(MYISAM_SHARE *share) { if ((share->kfile= mysql_file_open(mi_key_file_kfile, share->unique_file_name, - share->mode | O_SHARE | O_NOFOLLOW, + share->mode | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_NOSYMLINKS | MY_WME))) < 0) return 1; return 0; diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake index c76f711463e..8f01024be63 100644 --- a/storage/rocksdb/build_rocksdb.cmake +++ b/storage/rocksdb/build_rocksdb.cmake @@ -64,10 +64,20 @@ if(SNAPPY_FOUND AND (NOT WITH_ROCKSDB_SNAPPY STREQUAL "OFF")) list(APPEND THIRDPARTY_LIBS ${SNAPPY_LIBRARIES}) endif() +include(CheckFunctionExists) if(ZSTD_FOUND AND (NOT WITH_ROCKSDB_ZSTD STREQUAL "OFF")) - add_definitions(-DZSTD) - include_directories(${ZSTD_INCLUDE_DIR}) - list(APPEND THIRDPARTY_LIBS ${ZSTD_LIBRARY}) + SET(CMAKE_REQUIRED_LIBRARIES zstd) + CHECK_FUNCTION_EXISTS(ZDICT_trainFromBuffer ZSTD_VALID) + UNSET(CMAKE_REQUIRED_LIBRARIES) + if (WITH_ROCKSDB_ZSTD STREQUAL "ON" AND NOT ZSTD_VALID) + MESSAGE(FATAL_ERROR + "WITH_ROCKSDB_ZSTD is ON and ZSTD library was found, but the version needs to be >= 1.1.3") + endif() + if (ZSTD_VALID) + add_definitions(-DZSTD) + include_directories(${ZSTD_INCLUDE_DIR}) + list(APPEND THIRDPARTY_LIBS ${ZSTD_LIBRARY}) + endif() endif() add_definitions(-DZLIB) @@ -119,7 +129,6 @@ int main() { endif() endif() -include(CheckFunctionExists) CHECK_FUNCTION_EXISTS(malloc_usable_size HAVE_MALLOC_USABLE_SIZE) if(HAVE_MALLOC_USABLE_SIZE) add_definitions(-DROCKSDB_MALLOC_USABLE_SIZE) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index dfb4db11343..2c7737a821d 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -479,6 +479,7 @@ static uint32_t rocksdb_access_hint_on_compaction_start; static char *rocksdb_compact_cf_name; static char *rocksdb_checkpoint_name; static my_bool rocksdb_signal_drop_index_thread; +static my_bool rocksdb_signal_remove_mariabackup_checkpoint; static my_bool rocksdb_strict_collation_check = 1; static my_bool rocksdb_ignore_unknown_options = 1; static my_bool rocksdb_enable_2pc = 0; @@ -515,6 +516,67 @@ std::atomic<uint64_t> rocksdb_row_lock_wait_timeouts(0); std::atomic<uint64_t> rocksdb_snapshot_conflict_errors(0); std::atomic<uint64_t> rocksdb_wal_group_syncs(0); + + +/* + Remove directory with files in it. + Used to remove checkpoint created by mariabackup. +*/ +#ifdef _WIN32 +#include <direct.h> /* unlink*/ +#ifndef F_OK +#define F_OK 0 +#endif +#endif + +static int rmdir_force(const char *dir) { + if (access(dir, F_OK)) + return true; + + char path[FN_REFLEN]; + char sep[] = {FN_LIBCHAR, 0}; + int err = 0; + + MY_DIR *dir_info = my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT)); + if (!dir_info) + return 1; + + for (uint i = 0; i < dir_info->number_of_files; i++) { + FILEINFO *file = dir_info->dir_entry + i; + + strxnmov(path, sizeof(path), dir, sep, file->name, NULL); + + err = my_delete(path, 0); + + if (err) { + break; + } + } + + my_dirend(dir_info); + + if (!err) + err = rmdir(dir); + + return (err == 0) ? HA_EXIT_SUCCESS : HA_EXIT_FAILURE; +} + + +static void rocksdb_remove_mariabackup_checkpoint( + my_core::THD *const, + struct st_mysql_sys_var *const , + void *const var_ptr, const void *const) { + std::string mariabackup_checkpoint_dir(rocksdb_datadir); + + mariabackup_checkpoint_dir.append("/mariabackup-checkpoint"); + + if (unlink(mariabackup_checkpoint_dir.c_str()) == 0) + return; + + rmdir_force(mariabackup_checkpoint_dir.c_str()); +} + + static std::unique_ptr<rocksdb::DBOptions> rdb_init_rocksdb_db_options(void) { auto o = std::unique_ptr<rocksdb::DBOptions>(new rocksdb::DBOptions()); @@ -1312,6 +1374,11 @@ static MYSQL_SYSVAR_STR(create_checkpoint, rocksdb_checkpoint_name, rocksdb_create_checkpoint, rocksdb_create_checkpoint_stub, ""); +static MYSQL_SYSVAR_BOOL(remove_mariabackup_checkpoint, + rocksdb_signal_remove_mariabackup_checkpoint, + PLUGIN_VAR_RQCMDARG, "Remove mariabackup checkpoint", + nullptr, rocksdb_remove_mariabackup_checkpoint, FALSE); + static MYSQL_SYSVAR_BOOL(signal_drop_index_thread, rocksdb_signal_drop_index_thread, PLUGIN_VAR_RQCMDARG, "Wake up drop index thread", nullptr, @@ -1675,7 +1742,7 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = { MYSQL_SYSVAR(datadir), MYSQL_SYSVAR(supported_compression_types), MYSQL_SYSVAR(create_checkpoint), - + MYSQL_SYSVAR(remove_mariabackup_checkpoint), MYSQL_SYSVAR(checksums_pct), MYSQL_SYSVAR(store_row_debug_checksums), MYSQL_SYSVAR(verify_row_debug_checksums), @@ -5235,17 +5302,8 @@ int ha_rocksdb::load_hidden_pk_value() { active_index = m_tbl_def->m_key_count - 1; const uint8 save_table_status = table->status; - /* - We should read the latest committed value in the database. - That is, if we have an open transaction with a snapshot, we should not use - it as we may get old data. Start a new transaction to read the latest - value. - */ - Rdb_transaction *const temp_tx = new Rdb_transaction_impl(table->in_use); - temp_tx->start_tx(); - Rdb_transaction *&tx = get_tx_from_thd(table->in_use); - Rdb_transaction *save_tx= tx; - tx= temp_tx; + Rdb_transaction *const tx = get_or_create_tx(table->in_use); + const bool is_new_snapshot = !tx->has_snapshot(); longlong hidden_pk_id = 1; // Do a lookup. @@ -5255,8 +5313,9 @@ int ha_rocksdb::load_hidden_pk_value() { */ auto err = read_hidden_pk_id_from_rowkey(&hidden_pk_id); if (err) { - delete tx; - tx= save_tx; + if (is_new_snapshot) { + tx->release_snapshot(); + } return err; } @@ -5268,8 +5327,9 @@ int ha_rocksdb::load_hidden_pk_value() { !m_tbl_def->m_hidden_pk_val.compare_exchange_weak(old, hidden_pk_id)) { } - delete tx; - tx= save_tx; + if (is_new_snapshot) { + tx->release_snapshot(); + } table->status = save_table_status; active_index = save_active_index; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result index d9e2bf5eea5..017d7b77d31 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result @@ -107,3 +107,12 @@ a b 101 foo 102 bar DROP TABLE t1; +# +# MDEV-15319: [SQL Layer] Server crashes in Field::set_null / myrocks::ha_rocksdb::convert_record_from_storage_format +# (just a testcase) +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 ENGINE=RocksDB AS SELECT VALUE(i) AS a FROM t1; +DELETE FROM t2; +DROP TABLE t1,t2; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result index f616b786f7c..e5fb9ceacba 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result @@ -959,6 +959,7 @@ rocksdb_print_snapshot_conflict_queries OFF rocksdb_rate_limiter_bytes_per_sec 0 rocksdb_read_free_rpl_tables rocksdb_records_in_range 50 +rocksdb_remove_mariabackup_checkpoint OFF rocksdb_reset_stats OFF rocksdb_seconds_between_stat_computes 3600 rocksdb_signal_drop_index_thread OFF diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test index 7282ec237c2..99d4e2d117c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test @@ -101,3 +101,14 @@ UPDATE t1 SET a=a+100; SELECT * FROM t1; DROP TABLE t1; + +--echo # +--echo # MDEV-15319: [SQL Layer] Server crashes in Field::set_null / myrocks::ha_rocksdb::convert_record_from_storage_format +--echo # (just a testcase) +--echo # + +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 ENGINE=RocksDB AS SELECT VALUE(i) AS a FROM t1; +DELETE FROM t2; +DROP TABLE t1,t2; diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_remove_mariabackup_checkpoint_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_remove_mariabackup_checkpoint_basic.result new file mode 100644 index 00000000000..01145cd2ab8 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_remove_mariabackup_checkpoint_basic.result @@ -0,0 +1,4 @@ +SET GLOBAL rocksdb_create_checkpoint=CONCAT(@@rocksdb_datadir,'/mariabackup-checkpoint'); +SET GLOBAL rocksdb_remove_mariabackup_checkpoint=ON; +SET GLOBAL rocksdb_create_checkpoint=CONCAT(@@rocksdb_datadir,'/mariabackup-checkpoint'); +SET GLOBAL rocksdb_remove_mariabackup_checkpoint=ON; diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_remove_mariabackup_checkpoint_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_remove_mariabackup_checkpoint_basic.test new file mode 100644 index 00000000000..30f38283ba4 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_remove_mariabackup_checkpoint_basic.test @@ -0,0 +1,5 @@ +# Simulate creating and removing mariabackup checkpoint twice +SET GLOBAL rocksdb_create_checkpoint=CONCAT(@@rocksdb_datadir,'/mariabackup-checkpoint'); +SET GLOBAL rocksdb_remove_mariabackup_checkpoint=ON; +SET GLOBAL rocksdb_create_checkpoint=CONCAT(@@rocksdb_datadir,'/mariabackup-checkpoint'); +SET GLOBAL rocksdb_remove_mariabackup_checkpoint=ON; diff --git a/storage/spider/mysql-test/spider/r/spider_fixes_part.result b/storage/spider/mysql-test/spider/r/spider_fixes_part.result index faf0b6efbea..9668ef60adc 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes_part.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes_part.result @@ -214,6 +214,37 @@ id 10000 connection master_1; +Crash from b4a2baffa82e5c07b96a1c752228560dcac1359b (MDEV-11084) +Fixed with 4968049799193394d442f26b4e3a8d95b185be72 +Spider crashed if the first partition was not used first +connection master_1; +CREATE TABLE ta_l2 ( +a INT, +b CHAR(1), +c DATETIME, +PRIMARY KEY(a) +) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1 +INSERT INTO ta_l2 SELECT a, b, c FROM tb_l; +Query a Spider table only using the second partition +SELECT a,b,c FROM ta_l2 PARTITION (pt2); +a b c +4 d 2003-11-30 05:01:03 +5 c 2001-12-31 23:59:59 +Query a Spider table only using the first partition +SELECT a,b,c FROM ta_l2 PARTITION (pt1); +a b c +1 a 2008-08-01 10:21:39 +2 b 2000-01-01 00:00:00 +3 e 2007-06-04 20:03:11 +Query a Spider table by all paritions, then the second partition +SELECT min(a), max(a), min(b), max(b) FROM ta_l2; +min(a) max(a) min(b) max(b) +1 5 a e +SELECT a,b,c FROM ta_l2 PARTITION (pt2); +a b c +4 d 2003-11-30 05:01:03 +5 c 2001-12-31 23:59:59 + deinit connection master_1; DROP DATABASE IF EXISTS auto_test_local; diff --git a/storage/spider/mysql-test/spider/t/spider_fixes_part.test b/storage/spider/mysql-test/spider/t/spider_fixes_part.test index ef5a8026c02..c729131f338 100644 --- a/storage/spider/mysql-test/spider/t/spider_fixes_part.test +++ b/storage/spider/mysql-test/spider/t/spider_fixes_part.test @@ -616,6 +616,115 @@ if ($HAVE_PARTITION) } } +--echo +--echo Crash from b4a2baffa82e5c07b96a1c752228560dcac1359b (MDEV-11084) +--echo Fixed with 4968049799193394d442f26b4e3a8d95b185be72 +--echo Spider crashed if the first partition was not used first +if ($HAVE_PARTITION) +{ + if ($USE_CHILD_GROUP2) + { + if (!$OUTPUT_CHILD_GROUP2) + { + --disable_query_log + --disable_result_log + } + --connection child2_2 + if ($OUTPUT_CHILD_GROUP2) + { + --disable_query_log + echo CHILD2_2_DROP_TABLES; + echo CHILD2_2_CREATE_TABLES; + } + --disable_warnings + eval $CHILD2_2_DROP_TABLES; + --enable_warnings + eval $CHILD2_2_CREATE_TABLES; + if ($OUTPUT_CHILD_GROUP2) + { + --enable_query_log + } + if ($USE_GENERAL_LOG) + { + TRUNCATE TABLE mysql.general_log; + } + --connection child2_1 + if ($OUTPUT_CHILD_GROUP2) + { + --disable_query_log + echo CHILD2_1_DROP_TABLES2; + echo CHILD2_1_CREATE_TABLES2; + } + --disable_warnings + eval $CHILD2_1_DROP_TABLES2; + --enable_warnings + eval $CHILD2_1_CREATE_TABLES2; + if ($OUTPUT_CHILD_GROUP2) + { + --enable_query_log + } + if ($USE_GENERAL_LOG) + { + TRUNCATE TABLE mysql.general_log; + } + if (!$OUTPUT_CHILD_GROUP2) + { + --enable_query_log + --enable_result_log + } + } + --connection master_1 + --disable_query_log + --disable_warnings + DROP TABLE IF EXISTS ta_l2; + --enable_warnings + echo CREATE TABLE ta_l2 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) + ) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1; + eval CREATE TABLE ta_l2 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) + ) $MASTER_1_ENGINE $MASTER_1_COMMENT2_P_2_1; + --enable_query_log + INSERT INTO ta_l2 SELECT a, b, c FROM tb_l; + --echo Query a Spider table only using the second partition + SELECT a,b,c FROM ta_l2 PARTITION (pt2); + --echo Query a Spider table only using the first partition + SELECT a,b,c FROM ta_l2 PARTITION (pt1); + --echo Query a Spider table by all paritions, then the second partition + SELECT min(a), max(a), min(b), max(b) FROM ta_l2; + SELECT a,b,c FROM ta_l2 PARTITION (pt2); + if ($USE_CHILD_GROUP2) + { + if (!$OUTPUT_CHILD_GROUP2) + { + --disable_query_log + --disable_result_log + } + --connection child2_2 + if ($USE_GENERAL_LOG) + { + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; + } + eval $CHILD2_2_SELECT_TABLES; + --connection child2_1 + if ($USE_GENERAL_LOG) + { + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; + } + eval $CHILD2_1_SELECT_TABLES2; + if (!$OUTPUT_CHILD_GROUP2) + { + --enable_query_log + --enable_result_log + } + } +} --echo --echo deinit diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 16f7ab4ce75..8facf6c3f10 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -54,7 +54,7 @@ ELSEIF(LIBJEMALLOC STREQUAL jemalloc) GET_FILENAME_COMPONENT(LIBJEMALLOC_PATH ${LIBJEMALLOC_SO} REALPATH CACHE) ENDIF() -IF(LIBJEMALLOC_PATH AND RPM MATCHES fedora28) # TODO check for jemalloc version +IF(LIBJEMALLOC_PATH AND (RPM OR DEB)) UNSET(LIBJEMALLOC) GET_DIRECTORY_PROPERTY(V DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITION CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES) SET(CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES "${V} jemalloc" PARENT_SCOPE) @@ -75,6 +75,7 @@ IF(INSTALL_SYSCONFDIR) COMPONENT tokudb-engine) ENDIF() +MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-shadow") MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG) MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough") diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake index 385723aebc7..50d35ee4906 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake @@ -149,7 +149,7 @@ set_cflags_if_supported( -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith - -Wshadow + #-Wshadow will fail with GCC-8 ${OPTIONAL_CFLAGS} ## other flags to try: #-Wunsafe-loop-optimizations diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc index a98768158dd..aefd6f0ec22 100644 --- a/storage/tokudb/PerconaFT/ft/ft-ops.cc +++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc @@ -822,22 +822,22 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile), fprintf( stderr, "%s:%d:toku_ftnode_fetch_callback - " - "file[%s], blocknum[%ld], toku_deserialize_ftnode_from " + "file[%s], blocknum[%lld], toku_deserialize_ftnode_from " "failed with a checksum error.\n", __FILE__, __LINE__, toku_cachefile_fname_in_env(cachefile), - blocknum.b); + (longlong)blocknum.b); } else { fprintf( stderr, "%s:%d:toku_ftnode_fetch_callback - " - "file[%s], blocknum[%ld], toku_deserialize_ftnode_from " + "file[%s], blocknum[%lld], toku_deserialize_ftnode_from " "failed with %d.\n", __FILE__, __LINE__, toku_cachefile_fname_in_env(cachefile), - blocknum.b, + (longlong)blocknum.b, r); } // make absolutely sure we crash before doing anything else. diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc index b24d72a5dff..0d6573972d7 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc @@ -656,20 +656,20 @@ exit: fprintf(stderr, \ "%s:%d toku_deserialize_ft_from: " \ "filename[%s] " \ - "r[%d] max_acceptable_lsn[%lu]" \ - "r0[%d] checkpoint_lsn_0[%lu] checkpoint_count_0[%lu] " \ - "r1[%d] checkpoint_lsn_1[%lu] checkpoint_count_1[%lu]\n", \ + "r[%d] max_acceptable_lsn[%llu]" \ + "r0[%d] checkpoint_lsn_0[%llu] checkpoint_count_0[%llu] " \ + "r1[%d] checkpoint_lsn_1[%llu] checkpoint_count_1[%llu]\n", \ __FILE__, \ __LINE__, \ fn, \ r, \ - max_acceptable_lsn.lsn, \ + (ulonglong)max_acceptable_lsn.lsn, \ r0, \ - checkpoint_lsn_0.lsn, \ - checkpoint_count_0, \ + (ulonglong)checkpoint_lsn_0.lsn, \ + (ulonglong)checkpoint_count_0, \ r1, \ - checkpoint_lsn_1.lsn, \ - checkpoint_count_1); + (ulonglong)checkpoint_lsn_1.lsn, \ + (ulonglong)checkpoint_count_1); int toku_deserialize_ft_from(int fd, const char *fn, diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc index 22a562ae24c..f3b31eb31be 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc @@ -1170,11 +1170,11 @@ int verify_ftnode_sub_block(struct sub_block *sb, fprintf( stderr, "%s:%d:verify_ftnode_sub_block - " - "file[%s], blocknum[%ld], stored_xsum[%u] != actual_xsum[%u]\n", + "file[%s], blocknum[%lld], stored_xsum[%u] != actual_xsum[%u]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, stored_xsum, actual_xsum); dump_bad_block((Bytef *) sb->uncompressed_ptr, sb->uncompressed_size); @@ -1197,11 +1197,11 @@ static int deserialize_ftnode_info(struct sub_block *sb, FTNODE node) { fprintf( stderr, "%s:%d:deserialize_ftnode_info - " - "file[%s], blocknum[%ld], verify_ftnode_sub_block failed with %d\n", + "file[%s], blocknum[%lld], verify_ftnode_sub_block failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(static_cast<unsigned char *>(sb->uncompressed_ptr), sb->uncompressed_size); @@ -1253,11 +1253,11 @@ static int deserialize_ftnode_info(struct sub_block *sb, FTNODE node) { fprintf( stderr, "%s:%d:deserialize_ftnode_info - " - "file[%s], blocknum[%ld], data_size[%d] != rb.ndone[%d]\n", + "file[%s], blocknum[%lld], data_size[%d] != rb.ndone[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, data_size, rb.ndone); dump_bad_block(rb.buf, rb.size); @@ -1388,12 +1388,12 @@ static int deserialize_ftnode_partition( if (r != 0) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], " + "file[%s], blocknum[%lld], " "verify_ftnode_sub_block failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); goto exit; } @@ -1410,12 +1410,12 @@ static int deserialize_ftnode_partition( if (ch != FTNODE_PARTITION_MSG_BUFFER) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], ch[%d] != " + "file[%s], blocknum[%lld], ch[%d] != " "FTNODE_PARTITION_MSG_BUFFER[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, ch, FTNODE_PARTITION_MSG_BUFFER); dump_bad_block(rb.buf, rb.size); @@ -1433,12 +1433,12 @@ static int deserialize_ftnode_partition( if (ch != FTNODE_PARTITION_DMT_LEAVES) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], ch[%d] != " + "file[%s], blocknum[%lld], ch[%d] != " "FTNODE_PARTITION_DMT_LEAVES[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, ch, FTNODE_PARTITION_DMT_LEAVES); dump_bad_block(rb.buf, rb.size); @@ -1457,11 +1457,11 @@ static int deserialize_ftnode_partition( if (rb.ndone != rb.size) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], rb.ndone[%d] != rb.size[%d]\n", + "file[%s], blocknum[%lld], rb.ndone[%d] != rb.size[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, rb.ndone, rb.size); dump_bad_block(rb.buf, rb.size); @@ -1485,12 +1485,12 @@ static int decompress_and_deserialize_worker(struct rbuf curr_rbuf, const char *fname = toku_ftnode_get_cachefile_fname_in_env(node); fprintf(stderr, "%s:%d:decompress_and_deserialize_worker - " - "file[%s], blocknum[%ld], read_and_decompress_sub_block failed " + "file[%s], blocknum[%lld], read_and_decompress_sub_block failed " "with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(curr_rbuf.buf, curr_rbuf.size); goto exit; @@ -1502,12 +1502,12 @@ static int decompress_and_deserialize_worker(struct rbuf curr_rbuf, const char *fname = toku_ftnode_get_cachefile_fname_in_env(node); fprintf(stderr, "%s:%d:decompress_and_deserialize_worker - " - "file[%s], blocknum[%ld], deserialize_ftnode_partition failed " + "file[%s], blocknum[%lld], deserialize_ftnode_partition failed " "with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(curr_rbuf.buf, curr_rbuf.size); goto exit; @@ -1582,11 +1582,11 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], rb->size[%u] < 24\n", + "file[%s], blocknum[%lld], rb->size[%u] < 24\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, rb->size); dump_bad_block(rb->buf, rb->size); // TODO: What error do we return here? @@ -1602,12 +1602,12 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], unrecognized magic number " + "file[%s], blocknum[%lld], unrecognized magic number " "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, static_cast<const uint8_t*>(magic)[0], static_cast<const uint8_t*>(magic)[1], static_cast<const uint8_t*>(magic)[2], @@ -1627,12 +1627,12 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], node->layout_version_read_from_disk[%d] " + "file[%s], blocknum[%lld], node->layout_version_read_from_disk[%d] " "< FT_FIRST_LAYOUT_VERSION_WITH_BASEMENT_NODES[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, node->layout_version_read_from_disk, FT_FIRST_LAYOUT_VERSION_WITH_BASEMENT_NODES); dump_bad_block(rb->buf, rb->size); @@ -1667,11 +1667,11 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], needed_size[%d] > rb->size[%d]\n", + "file[%s], blocknum[%lld], needed_size[%d] > rb->size[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, needed_size, rb->size); dump_bad_block(rb->buf, rb->size); @@ -1695,11 +1695,11 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], stored_checksum[%d] != checksum[%d]\n", + "file[%s], blocknum[%lld], stored_checksum[%d] != checksum[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, stored_checksum, checksum); dump_bad_block(rb->buf, rb->size); @@ -1717,12 +1717,12 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], rb->size[%d] - rb->ndone[%d] < " + "file[%s], blocknum[%lld], rb->size[%d] - rb->ndone[%d] < " "sb_node_info.compressed_size[%d] + 8\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, rb->size, rb->ndone, sb_node_info.compressed_size); @@ -1744,11 +1744,11 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], sb_node_info.xsum[%d] != actual_xsum[%d]\n", + "file[%s], blocknum[%lld], sb_node_info.xsum[%d] != actual_xsum[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, sb_node_info.xsum, actual_xsum); dump_bad_block(rb->buf, rb->size); @@ -1774,12 +1774,12 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], deserialize_ftnode_info failed with " + "file[%s], blocknum[%lld], deserialize_ftnode_info failed with " "%d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block( static_cast<unsigned char *>(sb_node_info.uncompressed_ptr), @@ -1812,12 +1812,12 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], toku_ftnode_pf_callback failed with " + "file[%s], blocknum[%lld], toku_ftnode_pf_callback failed with " "%d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb->buf, rb->size); goto cleanup; @@ -2164,12 +2164,12 @@ static int deserialize_and_upgrade_ftnode(FTNODE node, const char* fname = toku_cachefile_fname_in_env(bfe->ft->cf); fprintf(stderr, "%s:%d:deserialize_and_upgrade_ftnode - " - "file[%s], blocknum[%ld], " + "file[%s], blocknum[%lld], " "read_and_decompress_block_from_fd_into_rbuf failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); goto exit; } @@ -2190,12 +2190,12 @@ static int deserialize_and_upgrade_ftnode(FTNODE node, const char* fname = toku_cachefile_fname_in_env(bfe->ft->cf); fprintf(stderr, "%s:%d:deserialize_and_upgrade_ftnode - " - "file[%s], blocknum[%ld], version[%d] > " + "file[%s], blocknum[%lld], version[%d] > " "FT_LAYOUT_VERSION_14[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, version, FT_LAYOUT_VERSION_14); dump_bad_block(rb.buf, rb.size); @@ -2278,12 +2278,12 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, memcmp(magic, "tokunode", 8) != 0) { fprintf(stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], unrecognized magic number " + "file[%s], blocknum[%lld], unrecognized magic number " "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, static_cast<const uint8_t *>(magic)[0], static_cast<const uint8_t *>(magic)[1], static_cast<const uint8_t *>(magic)[2], @@ -2309,12 +2309,12 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, if (r != 0) { fprintf(stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], deserialize_and_upgrade_ftnode " + "file[%s], blocknum[%lld], deserialize_and_upgrade_ftnode " "failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb->buf, rb->size); goto cleanup; @@ -2355,11 +2355,11 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], stored_checksum[%d] != checksum[%d]\n", + "file[%s], blocknum[%lld], stored_checksum[%d] != checksum[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, stored_checksum, checksum); dump_bad_block(rb->buf, rb->size); @@ -2377,12 +2377,12 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], read_and_decompress_sub_block failed " + "file[%s], blocknum[%lld], read_and_decompress_sub_block failed " "with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block( static_cast<unsigned char *>(sb_node_info.uncompressed_ptr), @@ -2398,12 +2398,12 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], deserialize_ftnode_info failed with " + "file[%s], blocknum[%lld], deserialize_ftnode_info failed with " "%d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb->buf, rb->size); goto cleanup; @@ -2470,12 +2470,12 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], childnum[%d], " + "file[%s], blocknum[%lld], childnum[%d], " "decompress_and_deserialize_worker failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, i, r); dump_bad_block(rb->buf, rb->size); @@ -2490,13 +2490,13 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], childnum[%d], " + "file[%s], blocknum[%lld], childnum[%d], " "check_and_copy_compressed_sub_block_worker failed with " "%d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, i, r); dump_bad_block(rb->buf, rb->size); @@ -2641,12 +2641,12 @@ int toku_deserialize_bp_from_compressed(FTNODE node, const char* fname = toku_cachefile_fname_in_env(bfe->ft->cf); fprintf(stderr, "%s:%d:toku_deserialize_bp_from_compressed - " - "file[%s], blocknum[%ld], " + "file[%s], blocknum[%lld], " "deserialize_ftnode_partition failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(static_cast<unsigned char *>(curr_sb->compressed_ptr), curr_sb->compressed_size); @@ -2689,12 +2689,12 @@ static int deserialize_ftnode_from_fd(int fd, fprintf( stderr, "%s:%d:deserialize_ftnode_from_fd - " - "file[%s], blocknum[%ld], deserialize_ftnode_from_rbuf failed with " + "file[%s], blocknum[%lld], deserialize_ftnode_from_rbuf failed with " "%d\n", __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb.buf, rb.size); } diff --git a/storage/tokudb/PerconaFT/portability/memory.h b/storage/tokudb/PerconaFT/portability/memory.h index 5ae652d39fc..851e4d69e03 100644 --- a/storage/tokudb/PerconaFT/portability/memory.h +++ b/storage/tokudb/PerconaFT/portability/memory.h @@ -107,7 +107,7 @@ size_t toku_malloc_usable_size(void *p) __attribute__((__visibility__("default") #define XMALLOC(v) CAST_FROM_VOIDP(v, toku_xmalloc(sizeof(*v))) #define XMALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xmalloc((n)*sizeof(*v))) #define XCALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xcalloc((n), (sizeof(*v)))) -#define XCALLOC(v) XCALLOC_N(1,(v)) +#define XCALLOC(v) XCALLOC_N(1,v) #define XREALLOC(v,s) CAST_FROM_VOIDP(v, toku_xrealloc(v, s)) #define XREALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xrealloc(v, (n)*sizeof(*v))) diff --git a/storage/tokudb/PerconaFT/portability/toku_debug_sync.h b/storage/tokudb/PerconaFT/portability/toku_debug_sync.h index cbe72b16912..cf0788f6f2b 100644 --- a/storage/tokudb/PerconaFT/portability/toku_debug_sync.h +++ b/storage/tokudb/PerconaFT/portability/toku_debug_sync.h @@ -63,9 +63,6 @@ inline void toku_debug_sync(struct tokutxn *txn, const char *sync_point_name) { void *client_extra; THD *thd; - if (likely(!opt_debug_sync_timeout)) - return; - toku_txn_get_client_id(txn, &client_id, &client_extra); thd = reinterpret_cast<THD *>(client_extra); DEBUG_SYNC(thd, sync_point_name); diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h index e3bd3bce598..a0dfcc246a7 100644 --- a/storage/tokudb/PerconaFT/portability/toku_pthread.h +++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h @@ -162,10 +162,20 @@ typedef struct toku_mutex_aligned { #define ZERO_COND_INITIALIZER \ { 0 } #elif defined(__APPLE__) +#if TOKU_PTHREAD_DEBUG +#define ZERO_COND_INITIALIZER \ + { \ + { 0 , { 0 } }, \ + nullptr, \ + 0 \ + } +#else #define ZERO_COND_INITIALIZER \ { \ - { 0 } \ + { 0 , { 0 } }, \ + nullptr \ } +#endif #else // __linux__, at least #define ZERO_COND_INITIALIZER \ {} diff --git a/storage/tokudb/PerconaFT/src/CMakeLists.txt b/storage/tokudb/PerconaFT/src/CMakeLists.txt index 65bf4814cf8..bae37389004 100644 --- a/storage/tokudb/PerconaFT/src/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/src/CMakeLists.txt @@ -18,7 +18,7 @@ set(tokudb_srcs ## make the shared library add_library(${LIBTOKUDB} SHARED ${tokudb_srcs}) add_dependencies(${LIBTOKUDB} install_tdb_h generate_log_code) -target_link_libraries(${LIBTOKUDB} LINK_PRIVATE locktree_static ft_static util_static lzma snappy ${LIBTOKUPORTABILITY}) +target_link_libraries(${LIBTOKUDB} LINK_PRIVATE locktree_static ft_static util_static lzma snappy dbug ${LIBTOKUPORTABILITY}) target_link_libraries(${LIBTOKUDB} LINK_PUBLIC ${ZLIB_LIBRARY} ) ## make the static library diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh index f0195ecadd3..f0195ecadd3 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile index ec64c622026..ec64c622026 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess index 7501b1bee01..7501b1bee01 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath index c492a93b663..c492a93b663 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub index a39437d0158..a39437d0158 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp index df8eea7e4ce..df8eea7e4ce 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh index 6781b987bdb..6781b987bdb 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh index b36c4ad366c..b36c4ad366c 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing index 28055d2ae6f..28055d2ae6f 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash index 35ea4dae973..35ea4dae973 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh index ff0cb304df4..ff0cb304df4 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh index 7dd9a3901bf..7dd9a3901bf 100644..100755 --- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh +++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh diff --git a/storage/tokudb/PerconaFT/util/dmt.cc b/storage/tokudb/PerconaFT/util/dmt.cc index b5b94982487..642c9367d7e 100644 --- a/storage/tokudb/PerconaFT/util/dmt.cc +++ b/storage/tokudb/PerconaFT/util/dmt.cc @@ -80,8 +80,8 @@ void dmt<dmtdata_t, dmtdataout_t, dmtwriter_t>::create_from_sorted_memory_of_fix paranoid_invariant(numvalues > 0); void *ptr = toku_mempool_malloc(&this->mp, aligned_memsize); paranoid_invariant_notnull(ptr); - uint8_t * const CAST_FROM_VOIDP(dest, ptr); - const uint8_t * const CAST_FROM_VOIDP(src, mem); + uint8_t * CAST_FROM_VOIDP(dest, ptr); + const uint8_t * CAST_FROM_VOIDP(src, mem); if (pad_bytes == 0) { paranoid_invariant(aligned_memsize == mem_length); memcpy(dest, src, aligned_memsize); diff --git a/storage/tokudb/PerconaFT/util/omt.h b/storage/tokudb/PerconaFT/util/omt.h index c7ed2ca546f..36946401381 100644 --- a/storage/tokudb/PerconaFT/util/omt.h +++ b/storage/tokudb/PerconaFT/util/omt.h @@ -127,7 +127,7 @@ public: paranoid_invariant(index != NODE_NULL); m_index = index; } -} __attribute__((__packed__,aligned(4))); +} ; template<> class subtree_templated<true> { @@ -184,7 +184,7 @@ public: inline void disable_bit(void) { m_bitfield &= MASK_INDEX; } -} __attribute__((__packed__)) ; +} ; template<typename omtdata_t, bool subtree_supports_marks> class omt_node_templated { @@ -197,7 +197,7 @@ public: // this needs to be in both implementations because we don't have // a "static if" the caller can use inline void clear_stolen_bits(void) {} -} __attribute__((__packed__,aligned(4))); +} ; template<typename omtdata_t> class omt_node_templated<omtdata_t, true> { @@ -234,7 +234,7 @@ public: this->unset_marked_bit(); this->unset_marks_below_bit(); } -} __attribute__((__packed__,aligned(4))); +} ; } diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result index 7f8b9dd5104..a5060d9e3bf 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result @@ -483,72 +483,72 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; ******************** CREATE USER ******************** CREATE USER 'user_test_rpl'@'localhost' IDENTIFIED BY PASSWORD '*1111111111111111111111111111111111111111'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection master; ******************** GRANT ******************** GRANT SELECT ON *.* TO 'user_test_rpl'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 Y +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 Y connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 Y +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 Y connection master; ******************** REVOKE ******************** REVOKE SELECT ON *.* FROM 'user_test_rpl'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *1111111111111111111111111111111111111111 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl *1111111111111111111111111111111111111111 N connection master; ******************** SET PASSWORD ******************** SET PASSWORD FOR 'user_test_rpl'@'localhost' = '*0000000000000000000000000000000000000000'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl mysql_native_password *0000000000000000000000000000000000000000 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl mysql_native_password *0000000000000000000000000000000000000000 N connection master; ******************** RENAME USER ******************** RENAME USER 'user_test_rpl'@'localhost' TO 'user_test_rpl_2'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl_2 *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl_2 mysql_native_password *0000000000000000000000000000000000000000 N connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv -localhost user_test_rpl_2 *0000000000000000000000000000000000000000 N +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv +localhost user_test_rpl_2 mysql_native_password *0000000000000000000000000000000000000000 N connection master; ******************** DROP USER ******************** DROP USER 'user_test_rpl_2'@'localhost'; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv connection slave; USE test_rpl; -SELECT host, user, password, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; -host user password select_priv +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +host user password plugin authentication_string select_priv connection master; INSERT INTO t1 VALUES(100, 'test'); diff --git a/storage/tokudb/tokudb.cnf.in b/storage/tokudb/tokudb.cnf.in index de9b5b711ee..ff7f0a5f5f6 100644 --- a/storage/tokudb/tokudb.cnf.in +++ b/storage/tokudb/tokudb.cnf.in @@ -5,5 +5,4 @@ plugin-load-add=ha_tokudb.so [mysqld_safe] -# it might be necessary to uncomment the following line if jemalloc >= 5.0.0 @cnf_malloc_lib@ diff --git a/storage/tokudb/tokudb.conf.in b/storage/tokudb/tokudb.conf.in index d22f6686d91..a5ff055f44c 100644 --- a/storage/tokudb/tokudb.conf.in +++ b/storage/tokudb/tokudb.conf.in @@ -1,3 +1,2 @@ [Service] -# it might be necessary to uncomment the following line if jemalloc >= 5.0.0 @systemd_env@ diff --git a/storage/tokudb/tokudb_thread.h b/storage/tokudb/tokudb_thread.h index 0be5583ffb2..bd89f4dfd9c 100644 --- a/storage/tokudb/tokudb_thread.h +++ b/storage/tokudb/tokudb_thread.h @@ -111,7 +111,6 @@ public: // wait for the event to become signalled void wait(void); - int wait(ulonglong microseconds); // signal the event void signal(void); @@ -152,7 +151,6 @@ public: // wait for the semaphore to become signalled E_WAIT wait(void); - E_WAIT wait(ulonglong microseconds); // signal the semaphore to increase the count // return true if signalled, false if ignored due to count @@ -372,28 +370,6 @@ inline void event_t::wait(void) { assert_debug(r == 0); return; } -inline int event_t::wait(ulonglong microseconds) { - timespec waittime = time::offset_timespec(microseconds); - int r = pthread_mutex_timedlock(&_mutex, &waittime); - if (r == ETIMEDOUT) return ETIMEDOUT; - assert_debug(r == 0); - while (_signalled == false && _pulsed == false) { - r = pthread_cond_timedwait(&_cond, &_mutex, &waittime); - if (r == ETIMEDOUT) { - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return ETIMEDOUT; - } - assert_debug(r == 0); - } - if (_manual_reset == false) - _signalled = false; - if (_pulsed) - _pulsed = false; - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return 0; -} inline void event_t::signal(void) { int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex); assert_debug(r == 0); @@ -479,31 +455,6 @@ inline semaphore_t::E_WAIT semaphore_t::wait(void) { assert_debug(r == 0); return ret; } -inline semaphore_t::E_WAIT semaphore_t::wait(ulonglong microseconds) { - E_WAIT ret; - timespec waittime = time::offset_timespec(microseconds); - int r = pthread_mutex_timedlock(&_mutex, &waittime); - if (r == ETIMEDOUT) return E_TIMEDOUT; - assert_debug(r == 0); - while (_signalled == 0 && _interrupted == false) { - r = pthread_cond_timedwait(&_cond, &_mutex, &waittime); - if (r == ETIMEDOUT) { - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return E_TIMEDOUT; - } - assert_debug(r == 0); - } - if (_interrupted) { - ret = E_INTERRUPTED; - } else { - _signalled--; - ret = E_SIGNALLED; - } - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return ret; -} inline bool semaphore_t::signal(void) { bool ret = false; int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex); diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 52184baef7e..b5767432fc2 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -41,10 +41,12 @@ ELSE() SET(inst_location ${INSTALL_SUPPORTFILESDIR}) ENDIF() -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh - ${CMAKE_CURRENT_BINARY_DIR}/wsrep.${ini_file_extension} @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wsrep.${ini_file_extension} +IF(WITH_WSREP) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh + ${CMAKE_CURRENT_BINARY_DIR}/wsrep.${ini_file_extension} @ONLY) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wsrep.${ini_file_extension} DESTINATION ${inst_location} COMPONENT IniFiles) +ENDIF() IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 342929d2ecd..0a81b71171a 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -25,7 +25,6 @@ # Description: MariaDB is a very fast and reliable SQL database engine. ### END INIT INFO -# If you install MariaDB on some other places than @prefix@, then you # have to do one of the following things for this script to work: # # - Run this script from within the MariaDB installation directory diff --git a/support-files/policy/selinux/mariadb-server.fc b/support-files/policy/selinux/mariadb-server.fc index 1a69ecc2c40..409f72923aa 100644 --- a/support-files/policy/selinux/mariadb-server.fc +++ b/support-files/policy/selinux/mariadb-server.fc @@ -1,4 +1,4 @@ -# This SELinux file contexts (.fc) file has been copied under BSD License from +# This SELinux file contexts (.fc) file has been copied under New BSD License from # Percona XtraDB Cluster. /etc/init\.d/rc\.d/mysql -- gen_context(system_u:object_r:mysqld_initrc_exec_t,s0) diff --git a/support-files/policy/selinux/mariadb-server.te b/support-files/policy/selinux/mariadb-server.te index 34d79326b10..45ef40f4153 100644 --- a/support-files/policy/selinux/mariadb-server.te +++ b/support-files/policy/selinux/mariadb-server.te @@ -1,4 +1,4 @@ -# This SELinux type enforcement (.te) file has been copied under BSD License +# This SELinux type enforcement (.te) file has been copied under New BSD License # from Percona XtraDB Cluster, along with some additions. module mariadb-server 1.0; diff --git a/support-files/wsrep.cnf.sh b/support-files/wsrep.cnf.sh index a5390855ca1..51ce3dca2dd 100644 --- a/support-files/wsrep.cnf.sh +++ b/support-files/wsrep.cnf.sh @@ -30,6 +30,9 @@ bind-address=0.0.0.0 ## WSREP options ## +# Enable wsrep +wsrep_on=1 + # Full path to wsrep provider library or 'none' wsrep_provider=none diff --git a/unittest/embedded/CMakeLists.txt b/unittest/embedded/CMakeLists.txt new file mode 100644 index 00000000000..cf48550c377 --- /dev/null +++ b/unittest/embedded/CMakeLists.txt @@ -0,0 +1,20 @@ + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/libmysqld/include + ${PCRE_INCLUDES} + ${CMAKE_SOURCE_DIR}/sql + ${MY_READLINE_INCLUDE_DIR} + ) + + +ADD_DEFINITIONS(-DEMBEDDED_LIBRARY -UMYSQL_CLIENT) + + +MYSQL_ADD_EXECUTABLE(test-connect-t test-connect.cc + COMPONENT Test) +TARGET_LINK_LIBRARIES(test-connect-t mysqlserver ) +MY_ADD_TEST(test-connect) + +IF(UNIX) +SET_TARGET_PROPERTIES(test-connect-t PROPERTIES ENABLE_EXPORTS TRUE) +ENDIF() diff --git a/unittest/embedded/test-connect.cc b/unittest/embedded/test-connect.cc new file mode 100644 index 00000000000..cd122286130 --- /dev/null +++ b/unittest/embedded/test-connect.cc @@ -0,0 +1,78 @@ +#include <mysql.h> +#include <stdio.h> +#include <stdlib.h> + +int get_evar(char **hostname, char **port, char** username, char ** password) +{ + + if (!((*hostname)= getenv("MYSQL_TEST_HOST"))) + (*hostname)= (char *)"127.0.0.1"; + + if (!((*port)= getenv("MASTER_MYPORT"))) + { + if (!((*port)= getenv("MYSQL_TEST_PORT"))) + return 1; + } + + if (!((*username)= getenv("MYSQL_TEST_USER"))) + (*username)= (char *)"root"; + + if (!((*password)= getenv("MYSQL_TEST_PASSWD"))) + (*password)= (char *)""; + + return 0; +} + +int main(int argc, char *argv[]) +{ + MYSQL *mysql; + char *host; + char *user; + char *passwd; + char *porta; + unsigned int port; + + if (get_evar(&host, &porta, &user, &passwd)) + { + printf("set environment variable MASTER_MYPORT\n"); + return 1; + } + + port = atoi(porta); + + mysql_thread_init(); + + if (mysql_server_init(-1, NULL, NULL) != 0) { + printf("mysql_library_init failed"); + return 1; + } + + + mysql = mysql_init(NULL); + + if (!mysql) { + printf("mysql_init failed"); + return 1; + } + + if (mysql_options(mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL) != 0) { + printf("mysql_options MYSQL_OPT_USE_REMOTE_CONNECTION failed: %s\n", mysql_error(mysql)); + return 1; + } + + if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4") != 0) { + printf("mysql_options MYSQL_SET_CHARSET_NAME utf8mb4 failed: %s\n", mysql_error(mysql)); + return 1; + } + + if (!mysql_real_connect(mysql, host, user, passwd, NULL, port, NULL, CLIENT_FOUND_ROWS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS)) { + printf("mysql_real_connect failed: %s\n", mysql_error(mysql)); + return 1; + } + mysql_close(mysql); + mysql_thread_end(); + mysql_library_end(); + + return 0; + +} diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc index dbb16e51c70..07f0b0e7a7e 100644 --- a/unittest/sql/mf_iocache-t.cc +++ b/unittest/sql/mf_iocache-t.cc @@ -254,10 +254,43 @@ void mdev10259() } +void mdev14014() +{ + int res; + uchar buf_o[200]; + uchar buf_i[200]; + memset(buf_i, 0, sizeof( buf_i)); + memset(buf_o, FILL, sizeof(buf_o)); + + diag("MDEV-14014 Dump thread reads past last 'officially' written byte"); + + init_io_cache_encryption(); + + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + + res= my_b_write(&info, buf_o, sizeof(buf_o)); + ok(res == 0, "buffer is written" INFO_TAIL); + + res= my_b_flush_io_cache(&info, 1); + ok(res == 0, "flush" INFO_TAIL); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + info.end_of_file= 100; + res= my_b_read(&info, buf_i, sizeof(buf_i)); + ok(res == 1 && buf_i[100] == 0 && buf_i[200-1] == 0, + "short read leaves buf_i[100..200-1] == 0"); + + close_cached_file(&info); +} + + int main(int argc __attribute__((unused)),char *argv[]) { MY_INIT(argv[0]); - plan(46); + plan(51); /* temp files with and without encryption */ encrypt_tmp_files= 1; @@ -273,6 +306,8 @@ int main(int argc __attribute__((unused)),char *argv[]) mdev10259(); encrypt_tmp_files= 0; + mdev14014(); + my_end(0); return exit_status(); } diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 6358b976e16..fa02eb03caa 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -211,6 +211,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, none of the provided ciphers could be selected */ if (cipher && + SSL_CTX_set_ciphersuites(ssl_fd->ssl_context, cipher) == 0 && SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher) == 0) { *error= SSL_INITERR_CIPHERS; |