diff --git a/CMakeLists.txt b/CMakeLists.txt
index b9c24eff4267..14362b1c4725 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -241,6 +241,7 @@ INCLUDE(zlib)
INCLUDE(lz4)
INCLUDE(libevent)
INCLUDE(ssl)
+INCLUDE(sasl)
INCLUDE(readline)
INCLUDE(protobuf)
INCLUDE(mysql_version)
@@ -532,6 +533,12 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/libbinlogevents/export)
# Add bundled or system zlib.
MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+IF(BUILD_BUNDLED_ZLIB)
+ INCLUDE_DIRECTORIES(SYSTEM
+ ${CMAKE_CURRENT_SOURCE_DIR}/zlib
+ ${CMAKE_CURRENT_BINARY_DIR}/zlib
+ )
+ENDIF()
# Add bundled yassl/taocrypt or system openssl.
MYSQL_CHECK_SSL()
# Add system/bundled editline.
@@ -540,6 +547,8 @@ MYSQL_CHECK_EDITLINE()
MYSQL_CHECK_LIBEVENT()
# Add lz4 library
MYSQL_CHECK_LZ4()
+# Add SASL library
+MYSQL_CHECK_SASL()
# Add protoc and libprotobuf
IF(NOT WITHOUT_SERVER)
MYSQL_CHECK_PROTOBUF()
diff --git a/VERSION b/VERSION
index c15a03c3f084..41dc80043516 100644
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=5
MYSQL_VERSION_MINOR=7
-MYSQL_VERSION_PATCH=23
-MYSQL_VERSION_EXTRA=-25
+MYSQL_VERSION_PATCH=24
+MYSQL_VERSION_EXTRA=-26
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 18d3286249e7..d031922e278f 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -17,7 +17,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/client
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/mysys_ssl
- ${ZLIB_INCLUDE_DIR}
${LZ4_INCLUDE_DIR}
${SSL_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/libmysql
diff --git a/client/mysql.cc b/client/mysql.cc
index cb1b195daa5f..dd698ef94c8c 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1656,7 +1656,7 @@ static struct my_option my_long_options[] =
{"bind-address", 0, "IP address to bind to.",
(uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"binary-as-hex", 'b', "Print binary data as hex", &opt_binhex, &opt_binhex,
+ {"binary-as-hex", 0, "Print binary data as hex", &opt_binhex, &opt_binhex,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
diff --git a/client/mysqldump.c b/client/mysqldump.c
index b65abc3256bc..9a4f1decd07f 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1520,6 +1520,37 @@ static void restore_cs_variables(FILE *sql_file,
(const char *) delimiter);
}
+/*
+ This function will remove specific sql mode.
+
+ @param[in] sql_mode Original sql mode from where input mode needs to
+ be removed.
+ @param[in] replace_mode sql mode which needs to be removed from original
+ sql mode.
+ @param[in] replace_len length of sql mode which needs to be removed.
+
+ @retval 1 replace_mode is not present
+ 0 replace_mode is removed successfully
+*/
+static int remove_sql_mode(char* sql_mode, const char* replace_mode,
+ size_t replace_len) {
+ char *start = strstr(sql_mode, replace_mode);
+ /* nothing to replace */
+ if (!start)
+ return 1;
+ /* sql mode to replace is the only sql mode present or the last one */
+ if (strlen(start) == replace_len) {
+ if (start == sql_mode)
+ *start = 0;
+ else
+ start[-1] = 0;
+ }
+ else {
+ const char *next = start + replace_len + 1;
+ memmove(start, next, strlen(next) + 1);
+ }
+ return 0;
+}
static void switch_sql_mode(FILE *sql_file,
const char *delimiter,
@@ -2617,7 +2648,7 @@ static uint dump_events_for_db(char *db)
"The following dump may be incomplete.\n"
"--\n");
}
-
+ remove_sql_mode(row[1], C_STRING_WITH_LEN("NO_AUTO_CREATE_USER"));
switch_sql_mode(sql_file, delimiter, row[1]);
switch_time_zone(sql_file, delimiter, row[2]);
@@ -2852,7 +2883,7 @@ static uint dump_routines_for_db(char *db)
"--\n");
}
-
+ remove_sql_mode(row[1], C_STRING_WITH_LEN("NO_AUTO_CREATE_USER"));
switch_sql_mode(sql_file, ";", row[1]);
fprintf(sql_file,
@@ -4199,6 +4230,7 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
row[3], /* character_set_results */
row[4]); /* collation_connection */
+ remove_sql_mode(row[1], C_STRING_WITH_LEN("NO_AUTO_CREATE_USER"));
switch_sql_mode(sql_file, ";", row[1]);
if (opt_drop_trigger)
diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake
index f1498816d497..9d8b5d7f3ab3 100644
--- a/cmake/os/Windows.cmake
+++ b/cmake/os/Windows.cmake
@@ -1,4 +1,4 @@
-# Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -114,10 +114,11 @@ IF(MSVC)
SET("${flag}" "${${flag}} /EHsc")
ENDFOREACH()
- # Fix CMake's predefined huge stack size
FOREACH(type EXE SHARED MODULE)
- STRING(REGEX REPLACE "/STACK:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS "${CMAKE_${type}_LINKER_FLAGS}")
- STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO}")
+ SET(CMAKE_${type}_LINKER_FLAGS_DEBUG
+ "${CMAKE_${type}_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO")
+ SET(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO
+ "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
ENDFOREACH()
# Mark 32 bit executables large address aware so they can
diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake
index ad56c61670e8..df0a1c419fbf 100644
--- a/cmake/plugin.cmake
+++ b/cmake/plugin.cmake
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -64,7 +64,7 @@ MACRO(MYSQL_ADD_PLUGIN)
${CMAKE_SOURCE_DIR}/sql/auth
${CMAKE_SOURCE_DIR}/regex
${SSL_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIR})
+ )
LIST(GET ARG_DEFAULT_ARGS 0 plugin)
SET(SOURCES ${ARG_DEFAULT_ARGS})
diff --git a/cmake/sasl.cmake b/cmake/sasl.cmake
new file mode 100644
index 000000000000..ddb8dbef2f0c
--- /dev/null
+++ b/cmake/sasl.cmake
@@ -0,0 +1,62 @@
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
+#
+# 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, version 2.0, 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
+
+# cmake -DWITH_SASL=system|path
+# system is the default
+#
+# Sets SASL_LIBRARY. If not found, SASL_LIBRARY="".
+
+MACRO (FIND_SYSTEM_SASL)
+ FIND_LIBRARY(SASL_SYSTEM_LIBRARY NAMES "sasl2" "sasl")
+ IF (SASL_SYSTEM_LIBRARY)
+ SET(SYSTEM_SASL_FOUND 1)
+ SET(SASL_LIBRARY ${SASL_SYSTEM_LIBRARY})
+ MESSAGE(STATUS "SASL_LIBRARY ${SASL_LIBRARY}")
+ ENDIF()
+ENDMACRO()
+
+IF (NOT WITH_SASL)
+ SET(WITH_SASL "system" CACHE STRING "By default use system sasl library")
+ENDIF()
+
+MACRO (MYSQL_CHECK_SASL)
+ IF (NOT WITH_SASL OR WITH_SASL STREQUAL "system")
+ FIND_SYSTEM_SASL()
+ IF (NOT SYSTEM_SASL_FOUND)
+ MESSAGE(STATUS "Cannot find system sasl libraries.")
+ SET(SASL_LIBRARY "")
+ ENDIF()
+ ELSE()
+ FIND_LIBRARY(SASL_LIBRARY
+ NAMES "sasl2" "sasl" "libsasl"
+ PATHS ${WITH_SASL} ${WITH_SASL}/lib
+ NO_DEFAULT_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH)
+ IF (NOT SASL_LIBRARY)
+ MESSAGE(STATUS "Cannot find sasl libraries in ${WITH_SASL}.")
+ SET(SASL_LIBRARY "")
+ ELSE()
+ MESSAGE(STATUS "SASL_LIBRARY ${SASL_LIBRARY}")
+ ENDIF()
+ ENDIF()
+ENDMACRO()
diff --git a/cmake/tags.cmake b/cmake/tags.cmake
index 07c1411a1d65..fdbe61694a39 100644
--- a/cmake/tags.cmake
+++ b/cmake/tags.cmake
@@ -1,4 +1,4 @@
-# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -15,12 +15,29 @@
# Generate tag files
IF(UNIX)
- ADD_CUSTOM_TARGET (tags
- COMMAND support-files/build-tags
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- )
- ADD_CUSTOM_TARGET (ctags
- COMMAND ctags -R -f CTAGS
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- )
+ FIND_PROGRAM(CTAGS_EXECUTABLE ctags)
+ IF(NOT CTAGS_EXECUTABLE)
+ RETURN()
+ ENDIF()
+ EXEC_PROGRAM(${CTAGS_EXECUTABLE} ARGS --version OUTPUT_VARIABLE CTAGS_VERSION)
+
+ IF(CTAGS_VERSION MATCHES "Exuberant")
+ ADD_CUSTOM_TARGET(tags
+ COMMAND support-files/build-tags
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+ ADD_CUSTOM_TARGET(ctags
+ COMMAND support-files/build-tags ctags
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+ ELSE()
+ ADD_CUSTOM_TARGET (tags
+ COMMAND exit 1
+ COMMENT "Please install Exuberant Ctags"
+ )
+ ADD_CUSTOM_TARGET (ctags
+ COMMAND exit 1
+ COMMENT "Please install Exuberant Ctags"
+ )
+ ENDIF()
ENDIF()
diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake
index adbf62a14432..e97c7841c0d6 100644
--- a/cmake/zlib.cmake
+++ b/cmake/zlib.cmake
@@ -14,15 +14,11 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
MACRO (MYSQL_USE_BUNDLED_ZLIB)
+ SET(BUILD_BUNDLED_ZLIB 1)
SET(ZLIB_LIBRARY zlib CACHE INTERNAL "Bundled zlib library")
- SET(ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/zlib CACHE STRING "Will not be redefined by FindZLIB")
SET(ZLIB_FOUND TRUE)
SET(WITH_ZLIB "bundled" CACHE STRING "Use bundled zlib")
ADD_SUBDIRECTORY(zlib)
- GET_TARGET_PROPERTY(src zlib SOURCES)
- FOREACH(file ${src})
- SET(ZLIB_SOURCES ${ZLIB_SOURCES} ${CMAKE_SOURCE_DIR}/zlib/${file})
- ENDFOREACH()
ENDMACRO()
# MYSQL_CHECK_ZLIB_WITH_COMPRESS
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt
index 3adf988a219d..03f62e9bf4d2 100644
--- a/extra/CMakeLists.txt
+++ b/extra/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -15,7 +15,6 @@
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/include
-${ZLIB_INCLUDE_DIR}
${LZ4_INCLUDE_DIR}
# Following is for perror, in case NDB is compiled in.
${CMAKE_SOURCE_DIR}/storage/ndb/include
diff --git a/extra/protobuf/CMakeLists.txt b/extra/protobuf/CMakeLists.txt
index 7c7e97e32e51..593e23b0b3ec 100644
--- a/extra/protobuf/CMakeLists.txt
+++ b/extra/protobuf/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -71,7 +71,6 @@ ENDIF()
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/protobuf-2.6.1/src
- ${ZLIB_INCLUDE_DIR}
)
SET(PROTO_SRC_DIR
diff --git a/include/mysql/group_replication_priv.h b/include/mysql/group_replication_priv.h
index ed8ef3eb0980..384efe92e31e 100644
--- a/include/mysql/group_replication_priv.h
+++ b/include/mysql/group_replication_priv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -37,12 +37,9 @@
/**
- Server side initializations and cleanup.
+ Server side initializations.
*/
-int group_replication_init(const char* plugin_name);
-int group_replication_cleanup();
-int group_replication_start();
-int group_replication_stop();
+int group_replication_init();
/**
diff --git a/libbinlogevents/CMakeLists.txt b/libbinlogevents/CMakeLists.txt
index 44219c2ba407..3939a086b5ae 100644
--- a/libbinlogevents/CMakeLists.txt
+++ b/libbinlogevents/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -18,11 +18,7 @@ INCLUDE(configure.cmake)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libbinlogevents/include
- ${CMAKE_SOURCE_DIR}/libbinlogevents/export
- # ZLIB_INCLUDE_DIR points to ${CMAKE_SOURCE_DIR}/zlib,
- # when compiled with MySQL server version (< 5.7).
- # It is NULL otherwise.
- ${ZLIB_INCLUDE_DIR})
+ ${CMAKE_SOURCE_DIR}/libbinlogevents/export)
CONFIGURE_FILE(binlog_config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/include/binlog_config.h)
diff --git a/libbinlogstandalone/CMakeLists.txt b/libbinlogstandalone/CMakeLists.txt
index 3023fc807692..1743b8897cdb 100644
--- a/libbinlogstandalone/CMakeLists.txt
+++ b/libbinlogstandalone/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -27,18 +27,11 @@ ADD_DEFINITIONS(-DSTANDALONE_BINLOG)
# INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
#ENDIF()
-FIND_PACKAGE(ZLIB REQUIRED)
-
-
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libbinlogevents/include
${CMAKE_CURRENT_BINARY_DIR}/../libbinlogevents/include
${CMAKE_SOURCE_DIR}/libbinlogevents/export
- ${CMAKE_CURRENT_BINARY_DIR}/libbinlogevents/export
- # ZLIB_INCLUDE_DIR points to ${CMAKE_SOURCE_DIR}/zlib,
- # when compiled with MySQL server version (< 5.7).
- # It is NULL otherwise.
- ${ZLIB_INCLUDE_DIR})
+ ${CMAKE_CURRENT_BINARY_DIR}/libbinlogevents/export)
ADD_SUBDIRECTORY(src)
diff --git a/libbinlogstandalone/src/CMakeLists.txt b/libbinlogstandalone/src/CMakeLists.txt
index 18154e00915c..27e1f6a72a81 100644
--- a/libbinlogstandalone/src/CMakeLists.txt
+++ b/libbinlogstandalone/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -27,7 +27,7 @@ SET (REPLICATION_SOURCES
# Configure for building static library
ADD_LIBRARY(binlogstandalone_static STATIC ${REPLICATION_SOURCES})
-TARGET_LINK_LIBRARIES(binlogstandalone_static ${ZLIB_LIBRARIES})
+TARGET_LINK_LIBRARIES(binlogstandalone_static ${ZLIB_LIBRARY})
SET_TARGET_PROPERTIES(binlogstandalone_static PROPERTIES
OUTPUT_NAME "binlogstandalone")
@@ -38,7 +38,7 @@ SET_TARGET_PROPERTIES(binlogstandalone_static PROPERTIES
IF (NOT DISABLE_SHARED)
# Configure for building shared library
ADD_LIBRARY(binlogstandalone_shared SHARED ${REPLICATION_SOURCES})
- TARGET_LINK_LIBRARIES(binlogstandalone_shared ${ZLIB_LIBRARIES})
+ TARGET_LINK_LIBRARIES(binlogstandalone_shared ${ZLIB_LIBRARY})
SET_TARGET_PROPERTIES(binlogstandalone_shared
PROPERTIES OUTPUT_NAME "binlogstandalone")
SET_TARGET_PROPERTIES(binlogstandalone_shared
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index ea35afd9ec04..ba26a1012c45 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -20,8 +20,7 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/strings
${SSL_INCLUDE_DIRS}
- ${SSL_INTERNAL_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIR})
+ ${SSL_INTERNAL_INCLUDE_DIRS})
ADD_DEFINITIONS(${SSL_DEFINES})
SET(CLIENT_API_FUNCTIONS
diff --git a/libmysql/authentication_ldap/CMakeLists.txt b/libmysql/authentication_ldap/CMakeLists.txt
index 40ad785b4383..7499ea97783c 100644
--- a/libmysql/authentication_ldap/CMakeLists.txt
+++ b/libmysql/authentication_ldap/CMakeLists.txt
@@ -1,9 +1,9 @@
-# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
-#
+# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+#
# 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
@@ -19,14 +19,6 @@
INCLUDE(CheckIncludeFiles)
-IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- INCLUDE_DIRECTORIES(SYSTEM /usr/local/include)
- LIST(APPEND CMAKE_REQUIRED_INCLUDES "/usr/local/include")
-ENDIF()
-
-CHECK_INCLUDE_FILES(sasl/sasl.h HAVE_SASL_H)
-CHECK_INCLUDE_FILES(lber.h HAVE_LBER_H)
-
# If cmake was invoked with -DWITH_AUTHENTICATION_LDAP=1
# then fail if we are unable to build the LDAP plugin.
MACRO(CROAK_AND_RETURN)
@@ -38,29 +30,111 @@ MACRO(CROAK_AND_RETURN)
ENDIF()
ENDMACRO()
-IF(HAVE_SASL_H)
- SET(CMAKE_EXTRA_INCLUDE_FILES sasl/sasl.h)
-ELSE()
- CROAK_AND_RETURN("Required SASL library is missing.")
-ENDIF()
-IF(HAVE_LBER_H)
- SET(CMAKE_EXTRA_INCLUDE_FILES lber.h)
-ELSE()
- CROAK_AND_RETURN("Required LBER library is missing.")
-ENDIF()
+IF(NOT WIN32)
+ IF(DEFINED WITH_SASL)
+ MESSAGE(STATUS ${ARGV} "Currently LDAP SASL client authentication plug-in is build with only system installed cyrus SASL library.")
+ ENDIF()
+
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ INCLUDE_DIRECTORIES(SYSTEM /usr/local/include)
+ LIST(APPEND CMAKE_REQUIRED_INCLUDES "/usr/local/include")
+ ENDIF()
+
+ CHECK_INCLUDE_FILES(sasl/sasl.h HAVE_SASL_H)
+ CHECK_INCLUDE_FILES(lber.h HAVE_LBER_H)
-# LDAP authentication SASL client will not build on windows, as windows don't have cyrus sasl.
-# IF someone like can build the cyrus sasl library on windows and build LDAP authentication sasl client as well.
-IF (CMAKE_SYSTEM_NAME MATCHES "SunOS")
- SET(SASL_LIBRARY "sasl")
-ELSEIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- SET(SASL_LIBRARY "-L/usr/local/lib -R/usr/local/lib -lsasl2")
+ IF(HAVE_SASL_H)
+ SET(CMAKE_EXTRA_INCLUDE_FILES sasl/sasl.h)
+ ELSE()
+ CROAK_AND_RETURN("Required SASL library is missing.")
+ ENDIF()
+ IF(HAVE_LBER_H)
+ SET(CMAKE_EXTRA_INCLUDE_FILES lber.h)
+ ELSE()
+ CROAK_AND_RETURN("Required LBER library is missing.")
+ ENDIF()
ELSE()
- SET(SASL_LIBRARY "sasl2")
-ENDIF ()
+ # There is no system installed SASL library on Windows
+ SET(WITH_SASL "" CACHE PATH "Location of the SASL install")
+ IF(NOT WITH_SASL OR WITH_SASL STREQUAL "system")
+ # This plug-in is only compulsory for the enterprise MySQL.
+ # For MySQL community/Dev's user can build without this plug-in.
+ MESSAGE(STATUS ${ARGV} " You need to set WITH_SASL path to build LDAP SASL client authentication plugin.")
+ RETURN()
+ ENDIF()
+
+ # Use forward slashes from CMake code
+ FILE(TO_CMAKE_PATH "${WITH_SASL}" SASL_ROOT_DIR)
+
+ FIND_PATH(SASL_INCLUDE_DIR
+ NAMES sasl/sasl.h
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ PATHS ${SASL_ROOT_DIR}/include
+ )
+
+ FIND_FILE(SASL_LIBRARY_DLL
+ NAMES libsasl.dll
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ PATHS ${SASL_ROOT_DIR}/lib
+ )
+
+ FIND_FILE(SASL_SCRAM_PLUGIN
+ NAMES saslSCRAM.dll
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ PATHS ${SASL_ROOT_DIR}/lib
+ )
+
+ IF(SASL_INCLUDE_DIR AND
+ SASL_LIBRARY AND
+ SASL_LIBRARY_DLL AND
+ SASL_SCRAM_PLUGIN)
+ SET(SASL_FOUND TRUE)
+ ELSE()
+ SET(SASL_FOUND FALSE)
+ ENDIF()
+
+ INCLUDE_DIRECTORIES(${SASL_INCLUDE_DIR})
+
+ MESSAGE(STATUS "SASL_INCLUDE_DIR = ${SASL_INCLUDE_DIR}")
+ MESSAGE(STATUS "SASL_LIBRARY_DLL = ${SASL_LIBRARY_DLL}")
+ MESSAGE(STATUS "SASL_SCRAM_PLUGIN = ${SASL_SCRAM_PLUGIN}")
+
+ENDIF()
+
+MESSAGE(STATUS "SASL_LIBRARY = ${SASL_LIBRARY}")
MYSQL_ADD_PLUGIN(authentication_ldap_sasl_client
auth_ldap_sasl_client.cc log_client.cc
LINK_LIBRARIES ${SASL_LIBRARY}
CLIENT_ONLY MODULE_ONLY
MODULE_OUTPUT_NAME "authentication_ldap_sasl_client")
+
+IF(WIN32)
+ GET_FILENAME_COMPONENT(SASL_DLL_NAME ${SASL_LIBRARY_DLL} NAME)
+ GET_FILENAME_COMPONENT(SASL_SCRAM_PLUGIN_NAME "${SASL_SCRAM_PLUGIN}" NAME)
+
+ # Note that "libsasl.dll" and "saslSCRAM.dll" go into the "bin" directory where
+ # "mysql.exe" and other client executables are located.
+ INSTALL(FILES "${SASL_LIBRARY_DLL}"
+ DESTINATION ${INSTALL_BINDIR}
+ COMPONENT SharedLibraries)
+ INSTALL(FILES "${SASL_SCRAM_PLUGIN}"
+ DESTINATION ${INSTALL_BINDIR}
+ COMPONENT SharedLibraries)
+
+ # To run client executables that load the plug-in from the build tree we need
+ # to copy the SASL library DLL and SASL SCRAM library DLL to the same directory as the client executables.
+ ADD_CUSTOM_COMMAND(TARGET authentication_ldap_sasl_client POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${SASL_LIBRARY_DLL}"
+ "${CMAKE_BINARY_DIR}/client/${CMAKE_CFG_INTDIR}/${SASL_DLL_NAME}"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${SASL_SCRAM_PLUGIN}"
+ "${CMAKE_BINARY_DIR}/client/${CMAKE_CFG_INTDIR}/${SASL_SCRAM_PLUGIN_NAME}"
+ )
+ ADD_DEPENDENCIES(authentication_ldap_sasl_client mysqltest)
+
+ENDIF()
diff --git a/libmysql/authentication_ldap/auth_ldap_sasl_client.cc b/libmysql/authentication_ldap/auth_ldap_sasl_client.cc
index 613108bdead7..62a3308c7f4f 100644
--- a/libmysql/authentication_ldap/auth_ldap_sasl_client.cc
+++ b/libmysql/authentication_ldap/auth_ldap_sasl_client.cc
@@ -128,6 +128,36 @@ int Sasl_client::initilize()
{
std::stringstream log_stream;
int rc_sasl= SASL_FAIL;
+#ifdef _WIN32
+ char sasl_plugin_dir[MAX_PATH]= "";
+ int ret_executable_path= 0;
+ /**
+ Getting the current executable path, SASL SCRAM dll will be copied in executable path.
+ Using/Setting the path from cmake file may not work as during installation SASL SCRAM DLL may be
+ copied to any path based on installable path.
+ */
+ ret_executable_path= GetModuleFileName(NULL, sasl_plugin_dir, sizeof(sasl_plugin_dir));
+ if ((ret_executable_path == 0) || (ret_executable_path == sizeof(sasl_plugin_dir)))
+ {
+ log_error("sasl client initilize: failed to find executable path or buffer size for path is too small.");
+ goto EXIT;
+ }
+ char *pos= strrchr(sasl_plugin_dir, '\\');
+ if (pos != NULL)
+ {
+ *pos = '\0';
+ }
+ /**
+ Sasl SCRAM dll default search path is C:\CMU2,
+ This is the reason we have copied in the executable folder and setting the same
+ from the code.
+ */
+ sasl_set_path(SASL_PATH_TYPE_PLUGIN, sasl_plugin_dir);
+ log_stream << "Sasl_client::initilize sasl scrum plug-in path : "
+ << sasl_plugin_dir;
+ log_dbg(log_stream.str());
+ log_stream.clear();
+#endif
strncpy(m_service_name, SASL_SERVICE_NAME, sizeof(m_service_name)-1);
m_service_name[sizeof(m_service_name)-1]= '\0';
/** Initialize client-side of SASL. */
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 978fd49ffc2c..fd3529f15176 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -27,7 +27,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_BINARY_DIR}/libmysqld
${CMAKE_BINARY_DIR}/sql
${CMAKE_SOURCE_DIR}/regex
- ${ZLIB_INCLUDE_DIR}
${SSL_INCLUDE_DIRS}
${SSL_INTERNAL_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/sql/backup
diff --git a/man/comp_err.1 b/man/comp_err.1
index 70a3f7b45b85..3511784075f9 100644
--- a/man/comp_err.1
+++ b/man/comp_err.1
@@ -2,12 +2,12 @@
.\" Title: \fBcomp_err\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBCOMP_ERR\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBCOMP_ERR\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -253,7 +253,7 @@ You should have received a copy of the GNU General Public License along with the
.IP " 1." 4
MySQL Internals Manual
.RS 4
-\%http://dev.mysql.com/doc/internals/en
+\%https://dev.mysql.com/doc/internals/en
.RE
.SH "SEE ALSO"
For more information, please refer to the MySQL Reference Manual,
diff --git a/man/innochecksum.1 b/man/innochecksum.1
index 44fc28b8b09a..faf4cc4bccf0 100644
--- a/man/innochecksum.1
+++ b/man/innochecksum.1
@@ -2,12 +2,12 @@
.\" Title: \fBinnochecksum\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBINNOCHECKSUM\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBINNOCHECKSUM\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -41,15 +41,7 @@ files\&. This tool reads an
InnoDB
tablespace file, calculates the checksum for each page, compares the calculated checksum to the stored checksum, and reports mismatches, which indicate damaged pages\&. It was originally developed to speed up verifying the integrity of tablespace files after power outages but can also be used after file copies\&. Because checksum mismatches cause
InnoDB
-to deliberately shut down a running server, it may be preferable to use this tool rather than waiting for an in\-production server to encounter the damaged pages\&. As of MySQL 5\&.7\&.2,
-\fBinnochecksum\fR
-supports files greater than 2GB in size\&. Previously,
-\fBinnochecksum\fR
-only supported files up to 2GB in size\&.
-.PP
-As of MySQL 5\&.7\&.2,
-\fBinnochecksum\fR
-supports tablespaces that contain compressed pages\&.
+to deliberately shut down a running server, it may be preferable to use this tool rather than waiting for an in\-production server to encounter the damaged pages\&.
.PP
\fBinnochecksum\fR
cannot be used on tablespace files that the server already has open\&. For such files, you should use
diff --git a/man/lz4_decompress.1 b/man/lz4_decompress.1
index 0d8d42cc9ef5..e7f8288e4731 100644
--- a/man/lz4_decompress.1
+++ b/man/lz4_decompress.1
@@ -2,12 +2,12 @@
.\" Title: \fBlz4_decompress\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBLZ4_DECOMPRESS\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBLZ4_DECOMPRESS\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/my_print_defaults.1 b/man/my_print_defaults.1
index be474899f6e4..5ba34a9c920d 100644
--- a/man/my_print_defaults.1
+++ b/man/my_print_defaults.1
@@ -2,12 +2,12 @@
.\" Title: \fBmy_print_defaults\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMY_PRINT_DEFAULTS\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMY_PRINT_DEFAULTS\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/myisam_ftdump.1 b/man/myisam_ftdump.1
index 5d45fc0c7591..a3e4aa19ea3d 100644
--- a/man/myisam_ftdump.1
+++ b/man/myisam_ftdump.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisam_ftdump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYISAM_FTDUMP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYISAM_FTDUMP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/myisamchk.1 b/man/myisamchk.1
index 26a48c885e74..06979ebf4556 100644
--- a/man/myisamchk.1
+++ b/man/myisamchk.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisamchk\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYISAMCHK\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYISAMCHK\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/myisamlog.1 b/man/myisamlog.1
index 4dcf596e5360..76fd6dfd1621 100644
--- a/man/myisamlog.1
+++ b/man/myisamlog.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisamlog\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYISAMLOG\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYISAMLOG\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/myisampack.1 b/man/myisampack.1
index 7d63beab0acc..a1a509baea10 100644
--- a/man/myisampack.1
+++ b/man/myisampack.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisampack\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYISAMPACK\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYISAMPACK\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysql.1 b/man/mysql.1
index 7b97029b7644..d88a45e889f7 100644
--- a/man/mysql.1
+++ b/man/mysql.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -59,7 +59,7 @@ mysql_store_result()\&.
.br
.PP
Alternatively, MySQL Shell offers access to the X DevAPI\&. For details, see
-Chapter\ \&18, MySQL Shell User Guide\&.
+\m[blue]\fBMySQL Shell 8\&.0 (part of MySQL 8\&.0)\fR\m[]\&\s-2\u[1]\d\s+2\&.
.sp .5v
.RE
.PP
@@ -228,8 +228,7 @@ option\&.
.sp -1
.IP \(bu 2.3
.\}
-\fB\-\-binary\-as\-hex\fR,
-\fB\-b\fR
+\fB\-\-binary\-as\-hex\fR
.sp
When this option is given,
\fBmysql\fR
@@ -1218,14 +1217,20 @@ If the connection to the server is lost, automatically try to reconnect\&. A sin
\fB\-\-i\-am\-a\-dummy\fR,
\fB\-U\fR
.sp
-Permit only those
+If this option is enabled,
UPDATE
and
DELETE
-statements that specify which rows to modify by using key values\&. If you have set this option in an option file, you can override it by using
-\fB\-\-safe\-updates\fR
-on the command line\&. See
-the section called \(lqMYSQL TIPS\(rq, for more information about this option\&.
+statements that do not use a key in the
+WHERE
+clause or a
+LIMIT
+clause produce an error\&. In addition, restrictions are placed on
+SELECT
+statements that produce (or are estimated to produce) very large result sets\&. If you have set this option in an option file, you can use
+\fB\-\-skip\-safe\-updates\fR
+on the command line to override it\&. For more information about this option, see
+the section called \(lqUsing Safe\-Updates Mode (\-\-safe\-updates)\(rq\&.
.RE
.sp
.RS 4
@@ -2198,6 +2203,8 @@ Read the named file and executes the statements contained therein\&. On Windows,
/
or
\e\e\&.
+.sp
+Quote characters are taken as part of the file name itself\&. For best results, the name should not include space characters\&.
.RE
.sp
.RS 4
@@ -2211,9 +2218,9 @@ or
status,
\es
.sp
-Provide status information about the connection and the server you are using\&. If you are running in
+Provide status information about the connection and the server you are using\&. If you are running with
\fB\-\-safe\-updates\fR
-mode,
+enabled,
status
also prints the values for the
\fBmysql\fR
@@ -2827,6 +2834,39 @@ file\&.
.RE
.PP
The following discussion describes characteristics that apply to all logging types and provides information specific to each logging type\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+How Logging Occurs
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Controlling the History File
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+syslog Logging Characteristics
+.RE
How Logging Occurs.PP
For each enabled logging destination, statement logging occurs as follows:
.sp
@@ -3179,7 +3219,7 @@ command,
uses it as a search string to access server\-side help from the contents of the MySQL Reference Manual\&. The proper operation of this command requires that the help tables in the
mysql
database be initialized with help topic information (see
-Section\ \&5.1.13, \(lqServer-Side Help\(rq)\&.
+Section\ \&5.1.14, \(lqServer-Side Help\(rq)\&.
.PP
If there is no match for the search string, the search fails:
.sp
@@ -3528,7 +3568,8 @@ with the
(or
utf8mb4) option\&. This option is necessary because
utf16le
-is not supported as a connection character set\&.
+is one of the character sets that cannot be used as the client character set\&. See
+the section called \(lqImpermissible Client Character Sets\(rq\&.
.RE
.PP
With those changes,
@@ -3590,23 +3631,33 @@ Monty
.if n \{\
.RE
.\}
-.SS "Using the \-\-safe\-updates Option"
+.SS "Using Safe\-Updates Mode (\-\-safe\-updates)"
.PP
For beginners, a useful startup option is
\fB\-\-safe\-updates\fR
(or
-\fB\-\-i\-am\-a\-dummy\fR, which has the same effect)\&. It is helpful for cases when you might have issued a
-DELETE FROM \fItbl_name\fR
+\fB\-\-i\-am\-a\-dummy\fR, which has the same effect)\&. Safe\-updates mode is helpful for cases when you might have issued an
+UPDATE
+or
+DELETE
statement but forgotten the
WHERE
-clause\&. Normally, such a statement deletes all rows from the table\&. With
-\fB\-\-safe\-updates\fR, you can delete rows only by specifying the key values that identify them\&. This helps prevent accidents\&.
+clause indicating which rows to modify\&. Normally, such statements update or delete all rows in the table\&. With
+\fB\-\-safe\-updates\fR, you can modify rows only by specifying the key values that identify them, or a
+LIMIT
+clause, or both\&. This helps prevent accidents\&. Safe\-updates mode also restricts
+SELECT
+statements that produce (or are estimated to produce) very large result sets\&.
.PP
-When you use the
+The
\fB\-\-safe\-updates\fR
-option,
+option causes
\fBmysql\fR
-issues the following statement when it connects to the MySQL server:
+to execute the following statement when it connects to the MySQL server, to set the session values of the
+sql_safe_updates,
+sql_select_limit, and
+max_join_size
+system variables:
.sp
.if n \{\
.RS 4
@@ -3618,12 +3669,9 @@ SET sql_safe_updates=1, sql_select_limit=1000, max_join_size=1000000;
.RE
.\}
.PP
-See
-Section\ \&5.1.7, \(lqServer System Variables\(rq\&.
-.PP
The
SET
-statement has the following effects:
+statement affects statement processing as follows:
.sp
.RS 4
.ie n \{\
@@ -3633,15 +3681,17 @@ statement has the following effects:
.sp -1
.IP \(bu 2.3
.\}
-You are not permitted to execute an
+Enabling
+sql_safe_updates
+causes
UPDATE
-or
+and
DELETE
-statement unless you specify a key constraint in the
+statements to produce an error if they do not specify a key constraint in the
WHERE
-clause or provide a
+clause, or provide a
LIMIT
-clause (or both)\&. For example:
+clause, or both\&. For example:
.sp
.if n \{\
.RS 4
@@ -3663,9 +3713,11 @@ UPDATE \fItbl_name\fR SET \fInot_key_column\fR=\fIval\fR LIMIT 1;
.sp -1
.IP \(bu 2.3
.\}
-The server limits all large
+Setting
+sql_select_limit
+to 1,000 causes the server to limit all
SELECT
-results to 1,000 rows unless the statement includes a
+result sets to 1,000 rows unless the statement includes a
LIMIT
clause\&.
.RE
@@ -3678,26 +3730,117 @@ clause\&.
.sp -1
.IP \(bu 2.3
.\}
-The server aborts multiple\-table
+Setting
+max_join_size
+to 1,000,000 causes multiple\-table
SELECT
-statements that probably need to examine more than 1,000,000 row combinations\&.
+statements to produce an error if the server estimates it must examine more than 1,000,000 row combinations\&.
.RE
.PP
-To specify limits different from 1,000 and 1,000,000, you can override the defaults by using the
+To specify result set limits different from 1,000 and 1,000,000, you can override the defaults by using the
\fB\-\-select_limit\fR
and
\fB\-\-max_join_size\fR
-options:
+options when you invoke
+\fBmysql\fR:
.sp
.if n \{\
.RS 4
.\}
.nf
-shell> \fBmysql \-\-safe\-updates \-\-select_limit=500 \-\-max_join_size=10000\fR
+mysql \-\-safe\-updates \-\-select_limit=500 \-\-max_join_size=10000
.fi
.if n \{\
.RE
.\}
+.PP
+It is possible for
+UPDATE
+and
+DELETE
+statements to produce an error in safe\-updates mode even with a key specified in the
+WHERE
+clause, if the optimizer decides not to use the index on the key column:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Range access on the index cannot be used if memory usage exceeds that permitted by the
+range_optimizer_max_mem_size
+system variable\&. The optimizer then falls back to a table scan\&. See
+the section called \(lqLimiting Memory Use for Range Optimization\(rq\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If key comparisons require type conversion, the index may not be used (see
+Section\ \&8.3.1, \(lqHow MySQL Uses Indexes\(rq)\&. Suppose that an indexed string column
+c1
+is compared to a numeric value using
+WHERE c1 = 2222\&. For such comparisons, the string value is converted to a number and the operands are compared numerically (see
+Section\ \&12.2, \(lqType Conversion in Expression Evaluation\(rq), preventing use of the index\&. If safe\-updates mode is enabled, an error occurs\&.
+.RE
+.PP
+As of MySQL 5\&.7\&.25, safe\-updates mode includes these behaviors:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+EXPLAIN
+with
+UPDATE
+and
+DELETE
+statements does not produce safe\-updates errors\&. This enables use of
+EXPLAIN
+plus
+SHOW WARNINGS
+to see why an index is not used, which can be helpful in cases such as when a
+range_optimizer_max_mem_size
+violation or type conversion occurs and the optimizer does not use an index even though a key column was specified in the
+WHERE
+clause\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+When a safe\-updates error occurs, the error message includes the first diagnostic that was produced, to provide information about the reason for failure\&. For example, the message may indicate that the
+range_optimizer_max_mem_size
+value was exceeded or type conversion occurred, either of which can preclude use of an index\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+For multiple\-table deletes and updates, an error is produced with safe updates enabled only if any target table uses a table scan\&.
+.RE
.SS "Disabling mysql Auto\-Reconnect"
.PP
If the
@@ -3753,6 +3896,12 @@ This documentation is distributed in the hope that it will be useful, but WITHOU
.PP
You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see http://www.gnu.org/licenses/.
.sp
+.SH "NOTES"
+.IP " 1." 4
+MySQL Shell 8.0 (part of MySQL 8.0)
+.RS 4
+\%http://dev.mysql.com/doc/mysql-shell/8.0/en/
+.RE
.SH "SEE ALSO"
For more information, please refer to the MySQL Reference Manual,
which may already be installed locally and which is also available
diff --git a/man/mysql.server.1 b/man/mysql.server.1
index 3983e624eed8..b5f02b3725cd 100644
--- a/man/mysql.server.1
+++ b/man/mysql.server.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql.server\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL\&.SERVER\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL\&.SERVER\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -312,28 +312,28 @@ basedir
T}:T{
Path to MySQL installation directory
T}:T{
-directory name
+Directory name
T}
T{
datadir
T}:T{
Path to MySQL data directory
T}:T{
-directory name
+Directory name
T}
T{
pid-file
T}:T{
File in which server should write its process ID
T}:T{
-file name
+File name
T}
T{
service-startup-timeout
T}:T{
How long to wait for server startup
T}:T{
-integer
+Integer
T}
.TE
.sp 1
diff --git a/man/mysql_config.1 b/man/mysql_config.1
index 3f576af32c20..b1c0bea19014 100644
--- a/man/mysql_config.1
+++ b/man/mysql_config.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_config\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_CONFIG\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_CONFIG\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysql_config_editor.1 b/man/mysql_config_editor.1
index d4ea4062d383..de1f35e60e9c 100644
--- a/man/mysql_config_editor.1
+++ b/man/mysql_config_editor.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_config_editor\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_CONFIG_EDITOR\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_CONFIG_EDITOR\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -36,12 +36,12 @@ mysql_config_editor \- configure authentication information for connecting to My
.PP
The
\fBmysql_config_editor\fR
-utility enables you to store authentication credentials in an encrypted login path file named
+utility enables you to store authentication credentials in an obfuscated login path file named
\&.mylogin\&.cnf\&. The file location is the
%APPDATA%\eMySQL
directory on Windows and the current user\*(Aqs home directory on non\-Windows systems\&. The file can be read later by MySQL client programs to obtain authentication credentials for connecting to MySQL Server\&.
.PP
-The unencrypted format of the
+The unobfuscated format of the
\&.mylogin\&.cnf
login path file consists of option groups, similar to other option files\&. Each option group in
\&.mylogin\&.cnf
@@ -53,7 +53,7 @@ which is a group that permits only certain options:
\fBpassword\fR,
\fBport\fR
and
-\fBsocket\fR\&. Think of a login path option group as a set of options that specify which MySQL server to connect to and which account to authenticate as\&. Here is an unencrypted example:
+\fBsocket\fR\&. Think of a login path option group as a set of options that specify which MySQL server to connect to and which account to authenticate as\&. Here is an unobfuscated example:
.sp
.if n \{\
.RS 4
@@ -185,22 +185,22 @@ is present\&.
.RE
.PP
\fBmysql_config_editor\fR
-encrypts the
+obfuscates the
\&.mylogin\&.cnf
-file so it cannot be read as cleartext, and its contents when decrypted by client programs are used only in memory\&. In this way, passwords can be stored in a file in non\-cleartext format and used later without ever needing to be exposed on the command line or in an environment variable\&.
+file so it cannot be read as cleartext, and its contents when unobfuscated by client programs are used only in memory\&. In this way, passwords can be stored in a file in non\-cleartext format and used later without ever needing to be exposed on the command line or in an environment variable\&.
\fBmysql_config_editor\fR
provides a
print
command for displaying the login path file contents, but even in this case, password values are masked so as never to appear in a way that other users can see them\&.
.PP
-The encryption used by
+The obfuscation used by
\fBmysql_config_editor\fR
prevents passwords from appearing in
\&.mylogin\&.cnf
-as cleartext and provides a measure of security by preventing inadvertent password exposure\&. For example, if you display a regular unencrypted
+as cleartext and provides a measure of security by preventing inadvertent password exposure\&. For example, if you display a regular unobfuscated
my\&.cnf
option file on the screen, any passwords it contains are visible for anyone to see\&. With
-\&.mylogin\&.cnf, that is not true\&. But the encryption used will not deter a determined attacker and you should not consider it unbreakable\&. A user who can gain system administration privileges on your machine to access your files could decrypt the
+\&.mylogin\&.cnf, that is not true\&. But the obfuscation used will not deter a determined attacker and you should not consider it unbreakable\&. A user who can gain system administration privileges on your machine to access your files could unobfuscate the
\&.mylogin\&.cnf
file with some effort\&.
.PP
@@ -629,7 +629,7 @@ shell> \fBmysql_config_editor \fR\fB\fIcommand\fR\fR\fB \-\-help\fR
.\}
print [\fIoptions\fR]
.sp
-Print the contents of the login path file in unencrypted form, with the exception that passwords are displayed as
+Print the contents of the login path file in unobfuscated form, with the exception that passwords are displayed as
*****\&.
.sp
The default login path name is
@@ -823,7 +823,7 @@ Remove the password from the login path\&.
\fB\-\-port\fR,
\fB\-P\fR
.sp
-Remove the TCP/IP port number from the login path\&. This option was added in MySQL 5\&.7\&.1\&.
+Remove the TCP/IP port number from the login path\&.
.RE
.sp
.RS 4
@@ -837,7 +837,7 @@ Remove the TCP/IP port number from the login path\&. This option was added in My
\fB\-\-socket\fR,
\fB\-S\fR
.sp
-Remove the Unix socket file name from the login path\&. This option was added in MySQL 5\&.7\&.1\&.
+Remove the Unix socket file name from the login path\&.
.RE
.sp
.RS 4
@@ -1025,7 +1025,7 @@ password =
\fB\-\-port=\fR\fB\fIport_num\fR\fR,
\fB\-P \fR\fB\fIport_num\fR\fR
.sp
-The TCP/IP port number to write to the login path\&. This option was added in MySQL 5\&.7\&.1\&.
+The TCP/IP port number to write to the login path\&.
.RE
.sp
.RS 4
@@ -1039,7 +1039,7 @@ The TCP/IP port number to write to the login path\&. This option was added in My
\fB\-\-socket=\fR\fB\fIfile_name\fR\fR,
\fB\-S \fR\fB\fIfile_name\fR\fR
.sp
-The Unix socket file name to write to the login path\&. This option was added in MySQL 5\&.7\&.1\&.
+The Unix socket file name to write to the login path\&.
.RE
.sp
.RS 4
diff --git a/man/mysql_install_db.1 b/man/mysql_install_db.1
index 7513c4dc26c1..b6e4ce4ea091 100644
--- a/man/mysql_install_db.1
+++ b/man/mysql_install_db.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_install_db\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_INSTALL_DB\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_INSTALL_DB\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysql_plugin.1 b/man/mysql_plugin.1
index ff66554e8be4..13d668371e9e 100644
--- a/man/mysql_plugin.1
+++ b/man/mysql_plugin.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_plugin\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_PLUGIN\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_PLUGIN\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysql_secure_installation.1 b/man/mysql_secure_installation.1
index 18cf6d4665cb..3a66ec197b57 100644
--- a/man/mysql_secure_installation.1
+++ b/man/mysql_secure_installation.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_secure_installation\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_SECURE_INSTALLATION\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_SECURE_INSTALLATION\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysql_ssl_rsa_setup.1 b/man/mysql_ssl_rsa_setup.1
index 299d5baac3f7..bd3dcd6b0946 100644
--- a/man/mysql_ssl_rsa_setup.1
+++ b/man/mysql_ssl_rsa_setup.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_ssl_rsa_setup\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_SSL_RSA_SETUP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_SSL_RSA_SETUP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -403,7 +403,7 @@ should check for default SSL and RSA files and in which it should create files i
.\}
\fB\-\-suffix=\fR\fB\fIstr\fR\fR
.sp
-The suffix for the Common Name attribute in X509 certificates\&. The suffix value is limited to 17 characters\&. The default is based on the MySQL version number\&.
+The suffix for the Common Name attribute in X\&.509 certificates\&. The suffix value is limited to 17 characters\&. The default is based on the MySQL version number\&.
.RE
.sp
.RS 4
diff --git a/man/mysql_tzinfo_to_sql.1 b/man/mysql_tzinfo_to_sql.1
index 622b06f07fba..6c33b7d04c2e 100644
--- a/man/mysql_tzinfo_to_sql.1
+++ b/man/mysql_tzinfo_to_sql.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_tzinfo_to_sql\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_TZINFO_TO_SQL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_TZINFO_TO_SQL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1
index 730b29c2ed0f..8f9cc44d1aca 100644
--- a/man/mysql_upgrade.1
+++ b/man/mysql_upgrade.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_upgrade\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQL_UPGRADE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQL_UPGRADE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -120,7 +120,7 @@ If you upgrade to MySQL 5\&.7\&.2 or later from a version older than 5\&.7\&.2,
mysql\&.user
table requires a special sequence of steps to perform an upgrade using
\fBmysql_upgrade\fR\&. For details, see
-Section\ \&2.11.1.2, \(lqChanges Affecting Upgrades to MySQL 5.7\(rq\&.
+Section\ \&2.11.1.3, \(lqChanges in MySQL 5.7\(rq\&.
.sp .5v
.RE
.if n \{\
@@ -136,7 +136,7 @@ Section\ \&2.11.1.2, \(lqChanges Affecting Upgrades to MySQL 5.7\(rq\&.
.ps -1
.br
.PP
-On Windows Server 2008, Vista, and newer, you must run
+On Windows, you must run
\fBmysql_upgrade\fR
with administrator privileges\&. You can do this by running a Command Prompt as Administrator and running the command\&. Failure to do so may result in the upgrade failing to execute correctly\&.
.sp .5v
@@ -200,6 +200,46 @@ shell> \fBmysql_upgrade \-\-protocol=tcp \-P 3308 [\fR\fB\fIother_options\fR\fR\
For local host connections on Unix, the
\fB\-\-protocol=tcp\fR
option forces a connection using TCP/IP rather than the Unix socket file\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+If you run the server with the
+disabled_storage_engines
+system variable set to disable certain storage engines (for example,
+MyISAM),
+\fBmysql_upgrade\fR
+might fail with an error like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+mysql_upgrade: [ERROR] 3161: Storage engine MyISAM is disabled
+(Table creation is disallowed)\&.
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To handle this, restart the server with
+disabled_storage_engines
+disabled\&. Then you should be able to run
+\fBmysql_upgrade\fR
+successfully\&. After that, restart the server with
+disabled_storage_engines
+set to its original value\&.
+.sp .5v
+.RE
.PP
\fBmysql_upgrade\fR
processes all tables in all databases, which might take a long time to complete\&. Each table is locked and therefore unavailable to other sessions while it is being processed\&. Check and repair operations can be time\-consuming, particularly for large tables\&.
@@ -247,7 +287,7 @@ Section\ \&6.5.1.3, \(lqMigrating Away from Pre-4.1 Password Hashing and the mys
.PP
\fBmysql_upgrade\fR
does not upgrade the contents of the help tables\&. For upgrade instructions, see
-Section\ \&5.1.13, \(lqServer-Side Help\(rq\&.
+Section\ \&5.1.14, \(lqServer-Side Help\(rq\&.
.PP
As of MySQL 5\&.7\&.7, unless invoked with the
\fB\-\-skip\-sys\-schema\fR
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
index c83f18562740..f8c7a0628556 100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqladmin\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLADMIN\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLADMIN\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysqlbinlog.1 b/man/mysqlbinlog.1
index 44e91eef63d2..663197230dd7 100644
--- a/man/mysqlbinlog.1
+++ b/man/mysqlbinlog.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlbinlog\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLBINLOG\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLBINLOG\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -314,22 +314,22 @@ T}:T{
--binlog-row-event-max-size=#
T}
T{
-\fBType\fR (64-bit platforms)
+\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
-\fBDefault Value\fR (64-bit platforms)
+\fBDefault Value\fR
T}:T{
4294967040
T}
T{
-\fBMinimum Value\fR (64-bit platforms)
+\fBMinimum Value\fR
T}:T{
256
T}
T{
-\fBMaximum Value\fR (64-bit platforms)
+\fBMaximum Value\fR
T}:T{
18446744073709547520
T}
@@ -364,15 +364,13 @@ Section\ \&10.14, \(lqCharacter Set Configuration\(rq\&.
.sp
This option is used to test a MySQL server for support of the
BINLOG_DUMP_NON_BLOCK
-connection flag, which was inadvertently removed in MySQL 5\&.6\&.5, and restored in MySQL 5\&.7\&.5 (Bug #18000079, Bug #71178)\&. It is not required for normal operations\&.
+connection flag\&. It is not required for normal operations\&.
.sp
The effective default and minimum values for this option depend on whether
\fBmysqlbinlog\fR
is run in blocking mode or non\-blocking mode\&. When
\fBmysqlbinlog\fR
is run in blocking mode, the default (and minimum) value is 1; when run in non\-blocking mode, the default (and minimum) value is 0\&.
-.sp
-This option was added in MySQL 5\&.7\&.5
.RE
.sp
.RS 4
@@ -520,13 +518,9 @@ with the
option, you must ensure that tables that are modified are in the database selected by
USE\&. (In particular, no cross\-database updates should be used\&.)
.sp
-Prior to MySQL 5\&.7\&.1, the
-\fB\-\-database\fR
-option did not work correctly with a log written by a GTID\-enabled MySQL server\&. (Bug #15912728)
-.sp
When used together with the
\fB\-\-rewrite\-db\fR
-option (available in MySQL 5\&.7\&.1 and later), the
+option, the
\fB\-\-rewrite\-db\fR
option is applied first; then the
\fB\-\-database\fR
@@ -668,17 +662,14 @@ Disable binary logging\&. This is useful for avoiding an endless loop if you use
\fB\-\-to\-last\-log\fR
option and are sending the output to the same MySQL server\&. This option also is useful when restoring after a crash to avoid duplication of the statements you have logged\&.
.sp
-This option requires that you have the
-SUPER
-privilege\&. It causes
+This option causes
\fBmysqlbinlog\fR
to include a
SET sql_log_bin = 0
-statement in its output to disable binary logging of the remaining output\&. The
-SET
-statement is ineffective unless you have the
-SUPER
-privilege\&.
+statement in its output to disable binary logging of the remaining output\&. Manipulating the session value of the
+sql_log_bin
+system variable is a restricted operation, so this option requires that you have privileges sufficient to set restricted session variables\&. See
+Section\ \&5.1.8.1, \(lqSystem Variable Privileges\(rq\&.
.RE
.sp
.RS 4
@@ -800,10 +791,6 @@ Tell the MySQL Server to use idempotent mode while processing updates; this caus
The scope of effect for this option includes the current
\fBmysqlbinlog\fR
client and session only\&.
-.sp
-The
-\fB\-\-idempotent\fR
-option was introduced in MySQL 5\&.7\&.0\&.
.RE
.sp
.RS 4
@@ -1118,7 +1105,7 @@ option value is treated as a prefix that modifies output file names\&.
.\}
\fB\-\-rewrite\-db=\*(Aq\fR\fB\fIfrom_name\fR\fR\fB\->\fR\fB\fIto_name\fR\fR\fB\*(Aq\fR
.sp
-In MySQL 5\&.7\&.8 and later, when reading from a row\-based or statement\-based log, rewrite all occurrences of
+When reading from a row\-based or statement\-based log, rewrite all occurrences of
\fIfrom_name\fR
to
\fIto_name\fR\&. Rewriting is done on the rows, for row\-based logs, as well as on the
@@ -1181,8 +1168,6 @@ before applying the
\fB\-\-database\fR
option, there remain no updates that match
\fB\-\-database=mydb\fR\&.
-.sp
-This option was added in MySQL 5\&.7\&.1\&.
.RE
.sp
.RS 4
@@ -1195,7 +1180,7 @@ This option was added in MySQL 5\&.7\&.1\&.
.\}
\fB\-\-secure\-auth\fR
.sp
-Do not send passwords to the server in old (pre\-4\&.1) format\&. This prevents connections except for servers that use the newer password format\&. This option was added in MySQL 5\&.7\&.4\&.
+Do not send passwords to the server in old (pre\-4\&.1) format\&. This prevents connections except for servers that use the newer password format\&.
.sp
As of MySQL 5\&.7\&.5, this option is deprecated and will be removed in a future MySQL release\&. It is always enabled and attempting to disable it (\fB\-\-skip\-secure\-auth\fR,
\fB\-\-secure\-auth=0\fR) produces an error\&. Before MySQL 5\&.7\&.5, this option is enabled by default but can be disabled\&.
@@ -1862,7 +1847,7 @@ ROLLBACK;
.RE
.\}
.PP
-Hex dump output currently contains the elements in the following list\&. This format is subject to change\&. (For more information about binary log format, see
+Hex dump output currently contains the elements in the following list\&. This format is subject to change\&. For more information about binary log format, see
\m[blue]\fBMySQL Internals: The Binary Log\fR\m[]\&\s-2\u[1]\d\s+2\&.
.sp
.RS 4
@@ -1899,265 +1884,7 @@ in hexadecimal\&.
.sp -1
.IP \(bu 2.3
.\}
-Type: The event type code\&. In the example shown,
-\*(Aq0f\*(Aq
-indicates a
-FORMAT_DESCRIPTION_EVENT\&. The following table lists the possible type codes\&.
-.TS
-allbox tab(:);
-lB lB lB.
-T{
-Type
-T}:T{
-Name
-T}:T{
-Meaning
-T}
-.T&
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l.
-T{
-00
-T}:T{
-UNKNOWN_EVENT
-T}:T{
-This event should never be present in the log.
-T}
-T{
-01
-T}:T{
-START_EVENT_V3
-T}:T{
-This indicates the start of a log file written by MySQL 4 or earlier.
-T}
-T{
-02
-T}:T{
-QUERY_EVENT
-T}:T{
-The most common type of events. These contain statements executed on the
- master.
-T}
-T{
-03
-T}:T{
-STOP_EVENT
-T}:T{
-Indicates that master has stopped.
-T}
-T{
-04
-T}:T{
-ROTATE_EVENT
-T}:T{
-Written when the master switches to a new log file.
-T}
-T{
-05
-T}:T{
-INTVAR_EVENT
-T}:T{
-Used for AUTO_INCREMENT values or when the
- LAST_INSERT_ID()
- function is used in the statement.
-T}
-T{
-06
-T}:T{
-LOAD_EVENT
-T}:T{
-Used for LOAD DATA
- INFILE in MySQL 3.23.
-T}
-T{
-07
-T}:T{
-SLAVE_EVENT
-T}:T{
-Reserved for future use.
-T}
-T{
-08
-T}:T{
-CREATE_FILE_EVENT
-T}:T{
-Used for LOAD DATA
- INFILE statements. This indicates the start
- of execution of such a statement. A temporary file is
- created on the slave. Used in MySQL 4 only.
-T}
-T{
-09
-T}:T{
-APPEND_BLOCK_EVENT
-T}:T{
-Contains data for use in a
- LOAD DATA
- INFILE statement. The data is stored in the
- temporary file on the slave.
-T}
-T{
-0a
-T}:T{
-EXEC_LOAD_EVENT
-T}:T{
-Used for LOAD DATA
- INFILE statements. The contents of the
- temporary file is stored in the table on the slave.
- Used in MySQL 4 only.
-T}
-T{
-0b
-T}:T{
-DELETE_FILE_EVENT
-T}:T{
-Rollback of a LOAD DATA
- INFILE statement. The temporary file should
- be deleted on the slave.
-T}
-T{
-0c
-T}:T{
-NEW_LOAD_EVENT
-T}:T{
-Used for LOAD DATA
- INFILE in MySQL 4 and earlier.
-T}
-T{
-0d
-T}:T{
-RAND_EVENT
-T}:T{
-Used to send information about random values if the
- RAND() function is used
- in the statement.
-T}
-T{
-0e
-T}:T{
-USER_VAR_EVENT
-T}:T{
-Used to replicate user variables.
-T}
-T{
-0f
-T}:T{
-FORMAT_DESCRIPTION_EVENT
-T}:T{
-This indicates the start of a log file written by MySQL 5 or later.
-T}
-T{
-10
-T}:T{
-XID_EVENT
-T}:T{
-Event indicating commit of an XA transaction.
-T}
-T{
-11
-T}:T{
-BEGIN_LOAD_QUERY_EVENT
-T}:T{
-Used for LOAD DATA
- INFILE statements in MySQL 5 and later.
-T}
-T{
-12
-T}:T{
-EXECUTE_LOAD_QUERY_EVENT
-T}:T{
-Used for LOAD DATA
- INFILE statements in MySQL 5 and later.
-T}
-T{
-13
-T}:T{
-TABLE_MAP_EVENT
-T}:T{
-Information about a table definition. Used in MySQL 5.1.5 and later.
-T}
-T{
-14
-T}:T{
-PRE_GA_WRITE_ROWS_EVENT
-T}:T{
-Row data for a single table that should be created. Used in MySQL 5.1.5
- to 5.1.17.
-T}
-T{
-15
-T}:T{
-PRE_GA_UPDATE_ROWS_EVENT
-T}:T{
-Row data for a single table that needs to be updated. Used in MySQL
- 5.1.5 to 5.1.17.
-T}
-T{
-16
-T}:T{
-PRE_GA_DELETE_ROWS_EVENT
-T}:T{
-Row data for a single table that should be deleted. Used in MySQL 5.1.5
- to 5.1.17.
-T}
-T{
-17
-T}:T{
-WRITE_ROWS_EVENT
-T}:T{
-Row data for a single table that should be created. Used in MySQL 5.1.18
- and later.
-T}
-T{
-18
-T}:T{
-UPDATE_ROWS_EVENT
-T}:T{
-Row data for a single table that needs to be updated. Used in MySQL
- 5.1.18 and later.
-T}
-T{
-19
-T}:T{
-DELETE_ROWS_EVENT
-T}:T{
-Row data for a single table that should be deleted. Used in MySQL 5.1.18
- and later.
-T}
-T{
-1a
-T}:T{
-INCIDENT_EVENT
-T}:T{
-Something out of the ordinary happened. Added in MySQL 5.1.18.
-T}
-.TE
-.sp 1
+Type: The event type code\&.
.RE
.sp
.RS 4
@@ -2201,61 +1928,7 @@ Master Pos: The position of the next event in the original master log file\&.
.sp -1
.IP \(bu 2.3
.\}
-Flags: 16 flags\&. The following flags are used\&. The others are reserved for future use\&.
-.TS
-allbox tab(:);
-lB lB lB.
-T{
-Flag
-T}:T{
-Name
-T}:T{
-Meaning
-T}
-.T&
-l l l
-l l l
-l l l
-l l l.
-T{
-01
-T}:T{
-LOG_EVENT_BINLOG_IN_USE_F
-T}:T{
-Log file correctly closed. (Used only in
- FORMAT_DESCRIPTION_EVENT.) If this
- flag is set (if the flags are, for example,
- '01 00') in a
- FORMAT_DESCRIPTION_EVENT, the log
- file has not been properly closed. Most probably this
- is because of a master crash (for example, due to
- power failure).
-T}
-T{
-02
-T}:T{
-T}:T{
-Reserved for future use.
-T}
-T{
-04
-T}:T{
-LOG_EVENT_THREAD_SPECIFIC_F
-T}:T{
-Set if the event is dependent on the connection it was executed in (for
- example, '04 00'), for example, if
- the event uses temporary tables.
-T}
-T{
-08
-T}:T{
-LOG_EVENT_SUPPRESS_USE_F
-T}:T{
-Set in some circumstances when the event is not dependent on the default
- database.
-T}
-.TE
-.sp 1
+Flags: Event flag values\&.
.RE
.SH "MYSQLBINLOG ROW EVENT DISPLAY"
.PP
@@ -3075,7 +2748,7 @@ You should have received a copy of the GNU General Public License along with the
.IP " 1." 4
MySQL Internals: The Binary Log
.RS 4
-\%http://dev.mysql.com/doc/internals/en/binary-log.html
+\%https://dev.mysql.com/doc/internals/en/binary-log.html
.RE
.SH "SEE ALSO"
For more information, please refer to the MySQL Reference Manual,
diff --git a/man/mysqlcheck.1 b/man/mysqlcheck.1
index 7923e44494b5..6b8f4434b697 100644
--- a/man/mysqlcheck.1
+++ b/man/mysqlcheck.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlcheck\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLCHECK\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLCHECK\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -219,7 +219,7 @@ Check all tables in all databases\&. This is the same as using the
option and naming all the databases on the command line, except that the
INFORMATION_SCHEMA
and
-performace_schema
+performance_schema
databases are not checked\&. They can be checked by explicitly naming them with the
\fB\-\-databases\fR
option\&.
diff --git a/man/mysqld.8 b/man/mysqld.8
index 9764ad4ca6b9..42334ec45340 100644
--- a/man/mysqld.8
+++ b/man/mysqld.8
@@ -2,12 +2,12 @@
.\" Title: \fBmysqld\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLD\FR" "8" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLD\FR" "8" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysqld_multi.1 b/man/mysqld_multi.1
index 239dbed827ea..7645a69b29a2 100644
--- a/man/mysqld_multi.1
+++ b/man/mysqld_multi.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqld_multi\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLD_MULTI\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLD_MULTI\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1
index 2c27368c34b0..f7434ebe3bb4 100644
--- a/man/mysqld_safe.1
+++ b/man/mysqld_safe.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqld_safe\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLD_SAFE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLD_SAFE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -733,7 +733,7 @@ syslog; messages are written to an error log file\&.
.sp
When
syslog
-is used, the
+is used for error logging, the
daemon\&.err
facility/severity is used for all log messages\&.
.sp
@@ -744,7 +744,7 @@ log_syslog
system variable instead\&. To control the facility, use the server
log_syslog_facility
system variable\&. See
-Section\ \&5.4.2, \(lqThe Error Log\(rq\&.
+Section\ \&5.4.2.3, \(lqError Logging to the System Log\(rq\&.
.RE
.sp
.RS 4
@@ -776,7 +776,7 @@ Using this option to control
logging is deprecated as of MySQL 5\&.7\&.5\&. Use the server
log_syslog_tag
system variable instead\&. See
-Section\ \&5.4.2, \(lqThe Error Log\(rq\&.
+Section\ \&5.4.2.3, \(lqError Logging to the System Log\(rq\&.
.RE
.sp
.RS 4
@@ -1010,7 +1010,7 @@ logging from
is deprecated as of MySQL 5\&.7\&.5\&. Use the server\*(Aqs native
syslog
support instead\&. For more information, see
-Section\ \&5.4.2, \(lqThe Error Log\(rq\&.
+Section\ \&5.4.2.3, \(lqError Logging to the System Log\(rq\&.
.sp .5v
.RE
.SH "COPYRIGHT"
diff --git a/man/mysqldump.1 b/man/mysqldump.1
index af65ad602c5e..9bf287ea77ff 100644
--- a/man/mysqldump.1
+++ b/man/mysqldump.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqldump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLDUMP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLDUMP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -299,7 +299,7 @@ shell> \fBmysqldump [options] > dump\&.sql\fR
.\}
.PP
However, UTF\-16 is not permitted as a connection character set (see
-Section\ \&10.4, \(lqConnection Character Sets and Collations\(rq), so the dump file will not load correctly\&. To work around this issue, use the
+the section called \(lqImpermissible Client Character Sets\(rq), so the dump file will not load correctly\&. To work around this issue, use the
\fB\-\-result\-file\fR
option, which creates the output in ASCII format:
.sp
@@ -2088,7 +2088,7 @@ statements are included in the output before each new database\&.
This option may be used to dump the
INFORMATION_SCHEMA
and
-performace_schema
+performance_schema
databases, which normally are not dumped even with the
\fB\-\-all\-databases\fR
option\&. (Also use the
@@ -2247,7 +2247,7 @@ Multiple triggers are permitted\&.
dumps triggers in activation order so that when the dump file is reloaded, triggers are created in the same activation order\&. However, if a
\fBmysqldump\fR
dump file contains multiple triggers for a table that have the same trigger event and action time, an error occurs for attempts to load the dump file into an older server that does not support multiple triggers\&. (For a workaround, see
-Section\ \&2.11.2.1, \(lqChanges Affecting Downgrades from MySQL 5.7\(rq; you can convert triggers to be compatible with older servers\&.)
+Section\ \&2.11.2.3, \(lqDowngrade Notes\(rq; you can convert triggers to be compatible with older servers\&.)
.RE
.sp
.RS 4
@@ -2489,7 +2489,7 @@ database for proper restoration\&.
.br
For upgrades to MySQL 5\&.7 or higher from older versions, do not use
\fB\-\-flush\-privileges\fR\&. For upgrade instructions in this case, see
-Section\ \&2.11.1.2, \(lqChanges Affecting Upgrades to MySQL 5.7\(rq\&.
+Section\ \&2.11.1.3, \(lqChanges in MySQL 5.7\(rq\&.
.sp .5v
.RE
.RE
@@ -2888,10 +2888,16 @@ does not dump the NDB Cluster
ndbinfo
information database\&.
.PP
+\fBmysqldump\fR
+does not dump
+InnoDB
+CREATE TABLESPACE
+statements\&.
+.PP
It is not recommended to restore from a dump made using
\fBmysqldump\fR
to a MySQL 5\&.6\&.9 or earlier server that has GTIDs enabled\&. See
-Section\ \&16.1.3.4, \(lqRestrictions on Replication with GTIDs\(rq\&.
+Section\ \&16.1.3.6, \(lqRestrictions on Replication with GTIDs\(rq\&.
.PP
\fBmysqldump\fR
includes statements to recreate the
diff --git a/man/mysqlimport.1 b/man/mysqlimport.1
index 2b2c9520897e..44d7a897c645 100644
--- a/man/mysqlimport.1
+++ b/man/mysqlimport.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlimport\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLIMPORT\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLIMPORT\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysqlpump.1 b/man/mysqlpump.1
index ff87341306df..f8c36fb31116 100644
--- a/man/mysqlpump.1
+++ b/man/mysqlpump.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlpump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLPUMP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLPUMP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -2346,6 +2346,12 @@ or
option\&.
.PP
\fBmysqlpump\fR
+does not dump
+InnoDB
+CREATE TABLESPACE
+statements\&.
+.PP
+\fBmysqlpump\fR
dumps user accounts in logical form using
CREATE USER
and
diff --git a/man/mysqlshow.1 b/man/mysqlshow.1
index b2061590c004..0dd9d33fb2df 100644
--- a/man/mysqlshow.1
+++ b/man/mysqlshow.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlshow\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLSHOW\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLSHOW\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/mysqlslap.1 b/man/mysqlslap.1
index 0f483d2376db..18ab7d84cbdc 100644
--- a/man/mysqlslap.1
+++ b/man/mysqlslap.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlslap\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBMYSQLSLAP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBMYSQLSLAP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb-common-options.1 b/man/ndb-common-options.1
index 85343e9a058c..29089ef5c9fc 100644
--- a/man/ndb-common-options.1
+++ b/man/ndb-common-options.1
@@ -2,12 +2,12 @@
.\" Title: Options Common to NDB Cluster Programs
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "OPTIONS COMMON TO NDB CLUSTER PROGRAMS" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "OPTIONS COMMON TO NDB CLUSTER PROGRAMS" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -105,7 +105,7 @@ The options in the following table are common to all NDB Cluster executables (ex
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.340.\ \&Command\-line options common to all MySQL NDB Cluster programs
+.B Table\ \&21.355.\ \&Command\-line options common to all MySQL NDB Cluster programs
.TS
allbox tab(:);
lB lB lB.
@@ -341,7 +341,7 @@ T}
T{
\fBType\fR
T}:T{
-directory name
+Directory name
T}
T{
\fBDefault Value\fR
@@ -383,7 +383,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -446,9 +446,6 @@ l l
l l
l l
l l
-l l
-l l
-l l
l l.
T{
\fBCommand-Line Format\fR
@@ -456,19 +453,9 @@ T}:T{
--connect-retry-delay=#
T}
T{
-\fBType\fR (>= 5.7.10-ndb-7.5.0)
-T}:T{
-numeric
-T}
-T{
\fBType\fR
T}:T{
-numeric
-T}
-T{
-\fBDefault Value\fR (>= 5.7.10-ndb-7.5.0)
-T}:T{
-5
+Numeric
T}
T{
\fBDefault Value\fR
@@ -486,11 +473,6 @@ T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.10-ndb-7.5.0)
-T}:T{
-4294967295
-T}
-T{
\fBMaximum Value\fR
T}:T{
4294967295
@@ -530,7 +512,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -583,7 +565,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -626,7 +608,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -667,7 +649,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -708,7 +690,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -783,7 +765,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -829,7 +811,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -883,7 +865,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -926,7 +908,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -969,7 +951,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1010,7 +992,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1051,7 +1033,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_blob_tool.1 b/man/ndb_blob_tool.1
index 230c4197c31b..3fb3cc0363ac 100644
--- a/man/ndb_blob_tool.1
+++ b/man/ndb_blob_tool.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_blob_tool\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_BLOB_TOOL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_BLOB_TOOL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -93,7 +93,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.318.\ \&Command\-line options for the ndb_blob_tool program
+.B Table\ \&21.333.\ \&Command\-line options for the ndb_blob_tool program
.TS
allbox tab(:);
lB lB lB.
@@ -191,7 +191,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -233,7 +233,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -274,7 +274,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -315,7 +315,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -357,7 +357,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_config.1 b/man/ndb_config.1
index 1509a22d51aa..ecedaee04f06 100644
--- a/man/ndb_config.1
+++ b/man/ndb_config.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_config\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_CONFIG\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_CONFIG\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -68,7 +68,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.319.\ \&Command\-line options for the ndb_config program
+.B Table\ \&21.334.\ \&Command\-line options for the ndb_config program
.TS
allbox tab(:);
lB lB lB.
@@ -413,7 +413,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -457,7 +457,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -512,7 +512,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -564,10 +564,6 @@ T}
l l
l l
l l
-l l
-l l
-l l
-l l
l l.
T{
\fBCommand-Line Format\fR
@@ -580,29 +576,9 @@ T}:T{
5.7.18-ndb-7.6.3
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.3)
-T}:T{
-boolean
-T}
-T{
-\fBType\fR (>= 5.7.18-ndb-7.5.7)
-T}:T{
-boolean
-T}
-T{
\fBType\fR
T}:T{
-boolean
-T}
-T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.3)
-T}:T{
-FALSE
-T}
-T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.5.7)
-T}:T{
-FALSE
+Boolean
T}
T{
\fBDefault Value\fR
@@ -645,7 +621,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -708,7 +684,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -778,7 +754,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -825,7 +801,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -869,7 +845,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -912,7 +888,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -967,7 +943,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1040,12 +1016,12 @@ T}:T{
5.7.18-ndb-7.5.7
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.4.16,5.7.18-ndb-7.5.7)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.4.16,5.7.18-ndb-7.5.7)
+\fBDefault Value\fR
T}:T{
T}
.TE
@@ -1086,7 +1062,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1147,7 +1123,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1201,7 +1177,7 @@ T}
T{
\fBType\fR
T}:T{
-enumeration
+Enumeration
T}
T{
\fBDefault Value\fR
@@ -1325,7 +1301,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1344,7 +1320,7 @@ to provide output as XML by adding this option\&. A portion of such output is sh
.\}
.nf
shell> \fBndb_config \-\-configinfo \-\-xml\fR
-
diff --git a/man/ndb_cpcd.1 b/man/ndb_cpcd.1
index 98c71015acef..2d338d2a3994 100644
--- a/man/ndb_cpcd.1
+++ b/man/ndb_cpcd.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_cpcd\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_CPCD\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_CPCD\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb_delete_all.1 b/man/ndb_delete_all.1
index 593f669122cd..ff8e4cf8e56d 100644
--- a/man/ndb_delete_all.1
+++ b/man/ndb_delete_all.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_delete_all\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_DELETE_ALL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_DELETE_ALL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -69,7 +69,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.320.\ \&Command\-line options for the ndb_delete_all program
+.B Table\ \&21.335.\ \&Command\-line options for the ndb_delete_all program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_desc.1 b/man/ndb_desc.1
index 7d640754b0b9..3ebc7eba0c95 100644
--- a/man/ndb_desc.1
+++ b/man/ndb_desc.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_desc\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_DESC\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_DESC\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -479,7 +479,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.321.\ \&Command\-line options for the ndb_desc program
+.B Table\ \&21.336.\ \&Command\-line options for the ndb_desc program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_drop_index.1 b/man/ndb_drop_index.1
index cb39b9c5bc2e..89ebd421282c 100644
--- a/man/ndb_drop_index.1
+++ b/man/ndb_drop_index.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_drop_index\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_DROP_INDEX\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_DROP_INDEX\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -67,7 +67,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.322.\ \&Command\-line options for the ndb_drop_index program
+.B Table\ \&21.337.\ \&Command\-line options for the ndb_drop_index program
.TS
allbox tab(:);
lB lB lB.
@@ -122,7 +122,7 @@ Enter password: *******
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with \-A
Welcome to the MySQL monitor\&. Commands end with ; or \eg\&.
-Your MySQL connection id is 7 to server version: 5\&.7\&.23\-ndb\-7\&.5\&.11
+Your MySQL connection id is 7 to server version: 5\&.7\&.24\-ndb\-7\&.5\&.13
Type \*(Aqhelp;\*(Aq or \*(Aq\eh\*(Aq for help\&. Type \*(Aq\ec\*(Aq to clear the buffer\&.
mysql> \fBSHOW TABLES;\fR
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
diff --git a/man/ndb_drop_table.1 b/man/ndb_drop_table.1
index a5a32ce3dea9..117fcbbae97d 100644
--- a/man/ndb_drop_table.1
+++ b/man/ndb_drop_table.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_drop_table\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_DROP_TABLE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_DROP_TABLE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -65,7 +65,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.323.\ \&Command\-line options for the ndb_drop_table program
+.B Table\ \&21.338.\ \&Command\-line options for the ndb_drop_table program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_error_reporter.1 b/man/ndb_error_reporter.1
index 7b5df3d923d6..a92d179f301d 100644
--- a/man/ndb_error_reporter.1
+++ b/man/ndb_error_reporter.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_error_reporter\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_ERROR_REPORTER\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_ERROR_REPORTER\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -47,7 +47,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.324.\ \&Command\-line options for the ndb_error_reporter program
+.B Table\ \&21.339.\ \&Command\-line options for the ndb_error_reporter program
.TS
allbox tab(:);
lB lB lB.
@@ -154,7 +154,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -195,7 +195,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -238,7 +238,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -283,7 +283,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_import.1 b/man/ndb_import.1
index 0135a17d4512..e350d450f28f 100644
--- a/man/ndb_import.1
+++ b/man/ndb_import.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_import\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_IMPORT\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_IMPORT\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -182,7 +182,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.325.\ \&Command\-line options for the ndb_import program
+.B Table\ \&21.340.\ \&Command\-line options for the ndb_import program
.TS
allbox tab(:);
lB lB lB.
@@ -635,12 +635,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
FALSE
T}
@@ -684,22 +684,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -745,22 +745,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -806,22 +806,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1024
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -867,22 +867,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -924,12 +924,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
FALSE
T}
@@ -973,22 +973,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1031,17 +1031,17 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-enumeration
+Enumeration
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
[none]
T}
T{
-\fBValid Values\fR (>= 5.7.18-ndb-7.6.2)
+\fBValid Values\fR
T}:T{
.PP
stopjob
@@ -1098,22 +1098,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1000
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1155,12 +1155,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
[none]
T}
@@ -1207,12 +1207,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
\
T}
@@ -1258,12 +1258,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
[none]
T}
@@ -1310,12 +1310,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
\t
T}
@@ -1363,22 +1363,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1422,22 +1422,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1481,22 +1481,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1541,17 +1541,17 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-enumeration
+Enumeration
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
csv
T}
T{
-\fBValid Values\fR (>= 5.7.18-ndb-7.6.2)
+\fBValid Values\fR
T}:T{
.PP
random
@@ -1601,22 +1601,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
2
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1658,12 +1658,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
\n
T}
@@ -1711,22 +1711,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1770,22 +1770,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
2
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1827,12 +1827,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
FALSE
T}
@@ -1874,12 +1874,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
FALSE
T}
@@ -1923,22 +1923,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
256
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -1982,22 +1982,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2040,17 +2040,17 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-enumeration
+Enumeration
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
ndb
T}
T{
-\fBValid Values\fR (>= 5.7.18-ndb-7.6.2)
+\fBValid Values\fR
T}:T{
null
T}
@@ -2098,22 +2098,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
2
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2157,22 +2157,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
4096
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2216,22 +2216,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
64
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2275,22 +2275,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
1000
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
1
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2334,22 +2334,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2393,12 +2393,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
FALSE
T}
@@ -2442,22 +2442,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2501,22 +2501,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
262144
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2558,12 +2558,12 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-string
+String
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
.
T}
@@ -2610,22 +2610,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
10
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2669,22 +2669,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
4294967295
T}
@@ -2731,22 +2731,22 @@ T}:T{
5.7.18-ndb-7.6.2
T}
T{
-\fBType\fR (>= 5.7.18-ndb-7.6.2)
+\fBType\fR
T}:T{
-integer
+Integer
T}
T{
-\fBDefault Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBDefault Value\fR
T}:T{
0
T}
T{
-\fBMinimum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.18-ndb-7.6.2)
+\fBMaximum Value\fR
T}:T{
2
T}
diff --git a/man/ndb_index_stat.1 b/man/ndb_index_stat.1
index f7163d67dc7a..cd113a152fde 100644
--- a/man/ndb_index_stat.1
+++ b/man/ndb_index_stat.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_index_stat\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_INDEX_STAT\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_INDEX_STAT\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -176,7 +176,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.326.\ \&Command\-line options for the ndb_index_stat program
+.B Table\ \&21.341.\ \&Command\-line options for the ndb_index_stat program
.TS
allbox tab(:);
lB lB lB.
@@ -377,7 +377,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -428,7 +428,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -479,7 +479,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -530,7 +530,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -581,7 +581,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -637,7 +637,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -689,7 +689,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -740,7 +740,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -791,7 +791,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -842,7 +842,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -893,7 +893,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -946,7 +946,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -999,7 +999,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1050,7 +1050,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_mgm.1 b/man/ndb_mgm.1
index eb4974585c26..6e30fbc8266b 100644
--- a/man/ndb_mgm.1
+++ b/man/ndb_mgm.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_mgm\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_MGM\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_MGM\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -76,7 +76,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.317.\ \&Command\-line options for the ndb_mgm program
+.B Table\ \&21.332.\ \&Command\-line options for the ndb_mgm program
.TS
allbox tab(:);
lB lB lB.
@@ -147,7 +147,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -273,8 +273,6 @@ l l
l l
l l
l l
-l l
-l l
l l.
T{
\fBCommand-Line Format\fR
@@ -289,12 +287,12 @@ T}
T{
\fBType\fR (>= 5.7.10-ndb-7.5.0)
T}:T{
-numeric
+Numeric
T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR (>= 5.7.10-ndb-7.5.0)
@@ -307,21 +305,11 @@ T}:T{
3
T}
T{
-\fBMinimum Value\fR (>= 5.7.10-ndb-7.5.0)
-T}:T{
-0
-T}
-T{
\fBMinimum Value\fR
T}:T{
0
T}
T{
-\fBMaximum Value\fR (>= 5.7.10-ndb-7.5.0)
-T}:T{
-4294967295
-T}
-T{
\fBMaximum Value\fR
T}:T{
4294967295
diff --git a/man/ndb_mgmd.8 b/man/ndb_mgmd.8
index 47fecc551668..edb2efbf0dd5 100644
--- a/man/ndb_mgmd.8
+++ b/man/ndb_mgmd.8
@@ -2,12 +2,12 @@
.\" Title: \fBndb_mgmd\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_MGMD\FR" "8" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_MGMD\FR" "8" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -45,7 +45,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.316.\ \&Command\-line options for the ndb_mgmd program
+.B Table\ \&21.331.\ \&Command\-line options for the ndb_mgmd program
.TS
allbox tab(:);
lB lB lB.
@@ -283,7 +283,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -324,7 +324,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -479,7 +479,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -539,7 +539,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -583,7 +583,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -630,7 +630,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -705,7 +705,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -768,7 +768,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -813,7 +813,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -854,7 +854,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -897,7 +897,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -938,7 +938,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -987,7 +987,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -1145,7 +1145,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1190,7 +1190,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1257,7 +1257,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1299,7 +1299,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_move_data.1 b/man/ndb_move_data.1
index 4db14da2c768..3806ec133c66 100644
--- a/man/ndb_move_data.1
+++ b/man/ndb_move_data.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_move_data\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_MOVE_DATA\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_MOVE_DATA\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -58,7 +58,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.327.\ \&Command\-line options for the ndb_move_data program
+.B Table\ \&21.342.\ \&Command\-line options for the ndb_move_data program
.TS
allbox tab(:);
lB lB lB.
@@ -209,7 +209,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -250,7 +250,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -292,7 +292,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -333,7 +333,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -374,7 +374,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -415,7 +415,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -457,7 +457,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -499,7 +499,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -540,7 +540,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -581,7 +581,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_perror.1 b/man/ndb_perror.1
index 617ff862e3b1..134cc061851d 100644
--- a/man/ndb_perror.1
+++ b/man/ndb_perror.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_perror\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_PERROR\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_PERROR\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -122,7 +122,7 @@ The following table includes all options that are specific to the NDB Cluster pr
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.328.\ \&Command\-line options for the ndb_perror program
+.B Table\ \&21.343.\ \&Command\-line options for the ndb_perror program
.TS
allbox tab(:);
lB lB lB.
@@ -233,7 +233,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -280,7 +280,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -334,7 +334,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -382,7 +382,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -430,7 +430,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_print_backup_file.1 b/man/ndb_print_backup_file.1
index afd99a54dc3e..e7669423b5d6 100644
--- a/man/ndb_print_backup_file.1
+++ b/man/ndb_print_backup_file.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_print_backup_file\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_PRINT_BACKUP_FILE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_PRINT_BACKUP_FILE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb_print_file.1 b/man/ndb_print_file.1
index 6aa86541e3ce..4d82441144ac 100644
--- a/man/ndb_print_file.1
+++ b/man/ndb_print_file.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_print_file\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_PRINT_FILE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_PRINT_FILE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb_print_frag_file.1 b/man/ndb_print_frag_file.1
index 00c1196af64f..c1281e7ab663 100644
--- a/man/ndb_print_frag_file.1
+++ b/man/ndb_print_frag_file.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_print_frag_file\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_PRINT_FRAG_FILE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_PRINT_FRAG_FILE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb_print_schema_file.1 b/man/ndb_print_schema_file.1
index a88c238b3daf..7543e8bac001 100644
--- a/man/ndb_print_schema_file.1
+++ b/man/ndb_print_schema_file.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_print_schema_file\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_PRINT_SCHEMA_FILE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_PRINT_SCHEMA_FILE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb_print_sys_file.1 b/man/ndb_print_sys_file.1
index f97e23b376c9..1529442cae82 100644
--- a/man/ndb_print_sys_file.1
+++ b/man/ndb_print_sys_file.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_print_sys_file\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_PRINT_SYS_FILE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_PRINT_SYS_FILE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/ndb_redo_log_reader.1 b/man/ndb_redo_log_reader.1
index 4c9a01b083df..5cb0b5cc9917 100644
--- a/man/ndb_redo_log_reader.1
+++ b/man/ndb_redo_log_reader.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_redo_log_reader\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_REDO_LOG_READER\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_REDO_LOG_READER\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -71,7 +71,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.329.\ \&Command\-line options for the ndb_redo_log_reader program
+.B Table\ \&21.344.\ \&Command\-line options for the ndb_redo_log_reader program
.TS
allbox tab(:);
lB lB lB.
@@ -263,7 +263,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -303,7 +303,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -372,7 +372,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -414,7 +414,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -467,7 +467,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -507,7 +507,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -547,7 +547,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -589,7 +589,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -642,7 +642,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -684,7 +684,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -738,7 +738,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_restore.1 b/man/ndb_restore.1
index 3c887e89d76c..37f93d956b9b 100644
--- a/man/ndb_restore.1
+++ b/man/ndb_restore.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_restore\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_RESTORE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_RESTORE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -72,7 +72,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.330.\ \&Command\-line options for the ndb_restore program
+.B Table\ \&21.345.\ \&Command\-line options for the ndb_restore program
.TS
allbox tab(:);
lB lB lB.
@@ -718,7 +718,7 @@ T}
T{
\fBType\fR
T}:T{
-directory name
+Directory name
T}
T{
\fBDefault Value\fR
@@ -750,7 +750,7 @@ and
must be run twice\(emonce for each storage node in the cluster where the backup was taken\&. However,
\fBndb_restore\fR
cannot always restore backups made from a cluster running one version of MySQL to a cluster running a different MySQL version\&. See
-Section\ \&21.2.8, \(lqUpgrading and Downgrading NDB Cluster\(rq, for more information\&.
+Section\ \&21.2.9, \(lqUpgrading and Downgrading NDB Cluster\(rq, for more information\&.
.if n \{\
.sp
.\}
@@ -768,9 +768,9 @@ It is not possible to restore a backup made from a newer version of NDB Cluster
\fBndb_restore\fR
from the newer NDB Cluster version to do so\&.
.sp
-For example, to restore a cluster backup taken from a cluster running NDB Cluster 7\&.5\&.11 to a cluster running NDB Cluster 7\&.4\&.21, you must use the
+For example, to restore a cluster backup taken from a cluster running NDB Cluster 7\&.5\&.13 to a cluster running NDB Cluster 7\&.4\&.23, you must use the
\fBndb_restore\fR
-that comes with the NDB Cluster 7\&.5\&.11 distribution\&.
+that comes with the NDB Cluster 7\&.5\&.13 distribution\&.
.sp .5v
.RE
For more rapid restoration, the data may be restored in parallel, provided that there is a sufficient number of cluster connections available\&. That is, when restoring to multiple nodes in parallel, you must have an
@@ -814,7 +814,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -874,7 +874,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -985,7 +985,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1028,7 +1028,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1147,7 +1147,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1175,7 +1175,7 @@ options (other options possibly required have been omitted for clarity), and the
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.331.\ \&Several invocations of ndb_restore using \-\-exclude\-* options, and the effects these options have on restoring from an NDB Cluster backup\&.
+.B Table\ \&21.346.\ \&Several invocations of ndb_restore using \-\-exclude\-* options, and the effects these options have on restoring from an NDB Cluster backup\&.
.TS
allbox tab(:);
lB lB.
@@ -1369,7 +1369,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1410,7 +1410,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1455,7 +1455,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1525,7 +1525,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1566,7 +1566,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1593,7 +1593,7 @@ options (other options possibly required have been omitted for clarity), and the
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.332.\ \&Several invocations of ndb_restore using \-\-include\-* options, and their effects on restoring from an NDB Cluster backup\&.
+.B Table\ \&21.347.\ \&Several invocations of ndb_restore using \-\-include\-* options, and their effects on restoring from an NDB Cluster backup\&.
.TS
allbox tab(:);
lB lB.
@@ -1733,7 +1733,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1775,7 +1775,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1856,7 +1856,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1967,7 +1967,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -2014,7 +2014,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -2137,7 +2137,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2207,7 +2207,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2263,7 +2263,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2307,7 +2307,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2355,7 +2355,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2405,7 +2405,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -2627,7 +2627,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2708,7 +2708,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2780,7 +2780,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -2829,7 +2829,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -3094,7 +3094,7 @@ T}
T{
\fBType\fR
T}:T{
-directory name
+Directory name
T}
.TE
.sp 1
@@ -3137,7 +3137,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
diff --git a/man/ndb_select_all.1 b/man/ndb_select_all.1
index d51c97783018..4419cd7bb1d1 100644
--- a/man/ndb_select_all.1
+++ b/man/ndb_select_all.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_select_all\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_SELECT_ALL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_SELECT_ALL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -60,7 +60,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.333.\ \&Command\-line options for the ndb_select_all program
+.B Table\ \&21.348.\ \&Command\-line options for the ndb_select_all program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_select_count.1 b/man/ndb_select_count.1
index 383293bd7a9b..21c98d36a769 100644
--- a/man/ndb_select_count.1
+++ b/man/ndb_select_count.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_select_count\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_SELECT_COUNT\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_SELECT_COUNT\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -60,7 +60,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.334.\ \&Command\-line options for the ndb_select_count program
+.B Table\ \&21.349.\ \&Command\-line options for the ndb_select_count program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_setup.py.1 b/man/ndb_setup.py.1
index 507bad57d051..0a85f5b485b6 100644
--- a/man/ndb_setup.py.1
+++ b/man/ndb_setup.py.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_setup.py\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_SETUP\&.PY\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_SETUP\&.PY\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -59,7 +59,7 @@ or other administrative account\&.
This section describes usage of and program options for the command\-line tool only\&. For information about using the Auto\-Installer GUI that is spawned when
\fBndb_setup\&.py\fR
is invoked, see
-Section\ \&21.2.1, \(lqThe NDB Cluster Auto-Installer\(rq\&.
+Section\ \&21.2.1, \(lqThe NDB Cluster Auto-Installer (NDB 7.5)\(rq\&.
Usage.PP
All platforms:
.sp
@@ -92,7 +92,7 @@ The following table includes all options that are supported by the NDB Cluster i
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.335.\ \&Command\-line options for the ndb_setup\&.py program
+.B Table\ \&21.350.\ \&Command\-line options for the ndb_setup\&.py program
.TS
allbox tab(:);
lB lB lB.
@@ -114,6 +114,7 @@ l l l
l l l
l l l
l l l
+l l l
l l l.
T{
.PP
@@ -230,6 +231,17 @@ All MySQL 5.7 based releases
T}
T{
.PP
+--use-http,
+.PP
+-H
+T}:T{
+Use unencrypted (HTTP) client/server connection
+T}:T{
+.PP
+NDB 7.6 and later
+T}
+T{
+.PP
--use-https,
.PP
-S
@@ -272,7 +284,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -315,7 +327,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -357,7 +369,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -366,7 +378,7 @@ cfg.pem
T}
.TE
.sp 1
-Specify a file containing an X509 certificate which identifies the server\&. It is possible for the certificate to be self\-signed\&. The default is
+Specify a file containing an X\&.509 certificate which identifies the server\&. It is possible for the certificate to be self\-signed\&. The default is
cfg\&.pem\&.
.RE
.sp
@@ -401,7 +413,7 @@ T}
T{
\fBType\fR
T}:T{
-enumeration
+Enumeration
T}
T{
\fBDefault Value\fR
@@ -494,7 +506,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -503,7 +515,7 @@ T}:T{
T}
.TE
.sp 1
-Specify a file containing the private key if this is not included in the X509 certificate file (\fB\-\-cert\-file\fR)\&. The default is an empty string, which means that no such file is used\&.
+Specify a file containing the private key if this is not included in the X\&. 509 certificate file (\fB\-\-cert\-file\fR)\&. The default is an empty string, which means that no such file is used\&.
.RE
.sp
.RS 4
@@ -568,7 +580,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -624,7 +636,7 @@ T}
T{
\fBType\fR
T}:T{
-file name
+File name
T}
T{
\fBDefault Value\fR
@@ -679,7 +691,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -700,6 +712,38 @@ localhost\&.
.sp -1
.IP \(bu 2.3
.\}
+\fB\-\-use\-http\fR,
+\fB\-H\fR
+.TS
+allbox tab(:);
+lB lB.
+T{
+Property
+T}:T{
+Value
+T}
+.T&
+l l.
+T{
+\fBCommand-Line Format\fR
+T}:T{
+--use-http
+T}
+.TE
+.sp 1
+Make the browser use HTTP to connect with the server\&. This means that the connection is unencrypted and not secured in any way\&.
+.sp
+This option was added in NDB 7\&.6\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
\fB\-\-use\-https\fR,
\fB\-S\fR
.TS
diff --git a/man/ndb_show_tables.1 b/man/ndb_show_tables.1
index f312a1ac0709..0e15bb93941b 100644
--- a/man/ndb_show_tables.1
+++ b/man/ndb_show_tables.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_show_tables\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_SHOW_TABLES\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_SHOW_TABLES\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -51,7 +51,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.336.\ \&Command\-line options for the ndb_show_tables program
+.B Table\ \&21.351.\ \&Command\-line options for the ndb_show_tables program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_size.pl.1 b/man/ndb_size.pl.1
index cfe8855e5f79..1f3639ceb8b5 100644
--- a/man/ndb_size.pl.1
+++ b/man/ndb_size.pl.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_size.pl\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_SIZE\&.PL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_SIZE\&.PL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -101,7 +101,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.337.\ \&Command\-line options for the ndb_size\&.pl program
+.B Table\ \&21.352.\ \&Command\-line options for the ndb_size\&.pl program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndb_top.1 b/man/ndb_top.1
index f6f90b8c7b91..a85b173ea31d 100644
--- a/man/ndb_top.1
+++ b/man/ndb_top.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_top\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_TOP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_TOP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -135,7 +135,7 @@ The following table includes all options that are specific to the NDB Cluster pr
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.338.\ \&Command\-line options for the ndb_top program
+.B Table\ \&21.353.\ \&Command\-line options for the ndb_top program
.TS
allbox tab(:);
lB lB lB.
@@ -388,7 +388,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -438,7 +438,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -490,7 +490,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -538,7 +538,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -586,7 +586,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -636,7 +636,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -684,7 +684,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -740,7 +740,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -792,7 +792,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -846,7 +846,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -901,7 +901,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -949,7 +949,7 @@ T}
T{
\fBType\fR
T}:T{
-path name
+Path name
T}
T{
\fBDefault Value\fR
@@ -999,7 +999,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1051,7 +1051,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1107,7 +1107,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1129,7 +1129,7 @@ data node under a moderate load\&. Here, the program has been invoked using
\fB\-x\fR
to provide both text and graph output:
.PP
-\fBFigure\ \&21.17.\ \&ndb_top Running in Terminal\fR
+\fBFigure\ \&21.37.\ \&ndb_top Running in Terminal\fR
.sp
.RS 4
[IMAGE]\&\s-2\u[1]\d\s+2
diff --git a/man/ndb_waiter.1 b/man/ndb_waiter.1
index 2e10b1b0bba7..642f2898d333 100644
--- a/man/ndb_waiter.1
+++ b/man/ndb_waiter.1
@@ -2,12 +2,12 @@
.\" Title: \fBndb_waiter\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDB_WAITER\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDB_WAITER\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -141,7 +141,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.339.\ \&Command\-line options for the ndb_waiter program
+.B Table\ \&21.354.\ \&Command\-line options for the ndb_waiter program
.TS
allbox tab(:);
lB lB lB.
diff --git a/man/ndbd.8 b/man/ndbd.8
index 30ee3c6cabc9..45bfe9d3cd9d 100644
--- a/man/ndbd.8
+++ b/man/ndbd.8
@@ -2,12 +2,12 @@
.\" Title: \fBndbd\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDBD\FR" "8" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDBD\FR" "8" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -50,7 +50,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.314.\ \&Command\-line options for the ndbd program
+.B Table\ \&21.329.\ \&Command\-line options for the ndbd program
.TS
allbox tab(:);
lB lB lB.
@@ -282,7 +282,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -332,7 +332,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -391,7 +391,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -446,7 +446,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -504,7 +504,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -557,7 +557,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -610,7 +610,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -775,7 +775,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -859,7 +859,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -934,7 +934,7 @@ T}
T{
\fBType\fR
T}:T{
-integer
+Integer
T}
T{
\fBDefault Value\fR
@@ -985,7 +985,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1039,7 +1039,7 @@ T}
T{
\fBType\fR
T}:T{
-boolean
+Boolean
T}
T{
\fBDefault Value\fR
@@ -1087,7 +1087,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
@@ -1147,7 +1147,7 @@ T}
T{
\fBType\fR
T}:T{
-string
+String
T}
T{
\fBDefault Value\fR
diff --git a/man/ndbinfo_select_all.1 b/man/ndbinfo_select_all.1
index bce026e57cf6..f1f563bc43b9 100644
--- a/man/ndbinfo_select_all.1
+++ b/man/ndbinfo_select_all.1
@@ -2,12 +2,12 @@
.\" Title: \fBndbinfo_select_all\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDBINFO_SELECT_ALL\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDBINFO_SELECT_ALL\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -114,7 +114,7 @@ Options Common to NDB Cluster Programs(1)\&.
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B Table\ \&21.315.\ \&Command\-line options for the ndbinfo_select_all program
+.B Table\ \&21.330.\ \&Command\-line options for the ndbinfo_select_all program
.TS
allbox tab(:);
lB lB lB.
@@ -206,7 +206,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
@@ -262,7 +262,7 @@ T}
T{
\fBType\fR
T}:T{
-numeric
+Numeric
T}
T{
\fBDefault Value\fR
diff --git a/man/ndbmtd.8 b/man/ndbmtd.8
index edf18456321e..baef5d4ef68d 100644
--- a/man/ndbmtd.8
+++ b/man/ndbmtd.8
@@ -2,12 +2,12 @@
.\" Title: \fBndbmtd\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBNDBMTD\FR" "8" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBNDBMTD\FR" "8" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/perror.1 b/man/perror.1
index aa026b2ab559..4d5587daa7d2 100644
--- a/man/perror.1
+++ b/man/perror.1
@@ -2,12 +2,12 @@
.\" Title: \fBperror\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBPERROR\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBPERROR\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/replace.1 b/man/replace.1
index 7734c79ef898..41814d79adaf 100644
--- a/man/replace.1
+++ b/man/replace.1
@@ -2,12 +2,12 @@
.\" Title: \fBreplace\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBREPLACE\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBREPLACE\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/resolve_stack_dump.1 b/man/resolve_stack_dump.1
index 685639ea94a4..c89d1b000c0d 100644
--- a/man/resolve_stack_dump.1
+++ b/man/resolve_stack_dump.1
@@ -2,12 +2,12 @@
.\" Title: \fBresolve_stack_dump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBRESOLVE_STACK_DUMP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBRESOLVE_STACK_DUMP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/resolveip.1 b/man/resolveip.1
index cc0b5aefa7ce..639dae3975be 100644
--- a/man/resolveip.1
+++ b/man/resolveip.1
@@ -2,12 +2,12 @@
.\" Title: \fBresolveip\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBRESOLVEIP\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBRESOLVEIP\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/man/zlib_decompress.1 b/man/zlib_decompress.1
index e1e851ef92c9..019f659888ed 100644
--- a/man/zlib_decompress.1
+++ b/man/zlib_decompress.1
@@ -2,12 +2,12 @@
.\" Title: \fBzlib_decompress\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 06/07/2018
+.\" Date: 10/03/2018
.\" Manual: MySQL Database System
.\" Source: MySQL 5.7
.\" Language: English
.\"
-.TH "\FBZLIB_DECOMPRESS\FR" "1" "06/07/2018" "MySQL 5\&.7" "MySQL Database System"
+.TH "\FBZLIB_DECOMPRESS\FR" "1" "10/03/2018" "MySQL 5\&.7" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/mysql-test/collections/mysql-5.7-stage.push b/mysql-test/collections/mysql-5.7-stage.push
index c359b47e1755..18efb8ab72ac 100644
--- a/mysql-test/collections/mysql-5.7-stage.push
+++ b/mysql-test/collections/mysql-5.7-stage.push
@@ -44,3 +44,5 @@ perl mysql-test-run.pl --debug-server --timer --force --parallel=auto --comment=
perl mysql-test-run.pl --debug-server --timer --force --parallel=auto --comment=x --vardir=var-x --suite=x --experimental=collections/default.experimental
# cross_plugin_test
perl mysql-test-run.pl --debug-server --timer --force --parallel=auto --comment=cross_plugin_test --vardir=var-cross_plugin_test --suite=cross_plugin_test --experimental=collections/default.experimental
+# audit_log
+perl mysql-test-run.pl --debug-server --timer --force --parallel=auto --comment=audit_log --vardir=var-audit_log --suite=audit_log --experimental=collections/default.experimental --force-restart
diff --git a/mysql-test/extra/rpl_tests/rpl_multi_source_corrupt_repository.inc b/mysql-test/extra/rpl_tests/rpl_multi_source_corrupt_repository.inc
index 28275306547a..a9d7c33335bd 100644
--- a/mysql-test/extra/rpl_tests/rpl_multi_source_corrupt_repository.inc
+++ b/mysql-test/extra/rpl_tests/rpl_multi_source_corrupt_repository.inc
@@ -304,8 +304,25 @@ while ($i <= $number_of_channels)
#############################################################################
--echo ===== Executing SHOW SLAVE FOR CHANNEL on channel '$channel_name'.
+
--let $status_items=Slave_IO_State,Slave_SQL_Running_State,Last_IO_Errno,Last_IO_Error,Last_SQL_Errno,Last_SQL_Error,Channel_Name
--let $rpl_channel_name=$channel_name
+
+ if ($channel_name != $rpl_corrupt_channel_name)
+ {
+ --let $slave_timeout= 60
+
+ --let $slave_param= Slave_IO_State
+ --let $slave_param_value= Waiting for master to send event
+ --source include/wait_for_slave_param.inc
+
+ --let $slave_param= Slave_SQL_Running_State
+ --let $slave_param_value= Slave has read all relay log; waiting for more updates
+ --source include/wait_for_slave_param.inc
+
+ --let $status_items=Last_IO_Errno,Last_IO_Error,Last_SQL_Errno,Last_SQL_Error,Channel_Name
+ }
+
--source include/show_slave_status.inc
#############################################################################
diff --git a/mysql-test/extra/rpl_tests/rpl_perfschema_order_by.test b/mysql-test/extra/rpl_tests/rpl_perfschema_order_by.test
new file mode 100644
index 000000000000..9f3977e1e1f1
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_perfschema_order_by.test
@@ -0,0 +1,91 @@
+# The test file is invoked from rpl.rpl_perfschema_order_by.test
+#
+# === References ===
+# Bug #22958077: ORDER BY LAST_SEEN_TRANSACTION RESULTS IN EMPTY SET (OR DEBUG
+# ASSERTION)
+
+--echo # 1) Create a database on server_1.
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+CREATE DATABASE db1;
+
+--echo # 2) create database on server_3.
+--let $rpl_connection_name= server_3
+--source include/rpl_connection.inc
+CREATE DATABASE db3;
+
+--echo # 3) sync the slave (server_2) with both masters (server_1 and server_3).
+#sync the slave with server_1
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+
+--let $rpl_channel_name= channel_1
+--let $sync_slave_connection= server_2
+--source include/sync_slave_sql_with_master.inc
+
+# sync the slave with server_3
+--let $rpl_connection_name= server_3
+--source include/rpl_connection.inc
+
+--let $rpl_channel_name= channel_3
+--let $sync_slave_connection=server_2
+--source include/sync_slave_sql_with_master.inc
+
+# Restart slave for channel_3 so that SELECT returns unsorted data.
+--let $rpl_channel_name= channel_3
+--source include/stop_slave.inc
+--source include/start_slave.inc
+
+--echo
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_configuration;
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_configuration ORDER BY CHANNEL_NAME;
+
+--echo
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_status;
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_status ORDER BY CHANNEL_NAME;
+
+--echo
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_connection_status;
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_connection_status ORDER BY CHANNEL_NAME;
+
+--echo
+SELECT CHANNEL_NAME, TLS_VERSION FROM performance_schema.replication_connection_configuration;
+SELECT CHANNEL_NAME, TLS_VERSION FROM performance_schema.replication_connection_configuration ORDER BY CHANNEL_NAME;
+
+--let $is_mts= `SELECT @@global.slave_parallel_workers`
+if ($is_mts)
+{
+ --echo
+ SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_coordinator;
+ SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_coordinator ORDER BY CHANNEL_NAME;
+}
+
+--echo
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_worker;
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_worker ORDER BY CHANNEL_NAME;
+--echo
+
+# Cleanup
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+DROP DATABASE db1;
+
+--let $rpl_connection_name= server_3
+--source include/rpl_connection.inc
+DROP DATABASE db3;
+
+#sync the slave with server_1
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+
+--let $rpl_channel_name= channel_1
+--let $sync_slave_connection= server_2
+--source include/sync_slave_sql_with_master.inc
+
+# sync the slave with server_3
+--let $rpl_connection_name= server_3
+--source include/rpl_connection.inc
+
+--let $rpl_channel_name= channel_3
+--let $sync_slave_connection=server_2
+--source include/sync_slave_sql_with_master.inc
diff --git a/mysql-test/include/explain_non_select.inc b/mysql-test/include/explain_non_select.inc
index 0e6996b7470a..e5a8c65b0e01 100644
--- a/mysql-test/include/explain_non_select.inc
+++ b/mysql-test/include/explain_non_select.inc
@@ -640,7 +640,6 @@ CREATE TABLE t1 ( a INT, KEY( a ) );
INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
---error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
UPDATE IGNORE v1 SET a = 1;
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index b0de11dccc65..f56ba4c7dbee 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -1,4 +1,4 @@
--- Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+-- Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
--
-- 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
@@ -293,6 +293,11 @@ INSERT INTO global_suppressions VALUES
("Member with address .* is reachable again."),
("The member has resumed contact with a majority of the members in the group.*"),
("Members removed from the group.*"),
+ /*
+ Missing Private/Public key files
+ */
+ ("RSA private key file not found"),
+ ("RSA public key file not found"),
("THE_LAST_SUPPRESSION")||
diff --git a/mysql-test/include/uninstall_semisync_master.inc b/mysql-test/include/uninstall_semisync_master.inc
index 2ececc4ac49e..ffd0adf82309 100644
--- a/mysql-test/include/uninstall_semisync_master.inc
+++ b/mysql-test/include/uninstall_semisync_master.inc
@@ -7,6 +7,13 @@
--disable_query_log
--disable_warnings
+
+# wait till semisync clients are '0' before uninstalling
+# semisync master plugin.
+--let $status_var= Rpl_semi_sync_master_clients
+--let $status_var_value= 0
+--source include/wait_for_status_var.inc
+
UNINSTALL PLUGIN rpl_semi_sync_master;
--source include/end_include_file.inc
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index a239b0bdd538..306529ba1481 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -32,7 +32,7 @@ our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line
use mtr_match;
use File::Spec;
use My::Platform;
-use POSIX qw[ _exit ];
+use POSIX qw(_exit floor);
use IO::Handle qw[ flush ];
require "mtr_io.pl";
use mtr_results;
@@ -40,6 +40,7 @@ use mtr_results;
my $tot_real_time= 0;
my $done_percentage= 0;
+my $tests_completed= 0;
our $timestamp= 0;
our $timediff= 0;
@@ -67,9 +68,11 @@ sub _name {
return $name ? $name." " : undef;
}
-sub _mtr_report_test_name ($)
+sub _mtr_report_test_name ($$)
{
my $tinfo= shift;
+ my $done_percentage= shift;
+
my $tname= $tinfo->{name};
return unless defined $verbose;
@@ -141,13 +144,13 @@ sub mtr_report_test ($) {
{
if ($tinfo->{'name'} && !$retry)
{
- $::remaining= $::remaining - 1;
- $done_percentage = 100 - int (($::remaining * 100) /
- ($::num_tests_for_report));
+ $tests_completed= $tests_completed + 1;
+ $done_percentage=
+ floor(($tests_completed / $::num_tests_for_report) * 100);
}
}
- my $test_name = _mtr_report_test_name($tinfo);
+ my $test_name = _mtr_report_test_name($tinfo, $done_percentage);
if ($result eq 'MTR_RES_FAILED'){
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 8cbca7ed8649..ae82108f7b44 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -78,6 +78,7 @@ BEGIN
use lib "lib";
use Cwd;
+use Cwd 'abs_path';
use Getopt::Long;
use My::File::Path; # Patched version of File::Path
use File::Basename;
@@ -137,7 +138,6 @@ BEGIN
my $start_only;
our $num_tests_for_report; # for test-progress option
-our $remaining;
my $auth_plugin; # the path to the authentication test plugin
@@ -295,7 +295,7 @@ END
our $opt_check_testcases= 1;
my $opt_mark_progress;
-our $opt_test_progress;
+our $opt_test_progress= 1;
my $opt_max_connections;
our $opt_report_times= 0;
@@ -449,9 +449,7 @@ sub main {
#######################################################################
my $num_tests= @$tests;
-
$num_tests_for_report = $num_tests * $opt_repeat;
- $remaining= $num_tests_for_report;
if ( $opt_parallel eq "auto" ) {
# Try to find a suitable value for number of workers
@@ -1189,7 +1187,7 @@ sub command_line_setup {
'record' => \$opt_record,
'check-testcases!' => \$opt_check_testcases,
'mark-progress' => \$opt_mark_progress,
- 'test-progress' => \$opt_test_progress,
+ 'test-progress:1' => \$opt_test_progress,
# Extra options used when starting mysqld
'mysqld=s' => \@opt_extra_mysqld_opt,
@@ -1472,6 +1470,10 @@ sub command_line_setup {
}
}
+ if ($opt_test_progress != 0 and $opt_test_progress != 1) {
+ mtr_error("Invalid value '$opt_test_progress' for option 'test-progress'.");
+ }
+
# disable syslog / EventLog in normal (non-bootstrap) operation.
push(@opt_extra_mysqld_opt, "--log-syslog=0");
@@ -2407,6 +2409,7 @@ ()
my $exe;
# mysql_client_test executable may _not_ exist
$exe= mtr_exe_maybe_exists(vs_config_dirs('testclients', 'mysql_client_test'),
+ "$path_client_bindir/mysql_client_test",
"$basedir/testclients/mysql_client_test",
"$basedir/bin/mysql_client_test");
return "" unless $exe;
@@ -2671,14 +2674,14 @@ sub environment_setup {
if (IS_WINDOWS)
{
$ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."\\std_data";
- $ENV{'MYSQL_TEST_LOGIN_FILE'}=
- $opt_tmpdir . "\\.mylogin.cnf";
+ $ENV{'MYSQL_TEST_LOGIN_FILE'}= $opt_tmpdir . "\\.mylogin.cnf";
+ $ENV{'MYSQLTEST_VARDIR_ABS'}= $opt_vardir;
}
else
{
$ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."/std_data";
- $ENV{'MYSQL_TEST_LOGIN_FILE'}=
- $opt_tmpdir . "/.mylogin.cnf";
+ $ENV{'MYSQL_TEST_LOGIN_FILE'}= $opt_tmpdir . "/.mylogin.cnf";
+ $ENV{'MYSQLTEST_VARDIR_ABS'}= abs_path("$opt_vardir");
}
@@ -4122,6 +4125,10 @@ sub mysql_install_db {
mtr_tofile($bootstrap_sql_file,
sql_to_bootstrap(mtr_grab_file("include/mtr_check.sql")));
+ # Create directories mysql and test
+ mkpath("$install_datadir/mysql");
+ mkpath("$install_datadir/test");
+
if ( $opt_manual_boot_gdb )
{
# The configuration has been set up and user has been prompted for
@@ -4137,10 +4144,6 @@ sub mysql_install_db {
mtr_tofile($path_bootstrap_log,
"$exe_mysqld_bootstrap " . join(" ", @$args) . "\n");
- # Create directories mysql and test
- mkpath("$install_datadir/mysql");
- mkpath("$install_datadir/test");
-
if ( My::SafeProcess->run
(
name => "bootstrap",
@@ -7439,7 +7442,8 @@ ($)
record TESTNAME (Re)genereate the result file for TESTNAME
check-testcases Check testcases for sideeffects
mark-progress Log line number and elapsed time to .progress
- test-progress Print the percentage of tests completed
+ test-progress[={0|1}] Print the percentage of tests completed. This setting
+ is enabled by default.
Options that pass on options (these may be repeated)
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 459ded4ae553..c9471b812560 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -3786,3 +3786,56 @@ ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used le
DROP TABLE t1, t2;
SET sql_mode= @orig_sql_mode;
SET GLOBAL innodb_large_prefix= @orig_innodb_large_prefix;
+#
+# BUG#27788685: NO WARNING WHEN TRUNCATING A STRING WITH DATA LOSS
+#
+SET GLOBAL max_allowed_packet=17825792;
+CREATE TABLE t1 (t1_fld1 TEXT) ENGINE=InnoDB;
+CREATE TABLE t2 (t2_fld1 MEDIUMTEXT) ENGINE=InnoDB;
+CREATE TABLE t3 (t3_fld1 LONGTEXT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (REPEAT('a',300));
+INSERT INTO t2 VALUES (REPEAT('b',65680));
+INSERT INTO t3 VALUES (REPEAT('c',16777300));
+SELECT LENGTH(t1_fld1) FROM t1;
+LENGTH(t1_fld1)
+300
+SELECT LENGTH(t2_fld1) FROM t2;
+LENGTH(t2_fld1)
+65680
+SELECT LENGTH(t3_fld1) FROM t3;
+LENGTH(t3_fld1)
+16777300
+# With strict mode
+SET SQL_MODE='STRICT_ALL_TABLES';
+Warnings:
+Warning 3135 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
+Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
+ALTER TABLE t1 CHANGE `t1_fld1` `my_t1_fld1` TINYTEXT;
+ERROR 22001: Data too long for column 'my_t1_fld1' at row 1
+ALTER TABLE t2 CHANGE `t2_fld1` `my_t2_fld1` TEXT;
+ERROR 22001: Data too long for column 'my_t2_fld1' at row 1
+ALTER TABLE t3 CHANGE `t3_fld1` `my_t3_fld1` MEDIUMTEXT;
+ERROR 22001: Data too long for column 'my_t3_fld1' at row 1
+# With non-strict mode
+SET SQL_MODE='';
+ALTER TABLE t1 CHANGE `t1_fld1` `my_t1_fld1` TINYTEXT;
+Warnings:
+Warning 1265 Data truncated for column 'my_t1_fld1' at row 1
+ALTER TABLE t2 CHANGE `t2_fld1` `my_t2_fld1` TEXT;
+Warnings:
+Warning 1265 Data truncated for column 'my_t2_fld1' at row 1
+ALTER TABLE t3 CHANGE `t3_fld1` `my_t3_fld1` MEDIUMTEXT;
+Warnings:
+Warning 1265 Data truncated for column 'my_t3_fld1' at row 1
+SELECT LENGTH(my_t1_fld1) FROM t1;
+LENGTH(my_t1_fld1)
+44
+SELECT LENGTH(my_t2_fld1) FROM t2;
+LENGTH(my_t2_fld1)
+144
+SELECT LENGTH(my_t3_fld1) FROM t3;
+LENGTH(my_t3_fld1)
+84
+DROP TABLE t1, t2, t3;
+SET SQL_MODE=default;
+SET GLOBAL max_allowed_packet=default;
diff --git a/mysql-test/r/bug83739.result b/mysql-test/r/bug83739.result
new file mode 100644
index 000000000000..b9544ebd8676
--- /dev/null
+++ b/mysql-test/r/bug83739.result
@@ -0,0 +1,20 @@
+#
+# Bug #25062396 / #83739 "Assertion `cur_shape != Gcalc_function::shape_point' failed"
+# fixed in 5.6.39, 5.7.21, 8.0.4
+# For geometry calculations, invalid input parameters could lead to an
+# incorrect result buffer and cause an assertion to be raised or a
+# server exit
+#
+SELECT ST_ASTEXT(
+ST_DIFFERENCE(
+ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(' 'POINT(-5 -4),' 'POLYGON((-5 1,7 -7,10 0,-10 8,-7 9,-5 1)))'),
+ST_GEOMFROMTEXT('LINESTRING(5 3,7 -3,5 0,-6 -9,-4 9,-3 -8,10 1,10 -9,5 -3,4 -2,1 -3,-8 -5,4 -7,-2 -8)')
+)
+);
+ST_ASTEXT(
+ST_DIFFERENCE(
+ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(' 'POINT(-5 -4),' 'POLYGON((-5 1,7 -7,10 0,-10 8,-7 9,-5 1)))'),
+ST_GEOMFROMTEXT('LINESTRING(5 3,7 -3,5 0,-6 -9,-4 9,-3 -8,10 1,10 -9,5 -3,4 -2,1 -3,-8 -5,4 -7,-2 -8)')
+)
+)
+GEOMETRYCOLLECTION(POINT(-5 -4),POLYGON((-5 1,-7 9,-10 8,10 0,7 -7,-5 1)))
diff --git a/mysql-test/r/bug88781.result b/mysql-test/r/bug88781.result
new file mode 100644
index 000000000000..5841530bef7f
--- /dev/null
+++ b/mysql-test/r/bug88781.result
@@ -0,0 +1,14 @@
+#
+# Bug #26881798 / #88781 "handle_fatal_signal (sig=11) in replace_db_table"
+# fixed in 5.5.60, 5.6.40, 5.7.22, 8.0.4
+# Dropping an index from a system table could cause a server exit
+#
+CALL mtr.add_suppression("Did not write failed 'GRANT DROP ON none\\.\\* TO 'bug88781'@'localhost'' into binary log while granting/revoking privileges in databases\\.");
+CREATE USER 'bug88781'@'localhost';
+RENAME TABLE mysql.db TO mysql.bak;
+CREATE TABLE mysql.db ENGINE=MyISAM SELECT * FROM mysql.bak;
+GRANT DROP ON none.* TO 'bug88781'@'localhost';
+ERROR HY000: The table 'mysql.db' does not have the necessary key(s) defined on it. Please check the table definition and create index(s) accordingly.
+DROP TABLE mysql.db;
+RENAME TABLE mysql.bak TO mysql.db;
+DROP USER 'bug88781'@'localhost';
diff --git a/mysql-test/r/bug88800.result b/mysql-test/r/bug88800.result
new file mode 100644
index 000000000000..4e3dc30c0267
--- /dev/null
+++ b/mysql-test/r/bug88800.result
@@ -0,0 +1,34 @@
+#
+# Bug #27230925 / #88800 "handle_fatal_signal (sig=11) in show_routine_grants"
+# fixed in 5.5.61, 5.6.41, 5.7.23, 8.0.12
+# Mishandling of internal privilege structures could cause a server exit
+#
+CREATE TABLE t1 (
+id INT UNSIGNED AUTO_INCREMENT,
+name CHAR(50),
+PRIMARY KEY (id)
+);
+CREATE PROCEDURE p1() BEGIN END;
+CREATE USER 'bug88800'@'localhost';
+GRANT ALL ON test.* TO 'bug88800'@'localhost';
+GRANT EXECUTE ON PROCEDURE test.p1 TO 'bug88800'@'localhost' WITH GRANT OPTION;
+RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
+FLUSH PRIVILEGES;
+ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
+SHOW GRANTS FOR 'bug88800'@'localhost';
+Grants for bug88800@localhost
+GRANT USAGE ON *.* TO 'bug88800'@'localhost'
+GRANT ALL PRIVILEGES ON `test`.* TO 'bug88800'@'localhost'
+GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'bug88800'@'localhost' WITH GRANT OPTION
+FLUSH PRIVILEGES;
+ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
+SHOW GRANTS FOR 'bug88800'@'localhost';
+Grants for bug88800@localhost
+GRANT USAGE ON *.* TO 'bug88800'@'localhost'
+GRANT ALL PRIVILEGES ON `test`.* TO 'bug88800'@'localhost'
+GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'bug88800'@'localhost' WITH GRANT OPTION
+RENAME TABLE mysql.procs_gone TO mysql.procs_priv;
+DROP USER 'bug88800'@'localhost';
+DROP PROCEDURE p1;
+DROP TABLE t1;
+CALL mtr.add_suppression("Fatal error: Can't open and lock privilege tables: Table 'mysql.procs_priv' doesn't exist");
diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result
index f0ce15577b6c..32524e5bd3c7 100644
--- a/mysql-test/r/connect.result
+++ b/mysql-test/r/connect.result
@@ -345,4 +345,30 @@ DROP USER wl6587@localhost;
# ------------------------------------------------------------------
# -- End of 5.6 tests
# ------------------------------------------------------------------
+#
+# BUG#27539838: NOT ALL ABORTED CONNECTS ARE REPORTED TO ERROR.LOG
+# PROPERLY
+#
+# restart: --log-error=LOG_ERR --log-error-verbosity=3
+SHOW STATUS LIKE 'Aborted_connects';
+Variable_name Value
+Aborted_connects 0
+
+# Case 1: Connection attempt by an invalid user
+connect(localhost,newuser,,test,MASTER_PORT,MASTER_SOCKET);
+ERROR 28000: Access denied for user 'newuser'@'localhost' (using password: NO)
+
+# Case 2: Connection attempt by a valid user with incorrect password
+connect(localhost,root,1234,test,MASTER_PORT,MASTER_SOCKET);
+ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES)
+CREATE DATABASE test1;
+CREATE USER 'new1'@'localhost';
+
+# Case 3: Connection attempt by a valid user with no privileges to access a database
+connect(localhost,new1,,test1,MASTER_PORT,MASTER_SOCKET);
+ERROR 42000: Access denied for user 'new1'@'localhost' to database 'test1'
+
+# Case 4: SSL connection attempt without necessary certificates
+DROP USER 'new1'@'localhost';
+DROP DATABASE test1;
set global log_error_verbosity= STARTVAL;
diff --git a/mysql-test/r/ddl_i18n_koi8r.result b/mysql-test/r/ddl_i18n_koi8r.result
index 75df3c616bd1..3542bcfa0b72 100644
--- a/mysql-test/r/ddl_i18n_koi8r.result
+++ b/mysql-test/r/ddl_i18n_koi8r.result
@@ -732,7 +732,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
INOUT �����1 CHAR(10),
@@ -766,7 +766,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
INOUT �����1 CHAR(10) CHARACTER SET utf8,
@@ -808,7 +808,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
INOUT �����1 CHAR(10),
@@ -842,7 +842,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
INOUT �����1 CHAR(10) CHARACTER SET utf8,
@@ -908,7 +908,7 @@ set names koi8r|
SHOW CREATE PROCEDURE p1|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
+p1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
INOUT �����1 CHAR(10),
OUT �����2 CHAR(10))
BEGIN
@@ -929,7 +929,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci
SHOW CREATE PROCEDURE p2|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
+p2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
INOUT �����1 CHAR(10) CHARACTER SET utf8,
OUT �����2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -950,7 +950,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci
SHOW CREATE PROCEDURE mysqltest2.p3|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
+p3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
INOUT �����1 CHAR(10),
OUT �����2 CHAR(10))
BEGIN
@@ -971,7 +971,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci
SHOW CREATE PROCEDURE mysqltest2.p4|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
+p4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
INOUT �����1 CHAR(10) CHARACTER SET utf8,
OUT �����2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -1024,7 +1024,7 @@ COLLATION( '
@@character_set_client AS c8;
SET �����1 = 'a';
SET �����2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_name = 'p2'|
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -1042,7 +1042,7 @@ COLLATION( '
@@character_set_client AS c8;
SET �����1 = 'a';
SET �����2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_name = 'p3'|
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -1060,7 +1060,7 @@ COLLATION( '
@@character_set_client AS c8;
SET �����1 = 'a';
SET �����2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_name = 'p4'|
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -1078,7 +1078,7 @@ COLLATION( '
@@character_set_client AS c8;
SET �����1 = 'a';
SET �����2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SET @a = '1'|
@@ -1750,7 +1750,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
@@ -1779,7 +1779,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
BEGIN
@@ -1829,7 +1829,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
@@ -1858,7 +1858,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
@@ -1908,7 +1908,7 @@ use mysqltest1|
SHOW CREATE TRIGGER trg1|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+trg1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE �����1 CHAR(10);
INSERT INTO log VALUES(COLLATION(�����1));
@@ -1924,7 +1924,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci CREATED
SHOW CREATE TRIGGER trg2|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
+trg2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(�����1));
@@ -1940,7 +1940,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci CREATED
SHOW CREATE TRIGGER mysqltest2.trg3|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW
+trg3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
DECLARE �����1 CHAR(10);
INSERT INTO log VALUES(COLLATION(�����1));
@@ -1956,7 +1956,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci CREATED
SHOW CREATE TRIGGER mysqltest2.trg4|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW
+trg4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(�����1));
@@ -1984,7 +1984,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = '�����';
SET @a1 = '�����';
SET @a2 = '�����';
-END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
trg2 INSERT t1 BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(�����1));
@@ -1996,7 +1996,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = '�����';
SET @b1 = '�����';
SET @b2 = '�����';
-END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
use mysqltest2|
@@ -2013,7 +2013,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = '�����';
SET @a1 = '�����';
SET @a2 = '�����';
-END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
trg4 INSERT t1 BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(�����1));
@@ -2025,7 +2025,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = '�����';
SET @b1 = '�����';
SET @b2 = '�����';
-END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
use mysqltest1|
@@ -2042,7 +2042,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = '�����';
SET @a1 = '�����';
SET @a2 = '�����';
-END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2057,7 +2057,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = '�����';
SET @b1 = '�����';
SET @b2 = '�����';
-END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2072,7 +2072,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = '�����';
SET @a1 = '�����';
SET @a2 = '�����';
-END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2087,7 +2087,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = '�����';
SET @b1 = '�����';
SET @b2 = '�����';
-END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
+END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost koi8r koi8r_general_ci utf8_unicode_ci
SET @a1 = '1'|
@@ -2494,7 +2494,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2522,7 +2522,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev2` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2561,7 +2561,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2589,7 +2589,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev4` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2634,7 +2634,7 @@ set names koi8r|
SHOW CREATE EVENT ev1|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE �����1 CHAR(10);
SELECT
COLLATION(�����1) AS c1,
@@ -2647,7 +2647,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci
SHOW CREATE EVENT ev2|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev2` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev2` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
SELECT
COLLATION(�����1) AS c1,
@@ -2660,7 +2660,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci
SHOW CREATE EVENT mysqltest2.ev3|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
SELECT
COLLATION(�����1) AS c1,
@@ -2673,7 +2673,7 @@ END koi8r koi8r_general_ci utf8_unicode_ci
SHOW CREATE EVENT mysqltest2.ev3|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE �����1 CHAR(10) CHARACTER SET utf8;
SELECT
COLLATION(�����1) AS c1,
@@ -2711,7 +2711,7 @@ COLLATION( '
COLLATION( '�����') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev2'|
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2724,7 +2724,7 @@ COLLATION( '
COLLATION( '�����') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev3'|
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2737,7 +2737,7 @@ COLLATION( '
COLLATION( '�����') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev4'|
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2750,7 +2750,7 @@ COLLATION( '
COLLATION( '�����') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8_unicode_ci
-------------------------------------------------------------------
DDL statements within stored routine.
diff --git a/mysql-test/r/ddl_i18n_utf8.result b/mysql-test/r/ddl_i18n_utf8.result
index de715deacf7c..f8bc7df140cf 100644
--- a/mysql-test/r/ddl_i18n_utf8.result
+++ b/mysql-test/r/ddl_i18n_utf8.result
@@ -732,7 +732,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
INOUT парам1 CHAR(10),
@@ -766,7 +766,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
INOUT парам1 CHAR(10) CHARACTER SET utf8,
@@ -808,7 +808,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
INOUT парам1 CHAR(10),
@@ -842,7 +842,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
INOUT парам1 CHAR(10) CHARACTER SET utf8,
@@ -908,7 +908,7 @@ set names utf8|
SHOW CREATE PROCEDURE p1|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
+p1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
INOUT парам1 CHAR(10),
OUT парам2 CHAR(10))
BEGIN
@@ -929,7 +929,7 @@ END utf8 utf8_general_ci utf8_unicode_ci
SHOW CREATE PROCEDURE p2|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
+p2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
INOUT парам1 CHAR(10) CHARACTER SET utf8,
OUT парам2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -950,7 +950,7 @@ END utf8 utf8_general_ci utf8_unicode_ci
SHOW CREATE PROCEDURE mysqltest2.p3|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
+p3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
INOUT парам1 CHAR(10),
OUT парам2 CHAR(10))
BEGIN
@@ -971,7 +971,7 @@ END utf8 utf8_general_ci utf8_unicode_ci
SHOW CREATE PROCEDURE mysqltest2.p4|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
-p4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
+p4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
INOUT парам1 CHAR(10) CHARACTER SET utf8,
OUT парам2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -1024,7 +1024,7 @@ COLLATION( 'текст') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_name = 'p2'|
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -1042,7 +1042,7 @@ COLLATION( 'текст') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_name = 'p3'|
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -1060,7 +1060,7 @@ COLLATION( 'текст') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_name = 'p4'|
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -1078,7 +1078,7 @@ COLLATION( 'текст') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END NULL NULL SQL NO CONTAINS SQL NULL DEFINER CREATED ALTERED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SET @a = '1'|
@@ -1750,7 +1750,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
@@ -1779,7 +1779,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
BEGIN
@@ -1829,7 +1829,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
@@ -1858,7 +1858,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
@@ -1908,7 +1908,7 @@ use mysqltest1|
SHOW CREATE TRIGGER trg1|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+trg1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE перем1 CHAR(10);
INSERT INTO log VALUES(COLLATION(перем1));
@@ -1924,7 +1924,7 @@ END utf8 utf8_general_ci utf8_unicode_ci CREATED
SHOW CREATE TRIGGER trg2|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
+trg2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(перем1));
@@ -1940,7 +1940,7 @@ END utf8 utf8_general_ci utf8_unicode_ci CREATED
SHOW CREATE TRIGGER mysqltest2.trg3|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW
+trg3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
DECLARE перем1 CHAR(10);
INSERT INTO log VALUES(COLLATION(перем1));
@@ -1956,7 +1956,7 @@ END utf8 utf8_general_ci utf8_unicode_ci CREATED
SHOW CREATE TRIGGER mysqltest2.trg4|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
-trg4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW
+trg4 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW
BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(перем1));
@@ -1984,7 +1984,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = 'текст';
SET @a2 = 'текст';
SET @a3 = 'текст';
-END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
trg2 INSERT t1 BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(перем1));
@@ -1996,7 +1996,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = 'текст';
SET @b2 = 'текст';
SET @b3 = 'текст';
-END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
use mysqltest2|
@@ -2013,7 +2013,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = 'текст';
SET @a2 = 'текст';
SET @a3 = 'текст';
-END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END BEFORE CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
trg4 INSERT t1 BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
INSERT INTO log VALUES(COLLATION(перем1));
@@ -2025,7 +2025,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = 'текст';
SET @b2 = 'текст';
SET @b3 = 'текст';
-END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END AFTER CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
use mysqltest1|
@@ -2042,7 +2042,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = 'текст';
SET @a2 = 'текст';
SET @a3 = 'текст';
-END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2057,7 +2057,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = 'текст';
SET @b2 = 'текст';
SET @b3 = 'текст';
-END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2072,7 +2072,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @a1 = 'текст';
SET @a2 = 'текст';
SET @a3 = 'текст';
-END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END ROW BEFORE NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2087,7 +2087,7 @@ INSERT INTO log VALUES(@@character_set_client);
SET @b1 = 'текст';
SET @b2 = 'текст';
SET @b3 = 'текст';
-END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
+END ROW AFTER NULL NULL OLD NEW CREATED ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci utf8_unicode_ci
SET @a1 = '1'|
@@ -2494,7 +2494,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = utf8 */ ;;
/*!50003 SET collation_connection = utf8_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2522,7 +2522,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = utf8 */ ;;
/*!50003 SET collation_connection = utf8_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev2` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2561,7 +2561,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = utf8 */ ;;
/*!50003 SET collation_connection = utf8_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2589,7 +2589,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET character_set_results = utf8 */ ;;
/*!50003 SET collation_connection = utf8_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev4` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
@@ -2634,7 +2634,7 @@ set names utf8|
SHOW CREATE EVENT ev1|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev1 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE перем1 CHAR(10);
SELECT
COLLATION(перем1) AS c1,
@@ -2647,7 +2647,7 @@ END utf8 utf8_general_ci utf8_unicode_ci
SHOW CREATE EVENT ev2|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev2` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev2 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev2` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
SELECT
COLLATION(перем1) AS c1,
@@ -2660,7 +2660,7 @@ END utf8 utf8_general_ci utf8_unicode_ci
SHOW CREATE EVENT mysqltest2.ev3|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
SELECT
COLLATION(перем1) AS c1,
@@ -2673,7 +2673,7 @@ END utf8 utf8_general_ci utf8_unicode_ci
SHOW CREATE EVENT mysqltest2.ev3|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
-ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
+ev3 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev3` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
SELECT
COLLATION(перем1) AS c1,
@@ -2711,7 +2711,7 @@ COLLATION( 'текст') AS c3,
COLLATION( 'текст') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev2'|
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2724,7 +2724,7 @@ COLLATION( 'текст') AS c3,
COLLATION( 'текст') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev3'|
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2737,7 +2737,7 @@ COLLATION( 'текст') AS c3,
COLLATION( 'текст') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_name = 'ev4'|
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
@@ -2750,7 +2750,7 @@ COLLATION( 'текст') AS c3,
COLLATION( 'текст') AS c4,
@@collation_connection AS c5,
@@character_set_client AS c6;
-END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
+END ONE TIME 2030-01-01 00:00:00 NULL NULL ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION NULL NULL ENABLED NOT PRESERVE CREATED LAST_ALTERED NULL 1 utf8 utf8_general_ci utf8_unicode_ci
-------------------------------------------------------------------
DDL statements within stored routine.
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index 6e842267ba40..358397bedac8 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -159,8 +159,12 @@ INSERT INTO t1 VALUES(10),(20);
CREATE TABLE t2(b INTEGER);
INSERT INTO t2 VALUES(10),(20);
SET SESSION sql_safe_updates=1;
-DELETE t1 FROM t1 JOIN t2 WHERE t1.a = 10;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+EXPLAIN DELETE t2 FROM t1 JOIN t2 WHERE t1.a = 10;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 DELETE t2 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+DELETE t2 FROM t1 JOIN t2 WHERE t1.a = 10;
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates=default;
DROP TABLE t1, t2;
create table t1 (a int, b int, unique key (a), key (b));
diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
index dcb283481cee..7bc68d52c097 100644
--- a/mysql-test/r/heap_btree.result
+++ b/mysql-test/r/heap_btree.result
@@ -372,3 +372,10 @@ INSERT INTO t1 VALUES(1),(1);
DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a;
DROP TABLE t1;
End of 5.0 tests
+#
+# Bug#27799513: POTENTIAL DOUBLE FREE OR CORRUPTION OF HEAP INFO (HP_INFO)
+#
+CREATE TABLE t1 (id INT, a VARCHAR(300) NOT NULL, KEY USING BTREE(a)) ENGINE=Heap;
+INSERT t1 VALUES (1, REPEAT('a', 300));
+DROP TABLE t1;
+End of 5.5 tests
diff --git a/mysql-test/r/ignore_strict.result b/mysql-test/r/ignore_strict.result
index 3ac496950670..2e81b3fed48d 100644
--- a/mysql-test/r/ignore_strict.result
+++ b/mysql-test/r/ignore_strict.result
@@ -948,6 +948,6 @@ CREATE TABLE t1(a INT);
SET @org_safe_updates= @@sql_safe_updates;
SET SESSION sql_safe_updates=ON;
DELETE IGNORE FROM t1 WHERE a=1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
DROP TABLE t1;
SET sql_safe_updates= @org_safe_updates;
diff --git a/mysql-test/r/innodb_explain_json_non_select_all.result b/mysql-test/r/innodb_explain_json_non_select_all.result
index e00f932a9fa2..ae943260293a 100644
--- a/mysql-test/r/innodb_explain_json_non_select_all.result
+++ b/mysql-test/r/innodb_explain_json_non_select_all.result
@@ -6817,9 +6817,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/innodb_explain_json_non_select_none.result b/mysql-test/r/innodb_explain_json_non_select_none.result
index 1fe1012dc8d6..43ff30a61c7f 100644
--- a/mysql-test/r/innodb_explain_json_non_select_none.result
+++ b/mysql-test/r/innodb_explain_json_non_select_none.result
@@ -6853,9 +6853,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/innodb_explain_non_select_all.result b/mysql-test/r/innodb_explain_non_select_all.result
index 7204763b495b..197bfea97842 100644
--- a/mysql-test/r/innodb_explain_non_select_all.result
+++ b/mysql-test/r/innodb_explain_non_select_all.result
@@ -2658,9 +2658,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/innodb_explain_non_select_none.result b/mysql-test/r/innodb_explain_non_select_none.result
index 1b70a86fa5bc..1c4af517ddcf 100644
--- a/mysql-test/r/innodb_explain_non_select_none.result
+++ b/mysql-test/r/innodb_explain_non_select_none.result
@@ -2660,9 +2660,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/mdl_tablespace.result b/mysql-test/r/mdl_tablespace.result
index 37d422df8fce..47d8b4126037 100644
--- a/mysql-test/r/mdl_tablespace.result
+++ b/mysql-test/r/mdl_tablespace.result
@@ -865,6 +865,8 @@ ENGINE=InnoDB
PARTITION BY RANGE (a)
PARTITIONS 1
(PARTITION P1 VALUES LESS THAN (2) TABLESPACE ts1);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
#############################################
# Case1: Checking TRUNCATE TABLE
# Sending 'TRUNCATE TABLE t1;'
@@ -900,6 +902,8 @@ CREATE TABLE t3 ( a INT NOT NULL, PRIMARY KEY (a)) ENGINE=InnoDB PARTITION BY RA
SET DEBUG_SYNC= 'now WAIT_FOR got_lock';
SET DEBUG_SYNC= 'now SIGNAL cont';
# Reaping 'CREATE TABLE'
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
#############################################
# Case5: Checking CREATE TABLE LIKE
SET DEBUG_SYNC= 'RESET';
@@ -911,6 +915,8 @@ CREATE TABLE t4 LIKE t3;;
SET DEBUG_SYNC= 'now WAIT_FOR got_lock';
SET DEBUG_SYNC= 'now SIGNAL cont';
# Reaping 'CREATE TABLE LIKE'
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
#############################################
# Case6: Checking ALTER TABLE ... PARTITION
CREATE TABLESPACE ts2 ADD DATAFILE 'ts2.ibd';
@@ -923,6 +929,8 @@ ALTER TABLE t2 ADD PARTITION (partition p2 values less than (4) tablespace ts2);
SET DEBUG_SYNC= 'now WAIT_FOR got_lock';
SET DEBUG_SYNC= 'now SIGNAL cont';
# Reaping 'ALTER TABLE'
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
#############################################
# Case7: Checking LOCK TABLE t2 WRITE
SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index 0305fa0b6c84..90cea84e9687 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -182,10 +182,10 @@ drop table t1,t2;
set sql_safe_updates=1;
create table t1 (n int(10), d int(10));
create table t2 (n int(10), d int(10));
-insert into t1 values(1,1);
+insert into t1 values(1,1), (3,30);
insert into t2 values(1,10),(2,20);
UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
set sql_safe_updates=0;
drop table t1,t2;
set timestamp=1038401397;
@@ -667,7 +667,7 @@ INSERT INTO t1 VALUES (1), (2), (3);
SET SESSION sql_safe_updates = 1;
# Must not cause failed assertion
UPDATE IGNORE t1, t1 t1a SET t1.a = 1 WHERE t1a.a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
DROP TABLE t1;
#
# Bug#54543: update ignore with incorrect subquery leads to assertion
diff --git a/mysql-test/r/myisam-blob.result b/mysql-test/r/myisam-blob.result
index a528f54b9862..a7b8dae45a91 100644
--- a/mysql-test/r/myisam-blob.result
+++ b/mysql-test/r/myisam-blob.result
@@ -1,3 +1,6 @@
+SET SQL_MODE='';
+Warnings:
+Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
drop table if exists t1;
CREATE TABLE t1 (data LONGBLOB) ENGINE=myisam;
INSERT INTO t1 (data) VALUES (NULL);
@@ -29,6 +32,8 @@ select length(data) from t1;
length(data)
18874368
alter table t1 modify data blob;
+Warnings:
+Warning 1265 Data truncated for column 'data' at row 1
select length(data) from t1;
length(data)
0
@@ -42,3 +47,4 @@ select length(data) from t1;
length(data)
65535
drop table t1;
+SET SQL_MODE=default;
diff --git a/mysql-test/r/myisam_explain_json_non_select_all.result b/mysql-test/r/myisam_explain_json_non_select_all.result
index 04aba419947e..4400aae2383d 100644
--- a/mysql-test/r/myisam_explain_json_non_select_all.result
+++ b/mysql-test/r/myisam_explain_json_non_select_all.result
@@ -6666,9 +6666,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/myisam_explain_json_non_select_none.result b/mysql-test/r/myisam_explain_json_non_select_none.result
index 0e772769be31..5fbfde50689d 100644
--- a/mysql-test/r/myisam_explain_json_non_select_none.result
+++ b/mysql-test/r/myisam_explain_json_non_select_none.result
@@ -6698,9 +6698,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/myisam_explain_non_select_all.result b/mysql-test/r/myisam_explain_non_select_all.result
index e6d4a055e452..5166122e58c9 100644
--- a/mysql-test/r/myisam_explain_non_select_all.result
+++ b/mysql-test/r/myisam_explain_non_select_all.result
@@ -2541,9 +2541,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/myisam_explain_non_select_none.result b/mysql-test/r/myisam_explain_non_select_none.result
index 10ba4bf98197..128bd290bfa7 100644
--- a/mysql-test/r/myisam_explain_non_select_none.result
+++ b/mysql-test/r/myisam_explain_non_select_none.result
@@ -2539,9 +2539,13 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
EXPLAIN EXTENDED UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t11 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
+1 SIMPLE t12 NULL index NULL a 5 NULL 2 100.00 Using index
+Warnings:
+Warning 1681 'EXTENDED' is deprecated and will be removed in a future release.
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 06d11c46b9fc..287e3017d96f 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2819,7 +2819,7 @@ UNLOCK TABLES;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg1 before insert on t1 for each row
begin
@@ -2840,7 +2840,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg2 before update on t1 for each row begin
if old.a % 2 = 0 then set new.b := 12; end if;
@@ -2857,7 +2857,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg3 after update on t1 for each row
begin
@@ -2889,7 +2889,7 @@ UNLOCK TABLES;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg4 before insert on t2 for each row
begin
@@ -2992,10 +2992,10 @@ if new.a > 10 then
set new.a := 10;
set new.a := 11;
end if;
-end BEFORE # ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
+end BEFORE # ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
trg2 UPDATE t1 begin
if old.a % 2 = 0 then set new.b := 12; end if;
-end BEFORE # ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
+end BEFORE # ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
trg3 UPDATE t1 begin
if new.a = -1 then
set @fired:= "Yes";
@@ -3038,7 +3038,7 @@ a2
SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
testref INSERT test1 BEGIN
-INSERT INTO test2 SET a2 = NEW.a1; END BEFORE # ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
+INSERT INTO test2 SET a2 = NEW.a1; END BEFORE # ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
SELECT * FROM `test1`;
a1
1
@@ -3121,7 +3121,7 @@ UNLOCK TABLES;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
RETURN a+b ;;
@@ -3138,7 +3138,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1
begin
@@ -3175,7 +3175,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
BEGIN SELECT a+b INTO c; end ;;
@@ -3192,7 +3192,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `bug9056_proc2`(OUT a INT)
BEGIN
@@ -4297,7 +4297,7 @@ create procedure mysqldump_test_db.sp1() select 'hello';
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`user1`@`%` PROCEDURE `sp1`()
select 'hello' ;;
@@ -6419,3 +6419,117 @@ master_info_repository FILE
SHOW VARIABLES LIKE "relay_log_info_repository";
Variable_name Value
relay_log_info_repository FILE
+#
+# Bug#27931181: RESTAURE DUMP CREATED WITH 5.7.22 ON 8.0.11
+#
+CREATE DATABASE bug27931181;
+USE bug27931181;
+CREATE TABLE t1 (a INT);
+SET sql_mode='NO_AUTO_CREATE_USER';
+Warnings:
+Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
+CREATE TRIGGER trig1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = 1;
+SET sql_mode='NO_AUTO_CREATE_USER,ONLY_FULL_GROUP_BY';
+CREATE PROCEDURE p1() SELECT 1;
+SET sql_mode=@@global.sql_mode;
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+/*!50717 SELECT COUNT(*) INTO @rocksdb_has_p_s_session_variables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'performance_schema' AND TABLE_NAME = 'session_variables' */;
+/*!50717 SET @rocksdb_get_is_supported = IF (@rocksdb_has_p_s_session_variables, 'SELECT COUNT(*) INTO @rocksdb_is_supported FROM performance_schema.session_variables WHERE VARIABLE_NAME=\'rocksdb_bulk_load\'', 'SELECT 0') */;
+/*!50717 PREPARE s FROM @rocksdb_get_is_supported */;
+/*!50717 EXECUTE s */;
+/*!50717 DEALLOCATE PREPARE s */;
+/*!50717 SET @rocksdb_enable_bulk_load = IF (@rocksdb_is_supported, 'SET SESSION rocksdb_bulk_load = 1', 'SET @rocksdb_dummy_bulk_load = 0') */;
+/*!50717 PREPARE s FROM @rocksdb_enable_bulk_load */;
+/*!50717 EXECUTE s */;
+/*!50717 DEALLOCATE PREPARE s */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `bug27931181` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `bug27931181`;
+DROP TABLE IF EXISTS `t1`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+LOCK TABLES `t1` WRITE;
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!50003 SET @saved_cs_client = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client = latin1 */ ;
+/*!50003 SET character_set_results = latin1 */ ;
+/*!50003 SET collation_connection = latin1_swedish_ci */ ;
+/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
+/*!50003 SET sql_mode = '' */ ;
+DELIMITER ;;
+/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER trig1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = 1 */;;
+DELIMITER ;
+/*!50003 SET sql_mode = @saved_sql_mode */ ;
+/*!50003 SET character_set_client = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection = @saved_col_connection */ ;
+/*!50003 DROP FUNCTION IF EXISTS `f1` */;
+/*!50003 SET @saved_cs_client = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client = latin1 */ ;
+/*!50003 SET character_set_results = latin1 */ ;
+/*!50003 SET collation_connection = latin1_swedish_ci */ ;
+/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
+DELIMITER ;;
+CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+RETURN 1 ;;
+DELIMITER ;
+/*!50003 SET sql_mode = @saved_sql_mode */ ;
+/*!50003 SET character_set_client = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection = @saved_col_connection */ ;
+/*!50003 DROP PROCEDURE IF EXISTS `p1` */;
+/*!50003 SET @saved_cs_client = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client = latin1 */ ;
+/*!50003 SET character_set_results = latin1 */ ;
+/*!50003 SET collation_connection = latin1_swedish_ci */ ;
+/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY' */ ;
+DELIMITER ;;
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SELECT 1 ;;
+DELIMITER ;
+/*!50003 SET sql_mode = @saved_sql_mode */ ;
+/*!50003 SET character_set_client = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection = @saved_col_connection */ ;
+/*!50112 SET @disable_bulk_load = IF (@is_rocksdb_supported, 'SET SESSION rocksdb_bulk_load = @old_rocksdb_bulk_load', 'SET @dummy_rocksdb_bulk_load = 0') */;
+/*!50112 PREPARE s FROM @disable_bulk_load */;
+/*!50112 EXECUTE s */;
+/*!50112 DEALLOCATE PREPARE s */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+DROP DATABASE bug27931181;
diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result
index a120afe62115..e8e6c59b6bc8 100644
--- a/mysql-test/r/mysqlshow.result
+++ b/mysql-test/r/mysqlshow.result
@@ -135,7 +135,7 @@ Database: information_schema
| INNODB_CMPMEM_RESET |
| INNODB_SYS_FIELDS |
| XTRADB_ZIP_DICT |
-| INNODB_CHANGED_PAGES |
+| INNODB_TABLESPACES_SCRUBBING |
| INNODB_TEMP_TABLE_INFO |
| INNODB_FT_INDEX_TABLE |
| INNODB_CMPMEM |
@@ -154,6 +154,7 @@ Database: information_schema
| XTRADB_ZIP_DICT_COLS |
| INNODB_SYS_INDEXES |
| INNODB_SYS_VIRTUAL |
+| INNODB_CHANGED_PAGES |
+---------------------------------------+
Database: INFORMATION_SCHEMA
+---------------------------------------+
@@ -215,7 +216,7 @@ Database: INFORMATION_SCHEMA
| INNODB_CMPMEM_RESET |
| INNODB_SYS_FIELDS |
| XTRADB_ZIP_DICT |
-| INNODB_CHANGED_PAGES |
+| INNODB_TABLESPACES_SCRUBBING |
| INNODB_TEMP_TABLE_INFO |
| INNODB_FT_INDEX_TABLE |
| INNODB_CMPMEM |
@@ -234,6 +235,7 @@ Database: INFORMATION_SCHEMA
| XTRADB_ZIP_DICT_COLS |
| INNODB_SYS_INDEXES |
| INNODB_SYS_VIRTUAL |
+| INNODB_CHANGED_PAGES |
+---------------------------------------+
Wildcard: inf_rmation_schema
+--------------------+
diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result
index 14e6d866e423..807a7fcfe9f8 100644
--- a/mysql-test/r/parser.result
+++ b/mysql-test/r/parser.result
@@ -1233,3 +1233,9 @@ Warnings:
Warning 1287 '..' is deprecated and will be removed in a future release. Please use the table.column name without a dot prefix instead
DROP TABLE t1, t2;
#
+
+Bug #27714748: @@PARSER_MAX_MEM_SIZE DOES NOT WORK FOR ROUTINES
+
+SET parser_max_mem_size = 10000000;
+ERROR HY000: Memory capacity of 10000000 bytes for 'parser_max_mem_size' exceeded. Parser bailed out for this query.
+SET parser_max_mem_size = default;
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 8de9269b2ebd..70ebc3df1212 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -916,7 +916,11 @@ partitions 3
(partition x1 tablespace ts1,
partition x2 tablespace ts2,
partition x3 tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
CREATE TABLE t2 LIKE t1;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -953,6 +957,8 @@ partitions 3
(partition x1 values in (1,2,9,4) tablespace ts1,
partition x2 values in (3, 11, 5, 7) tablespace ts2,
partition x3 values in (16, 8, 5+19, 70-43) tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -976,6 +982,8 @@ partitions 3
(partition x1 values in (1,2,9,4) tablespace ts1,
partition x2 values in (3, 11, 5, 7) tablespace ts2,
partition x3 values in (16, 8, 5+19, 70-43) tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -998,6 +1006,8 @@ partition by list (b*a)
(partition x1 values in (1) tablespace ts1,
partition x2 values in (3, 11, 5, 7) tablespace ts2,
partition x3 values in (16, 8, 5+19, 70-43) tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/partition_hash.result b/mysql-test/r/partition_hash.result
index eb2338d8da70..3f79b8698e01 100644
--- a/mysql-test/r/partition_hash.result
+++ b/mysql-test/r/partition_hash.result
@@ -207,6 +207,8 @@ partitions 3
(partition x1 tablespace ts1,
partition x2 tablespace ts2,
partition x3 tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
insert into t1 values (1,1,1);
SHOW CREATE TABLE t1;
Table Create Table
@@ -255,6 +257,8 @@ partitions 3
(partition x1 tablespace ts1,
partition x2 tablespace ts2,
partition x3 tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
select * from t1;
a b c
SHOW CREATE TABLE t1;
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index bc4b84c08763..024859410230 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -1061,6 +1061,8 @@ PRIMARY KEY (`f1`,`f4`)
PARTITION BY LIST (`f4`)
(PARTITION p0 VALUES IN (0) ENGINE = InnoDB,
PARTITION p1 VALUES IN (1) DATA DIRECTORY = 'MYSQL_TMP_DIR/temp_tblspc' ENGINE = InnoDB);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -1133,6 +1135,8 @@ PRIMARY KEY (`f1`,`f4`)
PARTITION BY LIST (`f4`)
(PARTITION p0 VALUES IN (0) TABLESPACE ts1 ENGINE = InnoDB,
PARTITION p1 VALUES IN (1) TABLESPACE ts2 ENGINE = InnoDB);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -1171,6 +1175,8 @@ PARTITION BY LIST (`f4`)
PARTITION p1 VALUES IN (1) TABLESPACE innodb_file_per_table DATA DIRECTORY='MYSQL_TMP_DIR/temp_dir' ENGINE = InnoDB,
PARTITION p2 VALUES IN (2) TABLESPACE innodb_file_per_table ENGINE = InnoDB,
PARTITION p3 VALUES IN (3) TABLESPACE innodb_system ENGINE = InnoDB);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/partition_innodb_tablespace.result b/mysql-test/r/partition_innodb_tablespace.result
index 3079710ed246..742413a0f952 100644
--- a/mysql-test/r/partition_innodb_tablespace.result
+++ b/mysql-test/r/partition_innodb_tablespace.result
@@ -391,6 +391,8 @@ PARTITION p3 VALUES LESS THAN (300) TABLESPACE innodb_file_per_table
(SUBPARTITION sp9 TABLESPACE ts_part4,
SUBPARTITION sp10,
SUBPARTITION sp11));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
@@ -444,6 +446,8 @@ PARTITION p3 VALUES LESS THAN (300) TABLESPACE innodb_file_per_table
(SUBPARTITION sp9 TABLESPACE ts_part4,
SUBPARTITION sp10,
SUBPARTITION sp11));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
diff --git a/mysql-test/r/partition_list.result b/mysql-test/r/partition_list.result
index 9e7fa9fbd8d9..af110c91d220 100644
--- a/mysql-test/r/partition_list.result
+++ b/mysql-test/r/partition_list.result
@@ -426,6 +426,8 @@ c int not null,
primary key(a,b))
partition by list (a)
(partition x1 values in (1,2,9,4) tablespace ts1);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index dd36021fd428..d22f561c1ddc 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -47,6 +47,9 @@ PARTITION p4 VALUES LESS THAN (5),
PARTITION p5 VALUES LESS THAN (6),
PARTITION max VALUES LESS THAN MAXVALUE);
INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
SELECT * FROM t1 WHERE a < 1;
a
-1
@@ -484,6 +487,9 @@ PARTITION p3 VALUES LESS THAN (4),
PARTITION p4 VALUES LESS THAN (5),
PARTITION max VALUES LESS THAN MAXVALUE);
INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
SELECT * FROM t1 WHERE a < 1;
a
-1
@@ -2114,6 +2120,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'),
(1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'),
(1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 9 NULL # 33.33 Using where; Using index
@@ -2385,6 +2394,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'),
(1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'),
(1, '2009-04-07');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL # 33.33 Using where; Using index
@@ -2655,6 +2667,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'),
(1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'),
(1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL # 33.33 Using where
@@ -2925,6 +2940,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'),
(1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'),
(1, '2009-04-07');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL # 33.33 Using where
@@ -3192,6 +3210,9 @@ PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')),
PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')),
PARTITION p20090405 VALUES LESS THAN MAXVALUE);
INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
# test with an invalid date, which lead to item->null_value is set.
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -3221,6 +3242,9 @@ Warning 1292 Incorrect datetime value: '2009-12-00' for column 'b' at row 1
DROP TABLE t1;
create table t1 ( a int not null) partition by hash(a) partitions 2;
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain select * from t1 where a=5 and a=6;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL # NULL Impossible WHERE
@@ -3231,6 +3255,9 @@ create table t1 (
a int(11) not null
) partition by hash (a) partitions 2;
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a=1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL # 50.00 Using where
@@ -3254,6 +3281,9 @@ a int not null,
b int not null
) partition by key(a,b) partitions 2;
insert into t2 values (1,1),(2,2),(3,3);
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
explain partitions select * from t2 where a=1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL # 33.33 Using where
@@ -3280,6 +3310,9 @@ partition p0 values less than (10),
partition p1 values less than (20)
);
insert into t3 values (5),(15);
+ANALYZE TABLE t3;
+Table Op Msg_type Msg_text
+test.t3 analyze status OK
explain partitions select * from t3 where a=11;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 p1 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3309,6 +3342,9 @@ partition p0 values in (12),
partition p1 values in (14)
);
insert into t4 values (10,2), (10,4);
+ANALYZE TABLE t4;
+Table Op Msg_type Msg_text
+test.t4 analyze status OK
explain partitions select * from t4 where (a=10 and b=1) or (a=10 and b=2);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t4 p0 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3350,6 +3386,9 @@ partition p0 values in (12),
partition p1 values in (14)
);
insert into t5 values (10,2,0,0), (10,4,0,0), (10,2,0,1), (10,4,0,1);
+ANALYZE TABLE t5;
+Table Op Msg_type Msg_text
+test.t5 analyze status OK
explain partitions select * from t5;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL # 100.00 NULL
@@ -3404,6 +3443,9 @@ partition p7 values in (7),
partition p9 values in (9)
);
insert into t6 values (1),(3),(5);
+ANALYZE TABLE t6;
+Table Op Msg_type Msg_text
+test.t6 analyze status OK
explain partitions select * from t6 where a < 1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 NULL ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3479,6 +3521,9 @@ partition p7 values in (7),
partition p9 values in (9)
);
insert into t6 values (1),(3),(5);
+ANALYZE TABLE t6;
+Table Op Msg_type Msg_text
+test.t6 analyze status OK
explain partitions select * from t6 where a < 1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 NULL ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3553,6 +3598,9 @@ partition p70 values less than (70),
partition p90 values less than (90)
);
insert into t7 values (10),(30),(50);
+ANALYZE TABLE t7;
+Table Op Msg_type Msg_text
+test.t7 analyze status OK
explain partitions select * from t7 where a < 5;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t7 p10 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3700,6 +3748,9 @@ partition p70 values less than (70),
partition p90 values less than (90)
);
insert into t7 values (10),(30),(50);
+ANALYZE TABLE t7;
+Table Op Msg_type Msg_text
+test.t7 analyze status OK
explain partitions select * from t7 where a < 5;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t7 p10 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3844,6 +3895,9 @@ partition p1 values less than (1990),
partition p2 values less than (2000)
);
insert into t8 values ('1985-05-05'),('1995-05-05');
+ANALYZE TABLE t8;
+Table Op Msg_type Msg_text
+test.t8 analyze status OK
explain partitions select * from t8 where a < '1980-02-02';
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t8 p0,p1 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3856,6 +3910,9 @@ partition p1 values less than (732468), -- 2005-06-06
partition p2 values less than (732664) -- 2005-12-19
);
insert into t9 values ('2005-05-05'), ('2005-04-04');
+ANALYZE TABLE t9;
+Table Op Msg_type Msg_text
+test.t9 analyze status OK
explain partitions select * from t9 where a < '2004-12-19';
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t9 p0 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3878,6 +3935,9 @@ partition p1 values less than (6),
partition p2 values less than (9)
);
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a1 > 3;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3905,6 +3965,9 @@ partition p2 values in (3),
partition p3 values in (4)
);
insert into t3 values (1,1),(2,2),(3,3);
+ANALYZE TABLE t3;
+Table Op Msg_type Msg_text
+test.t3 analyze status OK
explain partitions select * from t3 where a=2 or b=1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 p0_p0sp1,p1_p1sp0,p1_p1sp1,p1_p1sp2,p1_p1sp3,p2_p2sp1,p3_p3sp1 ALL NULL NULL NULL NULL # 75.00 Using where
@@ -3926,6 +3989,9 @@ Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` fr
drop table t3;
create table t1 (a int) partition by hash(a) partitions 2;
insert into t1 values (1),(2);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3942,6 +4008,9 @@ drop table t1;
create table t1 (a int not null, b int not null, key(a), key(b))
partition by hash(a) partitions 4;
insert into t1 values (1,1),(2,2),(3,3),(4,4);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions
select * from t1 x, t1 y
where x.b = y.b and (x.a=1 or x.a=2) and (y.a=2 or y.a=3);
@@ -3962,6 +4031,9 @@ Note 1003 /* select#1 */ select `test`.`x`.`a` AS `a`,`test`.`x`.`b` AS `b`,`tes
drop table t1;
create table t1 (a int) partition by hash(a) partitions 20;
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a > 1 and a < 3;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p2 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -3996,6 +4068,9 @@ partition p2 values in (2),
partition p3 values in (3)
);
insert into t1 values (1,1),(2,2),(3,3);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where b > 1 and b < 3;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0_p0sp2,p1_p1sp2,p2_p2sp2,p3_p3sp2 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -4014,6 +4089,9 @@ partition p0 values in (1,2),
partition p1 values in (3,4)
);
insert into t1 values (1),(1),(2),(2),(3),(4),(3),(4);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
# This won't do any table access
explain extended update t1 set a=100 where a=5;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -4165,9 +4243,15 @@ a
4
4
insert into t1 values (1), (1);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
# Same as above multi-table UPDATE/DELETE
create table t2 like t1;
insert into t2 select * from t1;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
explain extended update t1,t2 set t1.a=1000, t2.a=1000 where t1.a=5 and t2.a=5;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 UPDATE t1 NULL ALL NULL NULL NULL NULL # 100.00 Using where
@@ -4267,6 +4351,9 @@ KEY `a` (`a`)
) ;
insert into t2 select A.a + 10*(B.a + 10* C.a) from t1 A, t1 B, t1 C ;
insert into t1 select a from t2;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
drop table t2;
CREATE TABLE `t2` (
`a` int(11) default NULL,
@@ -4293,6 +4380,9 @@ insert into t2 select a,2 from t1 where a >= 200 and a < 400;
insert into t2 select a,3 from t1 where a >= 400 and a < 600;
insert into t2 select a,4 from t1 where a >= 600 and a < 800;
insert into t2 select a,5 from t1 where a >= 800 and a < 1001;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
explain partitions select * from t2;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL # 100.00 NULL
@@ -4747,6 +4837,9 @@ partition part2 values in (1),
partition part4 values in (null)
);
insert into t1 set f_int1 = null;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
select * from t1 where f_int1 is null;
f_int1
NULL
@@ -4767,6 +4860,9 @@ partition p2 values in (3)
);
insert into t1 values (1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a=1 AND (b=1 OR b=2);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0_p0sp1,p0_p0sp2 ALL NULL NULL NULL NULL # 50.00 Using where
@@ -4785,6 +4881,9 @@ partition pn values in (NULL)
);
insert into t1 values (1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4), (NULL,1);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a IS NULL AND (b=1 OR b=2);
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -4817,6 +4916,9 @@ partition p4 values in (4), partition p5 values in (5),
partition p6 values in (6), partition pn values in (NULL)
);
insert into t1 values (NULL), (0),(1),(2),(3),(4),(5),(6);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a is null or a < 2;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0,p1,p2,p3,p4,p5,p6,pn ALL NULL NULL NULL NULL # 41.66 Using where
@@ -4829,6 +4931,9 @@ create table t1 (s1 int) partition by list (s1)
partition p2 values in (1),
partition p3 values in (null));
insert into t1 values (0),(1),(null);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
select count(*) from t1 where s1 < 0 or s1 is null;
count(*)
1
@@ -4843,6 +4948,9 @@ create table t1 (a char(32) primary key)
partition by key()
partitions 100;
insert into t1 values ('na');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
select * from t1;
a
na
@@ -4854,6 +4962,9 @@ create table t1 (s1 varchar(15)) partition by key (s1);
select * from t1 where s1 = 0 or s1 is null;
s1
insert into t1 values ('aa'),('bb'),('0');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where s1 = 0 or s1 is null;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL # 55.56 Using where
@@ -4867,6 +4978,9 @@ subpartition by HASH(b) subpartitions 40
( partition p_0_long_partition_name values in(1),
partition p_1_long_partition_name values in(2));
insert into t2 values (1,1),(2,2);
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
explain partitions select * from t2;
id 1
select_type SIMPLE
@@ -4907,6 +5021,9 @@ partition p4 values less than (18446744073709551614)
insert into t1 values (5),(15),(105),(1005);
insert into t1 values (18446744073709551000+1);
insert into t1 values (18446744073709551614-1);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a < 10;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL # 100.00 Using where
@@ -4960,6 +5077,12 @@ partition p2 values less than (255)
);
insert into t1 values (0x20), (0x20), (0x41), (0x41), (0xFE), (0xFE);
insert into t2 values (0x20), (0x20), (0x41), (0x41), (0xFE), (0xFE);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
explain partitions select * from t1 where a=0;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL # 50.00 Using where
@@ -5042,6 +5165,9 @@ partition p4 values less than (2305561538531950591)
);
insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1);
insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where
a >= 2305561538531885056-10 and a <= 2305561538531885056-8;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -5070,6 +5196,9 @@ partition p3 values less than (10),
partition p4 values less than (1000)
);
insert into t1 values (-15),(-5),(5),(15),(-15),(-5),(5),(15);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a>-2 and a <=0;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p3 ALL NULL NULL NULL NULL # 25.00 Using where
@@ -5086,6 +5215,9 @@ INSERT INTO t1 VALUES ('2007-03-01 12:00:00');
INSERT INTO t1 VALUES ('2007-03-07 12:00:00');
INSERT INTO t1 VALUES ('2007-03-08 12:00:00');
INSERT INTO t1 VALUES ('2007-03-15 12:00:00');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
must use p0 only:
explain partitions select * from t1 where recdate < '2007-03-08 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -5103,6 +5235,9 @@ INSERT INTO t1 VALUES ('2005-03-01 12:00:00');
INSERT INTO t1 VALUES ('2005-03-01 12:00:00');
INSERT INTO t1 VALUES ('2006-03-01 12:00:00');
INSERT INTO t1 VALUES ('2006-03-01 12:00:00');
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
must use p0 only:
explain partitions select * from t1 where recdate < '2006-01-01 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -5123,6 +5258,9 @@ partition p1 values less than (128),
partition p2 values less than (255)
);
insert into t1 select A.a + 10*B.a from t0 A, t0 B;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
explain partitions select * from t1 where a between 10 and 13;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL # 11.11 Using where
@@ -5150,6 +5288,9 @@ PARTITION BY LIST COLUMNS (c2)
PARTITION p2 VALUES IN (3,4));
INSERT INTO t1 VALUES (1, 1, 1, 1), (2, 3, 1, 1);
INSERT INTO t1 VALUES (1, 2, 1, 1), (2, 4, 1, 1);
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
c1 c2 c3 c4
SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result
index 21ff94250e32..5aba1b6a4c0a 100644
--- a/mysql-test/r/partition_range.result
+++ b/mysql-test/r/partition_range.result
@@ -346,6 +346,8 @@ partitions 3
(partition x1 values less than (5) tablespace ts1,
partition x2 values less than (10) tablespace ts2,
partition x3 values less than maxvalue tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
INSERT into t1 values (1, 1, 1);
INSERT into t1 values (6, 1, 1);
INSERT into t1 values (10, 1, 1);
@@ -374,6 +376,8 @@ partitions 3
(partition x1 values less than (5) tablespace ts1,
partition x2 values less than (10) tablespace ts2,
partition x3 values less than maxvalue tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
select * from t1;
a b c
1 1 1
@@ -402,6 +406,8 @@ partitions 3
(partition x1 values less than (5) tablespace ts1,
partition x2 values less than (10) tablespace ts2,
partition x3 values less than maxvalue tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
INSERT into t1 values (1, 1, 1);
INSERT into t1 values (6, 1, 1);
INSERT into t1 values (10, 1, 1);
@@ -429,6 +435,8 @@ partitions 3
(partition x1 values less than (5) tablespace ts1,
partition x2 values less than (10) tablespace ts2,
partition x3 values less than maxvalue tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
select * from t1;
a b c
1 1 1
@@ -457,6 +465,8 @@ partitions 3
(partition x1 values less than (5) tablespace ts1,
partition x2 values less than (10) tablespace ts2,
partition x3 values less than (15) tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
INSERT into t1 values (1, 1, 1);
INSERT into t1 values (6, 1, 1);
INSERT into t1 values (10, 1, 1);
@@ -485,6 +495,8 @@ partitions 3
(partition x1 values less than (5) tablespace ts1,
partition x2 values less than (10) tablespace ts2,
partition x3 values less than (15) tablespace ts3);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
select * from t1;
a b c
1 1 1
@@ -597,6 +609,8 @@ partition x2 values less than (5)
( subpartition x21 tablespace ts1 nodegroup 0,
subpartition x22 tablespace ts2 nodegroup 1)
);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SELECT * from t1;
a b c
SHOW CREATE TABLE t1;
diff --git a/mysql-test/r/percona_heap_blob.result b/mysql-test/r/percona_heap_blob.result
index 38fff03afc97..1be9de43523f 100644
--- a/mysql-test/r/percona_heap_blob.result
+++ b/mysql-test/r/percona_heap_blob.result
@@ -905,6 +905,7 @@ SET @old_max_heap_table_size = @@global.max_heap_table_size;
SET @old_max_allowed_packet = @@global.max_allowed_packet;
SET GLOBAL max_heap_table_size = 18 * 1024 * 1024;
SET GLOBAL max_allowed_packet = 24 * 1024 * 1024;
+SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
SET default_storage_engine=MEMORY;
drop table if exists t1;
CREATE TABLE t1 (data LONGBLOB);
@@ -925,6 +926,8 @@ select length(data) from t1;
length(data)
18874368
alter table t1 modify data blob;
+Warnings:
+Warning 1265 Data truncated for column 'data' at row 1
select length(data) from t1;
length(data)
0
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index f8354ed2f569..99f207a09bbf 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -20,15 +20,15 @@ select 1 from t1,t1 as t2,t1 as t3;
1
1
update t1 set b="a";
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
update t1 set b="a" where b="test";
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
delete from t1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
delete from t1 where b="test";
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
delete from t1 where a+0=1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5;
ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
update t1 set b="a" limit 1;
@@ -95,3 +95,88 @@ select * from (select 1 union select 2 union select 3) x;
ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
drop table t1;
SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, MAX_JOIN_SIZE=DEFAULT;
+#
+# Bug #28145710: SQL_SAFE_UPDATES ERROR IS INSUFFICIENTLY INFORMATIVE
+#
+CREATE TABLE t1 (c1 INT NOT NULL, c2 VARCHAR(200) NOT NULL,
+UNIQUE KEY idx1 (c1), UNIQUE KEY idx2 (c2));
+CREATE TABLE t2 (c1 INT NOT NULL, c2 VARCHAR(200) NOT NULL,
+UNIQUE KEY idx1 (c1));
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (11, 'a'), (12, 'b'), (3, 'c'), (14, 'd');
+ANALYZE TABLE t1, t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+SET SESSION sql_safe_updates=1;
+SET RANGE_OPTIMIZER_MAX_MEM_SIZE= 1;
+EXPLAIN DELETE FROM t1 WHERE c1 IN (1,22);
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 DELETE t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Warning 3170 Memory capacity of 1 bytes for 'range_optimizer_max_mem_size' exceeded. Range optimization was not done for this query.
+DELETE FROM t1 WHERE c1 IN (1,22);
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. Memory capacity of 1 bytes for 'range_optimizer_max_mem_size' exceeded. Range optimization was not done for this query.
+EXPLAIN UPDATE t1 SET c1=20 WHERE c1 IN (1,22);
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Warning 3170 Memory capacity of 1 bytes for 'range_optimizer_max_mem_size' exceeded. Range optimization was not done for this query.
+UPDATE t1 SET c1=20 WHERE c1 IN (1,22);
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. Memory capacity of 1 bytes for 'range_optimizer_max_mem_size' exceeded. Range optimization was not done for this query.
+SET RANGE_OPTIMIZER_MAX_MEM_SIZE= default;
+EXPLAIN DELETE t1 FROM t1 JOIN t2 ON t1.c2 = t2.c1;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 DELETE t1 NULL ALL idx2 NULL NULL NULL 4 100.00 NULL
+1 SIMPLE t2 NULL eq_ref idx1 idx1 4 test.t1.c2 1 100.00 Using where; Using index
+Warnings:
+Warning 1739 Cannot use ref access on index 'idx2' due to type or collation conversion on field 'c2'
+DELETE t1 FROM t1 JOIN t2 ON t1.c2 = t2.c1;
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. Cannot use ref access on index 'idx2' due to type or collation conversion on field 'c2'
+EXPLAIN UPDATE t1, t2 SET t1.c1=20 WHERE t1.c2 = t2.c1;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t1 NULL ALL idx2 NULL NULL NULL 4 100.00 NULL
+1 SIMPLE t2 NULL eq_ref idx1 idx1 4 test.t1.c2 1 100.00 Using where; Using index
+Warnings:
+Warning 1739 Cannot use ref access on index 'idx2' due to type or collation conversion on field 'c2'
+UPDATE t1, t2 SET t1.c1=20 WHERE t1.c2 = t2.c1;
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. Cannot use ref access on index 'idx2' due to type or collation conversion on field 'c2'
+EXPLAIN DELETE t2 FROM t1 JOIN t2 ON t1.c2 = t2.c1;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 NULL index idx2 idx2 202 NULL 4 100.00 Using index
+1 DELETE t2 NULL eq_ref idx1 idx1 4 test.t1.c2 1 100.00 Using where
+Warnings:
+Warning 1739 Cannot use ref access on index 'idx2' due to type or collation conversion on field 'c2'
+DELETE t2 FROM t1 JOIN t2 ON t1.c2 = t2.c1;
+Warnings:
+Warning 1739 Cannot use ref access on index 'idx2' due to type or collation conversion on field 'c2'
+EXPLAIN DELETE FROM t1 WHERE c2 IN(1,2222);
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 DELETE t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Warning 1739 Cannot use range access on index 'idx2' due to type or collation conversion on field 'c2'
+DELETE FROM t1 WHERE c2 IN(1,2222);
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. Cannot use range access on index 'idx2' due to type or collation conversion on field 'c2'
+EXPLAIN UPDATE t1 SET c1=20 WHERE c2 IN(1,2222);
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 UPDATE t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Warning 1739 Cannot use range access on index 'idx2' due to type or collation conversion on field 'c2'
+UPDATE t1 SET c1=20 WHERE c2 IN(1,2222);
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. Cannot use range access on index 'idx2' due to type or collation conversion on field 'c2'
+EXPLAIN DELETE FROM t2 WHERE c2 IN('a','e');
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 DELETE t2 NULL ALL NULL NULL NULL NULL 4 100.00 Using where
+DELETE FROM t2 WHERE c2 IN('a','e');
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
+EXPLAIN DELETE FROM t2;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 DELETE t2 NULL ALL NULL NULL NULL NULL 4 100.00 Deleting all rows
+DELETE FROM t2;
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
+SET sql_log_bin= 0;
+DELETE FROM t2;
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
+SET sql_log_bin= default;
+DROP TABLE t1, t2;
+SET SESSION sql_safe_updates=default;
diff --git a/mysql-test/r/subquery_bugs.result b/mysql-test/r/subquery_bugs.result
new file mode 100644
index 000000000000..3c52d459de88
--- /dev/null
+++ b/mysql-test/r/subquery_bugs.result
@@ -0,0 +1,85 @@
+#
+# Bug#27182010 SUBQUERY INCORRECTLY SHOWS DUPLICATE VALUES ON SUBQUERIES
+#
+CREATE TABLE p (Id INT,PRIMARY KEY (Id));
+INSERT INTO p VALUES (1);
+# Test UNIQUE KEY with NULL values
+CREATE TABLE s (Id INT, u INT, UNIQUE KEY o(Id, u) );
+INSERT INTO s VALUES (1, NULL),(1, NULL);
+EXPLAIN SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s WHERE Id=1 AND u IS NULL)ORDER BY Id DESC;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE p NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 SIMPLE s NULL ref o o 10 const,const 2 100.00 Using where; Using index; FirstMatch(p)
+Warnings:
+Note 1003 /* select#1 */ select '1' AS `Id` from `test`.`p` semi join (`test`.`s`) where ((`test`.`s`.`Id` = 1) and isnull(`test`.`s`.`u`)) order by '1' desc
+EXPLAIN SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s WHERE Id=1 AND u IS NOT NULL) ORDER BY Id DESC;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE p NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 SIMPLE s NULL range o o 10 NULL 1 100.00 Using where; Using index; FirstMatch(p)
+Warnings:
+Note 1003 /* select#1 */ select '1' AS `Id` from `test`.`p` semi join (`test`.`s`) where ((`test`.`s`.`Id` = 1) and (`test`.`s`.`u` is not null)) order by '1' desc
+SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s WHERE Id=1 AND u IS NULL)ORDER BY Id DESC;
+Id
+1
+SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s WHERE Id=1 AND u IS NOT NULL) ORDER BY Id DESC;
+Id
+# UNIQUE KEY without NULL values
+CREATE TABLE s1 (Id INT, u INT, UNIQUE KEY o(Id, u) );
+INSERT INTO s1 VALUES (1, 2),(1, 3);
+EXPLAIN SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s1.Id FROM s1 WHERE Id=1 AND u IS NOT NULL) ORDER BY Id DESC;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE p NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 SIMPLE s1 NULL ref o o 5 const 2 50.00 Using where; Using index; FirstMatch(p)
+Warnings:
+Note 1003 /* select#1 */ select '1' AS `Id` from `test`.`p` semi join (`test`.`s1`) where ((`test`.`s1`.`Id` = 1) and (`test`.`s1`.`u` is not null)) order by '1' desc
+EXPLAIN SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s1.Id FROM s1 WHERE Id=1 AND u != 1) ORDER BY Id DESC;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE p NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 SIMPLE s1 NULL ref o o 5 const 3 50.00 Using where; Using index; FirstMatch(p)
+Warnings:
+Note 1003 /* select#1 */ select '1' AS `Id` from `test`.`p` semi join (`test`.`s1`) where ((`test`.`s1`.`Id` = 1) and (`test`.`s1`.`u` <> 1)) order by '1' desc
+SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s1.Id FROM s1 WHERE Id=1 AND u IS NOT NULL) ORDER BY Id DESC;
+Id
+1
+SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s1.Id FROM s1 WHERE Id=1 AND u != 1) ORDER BY Id DESC;
+Id
+1
+# NON UNIQUE KEY Scenario
+CREATE TABLE s2 (Id INT, u INT, KEY o(Id, u) );
+INSERT INTO s2 VALUES (1, NULL),(1, NULL);
+#UNIQUE KEY with NON NULL FIELDS
+CREATE TABLE s3 (Id INT NOT NULL, u INT NOT NULL, UNIQUE KEY o(Id, u));
+INSERT INTO s3 VALUES (1, 2),(1, 3);
+EXPLAIN SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s2 s WHERE Id=1 AND u IS NULL) ORDER BY Id DESC;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE p NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 SIMPLE s NULL ref o o 10 const,const 2 100.00 Using where; Using index; FirstMatch(p)
+Warnings:
+Note 1003 /* select#1 */ select '1' AS `Id` from `test`.`p` semi join (`test`.`s2` `s`) where ((`test`.`s`.`Id` = 1) and isnull(`test`.`s`.`u`)) order by '1' desc
+EXPLAIN SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s3 s WHERE Id=1 AND u IS NOT NULL)
+ORDER BY Id DESC;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE p NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index
+1 SIMPLE s NULL ref o o 4 const 2 50.00 Using where; Using index; FirstMatch(p)
+Warnings:
+Note 1003 /* select#1 */ select '1' AS `Id` from `test`.`p` semi join (`test`.`s3` `s`) where ((`test`.`s`.`Id` = 1) and (`test`.`s`.`u` is not null)) order by '1' desc
+SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s2 s WHERE Id=1 AND u IS NULL) ORDER BY Id DESC;
+Id
+1
+SELECT p.Id FROM (p) WHERE p.Id IN (
+SELECT s.Id FROM s3 s WHERE Id=1 AND u IS NOT NULL)
+ORDER BY Id DESC;
+Id
+1
+DROP TABLE p, s, s1, s2, s3;
diff --git a/mysql-test/r/trigger_wl3253.result b/mysql-test/r/trigger_wl3253.result
index 01e86763ed93..3d09bc44f847 100644
--- a/mysql-test/r/trigger_wl3253.result
+++ b/mysql-test/r/trigger_wl3253.result
@@ -322,7 +322,7 @@ CREATE TABLE `t1` (
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 */;;
DELIMITER ;
@@ -337,7 +337,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2 */;;
DELIMITER ;
@@ -352,7 +352,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3 */;;
DELIMITER ;
@@ -384,7 +384,7 @@ CREATE TABLE `t1` (
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=0 */;;
DELIMITER ;
@@ -399,7 +399,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 */;;
DELIMITER ;
@@ -414,7 +414,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=0 */;;
DELIMITER ;
@@ -429,7 +429,7 @@ DELIMITER ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
-/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+/*!50003 SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2 */;;
DELIMITER ;
diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result
index 7c1b93070b8d..09edda6c3c0b 100644
--- a/mysql-test/r/type_year.result
+++ b/mysql-test/r/type_year.result
@@ -334,3 +334,22 @@ a
2012
DROP TABLE t1;
SET timestamp=DEFAULT;
+#
+# Bug#28172538 YEAR RANGE CHECK FAILS WITH MAX YEAR FLOAT CONSTANT
+#
+CREATE TABLE t(y YEAR);
+INSERT INTO t VALUES (2155), (2155.0);
+SELECT * FROM t;
+y
+2155
+2155
+Used to fail
+INSERT INTO t VALUES (2155.0E00);
+INSERT INTO t VALUES (2.1550E+03);
+SELECT * FROM t;
+y
+2155
+2155
+2155
+2155
+DROP TABLE t;
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index acccf56ff1ba..889a75455c91 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -545,7 +545,7 @@ INSERT INTO t1 VALUES (0), (1);
CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12;
SET SESSION sql_safe_updates = 1;
UPDATE IGNORE v1 SET a = 1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
diff --git a/mysql-test/std_data/binlog_56_gtid_reserved_word.000001 b/mysql-test/std_data/binlog_56_gtid_reserved_word.000001
new file mode 100644
index 000000000000..46d5338e0058
Binary files /dev/null and b/mysql-test/std_data/binlog_56_gtid_reserved_word.000001 differ
diff --git a/mysql-test/suite/binlog/r/binlog_group_commit_sync_delay_error.result b/mysql-test/suite/binlog/r/binlog_group_commit_sync_delay_error.result
new file mode 100644
index 000000000000..428279f4e04b
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_group_commit_sync_delay_error.result
@@ -0,0 +1,9 @@
+CREATE TABLE t(s INT);
+SET GLOBAL binlog_group_commit_sync_delay = 32;
+SET GLOBAL binlog_group_commit_sync_no_delay_count = 0;
+BEGIN;
+INSERT INTO t VALUES(10);
+COMMIT;
+SET GLOBAL binlog_group_commit_sync_delay = 0;
+SET GLOBAL binlog_group_commit_sync_no_delay_count = 0;
+DROP TABLE t;
diff --git a/mysql-test/suite/binlog/r/binlog_gtid_reset_consistency_violation_on_fail.result b/mysql-test/suite/binlog/r/binlog_gtid_reset_consistency_violation_on_fail.result
new file mode 100644
index 000000000000..28f3981047c7
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_gtid_reset_consistency_violation_on_fail.result
@@ -0,0 +1,13 @@
+# TC1. Test if GTID consistency state is rolled back after failure
+# ----------------------------------------------------------------
+XA START 'xa1';
+XA END 'xa1';
+XA PREPARE 'xa1';
+CREATE TEMPORARY TABLE t1 (c INT) ENGINE=InnoDB;
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state
+SET @@SESSION.GTID_NEXT='ANONYMOUS';
+XA COMMIT 'xa1';
+# TC2. Test if GTID consistency state is persisted after success
+# --------------------------------------------------------------
+CREATE TEMPORARY TABLE t1 (c INT) ENGINE=InnoDB;
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_group_commit_sync_delay_error.test b/mysql-test/suite/binlog/t/binlog_group_commit_sync_delay_error.test
new file mode 100644
index 000000000000..6a937fb4f8fa
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_group_commit_sync_delay_error.test
@@ -0,0 +1,40 @@
+# ==== Purpose ====
+#
+# This test will set a value for binlog_group_commit_sync_delay
+# which will be a non multiple of delta(the waiting time is
+# broken into smaller chunks called as delta), and execute some
+# transactions after that.
+#
+# The test verifies that server does not hang when a non multiple of 10
+# is assigned to binlog_group_commit_sync_delay variable.
+#
+# Related bugs and Worklogs
+#
+# Bug#28091735:COMMIT WILL HANG IF BINLOG_GROUP_COMMIT_SYNC_DELAY
+# IS NOT A MULTIPLE OF 10
+
+# this is binlog format agnostic
+--source include/have_binlog_format_row.inc
+
+--let $bgcd_saved = `SELECT @@GLOBAL.binlog_group_commit_sync_delay`
+--let $bgcc_saved = `SELECT @@GLOBAL.binlog_group_commit_sync_no_delay_count`
+
+CREATE TABLE t(s INT);
+
+# Set the delay to a non multiple of delta, in this case
+# delta will be 3, MAX(1, wait_time * .1) and so it will not be
+# a multiple of the waiting time which is 32
+
+SET GLOBAL binlog_group_commit_sync_delay = 32;
+SET GLOBAL binlog_group_commit_sync_no_delay_count = 0;
+
+BEGIN;
+INSERT INTO t VALUES(10);
+COMMIT; # Hangs here without the fix
+
+#cleanup
+
+--eval SET GLOBAL binlog_group_commit_sync_delay = $bgcd_saved
+--eval SET GLOBAL binlog_group_commit_sync_no_delay_count = $bgcc_saved
+DROP TABLE t;
+
diff --git a/mysql-test/suite/binlog/t/binlog_gtid_reset_consistency_violation_on_fail.test b/mysql-test/suite/binlog/t/binlog_gtid_reset_consistency_violation_on_fail.test
new file mode 100644
index 000000000000..ddd7f42751ca
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_gtid_reset_consistency_violation_on_fail.test
@@ -0,0 +1,71 @@
+# ==== Purpose ====
+#
+# The purpose of this test is to ensure that the server properly restores a
+# previous state or preserves a new state, for GTID consistency violation,
+# whenever a statement execution succeeds or fails.
+#
+# ==== Requirements ====
+#
+# R1. If a statement fails to execute successfully, the overall state observed
+# prior to the statement execution must be kept after the failure.
+# R2. If a statement executes successfully, the overall state observed after the
+# statement execution must be kept.
+#
+# ==== Implementation ====
+#
+# -- TEST CASES --
+#
+# TC1. Test if GTID consistency state is rolled back after failure
+# ----------------------------------------------------------------
+# 1) Place an XA transaction in the prepare state.
+# 2) Try to create a temporary table.
+# 3) Test if the execution state prior to the failure is restored, using
+# DEBUG_SYNC.
+# 4) Commit the transaction.
+#
+# TC2. Test if GTID consistency state is persisted after success
+# --------------------------------------------------------------
+# 1) Try to create a temporary table.
+# 2) Test if the execution state after the successful execution is persisted,
+# using DEBUG_SYNC.
+#
+# ==== References ====
+#
+# BUG#27903831 [MYSQL 8.0 GA DEBUG BUILD] ASSERTION
+# `!THD->HAS_GTID_CONSISTENCY_VIOLATION
+
+
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/not_gtid_enabled.inc
+--source include/have_binlog_format_statement.inc
+
+--echo # TC1. Test if GTID consistency state is rolled back after failure
+--echo # ----------------------------------------------------------------
+# 1) Place an XA transaction in the prepare state.
+XA START 'xa1';
+XA END 'xa1';
+XA PREPARE 'xa1';
+#SET DEBUG_SYNC='restore_previous_state_after_statement_failed SIGNAL failure';
+# 2) Try to create a temporary table.
+--error ER_XAER_RMFAIL
+CREATE TEMPORARY TABLE t1 (c INT) ENGINE=InnoDB;
+# 3) Test if the `Rpl_state_guard` instance restored the execution state prior
+# to the failure, using DEBUG_SYNC.
+#SET DEBUG_SYNC='now WAIT_FOR failure';
+# 4) Commit the transaction.
+SET @@SESSION.GTID_NEXT='ANONYMOUS';
+XA COMMIT 'xa1';
+
+--echo # TC2. Test if GTID consistency state is persisted after success
+--echo # --------------------------------------------------------------
+#SET DEBUG_SYNC='persist_new_state_after_statement_succeeded SIGNAL success';
+# 1) Try to create a temporary table.
+CREATE TEMPORARY TABLE t1 (c INT) ENGINE=InnoDB;
+# 2) Test if the `Rpl_state_guard` instance persisted the execution state after
+# the successful execution, using DEBUG_SYNC.
+#SET DEBUG_SYNC='now WAIT_FOR success';
+#
+
+DROP TABLE t1;
+#SET DEBUG_SYNC='RESET';
diff --git a/mysql-test/suite/federated/r/percona_bug1739734.result b/mysql-test/suite/federated/r/percona_bug1739734.result
new file mode 100644
index 000000000000..5f4bdd9a1318
--- /dev/null
+++ b/mysql-test/suite/federated/r/percona_bug1739734.result
@@ -0,0 +1,44 @@
+#
+# Bug lp1739734 "Federated table returns error 1430 from storage engine"
+#
+# This is a bug introduced in the artful/gcc7 compilation fixes, caused by
+# a moved break statement.
+CREATE DATABASE federated;
+CREATE DATABASE federated;
+CREATE DATABASE lp1739734;
+use lp1739734;
+CREATE SERVER local_server
+FOREIGN DATA WRAPPER mysql
+OPTIONS (
+HOST '127.0.0.1',
+PORT MASTER_PORT,
+USER 'root',
+PASSWORD '',
+DATABASE 'lp1739734'
+);
+CREATE TABLE remote_table (
+a INT,
+b INT,
+KEY ab (a,b),
+KEY ba (b,a)
+);
+CREATE TABLE local_table (
+a INT,
+b INT,
+KEY ab (a,b),
+KEY ba (b,a)
+) ENGINE=federated CONNECTION='local_server/remote_table';
+SELECT * FROM local_table;
+a b
+SELECT * FROM local_table USE INDEX (ab)
+WHERE a<1 AND b=0;
+a b
+SELECT * FROM local_table USE INDEX (ba)
+WHERE a<1 AND b=0;
+a b
+DROP DATABASE lp1739734;
+DROP SERVER local_server;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE federated;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE federated;
diff --git a/mysql-test/suite/federated/t/percona_bug1739734.test b/mysql-test/suite/federated/t/percona_bug1739734.test
new file mode 100644
index 000000000000..cbb4c90dd756
--- /dev/null
+++ b/mysql-test/suite/federated/t/percona_bug1739734.test
@@ -0,0 +1,50 @@
+--echo #
+--echo # Bug lp1739734 "Federated table returns error 1430 from storage engine"
+--echo #
+--echo # This is a bug introduced in the artful/gcc7 compilation fixes, caused by
+--echo # a moved break statement.
+
+--source suite/federated/include/federated.inc
+
+connection master;
+CREATE DATABASE lp1739734;
+use lp1739734;
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval CREATE SERVER local_server
+FOREIGN DATA WRAPPER mysql
+OPTIONS (
+ HOST '127.0.0.1',
+ PORT $MASTER_MYPORT,
+ USER 'root',
+ PASSWORD '',
+ DATABASE 'lp1739734'
+);
+
+CREATE TABLE remote_table (
+ a INT,
+ b INT,
+ KEY ab (a,b),
+ KEY ba (b,a)
+);
+
+
+CREATE TABLE local_table (
+ a INT,
+ b INT,
+ KEY ab (a,b),
+ KEY ba (b,a)
+) ENGINE=federated CONNECTION='local_server/remote_table';
+
+SELECT * FROM local_table;
+
+SELECT * FROM local_table USE INDEX (ab)
+WHERE a<1 AND b=0;
+
+SELECT * FROM local_table USE INDEX (ba)
+WHERE a<1 AND b=0;
+
+DROP DATABASE lp1739734;
+DROP SERVER local_server;
+
+--source suite/federated/include/federated_cleanup.inc
diff --git a/mysql-test/suite/innodb/r/bug79821.result b/mysql-test/suite/innodb/r/bug79821.result
new file mode 100644
index 000000000000..ce8a51f048f8
--- /dev/null
+++ b/mysql-test/suite/innodb/r/bug79821.result
@@ -0,0 +1,19 @@
+#
+# Bug #22486025 / #79821 "InnoDB: Failing assertion: key_len != 0 || find_flag != HA_READ_KEY_EXACT"
+# fixed in 5.7.21, 8.0.4
+# A "wrong key column" error was added to address an unsupported index creation scenario
+#
+SET sql_mode = '';
+Warnings:
+Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
+CREATE TEMPORARY TABLE t1 (c1 INT NOT NULL) ENGINE=InnoDB;
+CREATE TABLE t1(c1 CHAR(0) NOT NULL);
+DROP TABLE t1;
+ALTER TABLE t1 ADD COLUMN c4 INT COMMENT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
+SET big_tables = 1;
+INSERT INTO t1 VALUES(0, 0);
+Warnings:
+Warning 1265 Data truncated for column 'c1' at row 1
+SELECT AVG(sum_c1) FROM (SELECT SUM(c1) AS sum_c1 FROM t1 GROUP BY c1) AS t1;
+ERROR 42000: The used storage engine can't index column 'c1'
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/bug88747.result b/mysql-test/suite/innodb/r/bug88747.result
new file mode 100644
index 000000000000..00c5a7131c1d
--- /dev/null
+++ b/mysql-test/suite/innodb/r/bug88747.result
@@ -0,0 +1,16 @@
+#
+# Bug #27216817 / #88747 "InnoDB: Failing assertion: prebuilt->table->n_mysql_handles_opened == 1"
+# fixed in 5.5.60, 5.6.40, 5.7.22, 8.0.11
+# Adding a unique index to an InnoDB table on which multiple locks were
+# held could raise an assertion
+#
+CREATE TABLE t1(
+c1 INT NOT NULL,
+c2 TIMESTAMP NOT NULL,
+c3 INT NULL,
+c4 CHAR(1) NOT NULL
+) ENGINE=InnoDB;
+LOCK TABLES t1 WRITE, t1 AS a READ;
+ALTER TABLE t1 ADD PRIMARY KEY(c1);
+UNLOCK TABLES;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/bug88782.result b/mysql-test/suite/innodb/r/bug88782.result
new file mode 100644
index 000000000000..fffe2545c79e
--- /dev/null
+++ b/mysql-test/suite/innodb/r/bug88782.result
@@ -0,0 +1,15 @@
+#
+# Bug #27225649, #27229072 / #88782 "Failing assertion: prebuilt->sql_stat_start || prebuilt->select_lock_type != LOC"
+# fixed in 5.5.60, 5.6.40, 5.7.22, 8.0.11
+# InnoDB: A REPLACE operation on a temporary table raised an assertion
+#
+CREATE TEMPORARY TABLE t2(c1 INT);
+CREATE TEMPORARY TABLE t1(a int) ENGINE=InnoDB;
+ALTER TABLE t1 ADD UNIQUE INDEX(a);
+LOCK TABLES t1 READ, t2 READ;
+INSERT INTO t2 VALUES(8403+0.75);
+SELECT DAYNAME(c1) FROM t1;
+ERROR 42S22: Unknown column 'c1' in 'field list'
+INSERT INTO t1 VALUES(0xAFBA);
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1 SELECT * FROM t2;
diff --git a/mysql-test/suite/innodb/r/create_table.result b/mysql-test/suite/innodb/r/create_table.result
index c086f4fa8d98..edd1460c84a4 100644
--- a/mysql-test/suite/innodb/r/create_table.result
+++ b/mysql-test/suite/innodb/r/create_table.result
@@ -24,17 +24,17 @@ SET DEBUG ='-d, simulate_max_char_col';
"Try creating temporary table with innodb_file_per_table option with STRICT mode"
SET innodb_strict_mode = ON;
CREATE TEMPORARY TABLE t1(c1 int) TABLESPACE innodb_file_per_table;
-ERROR HY000: InnoDB: innodb_file_per_table option not supported for temporary tables.
+ERROR HY000: InnoDB: TABLESPACE=innodb_file_per_table option is disallowed for temporary tables with INNODB_STRICT_NODE=ON. This option is deprecated and will be removed in a future release
SELECT COUNT(*) FROM t1;
ERROR 42S02: Table 'test.t1' doesn't exist
"Try creating temporary table with innodb_file_per_table option without STRICT mode"
SET innodb_strict_mode = OFF;
CREATE TEMPORARY TABLE t1(c1 int) TABLESPACE innodb_file_per_table;
Warnings:
-Warning 1478 InnoDB: innodb_file_per_table option ignored while creating temporary table with INNODB_STRICT_MODE=OFF.
+Warning 1478 InnoDB: TABLESPACE=innodb_file_per_table option is ignored. This option is deprecated and will be removed in a future release.
SHOW WARNINGS;
Level Code Message
-Warning 1478 InnoDB: innodb_file_per_table option ignored while creating temporary table with INNODB_STRICT_MODE=OFF.
+Warning 1478 InnoDB: TABLESPACE=innodb_file_per_table option is ignored. This option is deprecated and will be removed in a future release.
SELECT COUNT(*) FROM t1;
COUNT(*)
0
diff --git a/mysql-test/suite/innodb/r/create_tablespace.result b/mysql-test/suite/innodb/r/create_tablespace.result
index 030c9cb21616..ff66a067b291 100644
--- a/mysql-test/suite/innodb/r/create_tablespace.result
+++ b/mysql-test/suite/innodb/r/create_tablespace.result
@@ -1311,7 +1311,69 @@ Level Code Message
Error 1478 InnoDB: Tablespace `innodb_temporary` can only contain TEMPORARY tables.
Error 1478 Table storage engine 'InnoDB' does not support the create option 'TABLESPACE'
DROP TABLE t_not_temp;
+#
+# Try to create or move a temporary table in innodb_file_per_table
+# or innodb_temporary tablespaces with STRICT_MODE ON and OFF
+#
CREATE TEMPORARY TABLE t_my_temp (a int, b text) TABLESPACE=`innodb_temporary`;
+Warnings:
+Warning 1478 InnoDB: TABLESPACE=innodb_temporary option is deprecated and will be removed in a future release.
+SHOW CREATE TABLE t_my_temp;
+Table Create Table
+t_my_temp CREATE TEMPORARY TABLE `t_my_temp` (
+ `a` int(11) DEFAULT NULL,
+ `b` text
+) /*!50100 TABLESPACE `innodb_temporary` */ ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t_my_temp;
+SET innodb_strict_mode = OFF;
+CREATE TEMPORARY TABLE t_my_temp (a int, b text);
+SHOW CREATE TABLE t_my_temp;
+Table Create Table
+t_my_temp CREATE TEMPORARY TABLE `t_my_temp` (
+ `a` int(11) DEFAULT NULL,
+ `b` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t_my_temp TABLESPACE innodb_temporary;
+Warnings:
+Warning 1478 InnoDB: TABLESPACE=innodb_temporary option is deprecated and will be removed in a future release.
+SHOW WARNINGS;
+Level Code Message
+Warning 1478 InnoDB: TABLESPACE=innodb_temporary option is deprecated and will be removed in a future release.
+SHOW CREATE TABLE t_my_temp;
+Table Create Table
+t_my_temp CREATE TEMPORARY TABLE `t_my_temp` (
+ `a` int(11) DEFAULT NULL,
+ `b` text
+) /*!50100 TABLESPACE `innodb_temporary` */ ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t_my_temp TABLESPACE innodb_file_per_table;
+Warnings:
+Warning 1478 InnoDB: TABLESPACE=innodb_file_per_table option is ignored. This option is deprecated and will be removed in a future release.
+SHOW WARNINGS;
+Level Code Message
+Warning 1478 InnoDB: TABLESPACE=innodb_file_per_table option is ignored. This option is deprecated and will be removed in a future release.
+SHOW CREATE TABLE t_my_temp;
+Table Create Table
+t_my_temp CREATE TEMPORARY TABLE `t_my_temp` (
+ `a` int(11) DEFAULT NULL,
+ `b` text
+) /*!50100 TABLESPACE `innodb_file_per_table` */ ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t_my_temp;
+SET innodb_strict_mode = ON;
+CREATE TEMPORARY TABLE t_my_temp (a int, b text);
+SHOW CREATE TABLE t_my_temp;
+Table Create Table
+t_my_temp CREATE TEMPORARY TABLE `t_my_temp` (
+ `a` int(11) DEFAULT NULL,
+ `b` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t_my_temp TABLESPACE=innodb_file_per_table;
+ERROR HY000: InnoDB: TABLESPACE=innodb_file_per_table option is disallowed for temporary tables with INNODB_STRICT_NODE=ON. This option is deprecated and will be removed in a future release
+ALTER TABLE t_my_temp TABLESPACE=innodb_temporary;
+Warnings:
+Warning 1478 InnoDB: TABLESPACE=innodb_temporary option is deprecated and will be removed in a future release.
+SHOW WARNINGS;
+Level Code Message
+Warning 1478 InnoDB: TABLESPACE=innodb_temporary option is deprecated and will be removed in a future release.
SHOW CREATE TABLE t_my_temp;
Table Create Table
t_my_temp CREATE TEMPORARY TABLE `t_my_temp` (
diff --git a/mysql-test/suite/innodb/r/create_tablespace_partition.result b/mysql-test/suite/innodb/r/create_tablespace_partition.result
index 50d1cf34c8fd..eb2f724a93b1 100644
--- a/mysql-test/suite/innodb/r/create_tablespace_partition.result
+++ b/mysql-test/suite/innodb/r/create_tablespace_partition.result
@@ -22,6 +22,8 @@ SUBPARTITION subpart24),
PARTITION thousands VALUES LESS THAN (10000)
(SUBPARTITION subpart31,
SUBPARTITION subpart32));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SET GLOBAL innodb_file_per_table = ON;
CREATE TABLE t2 (a INT, b INT)
ENGINE = InnoDB
@@ -35,11 +37,15 @@ SUBPARTITION subpart22 TABLESPACE=`s``1`),
PARTITION thousands VALUES LESS THAN (10000)
(SUBPARTITION subpart31 DATA DIRECTORY 'MYSQL_TMP_DIR',
SUBPARTITION subpart32 DATA DIRECTORY 'MYSQL_TMP_DIR' TABLESPACE `innodb_file_per_table`));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE t1 ALGORITHM=COPY, ADD PARTITION
(PARTITION tenthousands VALUES LESS THAN (20000));
ERROR 0A000: ALGORITHM=COPY/INPLACE is not supported. Reason: Partition specific operations do not yet support LOCK/ALGORITHM. Try ALGORITHM=DEFAULT.
ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION tenthousands VALUES LESS THAN (20000));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
# Only allow tablespace name as ident, not text. I.e. no 'single' quotes.
ALTER TABLE t1 ALGORITHM=COPY, ADD PARTITION
(PARTITION twentythousands VALUES LESS THAN (30000)
@@ -60,6 +66,8 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION twentythousands VALUES LESS THAN (30000)
TABLESPACE = "innodb_system");
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION thirtythousands VALUES LESS THAN (40000)
TABLESPACE = `innodb_file_per_table`);
@@ -99,9 +107,13 @@ SUBPARTITION p40k_2 TABLESPACE = innodb_file_per_table DATA DIRECTORY = 'MYSQL_T
SET GLOBAL innodb_file_per_table = OFF;
ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION fiftythousands VALUES LESS THAN (60000));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION sixtythousands VALUES LESS THAN (70000)
TABLESPACE = `innodb_system`);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION seventythousands VALUES LESS THAN (80000)
TABLESPACE = `innodb_file_per_table`);
@@ -121,6 +133,8 @@ ALTER TABLE t1 ALGORITHM=DEFAULT, ADD PARTITION
(PARTITION ninetythousands VALUES LESS THAN (100000)
(SUBPARTITION p90k_1 TABLESPACE = `innodb_file_per_table`,
SUBPARTITION p90k_2 TABLESPACE = `innodb_system`));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
FLUSH TABLES;
=== information_schema.innodb_sys_tables and innodb_sys_tablespaces ===
Table Name Tablespace Table Flags Columns Row Format Zip Size Space Type
@@ -388,6 +402,8 @@ SUBPARTITION seventythousandssp1 ENGINE = InnoDB),
PARTITION ninetythousands VALUES LESS THAN (100000)
(SUBPARTITION p90k_1 ENGINE = InnoDB,
SUBPARTITION p90k_2 TABLESPACE = innodb_system ENGINE = InnoDB)) */;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL
@@ -403,6 +419,8 @@ SUBPARTITION subpart22 TABLESPACE = `s``1` ENGINE = InnoDB),
PARTITION thousands VALUES LESS THAN (10000)
(SUBPARTITION subpart31 ENGINE = InnoDB,
SUBPARTITION subpart32 ENGINE = InnoDB)) */;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
=== information_schema.innodb_sys_tables and innodb_sys_tablespaces ===
Table Name Tablespace Table Flags Columns Row Format Zip Size Space Type
test/t1#p#fiftythousands#sp#fiftythousandssp0 s1 161 5 Dynamic 0 General
@@ -531,6 +549,8 @@ CREATE TABLE ti
ENGINE=INNODB
PARTITION BY HASH( MONTH(tr_date) )
PARTITIONS 6;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
DROP TABLE t1,ti;
DROP TABLESPACE ts1;
#
diff --git a/mysql-test/suite/innodb/r/deprecate_part_in_shared_ts.result b/mysql-test/suite/innodb/r/deprecate_part_in_shared_ts.result
new file mode 100644
index 000000000000..9818b99a586a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/deprecate_part_in_shared_ts.result
@@ -0,0 +1,130 @@
+CREATE TABLESPACE ts add datafile 'ts.ibd';
+#########################################################################
+# Partitioned Table #
+#########################################################################
+
+DROP TABLE IF EXISTS t1;
+# Create table without explicit tablespace name
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30));
+# Try to ALTER TABLE to have general tablespace at table level
+ALTER TABLE t1 TABLESPACE=ts;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+DROP TABLE t1;
+# Create table with general tablespace at table level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+TABLESPACE=ts
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+DROP TABLE t1;
+# Create table with system tablespace at table level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+TABLESPACE=innodb_system
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+DROP TABLE t1;
+# Create table with innodb_file_per_table tablespace at table level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+TABLESPACE=innodb_file_per_table
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30));
+DROP TABLE t1;
+# Create table with general tablespace at partition level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30) TABLESPACE=ts);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+DROP TABLE t1;
+# Create table with system tablespace at partition level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30) TABLESPACE=innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+DROP TABLE t1;
+# Create table with innodb_file_per_table tablespace at partition level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+PARTITION BY RANGE(id) (
+PARTITION p0 VALUES LESS THAN (10),
+PARTITION p1 VALUES LESS THAN (20),
+PARTITION p2 VALUES LESS THAN (30),
+PARTITION p3 VALUES LESS THAN (40) TABLESPACE=innodb_file_per_table);
+# Alter table to move a partition to general tablespace.
+ALTER TABLE t1 REORGANIZE PARTITION P0 INTO (
+PARTITION P0 VALUES LESS THAN (10) TABLESPACE=ts);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+# Alter table to move a partition to system tablespace.
+ALTER TABLE t1 REORGANIZE PARTITION P1 INTO (
+PARTITION P1 VALUES LESS THAN (20) TABLESPACE=innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+# Alter table to move a partition to file_per_table tablespace.
+ALTER TABLE t1 REORGANIZE PARTITION P2 INTO (
+PARTITION P2 VALUES LESS THAN (30) TABLESPACE=innodb_file_per_table);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `name` varchar(50) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (id)
+(PARTITION P0 VALUES LESS THAN (10) TABLESPACE = `ts` ENGINE = InnoDB,
+ PARTITION P1 VALUES LESS THAN (20) TABLESPACE = `innodb_system` ENGINE = InnoDB,
+ PARTITION P2 VALUES LESS THAN (30) TABLESPACE = `innodb_file_per_table` ENGINE = InnoDB,
+ PARTITION p3 VALUES LESS THAN (40) TABLESPACE = `innodb_file_per_table` ENGINE = InnoDB) */
+# Alter table to add a new partition in general tablespace
+ALTER TABLE t1 ADD PARTITION (
+PARTITION p4 VALUES LESS THAN (50) tablespace=ts);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+# Alter table to add a new partition in innodb_system tablespace
+ALTER TABLE t1 ADD PARTITION (
+PARTITION p5 VALUES LESS THAN (60) tablespace=innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
+# Alter table to add a new partition in innodb_file_per_table tablespace
+ALTER TABLE t1 ADD PARTITION (
+PARTITION p6 VALUES LESS THAN (70) tablespace=innodb_file_per_table);
+# Alter table to add a new partition without giving tablespace
+ALTER TABLE t1 ADD PARTITION (
+PARTITION p7 VALUES LESS THAN (80));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `name` varchar(50) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (id)
+(PARTITION P0 VALUES LESS THAN (10) TABLESPACE = `ts` ENGINE = InnoDB,
+ PARTITION P1 VALUES LESS THAN (20) TABLESPACE = `innodb_system` ENGINE = InnoDB,
+ PARTITION P2 VALUES LESS THAN (30) TABLESPACE = `innodb_file_per_table` ENGINE = InnoDB,
+ PARTITION p3 VALUES LESS THAN (40) TABLESPACE = `innodb_file_per_table` ENGINE = InnoDB,
+ PARTITION p4 VALUES LESS THAN (50) TABLESPACE = `ts` ENGINE = InnoDB,
+ PARTITION p5 VALUES LESS THAN (60) TABLESPACE = `innodb_system` ENGINE = InnoDB,
+ PARTITION p6 VALUES LESS THAN (70) TABLESPACE = `innodb_file_per_table` ENGINE = InnoDB,
+ PARTITION p7 VALUES LESS THAN (80) ENGINE = InnoDB) */
+###########
+# Cleanup #
+###########
+DROP TABLE t1;
+DROP TABLESPACE ts;
diff --git a/mysql-test/suite/innodb/r/events-merge-tmp-path.result b/mysql-test/suite/innodb/r/events-merge-tmp-path.result
new file mode 100644
index 000000000000..ce85f2329b12
--- /dev/null
+++ b/mysql-test/suite/innodb/r/events-merge-tmp-path.result
@@ -0,0 +1,19 @@
+update performance_schema.setup_instruments set enabled='YES' where name like '%innodb_temp%';
+update performance_schema.setup_consumers set enabled='YES';
+use test;
+CREATE TABLE `t1`(`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `name1` varchar(180) NOT NULL, `name2` varchar(180) DEFAULT NULL, `name3` varchar(180) DEFAULT NULL, `name4` varchar(180) DEFAULT NULL, PRIMARY KEY (`id`,`name1`(10)) ) engine=InnoDB;
+set @id:=0;
+insert into t1 values
+(@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000))
+, (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000))
+, (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000))
+, (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000));
+insert into `t1`(`id`,`name1`,`name2`,`name3`,`name4`)
+select @id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000) from
+`t1` k1, `t1` k2, `t1` k3, `t1` k4,`t1` k5,`t1` k6;
+create index i_dtyp_big on `t1`(name1) algorithm=inplace;
+select distinct object_name from performance_schema.events_waits_history_long where event_name like '%wait%io%file%innodb%innodb_temp_file%'
+and object_name like '%Innodb Merge Temp File%';
+object_name
+MYSQL_TEST_DIR#Innodb Merge Temp File
+drop table t1;
diff --git a/mysql-test/suite/innodb/r/general_ts_encrypt.result b/mysql-test/suite/innodb/r/general_ts_encrypt.result
index 7050830d2cf2..8874ace954a8 100644
--- a/mysql-test/suite/innodb/r/general_ts_encrypt.result
+++ b/mysql-test/suite/innodb/r/general_ts_encrypt.result
@@ -58,17 +58,27 @@ PARTITION BY RANGE (a) PARTITIONS 3 (
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (40) TABLESPACE innodb_file_per_table,
PARTITION p3 VALUES LESS THAN (60) TABLESPACE innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
CREATE TABLE pt2 (a INT NOT NULL, PRIMARY KEY(a))
ENGINE=InnoDB TABLESPACE ts_encrypted ENCRYPTION='y'
PARTITION BY RANGE (a) PARTITIONS 3 (
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (40) TABLESPACE innodb_file_per_table,
PARTITION p3 VALUES LESS THAN (60) TABLESPACE ts_encrypted_new);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE pt1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (80) TABLESPACE ts_unencrypted_new);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE pt1 ADD PARTITION (PARTITION p5 VALUES LESS THAN (100) TABLESPACE ts_encrypted);
ERROR HY000: InnoDB: Tablespace `ts_encrypted` can contain only an ENCRYPTED tables.
ALTER TABLE pt1 ADD PARTITION (PARTITION p6 VALUES LESS THAN (120) TABLESPACE innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE pt2 ADD PARTITION (PARTITION p4 VALUES LESS THAN (80) TABLESPACE ts_encrypted_new);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE pt2 ADD PARTITION (PARTITION p5 VALUES LESS THAN (100) TABLESPACE ts_unencrypted);
ERROR HY000: InnoDB: Tablespace `ts_unencrypted` cannot contain an ENCRYPTED table.
ALTER TABLE pt2 ADD PARTITION (PARTITION p6 VALUES LESS THAN (120) TABLESPACE innodb_system);
@@ -88,6 +98,8 @@ PARTITION p3 VALUES LESS THAN (60) TABLESPACE innodb_system (
SUBPARTITION p31 TABLESPACE ts_unencrypted,
SUBPARTITION p32 TABLESPACE innodb_file_per_table,
SUBPARTITION p33 TABLESPACE ts_unencrypted_new));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE spt1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (130) (
SUBPARTITION p41 TABLESPACE ts_unencrypted,
SUBPARTITION p42 TABLESPACE ts_encrypted,
@@ -97,10 +109,14 @@ ALTER TABLE spt1 ADD PARTITION (PARTITION p5 VALUES LESS THAN (140) (
SUBPARTITION p51 TABLESPACE ts_unencrypted,
SUBPARTITION p52 TABLESPACE innodb_system,
SUBPARTITION p53 TABLESPACE ts_unencrypted_new));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE spt1 ADD PARTITION (PARTITION p6 VALUES LESS THAN (150) TABLESPACE ts_encrypted (
SUBPARTITION p61 TABLESPACE ts_unencrypted,
SUBPARTITION p62 TABLESPACE innodb_system,
SUBPARTITION p63 TABLESPACE ts_unencrypted_new));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
CREATE TABLE spt2 (a INT NOT NULL, b INT)
ENGINE=InnoDB TABLESPACE ts_encrypted ENCRYPTION='y'
PARTITION BY RANGE (a) PARTITIONS 3 SUBPARTITION BY KEY (b) (
@@ -116,6 +132,8 @@ PARTITION p3 VALUES LESS THAN (60) TABLESPACE ts_encrypted_new (
SUBPARTITION p31 TABLESPACE ts_encrypted,
SUBPARTITION p32 TABLESPACE innodb_file_per_table,
SUBPARTITION p33 TABLESPACE ts_encrypted_new));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE spt2 ADD PARTITION (PARTITION p4 VALUES LESS THAN (130) (
SUBPARTITION p41 TABLESPACE ts_encrypted,
SUBPARTITION p42 TABLESPACE ts_unencrypted,
@@ -125,10 +143,14 @@ ALTER TABLE spt2 ADD PARTITION (PARTITION p5 VALUES LESS THAN (140) (
SUBPARTITION p51 TABLESPACE ts_encrypted,
SUBPARTITION p52 TABLESPACE ts_encrypted_new,
SUBPARTITION p53 TABLESPACE ts_encrypted_new));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE spt2 ADD PARTITION (PARTITION p6 VALUES LESS THAN (150) TABLESPACE ts_unencrypted (
SUBPARTITION p61 TABLESPACE ts_encrypted,
SUBPARTITION p62 TABLESPACE ts_encrypted_new,
SUBPARTITION p63 TABLESPACE ts_encrypted_new));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE spt2 ADD PARTITION (PARTITION p7 VALUES LESS THAN (160) (
SUBPARTITION p71 ENGINE=MyISAM,
SUBPARTITION p72 ENGINE=MyISAM,
diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result
index c6fa1ed0072b..c25e2582736e 100644
--- a/mysql-test/suite/innodb/r/innodb-alter-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result
@@ -41,7 +41,7 @@ ERROR 23000: Duplicate entry '1' for key 'uk'
SET DEBUG_SYNC = 'now SIGNAL s2';
/* connection default */
/* reap */ alter table t1 add b int, ALGORITHM=inplace;
-ERROR 23000: Duplicate entry '3' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '1' for key 'uk'
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL s1 WAIT_FOR s2';
alter table t1 add b int, ALGORITHM=inplace;;
/* connection con1 */
@@ -51,5 +51,25 @@ ERROR 23000: Duplicate entry '1' for key 'uk'
SET DEBUG_SYNC = 'now SIGNAL s2';
/* connection default */
/* reap */ alter table t1 add b int, ALGORITHM=inplace;
-ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '1' for key 'uk'
drop table t1;
+#
+# Bug #27753193 ASSERTION `PREBUILT->TRX->ERROR_KEY_NUM <
+# HA_ALTER_INFO->KEY_COUNT'
+CREATE TABLE t1 (a INT, UNIQUE KEY(a)) ENGINE = INNODB;
+INSERT INTO t1 VALUES (1);
+SET DEBUG_SYNC = 'row_log_table_apply1_before signal S1 WAIT_FOR S2';
+OPTIMIZE TABLE t1;;
+SET DEBUG_SYNC = 'now WAIT_FOR S1';
+INSERT INTO t1 VALUES (1);
+ERROR 23000: Duplicate entry '1' for key 'a'
+SET DEBUG_SYNC = 'now SIGNAL S2';
+/* reap */ OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize error Duplicate entry '1' for key 'a'
+test.t1 optimize status Operation failed
+Warnings:
+Error 1062 Duplicate entry '1' for key 'a'
+SET DEBUG_SYNC='RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb_tablespace.result b/mysql-test/suite/innodb/r/innodb_tablespace.result
index 5cb82e45012c..b6fb5afedf5e 100644
--- a/mysql-test/suite/innodb/r/innodb_tablespace.result
+++ b/mysql-test/suite/innodb/r/innodb_tablespace.result
@@ -582,3 +582,14 @@ FLUSH TABLES t1 FOR EXPORT;
ERROR HY000: Tablespace has been discarded for table 't1'
UNLOCK TABLES;
DROP TABLE t1;
+#
+# Bug#27903881 [MYSQL 8.0 GA RELEASE & DEBUG BUILD]
+# FIL_SPACE_GET(TABLE->SPACE) != __NULL
+#
+call mtr.add_suppression("\\[Warning\\] InnoDB: Missing .ibd file for table `test`\.`t1` .* ");
+CREATE TABLE t1(c1 INT,c2 CHAR,c3 DATE)PARTITION BY HASH(DAYOFWEEK(c3));
+ALTER TABLE t1 DISCARD TABLESPACE;
+FLUSH TABLES t1 FOR EXPORT;
+ERROR HY000: Tablespace has been discarded for table 't1'
+UNLOCK TABLES;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/partition.result b/mysql-test/suite/innodb/r/partition.result
index eaee4a7d6872..4c1b1a12a2ea 100644
--- a/mysql-test/suite/innodb/r/partition.result
+++ b/mysql-test/suite/innodb/r/partition.result
@@ -237,7 +237,11 @@ INDEX (b(5), c(10), a))
ENGINE=InnoDB stats_persistent=DEFAULT
PARTITION BY LINEAR HASH(d) PARTITIONS 2;
ALTER TABLE t1 TABLESPACE ts1;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE t1 DROP PRIMARY KEY, ALGORITHM=DEFAULT;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
DROP TABLE t1;
DROP TABLESPACE ts1;
#
@@ -449,6 +453,8 @@ PARTITION BY RANGE (a) PARTITIONS 3
( PARTITION P1 VALUES LESS THAN (2) TABLESPACE ts1,
PARTITION P2 VALUES LESS THAN (4) TABLESPACE `innodb_system`,
PARTITION P3 VALUES LESS THAN (6));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
ALTER TABLE t1 ADD COLUMN f int;
DROP TABLE t1;
DROP TABLESPACE ts1;
@@ -462,6 +468,8 @@ PARTITION p1 VALUES LESS THAN (100) TABLESPACE innodb_system,
PARTITION p2 VALUES LESS THAN (200),
PARTITION p3 VALUES LESS THAN (300) TABLESPACE ts1,
PARTITION p4 VALUES LESS THAN (400) TABLESPACE innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
FLUSH table t1 FOR EXPORT;
Warnings:
Warning 1809 InnoDB: Table '`test`.`t1` /* Partition `p1` */' in system tablespace
@@ -558,6 +566,8 @@ PARTITIONS 4
PARTITION p2 VALUES LESS THAN (4) TABLESPACE innodb_system,
PARTITION p3 VALUES LESS THAN (6),
PARTITION p4 VALUES LESS THAN (8) TABLESPACE innodb_file_per_table);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -605,6 +615,8 @@ test/t1#p#p2 System NULL
test/t1#p#p3 General ts2
test/t1#p#p4 Single test/t1#p#p4
ALTER TABLE t1 ADD COLUMN c int, TABLESPACE ts1;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -630,6 +642,8 @@ test/t1#p#p2 System NULL
test/t1#p#p3 General ts2
test/t1#p#p4 Single test/t1#p#p4
ALTER TABLE t1 ADD PARTITION (PARTITION p5 VALUES LESS THAN (10) TABLESPACE ts2);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -657,6 +671,8 @@ test/t1#p#p3 General ts2
test/t1#p#p4 Single test/t1#p#p4
test/t1#p#p5 General ts2
ALTER TABLE t1 ADD PARTITION (PARTITION p6 VALUES LESS THAN (12));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -686,6 +702,8 @@ test/t1#p#p4 Single test/t1#p#p4
test/t1#p#p5 General ts2
test/t1#p#p6 General ts1
ALTER TABLE t1 REORGANIZE PARTITION p4 INTO (PARTITION p4 VALUES LESS THAN (8));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -715,6 +733,8 @@ test/t1#p#p4 General ts1
test/t1#p#p5 General ts2
test/t1#p#p6 General ts1
ALTER TABLE t1 REORGANIZE PARTITION p3 INTO (PARTITION p3 VALUES LESS THAN (6) TABLESPACE innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -752,6 +772,8 @@ PARTITIONS 4
PARTITION p2 VALUES LESS THAN (4) TABLESPACE innodb_system,
PARTITION p3 VALUES LESS THAN (6),
PARTITION p4 VALUES LESS THAN (8) TABLESPACE innodb_file_per_table);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -799,6 +821,8 @@ test/t1#p#p2 System NULL
test/t1#p#p3 Single test/t1#p#p3
test/t1#p#p4 Single test/t1#p#p4
ALTER TABLE t1 ADD COLUMN c int, TABLESPACE ts1;
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -824,6 +848,8 @@ test/t1#p#p2 System NULL
test/t1#p#p3 Single test/t1#p#p3
test/t1#p#p4 Single test/t1#p#p4
ALTER TABLE t1 ADD PARTITION (PARTITION p5 VALUES LESS THAN (10) TABLESPACE ts2);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -851,6 +877,8 @@ test/t1#p#p3 Single test/t1#p#p3
test/t1#p#p4 Single test/t1#p#p4
test/t1#p#p5 General ts2
ALTER TABLE t1 ADD PARTITION (PARTITION p6 VALUES LESS THAN (12));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -880,6 +908,8 @@ test/t1#p#p4 Single test/t1#p#p4
test/t1#p#p5 General ts2
test/t1#p#p6 General ts1
ALTER TABLE t1 REORGANIZE PARTITION p4 INTO (PARTITION p4 VALUES LESS THAN (8));
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -909,6 +939,8 @@ test/t1#p#p4 General ts1
test/t1#p#p5 General ts2
test/t1#p#p6 General ts1
ALTER TABLE t1 REORGANIZE PARTITION p3 INTO (PARTITION p3 VALUES LESS THAN (6) TABLESPACE innodb_system);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/suite/innodb/r/percona_force_encryption.result b/mysql-test/suite/innodb/r/percona_force_encryption.result
index 25cfc8ec3042..5131ca5f9797 100644
--- a/mysql-test/suite/innodb/r/percona_force_encryption.result
+++ b/mysql-test/suite/innodb/r/percona_force_encryption.result
@@ -23,6 +23,8 @@ engine=innodb tablespace ts_encrypted1
partition by range (a) partitions 2 (
partition p1 values less than (20),
partition p2 values less than (40) tablespace ts_encrypted2);
+Warnings:
+Warning 1681 'InnoDB : A table partition in a shared tablespace' is deprecated and will be removed in a future release.
create table t_unencrypted_tablespace (a text) tablespace ts_unencrypted1 ENGINE="InnoDB";
ERROR HY000: InnoDB: Tablespace `ts_unencrypted1` cannot contain an ENCRYPTED table.
set global innodb_encrypt_tables='OFF';
diff --git a/mysql-test/suite/innodb/r/virtual_debug.result b/mysql-test/suite/innodb/r/virtual_debug.result
index f466f0fe7f32..368f243d47fc 100644
--- a/mysql-test/suite/innodb/r/virtual_debug.result
+++ b/mysql-test/suite/innodb/r/virtual_debug.result
@@ -125,10 +125,10 @@ SET DEBUG_SYNC = 'now SIGNAL go_ahead';
/* connection default */ optimize table t;
Table Op Msg_type Msg_text
test.t optimize note Table does not support optimize, doing recreate + analyze instead
-test.t optimize error Duplicate entry 'NULL' for key 'b'
+test.t optimize error Duplicate entry 'NULL' for key 'c'
test.t optimize status Operation failed
Warnings:
-Error 1062 Duplicate entry 'NULL' for key 'b'
+Error 1062 Duplicate entry 'NULL' for key 'c'
SELECT c FROM t;
c
1
@@ -237,4 +237,18 @@ SELECT * FROM t;
b v
fubar fub
DROP TABLE t;
+#
+# Bug#26375771 INNODB: ASSERTION FAILURE: MACH0DATA.IC:308:VAL > 0X7F
+#
+create table ibstd_07 (a int not null, d int not null, b blob not null, c text, vadcol int as (a+length(d)) stored, vbcol char(2) as (substr(b,2,2)) virtual, vbidxcol char(3) as (substr(b,1,3)) virtual , index(d desc), index(a desc), index(vbidxcol desc), index(vbidxcol desc,d asc), unique key (b(101) desc, a asc, d ), index(c(255) desc, b(255) asc), index(b(5) desc, c(10) asc, a ) ) engine=InnoDB default charset=latin1 row_format=redundant;
+insert into ibstd_07 values (2, 2, repeat('rocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaooc','281'),repeat('ouolrculuouocououooalcoraooaulouuacrolrocooraoaooooolaccralacalooolalocoaacoorarorcurccarocucla','317'), default, default, default);
+SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
+alter table ibstd_07 add primary key (b(11) desc,a asc, d );;
+SET DEBUG_SYNC = 'now WAIT_FOR start_create';
+update ibstd_07 set c=repeat('0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo','70');
+SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+SELECT * FROM ibstd_07;
+a d b c vadcol vbcol vbidxcol
+2 2 rocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaoocrocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaooc 0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo 3 oc roc
+DROP TABLE ibstd_07;
SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/suite/innodb/r/xtradb_compressed_columns_mysqldump.result b/mysql-test/suite/innodb/r/xtradb_compressed_columns_mysqldump.result
index 9b4164dc61a5..b4f6bc60fa19 100644
--- a/mysql-test/suite/innodb/r/xtradb_compressed_columns_mysqldump.result
+++ b/mysql-test/suite/innodb/r/xtradb_compressed_columns_mysqldump.result
@@ -82,11 +82,11 @@ COUNT(*) = 0
1
# Importing SQL dump with compressed columns enabled and dictionaries disabled
Warnings:
-Note 3231 Compression dictionary 'd1' does not exist
+Note 3232 Compression dictionary 'd1' does not exist
Warnings:
-Note 3231 Compression dictionary 'd2' does not exist
+Note 3232 Compression dictionary 'd2' does not exist
Warnings:
-Note 3231 Compression dictionary 'd3' does not exist
+Note 3232 Compression dictionary 'd3' does not exist
number_of_short_rows_in_first_match
1
number_of_long_rows_in_first_match
@@ -99,11 +99,11 @@ COUNT(*) = 0
1
# Importing SQL dump with compressed columns and dictionaries enabled
Warnings:
-Note 3231 Compression dictionary 'd1' does not exist
+Note 3232 Compression dictionary 'd1' does not exist
Warnings:
-Note 3231 Compression dictionary 'd2' does not exist
+Note 3232 Compression dictionary 'd2' does not exist
Warnings:
-Note 3231 Compression dictionary 'd3' does not exist
+Note 3232 Compression dictionary 'd3' does not exist
number_of_short_rows_in_first_match
1
number_of_long_rows_in_first_match
diff --git a/mysql-test/suite/innodb/r/xtradb_compressed_columns_with_dictionaries.result b/mysql-test/suite/innodb/r/xtradb_compressed_columns_with_dictionaries.result
index 7a48ab766b32..3c30a3ee982a 100644
--- a/mysql-test/suite/innodb/r/xtradb_compressed_columns_with_dictionaries.result
+++ b/mysql-test/suite/innodb/r/xtradb_compressed_columns_with_dictionaries.result
@@ -1,14 +1,14 @@
CREATE COMPRESSION_DICTIONARY IF NOT EXISTS ddd('foo');
CREATE COMPRESSION_DICTIONARY IF NOT EXISTS ddd('foo');
Warnings:
-Note 3230 Compression dictionary 'ddd' already exists
+Note 3231 Compression dictionary 'ddd' already exists
CREATE COMPRESSION_DICTIONARY IF NOT EXISTS ddd('bar');
Warnings:
-Note 3230 Compression dictionary 'ddd' already exists
+Note 3231 Compression dictionary 'ddd' already exists
DROP COMPRESSION_DICTIONARY IF EXISTS ddd;
DROP COMPRESSION_DICTIONARY IF EXISTS ddd;
Warnings:
-Note 3231 Compression dictionary 'ddd' does not exist
+Note 3232 Compression dictionary 'ddd' does not exist
CREATE COMPRESSION_DICTIONARY d1('');
CREATE COMPRESSION_DICTIONARY d2(_ucs2'');
CREATE COMPRESSION_DICTIONARY d3('aaaaaaaabbbbbbbbccccccccdddddddd');
diff --git a/mysql-test/suite/innodb/t/bug79821.test b/mysql-test/suite/innodb/t/bug79821.test
new file mode 100644
index 000000000000..27daf16b439b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/bug79821.test
@@ -0,0 +1,18 @@
+--source include/have_innodb.inc
+
+--echo #
+--echo # Bug #22486025 / #79821 "InnoDB: Failing assertion: key_len != 0 || find_flag != HA_READ_KEY_EXACT"
+--echo # fixed in 5.7.21, 8.0.4
+--echo # A "wrong key column" error was added to address an unsupported index creation scenario
+--echo #
+
+SET sql_mode = '';
+CREATE TEMPORARY TABLE t1 (c1 INT NOT NULL) ENGINE=InnoDB;
+CREATE TABLE t1(c1 CHAR(0) NOT NULL);
+DROP TABLE t1;
+ALTER TABLE t1 ADD COLUMN c4 INT COMMENT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
+SET big_tables = 1;
+INSERT INTO t1 VALUES(0, 0);
+--error ER_WRONG_KEY_COLUMN
+SELECT AVG(sum_c1) FROM (SELECT SUM(c1) AS sum_c1 FROM t1 GROUP BY c1) AS t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/bug88747.test b/mysql-test/suite/innodb/t/bug88747.test
new file mode 100644
index 000000000000..5d9e6d5ac569
--- /dev/null
+++ b/mysql-test/suite/innodb/t/bug88747.test
@@ -0,0 +1,23 @@
+--source include/have_innodb.inc
+
+--echo #
+--echo # Bug #27216817 / #88747 "InnoDB: Failing assertion: prebuilt->table->n_mysql_handles_opened == 1"
+--echo # fixed in 5.5.60, 5.6.40, 5.7.22, 8.0.11
+--echo # Adding a unique index to an InnoDB table on which multiple locks were
+--echo # held could raise an assertion
+--echo #
+
+CREATE TABLE t1(
+ c1 INT NOT NULL,
+ c2 TIMESTAMP NOT NULL,
+ c3 INT NULL,
+ c4 CHAR(1) NOT NULL
+) ENGINE=InnoDB;
+
+LOCK TABLES t1 WRITE, t1 AS a READ;
+
+ALTER TABLE t1 ADD PRIMARY KEY(c1);
+
+UNLOCK TABLES;
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/bug88782.test b/mysql-test/suite/innodb/t/bug88782.test
new file mode 100644
index 000000000000..807dac2696f6
--- /dev/null
+++ b/mysql-test/suite/innodb/t/bug88782.test
@@ -0,0 +1,22 @@
+--source include/have_innodb.inc
+
+--echo #
+--echo # Bug #27225649, #27229072 / #88782 "Failing assertion: prebuilt->sql_stat_start || prebuilt->select_lock_type != LOC"
+--echo # fixed in 5.5.60, 5.6.40, 5.7.22, 8.0.11
+--echo # InnoDB: A REPLACE operation on a temporary table raised an assertion
+--echo #
+
+CREATE TEMPORARY TABLE t2(c1 INT);
+CREATE TEMPORARY TABLE t1(a int) ENGINE=InnoDB;
+
+ALTER TABLE t1 ADD UNIQUE INDEX(a);
+
+LOCK TABLES t1 READ, t2 READ;
+
+INSERT INTO t2 VALUES(8403+0.75);
+--error ER_BAD_FIELD_ERROR
+SELECT DAYNAME(c1) FROM t1;
+INSERT INTO t1 VALUES(0xAFBA);
+
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1 SELECT * FROM t2;
diff --git a/mysql-test/suite/innodb/t/create_tablespace.test b/mysql-test/suite/innodb/t/create_tablespace.test
index fcc8a2b15e1f..47b7adb2b183 100644
--- a/mysql-test/suite/innodb/t/create_tablespace.test
+++ b/mysql-test/suite/innodb/t/create_tablespace.test
@@ -787,10 +787,42 @@ ALTER TABLE t_not_temp TABLESPACE=`innodb_temporary`;
SHOW WARNINGS;
DROP TABLE t_not_temp;
+--echo #
+--echo # Try to create or move a temporary table in innodb_file_per_table
+--echo # or innodb_temporary tablespaces with STRICT_MODE ON and OFF
+--echo #
CREATE TEMPORARY TABLE t_my_temp (a int, b text) TABLESPACE=`innodb_temporary`;
SHOW CREATE TABLE t_my_temp;
DROP TABLE t_my_temp;
+SET innodb_strict_mode = OFF;
+
+CREATE TEMPORARY TABLE t_my_temp (a int, b text);
+SHOW CREATE TABLE t_my_temp;
+
+ALTER TABLE t_my_temp TABLESPACE innodb_temporary;
+SHOW WARNINGS;
+SHOW CREATE TABLE t_my_temp;
+
+ALTER TABLE t_my_temp TABLESPACE innodb_file_per_table;
+SHOW WARNINGS;
+SHOW CREATE TABLE t_my_temp;
+
+DROP TABLE t_my_temp;
+
+SET innodb_strict_mode = ON;
+CREATE TEMPORARY TABLE t_my_temp (a int, b text);
+SHOW CREATE TABLE t_my_temp;
+
+--error ER_ILLEGAL_HA_CREATE_OPTION
+ALTER TABLE t_my_temp TABLESPACE=innodb_file_per_table;
+
+ALTER TABLE t_my_temp TABLESPACE=innodb_temporary;
+SHOW WARNINGS;
+SHOW CREATE TABLE t_my_temp;
+
+DROP TABLE t_my_temp;
+
--echo #
--echo # Try to create or move a table into the redo tablespace
--echo # or any tablespace using the reserved `innodb_` prefix.
diff --git a/mysql-test/suite/innodb/t/deprecate_part_in_shared_ts.test b/mysql-test/suite/innodb/t/deprecate_part_in_shared_ts.test
new file mode 100644
index 000000000000..4deb332b2f8b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/deprecate_part_in_shared_ts.test
@@ -0,0 +1,119 @@
+################################################################################
+# Test case to test deprecation warning message to be thrown when a partition #
+# of a partitioned table is found in a shared tablespace. #
+# #
+# This test case will test #
+# - Partitioned Table create/alter with different combination of tablespace #
+# at table level and partition level. #
+################################################################################
+
+--source include/no_valgrind_without_big.inc
+CREATE TABLESPACE ts add datafile 'ts.ibd';
+
+--echo #########################################################################
+--echo # Partitioned Table #
+--echo #########################################################################
+--echo
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo # Create table without explicit tablespace name
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30));
+
+--echo # Try to ALTER TABLE to have general tablespace at table level
+ALTER TABLE t1 TABLESPACE=ts;
+DROP TABLE t1;
+
+--echo # Create table with general tablespace at table level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ TABLESPACE=ts
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30));
+DROP TABLE t1;
+
+--echo # Create table with system tablespace at table level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ TABLESPACE=innodb_system
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30));
+DROP TABLE t1;
+
+--echo # Create table with innodb_file_per_table tablespace at table level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ TABLESPACE=innodb_file_per_table
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30));
+DROP TABLE t1;
+
+--echo # Create table with general tablespace at partition level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30) TABLESPACE=ts);
+DROP TABLE t1;
+
+--echo # Create table with system tablespace at partition level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30) TABLESPACE=innodb_system);
+DROP TABLE t1;
+
+--echo # Create table with innodb_file_per_table tablespace at partition level
+CREATE TABLE t1 (id INT, name VARCHAR(50))
+ PARTITION BY RANGE(id) (
+ PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p1 VALUES LESS THAN (20),
+ PARTITION p2 VALUES LESS THAN (30),
+ PARTITION p3 VALUES LESS THAN (40) TABLESPACE=innodb_file_per_table);
+
+--echo # Alter table to move a partition to general tablespace.
+ALTER TABLE t1 REORGANIZE PARTITION P0 INTO (
+ PARTITION P0 VALUES LESS THAN (10) TABLESPACE=ts);
+
+--echo # Alter table to move a partition to system tablespace.
+ALTER TABLE t1 REORGANIZE PARTITION P1 INTO (
+ PARTITION P1 VALUES LESS THAN (20) TABLESPACE=innodb_system);
+
+--echo # Alter table to move a partition to file_per_table tablespace.
+ALTER TABLE t1 REORGANIZE PARTITION P2 INTO (
+ PARTITION P2 VALUES LESS THAN (30) TABLESPACE=innodb_file_per_table);
+
+SHOW CREATE TABLE t1;
+
+--echo # Alter table to add a new partition in general tablespace
+ALTER TABLE t1 ADD PARTITION (
+ PARTITION p4 VALUES LESS THAN (50) tablespace=ts);
+
+--echo # Alter table to add a new partition in innodb_system tablespace
+ALTER TABLE t1 ADD PARTITION (
+ PARTITION p5 VALUES LESS THAN (60) tablespace=innodb_system);
+
+--echo # Alter table to add a new partition in innodb_file_per_table tablespace
+ALTER TABLE t1 ADD PARTITION (
+ PARTITION p6 VALUES LESS THAN (70) tablespace=innodb_file_per_table);
+
+--echo # Alter table to add a new partition without giving tablespace
+ALTER TABLE t1 ADD PARTITION (
+ PARTITION p7 VALUES LESS THAN (80));
+
+SHOW CREATE TABLE t1;
+
+--echo ###########
+--echo # Cleanup #
+--echo ###########
+DROP TABLE t1;
+DROP TABLESPACE ts;
diff --git a/mysql-test/suite/innodb/t/events-merge-tmp-path-master.opt b/mysql-test/suite/innodb/t/events-merge-tmp-path-master.opt
new file mode 100644
index 000000000000..0467aea4f12b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/events-merge-tmp-path-master.opt
@@ -0,0 +1 @@
+--performance_schema_events_waits_history_long_size=100000 --innodb_sort_buffer_size=64k --innodb-buffer-pool-size=8M --tmpdir=$MYSQLTEST_VARDIR_ABS
diff --git a/mysql-test/suite/innodb/t/events-merge-tmp-path.test b/mysql-test/suite/innodb/t/events-merge-tmp-path.test
new file mode 100644
index 000000000000..584ec92dfcc1
--- /dev/null
+++ b/mysql-test/suite/innodb/t/events-merge-tmp-path.test
@@ -0,0 +1,31 @@
+### test to check if performance_schema.events_waits_history_long
+### reflects correct data
+
+### disable for embedded server
+--source include/not_embedded.inc
+update performance_schema.setup_instruments set enabled='YES' where name like '%innodb_temp%';
+update performance_schema.setup_consumers set enabled='YES';
+use test;
+CREATE TABLE `t1`(`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `name1` varchar(180) NOT NULL, `name2` varchar(180) DEFAULT NULL, `name3` varchar(180) DEFAULT NULL, `name4` varchar(180) DEFAULT NULL, PRIMARY KEY (`id`,`name1`(10)) ) engine=InnoDB;
+ set @id:=0;
+
+### populate random data
+ insert into t1 values
+ (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000))
+, (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000))
+, (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000))
+, (@id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000));
+insert into `t1`(`id`,`name1`,`name2`,`name3`,`name4`)
+select @id:=@id+1,md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000),md5(rand()*1000000) from
+`t1` k1, `t1` k2, `t1` k3, `t1` k4,`t1` k5,`t1` k6;
+
+#create inplace index and check if data is mention in events_waits_h
+create index i_dtyp_big on `t1`(name1) algorithm=inplace;
+
+--replace_regex /[\\\/]Innodb Merge Temp File/#Innodb Merge Temp File/
+--replace_result $MYSQLTEST_VARDIR_ABS MYSQL_TEST_DIR
+
+select distinct object_name from performance_schema.events_waits_history_long where event_name like '%wait%io%file%innodb%innodb_temp_file%'
+and object_name like '%Innodb Merge Temp File%';
+drop table t1;
+
diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test
index 59cc1307c848..b964d61c3001 100644
--- a/mysql-test/suite/innodb/t/innodb-alter-debug.test
+++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test
@@ -76,3 +76,31 @@ drop table t1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+
+--echo #
+--echo # Bug #27753193 ASSERTION `PREBUILT->TRX->ERROR_KEY_NUM <
+--echo # HA_ALTER_INFO->KEY_COUNT'
+
+CREATE TABLE t1 (a INT, UNIQUE KEY(a)) ENGINE = INNODB;
+INSERT INTO t1 VALUES (1);
+
+SET DEBUG_SYNC = 'row_log_table_apply1_before signal S1 WAIT_FOR S2';
+--send OPTIMIZE TABLE t1;
+
+CONNECT (con1,localhost,root,,);
+CONNECTION con1;
+SET DEBUG_SYNC = 'now WAIT_FOR S1';
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES (1);
+SET DEBUG_SYNC = 'now SIGNAL S2';
+
+CONNECTION default;
+--echo /* reap */ OPTIMIZE TABLE t1;
+--reap
+DISCONNECT con1;
+SET DEBUG_SYNC='RESET';
+
+DROP TABLE t1;
+
+# Wait till all disconnects are completed
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/innodb_tablespace.test b/mysql-test/suite/innodb/t/innodb_tablespace.test
index 43b69f6c9f6f..85e61dccb8b6 100644
--- a/mysql-test/suite/innodb/t/innodb_tablespace.test
+++ b/mysql-test/suite/innodb/t/innodb_tablespace.test
@@ -422,3 +422,14 @@ FLUSH TABLES t1 FOR EXPORT;
UNLOCK TABLES;
DROP TABLE t1;
+--echo #
+--echo # Bug#27903881 [MYSQL 8.0 GA RELEASE & DEBUG BUILD]
+--echo # FIL_SPACE_GET(TABLE->SPACE) != __NULL
+--echo #
+call mtr.add_suppression("\\[Warning\\] InnoDB: Missing .ibd file for table `test`\.`t1` .* ");
+CREATE TABLE t1(c1 INT,c2 CHAR,c3 DATE)PARTITION BY HASH(DAYOFWEEK(c3));
+ALTER TABLE t1 DISCARD TABLESPACE;
+--error ER_TABLESPACE_DISCARDED
+FLUSH TABLES t1 FOR EXPORT;
+UNLOCK TABLES;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/virtual_debug.test b/mysql-test/suite/innodb/t/virtual_debug.test
index 74838c2250b3..a589cd0d497e 100644
--- a/mysql-test/suite/innodb/t/virtual_debug.test
+++ b/mysql-test/suite/innodb/t/virtual_debug.test
@@ -281,6 +281,32 @@ CHECK TABLE t;
SELECT * FROM t;
DROP TABLE t;
+--echo #
+--echo # Bug#26375771 INNODB: ASSERTION FAILURE: MACH0DATA.IC:308:VAL > 0X7F
+--echo #
+create table ibstd_07 (a int not null, d int not null, b blob not null, c text, vadcol int as (a+length(d)) stored, vbcol char(2) as (substr(b,2,2)) virtual, vbidxcol char(3) as (substr(b,1,3)) virtual , index(d desc), index(a desc), index(vbidxcol desc), index(vbidxcol desc,d asc), unique key (b(101) desc, a asc, d ), index(c(255) desc, b(255) asc), index(b(5) desc, c(10) asc, a ) ) engine=InnoDB default charset=latin1 row_format=redundant;
+
+insert into ibstd_07 values (2, 2, repeat('rocalrulcrcaurcuccoolrouuocacaooaucauualcucuoucucclolcllloocuarcoorlaccarocouuaoorcolloucraoaaooc','281'),repeat('ouolrculuouocououooalcoraooaulouuacrolrocooraoaooooolaccralacalooolalocoaacoorarorcurccarocucla','317'), default, default, default);
+
+
+SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
+--send alter table ibstd_07 add primary key (b(11) desc,a asc, d );
+
+# Do a concurrent update
+connection con1;
+SET DEBUG_SYNC = 'now WAIT_FOR start_create';
+
+update ibstd_07 set c=repeat('0.366710324443464crllooolarlollorlulololucrluacoorrrluroluroocouauacacruloulcurlraorcrclrolcocrrcoccolourrooclrcocruruauallo','70');
+
+
+SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+
+connection default;
+reap;
+
+SELECT * FROM ibstd_07;
+DROP TABLE ibstd_07;
+
disconnect con1;
SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/suite/innodb/t/virtual_index.test b/mysql-test/suite/innodb/t/virtual_index.test
index 9f875a7b5a8a..1faba4ba5db4 100644
--- a/mysql-test/suite/innodb/t/virtual_index.test
+++ b/mysql-test/suite/innodb/t/virtual_index.test
@@ -228,3 +228,38 @@ ALTER TABLE t1 ADD col2 char(21) AS (col1 * col1), ADD INDEX n (col2);
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+#Disable the test case because it's being failed on ASAN.
+#TODO : Bug #28556793 INNODB UPDATE_ROW ASAN FAILURE HEAP-USE-AFTER-FREE
+if (0)
+{
+ --echo #
+ --echo # Bug #27968952 INNODB CRASH/CORRUPTION WITH TEXT PREFIX INDEXES
+ SET sql_mode='';
+ CREATE TABLE t1(
+ a INT not null,
+ b CHAR(4) not null,
+ c TEXT GENERATED ALWAYS AS ((a <> b)) VIRTUAL,
+ UNIQUE KEY i1 (a),
+ UNIQUE KEY i2 (c(1))
+ ) ENGINE=INNODB;
+ insert into t1 set a=1;
+ insert into t1 set a=0;
+ replace into t1 set b ='1';
+ DROP TABLE t1;
+
+ SET names utf8;
+ CREATE TABLE t1 (
+ a VARCHAR(1000) GENERATED ALWAYS AS ('1') VIRTUAL,
+ b VARCHAR(1000) NOT NULL,
+ c VARCHAR(1000) GENERATED ALWAYS AS (b) STORED NOT NULL,
+ KEY (b(1)),
+ KEY (a(1))
+ ) ENGINE=INNODB
+ ROW_FORMAT=COMPRESSED
+ KEY_BLOCK_SIZE=1;
+ INSERT INTO t1(b) VALUES(REPEAT('a',947));
+ DELETE FROM t1;
+ DROP TABLE t1;
+ SET sql_mode = default;
+}
diff --git a/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch_2.result b/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch_2.result
new file mode 100644
index 000000000000..b9345e572643
--- /dev/null
+++ b/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch_2.result
@@ -0,0 +1,35 @@
+CREATE TABLE g (
+id INT PRIMARY KEY,
+p GEOMETRY NOT NULL,
+SPATIAL KEY p_idx(p)
+) ENGINE=InnoDB;
+create procedure populate_g(IN `rows` INT)
+begin
+declare i int default 1;
+while (i <= `rows`) DO
+insert into test.g (id, p) values (i, POINT(i, i));
+set i = i + 1;
+end while;
+end|
+call populate_g(650);
+start transaction;
+select id from g WHERE MBRContains(ST_GeomFromText('Polygon((100 0,100 5,105
+5,105 0,100 0))'),p) for update;
+id
+set innodb_lock_wait_timeout = 1;
+set transaction isolation level serializable;
+insert into g values(1103, POINT(100, 1));
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+start transaction;
+select id from g WHERE MBRContains(ST_GeomFromText('Polygon((100 0,100 5,105
+5,105 0,100 0))'),p) for update;
+id
+commit;
+set innodb_lock_wait_timeout = 1;
+set transaction isolation level serializable;
+insert into g values(1103, POINT(100, 1));
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+DROP TABLE g;
+DROP PROCEDURE populate_g;
+set innodb_lock_wait_timeout = default;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch_2.test b/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch_2.test
new file mode 100644
index 000000000000..7f3f639474b5
--- /dev/null
+++ b/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch_2.test
@@ -0,0 +1,66 @@
+# This test case will test concurrent search on R-tree.
+# Not supported in embedded
+--source include/not_embedded.inc
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_innodb_16k.inc
+
+CREATE TABLE g (
+ id INT PRIMARY KEY,
+ p GEOMETRY NOT NULL,
+ SPATIAL KEY p_idx(p)
+) ENGINE=InnoDB;
+
+delimiter |;
+create procedure populate_g(IN `rows` INT)
+begin
+ declare i int default 1;
+ while (i <= `rows`) DO
+ insert into test.g (id, p) values (i, POINT(i, i));
+ set i = i + 1;
+ end while;
+end|
+delimiter ;|
+
+call populate_g(650);
+
+start transaction;
+select id from g WHERE MBRContains(ST_GeomFromText('Polygon((100 0,100 5,105
+5,105 0,100 0))'),p) for update;
+
+connect (a,localhost,root,,);
+connection a;
+set innodb_lock_wait_timeout = 1;
+set transaction isolation level serializable;
+
+--error ER_LOCK_WAIT_TIMEOUT
+insert into g values(1103, POINT(100, 1));
+
+connect (b,localhost,root,,);
+connection b;
+start transaction;
+select id from g WHERE MBRContains(ST_GeomFromText('Polygon((100 0,100 5,105
+5,105 0,100 0))'),p) for update;
+
+connection default;
+commit;
+
+connection a;
+set innodb_lock_wait_timeout = 1;
+set transaction isolation level serializable;
+
+--error ER_LOCK_WAIT_TIMEOUT
+insert into g values(1103, POINT(100, 1));
+disconnect a;
+--source include/wait_until_disconnected.inc
+
+connection b;
+commit;
+disconnect b;
+--source include/wait_until_disconnected.inc
+
+connection default;
+DROP TABLE g;
+DROP PROCEDURE populate_g;
+set innodb_lock_wait_timeout = default;
diff --git a/mysql-test/suite/innodb_zip/r/wl6469.result b/mysql-test/suite/innodb_zip/r/wl6469.result
index 1c64e20e23a5..2842eb858e2d 100644
--- a/mysql-test/suite/innodb_zip/r/wl6469.result
+++ b/mysql-test/suite/innodb_zip/r/wl6469.result
@@ -281,6 +281,7 @@ b blob not null,
index sk (b(3021))
) row_format = compact engine=innodb;
ERROR 42000: Specified key was too long; max key length is 767 bytes
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
create temporary table t (
a int not null,
b blob not null,
@@ -293,6 +294,7 @@ b blob not null,
index sk (b(3021))
) row_format = compressed engine=innodb;
drop table t;
+SET sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';
SET GLOBAL innodb_large_prefix=default;
set global innodb_file_per_table = 0;
create temporary table t (
@@ -301,6 +303,7 @@ b blob not null,
index sk (b(3021))
) row_format = compact engine=innodb;
ERROR 42000: Specified key was too long; max key length is 767 bytes
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
create temporary table t (
a int not null,
b blob not null,
diff --git a/mysql-test/suite/innodb_zip/t/wl6469.test b/mysql-test/suite/innodb_zip/t/wl6469.test
index 1c49d3b1e775..8603748faa3c 100644
--- a/mysql-test/suite/innodb_zip/t/wl6469.test
+++ b/mysql-test/suite/innodb_zip/t/wl6469.test
@@ -228,6 +228,8 @@ create temporary table t (
b blob not null,
index sk (b(3021))
) row_format = compact engine=innodb;
+
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
#
create temporary table t (
a int not null,
@@ -243,6 +245,7 @@ create temporary table t (
) row_format = compressed engine=innodb;
drop table t;
#
+SET sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';
SET GLOBAL innodb_large_prefix=default;
set global innodb_file_per_table = 0;
#
@@ -253,6 +256,7 @@ create temporary table t (
index sk (b(3021))
) row_format = compact engine=innodb;
#
+SET sql_mode='NO_ENGINE_SUBSTITUTION';
create temporary table t (
a int not null,
b blob not null,
diff --git a/mysql-test/suite/memcached/r/memc_api_trx_level.result b/mysql-test/suite/memcached/r/memc_api_trx_level.result
new file mode 100644
index 000000000000..39314818893b
--- /dev/null
+++ b/mysql-test/suite/memcached/r/memc_api_trx_level.result
@@ -0,0 +1,23 @@
+INSERT INTO cache_policies VALUES("cache_policy", "innodb_only",
+"innodb_only", "innodb_only", "innodb_only");
+INSERT INTO config_options VALUES("separator", "|");
+INSERT INTO containers VALUES ("desc_t1", "test", "t1",
+"c1", "c2", "c3", "c4", "c5", "PRIMARY");
+USE test;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 VARCHAR(32),
+c2 VARCHAR(1024),
+c3 INT, c4 BIGINT UNSIGNED, c5 INT, primary key(c1))
+ENGINE = INNODB;
+INSERT INTO t1 VALUES ('B', 'Berlin', 0, 0, 0);
+INSTALL PLUGIN daemon_memcached SONAME 'libmemcached.so';
+SELECT SLEEP(2);
+SLEEP(2)
+0
+begin;
+INSERT INTO t1 VALUES ('H', 'Hamburg', 0, 0, 0);
+Here the memcached results with H:
+commit;
+DROP TABLE t1;
+UNINSTALL PLUGIN daemon_memcached;
+DROP DATABASE innodb_memcache;
diff --git a/mysql-test/suite/memcached/t/memc_api_trx_level-master.opt b/mysql-test/suite/memcached/t/memc_api_trx_level-master.opt
new file mode 100644
index 000000000000..c7a54a370da6
--- /dev/null
+++ b/mysql-test/suite/memcached/t/memc_api_trx_level-master.opt
@@ -0,0 +1,4 @@
+$DAEMON_MEMCACHED_OPT
+--loose-daemon_memcached_engine_lib_path=$INNODB_ENGINE_DIR
+--loose-daemon_memcached_option="-p11242"
+--loose-innodb_api_trx_level=1
diff --git a/mysql-test/suite/memcached/t/memc_api_trx_level.test b/mysql-test/suite/memcached/t/memc_api_trx_level.test
new file mode 100644
index 000000000000..7d6e485e307c
--- /dev/null
+++ b/mysql-test/suite/memcached/t/memc_api_trx_level.test
@@ -0,0 +1,65 @@
+source include/not_valgrind.inc;
+source include/have_memcached_plugin.inc;
+source include/not_windows.inc;
+source include/have_innodb.inc;
+
+--disable_query_log
+CALL mtr.add_suppression("daemon-memcached-w-batch-size': unsigned");
+CALL mtr.add_suppression("Could not obtain server's UPN to be used as target service name");
+CALL mtr.add_suppression("InnoDB: Warning: MySQL is trying to drop");
+--enable_query_log
+
+--enable_connect_log
+
+# Create the memcached tables
+--disable_query_log
+source include/memcache_config.inc;
+--enable_query_log
+
+INSERT INTO cache_policies VALUES("cache_policy", "innodb_only",
+ "innodb_only", "innodb_only", "innodb_only");
+
+INSERT INTO config_options VALUES("separator", "|");
+
+# describe table for memcache
+INSERT INTO containers VALUES ("desc_t1", "test", "t1",
+ "c1", "c2", "c3", "c4", "c5", "PRIMARY");
+
+USE test;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TABLE t1 (c1 VARCHAR(32),
+ c2 VARCHAR(1024),
+ c3 INT, c4 BIGINT UNSIGNED, c5 INT, primary key(c1))
+ENGINE = INNODB;
+
+INSERT INTO t1 VALUES ('B', 'Berlin', 0, 0, 0);
+
+INSTALL PLUGIN daemon_memcached SONAME 'libmemcached.so';
+
+SELECT SLEEP(2);
+begin;
+INSERT INTO t1 VALUES ('H', 'Hamburg', 0, 0, 0);
+
+perl;
+use DBI;
+use Cache::Memcached;
+my $memd = new Cache::Memcached {
+ 'servers' => [ "127.0.0.1:11242" ],
+ 'connect_timeout' => 20,
+ 'select_timeout' => 20
+};
+print "Here the memcached results with H:\n";
+$val = $memd->get("H");
+if ($val) { print "$val\n"; }
+$memd->disconnect_all;
+EOF
+commit;
+
+DROP TABLE t1;
+
+# Stop plugin befor innodb_memcached configuration
+UNINSTALL PLUGIN daemon_memcached;
+DROP DATABASE innodb_memcache;
diff --git a/mysql-test/suite/parts/t/partition_names.test b/mysql-test/suite/parts/t/partition_names.test
index 188de1ecfa90..11e312c254bc 100644
--- a/mysql-test/suite/parts/t/partition_names.test
+++ b/mysql-test/suite/parts/t/partition_names.test
@@ -1,3 +1,5 @@
+# Becasue of Bug 28112444 disabling this test on windows
+-- source include/not_windows.inc
-- source include/have_innodb.inc
-- source include/mysql_upgrade_preparation.inc
--echo #
diff --git a/mysql-test/suite/rpl/r/rpl_flush_logs.result b/mysql-test/suite/rpl/r/rpl_flush_logs.result
index 9f6adb375711..4d7e498cea8d 100644
--- a/mysql-test/suite/rpl/r/rpl_flush_logs.result
+++ b/mysql-test/suite/rpl/r/rpl_flush_logs.result
@@ -56,5 +56,12 @@ flush logs;
include/sync_slave_io_with_master.inc
# Check the 'slave-relay-bin.000007' and 'slave-relay-bin.000008'
# files are created after execute 'flush logs' statement.
+FLUSH SLOW LOGS;
+ERROR HY000: File not found (Errcode: ##)
+FLUSH GENERAL LOGS;
+ERROR HY000: File not found (Errcode: ##)
+include/assert.inc [assert that the above events are not written to binlog]
+include/show_binlog_events.inc
+include/sync_slave_io_with_master.inc
include/start_slave_sql.inc
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_skip_with_parser_error.result b/mysql-test/suite/rpl/r/rpl_gtid_skip_with_parser_error.result
new file mode 100644
index 000000000000..582fd4164d31
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_gtid_skip_with_parser_error.result
@@ -0,0 +1,32 @@
+include/master-slave.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection master]
+include/rpl_stop_server.inc [server_number=1]
+include/rpl_start_server.inc [server_number=1]
+include/assert.inc [All transactions are assumed as applied on master]
+[connection slave]
+include/start_slave_io.inc
+[connection master]
+include/sync_slave_io_with_master.inc
+START SLAVE SQL_THREAD;
+include/wait_for_slave_sql_error.inc [errno=1064]
+include/assert.inc [Only 1st transaction is applied on slave]
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:2';
+BEGIN;
+COMMIT;
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:3';
+BEGIN;
+COMMIT;
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:4';
+BEGIN;
+COMMIT;
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:6';
+BEGIN;
+COMMIT;
+SET GTID_NEXT=AUTOMATIC;
+include/start_slave_sql.inc
+include/sync_slave_sql_with_io.inc
+CALL mtr.add_suppression("The slave coordinator and worker threads are stopped");
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_multi_source_corrupt_repository.result b/mysql-test/suite/rpl/r/rpl_multi_source_corrupt_repository.result
index fe17f3e45408..0139c06b8db1 100644
--- a/mysql-test/suite/rpl/r/rpl_multi_source_corrupt_repository.result
+++ b/mysql-test/suite/rpl/r/rpl_multi_source_corrupt_repository.result
@@ -147,10 +147,10 @@ FLUSH RELAY LOGS FOR CHANNEL 'channel_2';
===== Executing SHOW RELAYLOG EVENTS FOR CHANNEL on channel 'channel_2'.
SHOW RELAYLOG EVENTS FOR CHANNEL 'channel_2';
===== Executing SHOW SLAVE FOR CHANNEL on channel 'channel_2'.
+include/wait_for_slave_param.inc [Slave_IO_State channel=channel_2]
+include/wait_for_slave_param.inc [Slave_SQL_Running_State channel=channel_2]
Warnings:
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-Slave_IO_State = 'Waiting for master to send event'
-Slave_SQL_Running_State = 'Slave has read all relay log; waiting for more updates'
Last_IO_Errno = '0'
Last_IO_Error = ''
Last_SQL_Errno = '0'
@@ -194,10 +194,10 @@ FLUSH RELAY LOGS FOR CHANNEL 'channel_3';
===== Executing SHOW RELAYLOG EVENTS FOR CHANNEL on channel 'channel_3'.
SHOW RELAYLOG EVENTS FOR CHANNEL 'channel_3';
===== Executing SHOW SLAVE FOR CHANNEL on channel 'channel_3'.
+include/wait_for_slave_param.inc [Slave_IO_State channel=channel_3]
+include/wait_for_slave_param.inc [Slave_SQL_Running_State channel=channel_3]
Warnings:
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-Slave_IO_State = 'Waiting for master to send event'
-Slave_SQL_Running_State = 'Slave has read all relay log; waiting for more updates'
Last_IO_Errno = '0'
Last_IO_Error = ''
Last_SQL_Errno = '0'
@@ -325,10 +325,10 @@ FLUSH RELAY LOGS FOR CHANNEL '';
===== Executing SHOW RELAYLOG EVENTS FOR CHANNEL on channel ''.
SHOW RELAYLOG EVENTS FOR CHANNEL '';
===== Executing SHOW SLAVE FOR CHANNEL on channel ''.
+include/wait_for_slave_param.inc [Slave_IO_State]
+include/wait_for_slave_param.inc [Slave_SQL_Running_State]
Warnings:
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-Slave_IO_State = 'Waiting for master to send event'
-Slave_SQL_Running_State = 'Slave has read all relay log; waiting for more updates'
Last_IO_Errno = '0'
Last_IO_Error = ''
Last_SQL_Errno = '0'
@@ -415,10 +415,10 @@ FLUSH RELAY LOGS FOR CHANNEL 'channel_3';
===== Executing SHOW RELAYLOG EVENTS FOR CHANNEL on channel 'channel_3'.
SHOW RELAYLOG EVENTS FOR CHANNEL 'channel_3';
===== Executing SHOW SLAVE FOR CHANNEL on channel 'channel_3'.
+include/wait_for_slave_param.inc [Slave_IO_State channel=channel_3]
+include/wait_for_slave_param.inc [Slave_SQL_Running_State channel=channel_3]
Warnings:
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-Slave_IO_State = 'Waiting for master to send event'
-Slave_SQL_Running_State = 'Slave has read all relay log; waiting for more updates'
Last_IO_Errno = '0'
Last_IO_Error = ''
Last_SQL_Errno = '0'
@@ -546,10 +546,10 @@ FLUSH RELAY LOGS FOR CHANNEL '';
===== Executing SHOW RELAYLOG EVENTS FOR CHANNEL on channel ''.
SHOW RELAYLOG EVENTS FOR CHANNEL '';
===== Executing SHOW SLAVE FOR CHANNEL on channel ''.
+include/wait_for_slave_param.inc [Slave_IO_State]
+include/wait_for_slave_param.inc [Slave_SQL_Running_State]
Warnings:
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-Slave_IO_State = 'Waiting for master to send event'
-Slave_SQL_Running_State = 'Slave has read all relay log; waiting for more updates'
Last_IO_Errno = '0'
Last_IO_Error = ''
Last_SQL_Errno = '0'
@@ -593,10 +593,10 @@ FLUSH RELAY LOGS FOR CHANNEL 'channel_2';
===== Executing SHOW RELAYLOG EVENTS FOR CHANNEL on channel 'channel_2'.
SHOW RELAYLOG EVENTS FOR CHANNEL 'channel_2';
===== Executing SHOW SLAVE FOR CHANNEL on channel 'channel_2'.
+include/wait_for_slave_param.inc [Slave_IO_State channel=channel_2]
+include/wait_for_slave_param.inc [Slave_SQL_Running_State channel=channel_2]
Warnings:
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-Slave_IO_State = 'Waiting for master to send event'
-Slave_SQL_Running_State = 'Slave has read all relay log; waiting for more updates'
Last_IO_Errno = '0'
Last_IO_Error = ''
Last_SQL_Errno = '0'
diff --git a/mysql-test/suite/rpl/r/rpl_multi_source_relay_log.result b/mysql-test/suite/rpl/r/rpl_multi_source_relay_log.result
index 5efbd543b05c..99be954fd295 100644
--- a/mysql-test/suite/rpl/r/rpl_multi_source_relay_log.result
+++ b/mysql-test/suite/rpl/r/rpl_multi_source_relay_log.result
@@ -1,7 +1,9 @@
#########################################################################
# Verify RESET SLAVE and RESET SLAVE FOR CHANNEL
-# - deletes all relay log files of named channels.
+# - deletes all relay log files of named channels and reintializes
+# them.
# - For default channel, it restart the relay log from .000001
+# - For named channel, it restart the relay log from ch.000001
#########################################################################
include/master-slave.inc
Warnings:
@@ -18,19 +20,21 @@ FLUSH RELAY LOGS FOR CHANNEL "ch2";
# RESET SLAVE FOR CHANNEL "ch1" deletes all relay log files of ch1.
#
RESET SLAVE FOR CHANNEL "ch1";
+slave-relay-bin-ch1.000001
+slave-relay-bin-ch1.index
#
# RESET SLAVE deletes all relay log files of ch2
#
include/stop_slave.inc
RESET SLAVE;
+slave-relay-bin-ch2.000001
+slave-relay-bin-ch2.index
#
# RESET SLAVE resets relay log of default channel from .000001
#
#
-# Recreate channels "ch1" and "ch2" files again.
+# Relay log files for all channels are recreated automatically.
#
-CHANGE MASTER TO MASTER_HOST="localhost", MASTER_PORT=10 FOR CHANNEL "ch1";
-CHANGE MASTER TO MASTER_HOST="localhost", MASTER_PORT=11 FOR CHANNEL "ch2";
#
# RESET SLAVE ALL deletes all channels info and files.
#
diff --git a/mysql-test/suite/rpl/r/rpl_multi_source_relay_log_recovery.result b/mysql-test/suite/rpl/r/rpl_multi_source_relay_log_recovery.result
index 3ebadab01c98..8556ef70fb1c 100644
--- a/mysql-test/suite/rpl/r/rpl_multi_source_relay_log_recovery.result
+++ b/mysql-test/suite/rpl/r/rpl_multi_source_relay_log_recovery.result
@@ -38,7 +38,7 @@ INSERT INTO d1_1.t VALUES (2, 'T5');;
[connection server_2]
# Now d1_1.t has two rows and d2_.t has one row.
#
-# Generate MTS gaps for channel2.
+# Generate MTS gaps for channel3.
#
[connection server_3]
[connection server_3]
diff --git a/mysql-test/suite/rpl/r/rpl_perfschema_applier_status_by_coordinator.result b/mysql-test/suite/rpl/r/rpl_perfschema_applier_status_by_coordinator.result
index bf9c6bab4a97..b27f8fcc0c0e 100644
--- a/mysql-test/suite/rpl/r/rpl_perfschema_applier_status_by_coordinator.result
+++ b/mysql-test/suite/rpl/r/rpl_perfschema_applier_status_by_coordinator.result
@@ -55,6 +55,7 @@ include/stop_slave.inc
drop table t;
reset master;
reset slave;
+reset master;
# Restarting servers and setting up MTS now. Since, SQL thread and
# coordinator are the same and follow same code path, we can skip
diff --git a/mysql-test/suite/rpl/r/rpl_perfschema_order_by.result b/mysql-test/suite/rpl/r/rpl_perfschema_order_by.result
new file mode 100644
index 000000000000..deb347fa2f73
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_perfschema_order_by.result
@@ -0,0 +1,169 @@
+include/rpl_init.inc [topology=3->2,1->2]
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server_2]
+SET @save.slave_parallel_workers= @@global.slave_parallel_workers;
+# Test for Single Threaded Slave
+SET GLOBAL slave_parallel_workers= 0;
+START SLAVE;
+# 1) Create a database on server_1.
+[connection server_1]
+CREATE DATABASE db1;
+# 2) create database on server_3.
+[connection server_3]
+CREATE DATABASE db3;
+# 3) sync the slave (server_2) with both masters (server_1 and server_3).
+[connection server_1]
+include/sync_slave_sql_with_master.inc
+[connection server_3]
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+include/start_slave.inc
+
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_configuration;
+CHANNEL_NAME
+channel_3
+channel_1
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_configuration ORDER BY CHANNEL_NAME;
+CHANNEL_NAME
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_status;
+CHANNEL_NAME
+channel_3
+channel_1
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_status ORDER BY CHANNEL_NAME;
+CHANNEL_NAME
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_connection_status;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_3
+channel_1
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_connection_status ORDER BY CHANNEL_NAME;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, TLS_VERSION FROM performance_schema.replication_connection_configuration;
+CHANNEL_NAME TLS_VERSION
+channel_3
+channel_1
+SELECT CHANNEL_NAME, TLS_VERSION FROM performance_schema.replication_connection_configuration ORDER BY CHANNEL_NAME;
+CHANNEL_NAME TLS_VERSION
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_worker;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_3
+channel_1
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_worker ORDER BY CHANNEL_NAME;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_1
+channel_3
+
+[connection server_1]
+DROP DATABASE db1;
+[connection server_3]
+DROP DATABASE db3;
+[connection server_1]
+include/sync_slave_sql_with_master.inc
+[connection server_3]
+include/sync_slave_sql_with_master.inc
+# Test for Multi Threaded Slave
+STOP SLAVE;
+SET GLOBAL slave_parallel_workers = 2;
+START SLAVE;
+# 1) Create a database on server_1.
+[connection server_1]
+CREATE DATABASE db1;
+# 2) create database on server_3.
+[connection server_3]
+CREATE DATABASE db3;
+# 3) sync the slave (server_2) with both masters (server_1 and server_3).
+[connection server_1]
+include/sync_slave_sql_with_master.inc
+[connection server_3]
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+include/start_slave.inc
+
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_configuration;
+CHANNEL_NAME
+channel_3
+channel_1
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_configuration ORDER BY CHANNEL_NAME;
+CHANNEL_NAME
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_status;
+CHANNEL_NAME
+channel_3
+channel_1
+SELECT CHANNEL_NAME FROM performance_schema.replication_applier_status ORDER BY CHANNEL_NAME;
+CHANNEL_NAME
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_connection_status;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_3
+channel_1
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_connection_status ORDER BY CHANNEL_NAME;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, TLS_VERSION FROM performance_schema.replication_connection_configuration;
+CHANNEL_NAME TLS_VERSION
+channel_3
+channel_1
+SELECT CHANNEL_NAME, TLS_VERSION FROM performance_schema.replication_connection_configuration ORDER BY CHANNEL_NAME;
+CHANNEL_NAME TLS_VERSION
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_coordinator;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_3
+channel_1
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_coordinator ORDER BY CHANNEL_NAME;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_1
+channel_3
+
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_worker;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_3
+channel_3
+channel_1
+channel_1
+SELECT CHANNEL_NAME, LAST_ERROR_MESSAGE FROM performance_schema.replication_applier_status_by_worker ORDER BY CHANNEL_NAME;
+CHANNEL_NAME LAST_ERROR_MESSAGE
+channel_1
+channel_1
+channel_3
+channel_3
+
+[connection server_1]
+DROP DATABASE db1;
+[connection server_3]
+DROP DATABASE db3;
+[connection server_1]
+include/sync_slave_sql_with_master.inc
+[connection server_3]
+include/sync_slave_sql_with_master.inc
+STOP SLAVE;
+SET @@global.slave_parallel_workers= @save.slave_parallel_workers;
+START SLAVE;
+include/rpl_end.inc
+RESET SLAVE ALL FOR CHANNEL 'channel_3';
+RESET SLAVE ALL FOR CHANNEL 'channel_1';
diff --git a/mysql-test/suite/rpl/r/rpl_reset_restart.result b/mysql-test/suite/rpl/r/rpl_reset_restart.result
new file mode 100644
index 000000000000..15a62ff24d47
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_reset_restart.result
@@ -0,0 +1,19 @@
+include/master-slave.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection master]
+CREATE TABLE t1 (c1 INT);
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+[connection master]
+RESET MASTER;
+[connection slave]
+RESET MASTER;
+RESET SLAVE;
+include/start_slave.inc
+# Kill and restart
+include/rpl_reconnect.inc
+[connection master]
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_add_remove_slaves.result b/mysql-test/suite/rpl/r/rpl_semi_sync_add_remove_slaves.result
new file mode 100644
index 000000000000..fd4789ef3929
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_add_remove_slaves.result
@@ -0,0 +1,120 @@
+include/rpl_init.inc [topology=1->2, 1->3, 1->4, 1->5, 1->6, 1->7, 1->8, 1->9]
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+#
+# 1. Initial data.
+#
+call mtr.add_suppression("Timeout waiting for reply of binlog");
+CREATE TABLE t1(c1 INT);
+include/rpl_sync.inc
+#
+# 2. Install semisync on all the 9 servers.
+#
+[connection server_1]
+CALL mtr.add_suppression("Semi-sync master failed on net_flush.*");
+include/install_semisync_master.inc
+[connection server_2]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_3]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_4]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_5]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_6]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_7]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_8]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+[connection server_9]
+CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+include/install_semisync_slave.inc
+#
+# 3. Make Master aware of 8 semisync slaves.
+#
+[connection server1_1]
+SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = 8;
+#
+# 4. Insert 5000 tuples in background using 10 parallel connections.
+#
+#
+# 5. While the insert operations are going in the background, keep
+# adding/removing semisync slaves randomly.
+#
+#
+# 6. Add all 8 semisync slaves back to Master
+# (if they were disconnected, in above step).
+#
+#
+# 7. Make sure the data is synced on Master without any issues.
+#
+[connection server_1]
+include/rpl_sync.inc
+#
+# 8. Check on all servers semisync is enabled after the
+# the experiment and then uninstall semisync pluging
+# from it.
+#
+[connection server_9]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_8]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_7]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_6]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_5]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_4]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_3]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_2]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_slave.inc
+[connection server_1]
+include/assert.inc [ should be 1]
+include/uninstall_semisync_master.inc
+#
+# 9. Cleanup time.
+#
+[connection server_1]
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_server_uuid.result b/mysql-test/suite/rpl/r/rpl_server_uuid.result
index 66f08031f362..a82d73073b69 100644
--- a/mysql-test/suite/rpl/r/rpl_server_uuid.result
+++ b/mysql-test/suite/rpl/r/rpl_server_uuid.result
@@ -62,7 +62,7 @@ include/rpl_restart_server.inc [server_number=1]
# Master's UUID and server_id will not be cleared if both master_port
# and master_host are not changed.
-----------------------------------------------------------------------------
-START SLAVE IO_THREAD;
+include/start_slave_io.inc
include/wait_for_slave_param.inc [Master_UUID]
include/stop_slave.inc
@@ -72,7 +72,7 @@ include/check_slave_param.inc [Master_UUID]
include/check_slave_param.inc [Master_Server_Id]
CHANGE MASTER TO MASTER_PORT= MASTER_PORT,
MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
-START SLAVE IO_THREAD;
+include/start_slave_io.inc
include/wait_for_slave_param.inc [Master_UUID]
# Only change MASTER_HOST
@@ -83,7 +83,7 @@ include/check_slave_param.inc [Master_UUID]
include/check_slave_param.inc [Master_Server_Id]
CHANGE MASTER TO MASTER_HOST= '127.0.0.1',
MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
-START SLAVE IO_THREAD;
+include/start_slave_io.inc
include/wait_for_slave_param.inc [Master_UUID]
# Both MASTER_HOST and MASTER_PORT are changed
@@ -94,7 +94,7 @@ include/check_slave_param.inc [Master_UUID]
include/check_slave_param.inc [Master_Server_Id]
CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= MASTER_PORT,
MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
-START SLAVE IO_THREAD;
+include/start_slave_io.inc
include/wait_for_slave_param.inc [Master_UUID]
# Both MASTER_HOST and MASTER_PORT are NOT changed
diff --git a/mysql-test/suite/rpl/t/rpl_flush_logs.test b/mysql-test/suite/rpl/t/rpl_flush_logs.test
index f98d0173d54a..2bed6780f532 100644
--- a/mysql-test/suite/rpl/t/rpl_flush_logs.test
+++ b/mysql-test/suite/rpl/t/rpl_flush_logs.test
@@ -1,5 +1,5 @@
#
-# WL#5124
+# WL#5142
# This test verifies if the 'flush individual logs' statement
# works fine.
#
@@ -147,5 +147,44 @@ file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003;
file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007;
file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000008;
+#
+# Bug #24786290: REPLICATION BREAKS AFTER BUG #74145 HAPPENS IN MASTER
+#
+# === Purpose ===
+#
+# This test verifies that failed FLUSH LOGS statements
+# are not written to binary log.
+
+--connection master
+--let $binlog_file= query_get_value(SHOW MASTER STATUS,File,1)
+--let $binlog_start= query_get_value(SHOW MASTER STATUS,Position,1)
+--let $master_pos_before_flush_logs= $binlog_start
+
+# Make FLUSH LOGS fail by changing
+# the permissions of the slow log and general log.
+--let $slow_log= `SELECT @@global.slow_query_log_file`
+--chmod 0000 $slow_log
+--replace_regex /.*File .* not found .*/File not found (Errcode: ##)/
+--error 29
+FLUSH SLOW LOGS;
+
+--let $general_log= `SELECT @@global.general_log_file`
+--chmod 0000 $general_log
+--replace_regex /.*File .* not found .*/File not found (Errcode: ##)/
+--error 29
+FLUSH GENERAL LOGS;
+
+# Assert that the above statements are not written to the binlog.
+--let $master_pos_after_flush_logs= query_get_value(SHOW MASTER STATUS,Position,1)
+--let $assert_text= assert that the above events are not written to binlog
+--let $assert_cond= $master_pos_before_flush_logs = $master_pos_after_flush_logs
+--source include/assert.inc
+--source include/show_binlog_events.inc
+
+# Restore permissions
+--chmod 0644 $slow_log
+--chmod 0644 $general_log
+
+--source include/sync_slave_io_with_master.inc
--source include/start_slave_sql.inc
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_skip_with_parser_error.test b/mysql-test/suite/rpl/t/rpl_gtid_skip_with_parser_error.test
new file mode 100644
index 000000000000..8b83989a9074
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_gtid_skip_with_parser_error.test
@@ -0,0 +1,107 @@
+# ==== Purpose ====
+#
+# Test that GTID auto skip works even when replication applier is applying
+# events that would lead to ER_PARSE_ERROR.
+#
+# For this test case a binary log file was generated in MySQL 5.6 creating
+# a table with a name that is a reserved word in MySQL 5.7+.
+#
+# Replicating the binary log to a 5.7+ slave shall make the applier thread
+# to stop once reaching the offending transaction.
+#
+# Supposing a DBA/operator fixed the issue manually and the GTID of the
+# offending transaction was committed so the replicated one shall be skipped
+# by GTID auto skip functionality, restarting the slave applier thread shall
+# not hit errors for this transaction anymore.
+#
+# The binary log file generated in MySQL 5.6 has the following content:
+#
+#+-------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
+#| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+#+-------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
+#| master-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.41-debug-log, Binlog ver: 4 |
+#| master-bin.000001 | 120 | Previous_gtids | 1 | 151 | |
+#| master-bin.000001 | 151 | Gtid | 1 | 199 | SET @@SESSION.GTID_NEXT= '11111111-1111-1111-1111-111111111111:1' |
+#| master-bin.000001 | 199 | Query | 1 | 308 | use `test`; CREATE TABLE t1 (a int PRIMARY KEY) |
+#| master-bin.000001 | 308 | Gtid | 1 | 356 | SET @@SESSION.GTID_NEXT= '11111111-1111-1111-1111-111111111111:2' |
+#| master-bin.000001 | 356 | Query | 1 | 458 | use `test`; CREATE TABLE GENERATED LIKE test.t1 |
+#| master-bin.000001 | 458 | Gtid | 1 | 506 | SET @@SESSION.GTID_NEXT= '11111111-1111-1111-1111-111111111111:3' |
+#| master-bin.000001 | 506 | Query | 1 | 585 | BEGIN |
+#| master-bin.000001 | 585 | Query | 1 | 701 | use `test`; INSERT INTO GENERATED VALUES (1), (2), (3) |
+#| master-bin.000001 | 701 | Query | 1 | 781 | COMMIT |
+#| master-bin.000001 | 781 | Gtid | 1 | 829 | SET @@SESSION.GTID_NEXT= '11111111-1111-1111-1111-111111111111:4' |
+#| master-bin.000001 | 829 | Query | 1 | 901 | BEGIN |
+#| master-bin.000001 | 901 | Table_map | 1 | 953 | table_id: 75 (test.GENERATED) |
+#| master-bin.000001 | 953 | Write_rows | 1 | 993 | table_id: 75 flags: STMT_END_F |
+#| master-bin.000001 | 993 | Query | 1 | 1066 | COMMIT |
+#| master-bin.000001 | 1066 | Gtid | 1 | 1114 | SET @@SESSION.GTID_NEXT= '11111111-1111-1111-1111-111111111111:5' |
+#| master-bin.000001 | 1114 | Query | 1 | 1229 | use `test`; DROP TABLE `t1` /* generated by server */ |
+#| master-bin.000001 | 1229 | Gtid | 1 | 1277 | SET @@SESSION.GTID_NEXT= '11111111-1111-1111-1111-111111111111:6' |
+#| master-bin.000001 | 1277 | Query | 1 | 1399 | use `test`; DROP TABLE `GENERATED` /* generated by server */ |
+#+-------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
+#
+# ==== Related Bugs and Worklogs ====
+#
+# BUG#27638268 GTID AUTO SKIP DOES NOT WORK FOR QUERIES WITH PARSER ERRORS
+#
+
+# This test case is not compatible with SBR.
+--source include/have_binlog_format_mixed_or_row.inc
+--source include/have_gtid.inc
+--let $rpl_skip_start_slave = 1
+--source include/master-slave.inc
+
+--let $MASTER_DATADIR= `select @@datadir`
+
+# Restart the master to make it use the 5.6 binary log file as its own.
+--let $rpl_server_number= 1
+--source include/rpl_stop_server.inc
+--remove_file $MASTER_DATADIR/master-bin.000001
+--copy_file std_data/binlog_56_gtid_reserved_word.000001 $MASTER_DATADIR/master-bin.000001
+--source include/rpl_start_server.inc
+
+# Assert that all 6 transactions are assumed as already applied.
+--let $assert_text= All transactions are assumed as applied on master
+--let $assert_cond= "[SELECT @@GLOBAL.gtid_executed]" = "11111111-1111-1111-1111-111111111111:1-6"
+--source include/assert.inc
+
+# Start and sync slave's receiver thread
+--source include/rpl_connection_slave.inc
+--source include/start_slave_io.inc
+--source include/rpl_connection_master.inc
+--source include/sync_slave_io_with_master.inc
+
+# Start slave's applier thread. It should stop with ER_PARSE_ERROR.
+START SLAVE SQL_THREAD;
+--let $slave_sql_errno= convert_error(ER_PARSE_ERROR)
+--source include/wait_for_slave_sql_error.inc
+
+# Assert that only 1st transaction is applied.
+--let $assert_text= Only 1st transaction is applied on slave
+--let $assert_cond= "[SELECT @@GLOBAL.gtid_executed]" = "11111111-1111-1111-1111-111111111111:1"
+--source include/assert.inc
+
+# Prepare GTID auto skip of offending transactions.
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:2';
+BEGIN;
+COMMIT;
+
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:3';
+BEGIN;
+COMMIT;
+
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:4';
+BEGIN;
+COMMIT;
+
+SET GTID_NEXT='11111111-1111-1111-1111-111111111111:6';
+BEGIN;
+COMMIT;
+
+SET GTID_NEXT=AUTOMATIC;
+
+# Restart applier thread that shall sync without issues.
+--source include/start_slave_sql.inc
+--source include/sync_slave_sql_with_io.inc
+CALL mtr.add_suppression("The slave coordinator and worker threads are stopped");
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error-slave.opt b/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error-slave.opt
new file mode 100644
index 000000000000..13af78657748
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/rpl_mts_slave_preserve_commit_order_deadlock_error.2.err
diff --git a/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error.test b/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error.test
index 8d02f7671eae..019b5f0baa5d 100644
--- a/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error.test
+++ b/mysql-test/suite/rpl/t/rpl_mts_slave_preserve_commit_order_deadlock_error.test
@@ -167,7 +167,7 @@ COMMIT;
--echo # 3.13 Check that worker 2 did not *retry* transaction-2
--echo # before throwing ER_DUP_ENTRY error (non-temporary error).
--echo #
---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err
+--let $assert_file= $MYSQLTEST_VARDIR/tmp/rpl_mts_slave_preserve_commit_order_deadlock_error.2.err
--let $assert_only_after = CURRENT_TEST: rpl.rpl_mts_slave_preserve_commit_order_deadlock_error
--let $assert_count = 1
--let $assert_select = Error 'Duplicate entry '1' for key 'PRIMARY'' on query
diff --git a/mysql-test/suite/rpl/t/rpl_multi_source_relay_log.test b/mysql-test/suite/rpl/t/rpl_multi_source_relay_log.test
index 1fdbf1fa28fe..9e2346d18308 100644
--- a/mysql-test/suite/rpl/t/rpl_multi_source_relay_log.test
+++ b/mysql-test/suite/rpl/t/rpl_multi_source_relay_log.test
@@ -1,7 +1,9 @@
--echo #########################################################################
--echo # Verify RESET SLAVE and RESET SLAVE FOR CHANNEL
---echo # - deletes all relay log files of named channels.
+--echo # - deletes all relay log files of named channels and reintializes
+--echo # them.
--echo # - For default channel, it restart the relay log from .000001
+--echo # - For named channel, it restart the relay log from ch.000001
--echo #########################################################################
# The test doesn't relate to binlog format, so it is just tested on mixed mode.
#Skip on group replication runs
@@ -25,7 +27,7 @@ FLUSH RELAY LOGS FOR CHANNEL "ch2";
--echo #
eval RESET SLAVE FOR CHANNEL "ch1";
-# all files of "ch1" are removed
+# all files of "ch1" are deleted and recreated.
--list_files $datadir *ch1*
--echo #
@@ -36,7 +38,7 @@ eval RESET SLAVE FOR CHANNEL "ch1";
--enable_warnings
RESET SLAVE;
-# all files of "ch2" are removed
+# all files of "ch2" are deleted and recreated.
--list_files $datadir *ch2*
--echo #
@@ -50,10 +52,8 @@ RESET SLAVE;
--file_exists $relay_log_basename.000001
--echo #
---echo # Recreate channels "ch1" and "ch2" files again.
+--echo # Relay log files for all channels are recreated automatically.
--echo #
-CHANGE MASTER TO MASTER_HOST="localhost", MASTER_PORT=10 FOR CHANNEL "ch1";
-CHANGE MASTER TO MASTER_HOST="localhost", MASTER_PORT=11 FOR CHANNEL "ch2";
# Check that files exist.
--let $relay_log_base_name= `SELECT @@GLOBAL.relay_log_basename`
diff --git a/mysql-test/suite/rpl/t/rpl_multi_source_relay_log_recovery.test b/mysql-test/suite/rpl/t/rpl_multi_source_relay_log_recovery.test
index 79b3f2992d68..3f75f72bce57 100644
--- a/mysql-test/suite/rpl/t/rpl_multi_source_relay_log_recovery.test
+++ b/mysql-test/suite/rpl/t/rpl_multi_source_relay_log_recovery.test
@@ -4,27 +4,25 @@
# Problem:
# ========
# Enable MTS along with crash-safe replication tables. Make sure that the
-# server
-# is busily inserting data with multiple threads in parallel. Shutdown mysqld
-# uncleanly (kill -9 or power off server without notice).
+# server is busily inserting data with multiple threads in parallel. Shutdown
+# mysqld uncleanly (kill -9 or power off server without notice).
#
# Now users are restarting the server with --relay-log-recovery=1 to recover
-# the
-# crashed slave.
+# the crashed slave.
#
# This results in following error:
# ================================
-# 2015-06-24 13:49:03 3895 [ERROR] --relay-log-recovery cannot
-# be executed when the slave was stopped with an error or
-# killed in MTS mode; consider using RESET SLAVE or restart
-# the server with --relay-log-recovery = 0 followed by
-# START SLAVE UNTIL SQL_AFTER_MTS_GAPS.
+# 2015-06-24 13:49:03 3895 [ERROR] --relay-log-recovery cannot be executed
+# when the slave was stopped with an error or killed in MTS mode; consideri
+# using RESET SLAVE or restart the server with --relay-log-recovery = 0
+# followed by # START SLAVE UNTIL SQL_AFTER_MTS_GAPS.
#
# i.e relay-log-recovery will not work in MTS mode.
###############################################################################
# Following test demonstrates that when gaps are generated due to MTS crash
# but not due to an error then recovery should be successful with
# --relay-log-recovery=1 option.
+#
# In case of Multi source replication all channels will go through the relay
# log recovery process and gaps will be filled.
@@ -66,7 +64,7 @@ SET @save.innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout;
--source extra/rpl_tests/rpl_multi_source_generate_mts_gap.test
--echo #
---echo # Generate MTS gaps for channel2.
+--echo # Generate MTS gaps for channel3.
--echo #
--let $rpl_connection_name= server_3
--source include/rpl_connection.inc
diff --git a/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test b/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test
index 878dba9b5876..77ccb3becc60 100644
--- a/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test
+++ b/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test
@@ -353,6 +353,7 @@ reset master;
--connection slave
reset slave;
+reset master;
--echo
--echo # Restarting servers and setting up MTS now. Since, SQL thread and
diff --git a/mysql-test/suite/rpl/t/rpl_perfschema_order_by.cnf b/mysql-test/suite/rpl/t/rpl_perfschema_order_by.cnf
new file mode 100644
index 000000000000..8417bf14e3df
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_perfschema_order_by.cnf
@@ -0,0 +1,17 @@
+!include ../my.cnf
+
+[mysqld.1]
+log-slave-updates
+
+[mysqld.2]
+master-info-repository=TABLE
+relay-log-info-repository=TABLE
+log-slave-updates
+
+[mysqld.3]
+log-slave-updates
+
+[ENV]
+SERVER_MYPORT_3= @mysqld.3.port
+SERVER_MYSOCK_3= @mysqld.3.socket
+
diff --git a/mysql-test/suite/rpl/t/rpl_perfschema_order_by.test b/mysql-test/suite/rpl/t/rpl_perfschema_order_by.test
new file mode 100644
index 000000000000..0d9e0882e5c0
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_perfschema_order_by.test
@@ -0,0 +1,43 @@
+# === Purpose ===
+#
+# This test verifies that ORDER BY on replication pfs tables returns
+# the correct data set.
+#
+# === Implementation ===
+#
+# 1) Setup a multi-source replication topology.
+# 2) With STS, execute DDLs on both the masters and use SQL ordering
+# on PFS tables on slave.
+# 3) Repeat step 2 with Multi-threaded Slave.
+#
+# === References ===
+# Bug #22958077: ORDER BY LAST_SEEN_TRANSACTION RESULTS IN EMPTY SET (OR DEBUG
+# ASSERTION)
+
+--let $rpl_topology= 3->2,1->2
+--let $rpl_multi_source= 1
+--let $rpl_skip_start_slave= 1
+--source include/rpl_init.inc
+
+--let $rpl_connection_name= server_2
+--source include/rpl_connection.inc
+SET @save.slave_parallel_workers= @@global.slave_parallel_workers;
+
+--echo # Test for Single Threaded Slave
+SET GLOBAL slave_parallel_workers= 0;
+START SLAVE;
+--source extra/rpl_tests/rpl_perfschema_order_by.test
+
+--echo # Test for Multi Threaded Slave
+STOP SLAVE;
+SET GLOBAL slave_parallel_workers = 2;
+START SLAVE;
+--source extra/rpl_tests/rpl_perfschema_order_by.test
+
+#Cleanup
+STOP SLAVE;
+SET @@global.slave_parallel_workers= @save.slave_parallel_workers;
+START SLAVE;
+
+--let $rpl_skip_sync= 1
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_reset_restart-slave.opt b/mysql-test/suite/rpl/t/rpl_reset_restart-slave.opt
new file mode 100644
index 000000000000..00a660e47c10
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_reset_restart-slave.opt
@@ -0,0 +1,2 @@
+--skip-slave-start=0
+--relay-log-purge=0
diff --git a/mysql-test/suite/rpl/t/rpl_reset_restart.test b/mysql-test/suite/rpl/t/rpl_reset_restart.test
new file mode 100644
index 000000000000..45acaafdc672
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_reset_restart.test
@@ -0,0 +1,47 @@
+# ==== Purpose ====
+#
+# This test will check if reset slave is generating correct Previous_gtids
+# event in first relay log file after a RESET SLAVE.
+#
+# It will:
+# 1) generate some workload at the master;
+# 2) sync the slave with the master;
+# 3) stop slave replication threads;
+# 4) do RESET MASTER on the master;
+# 5) do RESET MASTER on the slave;
+# 6) do RESET SLAVE on the slave;
+# 7) restart the slave.
+#
+# Slave shall be able to sync with master without issues.
+#
+# ==== Related Bugs and Worklogs ====
+#
+# BUG#27636289 RPL BREAKS WITH RESTART AFTER RESET SLAVE IF --RELAY-LOG-PURGE=0
+#
+
+# This test case is binary log format agnostic
+--source include/have_binlog_format_row.inc
+--source include/have_gtid.inc
+--source include/master-slave.inc
+
+CREATE TABLE t1 (c1 INT);
+--source include/sync_slave_sql_with_master.inc
+--source include/stop_slave.inc
+
+--source include/rpl_connection_master.inc
+RESET MASTER;
+
+--source include/rpl_connection_slave.inc
+RESET MASTER;
+RESET SLAVE;
+--source include/start_slave.inc
+
+--source include/kill_and_restart_mysqld.inc
+
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--source include/rpl_connection_master.inc
+DROP TABLE t1;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves-master.opt b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves-master.opt
new file mode 100644
index 000000000000..58029d28acec
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves-master.opt
@@ -0,0 +1 @@
+$SEMISYNC_PLUGIN_OPT
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves-slave.opt b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves-slave.opt
new file mode 100644
index 000000000000..58029d28acec
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves-slave.opt
@@ -0,0 +1 @@
+$SEMISYNC_PLUGIN_OPT
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves.cnf b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves.cnf
new file mode 100644
index 000000000000..546452029ffe
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves.cnf
@@ -0,0 +1,59 @@
+!include ../my.cnf
+
+[mysqld.1]
+log-slave-updates
+server_id=1
+
+[mysqld.2]
+log-slave-updates
+server_id=2
+
+[mysqld.3]
+log-slave-updates
+server_id=3
+
+[mysqld.4]
+log-slave-updates
+server_id=4
+
+[mysqld.5]
+log-slave-updates
+server_id=5
+
+[mysqld.6]
+log-slave-updates
+server_id=6
+
+[mysqld.7]
+log-slave-updates
+server_id=7
+
+[mysqld.8]
+log-slave-updates
+server_id=8
+
+[mysqld.9]
+log-slave-updates
+server_id=9
+
+[ENV]
+SERVER_MYPORT_3= @mysqld.3.port
+SERVER_MYSOCK_3= @mysqld.3.socket
+
+SERVER_MYPORT_4= @mysqld.4.port
+SERVER_MYSOCK_4= @mysqld.4.socket
+
+SERVER_MYPORT_5= @mysqld.5.port
+SERVER_MYSOCK_5= @mysqld.5.socket
+
+SERVER_MYPORT_6= @mysqld.6.port
+SERVER_MYSOCK_6= @mysqld.6.socket
+
+SERVER_MYPORT_7= @mysqld.7.port
+SERVER_MYSOCK_7= @mysqld.7.socket
+
+SERVER_MYPORT_8= @mysqld.8.port
+SERVER_MYSOCK_8= @mysqld.8.socket
+
+SERVER_MYPORT_9= @mysqld.9.port
+SERVER_MYSOCK_9= @mysqld.9.socket
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves.test b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves.test
new file mode 100644
index 000000000000..0692438596f0
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_add_remove_slaves.test
@@ -0,0 +1,191 @@
+#==== Purpose ====
+#
+# This test script purpose is to check semisync replication
+# behaviour when there are semisync slaves getting added and
+# removed while dml changes are happening.
+#
+#==== Implementation ====
+#
+# 1) Install semisync on one Master and 8 Slaves.
+# 2) Using mysqlslap, keep inserting data in background on Master.
+# 3) While the DMLs are going on, keep adding/removing semisync slaves.
+# 4) At the end of the step-3, check that the data is synced without any
+# issues.
+# 5) Check semisync is still enabled on Master and all slaves.
+#
+#==== References ====
+#
+# Bug#27610678 SEMI-SYNC REPLICATION DOESN'T WORK FOR MINUTES AFTER RESTART
+# REPLICATION
+#
+#========
+#
+# 9 servers + 5000 inserts involved in test. Hence marking it as big-test.
+#
+--source include/big_test.inc
+--source include/not_group_replication_plugin.inc
+--source include/have_binlog_format_statement.inc
+--source include/have_debug.inc
+
+#
+# One Master and 8 Slaves in the semi sync topology.
+#
+--let rpl_topology=1->2, 1->3, 1->4, 1->5, 1->6, 1->7, 1->8, 1->9
+--source include/rpl_init.inc
+
+--echo #
+--echo # 1. Initial data.
+--echo #
+call mtr.add_suppression("Timeout waiting for reply of binlog");
+CREATE TABLE t1(c1 INT);
+--source include/rpl_sync.inc
+
+--echo #
+--echo # 2. Install semisync on all the 9 servers.
+--echo #
+--let $i= 1
+while ($i < 10)
+{
+ --let $rpl_connection_name= server_$i
+ --source include/rpl_connection.inc
+ if ( $i == 1)
+ {
+ --connect(server1_1, localhost,root,,,$MASTER_MYPORT)
+ CALL mtr.add_suppression("Semi-sync master failed on net_flush.*");
+ --source include/install_semisync_master.inc
+ }
+ if ( $i != 1 )
+ {
+ CALL mtr.add_suppression("Semi-sync slave net_flush.*");
+ --source include/install_semisync_slave.inc
+ }
+ --inc $i
+}
+
+--echo #
+--echo # 3. Make Master aware of 8 semisync slaves.
+--echo #
+--let $rpl_connection_name= server1_1
+--source include/rpl_connection.inc
+--let $slaves = 8
+--eval SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = $slaves
+
+--echo #
+--echo # 4. Insert 5000 tuples in background using 10 parallel connections.
+--echo #
+--exec_in_background $MYSQL_SLAP --create-schema=test --delimiter=";" --iterations=500 --query="INSERT INTO t1 values (1)" --concurrency=10 --silent 2>&1
+
+--echo #
+--echo # 5. While the insert operations are going in the background, keep
+--echo # adding/removing semisync slaves randomly.
+--echo #
+--let $rpl_connection_silent = 1
+--let $include_silent= 1
+--disable_result_log
+--disable_query_log
+--let $rpl_debug= 0
+--let $iter= 1
+while ( $iter < 50 )
+{
+ # Random server_id generator ( server_id will between [2-9]
+ --let $server_id=`SELECT FLOOR(2 + ((RAND() * 100) % 8))`
+ --let $rpl_connection_name= server_$server_id
+ --source include/rpl_connection.inc
+ --let $service_state= `SELECT service_state FROM performance_schema.replication_connection_status`
+ if ($service_state == 'ON')
+ {
+ # If the replication state is ON, bring it down.
+ --source include/stop_slave.inc
+ --let $rpl_connection_name= server1_1
+ --source include/rpl_connection.inc
+ # Adjust rpl_semi_sync_master_wait_for_slave_count variable.
+ --dec $slaves
+ --eval SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = $slaves
+ }
+ if ($service_state == 'OFF')
+ {
+ # If the replication state is OFF, bring it up.
+ --source include/start_slave.inc
+ --let $rpl_connection_name= server1_1
+ --source include/rpl_connection.inc
+ # Adjust rpl_semi_sync_master_wait_for_slave_count variable.
+ --inc $slaves
+ --eval SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = $slaves
+ }
+ --inc $iter
+ # Do it slowly while insertions on the master are happening in the background.
+ sleep 1;
+}
+
+--echo #
+--echo # 6. Add all 8 semisync slaves back to Master
+--echo # (if they were disconnected, in above step).
+--echo #
+--let $iter = 2
+while ($iter <= 9)
+{
+ --let $rpl_connection_name= server_$iter
+ --source include/rpl_connection.inc
+ --let $service_state= `SELECT service_state FROM performance_schema.replication_connection_status`
+ if ($service_state == 'OFF')
+ {
+ --source include/start_slave.inc
+ --let $rpl_connection_name= server1_1
+ --source include/rpl_connection.inc
+ # Adjust rpl_semi_sync_master_wait_for_slave_count variable.
+ --inc $slaves
+ --eval SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = $slaves
+ }
+ --inc $iter
+}
+--enable_result_log
+--enable_query_log
+--let $rpl_connection_silent = 0
+--let $include_silent= 0
+
+
+--echo #
+--echo # 7. Make sure the data is synced on Master without any issues.
+--echo #
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+--let $wait_timeout= 60
+--let $wait_condition= SELECT count(*) = 5000 FROM t1
+--source include/wait_condition.inc
+--let $slave_timeout=600
+--source include/rpl_sync.inc
+
+--echo #
+--echo # 8. Check on all servers semisync is enabled after the
+--echo # the experiment and then uninstall semisync pluging
+--echo # from it.
+--echo #
+--let $i= 9
+while ($i >= 1)
+{
+ --let $rpl_connection_name= server_$i
+ --source include/rpl_connection.inc
+ if ( $i == 1)
+ {
+ --let $assert_variable_name= rpl_semi_sync_master_enabled
+ --let $assert_variable_value= 1
+ --source include/assert_variable.inc
+ --source include/uninstall_semisync_master.inc
+ }
+ if ( $i != 1 )
+ {
+ --let $assert_variable_name= rpl_semi_sync_slave_enabled
+ --let $assert_variable_value= 1
+ --source include/assert_variable.inc
+ --source include/uninstall_semisync_slave.inc
+ }
+ --dec $i
+}
+
+--echo #
+--echo # 9. Cleanup time.
+--echo #
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+DROP TABLE t1;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_server_uuid.test b/mysql-test/suite/rpl/t/rpl_server_uuid.test
index 8f1d833b8538..48c1ee6012a7 100644
--- a/mysql-test/suite/rpl/t/rpl_server_uuid.test
+++ b/mysql-test/suite/rpl/t/rpl_server_uuid.test
@@ -133,7 +133,7 @@ connection master;
--echo # and master_host are not changed.
--echo -----------------------------------------------------------------------------
connection slave;
-START SLAVE IO_THREAD;
+--source include/start_slave_io.inc
--let $slave_param= Master_UUID
--let $slave_param_value= $original_master_uuid
--source include/wait_for_slave_param.inc
@@ -156,7 +156,7 @@ CHANGE MASTER TO MASTER_PORT= 1111;
--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
eval CHANGE MASTER TO MASTER_PORT= $MASTER_MYPORT,
MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
-START SLAVE IO_THREAD;
+--source include/start_slave_io.inc
--let $slave_param= Master_UUID
--let $slave_param_value= $original_master_uuid
--source include/wait_for_slave_param.inc
@@ -179,7 +179,7 @@ CHANGE MASTER TO MASTER_HOST= 'localhost';
--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1',
MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
-START SLAVE IO_THREAD;
+--source include/start_slave_io.inc
--let $slave_param= Master_UUID
--let $slave_param_value= $original_master_uuid
--source include/wait_for_slave_param.inc
@@ -200,7 +200,7 @@ CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= 1111;
--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= $MASTER_MYPORT,
MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
-START SLAVE IO_THREAD;
+--source include/start_slave_io.inc
--let $slave_param= Master_UUID
--let $slave_param_value= $original_master_uuid
--source include/wait_for_slave_param.inc
diff --git a/mysql-test/suite/sys_vars/r/sql_safe_updates_func.result b/mysql-test/suite/sys_vars/r/sql_safe_updates_func.result
index cf8d613b6830..a446363bdd86 100644
--- a/mysql-test/suite/sys_vars/r/sql_safe_updates_func.result
+++ b/mysql-test/suite/sys_vars/r/sql_safe_updates_func.result
@@ -19,7 +19,7 @@ SET SESSION sql_safe_updates = ON;
'#-----------------------------FN_DYNVARS_164_02------------------------------------#'
Expected error : Update without key in safe mode
DELETE FROM t1;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SELECT * FROM t1;
a b
1 val1
@@ -34,16 +34,13 @@ a b
PREPARE stmt FROM 'DELETE FROM t1;';
Expected error : Update without key in safe mode
EXECUTE stmt;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
DEALLOCATE PREPARE stmt;
'#-----------------------------FN_DYNVARS_164_03------------------------------------#'
-Expected error : Update without key in safe mode
+No error : Update without key in safe mode but with LIMIT
DELETE FROM t1 LIMIT 2;
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
SELECT * FROM t1;
a b
-1 val1
-2 val2
3 val3
4 val4
5 val5
@@ -54,11 +51,9 @@ a b
'#-----------------------------FN_DYNVARS_164_04------------------------------------#'
Expected error : Update without key in safe mode
DELETE FROM t1 WHERE b='val1';
-ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SELECT * FROM t1;
a b
-1 val1
-2 val2
3 val3
4 val4
5 val5
@@ -68,11 +63,9 @@ a b
9 val9
'#-----------------------------FN_DYNVARS_164_05------------------------------------#'
This one should work
-DELETE FROM t1 WHERE a=1;
+DELETE FROM t1 WHERE a=3;
SELECT * FROM t1;
a b
-2 val2
-3 val3
4 val4
5 val5
6 val6
@@ -88,8 +81,6 @@ This one should work
DELETE FROM t1 WHERE b='val1';
SELECT * FROM t1;
a b
-2 val2
-3 val3
4 val4
5 val5
6 val6
@@ -98,13 +89,10 @@ a b
9 val9
'#-----------------------------FN_DYNVARS_164_07------------------------------------#'
This one should work
-DELETE FROM t1 WHERE a=1;
+DELETE FROM t1 WHERE a=5;
SELECT * FROM t1;
a b
-2 val2
-3 val3
4 val4
-5 val5
6 val6
7 val7
8 val8
@@ -114,9 +102,6 @@ This one should work
DELETE FROM t1 LIMIT 2;
SELECT * FROM t1;
a b
-4 val4
-5 val5
-6 val6
7 val7
8 val8
9 val9
@@ -127,9 +112,6 @@ Bug#35392 Unexpected error occurs in this statement Can't change size of the fil
statement is remarked because the error is uncatchable by testing framework
SELECT * FROM t1;
a b
-4 val4
-5 val5
-6 val6
7 val7
8 val8
9 val9
diff --git a/mysql-test/suite/sys_vars/t/sql_safe_updates_func.test b/mysql-test/suite/sys_vars/t/sql_safe_updates_func.test
index a8ce3a8d0f7a..893d06c2bac0 100644
--- a/mysql-test/suite/sys_vars/t/sql_safe_updates_func.test
+++ b/mysql-test/suite/sys_vars/t/sql_safe_updates_func.test
@@ -74,8 +74,7 @@ DEALLOCATE PREPARE stmt;
#
# With a LIMIT Clause
#
---echo Expected error : Update without key in safe mode
---error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+--echo No error : Update without key in safe mode but with LIMIT
DELETE FROM t1 LIMIT 2;
SELECT * FROM t1;
@@ -93,7 +92,7 @@ SELECT * FROM t1;
# With a key WHERE Clause
#
--echo This one should work
-DELETE FROM t1 WHERE a=1;
+DELETE FROM t1 WHERE a=3;
SELECT * FROM t1;
--echo
@@ -118,7 +117,7 @@ SELECT * FROM t1;
# With a key WHERE Clause
#
--echo This one should work
-DELETE FROM t1 WHERE a=1;
+DELETE FROM t1 WHERE a=5;
SELECT * FROM t1;
--echo '#-----------------------------FN_DYNVARS_164_08------------------------------------#'
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index e5832548829c..2b01c813bfb1 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -3167,3 +3167,54 @@ ALTER TABLE t2 ADD INDEX idx1(fld1(769));
DROP TABLE t1, t2;
SET sql_mode= @orig_sql_mode;
SET GLOBAL innodb_large_prefix= @orig_innodb_large_prefix;
+
+--echo #
+--echo # BUG#27788685: NO WARNING WHEN TRUNCATING A STRING WITH DATA LOSS
+--echo #
+
+--enable_warnings
+SET GLOBAL max_allowed_packet=17825792;
+
+--connect(con1, localhost, root,,)
+CREATE TABLE t1 (t1_fld1 TEXT) ENGINE=InnoDB;
+CREATE TABLE t2 (t2_fld1 MEDIUMTEXT) ENGINE=InnoDB;
+CREATE TABLE t3 (t3_fld1 LONGTEXT) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (REPEAT('a',300));
+INSERT INTO t2 VALUES (REPEAT('b',65680));
+INSERT INTO t3 VALUES (REPEAT('c',16777300));
+
+SELECT LENGTH(t1_fld1) FROM t1;
+SELECT LENGTH(t2_fld1) FROM t2;
+SELECT LENGTH(t3_fld1) FROM t3;
+
+--echo # With strict mode
+SET SQL_MODE='STRICT_ALL_TABLES';
+
+--error ER_DATA_TOO_LONG
+ALTER TABLE t1 CHANGE `t1_fld1` `my_t1_fld1` TINYTEXT;
+--error ER_DATA_TOO_LONG
+ALTER TABLE t2 CHANGE `t2_fld1` `my_t2_fld1` TEXT;
+--error ER_DATA_TOO_LONG
+ALTER TABLE t3 CHANGE `t3_fld1` `my_t3_fld1` MEDIUMTEXT;
+
+--echo # With non-strict mode
+SET SQL_MODE='';
+
+ALTER TABLE t1 CHANGE `t1_fld1` `my_t1_fld1` TINYTEXT;
+ALTER TABLE t2 CHANGE `t2_fld1` `my_t2_fld1` TEXT;
+ALTER TABLE t3 CHANGE `t3_fld1` `my_t3_fld1` MEDIUMTEXT;
+
+SELECT LENGTH(my_t1_fld1) FROM t1;
+SELECT LENGTH(my_t2_fld1) FROM t2;
+SELECT LENGTH(my_t3_fld1) FROM t3;
+
+# Cleanup
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--connection default
+DROP TABLE t1, t2, t3;
+
+SET SQL_MODE=default;
+SET GLOBAL max_allowed_packet=default;
diff --git a/mysql-test/t/bug83739.test b/mysql-test/t/bug83739.test
new file mode 100644
index 000000000000..bd10efa4ca59
--- /dev/null
+++ b/mysql-test/t/bug83739.test
@@ -0,0 +1,16 @@
+--source include/have_geometry.inc
+
+--echo #
+--echo # Bug #25062396 / #83739 "Assertion `cur_shape != Gcalc_function::shape_point' failed"
+--echo # fixed in 5.6.39, 5.7.21, 8.0.4
+--echo # For geometry calculations, invalid input parameters could lead to an
+--echo # incorrect result buffer and cause an assertion to be raised or a
+--echo # server exit
+--echo #
+
+SELECT ST_ASTEXT(
+ ST_DIFFERENCE(
+ ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(' 'POINT(-5 -4),' 'POLYGON((-5 1,7 -7,10 0,-10 8,-7 9,-5 1)))'),
+ ST_GEOMFROMTEXT('LINESTRING(5 3,7 -3,5 0,-6 -9,-4 9,-3 -8,10 1,10 -9,5 -3,4 -2,1 -3,-8 -5,4 -7,-2 -8)')
+ )
+);
diff --git a/mysql-test/t/bug88781.test b/mysql-test/t/bug88781.test
new file mode 100644
index 000000000000..effd108a196d
--- /dev/null
+++ b/mysql-test/t/bug88781.test
@@ -0,0 +1,22 @@
+--echo #
+--echo # Bug #26881798 / #88781 "handle_fatal_signal (sig=11) in replace_db_table"
+--echo # fixed in 5.5.60, 5.6.40, 5.7.22, 8.0.4
+--echo # Dropping an index from a system table could cause a server exit
+--echo #
+
+CALL mtr.add_suppression("Did not write failed 'GRANT DROP ON none\\.\\* TO 'bug88781'@'localhost'' into binary log while granting/revoking privileges in databases\\.");
+
+CREATE USER 'bug88781'@'localhost';
+
+RENAME TABLE mysql.db TO mysql.bak;
+
+CREATE TABLE mysql.db ENGINE=MyISAM SELECT * FROM mysql.bak;
+
+--error ER_MISSING_KEY
+GRANT DROP ON none.* TO 'bug88781'@'localhost';
+
+DROP TABLE mysql.db;
+
+RENAME TABLE mysql.bak TO mysql.db;
+
+DROP USER 'bug88781'@'localhost';
diff --git a/mysql-test/t/bug88800.test b/mysql-test/t/bug88800.test
new file mode 100644
index 000000000000..72a591cb0440
--- /dev/null
+++ b/mysql-test/t/bug88800.test
@@ -0,0 +1,36 @@
+--echo #
+--echo # Bug #27230925 / #88800 "handle_fatal_signal (sig=11) in show_routine_grants"
+--echo # fixed in 5.5.61, 5.6.41, 5.7.23, 8.0.12
+--echo # Mishandling of internal privilege structures could cause a server exit
+--echo #
+
+CREATE TABLE t1 (
+ id INT UNSIGNED AUTO_INCREMENT,
+ name CHAR(50),
+ PRIMARY KEY (id)
+);
+CREATE PROCEDURE p1() BEGIN END;
+
+CREATE USER 'bug88800'@'localhost';
+GRANT ALL ON test.* TO 'bug88800'@'localhost';
+GRANT EXECUTE ON PROCEDURE test.p1 TO 'bug88800'@'localhost' WITH GRANT OPTION;
+
+RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
+
+--error ER_NO_SUCH_TABLE
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR 'bug88800'@'localhost';
+
+--error ER_NO_SUCH_TABLE
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR 'bug88800'@'localhost';
+
+RENAME TABLE mysql.procs_gone TO mysql.procs_priv;
+
+DROP USER 'bug88800'@'localhost';
+
+DROP PROCEDURE p1;
+
+DROP TABLE t1;
+
+CALL mtr.add_suppression("Fatal error: Can't open and lock privilege tables: Table 'mysql.procs_priv' doesn't exist");
diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test
index 7948576b90e6..80e870c6187b 100644
--- a/mysql-test/t/connect.test
+++ b/mysql-test/t/connect.test
@@ -452,6 +452,67 @@ DROP USER wl6587@localhost;
--echo # -- End of 5.6 tests
--echo # ------------------------------------------------------------------
+--echo #
+--echo # BUG#27539838: NOT ALL ABORTED CONNECTS ARE REPORTED TO ERROR.LOG
+--echo # PROPERLY
+--echo #
+
+--let LOG_ERR=$MYSQLTEST_VARDIR/tmp/myerror.err
+--let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/myerror.err
+
+--let restart_parameters="restart: --log-error=$LOG_ERR --log-error-verbosity=3"
+--replace_result $LOG_ERR LOG_ERR
+--source include/restart_mysqld.inc
+
+SHOW STATUS LIKE 'Aborted_connects';
+
+--echo
+--echo # Case 1: Connection attempt by an invalid user
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_ACCESS_DENIED_ERROR
+connect(con1,localhost,newuser,,);
+
+--let SEARCH_PATTERN= Access denied for user 'newuser'@'localhost' \(using password: NO\)
+--source include/search_pattern_in_file.inc
+
+--echo
+--echo # Case 2: Connection attempt by a valid user with incorrect password
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_ACCESS_DENIED_ERROR
+connect(con1,localhost,root,1234,);
+
+--let SEARCH_PATTERN= Access denied for user 'root'@'localhost' \(using password: YES\)
+--source include/search_pattern_in_file.inc
+
+# Creating a dummy database and an user with no privileges to access that database
+--connection default
+CREATE DATABASE test1;
+CREATE USER 'new1'@'localhost';
+
+--echo
+--echo # Case 3: Connection attempt by a valid user with no privileges to access a database
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_DBACCESS_DENIED_ERROR
+connect(con1,localhost,new1,,test1);
+
+--let SEARCH_PATTERN= Access denied for user 'new1'@'localhost' to database 'test1'
+--source include/search_pattern_in_file.inc
+
+--echo
+--echo # Case 4: SSL connection attempt without necessary certificates
+--error 1
+--exec $MYSQL --user=root --ssl-mode=VERIFY_CA
+
+--let SEARCH_PATTERN= Got an error reading communication packets
+--source include/search_pattern_in_file.inc
+
+# Uncomment the below statement when BUG#28490126 is fixed.
+# SHOW STATUS LIKE 'Aborted_connects';
+
+# Cleanup
+DROP USER 'new1'@'localhost';
+DROP DATABASE test1;
+--remove_file $LOG_ERR
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 05313f71f132..c832569b5de8 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -146,8 +146,9 @@ INSERT INTO t2 VALUES(10),(20);
SET SESSION sql_safe_updates=1;
+EXPLAIN DELETE t2 FROM t1 JOIN t2 WHERE t1.a = 10;
-- error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
-DELETE t1 FROM t1 JOIN t2 WHERE t1.a = 10;
+DELETE t2 FROM t1 JOIN t2 WHERE t1.a = 10;
SET SESSION sql_safe_updates=default;
diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
index b68cefc47fe4..9a8ec263675a 100644
--- a/mysql-test/t/heap_btree.test
+++ b/mysql-test/t/heap_btree.test
@@ -265,3 +265,10 @@ DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a;
DROP TABLE t1;
--echo End of 5.0 tests
+--echo #
+--echo # Bug#27799513: POTENTIAL DOUBLE FREE OR CORRUPTION OF HEAP INFO (HP_INFO)
+--echo #
+ CREATE TABLE t1 (id INT, a VARCHAR(300) NOT NULL, KEY USING BTREE(a)) ENGINE=Heap;
+INSERT t1 VALUES (1, REPEAT('a', 300));
+DROP TABLE t1;
+--echo End of 5.5 tests
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 9f08f68a8514..399128557207 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -197,7 +197,7 @@ drop table t1,t2;
set sql_safe_updates=1;
create table t1 (n int(10), d int(10));
create table t2 (n int(10), d int(10));
-insert into t1 values(1,1);
+insert into t1 values(1,1), (3,30);
insert into t2 values(1,10),(2,20);
--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
diff --git a/mysql-test/t/myisam-blob.test b/mysql-test/t/myisam-blob.test
index a06df127c6c1..1563e9823f2b 100644
--- a/mysql-test/t/myisam-blob.test
+++ b/mysql-test/t/myisam-blob.test
@@ -6,6 +6,7 @@
--source include/force_myisam_default.inc
--source include/have_myisam.inc
+SET SQL_MODE='';
#
# Test bugs in the MyISAM code with blobs
#
@@ -48,4 +49,5 @@ UPDATE IGNORE t1 set data=repeat('a',18*1024*1024);
select length(data) from t1;
drop table t1;
+SET SQL_MODE=default;
# End of 4.1 tests
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 31414325d9f2..82c524b0637c 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -2723,3 +2723,21 @@ SET GLOBAL relay_log_info_repository= 'FILE';
SHOW VARIABLES LIKE "master_info_repository";
SHOW VARIABLES LIKE "relay_log_info_repository";
+
+--echo #
+--echo # Bug#27931181: RESTAURE DUMP CREATED WITH 5.7.22 ON 8.0.11
+--echo #
+
+CREATE DATABASE bug27931181;
+USE bug27931181;
+CREATE TABLE t1 (a INT);
+SET sql_mode='NO_AUTO_CREATE_USER';
+CREATE TRIGGER trig1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = 1;
+SET sql_mode='NO_AUTO_CREATE_USER,ONLY_FULL_GROUP_BY';
+CREATE PROCEDURE p1() SELECT 1;
+SET sql_mode=@@global.sql_mode;
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+
+--exec $MYSQL_DUMP --skip-comments --databases --events --triggers --routines bug27931181
+#cleanup
+DROP DATABASE bug27931181;
diff --git a/mysql-test/t/parser-master.opt b/mysql-test/t/parser-master.opt
new file mode 100644
index 000000000000..6dee8ced3487
--- /dev/null
+++ b/mysql-test/t/parser-master.opt
@@ -0,0 +1 @@
+--max_allowed_packet=18000000
diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test
index 69d9e057185d..d60a33dbf339 100644
--- a/mysql-test/t/parser.test
+++ b/mysql-test/t/parser.test
@@ -1365,3 +1365,14 @@ DROP TABLE t1, t2;
--echo #
+--echo
+--echo Bug #27714748: @@PARSER_MAX_MEM_SIZE DOES NOT WORK FOR ROUTINES
+--echo
+
+SET parser_max_mem_size = 10000000; # minimum allowed value
+--let $s = `SELECT REPEAT('x', @@parser_max_mem_size)`
+--disable_query_log
+--error ER_CAPACITY_EXCEEDED
+--eval CREATE PROCEDURE p() SELECT 1 FROM (SELECT '$s') a
+--enable_query_log
+SET parser_max_mem_size = default;
diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test
index bab0ef276034..969f0c2a6420 100644
--- a/mysql-test/t/partition_pruning.test
+++ b/mysql-test/t/partition_pruning.test
@@ -4,6 +4,7 @@
#
--source include/no_valgrind_without_big.inc
--source include/have_partition.inc
+--source include/have_innodb_16k.inc
let $verify_without_partitions=0;
--echo #
@@ -53,6 +54,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
}
INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8);
+ANALYZE TABLE t1;
SELECT * FROM t1 WHERE a < 1;
--replace_column 10 #
@@ -175,6 +177,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
}
INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7);
+ANALYZE TABLE t1;
SELECT * FROM t1 WHERE a < 1;
--replace_column 10 #
@@ -364,6 +367,7 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'),
(1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'),
(1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07');
+ANALYZE TABLE t1;
--replace_column 10 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
--replace_column 10 #
@@ -480,6 +484,7 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'),
(1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'),
(1, '2009-04-07');
+ANALYZE TABLE t1;
--replace_column 10 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
--replace_column 10 #
@@ -595,6 +600,7 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'),
(1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'),
(1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07');
+ANALYZE TABLE t1;
--replace_column 10 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
--replace_column 10 #
@@ -710,6 +716,7 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'),
(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'),
(1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'),
(1, '2009-04-07');
+ANALYZE TABLE t1;
--replace_column 10 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME);
--replace_column 10 #
@@ -822,6 +829,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL);
+ANALYZE TABLE t1;
--echo # test with an invalid date, which lead to item->null_value is set.
--replace_column 10 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME);
@@ -856,6 +864,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
--replace_column 10 #
explain select * from t1 where a=5 and a=6;
drop table t1;
@@ -869,6 +878,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a=1;
@@ -887,6 +897,7 @@ if ($verify_without_partitions)
ALTER TABLE t2 REMOVE PARTITIONING;
}
insert into t2 values (1,1),(2,2),(3,3);
+ANALYZE TABLE t2;
--replace_column 10 #
explain partitions select * from t2 where a=1;
@@ -909,6 +920,7 @@ if ($verify_without_partitions)
ALTER TABLE t3 REMOVE PARTITIONING;
}
insert into t3 values (5),(15);
+ANALYZE TABLE t3;
--replace_column 10 #
explain partitions select * from t3 where a=11;
@@ -929,6 +941,7 @@ if ($verify_without_partitions)
ALTER TABLE t4 REMOVE PARTITIONING;
}
insert into t4 values (10,2), (10,4);
+ANALYZE TABLE t4;
# empty OR one
--replace_column 10 #
@@ -968,6 +981,7 @@ ALTER TABLE t5 REMOVE PARTITIONING;
}
insert into t5 values (10,2,0,0), (10,4,0,0), (10,2,0,1), (10,4,0,1);
+ANALYZE TABLE t5;
--replace_column 10 #
explain partitions select * from t5;
@@ -1010,6 +1024,7 @@ if ($verify_without_partitions)
ALTER TABLE t6 REMOVE PARTITIONING;
}
insert into t6 values (1),(3),(5);
+ANALYZE TABLE t6;
--replace_column 10 #
explain partitions select * from t6 where a < 1;
@@ -1051,6 +1066,7 @@ if ($verify_without_partitions)
ALTER TABLE t6 REMOVE PARTITIONING;
}
insert into t6 values (1),(3),(5);
+ANALYZE TABLE t6;
--replace_column 10 #
explain partitions select * from t6 where a < 1;
@@ -1091,6 +1107,7 @@ if ($verify_without_partitions)
ALTER TABLE t7 REMOVE PARTITIONING;
}
insert into t7 values (10),(30),(50);
+ANALYZE TABLE t7;
# leftmost intervals
--replace_column 10 #
@@ -1158,6 +1175,7 @@ if ($verify_without_partitions)
ALTER TABLE t7 REMOVE PARTITIONING;
}
insert into t7 values (10),(30),(50);
+ANALYZE TABLE t7;
# leftmost intervals
--replace_column 10 #
@@ -1222,6 +1240,7 @@ if ($verify_without_partitions)
ALTER TABLE t8 REMOVE PARTITIONING;
}
insert into t8 values ('1985-05-05'),('1995-05-05');
+ANALYZE TABLE t8;
--replace_column 10 #
explain partitions select * from t8 where a < '1980-02-02';
@@ -1237,6 +1256,7 @@ if ($verify_without_partitions)
ALTER TABLE t9 REMOVE PARTITIONING;
}
insert into t9 values ('2005-05-05'), ('2005-04-04');
+ANALYZE TABLE t9;
--replace_column 10 #
explain partitions select * from t9 where a < '2004-12-19';
@@ -1271,6 +1291,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a1 > 3;
--replace_column 10 #
@@ -1293,6 +1314,7 @@ if ($verify_without_partitions)
ALTER TABLE t3 REMOVE PARTITIONING;
}
insert into t3 values (1,1),(2,2),(3,3);
+ANALYZE TABLE t3;
--replace_column 10 #
explain partitions select * from t3 where a=2 or b=1;
@@ -1309,6 +1331,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1),(2);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a is null;
@@ -1325,6 +1348,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1,1),(2,2),(3,3),(4,4);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions
@@ -1344,6 +1368,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1),(2),(3);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a > 1 and a < 3;
--replace_column 10 #
@@ -1367,6 +1392,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1,1),(2,2),(3,3);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where b > 1 and b < 3;
@@ -1388,6 +1414,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1),(1),(2),(2),(3),(4),(3),(4);
+ANALYZE TABLE t1;
--echo # This won't do any table access
--let $q = update t1 set a=100 where a=5
@@ -1471,10 +1498,12 @@ show status like 'Handler_external_lock';
--sorted_result
select * from t1;
insert into t1 values (1), (1);
+ANALYZE TABLE t1;
--echo # Same as above multi-table UPDATE/DELETE
create table t2 like t1;
insert into t2 select * from t1;
+ANALYZE TABLE t2;
--let $q = update t1,t2 set t1.a=1000, t2.a=1000 where t1.a=5 and t2.a=5
--replace_column 10 #
@@ -1536,7 +1565,7 @@ CREATE TABLE `t2` (
insert into t2 select A.a + 10*(B.a + 10* C.a) from t1 A, t1 B, t1 C ;
insert into t1 select a from t2;
-
+ANALYZE TABLE t1;
drop table t2;
CREATE TABLE `t2` (
`a` int(11) default NULL,
@@ -1565,6 +1594,7 @@ insert into t2 select a,2 from t1 where a >= 200 and a < 400;
insert into t2 select a,3 from t1 where a >= 400 and a < 600;
insert into t2 select a,4 from t1 where a >= 600 and a < 800;
insert into t2 select a,5 from t1 where a >= 800 and a < 1001;
+ANALYZE TABLE t2;
--let $q = select * from t2
--replace_column 10 #
@@ -1853,6 +1883,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 set f_int1 = null;
+ANALYZE TABLE t1;
select * from t1 where f_int1 is null;
--replace_column 10 #
@@ -1876,6 +1907,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a=1 AND (b=1 OR b=2);
drop table t1;
@@ -1895,6 +1927,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4), (NULL,1);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a IS NULL AND (b=1 OR b=2);
@@ -1919,6 +1952,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (NULL), (0),(1),(2),(3),(4),(5),(6);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a is null or a < 2;
drop table t1;
@@ -1934,6 +1968,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (0),(1),(null);
+ANALYZE TABLE t1;
select count(*) from t1 where s1 < 0 or s1 is null;
--replace_column 10 #
@@ -1954,6 +1989,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values ('na');
+ANALYZE TABLE t1;
select * from t1;
select * from t1 where a like 'n%';
drop table t1;
@@ -1967,6 +2003,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
}
select * from t1 where s1 = 0 or s1 is null;
insert into t1 values ('aa'),('bb'),('0');
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where s1 = 0 or s1 is null;
drop table t1;
@@ -1985,7 +2022,7 @@ ALTER TABLE t2 REMOVE PARTITIONING;
}
insert into t2 values (1,1),(2,2);
-
+ANALYZE TABLE t2;
--vertical_results
--replace_column 10 #
explain partitions select * from t2;
@@ -2015,6 +2052,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
insert into t1 values (5),(15),(105),(1005);
insert into t1 values (18446744073709551000+1);
insert into t1 values (18446744073709551614-1);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a < 10;
@@ -2067,6 +2105,8 @@ ALTER TABLE t2 REMOVE PARTITIONING;
insert into t1 values (0x20), (0x20), (0x41), (0x41), (0xFE), (0xFE);
insert into t2 values (0x20), (0x20), (0x41), (0x41), (0xFE), (0xFE);
+ANALYZE TABLE t1;
+ANALYZE TABLE t2;
--replace_column 10 #
explain partitions select * from t1 where a=0;
--replace_column 10 #
@@ -2107,6 +2147,7 @@ ALTER TABLE t1 REMOVE PARTITIONING;
insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1);
insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where
@@ -2131,6 +2172,7 @@ if ($verify_without_partitions)
ALTER TABLE t1 REMOVE PARTITIONING;
}
insert into t1 values (-15),(-5),(5),(15),(-15),(-5),(5),(15);
+ANALYZE TABLE t1;
--replace_column 10 #
explain partitions select * from t1 where a>-2 and a <=0;
drop table t1;
@@ -2153,6 +2195,7 @@ INSERT INTO t1 VALUES ('2007-03-01 12:00:00');
INSERT INTO t1 VALUES ('2007-03-07 12:00:00');
INSERT INTO t1 VALUES ('2007-03-08 12:00:00');
INSERT INTO t1 VALUES ('2007-03-15 12:00:00');
+ANALYZE TABLE t1;
-- echo must use p0 only:
--replace_column 10 #
explain partitions select * from t1 where recdate < '2007-03-08 00:00:00';
@@ -2171,6 +2214,7 @@ INSERT INTO t1 VALUES ('2005-03-01 12:00:00');
INSERT INTO t1 VALUES ('2005-03-01 12:00:00');
INSERT INTO t1 VALUES ('2006-03-01 12:00:00');
INSERT INTO t1 VALUES ('2006-03-01 12:00:00');
+ANALYZE TABLE t1;
-- echo must use p0 only:
--replace_column 10 #
@@ -2193,6 +2237,7 @@ if ($verify_without_partitions)
ALTER TABLE t0 REMOVE PARTITIONING;
}
insert into t1 select A.a + 10*B.a from t0 A, t0 B;
+ANALYZE TABLE t1;
# this will use interval_via_walking
--replace_column 10 #
@@ -2216,6 +2261,7 @@ PARTITION BY LIST COLUMNS (c2)
PARTITION p2 VALUES IN (3,4));
INSERT INTO t1 VALUES (1, 1, 1, 1), (2, 3, 1, 1);
INSERT INTO t1 VALUES (1, 2, 1, 1), (2, 4, 1, 1);
+ANALYZE TABLE t1;
SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
diff --git a/mysql-test/t/percona_heap_blob.test b/mysql-test/t/percona_heap_blob.test
index e82509893b93..d43d41ad102d 100644
--- a/mysql-test/t/percona_heap_blob.test
+++ b/mysql-test/t/percona_heap_blob.test
@@ -584,6 +584,7 @@ SET GLOBAL max_allowed_packet = 24 * 1024 * 1024;
connect(con1, localhost, root,,);
connection con1;
+SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
SET default_storage_engine=MEMORY;
diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test
index c6fd77f8077a..88805ab4b7e7 100644
--- a/mysql-test/t/select_safe.test
+++ b/mysql-test/t/select_safe.test
@@ -93,3 +93,83 @@ drop table t1;
SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, MAX_JOIN_SIZE=DEFAULT;
# End of 4.1 tests
+
+--echo #
+--echo # Bug #28145710: SQL_SAFE_UPDATES ERROR IS INSUFFICIENTLY INFORMATIVE
+--echo #
+
+CREATE TABLE t1 (c1 INT NOT NULL, c2 VARCHAR(200) NOT NULL,
+ UNIQUE KEY idx1 (c1), UNIQUE KEY idx2 (c2));
+CREATE TABLE t2 (c1 INT NOT NULL, c2 VARCHAR(200) NOT NULL,
+ UNIQUE KEY idx1 (c1));
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (11, 'a'), (12, 'b'), (3, 'c'), (14, 'd');
+ANALYZE TABLE t1, t2;
+
+SET SESSION sql_safe_updates=1;
+
+SET RANGE_OPTIMIZER_MAX_MEM_SIZE= 1;
+#DELETE with range_optimizer_max_mem_size warning
+let query1= DELETE FROM t1 WHERE c1 IN (1,22);
+#UPDATE with range_optimizer_max_mem_size warning
+let query2= UPDATE t1 SET c1=20 WHERE c1 IN (1,22);
+#multi-table DELETE with conversion warning and target table uses table scan
+let query3= DELETE t1 FROM t1 JOIN t2 ON t1.c2 = t2.c1;
+#multi-table UPDATE with conversion warning and target table uses table scan
+let query4= UPDATE t1, t2 SET t1.c1=20 WHERE t1.c2 = t2.c1;
+#multi-table DELETE with target table uses eq_ref (no error)
+let query5= DELETE t2 FROM t1 JOIN t2 ON t1.c2 = t2.c1;
+#DELETE with conversion warning
+let query6= DELETE FROM t1 WHERE c2 IN(1,2222);
+#DELETE with conversion warning
+let query7= UPDATE t1 SET c1=20 WHERE c2 IN(1,2222);
+#DELETE with non-indexed column returns error
+let query8= DELETE FROM t2 WHERE c2 IN('a','e');
+#DELETE full table and test with binlog disabled
+let query9= DELETE FROM t2;
+
+
+
+eval EXPLAIN $query1;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query1;
+
+eval EXPLAIN $query2;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query2;
+SET RANGE_OPTIMIZER_MAX_MEM_SIZE= default;
+
+eval EXPLAIN $query3;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query3;
+
+eval EXPLAIN $query4;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query4;
+
+eval EXPLAIN $query5;
+eval $query5;
+
+eval EXPLAIN $query6;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query6;
+
+eval EXPLAIN $query7;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query7;
+
+eval EXPLAIN $query8;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query8;
+
+eval EXPLAIN $query9;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query9;
+
+SET sql_log_bin= 0;
+--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
+eval $query9;
+SET sql_log_bin= default;
+
+DROP TABLE t1, t2;
+SET SESSION sql_safe_updates=default;
diff --git a/mysql-test/t/subquery_bugs.test b/mysql-test/t/subquery_bugs.test
new file mode 100644
index 000000000000..dc9c5f4617f0
--- /dev/null
+++ b/mysql-test/t/subquery_bugs.test
@@ -0,0 +1,59 @@
+--echo #
+--echo # Bug#27182010 SUBQUERY INCORRECTLY SHOWS DUPLICATE VALUES ON SUBQUERIES
+--echo #
+
+CREATE TABLE p (Id INT,PRIMARY KEY (Id));
+INSERT INTO p VALUES (1);
+
+--echo # Test UNIQUE KEY with NULL values
+CREATE TABLE s (Id INT, u INT, UNIQUE KEY o(Id, u) );
+INSERT INTO s VALUES (1, NULL),(1, NULL);
+
+let query1= SELECT p.Id FROM (p) WHERE p.Id IN (
+ SELECT s.Id FROM s WHERE Id=1 AND u IS NULL)ORDER BY Id DESC;
+let query2= SELECT p.Id FROM (p) WHERE p.Id IN (
+ SELECT s.Id FROM s WHERE Id=1 AND u IS NOT NULL) ORDER BY Id DESC;
+
+eval EXPLAIN $query1;
+eval EXPLAIN $query2;
+
+eval $query1;
+eval $query2;
+
+--echo # UNIQUE KEY without NULL values
+CREATE TABLE s1 (Id INT, u INT, UNIQUE KEY o(Id, u) );
+INSERT INTO s1 VALUES (1, 2),(1, 3);
+
+let query3= SELECT p.Id FROM (p) WHERE p.Id IN (
+ SELECT s1.Id FROM s1 WHERE Id=1 AND u IS NOT NULL) ORDER BY Id DESC;
+let query4= SELECT p.Id FROM (p) WHERE p.Id IN (
+ SELECT s1.Id FROM s1 WHERE Id=1 AND u != 1) ORDER BY Id DESC;
+
+eval EXPLAIN $query3;
+eval EXPLAIN $query4;
+
+eval $query3;
+eval $query4;
+
+--echo # NON UNIQUE KEY Scenario
+CREATE TABLE s2 (Id INT, u INT, KEY o(Id, u) );
+INSERT INTO s2 VALUES (1, NULL),(1, NULL);
+
+let query5= SELECT p.Id FROM (p) WHERE p.Id IN (
+ SELECT s.Id FROM s2 s WHERE Id=1 AND u IS NULL) ORDER BY Id DESC;
+
+--echo #UNIQUE KEY with NON NULL FIELDS
+CREATE TABLE s3 (Id INT NOT NULL, u INT NOT NULL, UNIQUE KEY o(Id, u));
+INSERT INTO s3 VALUES (1, 2),(1, 3);
+
+let query6= SELECT p.Id FROM (p) WHERE p.Id IN (
+ SELECT s.Id FROM s3 s WHERE Id=1 AND u IS NOT NULL)
+ ORDER BY Id DESC;
+
+eval EXPLAIN $query5;
+eval EXPLAIN $query6;
+
+eval $query5;
+eval $query6;
+
+DROP TABLE p, s, s1, s2, s3;
\ No newline at end of file
diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test
index 8524cc7ac656..38a03a0f1f18 100644
--- a/mysql-test/t/type_year.test
+++ b/mysql-test/t/type_year.test
@@ -197,3 +197,15 @@ INSERT INTO t1 VALUES (TIME'25:00:00');
SELECT * FROM t1;
DROP TABLE t1;
SET timestamp=DEFAULT;
+
+--echo #
+--echo # Bug#28172538 YEAR RANGE CHECK FAILS WITH MAX YEAR FLOAT CONSTANT
+--echo #
+CREATE TABLE t(y YEAR);
+INSERT INTO t VALUES (2155), (2155.0);
+SELECT * FROM t;
+--echo Used to fail
+INSERT INTO t VALUES (2155.0E00);
+INSERT INTO t VALUES (2.1550E+03);
+SELECT * FROM t;
+DROP TABLE t;
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 4ae8871b6621..c09d3f1b7261 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -13,7 +13,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys)
SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c
errors.c hash.c list.c mf_cache.c mf_dirname.c mf_fn_ext.c
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index e48bc4338ebc..17043450c3df 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018, Percona and/or its affiliates. All rights reserved.
Copyright (c) 2010, 2017, MariaDB
@@ -105,14 +105,14 @@ my_off_t my_b_append_tell(IO_CACHE* info)
*/
{
volatile my_off_t save_pos;
- save_pos= mysql_file_tell(info->file, MYF(0));
- mysql_file_seek(info->file, (my_off_t)0, MY_SEEK_END,MYF(0));
+ save_pos = mysql_file_tell(info->file,MYF(0));
+ mysql_file_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0));
/*
Save the value of my_tell in res so we can see it when studying coredump
*/
DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
- == (res= mysql_file_tell(info->file, MYF(0))));
- mysql_file_seek(info->file, save_pos, MY_SEEK_SET,MYF(0));
+ == (res=mysql_file_tell(info->file,MYF(0))));
+ mysql_file_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
}
#endif
res = info->end_of_file + (info->write_pos-info->append_read_pos);
@@ -212,7 +212,7 @@ size_t my_b_fill(IO_CACHE *info)
if (info->seek_not_done)
{ /* File touched, do seek */
- if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET,MYF(0)) ==
+ if (mysql_file_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
{
info->error= 0;
@@ -232,7 +232,7 @@ size_t my_b_fill(IO_CACHE *info)
}
DBUG_EXECUTE_IF ("simulate_my_b_fill_error",
{DBUG_SET("+d,simulate_file_read_error");});
- if ((length= mysql_file_read(info->file, info->buffer, max_length,
+ if ((length= mysql_file_read(info->file,info->buffer,max_length,
info->myflags)) == (size_t) -1)
{
info->error= -1;
diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in
index 7561f0937685..534f7b611d7d 100644
--- a/packaging/WiX/mysql_server.wxs.in
+++ b/packaging/WiX/mysql_server.wxs.in
@@ -39,6 +39,9 @@
+
+
+
@@ -137,6 +140,13 @@
INSTALLDIR2
+
+
+
+
+ (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") AND (NOT MYSQL_INSTALLER="YES")
+
diff --git a/packaging/deb-in/CMakeLists.txt b/packaging/deb-in/CMakeLists.txt
index b7b451c40b8f..682077ac11c6 100644
--- a/packaging/deb-in/CMakeLists.txt
+++ b/packaging/deb-in/CMakeLists.txt
@@ -46,6 +46,7 @@ IF (NOT DEFINED DEB_CHANGELOG_TIMESTAMP)
)
SET (DEB_CHANGELOG_TIMESTAMP ${DEB_CHANGELOG_TIMESTAMP} CACHE STRING "")
ENDIF()
+
# Commercial or community
IF (DEB_PRODUCT STREQUAL "commercial")
SET (DEB_COPYRIGHT_UPSTREAMNAME "MySQL Commercial Server ${MYSQL_BASE_VERSION}")
@@ -75,6 +76,7 @@ usr/lib/mysql/plugin/audit_log.so
usr/lib/mysql/plugin/authentication_pam.so
usr/lib/mysql/plugin/authentication_ldap_sasl.so
usr/lib/mysql/plugin/authentication_ldap_simple.so
+usr/lib/mysql/plugin/data_masking.so
usr/lib/mysql/plugin/keyring_okv.so
usr/lib/mysql/plugin/keyring_encrypted_file.so
usr/lib/mysql/plugin/openssl_udf.so
@@ -88,6 +90,7 @@ usr/lib/mysql/plugin/debug/audit_log.so
usr/lib/mysql/plugin/debug/authentication_pam.so
usr/lib/mysql/plugin/debug/authentication_ldap_sasl.so
usr/lib/mysql/plugin/debug/authentication_ldap_simple.so
+usr/lib/mysql/plugin/debug/data_masking.so
usr/lib/mysql/plugin/debug/keyring_okv.so
usr/lib/mysql/plugin/debug/keyring_encrypted_file.so
usr/lib/mysql/plugin/debug/openssl_udf.so
@@ -127,6 +130,46 @@ ELSE()
SET (DEB_REMOVEPATTERN "com.in")
ENDIF()
+# Generate debug symbol packages (this is done automatically in Debian9+)
+SET (DEB_RULES_STRIP_DEFAULT
+"
+override_dh_strip:
+ dh_strip -pmysql-${DEB_PRODUCTNAME}-server --dbg-package=mysql-${DEB_PRODUCTNAME}-server-dbgsym
+ dh_strip -pmysql-${DEB_PRODUCTNAME}-client --dbg-package=mysql-${DEB_PRODUCTNAME}-client-dbgsym
+ dh_strip -pmysql-${DEB_PRODUCTNAME}-test --dbg-package=mysql-${DEB_PRODUCTNAME}-test-dbgsym
+ dh_strip -pmysql-server
+ dh_strip -pmysql-client
+ dh_strip -pmysql-testsuite
+ dh_strip -plibmysqlclient20 --dbg-package=libmysqlclient20-dbgsym
+ dh_strip -plibmysqlclient-dev
+")
+SET (DEB_CONTROL_DBGSYM_DEFAULT
+"
+Package: libmysqlclient20-dbgsym
+Architecture: any
+Section: debug
+Depends: libmysqlclient20 (=\${binary:Version}), \${misc:Depends}
+Description: Debugging symbols for client library
+
+Package: mysql-${DEB_PRODUCTNAME}-test-dbgsym
+Architecture: any
+Section: debug
+Depends: mysql-${DEB_PRODUCTNAME}-test (= \${binary:Version}), \${misc:Depends}
+Description: Debugging symbols for test suite
+
+Package: mysql-${DEB_PRODUCTNAME}-server-dbgsym
+Architecture: any
+Section: debug
+Depends: mysql-${DEB_PRODUCTNAME}-server (= \${binary:Version}), \${misc:Depends}
+Description: Debugging symbols for server
+
+Package: mysql-${DEB_PRODUCTNAME}-client-dbgsym
+Architecture: any
+Section: debug
+Depends: mysql-${DEB_PRODUCTNAME}-client (= \${binary:Version}), \${misc:Depends}
+Description: Debugging symbols for client
+")
+
# Platform specifics. The differences are generally only distro version
# and whether or not systemd and/or apparmor are available
IF (DEB_CODENAME STREQUAL "wheezy")
@@ -142,6 +185,8 @@ IF (DEB_CODENAME STREQUAL "wheezy")
SET (DEB_INSTALL_SERVER_APPARMOR "")
SET (DEB_SERVICE_SERVER_EXECPRE "")
SET (DEB_INIT_APPARMOR "")
+ SET (DEB_CONTROL_DBGSYM ${DEB_CONTROL_DBGSYM_DEFAULT})
+ SET (DEB_RULES_STRIP ${DEB_RULES_STRIP_DEFAULT})
ELSEIF(DEB_CODENAME STREQUAL "jessie")
SET (DEB_PLATFORMRELEASE "debian8")
SET (DEB_CONTROL_BDEPS "dh-systemd")
@@ -157,6 +202,8 @@ ELSEIF(DEB_CODENAME STREQUAL "jessie")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "")
+ SET (DEB_CONTROL_DBGSYM ${DEB_CONTROL_DBGSYM_DEFAULT})
+ SET (DEB_RULES_STRIP ${DEB_RULES_STRIP_DEFAULT})
ELSEIF(DEB_CODENAME STREQUAL "stretch")
SET (DEB_PLATFORMRELEASE "debian9")
SET (DEB_CONTROL_BDEPS "dh-systemd")
@@ -172,6 +219,8 @@ ELSEIF(DEB_CODENAME STREQUAL "stretch")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "")
+ SET (DEB_CONTROL_DBGSYM "")
+ SET (DEB_RULES_STRIP "")
ELSEIF(DEB_CODENAME STREQUAL "sid")
IF (DEFINED DEB_GCC_SNAPSHOT)
SET (DEB_CMAKE_EXTRAS "${DEB_CMAKE_EXTRAS} -DCMAKE_C_COMPILER=/usr/lib/gcc-snapshot/bin/gcc -DCMAKE_CXX_COMPILER=/usr/lib/gcc-snapshot/bin/g++ -DMYSQL_MAINTAINER_MODE=0 -DCMAKE_CXX_COMPILER_LAUNCHER=ccache")
@@ -190,6 +239,8 @@ ELSEIF(DEB_CODENAME STREQUAL "sid")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "")
+ SET (DEB_CONTROL_DBGSYM "")
+ SET (DEB_RULES_STRIP "")
ELSEIF(DEB_CODENAME STREQUAL "trusty")
SET (DEB_PLATFORMRELEASE "ubuntu14.04")
SET (DEB_CONTROL_BDEPS "dh-apparmor")
@@ -205,6 +256,8 @@ ELSEIF(DEB_CODENAME STREQUAL "trusty")
SET (DEB_INSTALL_SERVER_APPARMOR "etc/apparmor.d/usr.sbin.mysqld")
SET (DEB_SERVICE_SERVER_EXECPRE "")
SET (DEB_INIT_APPARMOR "/lib/init/apparmor-profile-load usr.sbin.mysqld")
+ SET (DEB_CONTROL_DBGSYM ${DEB_CONTROL_DBGSYM_DEFAULT})
+ SET (DEB_RULES_STRIP ${DEB_RULES_STRIP_DEFAULT})
ELSEIF(DEB_CODENAME STREQUAL "xenial")
SET (DEB_PLATFORMRELEASE "ubuntu16.04")
SET (DEB_CONTROL_BDEPS "dh-apparmor, dh-systemd (>=1.5)")
@@ -222,6 +275,8 @@ ELSEIF(DEB_CODENAME STREQUAL "xenial")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "/lib/apparmor/profile-load usr.sbin.mysqld")
+ SET (DEB_CONTROL_DBGSYM ${DEB_CONTROL_DBGSYM_DEFAULT})
+ SET (DEB_RULES_STRIP ${DEB_RULES_STRIP_DEFAULT})
ELSEIF(DEB_CODENAME STREQUAL "zesty")
SET (DEB_PLATFORMRELEASE "ubuntu17.04")
SET (DEB_CONTROL_BDEPS "dh-apparmor, dh-systemd (>=1.5)")
@@ -239,6 +294,8 @@ ELSEIF(DEB_CODENAME STREQUAL "zesty")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "/lib/apparmor/profile-load usr.sbin.mysqld")
+ SET (DEB_CONTROL_DBGSYM ${DEB_CONTROL_DBGSYM_DEFAULT})
+ SET (DEB_RULES_STRIP ${DEB_RULES_STRIP_DEFAULT})
ELSEIF(DEB_CODENAME STREQUAL "artful")
SET (DEB_PLATFORMRELEASE "ubuntu17.10")
SET (DEB_CONTROL_BDEPS "dh-apparmor, dh-systemd (>=1.5)")
@@ -256,6 +313,8 @@ ELSEIF(DEB_CODENAME STREQUAL "artful")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "/lib/apparmor/profile-load usr.sbin.mysqld")
+ SET (DEB_CONTROL_DBGSYM ${DEB_CONTROL_DBGSYM_DEFAULT})
+ SET (DEB_RULES_STRIP ${DEB_RULES_STRIP_DEFAULT})
ELSEIF(DEB_CODENAME STREQUAL "bionic")
SET (DEB_PLATFORMRELEASE "ubuntu18.04")
SET (DEB_CONTROL_BDEPS "dh-apparmor, dh-systemd (>=1.5)")
@@ -273,6 +332,27 @@ ELSEIF(DEB_CODENAME STREQUAL "bionic")
SET (DEB_SERVICE_SERVER_EXECPRE
"ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
SET (DEB_INIT_APPARMOR "/lib/apparmor/profile-load usr.sbin.mysqld")
+ SET (DEB_CONTROL_DBGSYM "")
+ SET (DEB_RULES_STRIP "")
+ELSEIF(DEB_CODENAME STREQUAL "cosmic")
+ SET (DEB_PLATFORMRELEASE "ubuntu18.10")
+ SET (DEB_CONTROL_BDEPS "dh-apparmor, dh-systemd (>=1.5)")
+ SET (DEB_INSTALL_SOURCE_XZ "../*.tar.xz usr/src/mysql/")
+ SET (DEB_RULES_INSTALL_SYSTEMD
+ "install -m 0755 debian/extra/mysql-systemd-start debian/tmp/usr/share/mysql/")
+ SET (DEB_RULES_INSTALL_APPARMOR
+ "install -g root -o root -m 0644 -D debian/extra/apparmor-profile debian/tmp/etc/apparmor.d/usr.sbin.mysqld")
+ SET (DEB_RULES_APPARMOR_LOAD
+ "dh_apparmor -pmysql-${DEB_PRODUCTNAME}-server --profile-name=usr.sbin.mysqld")
+ SET (DEB_RULES_SYSTEMD_ENABLE "dh_systemd_enable --name=mysql")
+ SET (DEB_RULES_SYSTEMD_START "dh_systemd_start --restart-after-upgrade")
+ SET (DEB_INSTALL_SERVER_SYSTEMD "usr/share/mysql/mysql-systemd-start")
+ SET (DEB_INSTALL_SERVER_APPARMOR "etc/apparmor.d/usr.sbin.mysqld")
+ SET (DEB_SERVICE_SERVER_EXECPRE
+ "ExecStartPre=/usr/share/mysql/mysql-systemd-start pre")
+ SET (DEB_INIT_APPARMOR "/lib/apparmor/profile-load usr.sbin.mysqld")
+ SET (DEB_CONTROL_DBGSYM "")
+ SET (DEB_RULES_STRIP "")
ELSE()
MESSAGE(STATUS
"Skipping deb packaging on unsupported platform ${DEB_CODENAME}.")
diff --git a/packaging/deb-in/control.in b/packaging/deb-in/control.in
index 59f95fabb021..517a5e614880 100644
--- a/packaging/deb-in/control.in
+++ b/packaging/deb-in/control.in
@@ -227,4 +227,5 @@ Description: MySQL source
as for embedding into mass-deployed software. MySQL is a trademark of
Oracle.
+@DEB_CONTROL_DBGSYM@
@DEB_NDB_CONTROL_EXTRAS@
diff --git a/packaging/deb-in/libmysqlclient20-dbgsym.install.in b/packaging/deb-in/libmysqlclient20-dbgsym.install.in
new file mode 100644
index 000000000000..424809484a52
--- /dev/null
+++ b/packaging/deb-in/libmysqlclient20-dbgsym.install.in
@@ -0,0 +1,18 @@
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# 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
+
+# legal
+usr/share/mysql/@DEB_INSTALL_LICENSEFILE@ usr/share/doc/libmysqlclient20-dbgsym/
+usr/share/mysql/README usr/share/doc/libmysqlclient20-dbgsym/
diff --git a/packaging/deb-in/mysql-packagesource-client-dbgsym.install.in b/packaging/deb-in/mysql-packagesource-client-dbgsym.install.in
new file mode 100644
index 000000000000..a7b21a6573e5
--- /dev/null
+++ b/packaging/deb-in/mysql-packagesource-client-dbgsym.install.in
@@ -0,0 +1,19 @@
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# 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
+
+# legal
+usr/share/mysql/@DEB_INSTALL_LICENSEFILE@ usr/share/doc/mysql-@DEB_PRODUCTNAME@-client-dbgsym/
+usr/share/mysql/README usr/share/doc/mysql-@DEB_PRODUCTNAME@-client-dbgsym/
+
diff --git a/packaging/deb-in/mysql-packagesource-server-dbgsym.install.in b/packaging/deb-in/mysql-packagesource-server-dbgsym.install.in
new file mode 100644
index 000000000000..f356c17fccf2
--- /dev/null
+++ b/packaging/deb-in/mysql-packagesource-server-dbgsym.install.in
@@ -0,0 +1,18 @@
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# 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
+
+# legal
+usr/share/mysql/@DEB_INSTALL_LICENSEFILE@ usr/share/doc/mysql-@DEB_PRODUCTNAME@-server-dbgsym/
+usr/share/mysql/README usr/share/doc/mysql-@DEB_PRODUCTNAME@-server-dbgsym/
diff --git a/packaging/deb-in/mysql-packagesource-test-dbgsym.install.in b/packaging/deb-in/mysql-packagesource-test-dbgsym.install.in
new file mode 100644
index 000000000000..c1fb527015f4
--- /dev/null
+++ b/packaging/deb-in/mysql-packagesource-test-dbgsym.install.in
@@ -0,0 +1,18 @@
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# 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
+
+# legal
+usr/share/mysql/@DEB_INSTALL_LICENSEFILE@ usr/share/doc/mysql-@DEB_PRODUCTNAME@-test-dbgsym/
+usr/share/mysql/README usr/share/doc/mysql-@DEB_PRODUCTNAME@-test-dbgsym/
diff --git a/packaging/deb-in/rules.in b/packaging/deb-in/rules.in
index 32ef7211b264..a4e416e7d59e 100644
--- a/packaging/deb-in/rules.in
+++ b/packaging/deb-in/rules.in
@@ -69,6 +69,8 @@ override_dh_auto_test:
make test || true
touch $@
+@DEB_RULES_STRIP@
+
override_dh_auto_install:
@echo "RULES.$@"
diff --git a/packaging/rpm-docker/mysql.spec.in b/packaging/rpm-docker/mysql.spec.in
index 6ab1117111a0..13731bf9739b 100644
--- a/packaging/rpm-docker/mysql.spec.in
+++ b/packaging/rpm-docker/mysql.spec.in
@@ -324,6 +324,7 @@ rm -r $(readlink var) var
%attr(755, root, root) %{_libdir}/mysql/plugin/audit_log.so
%attr(644, root, root) %{_datadir}/mysql/audit_log_filter_linux_install.sql
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_pam.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/data_masking.so
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_encrypted_file.so
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_okv.so
%attr(755, root, root) %{_libdir}/mysql/plugin/thread_pool.so
diff --git a/packaging/rpm-fedora/mysql.spec.in b/packaging/rpm-fedora/mysql.spec.in
index d0621571cf1a..68050eae6420 100644
--- a/packaging/rpm-fedora/mysql.spec.in
+++ b/packaging/rpm-fedora/mysql.spec.in
@@ -105,6 +105,11 @@ BuildRequires: perl(Time::localtime)
%if 0%{?fedora} > 24
BuildRequires: perl-generators
%endif
+%if 0%{?fedora} > 28
+BuildRequires: compat-openssl10-devel
+%else
+BuildRequires: openssl-devel
+%endif
BuildRequires: time
BuildRequires: cyrus-sasl-devel
BuildRequires: libaio-devel
@@ -113,7 +118,6 @@ BuildRequires: multilib-rpm-config
BuildRequires: ncurses-devel
BuildRequires: numactl-devel
BuildRequires: openldap-devel
-BuildRequires: openssl-devel
BuildRequires: zlib-devel
BuildRequires: systemd
BuildRequires: pkgconfig(systemd)
@@ -163,6 +167,7 @@ Obsoletes: community-mysql-bench
Obsoletes: mysql-bench
Obsoletes: mariadb-backup
Obsoletes: mariadb-bench
+Obsoletes: mariadb-connector-c-config
Obsoletes: mariadb-cracklib-password-check
Obsoletes: mariadb-gssapi-server
Obsoletes: mariadb-rocksdb-engine
diff --git a/packaging/rpm-oel/mysql.init b/packaging/rpm-oel/mysql.init
index 9e037883cce8..23d110506327 100644
--- a/packaging/rpm-oel/mysql.init
+++ b/packaging/rpm-oel/mysql.init
@@ -175,7 +175,7 @@ stop(){
fi
MYSQLPID=$(cat "$mypidfile")
if [ -n "$MYSQLPID" ]; then
- /bin/kill "$MYSQLPID" >/dev/null 2>&1
+ /bin/su - mysql -s /bin/bash -c "/bin/kill $MYSQLPID" >/dev/null 2>&1
ret=$?
if [ $ret -eq 0 ]; then
TIMEOUT="$STOPTIMEOUT"
diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in
index 534c73c7c2f4..79b4e5a55b9d 100644
--- a/packaging/rpm-oel/mysql.spec.in
+++ b/packaging/rpm-oel/mysql.spec.in
@@ -1061,6 +1061,7 @@ fi
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_pam.so
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_sasl.so
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_simple.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/data_masking.so
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_okv.so
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_encrypted_file.so
%attr(755, root, root) %{_libdir}/mysql/plugin/thread_pool.so
@@ -1071,6 +1072,7 @@ fi
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_pam.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_sasl.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_simple.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/data_masking.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_okv.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_encrypted_file.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/thread_pool.so
diff --git a/packaging/rpm-sles/mysql.init b/packaging/rpm-sles/mysql.init
index 8f3f793597e7..a8b33894797b 100644
--- a/packaging/rpm-sles/mysql.init
+++ b/packaging/rpm-sles/mysql.init
@@ -199,7 +199,7 @@ stop () {
# We use a signal to avoid having to know the root password
# Send single kill command and then wait
- if kill $pid >/dev/null 2>&1; then
+ if su - mysql -s /bin/bash -c "kill $pid" >/dev/null 2>&1; then
timer=$STOPTIMEOUT
while [ $timer -gt 0 ]; do
kill -0 $pid >/dev/null 2>&1 || break
@@ -232,7 +232,7 @@ reload () {
ret=0
if chk_running && mysqladmin --no-defaults --socket="$socket" ping >/dev/null 2>&1 ; then
pid=$(cat "$pidfile")
- kill -HUP $pid >/dev/null 2>&1
+ su - mysql -s /bin/bash -c "kill -HUP $pid" >/dev/null 2>&1
echo -n "Reloading service MySQL:"
rc_reset
else
diff --git a/packaging/rpm-sles/mysql.spec.in b/packaging/rpm-sles/mysql.spec.in
index eba1ab5793e7..56505dcd42d6 100644
--- a/packaging/rpm-sles/mysql.spec.in
+++ b/packaging/rpm-sles/mysql.spec.in
@@ -862,6 +862,7 @@ fi
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_pam.so
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_sasl.so
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_simple.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/data_masking.so
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_okv.so
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_encrypted_file.so
%attr(755, root, root) %{_libdir}/mysql/plugin/thread_pool.so
@@ -872,6 +873,7 @@ fi
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_pam.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_sasl.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_simple.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/data_masking.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_okv.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_encrypted_file.so
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/thread_pool.so
diff --git a/plugin/semisync/semisync_master_ack_receiver.cc b/plugin/semisync/semisync_master_ack_receiver.cc
index 9cce7317da91..2233f5b2b257 100644
--- a/plugin/semisync/semisync_master_ack_receiver.cc
+++ b/plugin/semisync/semisync_master_ack_receiver.cc
@@ -128,7 +128,9 @@ bool Ack_receiver::add_slave(THD *thd)
const char *kWho = "Ack_receiver::add_slave";
function_enter(kWho);
- slave.thd= thd;
+ slave.thread_id= thd->thread_id();
+ slave.server_id= thd->server_id;
+ slave.net_compress= thd->get_protocol_classic()->get_compression();
slave.vio= *thd->get_protocol_classic()->get_vio();
slave.vio.mysql_socket.m_psi= NULL;
slave.vio.read_timeout= 1;
@@ -163,7 +165,7 @@ void Ack_receiver::remove_slave(THD *thd)
for (it= m_slaves.begin(); it != m_slaves.end(); it++)
{
- if (it->thd == thd)
+ if (it->thread_id == thd->thread_id())
{
m_slaves.erase(it);
m_slaves_changed= true;
@@ -202,11 +204,7 @@ void Ack_receiver::run()
NET net;
unsigned char net_buff[REPLY_MESSAGE_MAX_LENGTH];
uint i;
-#ifdef HAVE_POLL
- Poll_socket_listener listener(m_slaves);
-#else
- Select_socket_listener listener(m_slaves);
-#endif //HAVE_POLL
+ Socket_listener listener;
sql_print_information("Starting ack receiver thread");
@@ -234,14 +232,14 @@ void Ack_receiver::run()
mysql_mutex_unlock(&m_mutex);
continue;
}
- if (!listener.init_slave_sockets())
+ if (!listener.init_slave_sockets(m_slaves))
goto end;
m_slaves_changed= false;
}
+ mysql_mutex_unlock(&m_mutex);
ret= listener.listen_on_sockets();
if (ret <= 0)
{
- mysql_mutex_unlock(&m_mutex);
ret= DBUG_EVALUATE_IF("rpl_semisync_simulate_select_error", -1, ret);
@@ -255,33 +253,32 @@ void Ack_receiver::run()
set_stage_info(stage_reading_semi_sync_ack);
i= 0;
- while (i < m_slaves.size())
+ while (i < listener.number_of_slave_sockets() && m_status == ST_UP)
{
if (listener.is_socket_active(i))
{
+ Slave slave_obj= listener.get_slave_obj(i);
ulong len;
- net.vio= &m_slaves[i].vio;
+ net.vio= &slave_obj.vio;
/*
Set compress flag. This is needed to support
Slave_compress_protocol flag enabled Slaves
*/
- net.compress=
- m_slaves[i].thd->get_protocol_classic()->get_compression();
+ net.compress= slave_obj.net_compress;
do {
net_clear(&net, 0);
len= my_net_read(&net);
if (likely(len != packet_error))
- repl_semisync.reportReplyPacket(m_slaves[i].server_id(),
+ repl_semisync.reportReplyPacket(slave_obj.server_id,
net.read_pos, len);
else if (net.last_errno == ER_NET_READ_ERROR)
listener.clear_socket_info(i);
- } while (net.vio->has_data(net.vio));
+ } while (net.vio->has_data(net.vio) && m_status == ST_UP);
}
i++;
}
- mysql_mutex_unlock(&m_mutex);
}
end:
sql_print_information("Stopping ack receiver thread");
diff --git a/plugin/semisync/semisync_master_ack_receiver.h b/plugin/semisync/semisync_master_ack_receiver.h
index 925becdf152e..c191336b8882 100644
--- a/plugin/semisync/semisync_master_ack_receiver.h
+++ b/plugin/semisync/semisync_master_ack_receiver.h
@@ -23,11 +23,12 @@
struct Slave
{
- THD *thd;
+ uint32_t thread_id;
Vio vio;
+ uint server_id;
+ bool net_compress;
my_socket sock_fd() const { return vio.mysql_socket.fd; }
- uint server_id() const { return thd->server_id; }
};
typedef std::vector Slave_vector;
diff --git a/plugin/semisync/semisync_master_socket_listener.h b/plugin/semisync/semisync_master_socket_listener.h
index b021edf926f4..9853b093d368 100644
--- a/plugin/semisync/semisync_master_socket_listener.h
+++ b/plugin/semisync/semisync_master_socket_listener.h
@@ -24,8 +24,7 @@
class Poll_socket_listener
{
public:
- Poll_socket_listener(const Slave_vector &slaves)
- :m_slaves(slaves)
+ Poll_socket_listener()
{
}
@@ -45,8 +44,9 @@ class Poll_socket_listener
m_fds[index].events= 0;
}
- bool init_slave_sockets()
+ bool init_slave_sockets(Slave_vector slaves)
{
+ m_slaves= slaves;
m_fds.clear();
for (uint i= 0; i < m_slaves.size(); i++)
{
@@ -57,19 +57,29 @@ class Poll_socket_listener
}
return true;
}
+ uint number_of_slave_sockets()
+ {
+ return m_slaves.size();
+ }
+
+ Slave get_slave_obj(int index)
+ {
+ return m_slaves[index];
+ }
private:
- const Slave_vector &m_slaves;
+ Slave_vector m_slaves;
std::vector m_fds;
};
+typedef class Poll_socket_listener Socket_listener;
#else //NO POLL
class Select_socket_listener
{
public:
- Select_socket_listener(const Slave_vector &slaves)
- :m_slaves(slaves), m_max_fd(INVALID_SOCKET)
+ Select_socket_listener()
+ :m_max_fd(INVALID_SOCKET)
{
}
@@ -92,8 +102,9 @@ class Select_socket_listener
FD_CLR(m_slaves[index].sock_fd(), &m_init_fds);
}
- bool init_slave_sockets()
+ bool init_slave_sockets(Slave_vector slaves)
{
+ m_slaves= slaves;
FD_ZERO(&m_init_fds);
for (uint i= 0; i < m_slaves.size(); i++)
{
@@ -112,13 +123,23 @@ class Select_socket_listener
}
return true;
}
+ uint number_of_slave_sockets()
+ {
+ return m_slaves.size();
+ }
+
+ Slave get_slave_obj(int index)
+ {
+ return m_slaves[index];
+ }
private:
- const Slave_vector &m_slaves;
+ Slave_vector m_slaves;
my_socket m_max_fd;
fd_set m_init_fds;
fd_set m_fds;
};
+typedef class Select_socket_listener Socket_listener;
#endif //HAVE_POLL
#endif //SEMISYNC_MASTER_SOCKET_LISTENER
diff --git a/rapid/plugin/group_replication/include/gcs_view_modification_notifier.h b/rapid/plugin/group_replication/include/gcs_view_modification_notifier.h
index b28fd6fc0d9b..9529b01bf5b0 100644
--- a/rapid/plugin/group_replication/include/gcs_view_modification_notifier.h
+++ b/rapid/plugin/group_replication/include/gcs_view_modification_notifier.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -52,6 +52,15 @@ class Plugin_gcs_view_modification_notifier
*/
bool is_injected_view_modification();
+ /**
+ Checks if there is a view modification ongoing.
+
+ @return
+ @retval true there is a view modification ongoing
+ @retval false otherwise
+ */
+ bool is_view_modification_ongoing();
+
/**
Signals that a view modification has ended
*/
diff --git a/rapid/plugin/group_replication/include/plugin.h b/rapid/plugin/group_replication/include/plugin.h
index 15f894a4f767..e8b2b155a8ed 100644
--- a/rapid/plugin/group_replication/include/plugin.h
+++ b/rapid/plugin/group_replication/include/plugin.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -46,6 +46,20 @@ struct st_mysql_sys_var
};
typedef st_mysql_sys_var SYS_VAR;
+/**
+ An enum that represents the possible values of the
+ group_replication_exit_state_action sysvar.
+*/
+enum enum_exit_state_action {
+ /**
+ When configured to READ_ONLY, the server will go into super_read_only mode
+ and enter the ERROR GR state.
+ */
+ EXIT_STATE_ACTION_READ_ONLY = 0,
+ /** When configured to ABORT_SERVER, the server will abort(). */
+ EXIT_STATE_ACTION_ABORT_SERVER
+};
+
//Plugin variables
extern const char *group_replication_plugin_name;
extern char *group_name_var;
@@ -57,6 +71,7 @@ extern const char *available_bindings_names[];
extern bool known_server_reset;
//Certification latch
extern Wait_ticket *certification_latch;
+extern ulong exit_state_action_var;
//The modules
extern Gcs_operations *gcs_module;
diff --git a/rapid/plugin/group_replication/include/plugin_utils.h b/rapid/plugin/group_replication/include/plugin_utils.h
index a4c1af7ffa36..5cffe92ea01d 100644
--- a/rapid/plugin/group_replication/include/plugin_utils.h
+++ b/rapid/plugin/group_replication/include/plugin_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -26,6 +26,8 @@
void log_primary_member_details();
+void abort_plugin_process(const char *message);
+
class Blocked_transaction_handler
{
public:
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc
index bce439240108..698aeac9c034 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc
@@ -154,6 +154,8 @@ Gcs_xcom_control(Gcs_xcom_group_member_information *group_member_information,
m_join_attempts(0),
m_join_sleep_time(0),
m_xcom_running(false),
+ m_leave_view_requested(false),
+ m_leave_view_delivered(false),
m_boot(boot),
m_initial_peers(),
m_view_control(view_control),
@@ -464,8 +466,17 @@ enum_gcs_error Gcs_xcom_control::retry_do_join()
xcom_port port= 0;
char *addr= NULL;
std::vector::iterator it;
- std::string *local_node_info_str=
- m_local_node_info->get_member_representation();
+ std::string local_node_info_str_ip;
+ bool resolve_error = false;
+ resolve_error = resolve_ip_addr_from_hostname(
+ m_local_node_info->get_member_ip(), local_node_info_str_ip);
+
+ if (resolve_error)
+ {
+ MYSQL_GCS_LOG_ERROR("Error resolving local address name: "
+ << m_local_node_info->get_member_ip().c_str())
+ goto err;
+ }
while(con == NULL && n < Gcs_xcom_proxy::connection_attempts)
{
@@ -474,18 +485,27 @@ enum_gcs_error Gcs_xcom_control::retry_do_join()
it++)
{
Gcs_xcom_group_member_information *peer= *(it);
- std::string *peer_rep= peer->get_member_representation();
+ std::string peer_rep_ip;
+
+ resolve_error =
+ resolve_ip_addr_from_hostname(peer->get_member_ip(), peer_rep_ip);
+ if (resolve_error)
+ {
+ MYSQL_GCS_LOG_WARN("Unable to resolve peer address "
+ << peer->get_member_ip().c_str()
+ << ". Skipping...")
+ continue;
+ }
- if(peer_rep->compare(*local_node_info_str) == 0)
+ if (peer_rep_ip.compare(local_node_info_str_ip) == 0 &&
+ peer->get_member_port() == m_local_node_info->get_member_port())
{
MYSQL_GCS_LOG_TRACE(
"::join():: Skipping own address."
)
// Skip own address if configured in the peer list
- delete peer_rep;
continue;
}
- delete peer_rep;
port= peer->get_member_port();
addr= (char *)peer->get_member_ip().c_str();
@@ -506,10 +526,6 @@ enum_gcs_error Gcs_xcom_control::retry_do_join()
n++;
}
- // Not needed anymore since it was only used in the loop
- // above. As such, claim back memory.
- delete local_node_info_str;
-
if (con != NULL)
{
if(m_socket_util->disable_nagle_in_socket(con->fd) < 0)
@@ -670,6 +686,9 @@ enum_gcs_error Gcs_xcom_control::do_leave()
return GCS_NOK;
}
+ m_leave_view_delivered = false;
+ m_leave_view_requested = true;
+
m_xcom_proxy->xcom_client_remove_node(&m_node_list_me, m_gid_hash);
/*
@@ -723,43 +742,7 @@ enum_gcs_error Gcs_xcom_control::do_leave()
m_view_control->end_leave();
- /*
- There is no need to synchronize here and this method can access
- the current_view member stored in the view controller directly.
- */
- Gcs_view *current_view= m_view_control->get_unsafe_current_view();
-
- if(current_view == NULL)
- {
- /*
- XCOM has stopped but will not proceed with any view install. The
- current view might be NULL due to the fact that the view with
- the join still hasn't been delivered.
- */
- MYSQL_GCS_LOG_WARN("The member has left the group but the new view" <<
- " will not be installed, probably because it has not" <<
- " been delivered yet.")
- /*
- If the node leaves and joins within a 5 second window, it may not
- get a global view. See BUG#23718481.
- */
- My_xp_util::sleep_seconds(5);
-
- return GCS_OK;
- }
-
- /*
- Notify that the node has left the group because someone has
- requested to do so.
- */
- install_leave_view(Gcs_view::OK);
-
- /*
- Set that the node does not belong to a group anymore. Note there
- is a small window when the node does not belong to the group
- anymore but the view is not NULL.
- */
- m_view_control->set_belongs_to_group(false);
+ do_leave_view();
/*
Delete current view and set it to NULL.
@@ -775,6 +758,30 @@ enum_gcs_error Gcs_xcom_control::do_leave()
return GCS_OK;
}
+void Gcs_xcom_control::do_leave_view() {
+ /*
+ There is no need to synchronize here and this method can access
+ the current_view member stored in the view controller directly.
+ */
+ Gcs_view *current_view = m_view_control->get_unsafe_current_view();
+
+ if (current_view != NULL && !m_leave_view_delivered) {
+ MYSQL_GCS_LOG_DEBUG("Will install leave view: requested " <<
+ m_leave_view_requested << ", delivered " <<
+ m_leave_view_delivered);
+ install_leave_view(m_leave_view_requested ? Gcs_view::OK
+ : Gcs_view::MEMBER_EXPELLED);
+ if (m_leave_view_requested) {
+ m_view_control->set_belongs_to_group(false);
+ }
+
+ m_leave_view_delivered = m_leave_view_requested;
+
+ MYSQL_GCS_LOG_DEBUG("Installed leave view: requested " <<
+ m_leave_view_requested << ", delivered " <<
+ m_leave_view_delivered);
+ }
+}
bool Gcs_xcom_control::belongs_to_group()
{
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.h b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.h
index 451cadabd560..3092522069a0 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.h
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.h
@@ -121,6 +121,12 @@ class Gcs_xcom_control: public Gcs_control_interface
*/
enum_gcs_error do_leave();
+ /**
+ Sends a leave view message to inform that XCOM has already exited or
+ is about to do so.
+ */
+ void do_leave_view();
+
bool belongs_to_group();
Gcs_view *get_current_view();
@@ -368,6 +374,17 @@ class Gcs_xcom_control: public Gcs_control_interface
*/
bool m_xcom_running;
+ /*
+ Whether it was requested to make the node leave the group or not.
+ */
+ bool m_leave_view_requested;
+
+ /*
+ Whether a view saying that the node has voluntarily left the group
+ was delivered or not.
+ */
+ bool m_leave_view_delivered;
+
/* Whether this site boots the group or not. */
bool m_boot;
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.cc b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.cc
index 99422b12c53a..0490906d3553 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.cc
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.cc
@@ -81,6 +81,8 @@ void do_cb_xcom_receive_global_view(synode_no config_id,
void cb_xcom_comms(int status);
void cb_xcom_ready(int status);
void cb_xcom_exit(int status);
+void cb_xcom_expel(int status);
+
synode_no cb_xcom_get_app_snap(blob *gcs_snap);
void cb_xcom_handle_app_snap(blob *gcs_snap);
int cb_xcom_socket_accept(int fd, site_def const *xcom_config);
@@ -466,6 +468,23 @@ void Gcs_xcom_interface::finalize_xcom()
}
}
+void Gcs_xcom_interface::make_gcs_leave_group_on_error()
+{
+ Gcs_group_identifier *group_identifier = NULL;
+ map::iterator xcom_configured_groups_it;
+ Gcs_xcom_interface *intf =
+ static_cast(Gcs_xcom_interface::get_interface());
+
+ for (xcom_configured_groups_it = m_xcom_configured_groups.begin();
+ xcom_configured_groups_it != m_xcom_configured_groups.end();
+ xcom_configured_groups_it++)
+ {
+ group_identifier = (*xcom_configured_groups_it).second;
+ Gcs_xcom_control *control_if = static_cast(
+ intf->get_control_session(*group_identifier));
+ control_if->do_leave_view();
+ }
+}
enum_gcs_error Gcs_xcom_interface::finalize()
{
@@ -787,6 +806,7 @@ initialize_xcom(const Gcs_interface_parameters &interface_params)
::set_xcom_run_cb(cb_xcom_ready);
::set_xcom_comms_cb(cb_xcom_comms);
::set_xcom_exit_cb(cb_xcom_exit);
+ ::set_xcom_expel_cb(cb_xcom_expel);
::set_xcom_socket_accept_cb(cb_xcom_socket_accept);
const std::string *wait_time_str=
@@ -1470,6 +1490,31 @@ void cb_xcom_exit(int status MY_ATTRIBUTE((unused)))
xcom_proxy->xcom_signal_exit();
}
+void do_cb_xcom_expel() {
+ Gcs_xcom_interface *intf =
+ static_cast(Gcs_xcom_interface::get_interface());
+ if (intf) {
+ intf->make_gcs_leave_group_on_error();
+ }
+}
+
+/*
+ Callback function used by XCom to signal that a node has left the group
+ because of a `die_op` or a view where the node does not belong to.
+*/
+void cb_xcom_expel(int status MY_ATTRIBUTE((unused))) {
+ Gcs_xcom_notification *notification =
+ new Expel_notification(do_cb_xcom_expel);
+
+ bool scheduled = gcs_engine->push(notification);
+ if (!scheduled) {
+ MYSQL_GCS_LOG_DEBUG(
+ "Tried to enqueue an expel request but the member is about to stop.")
+ delete notification;
+ } else {
+ MYSQL_GCS_LOG_TRACE("Expel view notification: " << notification)
+ }
+}
void cb_xcom_logger(int level, const char *message)
{
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.h b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.h
index 3c3831727aa8..b962979338d9 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.h
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -165,6 +165,11 @@ class Gcs_xcom_interface: public Gcs_interface
void finalize_xcom();
+ /**
+ Triggers the termination of GCS when an error has caused XCom to terminate
+ unexpectedly.
+ */
+ void make_gcs_leave_group_on_error();
/**
Used to initialize SSL assuming that the necessary parameters have already
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc
index 2971f8d76531..d322287f79e0 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -129,6 +129,16 @@ void Local_view_notification::do_execute()
}
+Expel_notification::Expel_notification(xcom_expel_functor *functor)
+ : m_functor(functor) {}
+
+
+Expel_notification::~Expel_notification() {}
+
+
+void Expel_notification::do_execute() { (*m_functor)(); }
+
+
Control_notification::Control_notification(xcom_control_functor* functor,
Gcs_control_interface *control_if)
: m_functor(functor), m_control_if(control_if) { }
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.h b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.h
index 709a1acb120d..eafe691caeaa 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.h
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_notification.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -645,4 +645,44 @@ class Control_notification : public Parameterized_notification
Control_notification(Control_notification const&);
Control_notification& operator=(Control_notification const&);
};
+
+typedef void(xcom_expel_functor)(void);
+
+/**
+ Notification used to inform that the node has been expelled or is about
+ to be.
+*/
+class Expel_notification : public Parameterized_notification {
+ public:
+ /**
+ Constructor for Expel_notification.
+ @param functor Pointer to a function that contains that actual core of
+ the execution.
+ */
+ explicit Expel_notification(xcom_expel_functor *functor);
+
+ /**
+ Destructor for Expel_notification.
+ */
+ ~Expel_notification();
+
+ private:
+ /**
+ Task implemented by this notification.
+ */
+ void do_execute();
+
+ /*
+ Pointer to a function that contains that actual core of the execution.
+ */
+ xcom_expel_functor *m_functor;
+
+ /*
+ Disabling the copy constructor and assignment operator.
+ */
+ Expel_notification(Expel_notification const &);
+ Expel_notification &operator=(Expel_notification const &);
+
+};
+
#endif // GCS_XCOM_NOTIFICATION_INCLUDED
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.cc b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.cc
index fa4c99f8d290..955111345261 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.cc
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.cc
@@ -620,7 +620,7 @@ process_member_state(Xcom_member_state *ms_info,
return false;
}
- m_member_states[p_id]= ms_info;
+ save_member_state(ms_info, p_id);
/*
The rule of updating the awaited_vector at receiving is simply to
@@ -649,6 +649,17 @@ fill_member_set(std::vector &in,
std::copy(in.begin(), in.end(), std::inserter(pset, pset.begin()));
}
+void Gcs_xcom_state_exchange::save_member_state(
+ Xcom_member_state *ms_info, const Gcs_member_identifier &p_id) {
+ /* m_member_states[p_id] may already exist. In that case we delete the
+ * existing pointer, otherwise it leaks. */
+ std::map::iterator
+ member_state_it = m_member_states.find(p_id);
+ bool const state_already_exists = (member_state_it != m_member_states.end());
+ if (state_already_exists) delete member_state_it->second;
+ m_member_states[p_id] = ms_info;
+}
+
Gcs_xcom_view_identifier *
Gcs_xcom_state_exchange::get_new_view_id()
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.h b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.h
index fcebe3f106de..30a6d19b91f4 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.h
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_state_exchange.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -506,6 +506,16 @@ class Gcs_xcom_state_exchange: public Gcs_xcom_state_exchange_interface
void fill_member_set(std::vector &in,
std::set &pset);
+ /**
+ * Stores the member's state and protocol version.
+ *
+ * @param ms_info state
+ * @param p_id member
+ * @param protocol_version protocol version
+ */
+ void save_member_state(Xcom_member_state *ms_info,
+ const Gcs_member_identifier &p_id);
+
Gcs_communication_interface *m_broadcaster;
std::map m_awaited_vector;
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.c b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.c
index 31f3b4b2ce40..39b0a7190e0d 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.c
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -33,8 +33,7 @@
#include "node_list.h"
#include "xcom_vp_str.h"
-define_xdr_funcs(synode_no)
-define_xdr_funcs(app_data_ptr)
+clone_xdr_array(synode_no)
static app_data_list nextp(app_data_list l);
static unsigned long msg_count(app_data_ptr a);
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/site_def.c b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/site_def.c
index a3aedf02b36a..ca8edc295cc5 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/site_def.c
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/site_def.c
@@ -45,7 +45,9 @@ struct site_def_ptr_array {
};
typedef struct site_def_ptr_array site_def_ptr_array;
-define_xdr_funcs(site_def_ptr)
+init_xdr_array(site_def_ptr)
+free_xdr_array(site_def_ptr)
+set_xdr_array(site_def_ptr)
/* FIFO of site definitions */
static site_def_ptr_array site_defs;
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/synode_no.c b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/synode_no.c
index 786b798843b0..9110034715a1 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/synode_no.c
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/synode_no.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -60,8 +60,6 @@ int synode_gt(synode_no x, synode_no y)
}
/* purecov: begin deadcode */
-define_xdr_funcs(synode_no)
-
synode_no vp_count_to_synode(u_long high, u_long low, node_no nodeid,
uint32_t groupid)
{
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c
index 2fceb74e8188..6d19b8f9a617 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c
@@ -87,8 +87,14 @@ typedef struct {
task_env_p *task_env_p_array_val;
} task_env_p_array;
-define_xdr_funcs(pollfd)
-define_xdr_funcs(task_env_p)
+init_xdr_array(pollfd)
+free_xdr_array(pollfd)
+set_xdr_array(pollfd)
+get_xdr_array(pollfd)
+init_xdr_array(task_env_p)
+free_xdr_array(task_env_p)
+set_xdr_array(task_env_p)
+get_xdr_array(task_env_p)
struct iotasks {
int nwait;
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c
index 11211acabc29..a05b9f38508e 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c
@@ -506,9 +506,6 @@ static bool_t is_dead_site(uint32_t id)
return FALSE;
}
-define_xdr_funcs(node_no)
-
-
extern node_set *init_node_set(node_set *set, u_int n);
extern node_set *alloc_node_set(node_set *set, u_int n);
@@ -1067,6 +1064,7 @@ static xcom_state_change_cb xcom_run_cb = 0;
static xcom_state_change_cb xcom_terminate_cb = 0;
static xcom_state_change_cb xcom_comms_cb = 0;
static xcom_state_change_cb xcom_exit_cb = 0;
+static xcom_state_change_cb xcom_expel_cb = 0;
void set_xcom_run_cb(xcom_state_change_cb x)
{
@@ -1088,6 +1086,11 @@ void set_xcom_exit_cb(xcom_state_change_cb x)
xcom_exit_cb = x;
}
+void set_xcom_expel_cb(xcom_state_change_cb x)
+{
+ xcom_expel_cb = x;
+}
+
int xcom_taskmain2(xcom_port listen_port)
{
init_xcom_transport(listen_port);
@@ -2224,6 +2227,7 @@ static void terminate_and_exit()
{
XCOM_FSM(xa_terminate, int_arg(0)); /* Tell xcom to stop */
XCOM_FSM(xa_exit, int_arg(0)); /* Tell xcom to exit */
+ if (xcom_expel_cb) xcom_expel_cb(0);
}
int terminator_task(task_arg arg)
@@ -3877,10 +3881,11 @@ pax_msg *dispatch_op(site_def const *site, pax_msg *p, linkage *reply_queue)
vector), but I am not convinced that it is worth the effort.
*/
if(!synode_lt(p->synode, executed_msg)){
- g_critical("Node %u unable to get message, process will now exit. Please ensure that the process is restarted",
- get_nodeno(site));
- exit(1);
- }
+ g_critical("Node %u unable to get messages, since the "
+ "group is too far ahead. Node will now exit.",
+ get_nodeno(site));
+ terminate_and_exit();
+ }
default:
break;
}
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.h b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.h
index 7caf80f56744..3341b340113b 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.h
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.h
@@ -186,6 +186,7 @@ typedef void (*xcom_state_change_cb)(int status);
void set_xcom_run_cb(xcom_state_change_cb x);
void set_xcom_terminate_cb(xcom_state_change_cb x);
void set_xcom_exit_cb(xcom_state_change_cb x);
+void set_xcom_expel_cb(xcom_state_change_cb x);
app_data_ptr init_config_with_group(app_data *a, node_list *nl, cargo_type type,
uint32_t group_id);
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_recover.c b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_recover.c
index 620c1f61ca87..e58bc029bdc1 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_recover.c
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_recover.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -45,9 +45,6 @@ int client_boot_done = 0;
int netboot_ok = 0;
int booting = 0;
-define_xdr_funcs(synode_no)
-define_xdr_funcs(app_data_ptr)
-
/* purecov: begin deadcode */
void init_recover_vars()
{
diff --git a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xdr_utils.h b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xdr_utils.h
index 7f2d09d52dc8..2f18bb4e56e6 100644
--- a/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xdr_utils.h
+++ b/rapid/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xdr_utils.h
@@ -25,9 +25,7 @@ extern "C" {
/**
Initialize an array
*/
-#define def_init_xdr_array(name) \
- MY_ATTRIBUTE((unused)) \
- static inline void init_##name##_array(name##_array *x)
+#define def_init_xdr_array(name) static inline void init_##name##_array(name##_array *x)
#define init_xdr_array(name) \
def_init_xdr_array(name) { \
x->name##_array_len = 2; \
@@ -37,9 +35,7 @@ extern "C" {
/**
Free the contents of an array
*/
-#define def_free_xdr_array(name) \
- MY_ATTRIBUTE((unused)) \
- static inline void free_##name##_array(name##_array *x)
+#define def_free_xdr_array(name) static inline void free_##name##_array(name##_array *x)
#define free_xdr_array(name)\
def_free_xdr_array(name)\
{\
@@ -66,7 +62,6 @@ def_free_xdr_array(name)\
Define a set function for an array
*/
#define def_set_xdr_array(name) \
- MY_ATTRIBUTE((unused)) \
static inline void set_##name(name##_array *x, name a, u_int n)
#define set_xdr_array(name) \
def_set_xdr_array(name) { \
@@ -78,9 +73,7 @@ def_free_xdr_array(name)\
/**
Define a get function for an array
*/
-#define def_get_xdr_array(name) \
- MY_ATTRIBUTE((unused)) \
- static inline name get_##name(name##_array *x, u_int n)
+#define def_get_xdr_array(name) static inline name get_##name(name##_array *x, u_int n)
#define get_xdr_array(name) \
def_get_xdr_array(name) \
{ \
@@ -94,7 +87,6 @@ def_free_xdr_array(name)\
Define a function to clone an array
*/
#define def_clone_xdr_array(name) \
- MY_ATTRIBUTE((unused)) \
static inline name##_array clone_##name##_array(name##_array x)
#define clone_xdr_array(name) \
def_clone_xdr_array(name) { \
diff --git a/rapid/plugin/group_replication/src/applier.cc b/rapid/plugin/group_replication/src/applier.cc
index 79090c2006e7..2da0ba630ed0 100644
--- a/rapid/plugin/group_replication/src/applier.cc
+++ b/rapid/plugin/group_replication/src/applier.cc
@@ -683,6 +683,11 @@ void Applier_module::leave_group_on_failure()
Group_member_info::MEMBER_ERROR);
bool set_read_mode= false;
+ if (view_change_notifier != NULL &&
+ !view_change_notifier->is_view_modification_ongoing())
+ {
+ view_change_notifier->start_view_modification();
+ }
Gcs_operations::enum_leave_state state= gcs_module->leave();
int error= channel_stop_all(CHANNEL_APPLIER_THREAD|CHANNEL_RECEIVER_THREAD,
@@ -745,6 +750,30 @@ void Applier_module::kill_pending_transactions(bool set_read_mode,
enable_server_read_mode(PSESSION_USE_THREAD);
}
+ if (view_change_notifier != NULL)
+ {
+ log_message(MY_INFORMATION_LEVEL, "Going to wait for view modification");
+ if (view_change_notifier->wait_for_view_modification())
+ {
+ log_message(MY_ERROR_LEVEL, "On shutdown there was a timeout receiving a "
+ "view change. This can lead to a possible "
+ "inconsistent state. Check the log for more "
+ "details");
+ }
+ }
+
+ /*
+ Only abort() if we successfully asked to leave() the group (and we have
+ group_replication_exit_state_action set to ABORT_SERVER).
+ We don't want to abort() during the execution of START GROUP_REPLICATION or
+ STOP GROUP_REPLICATION.
+ */
+ if (set_read_mode &&
+ exit_state_action_var == EXIT_STATE_ACTION_ABORT_SERVER)
+ {
+ abort_plugin_process("Fatal error during execution of Group Replication");
+ }
+
DBUG_VOID_RETURN;
}
diff --git a/rapid/plugin/group_replication/src/gcs_view_modification_notifier.cc b/rapid/plugin/group_replication/src/gcs_view_modification_notifier.cc
index 6925107b35e1..62b9022479a3 100644
--- a/rapid/plugin/group_replication/src/gcs_view_modification_notifier.cc
+++ b/rapid/plugin/group_replication/src/gcs_view_modification_notifier.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -64,6 +64,15 @@ Plugin_gcs_view_modification_notifier::is_injected_view_modification()
return result;
}
+bool
+Plugin_gcs_view_modification_notifier::is_view_modification_ongoing()
+{
+ mysql_mutex_lock(&wait_for_view_mutex);
+ bool result = view_changing;
+ mysql_mutex_unlock(&wait_for_view_mutex);
+ return result;
+}
+
void
Plugin_gcs_view_modification_notifier::end_view_modification()
{
diff --git a/rapid/plugin/group_replication/src/group_partition_handling.cc b/rapid/plugin/group_replication/src/group_partition_handling.cc
index 978dbf544623..60b359cc0aff 100644
--- a/rapid/plugin/group_replication/src/group_partition_handling.cc
+++ b/rapid/plugin/group_replication/src/group_partition_handling.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -148,6 +148,11 @@ void Group_partition_handling::kill_transactions_and_leave()
if (set_read_mode)
enable_server_read_mode(PSESSION_INIT_THREAD);
+ if (exit_state_action_var == EXIT_STATE_ACTION_ABORT_SERVER)
+ {
+ abort_plugin_process("Fatal error during execution of Group Replication");
+ }
+
DBUG_VOID_RETURN;
}
diff --git a/rapid/plugin/group_replication/src/member_info.cc b/rapid/plugin/group_replication/src/member_info.cc
index 36538c55b9a5..54f7dd0fa077 100644
--- a/rapid/plugin/group_replication/src/member_info.cc
+++ b/rapid/plugin/group_replication/src/member_info.cc
@@ -41,7 +41,7 @@ Group_member_info(char* hostname_arg,
gtid_assignment_block_size(gtid_assignment_block_size_arg),
unreachable(false),
role(role_arg),
- configuration_flags(0), conflict_detection_enable(false),
+ configuration_flags(0), conflict_detection_enable(!in_single_primary_mode),
member_weight(member_weight_arg),
lower_case_table_names(lower_case_table_names_arg)
{
@@ -880,16 +880,17 @@ Group_member_info_manager::get_string_current_view_active_hosts() const
{
std::stringstream hosts_string;
map::iterator all_members_it= members->begin();
+ bool first_entry = true;
while (all_members_it != members->end())
{
Group_member_info* member_info= (*all_members_it).second;
- if (member_info->get_recovery_status() == Group_member_info::MEMBER_ONLINE ||
- member_info->get_recovery_status() == Group_member_info::MEMBER_IN_RECOVERY)
- hosts_string << member_info->get_hostname() << ":" << member_info->get_port();
+ if (!first_entry)
+ hosts_string << ", ";
+ else
+ first_entry = false;
+ hosts_string << member_info->get_hostname() << ":" << member_info->get_port();
all_members_it++;
- if (all_members_it != members->end())
- hosts_string<<", ";
}
return hosts_string.str();
diff --git a/rapid/plugin/group_replication/src/observer_server_state.cc b/rapid/plugin/group_replication/src/observer_server_state.cc
index 422a94cf7ec0..44a1a3e95d3f 100644
--- a/rapid/plugin/group_replication/src/observer_server_state.cc
+++ b/rapid/plugin/group_replication/src/observer_server_state.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -54,8 +54,7 @@ int group_replication_before_server_shutdown(Server_state_param *param)
int group_replication_after_server_shutdown(Server_state_param *param)
{
server_shutdown_status= true;
- if (plugin_is_group_replication_running())
- group_replication_stop();
+ plugin_group_replication_stop();
return 0;
}
diff --git a/rapid/plugin/group_replication/src/plugin.cc b/rapid/plugin/group_replication/src/plugin.cc
index 637162f032ea..602ad766ac2e 100644
--- a/rapid/plugin/group_replication/src/plugin.cc
+++ b/rapid/plugin/group_replication/src/plugin.cc
@@ -159,6 +159,12 @@ ulong components_stop_timeout_var= LONG_TIMEOUT;
/* The timeout before going to error when majority becomes unreachable */
ulong timeout_on_unreachable_var= 0;
+/*
+ Exit state action that is executed when a server involuntarily leaves the
+ group.
+*/
+ulong exit_state_action_var;
+
/**
The default value for auto_increment_increment is choosen taking into
account the maximum usable values for each possible auto_increment_increment
@@ -352,6 +358,12 @@ int plugin_group_replication_start()
Mutex_autolock auto_lock_mutex(&plugin_running_mutex);
+ DBUG_EXECUTE_IF("group_replication_wait_on_start",
+ {
+ const char act[]= "now signal signal.start_waiting wait_for signal.start_continue";
+ DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act)));
+ });
+
if (plugin_is_group_replication_running())
DBUG_RETURN(GROUP_REPLICATION_ALREADY_RUNNING);
if (check_if_server_properly_configured())
@@ -602,6 +614,18 @@ int initialize_plugin_and_join(enum_plugin_con_isolation sql_api_isolation,
set_read_mode_state(sql_command_interface, read_only_mode,
super_read_only_mode);
}
+
+ /*
+ Abort right away if the exit state action was set to ABORT_SERVER (and we
+ are starting GROUP_REPLICATION on boot).
+ */
+ if (exit_state_action_var == EXIT_STATE_ACTION_ABORT_SERVER &&
+ start_group_replication_at_boot_var)
+ {
+ abort_plugin_process("Fatal error during execution of Group Replication "
+ "group joining process");
+ }
+
if (certification_latch != NULL)
{
delete certification_latch; /* purecov: inspected */
@@ -803,8 +827,6 @@ int leave_group()
// Destroy handlers and notifiers
delete events_handler;
events_handler= NULL;
- delete view_change_notifier;
- view_change_notifier= NULL;
return 0;
}
@@ -815,6 +837,12 @@ int plugin_group_replication_stop()
Mutex_autolock auto_lock_mutex(&plugin_running_mutex);
+ DBUG_EXECUTE_IF("group_replication_wait_on_stop",
+ {
+ const char act[]= "now signal signal.stop_waiting wait_for signal.stop_continue";
+ DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act)));
+ });
+
/*
We delete the delayed initialization object here because:
@@ -986,7 +1014,7 @@ int plugin_group_replication_init(MYSQL_PLUGIN plugin_info)
plugin_info_ptr= plugin_info;
- if (group_replication_init(group_replication_plugin_name))
+ if (group_replication_init())
{
/* purecov: begin inspected */
log_message(MY_ERROR_LEVEL,
@@ -1030,13 +1058,14 @@ int plugin_group_replication_init(MYSQL_PLUGIN plugin_info)
//Initialize channel observation and auto increment handlers before start
auto_increment_handler= new Plugin_group_replication_auto_increment();
channel_observation_manager= new Channel_observation_manager(plugin_info);
+ view_change_notifier= new Plugin_gcs_view_modification_notifier();
gcs_module= new Gcs_operations();
//Initialize the compatibility module before starting
init_compatibility_manager();
plugin_is_auto_starting= start_group_replication_at_boot_var;
- if (start_group_replication_at_boot_var && group_replication_start())
+ if (start_group_replication_at_boot_var && plugin_group_replication_start())
{
log_message(MY_ERROR_LEVEL,
"Unable to start Group Replication on boot");
@@ -1054,10 +1083,9 @@ int plugin_group_replication_deinit(void *p)
plugin_is_being_uninstalled= true;
int observer_unregister_error= 0;
- //plugin_group_replication_stop will be called from this method stack
- if (group_replication_cleanup())
+ if (plugin_group_replication_stop())
log_message(MY_ERROR_LEVEL,
- "Failure when cleaning Group Replication server state");
+ "Failure when stopping Group Replication on plugin uninstall");
if (group_member_mgr != NULL)
{
@@ -1112,6 +1140,9 @@ int plugin_group_replication_deinit(void *p)
delete gcs_module;
gcs_module= NULL;
+ delete view_change_notifier;
+ view_change_notifier= NULL;
+
if(auto_increment_handler != NULL)
{
delete auto_increment_handler;
@@ -1417,7 +1448,6 @@ int start_group_communication()
get_server_id());
}
- view_change_notifier= new Plugin_gcs_view_modification_notifier();
events_handler= new Plugin_gcs_events_handler(applier_module,
recovery_module,
view_change_notifier,
@@ -1567,7 +1597,7 @@ static int check_if_server_properly_configured()
//Struct that holds startup and runtime requirements
Trans_context_info startup_pre_reqs;
- get_server_startup_prerequirements(startup_pre_reqs, true);
+ get_server_startup_prerequirements(startup_pre_reqs, !plugin_is_auto_starting);
if(!startup_pre_reqs.binlog_enabled)
{
@@ -2792,6 +2822,22 @@ static MYSQL_SYSVAR_UINT(
0 /* block */
);
+const char *exit_state_actions[]= {"READ_ONLY", "ABORT_SERVER", (char *)0};
+TYPELIB exit_state_actions_typelib_t= {array_elements(exit_state_actions) - 1,
+ "exit_state_actions_typelib_t",
+ exit_state_actions, NULL};
+static MYSQL_SYSVAR_ENUM(exit_state_action, /* name */
+ exit_state_action_var, /* var */
+ PLUGIN_VAR_OPCMDARG, /* optional var */
+ "The action that is taken when the server "
+ "leaves the group. "
+ "Possible values are READ_ONLY or "
+ "ABORT_SERVER.", /* values */
+ NULL, /* check func. */
+ NULL, /* update func. */
+ EXIT_STATE_ACTION_READ_ONLY, /* default */
+ &exit_state_actions_typelib_t); /* type lib */
+
static SYS_VAR* group_replication_system_vars[]= {
MYSQL_SYSVAR(group_name),
MYSQL_SYSVAR(start_on_boot),
@@ -2828,6 +2874,7 @@ static SYS_VAR* group_replication_system_vars[]= {
MYSQL_SYSVAR(transaction_size_limit),
MYSQL_SYSVAR(unreachable_majority_timeout),
MYSQL_SYSVAR(member_weight),
+ MYSQL_SYSVAR(exit_state_action),
NULL,
};
diff --git a/rapid/plugin/group_replication/src/plugin_utils.cc b/rapid/plugin/group_replication/src/plugin_utils.cc
index 0b6899a7737b..2fd6e740a476 100644
--- a/rapid/plugin/group_replication/src/plugin_utils.cc
+++ b/rapid/plugin/group_replication/src/plugin_utils.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -86,3 +86,12 @@ void log_primary_member_details()
}
}
}
+
+void abort_plugin_process(const char *message)
+{
+ log_message(MY_ERROR_LEVEL, "The plugin encountered a critical error and will abort: %s", message);
+#if !defined(DBUG_OFF)
+ DBUG_SUICIDE();
+#endif
+ abort();
+}
diff --git a/rapid/plugin/group_replication/src/recovery.cc b/rapid/plugin/group_replication/src/recovery.cc
index 5b1359d6f2e5..a2189da1f614 100644
--- a/rapid/plugin/group_replication/src/recovery.cc
+++ b/rapid/plugin/group_replication/src/recovery.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -185,6 +185,12 @@ void Recovery_module::leave_group_on_recovery_failure()
group_member_mgr->update_member_status(local_member_info->get_uuid(),
Group_member_info::MEMBER_ERROR);
+ if (view_change_notifier != NULL &&
+ !view_change_notifier->is_view_modification_ongoing())
+ {
+ view_change_notifier->start_view_modification();
+ }
+
Gcs_operations::enum_leave_state state= gcs_module->leave();
int error= channel_stop_all(CHANNEL_APPLIER_THREAD|CHANNEL_RECEIVER_THREAD,
@@ -198,6 +204,7 @@ void Recovery_module::leave_group_on_recovery_failure()
}
std::stringstream ss;
+ bool has_error= true;
plugin_log_level log_severity= MY_WARNING_LEVEL;
switch (state)
{
@@ -217,9 +224,27 @@ void Recovery_module::leave_group_on_recovery_failure()
break;
/* purecov: end */
case Gcs_operations::NOW_LEAVING:
- return;
+ has_error= false;
+ break;
}
- log_message(log_severity, ss.str().c_str());
+
+ if (has_error)
+ log_message(log_severity, ss.str().c_str());
+
+ if (view_change_notifier != NULL)
+ {
+ log_message(MY_INFORMATION_LEVEL, "Going to wait for view modification");
+ if (view_change_notifier->wait_for_view_modification())
+ {
+ log_message(MY_WARNING_LEVEL, "On shutdown there was a timeout receiving "
+ "a view change. This can lead to a possible"
+ " inconsistent state. Check the log for "
+ "more details");
+ }
+ }
+
+ if (exit_state_action_var == EXIT_STATE_ACTION_ABORT_SERVER)
+ abort_plugin_process("Fatal error during execution of Group Replication");
}
/*
diff --git a/rapid/plugin/group_replication/src/recovery_state_transfer.cc b/rapid/plugin/group_replication/src/recovery_state_transfer.cc
index e6598b8e6f82..9b4a73107dc4 100644
--- a/rapid/plugin/group_replication/src/recovery_state_transfer.cc
+++ b/rapid/plugin/group_replication/src/recovery_state_transfer.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -390,8 +390,16 @@ int Recovery_state_transfer::establish_donor_connection()
{
mysql_mutex_lock(&donor_selection_lock);
+ DBUG_EXECUTE_IF("gr_reset_max_connection_attempts_to_donors", {
+ if (donor_connection_retry_count == 3) {
+ const char act[] =
+ "now signal signal.connection_attempt_3 wait_for "
+ "signal.reset_recovery_retry_count_done";
+ DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act)));
+ }
+ };);
// max number of retries reached, abort
- if (donor_connection_retry_count == max_connection_attempts_to_donors)
+ if (donor_connection_retry_count >= max_connection_attempts_to_donors)
{
log_message(MY_ERROR_LEVEL,
"Maximum number of retries when trying to "
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_applier_early_failure.result b/rapid/plugin/group_replication/tests/mtr/r/gr_applier_early_failure.result
index d06e8d14ef31..a7d2f7685cc8 100644
--- a/rapid/plugin/group_replication/tests/mtr/r/gr_applier_early_failure.result
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_applier_early_failure.result
@@ -7,12 +7,18 @@ Note #### Storing MySQL user name or password information in the master info rep
# 1. Create a table on server 1 and replicate
#
[connection server1]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
+SET SESSION sql_log_bin = 1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
include/rpl_sync.inc
#
# 2. Insert a row on server 2 with log to the binlog disabled
#
[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
+SET SESSION sql_log_bin = 1;
SET SESSION sql_log_bin= 0;
INSERT INTO t1 VALUES (1);
SET SESSION sql_log_bin= 1;
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_start_uninstall.result b/rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_start_uninstall.result
new file mode 100644
index 000000000000..b17fbbb43b46
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_start_uninstall.result
@@ -0,0 +1,39 @@
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+
+# 1. Setup GR environment and execute START GR.
+
+[connection server1]
+SET GLOBAL group_replication_bootstrap_group=ON;
+SET GLOBAL group_replication_group_name= "GROUP_REPLICATION_GROUP_NAME";
+
+# 2. Block start, so we can execute UNINSTALL.
+
+SET @debug_save= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_wait_on_start';
+START GROUP_REPLICATION;
+
+# 3. Execute UNINSTALL PLUGIN GR should fail with error
+# ER_PLUGIN_CANNOT_BE_UNINSTALLED as START GR is already running.
+
+[connection server_1]
+SET DEBUG_SYNC= "now WAIT_FOR signal.start_waiting";
+UNINSTALL PLUGIN group_replication;
+ERROR HY000: Plugin 'group_replication' cannot be uninstalled now. Plugin is busy, it cannot be uninstalled. To force a stop run STOP GROUP_REPLICATION and then UNINSTALL PLUGIN group_replication.
+
+# 4. SIGNAL START GR to resume processing.
+
+SET DEBUG_SYNC= 'now SIGNAL signal.start_continue';
+[connection server1]
+
+# 5. Confirm GR is started
+
+include/gr_wait_for_member_state.inc
+
+# 6. Cleanup
+
+SET @@GLOBAL.DEBUG= @debug_save;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_stop_select.result b/rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_stop_select.result
new file mode 100644
index 000000000000..868baf72b1c9
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_concurrent_stop_select.result
@@ -0,0 +1,33 @@
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+
+# 1. Block Stop Group Replication
+
+SET @debug_save= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_wait_on_stop';
+STOP GROUP_REPLICATION;
+
+# 2. Wait for debug sync to be reached and then execute select query
+
+[connection server_1]
+SET DEBUG_SYNC= "now WAIT_FOR signal.stop_waiting";
+SELECT COUNT(*) FROM performance_schema.replication_connection_status;
+COUNT(*)
+2
+
+# 3. SIGNAL STOP GR to resume processing
+
+SET DEBUG_SYNC= 'now SIGNAL signal.stop_continue';
+[connection server1]
+
+# 4. Confirm Group Replication is stopped
+
+include/gr_wait_for_member_state.inc
+
+# 5. Cleanup
+
+SET @@GLOBAL.DEBUG= @debug_save;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_applier_error.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_applier_error.result
new file mode 100644
index 000000000000..edd456ac23bc
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_applier_error.result
@@ -0,0 +1,94 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Could not execute Write_rows event on table test.t1; Duplicate entry.*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Worker [0-9] failed executing transaction*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': ... The slave coordinator and worker threads are stopped,*");
+call mtr.add_suppression("The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.");
+call mtr.add_suppression("Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.");
+call mtr.add_suppression("The server was automatically set into read only mode after an error was detected.");
+call mtr.add_suppression("Member was expelled from the group due to network failures, changing member status to ERROR.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Force applier error on member 1.
+#########################################################################
+
+[connection server1]
+CREATE TABLE t1(a INT PRIMARY KEY);
+include/rpl_sync.inc
+SET SESSION sql_log_bin= 0;
+INSERT INTO t1 VALUES (1);
+SET SESSION sql_log_bin= 1;
+[connection server2]
+INSERT INTO t1 VALUES (1);
+include/rpl_sync.inc
+
+#########################################################################
+# 1.1) Verify that member 1 went to super_read_only mode.
+#########################################################################
+
+[connection server1]
+include/gr_wait_for_member_state.inc
+[connection server1]
+include/assert.inc [super_read_only should be enabled]
+
+#########################################################################
+# 2) Set exit state action to ABORT_SERVER on member 1.
+#########################################################################
+
+include/stop_group_replication.inc
+SET sql_log_bin = 0;
+DELETE FROM t1 WHERE a = 1;
+SET sql_log_bin = 1;
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+
+#########################################################################
+# 3) Force applier error again on member 1.
+#########################################################################
+
+include/start_group_replication.inc
+SET SESSION sql_log_bin= 0;
+INSERT INTO t1 VALUES (2);
+SET SESSION sql_log_bin= 1;
+[connection server2]
+INSERT INTO t1 VALUES (2);
+
+#########################################################################
+# 3.1) Verify that member 1 aborted.
+#########################################################################
+
+include/rpl_gr_wait_for_number_of_members.inc
+include/assert.inc [Member 1 should have aborted]
+
+#########################################################################
+# 4) Relaunch member 1.
+#########################################################################
+
+[connection server1]
+include/rpl_reconnect.inc
+[connection server1]
+SET SESSION sql_log_bin= 0;
+DELETE FROM t1 WHERE a = 2;
+SET SESSION sql_log_bin= 1;
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER1";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER1";
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 5) Cleanup.
+#########################################################################
+
+DROP TABLE t1;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_lower_version.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_lower_version.result
new file mode 100644
index 000000000000..e2948584b51c
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_lower_version.result
@@ -0,0 +1,94 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Error, maximum number of retries exceeded when waiting for the internal server session state to be operating");
+call mtr.add_suppression("Failed to establish an internal server connection to execute plugin operations");
+call mtr.add_suppression("Error when extracting information for group change. Operations and checks made to group joiners may be incomplete.");
+call mtr.add_suppression("Member version is incompatible with the group.");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Simulate a higher version on M1.
+#########################################################################
+
+[connection server1]
+SET @debug_saved= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_compatibility_higher_major_version';
+include/start_and_bootstrap_group_replication.inc
+
+#########################################################################
+# 2) Try to join M2 to the group.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1
+include/rpl_reconnect.inc
+
+#########################################################################
+# 3) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported expected incompatibility on member version]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 4) Change the exit_state_action to ABORT_SERVER. Try to join M2 to the
+# group again.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --group_replication_exit_state_action=ABORT_SERVER
+
+#########################################################################
+# 5) M2 should have abort()ed.
+#########################################################################
+
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+include/rpl_reconnect.inc
+[connection server2]
+include/rpl_reconnect.inc
+include/assert_grep.inc [GR reported expected incompatibility on member version]
+include/assert_grep.inc [GR reported expected abort]
+
+#########################################################################
+# 6) Restart M2 again without group_replication_start_on_boot enabled.
+# The server should start normally and be able to join the group.
+#########################################################################
+
+[connection server1]
+SET @@GLOBAL.DEBUG = @debug_saved;
+include/stop_group_replication.inc
+include/start_and_bootstrap_group_replication.inc
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME
+include/rpl_reconnect.inc
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 7) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_members_exceeded.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_members_exceeded.result
new file mode 100644
index 000000000000..fbc600db913a
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_members_exceeded.result
@@ -0,0 +1,89 @@
+
+#########################################################################
+# 0) Setup group of 1 member (M1).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+include/start_and_bootstrap_group_replication.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("Error, maximum number of retries exceeded when waiting for the internal server session state to be operating");
+call mtr.add_suppression("Failed to establish an internal server connection to execute plugin operations");
+call mtr.add_suppression("Error when extracting information for group change. Operations and checks made to group joiners may be incomplete");
+call mtr.add_suppression("The START GROUP_REPLICATION command failed since the group already has 9 members.");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Simulate a group of 10 members when member 2 joins. Member 2 will
+# be unable to join.
+#########################################################################
+
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --loose-debug=+d,group_replication_set_number_of_members_on_view_changed_to_10
+include/rpl_reconnect.inc
+
+#########################################################################
+# 2) Verify that member 2 was sent to super_read_only mode and in OFFLINE
+# state (since it failed to join the group).
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported expected excess of members in group]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 3) Set the exit_state_action to ABORT_SERVER and simulate again a
+# group of 10 members when member 2 joins. Member 2 will be unable to
+# join again.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --loose-debug=+d,group_replication_set_number_of_members_on_view_changed_to_10 --group_replication_exit_state_action=ABORT_SERVER
+
+#########################################################################
+# 4) Member 2 will have abort()ed.
+#########################################################################
+
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+include/rpl_reconnect.inc
+[connection server2]
+include/rpl_reconnect.inc
+include/assert_grep.inc [GR reported expected excess of members in group]
+include/assert_grep.inc [GR reported expected abort]
+
+#########################################################################
+# 5) Restart M2 again without group_replication_start_on_boot enabled.
+# The server should start normally and be able to join the group.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME
+include/rpl_reconnect.inc
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 6) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_transaction_mismatch.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_transaction_mismatch.result
new file mode 100644
index 000000000000..a9a6a78bca32
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_transaction_mismatch.result
@@ -0,0 +1,98 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+call mtr.add_suppression("This member has more executed transactions than those present in the group. Local transactions*");
+call mtr.add_suppression("The member contains transactions not present in the group. The member will now exit the group");
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Run a few transactions on M2.
+#########################################################################
+
+[connection server1]
+CREATE TABLE t3(a INT PRIMARY KEY);
+INSERT INTO t3 VALUES (2);
+include/start_and_bootstrap_group_replication.inc
+[connection server2]
+SET GTID_NEXT= "aaaaaaaa-bbbb-aaaa-bbbb-aaaaaaaaaaaa:1";
+CREATE TABLE t2(a INT PRIMARY KEY);
+SET GTID_NEXT= "AUTOMATIC";
+
+#########################################################################
+# 2) Restart M2 with start_on_boot enabled.
+#########################################################################
+
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1
+include/rpl_reconnect.inc
+
+#########################################################################
+# 3) M2 should go to super_read_only mode.
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported expected transaction mismatch]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 4) Restart M2 with start_on_boot enabled and exit_state_action set to
+# ABORT_SERVER.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --group_replication_exit_state_action=ABORT_SERVER
+
+#########################################################################
+# 5) M2 should have abort()'ed.
+#########################################################################
+
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+include/rpl_reconnect.inc
+[connection server2]
+include/rpl_reconnect.inc
+include/assert_grep.inc [GR reported expected transaction mismatch]
+include/assert_grep.inc [GR reported expected abort]
+
+#########################################################################
+# 6) Restart M2 again without group_replication_start_on_boot enabled.
+# The server should start normally and be able to join the group.
+#########################################################################
+
+[connection server2]
+RESET MASTER;
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME
+include/rpl_reconnect.inc
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 7) Cleanup.
+#########################################################################
+
+[connection server1]
+DROP TABLE t3;
+[connection server2]
+SET sql_log_bin = 0;
+DROP TABLE t2;
+SET sql_log_bin = 1;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.result
new file mode 100644
index 000000000000..6b8223e50533
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.result
@@ -0,0 +1,79 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+include/start_and_bootstrap_group_replication.inc
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Unable to start Group Replication on boot");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Relaunch M2 with a different gtid_assignment_block_size from M1.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --group_replication_gtid_assignment_block_size=GROUP_REPLICATION_GTID_ASSIGNMENT_BLOCK_SIZE
+include/rpl_reconnect.inc
+
+#########################################################################
+# 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported that it has a different gtid_assignment_block_size value (as expected)]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 3) Relaunch M2 with a different gtid_assignment_block_size from M1 and
+# with exit_state_action set to ABORT_SERVER.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --group_replication_gtid_assignment_block_size=GROUP_REPLICATION_GTID_ASSIGNMENT_BLOCK_SIZE --group_replication_exit_state_action=ABORT_SERVER
+
+#########################################################################
+# 4) M2 should have abort()ed.
+#########################################################################
+
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+include/rpl_reconnect.inc
+[connection server2]
+include/rpl_reconnect.inc
+include/assert_grep.inc [GR reported that it has a different gtid_assignment_block_size value (as expected)]
+include/assert_grep.inc [GR reported expected abort]
+
+#########################################################################
+# 5) Restart M2 again without group_replication_start_on_boot enabled.
+# The server should start normally and be able to join the group.
+#########################################################################
+
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME
+include/rpl_reconnect.inc
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 6) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_hash_algorithm.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_hash_algorithm.result
new file mode 100644
index 000000000000..759184259cd2
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_hash_algorithm.result
@@ -0,0 +1,79 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+include/start_and_bootstrap_group_replication.inc
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Unable to start Group Replication on boot");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Relaunch M2 with a different hash algorithm from M1.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --transaction-write-set-extraction=HASH_ALGORITHM
+include/rpl_reconnect.inc
+
+#########################################################################
+# 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported that it has an incompatible option with the group (as expected)]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 3) Relaunch M2 with a different hash algorithm from M1 and with
+# exit_state_action set to ABORT_SERVER.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --transaction-write-set-extraction=HASH_ALGORITHM --group_replication_exit_state_action=ABORT_SERVER
+
+#########################################################################
+# 4) M2 should have abort()ed.
+#########################################################################
+
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+include/rpl_reconnect.inc
+[connection server2]
+include/rpl_reconnect.inc
+include/assert_grep.inc [GR reported that it has an incompatible option with the group (as expected)]
+include/assert_grep.inc [GR reported expected abort]
+
+#########################################################################
+# 5) Restart M2 again without group_replication_start_on_boot enabled.
+# The server should start normally and be able to join the group.
+#########################################################################
+
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME
+include/rpl_reconnect.inc
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 6) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_single_primary_mode.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_single_primary_mode.result
new file mode 100644
index 000000000000..9f1dcb785b6b
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_join_wrong_single_primary_mode.result
@@ -0,0 +1,79 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+include/start_and_bootstrap_group_replication.inc
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Unable to start Group Replication on boot");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Relaunch M2 with a different single_primary_mode from M1.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --group_replication_single_primary_mode=FALSE --group_replication_enforce_update_everywhere_checks=FALSE
+include/rpl_reconnect.inc
+
+#########################################################################
+# 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+#########################################################################
+
+[connection server2]
+include/assert.inc [super_read_only should be enabled]
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert_grep.inc [GR reported that it has an incompatible option with the group (as expected)]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 3) Relaunch M2 with a different single_primary_mode from M1 and with
+# exit_state_action set to ABORT_SERVER.
+#########################################################################
+
+[connection server2]
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME --group_replication_start_on_boot=1 --group_replication_single_primary_mode=TRUE --group_replication_exit_state_action=ABORT_SERVER --group_replication_enforce_update_everywhere_checks=FALSE
+
+#########################################################################
+# 4) M2 should have abort()ed.
+#########################################################################
+
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+include/rpl_reconnect.inc
+[connection server2]
+include/rpl_reconnect.inc
+include/assert_grep.inc [GR reported that it has an incompatible option with the group (as expected)]
+include/assert_grep.inc [GR reported expected abort]
+
+#########################################################################
+# 5) Restart M2 again without group_replication_start_on_boot enabled.
+# The server should start normally and be able to join the group.
+#########################################################################
+
+# restart:--group_replication_local_address=GROUP_REPLICATION_LOCAL_ADDRESS --group_replication_group_seeds=GROUP_REPLICATION_GROUP_SEEDS --group-replication-group-name=GROUP_REPLICATION_GROUP_NAME
+include/rpl_reconnect.inc
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 6) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_majority_loss.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_majority_loss.result
new file mode 100644
index 000000000000..e829d96e52c2
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_majority_loss.result
@@ -0,0 +1,99 @@
+
+#########################################################################
+# 0) Setup group of 3 members (M1, M2 and M3).
+#########################################################################
+
+include/group_replication.inc [rpl_server_count=3]
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server1]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("read failed");
+call mtr.add_suppression("This member could not reach a majority of the members for more than.*");
+call mtr.add_suppression("The server was automatically set into read only mode after an error was detected.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("\\[GCS\\] Timeout while waiting for the group communication engine to exit!");
+call mtr.add_suppression("\\[GCS\\] The member has failed to gracefully leave the group.");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+[connection server2]
+[connection server3]
+
+#########################################################################
+# 1) Force majority loss.
+#########################################################################
+
+[connection server2]
+[connection server3]
+
+#########################################################################
+# 1.1) Verify that member 1 went to ERROR state.
+#########################################################################
+
+[connection server1]
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+
+#########################################################################
+# 2) Relaunch group with exit state action to ABORT_SERVER.
+#########################################################################
+
+[connection server1]
+include/stop_group_replication.inc
+include/start_and_bootstrap_group_replication.inc
+include/rpl_reconnect.inc
+[connection server2]
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER2";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER2";
+include/start_group_replication.inc
+include/rpl_reconnect.inc
+[connection server3]
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER3";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER3";
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+
+#########################################################################
+# 3) Force another majority loss.
+#########################################################################
+
+[connection server2]
+[connection server3]
+
+#########################################################################
+# 4) Verify that member 1 aborted.
+#########################################################################
+
+[connection server1]
+
+#########################################################################
+# 5) Relaunch all members.
+#########################################################################
+
+include/rpl_reconnect.inc
+[connection server1]
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER1";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER1";
+include/start_and_bootstrap_group_replication.inc
+include/rpl_reconnect.inc
+[connection server2]
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER2";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER2";
+include/start_group_replication.inc
+include/rpl_reconnect.inc
+[connection server3]
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER3";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER3";
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 6) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_member_expel.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_member_expel.result
new file mode 100644
index 000000000000..f42f4dbe1e64
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_member_expel.result
@@ -0,0 +1,78 @@
+
+#########################################################################
+# 0) Setup group of 3 members (M1, M2 and M3).
+#########################################################################
+
+include/group_replication.inc [rpl_server_count=3]
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server1]
+SET SESSION sql_log_bin = 0;
+CREATE TABLE pid_table(pid_no INT PRIMARY KEY);
+LOAD DATA LOCAL INFILE 'pid_file' INTO TABLE pid_table;
+DROP TABLE pid_table;
+call mtr.add_suppression("Member was expelled from the group due to network failures, changing member status to ERROR.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Force expel of member 1.
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server3]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 1.1) Verify that member 1 went to super_read_only mode.
+#########################################################################
+
+[connection server1]
+include/gr_wait_for_member_state.inc
+[connection server1]
+include/assert.inc [super_read_only should be enabled]
+include/stop_group_replication.inc
+
+#########################################################################
+# 2) Set exit state action to ABORT_SERVER on member 1.
+#########################################################################
+
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 3) Force expel again of member 1.
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server3]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 3.1) Wait until server is aborted.
+#########################################################################
+
+[connection server1]
+
+#########################################################################
+# 4) Relaunch member 1.
+#########################################################################
+
+include/rpl_reconnect.inc
+[connection server1]
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER1";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER1";
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 5) Cleanup.
+#########################################################################
+
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_recovery.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_recovery.result
new file mode 100644
index 000000000000..2e641d6ec27a
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_recovery.result
@@ -0,0 +1,94 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2) but only start GR on M2.
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server1]
+SET sql_log_bin = 0;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+SET sql_log_bin = 1;
+[connection server2]
+include/start_and_bootstrap_group_replication.inc
+[connection server1]
+SET sql_log_bin = 0;
+call mtr.add_suppression("read failed");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_recovery': Error 'Table 't1'*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_recovery': Worker [0-9] failed executing transaction*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_recovery': ... The slave coordinator and worker threads are stopped,*");
+call mtr.add_suppression("Slave: Table 't1' already exists Error_code:*");
+call mtr.add_suppression("Maximum number of retries when trying to connect to a donor reached. Aborting group replication recovery.");
+call mtr.add_suppression("Fatal error during the recovery process of Group Replication. The server will leave the group.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+call mtr.add_suppression("Error while starting the group replication recovery receiver/applier threads");
+SET sql_log_bin = 1;
+
+#########################################################################
+# 1) Force error during the catch-up phase of M1.
+#########################################################################
+
+[connection server2]
+CREATE TABLE t1 (a INT PRIMARY KEY);
+[connection server1]
+include/start_group_replication.inc
+
+#########################################################################
+# 1.1) Verify that M1 goes into ERROR state and to super_read_only mode.
+#########################################################################
+
+include/gr_wait_for_member_state.inc
+[connection server1]
+include/assert.inc [super_read_only should be enabled]
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 2) Set group_replication_exit_state_action to ABORT_SERVER on M1.
+#########################################################################
+
+[connection server1]
+include/stop_group_replication.inc
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+
+#########################################################################
+# 3) Force another error during the catch-up phase of M1.
+#########################################################################
+
+include/start_group_replication.inc
+
+#########################################################################
+# 3.1) Verify that M1 aborted.
+#########################################################################
+
+[connection server2]
+include/rpl_gr_wait_for_number_of_members.inc
+include/assert.inc [Member 1 should have aborted]
+
+#########################################################################
+# 4) Relaunch M1 and join the group.
+#########################################################################
+
+[connection server1]
+include/rpl_reconnect.inc
+[connection server1]
+SET SESSION sql_log_bin= 0;
+DROP TABLE t1;
+SET SESSION sql_log_bin= 1;
+RESET MASTER;
+SET @@global.group_replication_group_seeds="GROUP_SEEDS_SERVER1";
+SET @@global.group_replication_local_address="LOCAL_ADDRESS_SERVER1";
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 5) Cleanup.
+#########################################################################
+
+DROP TABLE t1;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_recovery_stage0.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_recovery_stage0.result
new file mode 100644
index 000000000000..ddd5f40b0330
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_recovery_stage0.result
@@ -0,0 +1,98 @@
+
+#########################################################################
+# 0) Setup group of 3 members (M1, M2 and M3).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server2]
+[connection server2]
+SET sql_log_bin = 0;
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Error 'Table 't1'*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Worker [0-9] failed executing transaction*");
+call mtr.add_suppression("Error writing relay log configuration.");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': ... The slave coordinator and worker threads are stopped,*");
+call mtr.add_suppression("Slave: Table 't1' already exists Error_code:*");
+call mtr.add_suppression("The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.");
+call mtr.add_suppression("Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.");
+call mtr.add_suppression("Unable to confirm whether the server has left the group or not. Check performance_schema.replication_group_members to check group membership information.");
+call mtr.add_suppression("There was a previous plugin error while the member joined the group. The member will now exit the group.");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
+SET sql_log_bin = 1;
+
+#########################################################################
+# 1) Stop the applier on M2.
+#########################################################################
+
+[connection server2]
+include/gr_stop_applier_sql_thread.inc
+STOP SLAVE SQL_THREAD FOR CHANNEL "group_replication_applier";
+
+#########################################################################
+# 2) Replicate TRX from M1 to M2 but without M2 applying it.
+#########################################################################
+
+[connection server1]
+CREATE TABLE t1 (a INT PRIMARY KEY);
+[connection server2]
+
+#########################################################################
+# 3) Stop GR on M2.
+#########################################################################
+
+include/stop_group_replication.inc
+
+#########################################################################
+# 4) Start GR on M2 again so he tries to join the group.
+#########################################################################
+
+SET SESSION sql_log_bin = 0;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+SET SESSION sql_log_bin = 1;
+START GROUP_REPLICATION;
+Got one of the listed errors
+include/assert_grep.inc [The applier should error out trying to create an already existing table]
+include/assert_grep.inc [The applier should error out trying to create an already existing table]
+include/assert_grep.inc [The applier should error out trying to create an already existing table]
+include/gr_wait_for_member_state.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 5) Set group_replication_exit_state_action sysvar to ABORT_SERVER on
+# M2.
+#########################################################################
+
+[connection server2]
+SET @group_replication_exit_state_action_saved = @@GLOBAL.group_replication_exit_state_action;
+SET GLOBAL group_replication_exit_state_action = ABORT_SERVER;
+
+#########################################################################
+# 6) Start GR on M2 again, so he tries to join the group. M2 should
+# not abort.
+#########################################################################
+
+START GROUP_REPLICATION;
+Got one of the listed errors
+include/assert_grep.inc [The applier should error out trying to create an already existing table]
+include/assert_grep.inc [The applier should error out trying to create an already existing table]
+include/assert_grep.inc [The applier should error out trying to create an already existing table]
+include/gr_wait_for_member_state.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 7) Cleanup.
+#########################################################################
+
+[connection server1]
+DROP TABLE t1;
+[connection server2]
+SET SESSION sql_log_bin = 0;
+DROP TABLE t1;
+SET SESSION sql_log_bin = 1;
+SET GLOBAL group_replication_exit_state_action = @group_replication_exit_state_action_saved;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_start_gr_cmd.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_start_gr_cmd.result
new file mode 100644
index 000000000000..49ef917a9b18
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_on_start_gr_cmd.result
@@ -0,0 +1,88 @@
+
+#########################################################################
+# 0) Setup group of 2 members (M1 and M2).
+#########################################################################
+
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+[connection server2]
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Member version is incompatible with the group.");
+SET SESSION sql_log_bin = 1;
+
+#########################################################################
+# 1) Simulate a higher version on M1.
+#########################################################################
+
+[connection server1]
+SET @debug_saved= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_compatibility_higher_major_version';
+include/start_and_bootstrap_group_replication.inc
+
+#########################################################################
+# 2) Try to join M2 to the group by issuing START GROUP_REPLICATION.
+#########################################################################
+
+[connection server2]
+SET @super_read_only_saved = @@GLOBAL.super_read_only;
+SET @exit_state_action_saved = @@GLOBAL.group_replication_exit_state_action;
+START GROUP_REPLICATION;
+ERROR HY000: The server is not configured properly to be an active member of the group. Please see more details on error log.
+
+#########################################################################
+# 3) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+#########################################################################
+
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported expected incompatibility on member version]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 4) Change the exit_state_action to ABORT_SERVER. Try to join M2 to the
+# group again.
+#########################################################################
+
+[connection server2]
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+START GROUP_REPLICATION;
+ERROR HY000: The server is not configured properly to be an active member of the group. Please see more details on error log.
+
+#########################################################################
+# 5) M2 should not abort().
+#########################################################################
+
+include/rpl_gr_wait_for_number_of_members.inc
+include/gr_wait_for_member_state.inc
+include/assert.inc [super_read_only should be enabled]
+include/assert_grep.inc [GR reported expected incompatibility on member version]
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 6) Remove the higher version from M1 and try to join M2 again. M2
+# should be able to join.
+#########################################################################
+
+SET @@GLOBAL.DEBUG = @debug_saved;
+include/stop_group_replication.inc
+include/start_and_bootstrap_group_replication.inc
+[connection server2]
+include/start_group_replication.inc
+include/rpl_gr_wait_for_number_of_members.inc
+[connection server1]
+include/rpl_gr_wait_for_number_of_members.inc
+
+#########################################################################
+# 7) Cleanup.
+#########################################################################
+
+[connection server2]
+SET @@GLOBAL.group_replication_exit_state_action = @exit_state_action_saved;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_option.result b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_option.result
new file mode 100644
index 000000000000..5ff9ec63efb6
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_exit_state_action_option.result
@@ -0,0 +1,49 @@
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+
+#########################################################################
+# 0) The test requires one server.
+#########################################################################
+
+[connection server1]
+SET @exit_state_action_saved = @@GLOBAL.group_replication_exit_state_action;
+
+#########################################################################
+# 1) Check the default value. It should be READ_ONLY.
+#########################################################################
+
+SET @@GLOBAL.group_replication_exit_state_action = default;
+include/assert.inc [The default of group_replication_exit_state_action should be READ_ONLY]
+
+#########################################################################
+# 2) Set the sysvar to the possible valid values.
+#########################################################################
+
+SET GLOBAL group_replication_exit_state_action = "READ_ONLY";
+include/assert.inc [The default of group_replication_exit_state_action should be READ_ONLY]
+SET GLOBAL group_replication_exit_state_action = "ABORT_SERVER";
+include/assert.inc [The default of group_replication_exit_state_action should be ABORT_SERVER]
+
+#########################################################################
+# 3) Set the sysvar to invalid values. There should be an error and the
+# value of the sysvar should not be altered.
+#########################################################################
+
+SET GLOBAL group_replication_exit_state_action = 42;
+ERROR 42000: Variable 'group_replication_exit_state_action' can't be set to the value of '42'
+SET GLOBAL group_replication_exit_state_action = on;
+ERROR 42000: Variable 'group_replication_exit_state_action' can't be set to the value of 'ON'
+SET GLOBAL group_replication_exit_state_action = "abort";
+ERROR 42000: Variable 'group_replication_exit_state_action' can't be set to the value of 'abort'
+SET GLOBAL group_replication_exit_state_action = "READ_ONLY";
+include/assert.inc [The default of group_replication_exit_state_action should be READ_ONLY]
+
+#########################################################################
+# 4) Cleanup.
+#########################################################################
+
+SET GLOBAL group_replication_exit_state_action = @exit_state_action_saved;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_channel.result b/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_channel.result
index 79ea7d1274fb..8d7831a899c4 100644
--- a/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_channel.result
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_channel.result
@@ -26,6 +26,7 @@ Note 1759 Sending passwords in plain text without SSL/TLS is extremely insecure.
Note 1760 Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
include/assert.inc ['The slave channel is present']
RESET SLAVE ALL;
+ERROR HY000: RESET SLAVE ALL FOR CHANNEL cannot be performed on channel 'group_replication_applier'.
include/assert.inc ['The group replication recovery channel is present']
include/assert.inc ['The group replication recovery channel is ON']
include/assert.inc ['The slave channel is not present']
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_lower_max_retry_count.result b/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_lower_max_retry_count.result
new file mode 100644
index 000000000000..7a9ff5598e60
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_lower_max_retry_count.result
@@ -0,0 +1,49 @@
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+
+# 1. Bootstrap start a group on M1.
+
+[connection server1]
+include/start_and_bootstrap_group_replication.inc
+
+# 2. Setup environment to fail donor connection and start GR on M2.
+# Set DEBUG on M2 to block donor connection attempt when count reaches 3.
+# Verify M2 is in recovery state.
+
+[connection server2]
+SET @debug_save= @@GLOBAL.DEBUG;
+SET @recovery_reconnect_interval_save= @@GLOBAL.GROUP_REPLICATION_RECOVERY_RECONNECT_INTERVAL;
+SET @recovery_retry_count_save= @@GLOBAL.group_replication_recovery_retry_count;
+CHANGE MASTER TO MASTER_USER="user_does_not_exist" FOR CHANNEL "group_replication_recovery";
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Maximum number of retries when trying to connect to a donor reached. Aborting group replication recovery.");
+call mtr.add_suppression("Fatal error during the recovery process of Group Replication. The server will leave the group.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+SET SESSION sql_log_bin = 1;
+SET @@GLOBAL.DEBUG='+d,gr_reset_max_connection_attempts_to_donors';
+SET GLOBAL group_replication_recovery_reconnect_interval= 2;
+include/start_group_replication.inc
+
+# 3. Reset group_replication_recovery_retry_count to 2.
+# Signal donor connection attempt to continue.
+
+SET DEBUG_SYNC= "now WAIT_FOR signal.connection_attempt_3";
+SET GLOBAL group_replication_recovery_retry_count= 2;
+SET DEBUG_SYNC= "now SIGNAL signal.reset_recovery_retry_count_done";
+
+# 4. Verification.
+
+include/gr_wait_for_member_state.inc
+include/assert_grep.inc [3 donor connections attempts were made.]
+include/assert_grep.inc [Post change of group_replication_recovery_retry_count, 4th donor connection attempt was not made.]
+include/assert_grep.inc [Recovery process aborted.]
+
+# 5. Clean up.
+
+SET @@GLOBAL.DEBUG= @debug_save;
+SET @@GLOBAL.GROUP_REPLICATION_RECOVERY_RECONNECT_INTERVAL= @recovery_reconnect_interval_save;
+SET @@GLOBAL.group_replication_recovery_retry_count= @recovery_retry_count_save;
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_no_donors.result b/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_no_donors.result
index 1812fe72528a..ce54c5cf4b93 100644
--- a/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_no_donors.result
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_recovery_no_donors.result
@@ -19,6 +19,7 @@ call mtr.add_suppression("Skipping leave operation: member already left the grou
call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
call mtr.add_suppression("Transaction cannot be executed while Group Replication is stopping.");
call mtr.add_suppression("Run function 'before_commit' in plugin 'group_replication' failed");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
SET SESSION sql_log_bin= 1;
CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT NOT NULL);
SET GLOBAL EVENT_SCHEDULER= ON;
@@ -53,6 +54,7 @@ call mtr.add_suppression("All donors left. Aborting group replication recovery."
call mtr.add_suppression("The member is already leaving or joining a group.");
call mtr.add_suppression("Skipping leave operation: member already left the group.");
call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
SET SESSION sql_log_bin= 1;
[connection server3]
SET SESSION sql_log_bin= 0;
@@ -63,6 +65,7 @@ call mtr.add_suppression("All donors left. Aborting group replication recovery."
call mtr.add_suppression("The member is already leaving or joining a group.");
call mtr.add_suppression("Skipping leave operation: member already left the group.");
call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
SET SESSION sql_log_bin= 1;
############################################################
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_reset_slave_channel.result b/rapid/plugin/group_replication/tests/mtr/r/gr_reset_slave_channel.result
index 11dfd57e4129..f7bc78c5dbff 100644
--- a/rapid/plugin/group_replication/tests/mtr/r/gr_reset_slave_channel.result
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_reset_slave_channel.result
@@ -18,6 +18,7 @@ CHANGE MASTER TO MASTER_HOST="127.0.0.1", MASTER_USER="root", MASTER_PASSWORD=""
include/assert.inc ['The group replication applier channel is present']
include/assert.inc ['The slave channel is present']
RESET SLAVE ALL;
+ERROR HY000: RESET SLAVE ALL FOR CHANNEL cannot be performed on channel 'group_replication_applier'.
include/assert.inc ['The group replication applier channel is still present']
include/assert.inc ['The group replication applier channel is ON']
include/assert.inc ['The slave channel is not present']
@@ -33,5 +34,25 @@ include/start_group_replication.inc
INSERT INTO t1 VALUES (5);
include/rpl_sync.inc
include/assert.inc [The table should contain 5 elements]
+server2
+Vefiry that group replication channels are present
+include/assert.inc ['The group replication applier channel is present']
+include/assert.inc ['The group replication recovery channel is present']
+include/stop_group_replication.inc
+RESET SLAVE command clears master and slave info repositories and will flush master info
+RESET SLAVE;
+include/assert.inc ['mysql.slave_relay_log_info contains no group replication channel information']
+include/assert.inc ['mysql.slave_master_info contains flushed group replication channel information']
+include/start_group_replication.inc
+include/assert.inc ['The group replication applier and recovery channel are present']
+include/stop_group_replication.inc
+RESET SLAVE ALL;
+include/assert.inc ['mysql.slave_relay_log_info does not contrain group replication channel information']
+include/assert.inc ['mysql.slave_master_info does not contrain group replication channel information']
+CHANGE MASTER TO MASTER_USER="root" FOR CHANNEL "group_replication_recovery";
+Warnings:
+Note 1759 Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note 1760 Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+include/start_group_replication.inc
DROP TABLE t1;
include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_show_global_and_session_variables.result b/rapid/plugin/group_replication/tests/mtr/r/gr_show_global_and_session_variables.result
index 0849d161007a..8fc6e839196c 100644
--- a/rapid/plugin/group_replication/tests/mtr/r/gr_show_global_and_session_variables.result
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_show_global_and_session_variables.result
@@ -7,8 +7,8 @@ Note #### Storing MySQL user name or password information in the master info rep
include/start_and_bootstrap_group_replication.inc
include/stop_group_replication.inc
-# Test#1: Basic check that there are 35 GR variables.
-include/assert.inc [There are 35 GR variables at present.]
+# Test#1: Basic check that there are 36 GR variables.
+include/assert.inc [There are 36 GR variables at present.]
# Test#2: Verify that all the group replication variables are GLOBAL variables.
SET @@SESSION.group_replication_allow_local_disjoint_gtids_join= 1;
@@ -75,6 +75,8 @@ SET @@SESSION.group_replication_unreachable_majority_timeout= 10240;
ERROR HY000: Variable 'group_replication_unreachable_majority_timeout' is a GLOBAL variable and should be set with SET GLOBAL
SET @@SESSION.group_replication_member_weight= 80;
ERROR HY000: Variable 'group_replication_member_weight' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@SESSION.group_replication_exit_state_action= "READ_ONLY";
+ERROR HY000: Variable 'group_replication_exit_state_action' is a GLOBAL variable and should be set with SET GLOBAL
Warnings:
Warning 1681 'group_replication_allow_local_disjoint_gtids_join' is deprecated and will be removed in a future release.
@@ -210,6 +212,10 @@ include/assert.inc [Verify GLOBAL value of group_replication_member_weight]
include/assert.inc [Verify GLOBAL value of group_replication_member_weight]
include/assert.inc [Verify SESSION value of group_replication_member_weight]
include/assert.inc [Verify SESSION value of group_replication_member_weight]
+include/assert.inc [Verify GLOBAL value of group_replication_exit_state_action]
+include/assert.inc [Verify GLOBAL value of group_replication_exit_state_action]
+include/assert.inc [Verify SESSION value of group_replication_exit_state_action]
+include/assert.inc [Verify SESSION value of group_replication_exit_state_action]
# Clean up
include/stop_group_replication.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_startup_check_node_seed_skips_own_address.result b/rapid/plugin/group_replication/tests/mtr/r/gr_startup_check_node_seed_skips_own_address.result
new file mode 100644
index 000000000000..3c048a6dec24
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_startup_check_node_seed_skips_own_address.result
@@ -0,0 +1,20 @@
+include/group_replication.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection server1]
+server1
+include/start_and_bootstrap_group_replication.inc
+server2
+"1. Test local address with raw address and seeds with name"
+include/start_group_replication.inc
+include/gr_wait_for_member_state.inc
+include/stop_group_replication.inc
+"2. Test local address with name address and seeds with raw address"
+include/start_group_replication.inc
+include/gr_wait_for_member_state.inc
+include/stop_group_replication.inc
+"3. Test local address with name address and seeds with name address"
+include/start_group_replication.inc
+include/gr_wait_for_member_state.inc
+include/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/r/gr_variables_default_values.result b/rapid/plugin/group_replication/tests/mtr/r/gr_variables_default_values.result
index 3ec4c2a4b1ed..d1c4383de0e5 100644
--- a/rapid/plugin/group_replication/tests/mtr/r/gr_variables_default_values.result
+++ b/rapid/plugin/group_replication/tests/mtr/r/gr_variables_default_values.result
@@ -24,9 +24,9 @@ include/stop_group_replication.inc
#
# Test Unit#1
# Set global group replication variables to default.
-# Curently there are 35 group replication variables.
+# Curently there are 36 group replication variables.
#
-include/assert.inc [There are 35 GR variables at present.]
+include/assert.inc [There are 36 GR variables at present.]
SET @@GLOBAL.group_replication_auto_increment_increment= default;
ERROR 42000: Variable 'group_replication_auto_increment_increment' can't be set to the value of 'DEFAULT'
SET @@GLOBAL.group_replication_compression_threshold= default;
@@ -68,6 +68,7 @@ SET @@GLOBAL.group_replication_start_on_boot= default;
SET @@GLOBAL.group_replication_transaction_size_limit= default;
SET @@GLOBAL.group_replication_unreachable_majority_timeout= default;
SET @@GLOBAL.group_replication_member_weight= default;
+SET @@GLOBAL.group_replication_exit_state_action= default;
#
# Test Unit#2
# Verify default values of the group replication variables.
@@ -100,6 +101,7 @@ include/assert.inc [Default group_replication_start_on_boot is ON/1]
include/assert.inc [Default group_replication_transaction_size_limit is 0]
include/assert.inc [Default group_replication_unreachable_majority_timeout is 0]
include/assert.inc [Default group_replication_member_weight is 50]
+include/assert.inc [Default group_replication_exit_state_action is READ_ONLY]
#
# Clean up
#
diff --git a/rapid/plugin/group_replication/tests/mtr/rpl_1slave_base.cnf b/rapid/plugin/group_replication/tests/mtr/rpl_1slave_base.cnf
index 50e1a75d01ff..1a75bd471b84 100644
--- a/rapid/plugin/group_replication/tests/mtr/rpl_1slave_base.cnf
+++ b/rapid/plugin/group_replication/tests/mtr/rpl_1slave_base.cnf
@@ -26,6 +26,7 @@ loose-group_replication_start_on_boot= OFF
loose-group_replication_single_primary_mode= FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
+loose-group_replication_exit_state_action= READ_ONLY
# Directory where slaves find the dumps generated by "load data"
# on the server. The path need to have constant length otherwise
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_applier_early_failure.test b/rapid/plugin/group_replication/tests/mtr/t/gr_applier_early_failure.test
index c1c6acab4c35..cc995f16aa28 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_applier_early_failure.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_applier_early_failure.test
@@ -31,6 +31,10 @@
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
+SET SESSION sql_log_bin = 1;
+
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
--source include/rpl_sync.inc
@@ -42,6 +46,10 @@ CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
+SET SESSION sql_log_bin = 1;
+
SET SESSION sql_log_bin= 0;
INSERT INTO t1 VALUES (1);
SET SESSION sql_log_bin= 1;
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error-slave.opt
new file mode 100644
index 000000000000..78e7e5c1b5c2
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_applier_error.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error.test b/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error.test
index c7e8a4db2eec..259bdcf59870 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_applier_error.test
@@ -69,8 +69,7 @@ INSERT INTO t1 VALUES (1);
--echo #
--echo # Step-6: Grep for the expected error in server log.
--echo #
---let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err
---let $assert_only_after = CURRENT_TEST: group_replication.gr_applier_error
+--let $assert_file= $MYSQLTEST_VARDIR/tmp/gr_applier_error.2.err
--let $assert_count = 1
--let $assert_select = failed executing transaction '.*'; Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY, Error_code: 1062
--let $assert_text = Found the expected error in group_replication_applier channel.
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_start_uninstall.test b/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_start_uninstall.test
new file mode 100644
index 000000000000..bf44f905f3a1
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_start_uninstall.test
@@ -0,0 +1,81 @@
+################################################################################
+# This test confirms that when START GR and UNINSTALL PLUGIN GR commands are
+# executed concurrently, no deadlock happens.
+#
+# Test:
+# 0. The test requires one server.
+# 1. Setup GR environment and execute START GR.
+# 2. Block start, so we can execute UNINSTALL.
+# 3. Execute UNINSTALL PLUGIN GR should fail with error
+# ER_PLUGIN_CANNOT_BE_UNINSTALLED as START GR is already running.
+# 4. SIGNAL START GR to resume processing.
+# 5. Confirm GR is started
+# 6. Cleanup
+#
+################################################################################
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source ../inc/have_group_replication_plugin.inc
+--let $rpl_skip_group_replication_start= 1
+--source ../inc/group_replication.inc
+
+--echo
+--echo # 1. Setup GR environment and execute START GR.
+--echo
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+
+SET GLOBAL group_replication_bootstrap_group=ON;
+--replace_result $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--eval SET GLOBAL group_replication_group_name= "$group_replication_group_name"
+
+--echo
+--echo # 2. Block start, so we can execute UNINSTALL.
+--echo
+
+## If START GR gets lock and UNINSTALL blocks SQL Query execution,
+## GR used to deadlock.
+
+SET @debug_save= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_wait_on_start';
+
+--send START GROUP_REPLICATION
+
+--echo
+--echo # 3. Execute UNINSTALL PLUGIN GR should fail with error
+--echo # ER_PLUGIN_CANNOT_BE_UNINSTALLED as START GR is already running.
+--echo
+
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+# Wait for the debug sync to be reached.
+SET DEBUG_SYNC= "now WAIT_FOR signal.start_waiting";
+
+--error ER_PLUGIN_CANNOT_BE_UNINSTALLED
+UNINSTALL PLUGIN group_replication;
+
+
+--echo
+--echo # 4. SIGNAL START GR to resume processing.
+--echo
+SET DEBUG_SYNC= 'now SIGNAL signal.start_continue';
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--reap
+
+--echo
+--echo # 5. Confirm GR is started
+--echo
+
+--let $group_replication_member_state= ONLINE
+--source ../inc/gr_wait_for_member_state.inc
+
+
+--echo
+--echo # 6. Cleanup
+--echo
+
+SET @@GLOBAL.DEBUG= @debug_save;
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_stop_select.test b/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_stop_select.test
new file mode 100644
index 000000000000..b12b7a029ac9
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_stop_select.test
@@ -0,0 +1,66 @@
+################################################################################
+# This test confirms that when STOP GR and select
+# performance_schema.replication_connection_status query is executed
+# concurrently, no deadlock happens.
+#
+# Test:
+# 0. The test requires one server.
+# 1. Block Stop Group Replication
+# 2. Wait for debug sync to be reached and then execute select query
+# 3. SIGNAL STOP GR to resume processing
+# 4. Confirm Group Replication is stopped
+# 5. Cleanup
+#
+################################################################################
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source ../inc/have_group_replication_plugin.inc
+--source ../inc/group_replication.inc
+
+--echo
+--echo # 1. Block Stop Group Replication
+--echo
+
+SET @debug_save= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_wait_on_stop';
+
+--send STOP GROUP_REPLICATION
+
+
+--echo
+--echo # 2. Wait for debug sync to be reached and then execute select query
+--echo
+
+--let $rpl_connection_name= server_1
+--source include/rpl_connection.inc
+
+SET DEBUG_SYNC= "now WAIT_FOR signal.stop_waiting";
+
+SELECT COUNT(*) FROM performance_schema.replication_connection_status;
+
+
+--echo
+--echo # 3. SIGNAL STOP GR to resume processing
+--echo
+
+SET DEBUG_SYNC= 'now SIGNAL signal.stop_continue';
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--reap
+
+
+--echo
+--echo # 4. Confirm Group Replication is stopped
+--echo
+
+--let $group_replication_member_state= OFFLINE
+--source ../inc/gr_wait_for_member_state.inc
+
+
+--echo
+--echo # 5. Cleanup
+--echo
+
+SET @@GLOBAL.DEBUG= @debug_save;
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_uninstall_stop.test b/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_uninstall_stop.test
index e9bbd6ef74a5..59eed268fab6 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_uninstall_stop.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_concurrent_uninstall_stop.test
@@ -1,7 +1,7 @@
# ==== Purpose ====
#
# Verify that 'UNINSTALL PLUGIN' and 'STOP GROUP_REPLICATION' commands
-# run well in parallel.
+# don't run in parallel in mysql 5.7.
#
# ==== Implementation ====
#
@@ -30,6 +30,10 @@ SET SESSION sql_log_bin= 1;
--source ../inc/start_and_bootstrap_group_replication.inc
+## Warnings depends upon sequence of execution of
+## query "STOP GROUP_REPLICATION" and "UNINSTALL PLUGIN group_replication"
+--disable_warnings
+
--send UNINSTALL PLUGIN group_replication
--let $rpl_connection_name= server_1
@@ -37,15 +41,19 @@ SET SESSION sql_log_bin= 1;
--echo #
--echo # STOP GROUP_REPLICATION in parallel.
--echo #
+## Uninstall will fail as STOP GR is already running.
--error 0, ER_GROUP_REPLICATION_CONFIGURATION
STOP GROUP_REPLICATION;
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
---error 0, ER_OPTION_PREVENTS_STATEMENT
+--error 0, ER_PLUGIN_CANNOT_BE_UNINSTALLED
--reap
+--enable_warnings
+
SET @@GLOBAL.read_only= 0;
+
# The previous UNINSTALL attempt may have failed due to SUPER_READ_ONLY=1, as
# such we uninstall the plugin again.
--error 0, ER_SP_DOES_NOT_EXIST
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_applier_error.cnf b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_applier_error.cnf
new file mode 100644
index 000000000000..7b06c802ec10
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_applier_error.cnf
@@ -0,0 +1,6 @@
+!include ../my.cnf
+
+[mysqld.1]
+local-infile= true
+
+[mysqld.2]
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_applier_error.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_applier_error.test
new file mode 100644
index 000000000000..026b53255c56
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_applier_error.test
@@ -0,0 +1,176 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken
+# by a server once it has involuntarily left the group. Currently there are
+# only two actions: either the server continues running but with
+# super_read_only enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall test that the specified exit action is executed correctly
+# when an applier error occurs.
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Force applier error on member 1.
+# 1.1) Verify that member 1 went to super_read_only mode and changed to ERROR
+# state.
+# 2) Relaunch member 1 with exit state action to ABORT_SERVER.
+# 3) Force applier error again on member 1.
+# 3.1) Verify that member 1 aborted.
+# 4) Relaunch member 1.
+# 5) Cleanup.
+#
+################################################################################
+--source include/have_debug.inc
+--source include/not_valgrind.inc
+--source include/big_test.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--source ../inc/group_replication.inc
+# Supress log errors since they are expected.
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Could not execute Write_rows event on table test.t1; Duplicate entry.*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Worker [0-9] failed executing transaction*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': ... The slave coordinator and worker threads are stopped,*");
+call mtr.add_suppression("The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.");
+call mtr.add_suppression("Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.");
+call mtr.add_suppression("The server was automatically set into read only mode after an error was detected.");
+call mtr.add_suppression("Member was expelled from the group due to network failures, changing member status to ERROR.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+--let $member1_uuid= `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server1= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server1= `SELECT @@GLOBAL.group_replication_group_seeds`
+
+--echo
+--echo #########################################################################
+--echo # 1) Force applier error on member 1.
+--echo #########################################################################
+--echo
+# Create a table for our tests
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+CREATE TABLE t1(a INT PRIMARY KEY);
+--source include/rpl_sync.inc
+# Write to it without replicating the trx
+SET SESSION sql_log_bin= 0;
+INSERT INTO t1 VALUES (1);
+SET SESSION sql_log_bin= 1;
+# Write to the same row on member 2
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+INSERT INTO t1 VALUES (1);
+# The rows on member 2 will be replicated and clash with member 1, thus
+# generating an applier error
+--source include/rpl_sync.inc
+
+--echo
+--echo #########################################################################
+--echo # 1.1) Verify that member 1 went to super_read_only mode.
+--echo #########################################################################
+--echo
+# Firstly verify that the member entered an error state
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_member_state= ERROR
+--let $group_replication_member_id= $member1_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Then verify that it enabled super_read_only
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Set exit state action to ABORT_SERVER on member 1.
+--echo #########################################################################
+--echo
+# Stop GR
+--source include/stop_group_replication.inc
+
+# Delete the transaction that clashed, so the server doesn't error out right
+# when starting the applier channel.
+SET sql_log_bin = 0;
+DELETE FROM t1 WHERE a = 1;
+SET sql_log_bin = 1;
+
+# Set the exit state action sysvar to ABORT_SERVER
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+
+--echo
+--echo #########################################################################
+--echo # 3) Force applier error again on member 1.
+--echo #########################################################################
+--echo
+# Inform MTR that we are expecting an abort and that it should wait before
+# restarting the aborting member
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--source include/start_group_replication.inc
+
+# Write to t1 without replicating the trx
+SET SESSION sql_log_bin= 0;
+INSERT INTO t1 VALUES (2);
+SET SESSION sql_log_bin= 1;
+
+# Write to the same row on member 2. This will clash with member 1's row and
+# thus generate an applier error
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+INSERT INTO t1 VALUES (2);
+
+--echo
+--echo #########################################################################
+--echo # 3.1) Verify that member 1 aborted.
+--echo #########################################################################
+--echo
+# For simplicity, let's assume that once the group size is 1, then member 1 has
+# abort()'ed
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+# Also, the member should not be in the group view of any of the other members
+--let $assert_text = Member 1 should have aborted
+--let $assert_cond = COUNT(*) = 0 FROM performance_schema.replication_group_members WHERE MEMBER_ID = "$member1_uuid"
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Relaunch member 1.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--source include/wait_until_disconnected.inc
+# Inform MTR that it should restart the aborted member
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--let $rpl_server_number= 1
+--source include/rpl_reconnect.inc
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin= 0;
+DELETE FROM t1 WHERE a = 2;
+SET SESSION sql_log_bin= 1;
+--replace_result $group_seeds_server1 GROUP_SEEDS_SERVER1
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server1"
+--replace_result $local_address_server1 LOCAL_ADDRESS_SERVER1
+--eval SET @@global.group_replication_local_address="$local_address_server1"
+--source include/start_group_replication.inc
+
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Cleanup.
+--echo #########################################################################
+--echo
+DROP TABLE t1;
+
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_lower_version-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_lower_version-slave.opt
new file mode 100644
index 000000000000..c8094b17bfe6
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_lower_version-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_lower_version.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_lower_version.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_lower_version.test
new file mode 100644
index 000000000000..9012f5521d82
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_lower_version.test
@@ -0,0 +1,204 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs upon joining the group (in this case, the member version of
+# the joining member not being compatible with the rest of the group).
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Simulate a higher version on M1.
+# 2) Try to join M2 to the group.
+# 3) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+# 4) Change the exit_state_action to ABORT_SERVER. Try to join M2 to the group
+# again.
+# 5) M2 should have abort()ed.
+# 6) Restart M2 again without group_replication_start_on_boot enabled. The
+# server should start normally and be able to join the group.
+# 7) Cleanup.
+#
+################################################################################
+# By including have_debug.inc we make sure that we are using the debug version
+# of the server. This is needed because in the debug version (the one without
+# DBUG_OFF defined) the abort_plugin_process() function calls DBUG_SUICIDE()
+# which does not send a SIGABRT to itself but a SIGKILL instead (and in this way
+# MTR won't assume the process crashed).
+--source include/have_debug.inc
+--source include/big_test.inc
+--source include/not_valgrind.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Error, maximum number of retries exceeded when waiting for the internal server session state to be operating");
+call mtr.add_suppression("Failed to establish an internal server connection to execute plugin operations");
+call mtr.add_suppression("Error when extracting information for group change. Operations and checks made to group joiners may be incomplete.");
+call mtr.add_suppression("Member version is incompatible with the group.");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Simulate a higher version on M1.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET @debug_saved= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_compatibility_higher_major_version';
+--source ../inc/start_and_bootstrap_group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Try to join M2 to the group.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Save all the context we'll need during the test
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_lower_version.2.err
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+# Restart the server with group_replication_start_on_boot enabled
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+# Reestablish the connection to the server
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) M2 should be in super_read_only mode and in OFFLINE state (since it
+--echo # failed to join the group).
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that it went to super_read_only mode
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Verify that the expected error occurred
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected incompatibility on member version
+--let $assert_select = Member version is incompatible with the group
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Change the exit_state_action to ABORT_SERVER. Try to join M2 to the
+--echo # group again.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart the server again with group_replication_start_on_boot enabled and with
+# group_replication_exit_state_action set to ABORT_SERVER
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --group_replication_exit_state_action=ABORT_SERVER
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) M2 should have abort()ed.
+--echo #########################################################################
+--echo
+# Wait for server 1 to see that server 2 didn't join
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Wait until server 2 is connected again, so we know it has abort()'ed
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source include/wait_until_connected_again.inc
+# Search for the expected errors in the error log file
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected incompatibility on member version
+--let $assert_select = Member version is incompatible with the group
+--let $assert_count = 2
+--source include/assert_grep.inc
+--let $assert_text = GR reported expected abort
+--let $assert_select = The plugin encountered a critical error and will abort
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Restart M2 again without group_replication_start_on_boot enabled.
+--echo # The server should start normally and be able to join the group.
+--echo #########################################################################
+--echo
+# Restore the debug sysvar to its original state on server 1, so that we may
+# finally join server 2
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET @@GLOBAL.DEBUG = @debug_saved;
+# We must restart the GR plugin because updates on the debug sysvar are not
+# automatically reflected on the plugin if it is already running
+--source include/stop_group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart server 2 again, now with group_replication_start_on_boot disabled
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 7) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_members_exceeded-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_members_exceeded-slave.opt
new file mode 100644
index 000000000000..5ad7d4d892de
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_members_exceeded-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_members_exceeded.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_members_exceeded.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_members_exceeded.test
new file mode 100644
index 000000000000..961ad263595e
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_members_exceeded.test
@@ -0,0 +1,195 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs upon joining the group (in this case, number of members
+# exceeded).
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Simulate a group of 10 members when member 2 joins. Member 2 will be
+# unable to join.
+# 2) Verify that member 2 was sent to super_read_only mode and in OFFLINE
+# state (since it failed to join the group).
+# 3) Set the exit_state_aciton on member 2 to ABORT_SERVER and simulate again
+# a group of 10 members when member 2 joins. Member 2 will be unable to
+# join again.
+# 4) Member 2 will have abort()ed.
+# 5) Restart M2 again without group_replication_start_on_boot enabled. The
+# server should start normally and be able to join the group.
+# 6) Cleanup.
+#
+################################################################################
+# By including have_debug.inc we make sure that we are using the debug version
+# of the server. This is needed because in the debug version (the one without
+# DBUG_OFF defined) the abort_plugin_process() function calls DBUG_SUICIDE()
+# which does not send a SIGABRT to itself but a SIGKILL instead (and in this way
+# MTR won't assume the process crashed).
+--source include/have_debug.inc
+--source include/big_test.inc
+--source include/not_valgrind.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 1 member (M1).
+--echo #########################################################################
+--echo
+--let $allow_rpl_inited=1
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("Error, maximum number of retries exceeded when waiting for the internal server session state to be operating");
+call mtr.add_suppression("Failed to establish an internal server connection to execute plugin operations");
+call mtr.add_suppression("Error when extracting information for group change. Operations and checks made to group joiners may be incomplete");
+call mtr.add_suppression("The START GROUP_REPLICATION command failed since the group already has 9 members.");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Simulate a group of 10 members when member 2 joins. Member 2 will
+--echo # be unable to join.
+--echo #########################################################################
+--echo
+# Save all the context we'll need during the test
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_members_exceeded.2.err
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+# Restart server 2 with group_replication_start_on_boot enabled and with the
+# group_replication_set_number_of_members_on_view_changed_to_10 debug var
+# enabled, so that we simulate this test's scenario
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --loose-debug="+d,group_replication_set_number_of_members_on_view_changed_to_10"
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+# Reestablish the connection to the server
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Verify that member 2 was sent to super_read_only mode and in OFFLINE
+--echo # state (since it failed to join the group).
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that it went to super_read_only mode
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Verify that the expected error occurred
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected excess of members in group
+--let $assert_select = The START GROUP_REPLICATION command failed since the group already has 9 members
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Set the exit_state_action to ABORT_SERVER and simulate again a
+--echo # group of 10 members when member 2 joins. Member 2 will be unable to
+--echo # join again.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart the server again with group_replication_start_on_boot enabled and with
+# group_replication_exit_state_action set to ABORT_SERVER
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --loose-debug="+d,group_replication_set_number_of_members_on_view_changed_to_10" --group_replication_exit_state_action=ABORT_SERVER
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Member 2 will have abort()ed.
+--echo #########################################################################
+--echo
+# Wait for server 1 to see that server 2 didn't join
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Wait until server 2 is connected again, so we know it has abort()'ed
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source include/wait_until_connected_again.inc
+# Search for the expected errors in the error log file
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected excess of members in group
+--let $assert_select = The START GROUP_REPLICATION command failed since the group already has 9 members
+--let $assert_count = 2
+--source include/assert_grep.inc
+--let $assert_text = GR reported expected abort
+--let $assert_select = The plugin encountered a critical error and will abort
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Restart M2 again without group_replication_start_on_boot enabled.
+--echo # The server should start normally and be able to join the group.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart server 2 again, now with group_replication_start_on_boot disabled
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_transaction_mismatch-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_transaction_mismatch-slave.opt
new file mode 100644
index 000000000000..74c2d2c6423c
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_transaction_mismatch-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_transaction_mismatch.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_transaction_mismatch.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_transaction_mismatch.test
new file mode 100644
index 000000000000..2512347eb2f1
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_transaction_mismatch.test
@@ -0,0 +1,210 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs upon joining the group (in this case, when the joining
+# member's transaction set is not a subset of the group's transaction set).
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Run a few transactions on M2.
+# 2) Restart M2 with start_on_boot enabled.
+# 3) M2 should go to super_read_only mode and to OFFLINE state (since it
+# failed to join the group).
+# 4) Restart M2 with start_on_boot enabled and exit_state_action set to
+# ABORT_SERVER.
+# 5) M2 should have abort()'ed.
+# 6) Restart M2 again without group_replication_start_on_boot enabled. The
+# server should start normally and be able to join the group.
+# 7) Cleanup.
+#
+################################################################################
+# By including have_debug.inc we make sure that we are using the debug version
+# of the server. This is needed because in the debug version (the one without
+# DBUG_OFF defined) the abort_plugin_process() function calls DBUG_SUICIDE()
+# which does not send a SIGABRT to itself but a SIGKILL instead (and in this way
+# MTR won't assume the process crashed).
+--source include/have_debug.inc
+--source include/big_test.inc
+--source include/not_valgrind.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+call mtr.add_suppression("This member has more executed transactions than those present in the group. Local transactions*");
+call mtr.add_suppression("The member contains transactions not present in the group. The member will now exit the group");
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Run a few transactions on M2.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+CREATE TABLE t3(a INT PRIMARY KEY);
+INSERT INTO t3 VALUES (2);
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $errand_transaction_uuid= aaaaaaaa-bbbb-aaaa-bbbb-aaaaaaaaaaaa
+# Advance GTID_NEXT so that we have a clashing transaction with server 1
+--eval SET GTID_NEXT= "$errand_transaction_uuid:1"
+CREATE TABLE t2(a INT PRIMARY KEY);
+SET GTID_NEXT= "AUTOMATIC";
+
+--echo
+--echo #########################################################################
+--echo # 2) Restart M2 with start_on_boot enabled.
+--echo #########################################################################
+--echo
+# Save all the context we'll need during the test
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_transaction_mismatch.2.err
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+# Restart the server with group_replication_start_on_boot enabled
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+# Reestablish the connection to the server
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) M2 should go to super_read_only mode.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that super_read_only mode reverted to its original state
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Verify that the expected error occurred
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected transaction mismatch
+--let $assert_select = This member has more executed transactions than those present in the group
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Restart M2 with start_on_boot enabled and exit_state_action set to
+--echo # ABORT_SERVER.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart the server again with group_replication_start_on_boot enabled and with
+# group_replication_exit_state_action set to ABORT_SERVER
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --group_replication_exit_state_action=ABORT_SERVER
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) M2 should have abort()'ed.
+--echo #########################################################################
+--echo
+# Wait for server 1 to see that server 2 didn't join
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Wait until server 2 is connected again, so we know it has abort()'ed
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source include/wait_until_connected_again.inc
+# Search for the expected errors in the error log file
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected transaction mismatch
+--let $assert_select = This member has more executed transactions than those present in the group
+--let $assert_count = 2
+--source include/assert_grep.inc
+--let $assert_text = GR reported expected abort
+--let $assert_select = The plugin encountered a critical error and will abort
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Restart M2 again without group_replication_start_on_boot enabled.
+--echo # The server should start normally and be able to join the group.
+--echo #########################################################################
+--echo
+# Delete all transations on server 2's binary log, so that we may join the group
+# finally
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+RESET MASTER;
+# Restart server 2 again, now with group_replication_start_on_boot disabled
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 7) Cleanup.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+DROP TABLE t3;
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET sql_log_bin = 0;
+DROP TABLE t2;
+SET sql_log_bin = 1;
+--source ../inc/group_replication_end.inc
+
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size-slave.opt
new file mode 100644
index 000000000000..7b26c0aa61a5
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.test
new file mode 100644
index 000000000000..aebca00a0e46
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.test
@@ -0,0 +1,179 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs upon joining the group (in this case, when the
+# group_replication_gtid_assignment_block_size value on a joining member
+# differs from the group).
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Relaunch M2 with a different gtid_assignment_block_size from M1.
+# 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+# 3) Relaunch M2 with a different gtid_assignment_block_size from M1 and with
+# exit_state_action set to ABORT_SERVER.
+# 4) M2 should have abort()ed.
+# 5) Restart M2 again without group_replication_start_on_boot enabled. The
+# server should start normally and be able to join the group.
+# 6) Cleanup.
+#
+################################################################################
+--source include/have_debug.inc
+--source include/not_valgrind.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Unable to start Group Replication on boot");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Relaunch M2 with a different gtid_assignment_block_size from M1.
+--echo #########################################################################
+--echo
+# We need a different value to trigger a group incompatibility
+--let $gtid_assignment_block_size = `SELECT @@GLOBAL.group_replication_gtid_assignment_block_size`
+--inc $gtid_assignment_block_size
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Save all the context we'll need during the test
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_wrong_gtid_assignment_block_size.2.err
+--let $member2_uuid=`SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+# Restart the server with group_replication_start_on_boot enabled
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --group_replication_gtid_assignment_block_size=$gtid_assignment_block_size
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $gtid_assignment_block_size GROUP_REPLICATION_GTID_ASSIGNMENT_BLOCK_SIZE $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+# Reestablish the connection to the server
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+--echo # failed to join the group).
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that it went to super_read_only mode
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Verify that the expected error occurred
+--let $assert_file = $error_file
+--let $assert_text = GR reported that it has a different gtid_assignment_block_size value (as expected)
+--let $assert_select = The member is configured with a group_replication_gtid_assignment_block_size option value .+ different from the group
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Relaunch M2 with a different gtid_assignment_block_size from M1 and
+--echo # with exit_state_action set to ABORT_SERVER.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart the server again with group_replication_start_on_boot enabled and with
+# group_replication_exit_state_action set to ABORT_SERVER
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --group_replication_gtid_assignment_block_size=$gtid_assignment_block_size --group_replication_exit_state_action=ABORT_SERVER
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $gtid_assignment_block_size GROUP_REPLICATION_GTID_ASSIGNMENT_BLOCK_SIZE $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) M2 should have abort()ed.
+--echo #########################################################################
+--echo
+# Wait for server 1 to see that server 2 didn't join
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Wait until server 2 is connected again, so we know it has abort()'ed
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source include/wait_until_connected_again.inc
+# Search for the expected errors in the error log file
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported that it has a different gtid_assignment_block_size value (as expected)
+--let $assert_select = The member is configured with a group_replication_gtid_assignment_block_size option value .+ different from the group
+--let $assert_count = 2
+--source include/assert_grep.inc
+--let $assert_text = GR reported expected abort
+--let $assert_select = The plugin encountered a critical error and will abort
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Restart M2 again without group_replication_start_on_boot enabled.
+--echo # The server should start normally and be able to join the group.
+--echo #########################################################################
+--echo
+# Restart server 2 again, now with group_replication_start_on_boot disabled
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
+
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_hash_algorithm-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_hash_algorithm-slave.opt
new file mode 100644
index 000000000000..7d658993a2f6
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_hash_algorithm-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_wrong_hash_algorithm.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_hash_algorithm.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_hash_algorithm.test
new file mode 100644
index 000000000000..d53754fb1a9a
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_hash_algorithm.test
@@ -0,0 +1,192 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs upon joining the group (in this case, when the
+# transaction_write_set_extraction value on a joining member differs from
+# the group).
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Relaunch M2 with a different hash algorithm from M1.
+# 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+# 3) Relaunch M2 with a different hash algorithm from M1 and with
+# exit_state_action set to ABORT_SERVER.
+# 4) M2 should have abort()ed.
+# 5) Restart M2 again without group_replication_start_on_boot enabled. The
+# server should start normally and be able to join the group.
+# 6) Cleanup.
+#
+################################################################################
+# By including have_debug.inc we make sure that we are using the debug version
+# of the server. This is needed because in the debug version (the one without
+# DBUG_OFF defined) the abort_plugin_process() function calls DBUG_SUICIDE()
+# which does not send a SIGABRT to itself but a SIGKILL instead (and in this way
+# MTR won't assume the process crashed).
+--source include/have_debug.inc
+--source include/not_valgrind.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $group_hash_algorithm = `SELECT @@GLOBAL.transaction_write_set_extraction`
+
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Unable to start Group Replication on boot");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Relaunch M2 with a different hash algorithm from M1.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Save all the context we'll need during the test
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_wrong_hash_algorithm.2.err
+--let $member2_uuid=`SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+
+# Choose a hash algorithm that clashes with the group
+--let $hash_algorithm = XXHASH64
+if ($group_hash_algorithm == 'XXHASH64')
+{
+ --let $hash_algorithm = MURMUR32
+}
+
+# Restart the server with group_replication_start_on_boot enabled
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --transaction-write-set-extraction=$hash_algorithm
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME $hash_algorithm HASH_ALGORITHM
+--source include/restart_mysqld.inc
+
+# Reestablish the connection to the server
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+--echo # failed to join the group).
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that it went to super_read_only mode
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Verify that the expected error occurred
+--let $assert_file = $error_file
+--let $assert_text = GR reported that it has an incompatible option with the group (as expected)
+--let $assert_select = The member is configured with a transaction-write-set-extraction option value .+ different from the group
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Relaunch M2 with a different hash algorithm from M1 and with
+--echo # exit_state_action set to ABORT_SERVER.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart the server again with group_replication_start_on_boot enabled and with
+# group_replication_exit_state_action set to ABORT_SERVER
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --transaction-write-set-extraction=$hash_algorithm --group_replication_exit_state_action=ABORT_SERVER
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME $hash_algorithm HASH_ALGORITHM
+--source include/restart_mysqld.inc
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) M2 should have abort()ed.
+--echo #########################################################################
+--echo
+# Wait for server 1 to see that server 2 didn't join
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Wait until server 2 is connected again, so we know it has abort()'ed
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source include/wait_until_connected_again.inc
+# Search for the expected errors in the error log file
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported that it has an incompatible option with the group (as expected)
+--let $assert_select = The member is configured with a transaction-write-set-extraction option value .+ different from the group
+--let $assert_count = 2
+--source include/assert_grep.inc
+--let $assert_text = GR reported expected abort
+--let $assert_select = The plugin encountered a critical error and will abort
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Restart M2 again without group_replication_start_on_boot enabled.
+--echo # The server should start normally and be able to join the group.
+--echo #########################################################################
+--echo
+# Restart server 2 again, now with group_replication_start_on_boot disabled
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME $hash_algorithm HASH_ALGORITHM
+--source include/restart_mysqld.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
+
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_single_primary_mode-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_single_primary_mode-slave.opt
new file mode 100644
index 000000000000..b25913444c1b
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_single_primary_mode-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_wrong_single_primary_mode.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_single_primary_mode.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_single_primary_mode.test
new file mode 100644
index 000000000000..45337b15b855
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_join_wrong_single_primary_mode.test
@@ -0,0 +1,181 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs upon joining the group (in this case, when the
+# group_replication_single_primary_mode sysvar value on a joining member
+# differs from the group).
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Relaunch M2 with a different single_primary_mode from M1.
+# 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+# 3) Relaunch M2 with a different single_primary_mode from M1 and with
+# exit_state_action set to ABORT_SERVER.
+# 4) M2 should have abort()ed.
+# 5) Restart M2 again without group_replication_start_on_boot enabled. The
+# server should start normally and be able to join the group.
+# 6) Cleanup.
+#
+################################################################################
+# By including have_debug.inc we make sure that we are using the debug version
+# of the server. This is needed because in the debug version (the one without
+# DBUG_OFF defined) the abort_plugin_process() function calls DBUG_SUICIDE()
+# which does not send a SIGABRT to itself but a SIGKILL instead (and in this way
+# MTR won't assume the process crashed).
+--source include/have_debug.inc
+--source include/big_test.inc
+--source include/not_valgrind.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication");
+call mtr.add_suppression("Unable to start Group Replication on boot");
+call mtr.add_suppression("Timeout on wait for view after joining group");
+call mtr.add_suppression("\\[GCS\\] Error connecting to all peers. Member join failed.*");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("\\[GCS\\] The member was unable to join the group.*");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Relaunch M2 with a different single_primary_mode from M1.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Save all the context we'll need during the test
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_join_wrong_single_primary_mode.2.err
+--let $member2_uuid=`SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+# Restart the server with group_replication_start_on_boot enabled
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --group_replication_single_primary_mode=FALSE --group_replication_enforce_update_everywhere_checks=FALSE
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+# Reestablish the connection to the server
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) M2 should be in super_read_only mode and in OFFLINE state (since it
+--echo # failed to join the group).
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Verify that it went to super_read_only mode
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported that it has an incompatible option with the group (as expected)
+--let $assert_select = The member configuration is not compatible with the group configuration. Variables such as single_primary_mode or enforce_update_everywhere_checks must have the same value
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Relaunch M2 with a different single_primary_mode from M1 and with
+--echo # exit_state_action set to ABORT_SERVER.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Restart the server again with group_replication_start_on_boot enabled and with
+# group_replication_exit_state_action set to ABORT_SERVER
+--let $allow_rpl_inited = 1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name --group_replication_start_on_boot=1 --group_replication_single_primary_mode=TRUE --group_replication_exit_state_action=ABORT_SERVER --group_replication_enforce_update_everywhere_checks=FALSE
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) M2 should have abort()ed.
+--echo #########################################################################
+--echo
+# Wait for server 1 to see that server 2 didn't join
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+# Wait until server 2 is connected again, so we know it has abort()'ed
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source include/wait_until_connected_again.inc
+# Search for the expected errors in the error log file
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $assert_file = $error_file
+--let $assert_text = GR reported that it has an incompatible option with the group (as expected)
+--let $assert_select = The member configuration is not compatible with the group configuration. Variables such as single_primary_mode or enforce_update_everywhere_checks must have the same value
+--let $assert_count = 2
+--source include/assert_grep.inc
+--let $assert_text = GR reported expected abort
+--let $assert_select = The plugin encountered a critical error and will abort
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Restart M2 again without group_replication_start_on_boot enabled.
+--echo # The server should start normally and be able to join the group.
+--echo #########################################################################
+--echo
+# Restart server 2 again, now with group_replication_start_on_boot disabled
+--let $allow_rpl_inited=1
+--let $restart_parameters=restart:--group_replication_local_address=$local_address_server2 --group_replication_group_seeds=$group_seeds_server2 --group-replication-group-name=$group_replication_group_name
+--replace_result $local_address_server2 GROUP_REPLICATION_LOCAL_ADDRESS $group_seeds_server2 GROUP_REPLICATION_GROUP_SEEDS $group_replication_group_name GROUP_REPLICATION_GROUP_NAME
+--source include/restart_mysqld.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
+
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_majority_loss.cnf b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_majority_loss.cnf
new file mode 100644
index 000000000000..e0b8e81174ec
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_majority_loss.cnf
@@ -0,0 +1,13 @@
+!include ../my.cnf
+
+[mysqld.1]
+group_replication_unreachable_majority_timeout= 10
+
+[mysqld.2]
+
+[mysqld.3]
+report-port= @mysqld.3.port
+
+[ENV]
+SERVER_MYPORT_3= @mysqld.3.port
+SERVER_MYSOCK_3= @mysqld.3.socket
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_majority_loss.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_majority_loss.test
new file mode 100644
index 000000000000..c06197aa10b8
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_majority_loss.test
@@ -0,0 +1,228 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken
+# by a server once it has involuntarily left the group. Currently there are
+# only two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# In order to verify the expected behaviour, this test shall test that the
+# specified exit action is executed correctly after a member can't contact the
+# rest of the group after group_replication_unreachable_timeout ellapsed.
+#
+# Test:
+# 0) Setup group of 3 members (M1, M2 and M3).
+# 1) Force majority loss.
+# 1.1) Verify that member 1 went to ERROR state.
+# 2) Relaunch group with exit state action to ABORT_SERVER.
+# 3) Force another majority loss.
+# 4) Verify that member 1 aborted.
+# 5) Relaunch all members.
+# 6) Cleanup.
+#
+################################################################################
+--source include/big_test.inc
+--source include/have_debug.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 3 members (M1, M2 and M3).
+--echo #########################################################################
+--echo
+--let $rpl_server_count= 3
+--source ../inc/group_replication.inc
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+# Supress log errors since they are expected.
+call mtr.add_suppression("read failed");
+call mtr.add_suppression("This member could not reach a majority of the members for more than.*");
+call mtr.add_suppression("The server was automatically set into read only mode after an error was detected.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("\\[GCS\\] Timeout while waiting for the group communication engine to exit!");
+call mtr.add_suppression("\\[GCS\\] The member has failed to gracefully leave the group.");
+call mtr.add_suppression("\\[GCS\\] read failed");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+
+# Get address, seeds and UUID of all servers
+--let $local_address_server1= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server1= `SELECT @@GLOBAL.group_replication_group_seeds`
+--let $member1_uuid= `SELECT @@GLOBAL.server_uuid`
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+--let $member2_uuid= `SELECT @@GLOBAL.server_uuid`
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+--let $local_address_server3= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server3= `SELECT @@GLOBAL.group_replication_group_seeds`
+--let $member3_uuid= `SELECT @@GLOBAL.server_uuid`
+
+--echo
+--echo #########################################################################
+--echo # 1) Force majority loss.
+--echo #########################################################################
+--echo
+# Crash server 2
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--enable_reconnect
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--shutdown_server 0
+--source include/wait_until_disconnected.inc
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+# Crash server 3
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+--enable_reconnect
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.3.expect
+--shutdown_server 0
+--source include/wait_until_disconnected.inc
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+--echo
+--echo #########################################################################
+--echo # 1.1) Verify that member 1 went to ERROR state.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_member_state= ERROR
+--let $group_replication_member_id= $member1_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that it enabled super_read_only
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Relaunch group with exit state action to ABORT_SERVER.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+
+--source include/stop_group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+
+# First we relaunch server 2 and 3
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+
+--replace_result $group_seeds_server2 GROUP_SEEDS_SERVER2
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server2"
+--replace_result $local_address_server2 LOCAL_ADDRESS_SERVER2
+--eval SET @@global.group_replication_local_address="$local_address_server2"
+--source include/start_group_replication.inc
+
+--let $rpl_server_number= 3
+--source include/rpl_reconnect.inc
+
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+
+--replace_result $group_seeds_server3 GROUP_SEEDS_SERVER3
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server3"
+--replace_result $local_address_server3 LOCAL_ADDRESS_SERVER3
+--eval SET @@global.group_replication_local_address="$local_address_server3"
+--source include/start_group_replication.inc
+
+# Wait for everyone to settle down
+--let $group_replication_number_of_members= 3
+--source ../inc/gr_wait_for_number_of_members.inc
+
+# Then we set server 1's exit_state_action to ABORT_SERVER
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+
+# Set the exit state action sysvar to ABORT_SERVER
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+
+--echo
+--echo #########################################################################
+--echo # 3) Force another majority loss.
+--echo #########################################################################
+--echo
+# Prevent server 1 from restart after the abort()
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--enable_reconnect
+# Crash server 2
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--enable_reconnect
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+--shutdown_server 0
+--source include/wait_until_disconnected.inc
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+# Crash server 3
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+--enable_reconnect
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.3.expect
+--shutdown_server 0
+--source include/wait_until_disconnected.inc
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+--echo
+--echo #########################################################################
+--echo # 4) Verify that member 1 aborted.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+# Wait until the connection is dropped
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Relaunch all members.
+--echo #########################################################################
+--echo
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--let $rpl_server_number= 1
+--source include/rpl_reconnect.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--replace_result $group_seeds_server1 GROUP_SEEDS_SERVER1
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server1"
+--replace_result $local_address_server1 LOCAL_ADDRESS_SERVER1
+--eval SET @@global.group_replication_local_address="$local_address_server1"
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $rpl_server_number= 2
+--source include/rpl_reconnect.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--replace_result $group_seeds_server2 GROUP_SEEDS_SERVER2
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server2"
+--replace_result $local_address_server2 LOCAL_ADDRESS_SERVER2
+--eval SET @@global.group_replication_local_address="$local_address_server2"
+--source include/start_group_replication.inc
+--let $rpl_server_number= 3
+--source include/rpl_reconnect.inc
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+--replace_result $group_seeds_server3 GROUP_SEEDS_SERVER3
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server3"
+--replace_result $local_address_server3 LOCAL_ADDRESS_SERVER3
+--eval SET @@global.group_replication_local_address="$local_address_server3"
+--source include/start_group_replication.inc
+# Wait for everyone to settle down
+--let $group_replication_number_of_members= 3
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_member_expel.cnf b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_member_expel.cnf
new file mode 100644
index 000000000000..044d8038024f
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_member_expel.cnf
@@ -0,0 +1,13 @@
+!include ../my.cnf
+
+[mysqld.1]
+local-infile= true
+
+[mysqld.2]
+
+[mysqld.3]
+report-port= @mysqld.3.port
+
+[ENV]
+SERVER_MYPORT_3= @mysqld.3.port
+SERVER_MYSOCK_3= @mysqld.3.socket
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_member_expel.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_member_expel.test
new file mode 100644
index 000000000000..80820c51a4fe
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_member_expel.test
@@ -0,0 +1,171 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# In order to verify the expected behaviour, this test shall test that the
+# specified exit action is executed correctly after an expel by the other
+# members of the group.
+#
+# Test:
+# 0) Setup group of 3 members (M1, M2 and M3).
+# 1) Force expel of member 1.
+# 1.1) Verify that member 1 went to super_read_only mode.
+# 2) Relaunch member 1 with exit state action to ABORT_SERVER.
+# 3) Force expel again of member 1.
+# 3.1) Verify that member 1 aborted.
+# 4) Relaunch member 1.
+# 5) Cleanup.
+#
+################################################################################
+# Test involves sending SIGSTOP and SIGCONT signals using kill Linux command.
+--source include/linux.inc
+--source include/have_debug.inc
+--source include/not_valgrind.inc
+--source include/big_test.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 3 members (M1, M2 and M3).
+--echo #########################################################################
+--echo
+--let $rpl_server_count= 3
+--source ../inc/group_replication.inc
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+CREATE TABLE pid_table(pid_no INT PRIMARY KEY);
+--let $pid_file=`SELECT @@pid_file`
+--replace_result $pid_file pid_file
+--eval LOAD DATA LOCAL INFILE '$pid_file' INTO TABLE pid_table
+--let $server_pid=`SELECT pid_no FROM pid_table`
+DROP TABLE pid_table;
+
+# Supress log errors since they are expected.
+call mtr.add_suppression("Member was expelled from the group due to network failures, changing member status to ERROR.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+SET SESSION sql_log_bin = 1;
+
+--let $member1_uuid= `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server1= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server1= `SELECT @@GLOBAL.group_replication_group_seeds`
+
+
+--echo
+--echo #########################################################################
+--echo # 1) Force expel of member 1.
+--echo #########################################################################
+--echo
+# Then we send a SIGSTOP to it. This will stop the server from sending the
+# keep-alive message and thus it will be viewed as a faulty node by the rest of
+# the group (and consequently expelled).
+--exec kill -19 $server_pid
+
+# Wait until the group settles on 2 members
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 1.1) Verify that member 1 went to super_read_only mode.
+--echo #########################################################################
+--echo
+# Send SIGCONT to server, so it can continue (now that he is expelled)
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--exec kill -18 $server_pid
+
+# Verify that the member entered an error state
+--let $group_replication_member_state= ERROR
+--let $group_replication_member_id= $member1_uuid
+--source ../inc/gr_wait_for_member_state.inc
+
+# Then verify that it enabled super_read_only
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+--source include/stop_group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Set exit state action to ABORT_SERVER on member 1.
+--echo #########################################################################
+--echo
+# Set the exit state action sysvar to ABORT_SERVER
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 3
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Force expel again of member 1.
+--echo #########################################################################
+--echo
+# Inform MTR that we are expecting an abort and that it should wait before
+# restarting the aborting member
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+# Send SIGSTOP again
+--exec kill -19 $server_pid
+# Wait until the group settles on 2 members
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server3
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 3.1) Wait until server is aborted.
+--echo #########################################################################
+--echo
+# Send SIGCONT to server, so it can continue (now that he is expelled)
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--exec kill -18 $server_pid
+# Wait until the connection is dropped
+--source include/wait_until_disconnected.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Relaunch member 1.
+--echo #########################################################################
+--echo
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--let $rpl_server_number= 1
+--source include/rpl_reconnect.inc
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--replace_result $group_seeds_server1 GROUP_SEEDS_SERVER1
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server1"
+--replace_result $local_address_server1 LOCAL_ADDRESS_SERVER1
+--eval SET @@global.group_replication_local_address="$local_address_server1"
+--source include/start_group_replication.inc
+# Wait for member to stabilize in the group
+--let $group_replication_number_of_members = 3
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Cleanup.
+--echo #########################################################################
+--echo
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery.cnf b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery.cnf
new file mode 100644
index 000000000000..44721a61a6d6
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery.cnf
@@ -0,0 +1,6 @@
+!include ../my.cnf
+
+[mysqld.1]
+loose-group_replication_recovery_retry_count= 1
+
+[mysqld.2]
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery.test
new file mode 100644
index 000000000000..27be646fac6e
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery.test
@@ -0,0 +1,179 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs during the catch-up phase of distributed recovery.
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Force error during the catch-up phase of M1.
+# 1.1) Verify that M1 goes into ERROR state and to super_read_only mode.
+# 2) Set group_replication_exit_state_action to ABORT_SERVER on M1.
+# 3) Force another error during the catch-up phase of M1.
+# 3.1) Verify that M1 aborted.
+# 4) Relaunch M1 and join the group.
+# 5) Cleanup.
+#
+################################################################################
+--source include/have_debug.inc
+--source include/not_valgrind.inc
+--source include/big_test.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2) but only start GR on M2.
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start= 1
+--source ../inc/group_replication.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $member1_uuid= `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server1= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server1= `SELECT @@GLOBAL.group_replication_group_seeds`
+# Create a table on M1 while it isn't part of the group
+SET sql_log_bin = 0;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+SET sql_log_bin = 1;
+# Bootstrap the rest of the group (minus M1)
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+# Suppress expected errors and warnings
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET sql_log_bin = 0;
+call mtr.add_suppression("read failed");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_recovery': Error 'Table 't1'*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_recovery': Worker [0-9] failed executing transaction*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_recovery': ... The slave coordinator and worker threads are stopped,*");
+call mtr.add_suppression("Slave: Table 't1' already exists Error_code:*");
+call mtr.add_suppression("Maximum number of retries when trying to connect to a donor reached. Aborting group replication recovery.");
+call mtr.add_suppression("Fatal error during the recovery process of Group Replication. The server will leave the group.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("Fatal error during execution of Group Replication");
+call mtr.add_suppression("Error while starting the group replication recovery receiver/applier threads");
+SET sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Force error during the catch-up phase of M1.
+--echo #########################################################################
+--echo
+# Create and replicate a table on the group
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+CREATE TABLE t1 (a INT PRIMARY KEY);
+# Add M1 to the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_start_member_state= ERROR
+--source include/start_group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 1.1) Verify that M1 goes into ERROR state and to super_read_only mode.
+--echo #########################################################################
+--echo
+# Firstly verify that the member entered an error state
+--let $group_replication_member_state= ERROR
+--let $group_replication_member_id= $member1_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Then verify that it enabled super_read_only
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = 1;
+--source include/assert.inc
+# Lastly, verify that the member is not viewed as part of the group on M2 and
+# M3
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Set group_replication_exit_state_action to ABORT_SERVER on M1.
+--echo #########################################################################
+--echo
+# Stop GR
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--source include/stop_group_replication.inc
+
+# Set the exit state action sysvar to ABORT_SERVER
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+
+--echo
+--echo #########################################################################
+--echo # 3) Force another error during the catch-up phase of M1.
+--echo #########################################################################
+--echo
+# Inform MTR that we are expecting an abort and that it should wait before
+# restarting the aborting member
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Join the group again
+--let $group_replication_start_member_state= ERROR
+--source include/start_group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 3.1) Verify that M1 aborted.
+--echo #########################################################################
+--echo
+# For simplicity, let's assume that once the group size is 1, then member 1 has
+# abort()'ed
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+# Also, the member should not be in the group view of any of the other members
+--let $assert_text = Member 1 should have aborted
+--let $assert_cond = COUNT(*) = 0 FROM performance_schema.replication_group_members WHERE MEMBER_ID = "$member1_uuid"
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Relaunch M1 and join the group.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--source include/wait_until_disconnected.inc
+# Inform MTR that it should restart the aborted member
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+# Reconnect
+--let $rpl_server_number= 1
+--source include/rpl_reconnect.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+# Remove conflicting trx so M1 can stay in the group
+SET SESSION sql_log_bin= 0;
+DROP TABLE t1;
+SET SESSION sql_log_bin= 1;
+RESET MASTER;
+--replace_result $group_seeds_server1 GROUP_SEEDS_SERVER1
+--eval SET @@global.group_replication_group_seeds="$group_seeds_server1"
+--replace_result $local_address_server1 LOCAL_ADDRESS_SERVER1
+--eval SET @@global.group_replication_local_address="$local_address_server1"
+--source include/start_group_replication.inc
+# Wait for group to stabilize
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Cleanup.
+--echo #########################################################################
+--echo
+DROP TABLE t1;
+
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery_stage0-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery_stage0-slave.opt
new file mode 100644
index 000000000000..72b8d36d8720
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery_stage0-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_recovery_stage0.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery_stage0.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery_stage0.test
new file mode 100644
index 000000000000..1d1fa7f4f8b2
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_recovery_stage0.test
@@ -0,0 +1,203 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that the correct exit state action is executed when
+# an error occurs during the stage 0 of distributed recovery.
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Stop the applier on M2.
+# 2) Replicate TRX from M1 to M2 but without M2 applying it.
+# 3) Stop GR on M2.
+# 4) Start GR on M2 again so he tries to join the group. M2 should go to
+# OFFLINE state.
+# 5) Set group_replication_exit_state_action sysvar to ABORT_SERVER on M2.
+# 6) Start GR on M2 again, so he tries to join the group. M2 should not abort.
+# 7) Cleanup.
+#
+################################################################################
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/big_test.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 3 members (M1, M2 and M3).
+--echo #########################################################################
+--echo
+--source ../inc/group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+--let $member2_uuid= `SELECT @@GLOBAL.server_uuid`
+--let $local_address_server2= `SELECT @@GLOBAL.group_replication_local_address`
+--let $group_seeds_server2= `SELECT @@GLOBAL.group_replication_group_seeds`
+
+# Suppress expected errors and warnings
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_recovery_stage0.2.err
+
+SET sql_log_bin = 0;
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Error 'Table 't1'*");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Worker [0-9] failed executing transaction*");
+call mtr.add_suppression("Error writing relay log configuration.");
+call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': ... The slave coordinator and worker threads are stopped,*");
+call mtr.add_suppression("Slave: Table 't1' already exists Error_code:*");
+call mtr.add_suppression("The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.");
+call mtr.add_suppression("Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.");
+call mtr.add_suppression("Unable to confirm whether the server has left the group or not. Check performance_schema.replication_group_members to check group membership information.");
+call mtr.add_suppression("There was a previous plugin error while the member joined the group. The member will now exit the group.");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
+SET sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Stop the applier on M2.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+
+--source ../inc/gr_stop_applier_sql_thread.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Replicate TRX from M1 to M2 but without M2 applying it.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY);
+
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+
+# Verify that M2 certified one transaction but hasn't yet applied any
+--let $wait_condition= SELECT COUNT(*) = 1 FROM performance_schema.replication_group_member_stats WHERE member_id='$member2_uuid' AND count_transactions_checked = 1
+--source include/wait_condition.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Stop GR on M2.
+--echo #########################################################################
+--echo
+--source include/stop_group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Start GR on M2 again so he tries to join the group.
+--echo #########################################################################
+--echo
+SET SESSION sql_log_bin = 0;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+SET SESSION sql_log_bin = 1;
+
+# Start GR
+--error ER_GROUP_REPLICATION_CONFIGURATION,ER_GROUP_REPLICATION_APPLIER_INIT_ERROR
+START GROUP_REPLICATION;
+
+# Verify that the applier errored out
+--let $assert_file = $error_file
+--let $assert_text = The applier should error out trying to create an already existing table
+--let $assert_select = Error 'Table 't1' already exists' on query.
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--let $assert_file = $error_file
+--let $assert_text = The applier should error out trying to create an already existing table
+--let $assert_select = The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--let $assert_file = $error_file
+--let $assert_text = The applier should error out trying to create an already existing table
+--let $assert_select = Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+# Verify that M2 goes into OFFLINE state
+--let $group_replication_member_state= OFFLINE
+--let $group_replication_member_id= $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+
+# Lastly, verify that the member is not viewed as part of the group on M1
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 5) Set group_replication_exit_state_action sysvar to ABORT_SERVER on
+--echo # M2.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET @group_replication_exit_state_action_saved = @@GLOBAL.group_replication_exit_state_action;
+SET GLOBAL group_replication_exit_state_action = ABORT_SERVER;
+
+--echo
+--echo #########################################################################
+--echo # 6) Start GR on M2 again, so he tries to join the group. M2 should
+--echo # not abort.
+--echo #########################################################################
+--echo
+# Start GR on M2
+--error ER_GROUP_REPLICATION_CONFIGURATION,ER_GROUP_REPLICATION_APPLIER_INIT_ERROR
+START GROUP_REPLICATION;
+
+# Verify that the applier errored out
+--let $assert_file = $error_file
+--let $assert_text = The applier should error out trying to create an already existing table
+--let $assert_select = Error 'Table 't1' already exists' on query.
+--let $assert_count = 2
+--source include/assert_grep.inc
+
+--let $assert_file = $error_file
+--let $assert_text = The applier should error out trying to create an already existing table
+--let $assert_select = The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.
+--let $assert_count = 2
+--source include/assert_grep.inc
+
+--let $assert_file = $error_file
+--let $assert_text = The applier should error out trying to create an already existing table
+--let $assert_select = Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.
+--let $assert_count = 2
+--source include/assert_grep.inc
+
+# Verify that M2 goes into OFFLINE state
+--let $group_replication_member_state= OFFLINE
+--let $group_replication_member_id= $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+
+# Lastly, verify that the member is not viewed as part of the group on M1
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members= 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 7) Cleanup.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+DROP TABLE t1;
+
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+DROP TABLE t1;
+SET SESSION sql_log_bin = 1;
+SET GLOBAL group_replication_exit_state_action = @group_replication_exit_state_action_saved;
+
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_start_gr_cmd-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_start_gr_cmd-slave.opt
new file mode 100644
index 000000000000..bb2e0b8d3b33
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_start_gr_cmd-slave.opt
@@ -0,0 +1 @@
+--no-console --log_error=$MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_start_gr_cmd.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_start_gr_cmd.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_start_gr_cmd.test
new file mode 100644
index 000000000000..f056bdbac1e9
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_on_start_gr_cmd.test
@@ -0,0 +1,187 @@
+###############################################################################
+#
+# group_replication_exit_state_action sysvar specifies which action is taken by
+# a server once it has involuntarily left the group. Currently there are only
+# two actions: either the server continues running but with super_read_only
+# enabled (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test shall verify that when a join fails after issuing a START
+# GROUP_REPLICATION command, the command returns with the appropriate error
+# and does not crash or abort, even when group_replication_exit_state_action is
+# set to ABORT_SERVER.
+#
+# Test:
+# 0) Setup group of 2 members (M1 and M2).
+# 1) Simulate a higher version on M1.
+# 2) Try to join M2 to the group by issuing START GROUP_REPLICATION.
+# 3) M2 should be in super_read_only mode and in OFFLINE state (since it
+# failed to join the group).
+# 4) Change the exit_state_action to ABORT_SERVER. Try to join M2 to the group
+# again.
+# 5) M2 should not abort().
+# 6) Remove the higher version from M1 and try to join M2 again. M2 should be
+# able to join.
+# 7) Cleanup.
+#
+################################################################################
+# By including have_debug.inc we make sure that we are using the debug version
+# of the server. This is needed because in the debug version (the one without
+# DBUG_OFF defined) the abort_plugin_process() function calls DBUG_SUICIDE()
+# which does not send a SIGABRT to itself but a SIGKILL instead (and in this way
+# MTR won't assume the process crashed).
+--source include/have_debug.inc
+--source include/big_test.inc
+--source ../inc/have_group_replication_plugin.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) Setup group of 2 members (M1 and M2).
+--echo #########################################################################
+--echo
+--let $rpl_skip_group_replication_start = 1
+--source ../inc/group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Member version is incompatible with the group.");
+SET SESSION sql_log_bin = 1;
+
+--echo
+--echo #########################################################################
+--echo # 1) Simulate a higher version on M1.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET @debug_saved= @@GLOBAL.DEBUG;
+SET @@GLOBAL.DEBUG= '+d,group_replication_compatibility_higher_major_version';
+--source ../inc/start_and_bootstrap_group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Try to join M2 to the group by issuing START GROUP_REPLICATION.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Save the super_read_only mode, so we can assert the server reverted to it when
+# it failed to join the group
+SET @super_read_only_saved = @@GLOBAL.super_read_only;
+# Save the group_replication_exit_state_action
+SET @exit_state_action_saved = @@GLOBAL.group_replication_exit_state_action;
+# Save the group SID, so the server gets a member ID
+--disable_query_log
+--eval SET GLOBAL group_replication_group_name= "$group_replication_group_name"
+--enable_query_log
+# We expect a config error since this server's version is different from the
+# group
+--error ER_GROUP_REPLICATION_CONFIGURATION
+START GROUP_REPLICATION;
+
+--echo
+--echo #########################################################################
+--echo # 3) M2 should be in super_read_only mode and in OFFLINE state (since it
+--echo # failed to join the group).
+--echo #########################################################################
+--echo
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that super_read_only reverted to its original state
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = @super_read_only_saved;
+--source include/assert.inc
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_exit_state_action_on_start_gr_cmd.2.err
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected incompatibility on member version
+--let $assert_select = Member version is incompatible with the group
+--let $assert_count = 1
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Change the exit_state_action to ABORT_SERVER. Try to join M2 to the
+--echo # group again.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Set the exit state action to ABORT_SERVER
+SET @@GLOBAL.group_replication_exit_state_action = ABORT_SERVER;
+# We must restart GR to trigger another join
+# We expect a config error since this server's version is different from the
+# group
+--error ER_GROUP_REPLICATION_CONFIGURATION
+START GROUP_REPLICATION;
+
+--echo
+--echo #########################################################################
+--echo # 5) M2 should not abort().
+--echo #########################################################################
+--echo
+# Wait for the member to realize that it couldn't join the group
+--let $member2_uuid = `SELECT @@GLOBAL.server_uuid`
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $group_replication_member_state = OFFLINE
+--let $group_replication_member_id = $member2_uuid
+--source ../inc/gr_wait_for_member_state.inc
+# Verify that super_read_only reverted to its original state
+--let $assert_text= super_read_only should be enabled
+--let $assert_cond= [SELECT @@GLOBAL.super_read_only] = @super_read_only_saved;
+--source include/assert.inc
+# Verify that the expected error occurred
+--let $assert_file = $error_file
+--let $assert_text = GR reported expected incompatibility on member version
+--let $assert_select = Member version is incompatible with the group
+--let $assert_count = 2
+--source include/assert_grep.inc
+# Verify that member 2 didn't join the group
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 1
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 6) Remove the higher version from M1 and try to join M2 again. M2
+--echo # should be able to join.
+--echo #########################################################################
+--echo
+# Restore the debug sysvar to its original state on server 1, so that we may
+# finally join server 2
+SET @@GLOBAL.DEBUG = @debug_saved;
+# We must restart the GR plugin because updates on the debug sysvar are not
+# automatically reflected on the plugin if it is already running
+--source include/stop_group_replication.inc
+--source ../inc/start_and_bootstrap_group_replication.inc
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+# Start GR on server 2 and verify that the group stabilizes itself
+--source include/start_group_replication.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+--let $group_replication_number_of_members = 2
+--source ../inc/gr_wait_for_number_of_members.inc
+
+--echo
+--echo #########################################################################
+--echo # 7) Cleanup.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+SET @@GLOBAL.group_replication_exit_state_action = @exit_state_action_saved;
+
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_option.test b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_option.test
new file mode 100644
index 000000000000..6df029e31dfa
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_exit_state_action_option.test
@@ -0,0 +1,83 @@
+################################################################################
+#
+# exit_state_action sysvar specifies which action is taken by a server once it
+# has involuntarily left the group. Currently there are only two actions:
+# either the server continues running but with super_read_only enabled
+# (READ_ONLY) or it aborts (ABORT_SERVER).
+#
+# This test verifies that the sysvar behaves as expected, meaning that the
+# default value is the expected one (READ_ONLY), that we can change it
+# and the value is maintained and that invalid values result in error.
+#
+# Test:
+# 0) The test requires one server.
+# 1) Check the default value. It should be READ_ONLY.
+# 2) Set the sysvar to the possible valid values. Verify that the valid values
+# are accepted with no error and the values are set correctly.
+# 3) Set the sysvar to invalid values. There should be an error and the value of
+# the sysvar should not be altered.
+# 4) Cleanup.
+#
+################################################################################
+--source include/have_debug.inc
+--source ../inc/have_group_replication_plugin.inc
+--let $rpl_skip_group_replication_start= 1
+--source ../inc/group_replication.inc
+
+--echo
+--echo #########################################################################
+--echo # 0) The test requires one server.
+--echo #########################################################################
+--echo
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+SET @exit_state_action_saved = @@GLOBAL.group_replication_exit_state_action;
+
+--echo
+--echo #########################################################################
+--echo # 1) Check the default value. It should be READ_ONLY.
+--echo #########################################################################
+--echo
+SET @@GLOBAL.group_replication_exit_state_action = default;
+--let $assert_text= The default of group_replication_exit_state_action should be READ_ONLY
+--let $assert_cond= "[SELECT @@GLOBAL.group_replication_exit_state_action]" = "READ_ONLY"
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 2) Set the sysvar to the possible valid values.
+--echo #########################################################################
+--echo
+SET GLOBAL group_replication_exit_state_action = "READ_ONLY";
+--let $assert_text= The default of group_replication_exit_state_action should be READ_ONLY
+--let $assert_cond= "[SELECT @@GLOBAL.group_replication_exit_state_action]" = "READ_ONLY"
+--source include/assert.inc
+SET GLOBAL group_replication_exit_state_action = "ABORT_SERVER";
+--let $assert_text= The default of group_replication_exit_state_action should be ABORT_SERVER
+--let $assert_cond= "[SELECT @@GLOBAL.group_replication_exit_state_action]" = "ABORT_SERVER"
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 3) Set the sysvar to invalid values. There should be an error and the
+--echo # value of the sysvar should not be altered.
+--echo #########################################################################
+--echo
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL group_replication_exit_state_action = 42;
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL group_replication_exit_state_action = on;
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL group_replication_exit_state_action = "abort";
+SET GLOBAL group_replication_exit_state_action = "READ_ONLY";
+--let $assert_text= The default of group_replication_exit_state_action should be READ_ONLY
+--let $assert_cond= "[SELECT @@GLOBAL.group_replication_exit_state_action]" = "READ_ONLY"
+--source include/assert.inc
+
+--echo
+--echo #########################################################################
+--echo # 4) Cleanup.
+--echo #########################################################################
+--echo
+SET GLOBAL group_replication_exit_state_action = @exit_state_action_saved;
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_channel.test b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_channel.test
index 64c626cd5a7d..9885b7fa20b8 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_channel.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_channel.test
@@ -9,7 +9,7 @@
# 2. Stop replication on M1. On M2 lock a table to block recovery. Start M1.
# 3. Execute a STOP SLAVE command and see the recovery channel still active.
# 4. Execute a RESET SLAVE ALL command and see the recovery channel is not
-# affected on M1.
+# affected on M1 when GR node is active.
# 5. Kill the server M1. The recovery channel should still be there but it's
# not started. Recreate the slave channel to test that it started
# 6. Clean the created channels and tables.
@@ -84,7 +84,8 @@ STOP SLAVE;
--source include/assert.inc
#
-# Phase 4: Execute a RESET SLAVE ALL command and see the channel is not affected
+# Phase 4: Execute a RESET SLAVE ALL command and see the recovery channel is
+# not affected as GR node is active.
#
--connection server1
@@ -104,6 +105,7 @@ SET GLOBAL SUPER_READ_ONLY=0; # Bug#22097534
--let $recovery_relay_log_index= `SELECT CONCAT('$datadir_1', 'mgr-group_replication_recovery.index')`
--file_exists $recovery_relay_log_index
+--error ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED
RESET SLAVE ALL;
--let $assert_text= 'The group replication recovery channel is present'
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_lower_max_retry_count-slave.opt b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_lower_max_retry_count-slave.opt
new file mode 100644
index 000000000000..20d62c2eb30e
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_lower_max_retry_count-slave.opt
@@ -0,0 +1 @@
+--log_error=$MYSQLTEST_VARDIR/tmp/gr_recovery_lower_max_retry_count.2.err
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_lower_max_retry_count.test b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_lower_max_retry_count.test
new file mode 100644
index 000000000000..790eacd0dc3d
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_lower_max_retry_count.test
@@ -0,0 +1,103 @@
+################################################################################
+# This test verifies that recovery aborts successfully if
+# group_replication_recovery_retry_count is made smaller then connection
+# retry count in middle of recovery donor connection attempts.
+#
+# Test:
+# 0. The test requires two servers: M1 and M2.
+# 1. Bootstrap start a group on M1.
+# 2. Setup environment to fail donor connection and start GR on M2.
+# Set DEBUG on M2 to block donor connection attempt when count reaches 3.
+# Verify M2 is in recovery state.
+# 3. Reset group_replication_recovery_retry_count to 2.
+# Signal donor connection attempt to continue.
+# 4. Verification.
+# 5. Clean up.
+################################################################################
+--source include/have_debug_sync.inc
+--source ../inc/have_group_replication_plugin.inc
+--let $rpl_skip_group_replication_start= 1
+--source ../inc/group_replication.inc
+
+--let $error_file = $MYSQLTEST_VARDIR/tmp/gr_recovery_lower_max_retry_count.2.err
+
+--echo
+--echo # 1. Bootstrap start a group on M1.
+--echo
+
+--let $rpl_connection_name= server1
+--source include/rpl_connection.inc
+
+--source ../inc/start_and_bootstrap_group_replication.inc
+
+--echo
+--echo # 2. Setup environment to fail donor connection and start GR on M2.
+--echo # Set DEBUG on M2 to block donor connection attempt when count reaches 3.
+--echo # Verify M2 is in recovery state.
+--echo
+
+--let $rpl_connection_name= server2
+--source include/rpl_connection.inc
+
+SET @debug_save= @@GLOBAL.DEBUG;
+SET @recovery_reconnect_interval_save= @@GLOBAL.GROUP_REPLICATION_RECOVERY_RECONNECT_INTERVAL;
+SET @recovery_retry_count_save= @@GLOBAL.group_replication_recovery_retry_count;
+--disable_warnings
+CHANGE MASTER TO MASTER_USER="user_does_not_exist" FOR CHANNEL "group_replication_recovery";
+--enable_warnings
+
+SET SESSION sql_log_bin = 0;
+call mtr.add_suppression("Maximum number of retries when trying to connect to a donor reached. Aborting group replication recovery.");
+call mtr.add_suppression("Fatal error during the recovery process of Group Replication. The server will leave the group.");
+call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+SET SESSION sql_log_bin = 1;
+SET @@GLOBAL.DEBUG='+d,gr_reset_max_connection_attempts_to_donors';
+
+SET GLOBAL group_replication_recovery_reconnect_interval= 2;
+
+--let $group_replication_start_member_state= RECOVERING
+--source include/start_group_replication.inc
+
+--echo
+--echo # 3. Reset group_replication_recovery_retry_count to 2.
+--echo # Signal donor connection attempt to continue.
+--echo
+SET DEBUG_SYNC= "now WAIT_FOR signal.connection_attempt_3";
+
+SET GLOBAL group_replication_recovery_retry_count= 2;
+
+SET DEBUG_SYNC= "now SIGNAL signal.reset_recovery_retry_count_done";
+
+--echo
+--echo # 4. Verification.
+--echo
+
+--let $group_replication_member_state= ERROR
+--source ../inc/gr_wait_for_member_state.inc
+
+--let $assert_file = $error_file
+--let $assert_text = 3 donor connections attempts were made.
+--let $assert_select = Retrying group recovery connection with another donor. Attempt 3/10
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--let $assert_file = $error_file
+--let $assert_text = Post change of group_replication_recovery_retry_count, 4th donor connection attempt was not made.
+--let $assert_select = Retrying group recovery connection with another donor. Attempt 4
+--let $assert_count = 0
+--source include/assert_grep.inc
+
+--let $assert_file = $error_file
+--let $assert_text = Recovery process aborted.
+--let $assert_select = Maximum number of retries when trying to connect to a donor reached. Aborting group replication recovery.
+--let $assert_count = 1
+--source include/assert_grep.inc
+
+--echo
+--echo # 5. Clean up.
+--echo
+SET @@GLOBAL.DEBUG= @debug_save;
+SET @@GLOBAL.GROUP_REPLICATION_RECOVERY_RECONNECT_INTERVAL= @recovery_reconnect_interval_save;
+SET @@GLOBAL.group_replication_recovery_retry_count= @recovery_retry_count_save;
+
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_no_donors.test b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_no_donors.test
index 98b8a99b883f..29896307fd6e 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_no_donors.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_recovery_no_donors.test
@@ -39,6 +39,7 @@ call mtr.add_suppression("Skipping leave operation: member already left the grou
call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
call mtr.add_suppression("Transaction cannot be executed while Group Replication is stopping.");
call mtr.add_suppression("Run function 'before_commit' in plugin 'group_replication' failed");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
SET SESSION sql_log_bin= 1;
CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT NOT NULL);
@@ -82,6 +83,7 @@ call mtr.add_suppression("All donors left. Aborting group replication recovery."
call mtr.add_suppression("The member is already leaving or joining a group.");
call mtr.add_suppression("Skipping leave operation: member already left the group.");
call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
SET SESSION sql_log_bin= 1;
--let $rpl_connection_name= server3
@@ -94,6 +96,7 @@ call mtr.add_suppression("All donors left. Aborting group replication recovery."
call mtr.add_suppression("The member is already leaving or joining a group.");
call mtr.add_suppression("Skipping leave operation: member already left the group.");
call mtr.add_suppression("Skipping leave operation: concurrent attempt to leave the group is on-going.");
+call mtr.add_suppression("On shutdown there was a timeout receiving a view change. This can lead to a possible inconsistent state. Check the log for more details");
SET SESSION sql_log_bin= 1;
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_reset_slave_channel.test b/rapid/plugin/group_replication/tests/mtr/t/gr_reset_slave_channel.test
index 0ab6e6039cad..a95570f39360 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_reset_slave_channel.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_reset_slave_channel.test
@@ -1,7 +1,8 @@
################################################################################
# This test verifies that group replication channels are not affect by global
-# RESET SLAVE commands.
-# If a command is however used directly in a group channel it should work.
+# RESET SLAVE commands when the group replication is running.
+# If a command is used directly in a group channel it should work.
+# If a command is used when group replication is stopped it should work.
#
# Test:
# 0. The test requires two servers: M1, M2 and M3.
@@ -18,7 +19,8 @@
# c) On M2, group applier files should now be present with the channel.
# b) On M2, recovery files should be present.
#
-# 3. Phase 3: Check that the RESET SLAVE command doesn't affect GR.
+# 3. Phase 3: Check that the RESET SLAVE command doesn't affect GR specific
+# channels when the GR member is ONLINE.
# a) Execute RESET SLAVE ALL command on M1.
# b) Validate that group applier files are still present on M1.
# c) Check that slave files are removed on M1.
@@ -35,6 +37,23 @@
# c) Add some data on M1 to check if all is fine.
# d) Validate that both members have all the data.
#
+# 6. Phase 6: When GR is stopped, after global reset command all files
+# should disappear.
+# a) Stop GR on M2.
+# b) Execute RESET SLAVE command on M2
+# c) Validate that slave_master_info and slave_relay_log_info tables are
+# cleared.
+# d) Start GR on M2. The node should be ONLINE.
+#
+# 7. Phase 7: When GR is stopped, after global RESET SLAVE ALL command all
+# files should disappear including recovery channel specific credentials.
+# a) Stop GR on M2.
+# b) Execute RESET SLAVE ALL command on M2
+# c) Validate that slave_master_info and slave_relay_log_info tables are
+# cleared.
+# d) Execute CHANGE MASTER command to provide recovery channel credentials.
+# f) Start GR on M2. The node should be ONLINE.
+#
# 6. Phase 6: Cleanup.
################################################################################
@@ -136,11 +155,15 @@ INSERT INTO t1 VALUES (3);
#
# Phase 3: Check that the RESET SLAVE command doesn't affect group replication
-# The slave channel should not be there
+# specific channels when the GR member is ONLINE. Only the slave channel should
+# not be there
#
--connection server1
+# Global RESET SLAVE ALL command will not work on group replication channels
+# when the group memeber is ONLINE.
+--error ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED
RESET SLAVE ALL;
--let $relay_log_file=`SELECT CONCAT('$datadir_1','mgr-group_replication_applier.000001')`
@@ -216,7 +239,81 @@ INSERT INTO t1 VALUES (5);
--source include/assert.inc
#
-# Phase 6: Cleanup
+# Phase 6: After a global reset command all files should disappear
+#
+--connection server2
+--echo server2
+
+--echo Vefiry that group replication channels are present
+--let $assert_text= 'The group replication applier channel is present'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_relay_log_info WHERE channel_name="group_replication_applier", count, 1] = 1
+--source include/assert.inc
+
+--let $assert_text= 'The group replication recovery channel is present'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_relay_log_info WHERE channel_name="group_replication_recovery", count, 1] = 1
+--source include/assert.inc
+--let $datadir_2= `SELECT @@GLOBAL.datadir`
+
+--source include/stop_group_replication.inc
+
+--echo RESET SLAVE command clears master and slave info repositories and will flush master info
+RESET SLAVE;
+
+--let $assert_text= 'mysql.slave_relay_log_info contains no group replication channel information'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_relay_log_info WHERE channel_name like "group_replication%", count, 1] = 0
+--source include/assert.inc
+
+--let $assert_text= 'mysql.slave_master_info contains flushed group replication channel information'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_master_info WHERE channel_name like "group_replication%", count, 1] = 2
+--source include/assert.inc
+
+# Applier files are recreated
+--let $relay_log_index= `SELECT CONCAT('$datadir_2', 'mgr-group_replication_applier.index')`
+--file_exists $relay_log_index
+
+# Recovery files are recreated
+--let $recovery_relay_log_index= `SELECT CONCAT('$datadir_2', 'mgr-group_replication_recovery.index')`
+--file_exists $recovery_relay_log_index
+
+--source include/start_group_replication.inc
+
+--let $assert_text= 'The group replication applier and recovery channel are present'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_relay_log_info WHERE channel_name like "group_replication%", count, 1] = 2
+--source include/assert.inc
+
+#
+# Phase 7: After a global reset slave all command, all files should disappear
+# Executed the CHANGE MASTER command to create recovery channel and enable
+# group replication.
+#
+
+--source include/stop_group_replication.inc
+RESET SLAVE ALL;
+
+--let $assert_text= 'mysql.slave_relay_log_info does not contrain group replication channel information'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_relay_log_info WHERE channel_name like "group_replication%", count, 1] = 0
+--source include/assert.inc
+
+--let $assert_text= 'mysql.slave_master_info does not contrain group replication channel information'
+--let $assert_cond= [SELECT COUNT(*) AS count FROM mysql.slave_master_info WHERE channel_name like "group_replication%", count, 1] = 0
+--source include/assert.inc
+
+--let $relay_log_index= `SELECT CONCAT('$datadir_2', 'mgr-group_replication_applier.index')`
+--error 1
+--file_exists $relay_log_index
+
+# Recovery files are also removed
+
+--let $recovery_relay_log_index= `SELECT CONCAT('$datadir_2', 'mgr-group_replication_recovery.index')`
+--error 1
+--file_exists $recovery_relay_log_index
+
+CHANGE MASTER TO MASTER_USER="root" FOR CHANNEL "group_replication_recovery";
+
+--source include/start_group_replication.inc
+
+#
+# Phase 8: Cleanup
#
DROP TABLE t1;
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_show_global_and_session_variables.test b/rapid/plugin/group_replication/tests/mtr/t/gr_show_global_and_session_variables.test
index 435a16c16fc0..4e55f2b1abcf 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_show_global_and_session_variables.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_show_global_and_session_variables.test
@@ -3,7 +3,7 @@
#
# Test:
# 0. This test requires one server.
-# 1. Basic check that there are 35 GR variables.
+# 1. Basic check that there are 36 GR variables.
# 2. Verify that all the group replication variables are GLOBAL variables.
# 3. Verify values of GLOBAL and SESSION variables using below commands:-
# - SHOW GLOBAL VARIABLES LIKE 'group_replication_..'
@@ -29,12 +29,12 @@
--sleep 30
--echo
---echo # Test#1: Basic check that there are 35 GR variables.
+--echo # Test#1: Basic check that there are 36 GR variables.
# Note: If a new GR variable is added or an old GR variable is removed, then
# update this testcase for the sanity check.
---let $assert_text= There are 35 GR variables at present.
---let $assert_cond= "[SELECT COUNT(*) FROM performance_schema.global_variables WHERE VARIABLE_NAME LIKE \\'group_replication%\']" = 35
+--let $assert_text= There are 36 GR variables at present.
+--let $assert_cond= "[SELECT COUNT(*) FROM performance_schema.global_variables WHERE VARIABLE_NAME LIKE \\'group_replication%\']" = 36
--source include/assert.inc
# Take backup of GR variables
@@ -71,6 +71,7 @@
--let $saved_gr_transaction_size_limit = `SELECT @@GLOBAL.group_replication_transaction_size_limit;`
--let $saved_gr_unreachable_majority_timeout = `SELECT @@GLOBAL.group_replication_unreachable_majority_timeout`
--let $saved_gr_member_weight = `SELECT @@GLOBAL.group_replication_member_weight;`
+--let $saved_gr_exit_state_action = `SELECT @@GLOBAL.group_replication_exit_state_action;`
--enable_query_log
--echo
@@ -141,6 +142,8 @@ SET @@SESSION.group_replication_transaction_size_limit= 10240;
SET @@SESSION.group_replication_unreachable_majority_timeout= 10240;
--error ER_GLOBAL_VARIABLE
SET @@SESSION.group_replication_member_weight= 80;
+--error ER_GLOBAL_VARIABLE
+SET @@SESSION.group_replication_exit_state_action= "READ_ONLY";
# GR variables should be set at GLOBAL level.
# Set values to GLOBAL GR variables to test further.
@@ -177,6 +180,7 @@ SET GLOBAL group_replication_start_on_boot= ON;
SET GLOBAL group_replication_transaction_size_limit= 100000;
SET GLOBAL group_replication_unreachable_majority_timeout= 100000;
SET GLOBAL group_replication_member_weight= 70;
+SET GLOBAL group_replication_exit_state_action= "READ_ONLY";
--enable_query_log
--echo
@@ -729,6 +733,23 @@ SET GLOBAL group_replication_member_weight= 70;
--let $assert_cond= "[SELECT * FROM performance_schema.session_variables WHERE VARIABLE_NAME=\'group_replication_member_weight\', VARIABLE_VALUE, 1]" = 70
--source include/assert.inc
+# group_replication_exit_state_action
+--let $assert_text= Verify GLOBAL value of group_replication_exit_state_action
+--let $assert_cond= "[SHOW GLOBAL VARIABLES LIKE \'group_replication_exit_state_action\', Value, 1]" = "READ_ONLY"
+--source include/assert.inc
+
+--let $assert_text= Verify GLOBAL value of group_replication_exit_state_action
+--let $assert_cond= "[SELECT * FROM performance_schema.global_variables WHERE VARIABLE_NAME=\'group_replication_exit_state_action\', VARIABLE_VALUE, 1]" = "READ_ONLY"
+--source include/assert.inc
+
+--let $assert_text= Verify SESSION value of group_replication_exit_state_action
+--let $assert_cond= "[SHOW SESSION VARIABLES LIKE \'group_replication_exit_state_action\', Value, 1]" = "READ_ONLY"
+--source include/assert.inc
+
+--let $assert_text= Verify SESSION value of group_replication_exit_state_action
+--let $assert_cond= "[SELECT * FROM performance_schema.session_variables WHERE VARIABLE_NAME=\'group_replication_exit_state_action\', VARIABLE_VALUE, 1]" = "READ_ONLY"
+--source include/assert.inc
+
--echo
--echo # Clean up
--source include/stop_group_replication.inc
@@ -767,6 +788,7 @@ SET GLOBAL group_replication_member_weight= 70;
--eval SET @@GLOBAL.group_replication_transaction_size_limit= $saved_gr_transaction_size_limit
--eval SET @@GLOBAL.group_replication_unreachable_majority_timeout= $saved_gr_unreachable_majority_timeout
--eval SET @@GLOBAL.group_replication_member_weight= $saved_gr_member_weight
+--eval SET @@GLOBAL.group_replication_exit_state_action= $saved_gr_exit_state_action
--enable_query_log
--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_startup_check_node_seed_skips_own_address.test b/rapid/plugin/group_replication/tests/mtr/t/gr_startup_check_node_seed_skips_own_address.test
new file mode 100644
index 000000000000..ee0197203cdb
--- /dev/null
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_startup_check_node_seed_skips_own_address.test
@@ -0,0 +1,117 @@
+###############################################################
+# The purpose of this test is to exercise all possible options
+# that avoid a node connecting to himself as seed, if a
+# misconfiguration accidentally happens, when using names.
+#
+#
+# The following combinations (as an example) must succeed:
+#
+# boot_node = off
+# local_address = name:12345 //name resolves to 127.0.0.1
+# peers = 127.0.0.1:12345,127.0.0.1:12346
+#
+# boot_node = off
+# local_address = 127.0.0.1:12345
+# peers = name:12345,127.0.0.1:12346 //name resolves to 127.0.0.1
+#
+#
+# For that one needs to:
+# - Skip start as a whole
+# - Start server 1
+# - Build scenario 1
+# - Start server 2
+# - Make sure it comes online
+# - Build and run scenario 2
+# - Cleanup
+#
+###############################################################
+
+--let $group_replication_group_name= 89ab83b0-9f17-11e3-a5e2-0800200c9a66
+
+--source ../inc/have_group_replication_plugin.inc
+--let $rpl_skip_group_replication_start= 1
+--source ../inc/group_replication.inc
+
+# Start server 1 by hand
+--connection server1
+--echo server1
+--source ../inc/start_and_bootstrap_group_replication.inc
+
+# Go to server 2
+--connection server2
+--echo server2
+
+# Backup the original values
+--let $original_server_2_local_address= `SELECT @@GLOBAL.group_replication_local_address`
+--let $original_server_2_seeds= `SELECT @@GLOBAL.group_replication_group_seeds`
+
+--echo "1. Test local address with raw address and seeds with name"
+
+# Assemble the new values:
+# - local address with raw values
+# - local address first in seeds with name (which is default)
+--let $localhost_address= 127.0.0.1:
+--let $local_address_with_raw_address= $localhost_address$SERVER_GR_PORT_2
+
+# Set values
+--disable_query_log
+--eval SET GLOBAL group_replication_local_address= "$local_address_with_raw_address"
+--eval SET GLOBAL group_replication_group_seeds= "$original_server_2_local_address,$original_server_2_seeds"
+--enable_query_log
+
+# Start the server and wait for successful start
+--source include/start_group_replication.inc
+
+--let $group_replication_member_state= ONLINE
+--source ../inc/gr_wait_for_member_state.inc
+
+# Stop the server
+--source include/stop_group_replication.inc
+
+--echo "2. Test local address with name address and seeds with raw address"
+
+# Assemble the new values:
+# - local address with name values
+# - local address first in seeds with raw value
+
+--disable_query_log
+--eval SET GLOBAL group_replication_local_address= "$original_server_2_local_address"
+--eval SET GLOBAL group_replication_group_seeds= "$local_address_with_raw_address,$original_server_2_seeds"
+--enable_query_log
+
+--source include/start_group_replication.inc
+
+# Start the server and wait for successful start
+
+--let $group_replication_member_state= ONLINE
+--source ../inc/gr_wait_for_member_state.inc
+
+# Stop the server
+--source include/stop_group_replication.inc
+
+--echo "3. Test local address with name address and seeds with name address"
+
+# Assemble the new values:
+# - local address with name values
+# - local address first in seeds with name value
+
+--disable_query_log
+--eval SET GLOBAL group_replication_local_address= "$original_server_2_local_address"
+--eval SET GLOBAL group_replication_group_seeds= "$original_server_2_local_address,$original_server_2_seeds"
+--enable_query_log
+
+--source include/start_group_replication.inc
+
+# Start the server and wait for successful start
+
+--let $group_replication_member_state= ONLINE
+--source ../inc/gr_wait_for_member_state.inc
+
+# Cleanup
+
+--disable_query_log
+--eval SET GLOBAL group_replication_local_address= "$original_server_2_local_address"
+--eval SET GLOBAL group_replication_group_seeds= "$original_server_2_seeds"
+--enable_query_log
+
+--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/group_replication/tests/mtr/t/gr_variables_default_values.test b/rapid/plugin/group_replication/tests/mtr/t/gr_variables_default_values.test
index d6c06b5e0c92..ebc1e77d1f19 100644
--- a/rapid/plugin/group_replication/tests/mtr/t/gr_variables_default_values.test
+++ b/rapid/plugin/group_replication/tests/mtr/t/gr_variables_default_values.test
@@ -68,17 +68,18 @@ SET @@GLOBAL.group_replication_ip_whitelist= default;
--let $saved_gr_transaction_size_limit = `SELECT @@GLOBAL.group_replication_transaction_size_limit;`
--let $saved_gr_unreachable_majority_timeout = `SELECT @@GLOBAL.group_replication_unreachable_majority_timeout`
--let $saved_gr_member_weight = `SELECT @@GLOBAL.group_replication_member_weight;`
+--let $saved_gr_exit_state_action = `SELECT @@GLOBAL.group_replication_exit_state_action;`
--echo #
--echo # Test Unit#1
--echo # Set global group replication variables to default.
---echo # Curently there are 35 group replication variables.
+--echo # Curently there are 36 group replication variables.
--echo #
# Note: If a new GR variable is added or an old GR variable is removed, then
# update this testcase for the sanity check.
---let $assert_text= There are 35 GR variables at present.
---let $assert_cond= "[SELECT COUNT(*) FROM performance_schema.global_variables WHERE VARIABLE_NAME LIKE \\'group_replication%\']" = 35
+--let $assert_text= There are 36 GR variables at present.
+--let $assert_cond= "[SELECT COUNT(*) FROM performance_schema.global_variables WHERE VARIABLE_NAME LIKE \\'group_replication%\']" = 36
--source include/assert.inc
--error ER_WRONG_VALUE_FOR_VAR
@@ -121,6 +122,7 @@ SET @@GLOBAL.group_replication_start_on_boot= default;
SET @@GLOBAL.group_replication_transaction_size_limit= default;
SET @@GLOBAL.group_replication_unreachable_majority_timeout= default;
SET @@GLOBAL.group_replication_member_weight= default;
+SET @@GLOBAL.group_replication_exit_state_action= default;
--echo #
--echo # Test Unit#2
@@ -267,6 +269,11 @@ SET @@GLOBAL.group_replication_member_weight= default;
--let $assert_cond= "[SELECT @@GLOBAL.group_replication_member_weight]" = 50
--source include/assert.inc
+#group_replication_exit_state_action
+--let $assert_text= Default group_replication_exit_state_action is READ_ONLY
+--let $assert_cond= "[SELECT @@GLOBAL.group_replication_exit_state_action]" = "READ_ONLY"
+--source include/assert.inc
+
--echo #
--echo # Clean up
--echo #
@@ -306,6 +313,7 @@ SET @@GLOBAL.group_replication_member_weight= default;
--eval SET @@GLOBAL.group_replication_transaction_size_limit= $saved_gr_transaction_size_limit
--eval SET @@GLOBAL.group_replication_unreachable_majority_timeout= $saved_gr_unreachable_majority_timeout
--eval SET @@GLOBAL.group_replication_member_weight= $saved_gr_member_weight
+--eval SET @@GLOBAL.group_replication_exit_state_action= $saved_gr_exit_state_action
--enable_query_log
--source ../inc/group_replication_end.inc
diff --git a/rapid/plugin/x/CMakeLists.txt b/rapid/plugin/x/CMakeLists.txt
index 4614df5c8970..2b6fc25c2e37 100644
--- a/rapid/plugin/x/CMakeLists.txt
+++ b/rapid/plugin/x/CMakeLists.txt
@@ -93,7 +93,6 @@ ELSE()
${CMAKE_CURRENT_SOURCE_DIR}/include/mysql
${CMAKE_CURRENT_BINARY_DIR}/generated
${SSL_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIR}
)
INCLUDE_DIRECTORIES(SYSTEM
diff --git a/rapid/plugin/x/tests/mtr/r/delete_crud_o.result b/rapid/plugin/x/tests/mtr/r/delete_crud_o.result
index aa1135b85a8d..b0c92a38a991 100644
--- a/rapid/plugin/x/tests/mtr/r/delete_crud_o.result
+++ b/rapid/plugin/x/tests/mtr/r/delete_crud_o.result
@@ -244,7 +244,7 @@ send Mysqlx.Crud.Delete {
Mysqlx.Error {
severity: ERROR
code: 1175
- msg: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column"
+ msg: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. "
sql_state: "HY000"
}
@@ -306,7 +306,7 @@ send Mysqlx.Crud.Delete {
Mysqlx.Error {
severity: ERROR
code: 1175
- msg: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column"
+ msg: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. "
sql_state: "HY000"
}
@@ -341,7 +341,7 @@ send Mysqlx.Crud.Delete {
Mysqlx.Error {
severity: ERROR
code: 1175
- msg: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column"
+ msg: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. "
sql_state: "HY000"
}
diff --git a/rapid/plugin/x/tests/mtr/r/delete_sql_o.result b/rapid/plugin/x/tests/mtr/r/delete_sql_o.result
index c91b60e32592..fabbc52b75f9 100644
--- a/rapid/plugin/x/tests/mtr/r/delete_sql_o.result
+++ b/rapid/plugin/x/tests/mtr/r/delete_sql_o.result
@@ -71,20 +71,20 @@ RUN DELETE FROM ExtraCategoryInfo WHERE ExtraCategoryInfoID = 1
1 rows affected
RUN DELETE FROM ExtraCategoryInfo WHERE MainParentCategoryName = 'People'
While executing DELETE FROM ExtraCategoryInfo WHERE MainParentCategoryName = 'People':
-Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column (code 1175)
+Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. (code 1175)
RUN DELETE FROM ExtraCategoryInfo WHERE MainParentCategoryName = 'House' AND CategoryID in (4)
While executing DELETE FROM ExtraCategoryInfo WHERE MainParentCategoryName = 'House' AND CategoryID in (4):
-Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column (code 1175)
+Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. (code 1175)
RUN DELETE FROM Categories WHERE CategoryIMEI = 1
While executing DELETE FROM Categories WHERE CategoryIMEI = 1:
-Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column (code 1175)
+Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. (code 1175)
RUN DELETE FROM ExtraCategoryInfo WHERE EXISTS
(SELECT * FROM Categories WHERE Categories.CategoryID = ExtraCategoryInfo.CategoryID
AND ExtraCategoryInfo.MainParentCategoryName = 'People' )
While executing DELETE FROM ExtraCategoryInfo WHERE EXISTS
(SELECT * FROM Categories WHERE Categories.CategoryID = ExtraCategoryInfo.CategoryID
AND ExtraCategoryInfo.MainParentCategoryName = 'People' ):
-Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column (code 1175)
+Got expected error: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. (code 1175)
RUN SELECT * FROM ExtraCategoryInfo
ExtraCategoryInfoID CategoryID MainParentCategoryName
3 2 House
diff --git a/scripts/fill_help_tables.sql b/scripts/fill_help_tables.sql
index 58ab4b3e9a51..e79342edef2d 100644
--- a/scripts/fill_help_tables.sql
+++ b/scripts/fill_help_tables.sql
@@ -17,9 +17,9 @@
-- team. If you require changes to the format of this file, contact the
-- docs team.
--- File generation date: 2018-06-07
+-- File generation date: 2018-10-03
-- MySQL series: 5.7
--- Document repository revision: 57614
+-- Document repository revision: 59320
-- To use this file, load its contents into the mysql database. For example,
-- with the mysql client program, process the file like this, where
@@ -91,23 +91,23 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (10,38,'CHAR FUNCTION','Syntax:\nCHAR(N,... [USING charset_name])\n\nCHAR() interprets each argument N as an integer and returns a string\nconsisting of the characters given by the code values of those\nintegers. NULL values are skipped.\nBy default, CHAR() returns a binary string. To produce a string in a\ngiven character set, use the optional USING clause:\n\nmysql> SELECT CHARSET(CHAR(X\'65\')), CHARSET(CHAR(X\'65\' USING utf8));\n+----------------------+---------------------------------+\n| CHARSET(CHAR(X\'65\')) | CHARSET(CHAR(X\'65\' USING utf8)) |\n+----------------------+---------------------------------+\n| binary | utf8 |\n+----------------------+---------------------------------+\n\nIf USING is given and the result string is illegal for the given\ncharacter set, a warning is issued. Also, if strict SQL mode is\nenabled, the result from CHAR() becomes NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT CHAR(77,121,83,81,\'76\');\n -> \'MySQL\'\nmysql> SELECT CHAR(77,77.3,\'77.3\');\n -> \'MMM\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (11,7,'ASYMMETRIC_DECRYPT','Syntax:\nASYMMETRIC_DECRYPT(algorithm, crypt_str, key_str)\n\nDecrypts an encrypted string using the given algorithm and key string,\nand returns the resulting cleartext as a binary string. If decryption\nfails, the result is NULL.\n\nkey_str must be a valid key string in PEM format. For successful\ndecryption, it must be the public or private key string corresponding\nto the private or public key string used with ASYMMETRIC_ENCRYPT() to\nproduce the encrypted string. algorithm indicates the encryption\nalgorithm used to create the key.\n\nSupported algorithm values: \'RSA\'\n\nFor a usage example, see the description of ASYMMETRIC_ENCRYPT().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (12,27,'SHOW CREATE TRIGGER','Syntax:\nSHOW CREATE TRIGGER trigger_name\n\nThis statement shows the CREATE TRIGGER statement that creates the\nnamed trigger. This statement requires the TRIGGER privilege for the\ntable associated with the trigger.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-trigger.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-create-trigger.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (13,27,'SHOW CREATE PROCEDURE','Syntax:\nSHOW CREATE PROCEDURE proc_name\n\nThis statement is a MySQL extension. It returns the exact string that\ncan be used to re-create the named stored procedure. A similar\nstatement, SHOW CREATE FUNCTION, displays information about stored\nfunctions (see [HELP SHOW CREATE FUNCTION]).\n\nTo use either statement, you must be the user named in the routine\nDEFINER clause or have SELECT access to the mysql.proc table. If you do\nnot have privileges for the routine itself, the value displayed for the\nCreate Procedure or Create Function field will be NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-procedure.html\n\n','mysql> SHOW CREATE PROCEDURE test.simpleproc\\G\n*************************** 1. row ***************************\n Procedure: simpleproc\n sql_mode:\n Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT)\n BEGIN\n SELECT COUNT(*) INTO param1 FROM t;\n END\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nmysql> SHOW CREATE FUNCTION test.hello\\G\n*************************** 1. row ***************************\n Function: hello\n sql_mode:\n Create Function: CREATE FUNCTION `hello`(s CHAR(20))\n RETURNS CHAR(50)\n RETURN CONCAT(\'Hello, \',s,\'!\')\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.7/en/show-create-procedure.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (13,27,'SHOW CREATE PROCEDURE','Syntax:\nSHOW CREATE PROCEDURE proc_name\n\nThis statement is a MySQL extension. It returns the exact string that\ncan be used to re-create the named stored procedure. A similar\nstatement, SHOW CREATE FUNCTION, displays information about stored\nfunctions (see [HELP SHOW CREATE FUNCTION]).\n\nTo use either statement, you must be the user named in the routine\nDEFINER clause or have SELECT access to the mysql.proc table. If you do\nnot have privileges for the routine itself, the value displayed for the\nCreate Procedure or Create Function field will be NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-procedure.html\n\n','mysql> SHOW CREATE PROCEDURE test.simpleproc\\G\n*************************** 1. row ***************************\n Procedure: simpleproc\n sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,\n NO_ZERO_IN_DATE,NO_ZERO_DATE,\n ERROR_FOR_DIVISION_BY_ZERO,\n NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION\n Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT)\n BEGIN\n SELECT COUNT(*) INTO param1 FROM t;\n END\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n\nmysql> SHOW CREATE FUNCTION test.hello\\G\n*************************** 1. row ***************************\n Function: hello\n sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,\n NO_ZERO_IN_DATE,NO_ZERO_DATE,\n ERROR_FOR_DIVISION_BY_ZERO,\n NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION\n Create Function: CREATE FUNCTION `hello`(s CHAR(20))\n RETURNS char(50) CHARSET latin1\n RETURN CONCAT(\'Hello, \',s,\'!\')\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.7/en/show-create-procedure.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (14,24,'OPEN','Syntax:\nOPEN cursor_name\n\nThis statement opens a previously declared cursor. For an example, see\nhttp://dev.mysql.com/doc/refman/5.7/en/cursors.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/open.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/open.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (15,31,'ST_INTERSECTS','ST_Intersects(g1, g2)\n\nReturns 1 or 0 to indicate whether g1 spatially intersects g2.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (16,38,'LOWER','Syntax:\nLOWER(str)\n\nReturns the string str with all characters changed to lowercase\naccording to the current character set mapping. The default is latin1\n(cp1252 West European).\n\nmysql> SELECT LOWER(\'QUADRATICALLY\');\n -> \'quadratically\'\n\nLOWER() (and UPPER()) are ineffective when applied to binary strings\n(BINARY, VARBINARY, BLOB). To perform lettercase conversion, convert\nthe string to a nonbinary string:\n\nmysql> SET @str = BINARY \'New York\';\nmysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));\n+-------------+-----------------------------------+\n| LOWER(@str) | LOWER(CONVERT(@str USING latin1)) |\n+-------------+-----------------------------------+\n| New York | new york |\n+-------------+-----------------------------------+\n\nFor collations of Unicode character sets, LOWER() and UPPER() work\naccording to the Unicode Collation Algorithm (UCA) version in the\ncollation name, if there is one, and UCA 4.0.0 if no version is\nspecified. For example, utf8_unicode_520_ci works according to UCA\n5.2.0, whereas utf8_unicode_ci works according to UCA 4.0.0. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-unicode-sets.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (17,40,'CREATE TRIGGER','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n TRIGGER trigger_name\n trigger_time trigger_event\n ON tbl_name FOR EACH ROW\n [trigger_order]\n trigger_body\n\ntrigger_time: { BEFORE | AFTER }\n\ntrigger_event: { INSERT | UPDATE | DELETE }\n\ntrigger_order: { FOLLOWS | PRECEDES } other_trigger_name\n\nThis statement creates a new trigger. A trigger is a named database\nobject that is associated with a table, and that activates when a\nparticular event occurs for the table. The trigger becomes associated\nwith the table named tbl_name, which must refer to a permanent table.\nYou cannot associate a trigger with a TEMPORARY table or a view.\n\nTrigger names exist in the schema namespace, meaning that all triggers\nmust have unique names within a schema. Triggers in different schemas\ncan have the same name.\n\nThis section describes CREATE TRIGGER syntax. For additional\ndiscussion, see\nhttp://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html.\n\nCREATE TRIGGER requires the TRIGGER privilege for the table associated\nwith the trigger. The statement might also require the SUPER privilege,\ndepending on the DEFINER value, as described later in this section. If\nbinary logging is enabled, CREATE TRIGGER might require the SUPER\nprivilege, as described in\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html.\n\nThe DEFINER clause determines the security context to be used when\nchecking access privileges at trigger activation time, as described\nlater in this section.\n\ntrigger_time is the trigger action time. It can be BEFORE or AFTER to\nindicate that the trigger activates before or after each row to be\nmodified.\n\nBasic column value checks occur prior to trigger activation, so you\ncannot use BEFORE triggers to convert values inappropriate for the\ncolumn type to valid values.\n\ntrigger_event indicates the kind of operation that activates the\ntrigger. These trigger_event values are permitted:\n\no INSERT: The trigger activates whenever a new row is inserted into the\n table; for example, through INSERT, LOAD DATA, and REPLACE\n statements.\n\no UPDATE: The trigger activates whenever a row is modified; for\n example, through UPDATE statements.\n\no DELETE: The trigger activates whenever a row is deleted from the\n table; for example, through DELETE and REPLACE statements. DROP TABLE\n and TRUNCATE TABLE statements on the table do not activate this\n trigger, because they do not use DELETE. Dropping a partition does\n not activate DELETE triggers, either.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-trigger.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-trigger.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (18,32,'MONTH','Syntax:\nMONTH(date)\n\nReturns the month for date, in the range 1 to 12 for January to\nDecember, or 0 for dates such as \'0000-00-00\' or \'2008-00-00\' that have\na zero month part.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT MONTH(\'2008-02-03\');\n -> 2\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (19,7,'ASYMMETRIC_ENCRYPT','Syntax:\nASYMMETRIC_ENCRYPT(algorithm, str, key_str)\n\nEncrypts a string using the given algorithm and key string, and returns\nthe resulting ciphertext as a binary string. If encryption fails, the\nresult is NULL.\n\nThe str length cannot be greater than the key_str length − 11, in\nbytes\n\nkey_str must be a valid key string in PEM format. algorithm indicates\nthe encryption algorithm used to create the key.\n\nSupported algorithm values: \'RSA\'\n\nTo encrypt a string, pass a private or public key string to\nASYMMETRIC_ENCRYPT(). To recover the original unencrypted string, pass\nthe encrypted string to ASYMMETRIC_DECRYPT(), along with the public or\nprivate key string correponding to the private or public key string\nused for encryption.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html\n\n','-- Generate private/public key pair\nSET @priv = CREATE_ASYMMETRIC_PRIV_KEY(\'RSA\', 1024);\nSET @pub = CREATE_ASYMMETRIC_PUB_KEY(\'RSA\', @priv);\n\n-- Encrypt using private key, decrypt using public key\nSET @ciphertext = ASYMMETRIC_ENCRYPT(\'RSA\', \'The quick brown fox\', @priv);\nSET @cleartext = ASYMMETRIC_DECRYPT(\'RSA\', @ciphertext, @pub);\n\n-- Encrypt using public key, decrypt using private key\nSET @ciphertext = ASYMMETRIC_ENCRYPT(\'RSA\', \'The quick brown fox\', @pub);\nSET @cleartext = ASYMMETRIC_DECRYPT(\'RSA\', @ciphertext, @priv);\n','http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (20,27,'SHOW TRIGGERS','Syntax:\nSHOW TRIGGERS\n [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TRIGGERS lists the triggers currently defined for tables in a\ndatabase (the default database unless a FROM clause is given). This\nstatement returns results only for databases and tables for which you\nhave the TRIGGER privilege. The LIKE clause, if present, indicates\nwhich table names to match (not trigger names) and causes the statement\nto display triggers for those tables. The WHERE clause can be given to\nselect rows using more general conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nFor the trigger ins_sum as defined in\nhttp://dev.mysql.com/doc/refman/5.7/en/triggers.html, the output of\nthis statement is as shown here:\n\nmysql> SHOW TRIGGERS LIKE \'acc%\'\\G\n*************************** 1. row ***************************\n Trigger: ins_sum\n Event: INSERT\n Table: account\n Statement: SET @sum = @sum + NEW.amount\n Timing: BEFORE\n Created: 2013-07-09 10:39:34.96\n sql_mode: NO_ENGINE_SUBSTITUTION\n Definer: me@localhost\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-triggers.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-triggers.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (20,27,'SHOW TRIGGERS','Syntax:\nSHOW TRIGGERS\n [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TRIGGERS lists the triggers currently defined for tables in a\ndatabase (the default database unless a FROM clause is given). This\nstatement returns results only for databases and tables for which you\nhave the TRIGGER privilege. The LIKE clause, if present, indicates\nwhich table names (not trigger names) to match and causes the statement\nto display triggers for those tables. The WHERE clause can be given to\nselect rows using more general conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nFor the ins_sum trigger defined in\nhttp://dev.mysql.com/doc/refman/5.7/en/triggers.html, the output of\nSHOW TRIGGERS is as shown here:\n\nmysql> SHOW TRIGGERS LIKE \'acc%\'\\G\n*************************** 1. row ***************************\n Trigger: ins_sum\n Event: INSERT\n Table: account\n Statement: SET @sum = @sum + NEW.amount\n Timing: BEFORE\n Created: 2018-08-08 10:10:12.61\n sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,\n NO_ZERO_IN_DATE,NO_ZERO_DATE,\n ERROR_FOR_DIVISION_BY_ZERO,\n NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION\n Definer: me@localhost\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-triggers.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-triggers.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (21,13,'ISCLOSED','IsClosed(ls)\n\nST_IsClosed() and IsClosed() are synonyms. For more information, see\nthe description of ST_IsClosed().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (22,38,'REGEXP','Syntax:\nexpr REGEXP pat, expr RLIKE pat\n\nReturns 1 if the string expr matches the regular expression specified\nby the pattern pat, 0 otherwise. If either expr or pat is NULL, the\nreturn value is NULL.\n\nRLIKE is a synonym for REGEXP.\n\nThe pattern can be an extended regular expression, the syntax for which\nis discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/regexp.html#regexp-syntax. The\npattern need not be a literal string. For example, it can be specified\nas a string expression or table column.\n\n*Note*:\n\nBecause MySQL uses the C escape syntax in strings (for example, \\n to\nrepresent the newline character), you must double any \\ that you use in\nyour REGEXP arguments.\n\nRegular expression operations use the character set and collation of\nthe string expression and pattern arguments when deciding the type of a\ncharacter and performing the comparison. If the arguments have\ndifferent character sets or collations, coercibility rules apply as\ndescribed in\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-collation-coercibility.h\ntml. If either argument is a binary string, the arguments are handled\nin case-sensitive fashion as binary strings.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/regexp.html\n\n','mysql> SELECT \'Michael!\' REGEXP \'.*\';\n+------------------------+\n| \'Michael!\' REGEXP \'.*\' |\n+------------------------+\n| 1 |\n+------------------------+\nmysql> SELECT \'new*\\n*line\' REGEXP \'new\\\\*.\\\\*line\';\n+---------------------------------------+\n| \'new*\\n*line\' REGEXP \'new\\\\*.\\\\*line\' |\n+---------------------------------------+\n| 0 |\n+---------------------------------------+\nmysql> SELECT \'a\' REGEXP \'^[a-d]\';\n+---------------------+\n| \'a\' REGEXP \'^[a-d]\' |\n+---------------------+\n| 1 |\n+---------------------+\nmysql> SELECT \'a\' REGEXP \'A\', \'a\' REGEXP BINARY \'A\';\n+----------------+-----------------------+\n| \'a\' REGEXP \'A\' | \'a\' REGEXP BINARY \'A\' |\n+----------------+-----------------------+\n| 1 | 0 |\n+----------------+-----------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/regexp.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (23,13,'ST_POINTN','ST_PointN(ls, N)\n\nReturns the N-th Point in the Linestring value ls. Points are numbered\nbeginning with 1. If any argument is NULL or the geometry argument is\nan empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html\n\n','mysql> SET @ls = \'LineString(1 1,2 2,3 3)\';\nmysql> SELECT ST_AsText(ST_PointN(ST_GeomFromText(@ls),2));\n+----------------------------------------------+\n| ST_AsText(ST_PointN(ST_GeomFromText(@ls),2)) |\n+----------------------------------------------+\n| POINT(2 2) |\n+----------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (24,24,'IF STATEMENT','Syntax:\nIF search_condition THEN statement_list\n [ELSEIF search_condition THEN statement_list] ...\n [ELSE statement_list]\nEND IF\n\nThe IF statement for stored programs implements a basic conditional\nconstruct.\n\n*Note*:\n\nThere is also an IF() function, which differs from the IF statement\ndescribed here. See\nhttp://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html. The\nIF statement can have THEN, ELSE, and ELSEIF clauses, and it is\nterminated with END IF.\n\nIf the search_condition evaluates to true, the corresponding THEN or\nELSEIF clause statement_list executes. If no search_condition matches,\nthe ELSE clause statement_list executes.\n\nEach statement_list consists of one or more SQL statements; an empty\nstatement_list is not permitted.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/if.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/if.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (25,12,'VALIDATE_PASSWORD_STRENGTH','Syntax:\nVALIDATE_PASSWORD_STRENGTH(str)\n\nGiven an argument representing a cleartext password, this function\nreturns an integer to indicate how strong the password is. The return\nvalue ranges from 0 (weak) to 100 (strong).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (26,7,'WITHIN','Within(g1, g2)\n\nMBRWithin() and Within() are synonyms. For more information, see the\ndescription of MBRWithin().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (27,27,'SHOW PLUGINS','Syntax:\nSHOW PLUGINS\n\nSHOW PLUGINS displays information about server plugins. Plugin\ninformation is also available in the INFORMATION_SCHEMA.PLUGINS table.\nSee http://dev.mysql.com/doc/refman/5.7/en/plugins-table.html.\n\nExample of SHOW PLUGINS output:\n\nmysql> SHOW PLUGINS\\G\n*************************** 1. row ***************************\n Name: binlog\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 2. row ***************************\n Name: CSV\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 3. row ***************************\n Name: MEMORY\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 4. row ***************************\n Name: MyISAM\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n...\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-plugins.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-plugins.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (27,27,'SHOW PLUGINS','Syntax:\nSHOW PLUGINS\n\nSHOW PLUGINS displays information about server plugins.\n\nExample of SHOW PLUGINS output:\n\nmysql> SHOW PLUGINS\\G\n*************************** 1. row ***************************\n Name: binlog\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 2. row ***************************\n Name: CSV\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 3. row ***************************\n Name: MEMORY\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 4. row ***************************\n Name: MyISAM\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n...\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-plugins.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-plugins.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (28,8,'PREPARE','Syntax:\nPREPARE stmt_name FROM preparable_stmt\n\nThe PREPARE statement prepares a SQL statement and assigns it a name,\nstmt_name, by which to refer to the statement later. The prepared\nstatement is executed with EXECUTE and released with DEALLOCATE\nPREPARE. For examples, see\nhttp://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.h\ntml.\n\nStatement names are not case-sensitive. preparable_stmt is either a\nstring literal or a user variable that contains the text of the SQL\nstatement. The text must represent a single statement, not multiple\nstatements. Within the statement, ? characters can be used as parameter\nmarkers to indicate where data values are to be bound to the query\nlater when you execute it. The ? characters should not be enclosed\nwithin quotation marks, even if you intend to bind them to string\nvalues. Parameter markers can be used only where data values should\nappear, not for SQL keywords, identifiers, and so forth.\n\nIf a prepared statement with the given name already exists, it is\ndeallocated implicitly before the new statement is prepared. This means\nthat if the new statement contains an error and cannot be prepared, an\nerror is returned and no statement with the given name exists.\n\nThe scope of a prepared statement is the session within which it is\ncreated, which as several implications:\n\no A prepared statement created in one session is not available to other\n sessions.\n\no When a session ends, whether normally or abnormally, its prepared\n statements no longer exist. If auto-reconnect is enabled, the client\n is not notified that the connection was lost. For this reason,\n clients may wish to disable auto-reconnect. See\n http://dev.mysql.com/doc/refman/5.7/en/c-api-auto-reconnect.html.\n\no A prepared statement created within a stored program continues to\n exist after the program finishes executing and can be executed\n outside the program later.\n\no A statement prepared in stored program context cannot refer to stored\n procedure or function parameters or local variables because they go\n out of scope when the program ends and would be unavailable were the\n statement to be executed later outside the program. As a workaround,\n refer instead to user-defined variables, which also have session\n scope; see\n http://dev.mysql.com/doc/refman/5.7/en/user-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/prepare.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/prepare.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (29,8,'LOCK','Syntax:\nLOCK TABLES\n tbl_name [[AS] alias] lock_type\n [, tbl_name [[AS] alias] lock_type] ...\n\nlock_type:\n READ [LOCAL]\n | [LOW_PRIORITY] WRITE\n\nUNLOCK TABLES\n\nMySQL enables client sessions to acquire table locks explicitly for the\npurpose of cooperating with other sessions for access to tables, or to\nprevent other sessions from modifying tables during periods when a\nsession requires exclusive access to them. A session can acquire or\nrelease locks only for itself. One session cannot acquire locks for\nanother session or release locks held by another session.\n\nLocks may be used to emulate transactions or to get more speed when\nupdating tables. This is explained in more detail later in this\nsection.\n\nLOCK TABLES explicitly acquires table locks for the current client\nsession. Table locks can be acquired for base tables or views. You must\nhave the LOCK TABLES privilege, and the SELECT privilege for each\nobject to be locked.\n\nFor view locking, LOCK TABLES adds all base tables used in the view to\nthe set of tables to be locked and locks them automatically. If you\nlock a table explicitly with LOCK TABLES, any tables used in triggers\nare also locked implicitly, as described in\nhttp://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-triggers.html.\n\nUNLOCK TABLES explicitly releases any table locks held by the current\nsession. LOCK TABLES implicitly releases any table locks held by the\ncurrent session before acquiring new locks.\n\nAnother use for UNLOCK TABLES is to release the global read lock\nacquired with the FLUSH TABLES WITH READ LOCK statement, which enables\nyou to lock all tables in all databases. See [HELP FLUSH]. (This is a\nvery convenient way to get backups if you have a file system such as\nVeritas that can take snapshots in time.)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (29,8,'LOCK','Syntax:\nLOCK TABLES\n tbl_name [[AS] alias] lock_type\n [, tbl_name [[AS] alias] lock_type] ...\n\nlock_type: {\n READ [LOCAL]\n | [LOW_PRIORITY] WRITE\n}\n\nUNLOCK TABLES\n\nMySQL enables client sessions to acquire table locks explicitly for the\npurpose of cooperating with other sessions for access to tables, or to\nprevent other sessions from modifying tables during periods when a\nsession requires exclusive access to them. A session can acquire or\nrelease locks only for itself. One session cannot acquire locks for\nanother session or release locks held by another session.\n\nLocks may be used to emulate transactions or to get more speed when\nupdating tables. This is explained in more detail later in this\nsection.\n\nLOCK TABLES explicitly acquires table locks for the current client\nsession. Table locks can be acquired for base tables or views. You must\nhave the LOCK TABLES privilege, and the SELECT privilege for each\nobject to be locked.\n\nFor view locking, LOCK TABLES adds all base tables used in the view to\nthe set of tables to be locked and locks them automatically. If you\nlock a table explicitly with LOCK TABLES, any tables used in triggers\nare also locked implicitly, as described in\nhttp://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-triggers.html.\n\nUNLOCK TABLES explicitly releases any table locks held by the current\nsession. LOCK TABLES implicitly releases any table locks held by the\ncurrent session before acquiring new locks.\n\nAnother use for UNLOCK TABLES is to release the global read lock\nacquired with the FLUSH TABLES WITH READ LOCK statement, which enables\nyou to lock all tables in all databases. See [HELP FLUSH]. (This is a\nvery convenient way to get backups if you have a file system such as\nVeritas that can take snapshots in time.)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (30,27,'SHOW BINARY LOGS','Syntax:\nSHOW BINARY LOGS\nSHOW MASTER LOGS\n\nLists the binary log files on the server. This statement is used as\npart of the procedure described in [HELP PURGE BINARY LOGS], that shows\nhow to determine which logs can be purged.\n\nmysql> SHOW BINARY LOGS;\n+---------------+-----------+\n| Log_name | File_size |\n+---------------+-----------+\n| binlog.000015 | 724935 |\n| binlog.000016 | 733481 |\n+---------------+-----------+\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-binary-logs.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-binary-logs.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (31,25,'POLYGON','Polygon(ls [, ls] ...)\n\nConstructs a Polygon value from a number of LineString or WKB\nLineString arguments. If any argument does not represent a LinearRing\n(that is, not a closed and simple LineString), the return value is\nNULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (32,32,'MINUTE','Syntax:\nMINUTE(time)\n\nReturns the minute for time, in the range 0 to 59.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT MINUTE(\'2008-02-03 10:05:03\');\n -> 5\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
@@ -117,7 +117,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (36,7,'JSON_SEARCH','Syntax:\nJSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path]\n...])\n\nReturns the path to the given string within a JSON document. Returns\nNULL if any of the json_doc, search_str, or path arguments are NULL; no\npath exists within the document; or search_str is not found. An error\noccurs if the json_doc argument is not a valid JSON document, any path\nargument is not a valid path expression, one_or_all is not \'one\' or\n\'all\', or escape_char is not a constant expression.\n\nThe one_or_all argument affects the search as follows:\n\no \'one\': The search terminates after the first match and returns one\n path string. It is undefined which match is considered first.\n\no \'all\': The search returns all matching path strings such that no\n duplicate paths are included. If there are multiple strings, they are\n autowrapped as an array. The order of the array elements is\n undefined.\n\nWithin the search_str search string argument, the % and _ characters\nwork as for the LIKE operator: % matches any number of characters\n(including zero characters), and _ matches exactly one character.\n\nTo specify a literal % or _ character in the search string, precede it\nby the escape character. The default is \\ if the escape_char argument\nis missing or NULL. Otherwise, escape_char must be a constant that is\nempty or one character.\n\nFor more information about matching and escape character behavior, see\nthe description of LIKE in\nhttp://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html\n. For escape character handling, a difference from the LIKE behavior is\nthat the escape character for JSON_SEARCH() must evaluate to a constant\nat compile time, not just at execution time. For example, if\nJSON_SEARCH() is used in a prepared statement and the escape_char\nargument is supplied using a ? parameter, the parameter value might be\nconstant at execution time, but is not at compile time.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html\n\n','mysql> SET @j = \'["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]\';\n\nmysql> SELECT JSON_SEARCH(@j, \'one\', \'abc\');\n+-------------------------------+\n| JSON_SEARCH(@j, \'one\', \'abc\') |\n+-------------------------------+\n| "$[0]" |\n+-------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'abc\');\n+-------------------------------+\n| JSON_SEARCH(@j, \'all\', \'abc\') |\n+-------------------------------+\n| ["$[0]", "$[2].x"] |\n+-------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'ghi\');\n+-------------------------------+\n| JSON_SEARCH(@j, \'all\', \'ghi\') |\n+-------------------------------+\n| NULL |\n+-------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\');\n+------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\') |\n+------------------------------+\n| "$[1][0].k" |\n+------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$\');\n+-----------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$\') |\n+-----------------------------------------+\n| "$[1][0].k" |\n+-----------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[*]\');\n+--------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[*]\') |\n+--------------------------------------------+\n| "$[1][0].k" |\n+--------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$**.k\');\n+---------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$**.k\') |\n+---------------------------------------------+\n| "$[1][0].k" |\n+---------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[*][0].k\');\n+-------------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[*][0].k\') |\n+-------------------------------------------------+\n| "$[1][0].k" |\n+-------------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[1]\');\n+--------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[1]\') |\n+--------------------------------------------+\n| "$[1][0].k" |\n+--------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[1][0]\');\n+-----------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'10\', NULL, \'$[1][0]\') |\n+-----------------------------------------------+\n| "$[1][0].k" |\n+-----------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'abc\', NULL, \'$[2]\');\n+---------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'abc\', NULL, \'$[2]\') |\n+---------------------------------------------+\n| "$[2].x" |\n+---------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%a%\');\n+-------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%a%\') |\n+-------------------------------+\n| ["$[0]", "$[2].x"] |\n+-------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%b%\');\n+-------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%b%\') |\n+-------------------------------+\n| ["$[0]", "$[2].x", "$[3].y"] |\n+-------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%b%\', NULL, \'$[0]\');\n+---------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%b%\', NULL, \'$[0]\') |\n+---------------------------------------------+\n| "$[0]" |\n+---------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%b%\', NULL, \'$[2]\');\n+---------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%b%\', NULL, \'$[2]\') |\n+---------------------------------------------+\n| "$[2].x" |\n+---------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%b%\', NULL, \'$[1]\');\n+---------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%b%\', NULL, \'$[1]\') |\n+---------------------------------------------+\n| NULL |\n+---------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%b%\', \'\', \'$[1]\');\n+-------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%b%\', \'\', \'$[1]\') |\n+-------------------------------------------+\n| NULL |\n+-------------------------------------------+\n\nmysql> SELECT JSON_SEARCH(@j, \'all\', \'%b%\', \'\', \'$[3]\');\n+-------------------------------------------+\n| JSON_SEARCH(@j, \'all\', \'%b%\', \'\', \'$[3]\') |\n+-------------------------------------------+\n| "$[3].y" |\n+-------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (37,24,'CLOSE','Syntax:\nCLOSE cursor_name\n\nThis statement closes a previously opened cursor. For an example, see\nhttp://dev.mysql.com/doc/refman/5.7/en/cursors.html.\n\nAn error occurs if the cursor is not open.\n\nIf not closed explicitly, a cursor is closed at the end of the BEGIN\n... END block in which it was declared.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/close.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/close.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (38,38,'REPLACE FUNCTION','Syntax:\nREPLACE(str,from_str,to_str)\n\nReturns the string str with all occurrences of the string from_str\nreplaced by the string to_str. REPLACE() performs a case-sensitive\nmatch when searching for from_str.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT REPLACE(\'www.mysql.com\', \'w\', \'Ww\');\n -> \'WwWwWw.mysql.com\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (39,29,'USE','Syntax:\nUSE db_name\n\nThe USE db_name statement tells MySQL to use the db_name database as\nthe default (current) database for subsequent statements. The database\nremains the default until the end of the session or another USE\nstatement is issued:\n\nUSE db1;\nSELECT COUNT(*) FROM mytable; # selects from db1.mytable\nUSE db2;\nSELECT COUNT(*) FROM mytable; # selects from db2.mytable\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/use.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/use.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (39,29,'USE','Syntax:\nUSE db_name\n\nThe USE db_name statement tells MySQL to use the db_name database as\nthe default (current) database for subsequent statements. The database\nremains the default until the end of the session or another USE\nstatement is issued:\n\nUSE db1;\nSELECT COUNT(*) FROM mytable; # selects from db1.mytable\nUSE db2;\nSELECT COUNT(*) FROM mytable; # selects from db2.mytable\n\nThe database name must be specified on a single line. Newlines in\ndatabase names are not supported.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/use.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/use.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (40,6,'CASE OPERATOR','Syntax:\nCASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN\nresult ...] [ELSE result] END\n\nCASE WHEN [condition] THEN result [WHEN [condition] THEN result ...]\n[ELSE result] END\n\nThe first CASE syntax returns the result for the first\nvalue=compare_value comparison that is true. The second syntax returns\nthe result for the first condition that is true. If no comparison or\ncondition is true, the result after ELSE is returned, or NULL if there\nis no ELSE part.\n\n*Note*:\n\nThe syntax of the CASE expression described here differs slightly from\nthat of the SQL CASE statement described in [HELP CASE statement], for\nuse inside stored programs. The CASE statement cannot have an ELSE NULL\nclause, and it is terminated with END CASE instead of END.\n\nThe return type of a CASE expression result is the aggregated type of\nall result values.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html\n\n','mysql> SELECT CASE 1 WHEN 1 THEN \'one\'\n -> WHEN 2 THEN \'two\' ELSE \'more\' END;\n -> \'one\'\nmysql> SELECT CASE WHEN 1>0 THEN \'true\' ELSE \'false\' END;\n -> \'true\'\nmysql> SELECT CASE BINARY \'B\'\n -> WHEN \'a\' THEN 1 WHEN \'b\' THEN 2 END;\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (41,27,'SHOW MASTER STATUS','Syntax:\nSHOW MASTER STATUS\n\nThis statement provides status information about the binary log files\nof the master. It requires either the SUPER or REPLICATION CLIENT\nprivilege.\n\nExample:\n\nmysql> SHOW MASTER STATUS\\G\n*************************** 1. row ***************************\n File: master-bin.000002\n Position: 1307\n Binlog_Do_DB: test\n Binlog_Ignore_DB: manual, mysql\nExecuted_Gtid_Set: 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5\n1 row in set (0.00 sec)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-master-status.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-master-status.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (42,32,'TO_SECONDS','Syntax:\nTO_SECONDS(expr)\n\nGiven a date or datetime expr, returns the number of seconds since the\nyear 0. If expr is not a valid date or datetime value, returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT TO_SECONDS(950501);\n -> 62966505600\nmysql> SELECT TO_SECONDS(\'2009-11-29\');\n -> 63426672000\nmysql> SELECT TO_SECONDS(\'2009-11-29 13:43:32\');\n -> 63426721412\nmysql> SELECT TO_SECONDS( NOW() );\n -> 63426721458\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
@@ -131,7 +131,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (50,23,'BLOB DATA TYPE','A BLOB is a binary large object that can hold a variable amount of\ndata. The four BLOB types are TINYBLOB, BLOB, MEDIUMBLOB, and LONGBLOB.\nThese differ only in the maximum length of the values they can hold.\nThe four TEXT types are TINYTEXT, TEXT, MEDIUMTEXT, and LONGTEXT. These\ncorrespond to the four BLOB types and have the same maximum lengths and\nstorage requirements. See\nhttp://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/blob.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/blob.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (51,17,'CURRENT_USER','Syntax:\nCURRENT_USER, CURRENT_USER()\n\nReturns the user name and host name combination for the MySQL account\nthat the server used to authenticate the current client. This account\ndetermines your access privileges. The return value is a string in the\nutf8 character set.\n\nThe value of CURRENT_USER() can differ from the value of USER().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT USER();\n -> \'davida@localhost\'\nmysql> SELECT * FROM mysql.user;\nERROR 1044: Access denied for user \'\'@\'localhost\' to\ndatabase \'mysql\'\nmysql> SELECT CURRENT_USER();\n -> \'@localhost\'\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (52,20,'<=','Syntax:\n<=\n\nLess than or equal:\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT 0.1 <= 2;\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (53,27,'SHOW PROFILES','Syntax:\nSHOW PROFILES\n\nThe SHOW PROFILES statement, together with SHOW PROFILE, displays\nprofiling information that indicates resource usage for statements\nexecuted during the course of the current session. For more\ninformation, see [HELP SHOW PROFILE].\n\n*Note*:\n\nThese statements are deprecated and will be removed in a future MySQL\nrelease. Use the Performance Schema instead; see\nhttp://dev.mysql.com/doc/refman/5.7/en/performance-schema.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-profiles.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-profiles.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (53,27,'SHOW PROFILES','Syntax:\nSHOW PROFILES\n\nThe SHOW PROFILES statement, together with SHOW PROFILE, displays\nprofiling information that indicates resource usage for statements\nexecuted during the course of the current session. For more\ninformation, see [HELP SHOW PROFILE].\n\n*Note*:\n\nThe SHOW PROFILE and SHOW PROFILES statements are deprecated and will\nbe removed in a future MySQL release. Use the Performance Schema\ninstead; see\nhttp://dev.mysql.com/doc/refman/5.7/en/performance-schema-query-profili\nng.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-profiles.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-profiles.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (54,28,'UPDATE','Syntax:\nUPDATE is a DML statement that modifies rows in a table.\n\nSingle-table syntax:\n\nUPDATE [LOW_PRIORITY] [IGNORE] table_reference\n SET assignment_list\n [WHERE where_condition]\n [ORDER BY ...]\n [LIMIT row_count]\n\nvalue:\n {expr | DEFAULT}\n\nassignment:\n col_name = value\n\nassignment_list:\n assignment [, assignment] ...\n\nMultiple-table syntax:\n\nUPDATE [LOW_PRIORITY] [IGNORE] table_references\n SET assignment_list\n [WHERE where_condition]\n\nFor the single-table syntax, the UPDATE statement updates columns of\nexisting rows in the named table with new values. The SET clause\nindicates which columns to modify and the values they should be given.\nEach value can be given as an expression, or the keyword DEFAULT to set\na column explicitly to its default value. The WHERE clause, if given,\nspecifies the conditions that identify which rows to update. With no\nWHERE clause, all rows are updated. If the ORDER BY clause is\nspecified, the rows are updated in the order that is specified. The\nLIMIT clause places a limit on the number of rows that can be updated.\n\nFor the multiple-table syntax, UPDATE updates rows in each table named\nin table_references that satisfy the conditions. Each matching row is\nupdated once, even if it matches the conditions multiple times. For\nmultiple-table syntax, ORDER BY and LIMIT cannot be used.\n\nFor partitioned tables, both the single-single and multiple-table forms\nof this statement support the use of a PARTITION option as part of a\ntable reference. This option takes a list of one or more partitions or\nsubpartitions (or both). Only the partitions (or subpartitions) listed\nare checked for matches, and a row that is not in any of these\npartitions or subpartitions is not updated, whether it satisfies the\nwhere_condition or not.\n\n*Note*:\n\nUnlike the case when using PARTITION with an INSERT or REPLACE\nstatement, an otherwise valid UPDATE ... PARTITION statement is\nconsidered successful even if no rows in the listed partitions (or\nsubpartitions) match the where_condition.\n\nFor more information and examples, see\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-selection.html.\n\nwhere_condition is an expression that evaluates to true for each row to\nbe updated. For expression syntax, see\nhttp://dev.mysql.com/doc/refman/5.7/en/expressions.html.\n\ntable_references and where_condition are specified as described in\nhttp://dev.mysql.com/doc/refman/5.7/en/select.html.\n\nYou need the UPDATE privilege only for columns referenced in an UPDATE\nthat are actually updated. You need only the SELECT privilege for any\ncolumns that are read but not modified.\n\nThe UPDATE statement supports the following modifiers:\n\no With the LOW_PRIORITY modifier, execution of the UPDATE is delayed\n until no other clients are reading from the table. This affects only\n storage engines that use only table-level locking (such as MyISAM,\n MEMORY, and MERGE).\n\no With the IGNORE modifier, the update statement does not abort even if\n errors occur during the update. Rows for which duplicate-key\n conflicts occur on a unique key value are not updated. Rows updated\n to values that would cause data conversion errors are updated to the\n closest valid values instead. For more information, see\n http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#ignore-strict-co\n mparison.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/update.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/update.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (55,24,'CASE STATEMENT','Syntax:\nCASE case_value\n WHEN when_value THEN statement_list\n [WHEN when_value THEN statement_list] ...\n [ELSE statement_list]\nEND CASE\n\nOr:\n\nCASE\n WHEN search_condition THEN statement_list\n [WHEN search_condition THEN statement_list] ...\n [ELSE statement_list]\nEND CASE\n\nThe CASE statement for stored programs implements a complex conditional\nconstruct.\n\n*Note*:\n\nThere is also a CASE expression, which differs from the CASE statement\ndescribed here. See\nhttp://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html. The\nCASE statement cannot have an ELSE NULL clause, and it is terminated\nwith END CASE instead of END.\n\nFor the first syntax, case_value is an expression. This value is\ncompared to the when_value expression in each WHEN clause until one of\nthem is equal. When an equal when_value is found, the corresponding\nTHEN clause statement_list executes. If no when_value is equal, the\nELSE clause statement_list executes, if there is one.\n\nThis syntax cannot be used to test for equality with NULL because NULL\n= NULL is false. See\nhttp://dev.mysql.com/doc/refman/5.7/en/working-with-null.html.\n\nFor the second syntax, each WHEN clause search_condition expression is\nevaluated until one is true, at which point its corresponding THEN\nclause statement_list executes. If no search_condition is equal, the\nELSE clause statement_list executes, if there is one.\n\nIf no when_value or search_condition matches the value tested and the\nCASE statement contains no ELSE clause, a Case not found for CASE\nstatement error results.\n\nEach statement_list consists of one or more SQL statements; an empty\nstatement_list is not permitted.\n\nTo handle situations where no value is matched by any WHEN clause, use\nan ELSE containing an empty BEGIN ... END block, as shown in this\nexample. (The indentation used here in the ELSE clause is for purposes\nof clarity only, and is not otherwise significant.)\n\nDELIMITER |\n\nCREATE PROCEDURE p()\n BEGIN\n DECLARE v INT DEFAULT 1;\n\n CASE v\n WHEN 2 THEN SELECT v;\n WHEN 3 THEN SELECT 0;\n ELSE\n BEGIN\n END;\n END CASE;\n END;\n |\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/case.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/case.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (56,7,'ST_SIMPLIFY','ST_Simplify(g, max_distance)\n\nSimplifies a geometry using the Douglas-Peucker algorithm and returns a\nsimplified value of the same type. If any argument is NULL, the return\nvalue is NULL.\n\nThe geometry may be any geometry type, although the Douglas-Peucker\nalgorithm may not actually process every type. A geometry collection is\nprocessed by giving its components one by one to the simplification\nalgorithm, and the returned geometries are put into a geometry\ncollection as result.\n\nThe max_distance argument is the distance (in units of the input\ncoordinates) of a vertex to other segments to be removed. Vertices\nwithin this distance of the simplified linestring are removed. If the\nmax_distance argument is not positive, or is NaN, an ER_WRONG_ARGUMENTS\nerror occurs.\n\nAccording to Boost.Geometry, geometries might become invalid as a\nresult of the simplification process, and the process might create\nself-intersections. To check the validity of the result, pass it to\nST_IsValid().\n\nIf the geometry argument is not a syntactically well-formed geometry\nbyte string, an ER_GIS_INVALID_DATA error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html\n\n','mysql> SET @g = ST_GeomFromText(\'LINESTRING(0 0,0 1,1 1,1 2,2 2,2 3,3 3)\');\nmysql> SELECT ST_AsText(ST_Simplify(@g, 0.5));\n+---------------------------------+\n| ST_AsText(ST_Simplify(@g, 0.5)) |\n+---------------------------------+\n| LINESTRING(0 0,0 1,1 1,2 3,3 3) |\n+---------------------------------+\nmysql> SELECT ST_AsText(ST_Simplify(@g, 1.0));\n+---------------------------------+\n| ST_AsText(ST_Simplify(@g, 1.0)) |\n+---------------------------------+\n| LINESTRING(0 0,3 3) |\n+---------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html');
@@ -143,14 +143,14 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (62,38,'NOT LIKE','Syntax:\nexpr NOT LIKE pat [ESCAPE \'escape_char\']\n\nThis is the same as NOT (expr LIKE pat [ESCAPE \'escape_char\']).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (63,38,'SPACE','Syntax:\nSPACE(N)\n\nReturns a string consisting of N space characters.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT SPACE(6);\n -> \' \'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (64,16,'MAX','Syntax:\nMAX([DISTINCT] expr)\n\nReturns the maximum value of expr. MAX() may take a string argument; in\nsuch cases, it returns the maximum string value. See\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html. The DISTINCT\nkeyword can be used to find the maximum of the distinct values of expr,\nhowever, this produces the same result as omitting DISTINCT.\n\nIf there are no matching rows, MAX() returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','mysql> SELECT student_name, MIN(test_score), MAX(test_score)\n FROM student\n GROUP BY student_name;\n','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (65,22,'CREATE FUNCTION UDF','Syntax:\nCREATE [AGGREGATE] FUNCTION function_name\n RETURNS {STRING|INTEGER|REAL|DECIMAL}\n SONAME shared_library_name\n\nA user-defined function (UDF) is a way to extend MySQL with a new\nfunction that works like a native (built-in) MySQL function such as\nABS() or CONCAT().\n\nfunction_name is the name that should be used in SQL statements to\ninvoke the function. The RETURNS clause indicates the type of the\nfunction\'s return value. DECIMAL is a legal value after RETURNS, but\ncurrently DECIMAL functions return string values and should be written\nlike STRING functions.\n\nshared_library_name is the base name of the shared library file that\ncontains the code that implements the function. The file must be\nlocated in the plugin directory. This directory is given by the value\nof the plugin_dir system variable. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/udf-compiling.html.\n\nTo create a function, you must have the INSERT privilege for the mysql\ndatabase. This is necessary because CREATE FUNCTION adds a row to the\nmysql.func system table that records the function\'s name, type, and\nshared library name. If you do not have this table, you should run the\nmysql_upgrade command to create it. See\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-upgrade.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-function-udf.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-function-udf.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (65,22,'CREATE FUNCTION UDF','Syntax:\nCREATE [AGGREGATE] FUNCTION function_name\n RETURNS {STRING|INTEGER|REAL|DECIMAL}\n SONAME shared_library_name\n\nA user-defined function (UDF) is a way to extend MySQL with a new\nfunction that works like a native (built-in) MySQL function such as\nABS() or CONCAT().\n\nfunction_name is the name that should be used in SQL statements to\ninvoke the function. The RETURNS clause indicates the type of the\nfunction\'s return value. DECIMAL is a legal value after RETURNS, but\ncurrently DECIMAL functions return string values and should be written\nlike STRING functions.\n\nshared_library_name is the base name of the shared library file that\ncontains the code that implements the function. The file must be\nlocated in the plugin directory. This directory is given by the value\nof the plugin_dir system variable. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/udf-compiling.html.\n\nTo create a function, you must have the INSERT privilege for the mysql\nsystem database. This is necessary because CREATE FUNCTION adds a row\nto the mysql.func system table that records the function\'s name, type,\nand shared library name. If you do not have this table, you should run\nthe mysql_upgrade command to create it. See\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-upgrade.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-function-udf.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-function-udf.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (66,23,'TIMESTAMP','TIMESTAMP[(fsp)]\n\nA timestamp. The range is \'1970-01-01 00:00:01.000000\' UTC to\n\'2038-01-19 03:14:07.999999\' UTC. TIMESTAMP values are stored as the\nnumber of seconds since the epoch (\'1970-01-01 00:00:00\' UTC). A\nTIMESTAMP cannot represent the value \'1970-01-01 00:00:00\' because that\nis equivalent to 0 seconds from the epoch and the value 0 is reserved\nfor representing \'0000-00-00 00:00:00\', the "zero" TIMESTAMP value.\n\nAn optional fsp value in the range from 0 to 6 may be given to specify\nfractional seconds precision. A value of 0 signifies that there is no\nfractional part. If omitted, the default precision is 0.\n\nThe way the server handles TIMESTAMP definitions depends on the value\nof the explicit_defaults_for_timestamp system variable (see\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html).\n\nIf explicit_defaults_for_timestamp is enabled, there is no automatic\nassignment of the DEFAULT CURRENT_TIMESTAMP or ON UPDATE\nCURRENT_TIMESTAMP attributes to any TIMESTAMP column. They must be\nincluded explicitly in the column definition. Also, any TIMESTAMP not\nexplicitly declared as NOT NULL permits NULL values.\n\nIf explicit_defaults_for_timestamp is disabled, the server handles\nTIMESTAMP as follows:\n\nUnless specified otherwise, the first TIMESTAMP column in a table is\ndefined to be automatically set to the date and time of the most recent\nmodification if not explicitly assigned a value. This makes TIMESTAMP\nuseful for recording the timestamp of an INSERT or UPDATE operation.\nYou can also set any TIMESTAMP column to the current date and time by\nassigning it a NULL value, unless it has been defined with the NULL\nattribute to permit NULL values.\n\nAutomatic initialization and updating to the current date and time can\nbe specified using DEFAULT CURRENT_TIMESTAMP and ON UPDATE\nCURRENT_TIMESTAMP column definition clauses. By default, the first\nTIMESTAMP column has these properties, as previously noted. However,\nany TIMESTAMP column in a table can be defined to have these\nproperties.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (67,7,'CREATE_ASYMMETRIC_PUB_KEY','Syntax:\nCREATE_ASYMMETRIC_PUB_KEY(algorithm, priv_key_str)\n\nDerives a public key from the given private key using the given\nalgorithm, and returns the key as a binary string in PEM format. If key\nderivation fails, the result is NULL.\n\npriv_key_str must be a valid key string in PEM format. algorithm\nindicates the encryption algorithm used to create the key.\n\nSupported algorithm values: \'RSA\', \'DSA\', \'DH\'\n\nFor a usage example, see the description of\nCREATE_ASYMMETRIC_PRIV_KEY().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (68,27,'CACHE INDEX','Syntax:\nCACHE INDEX\n tbl_index_list [, tbl_index_list] ...\n [PARTITION (partition_list | ALL)]\n IN key_cache_name\n\ntbl_index_list:\n tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]\n\npartition_list:\n partition_name[, partition_name][, ...]\n\nThe CACHE INDEX statement assigns table indexes to a specific key\ncache. It is used only for MyISAM tables. After the indexes have been\nassigned, they can be preloaded into the cache if desired with LOAD\nINDEX INTO CACHE.\n\nThe following statement assigns indexes from the tables t1, t2, and t3\nto the key cache named hot_cache:\n\nmysql> CACHE INDEX t1, t2, t3 IN hot_cache;\n+---------+--------------------+----------+----------+\n| Table | Op | Msg_type | Msg_text |\n+---------+--------------------+----------+----------+\n| test.t1 | assign_to_keycache | status | OK |\n| test.t2 | assign_to_keycache | status | OK |\n| test.t3 | assign_to_keycache | status | OK |\n+---------+--------------------+----------+----------+\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/cache-index.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/cache-index.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (69,12,'COMPRESS','Syntax:\nCOMPRESS(string_to_compress)\n\nCompresses a string and returns the result as a binary string. This\nfunction requires MySQL to have been compiled with a compression\nlibrary such as zlib. Otherwise, the return value is always NULL. The\ncompressed string can be uncompressed with UNCOMPRESS().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SELECT LENGTH(COMPRESS(REPEAT(\'a\',1000)));\n -> 21\nmysql> SELECT LENGTH(COMPRESS(\'\'));\n -> 0\nmysql> SELECT LENGTH(COMPRESS(\'a\'));\n -> 13\nmysql> SELECT LENGTH(COMPRESS(REPEAT(\'a\',16)));\n -> 15\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (70,28,'HANDLER','Syntax:\nHANDLER tbl_name OPEN [ [AS] alias]\n\nHANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)\n [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }\n [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name READ { FIRST | NEXT }\n [ WHERE where_condition ] [LIMIT ... ]\n\nHANDLER tbl_name CLOSE\n\nThe HANDLER statement provides direct access to table storage engine\ninterfaces. It is available for InnoDB and MyISAM tables.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/handler.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/handler.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (71,9,'HELP_DATE','This help information was generated from the MySQL 5.7 Reference Manual\non: 2018-06-07\n','','');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (72,40,'RENAME TABLE','Syntax:\nRENAME TABLE\n tbl_name TO new_tbl_name\n [, tbl_name2 TO new_tbl_name2] ...\n\nRENAME TABLE renames one or more tables. You must have ALTER and DROP\nprivileges for the original table, and CREATE and INSERT privileges for\nthe new table.\n\nFor example, to rename a table named old_table to to new_table, use\nthis statement:\n\nRENAME TABLE old_table TO new_table;\n\nThat statement is equivalent to the following ALTER TABLE statement:\n\nALTER TABLE old_table RENAME new_table;\n\nRENAME TABLE, unlike ALTER TABLE, can rename multiple tables within a\nsingle statement:\n\nRENAME TABLE old_table1 TO new_table1,\n old_table2 TO new_table2,\n old_table3 TO new_table3;\n\nRenaming operations are performed left to right. Thus, to swap two\ntable names, do this (assuming that a table with the intermediary name\ntmp_table does not already exist):\n\nRENAME TABLE old_table TO tmp_table,\n new_table TO old_table,\n tmp_table TO new_table;\n\nWhen you execute RENAME TABLE, you cannot have any locked tables or\nactive transactions. With that condition satisfied, the rename\noperation is done atomically; no other session can access any of the\ntables while the rename is in progress.\n\nIf any errors occur during a RENAME TABLE, the statement fails and no\nchanges are made.\n\nYou can use RENAME TABLE to move a table from one database to another:\n\nRENAME TABLE current_db.tbl_name TO other_db.tbl_name;\n\nUsing this method to move all tables from one database to a different\none in effect renames the database (an operation for which MySQL has no\nsingle statement), except that the original database continues to\nexist, albeit with no tables.\n\nLike RENAME TABLE, ALTER TABLE ... RENAME can also be used to move a\ntable to a different database. Regardless of the statement used, if the\nrename operation would move the table to a database located on a\ndifferent file system, the success of the outcome is platform specific\nand depends on the underlying operating system calls used to move the\ntable files.\n\nIf a table has triggers, attempts to rename the table into a different\ndatabase fail with a Trigger in wrong schema error.\n\nRENAME TABLE does not work for TEMPORARY tables. However, you can use\nALTER TABLE to rename TEMPORARY tables.\n\nRENAME TABLE works for views, except that views cannot be renamed into\na different database.\n\nAny privileges granted specifically for a renamed table or view are not\nmigrated to the new name. They must be changed manually.\n\nRENAME TABLE changes internally generated foreign key constraint names\nand user-defined foreign key constraint names that contain the string\n"tbl_name_ibfk_" to reflect the new table name. InnoDB interprets\nforeign key constraint names that contain the string "tbl_name_ibfk_"\nas internally generated names.\n\nForeign key constraint names that point to the renamed table are\nautomatically updated unless there is a conflict, in which case, the\nstatement fails with an error. A conflict occurs if the renamed\nconstraint name already exists. In such cases, you must drop and\nre-create the foreign keys in order for them to function properly.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/rename-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/rename-table.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (71,9,'HELP_DATE','This help information was generated from the MySQL 5.7 Reference Manual\non: 2018-10-03\n','','');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (72,40,'RENAME TABLE','Syntax:\nRENAME TABLE\n tbl_name TO new_tbl_name\n [, tbl_name2 TO new_tbl_name2] ...\n\nRENAME TABLE renames one or more tables. You must have ALTER and DROP\nprivileges for the original table, and CREATE and INSERT privileges for\nthe new table.\n\nFor example, to rename a table named old_table to to new_table, use\nthis statement:\n\nRENAME TABLE old_table TO new_table;\n\nThat statement is equivalent to the following ALTER TABLE statement:\n\nALTER TABLE old_table RENAME new_table;\n\nRENAME TABLE, unlike ALTER TABLE, can rename multiple tables within a\nsingle statement:\n\nRENAME TABLE old_table1 TO new_table1,\n old_table2 TO new_table2,\n old_table3 TO new_table3;\n\nRenaming operations are performed left to right. Thus, to swap two\ntable names, do this (assuming that a table with the intermediary name\ntmp_table does not already exist):\n\nRENAME TABLE old_table TO tmp_table,\n new_table TO old_table,\n tmp_table TO new_table;\n\nTo execute RENAME TABLE, there must be no active transactions or tables\nlocked with LOCK TABLES. With the transaction table locking conditions\nsatisfied, the rename operation is done atomically; no other session\ncan access any of the tables while the rename is in progress.\n\nIf any errors occur during a RENAME TABLE, the statement fails and no\nchanges are made.\n\nYou can use RENAME TABLE to move a table from one database to another:\n\nRENAME TABLE current_db.tbl_name TO other_db.tbl_name;\n\nUsing this method to move all tables from one database to a different\none in effect renames the database (an operation for which MySQL has no\nsingle statement), except that the original database continues to\nexist, albeit with no tables.\n\nLike RENAME TABLE, ALTER TABLE ... RENAME can also be used to move a\ntable to a different database. Regardless of the statement used, if the\nrename operation would move the table to a database located on a\ndifferent file system, the success of the outcome is platform specific\nand depends on the underlying operating system calls used to move table\nfiles.\n\nIf a table has triggers, attempts to rename the table into a different\ndatabase fail with a Trigger in wrong schema (ER_TRG_IN_WRONG_SCHEMA)\nerror.\n\nTo rename TEMPORARY tables, RENAME TABLE does not work. Use ALTER TABLE\ninstead.\n\nRENAME TABLE works for views, except that views cannot be renamed into\na different database.\n\nAny privileges granted specifically for a renamed table or view are not\nmigrated to the new name. They must be changed manually.\n\nRENAME TABLE changes internally generated foreign key constraint names\nand user-defined foreign key constraint names that contain the string\n"tbl_name_ibfk_" to reflect the new table name. InnoDB interprets\nforeign key constraint names that contain the string "tbl_name_ibfk_"\nas internally generated names.\n\nForeign key constraint names that point to the renamed table are\nautomatically updated unless there is a conflict, in which case the\nstatement fails with an error. A conflict occurs if the renamed\nconstraint name already exists. In such cases, you must drop and\nre-create the foreign keys for them to function properly.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/rename-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/rename-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (73,23,'BOOLEAN','BOOL, BOOLEAN\n\nThese types are synonyms for TINYINT(1). A value of zero is considered\nfalse. Nonzero values are considered true:\n\nmysql> SELECT IF(0, \'true\', \'false\');\n+------------------------+\n| IF(0, \'true\', \'false\') |\n+------------------------+\n| false |\n+------------------------+\n\nmysql> SELECT IF(1, \'true\', \'false\');\n+------------------------+\n| IF(1, \'true\', \'false\') |\n+------------------------+\n| true |\n+------------------------+\n\nmysql> SELECT IF(2, \'true\', \'false\');\n+------------------------+\n| IF(2, \'true\', \'false\') |\n+------------------------+\n| true |\n+------------------------+\n\nHowever, the values TRUE and FALSE are merely aliases for 1 and 0,\nrespectively, as shown here:\n\nmysql> SELECT IF(0 = FALSE, \'true\', \'false\');\n+--------------------------------+\n| IF(0 = FALSE, \'true\', \'false\') |\n+--------------------------------+\n| true |\n+--------------------------------+\n\nmysql> SELECT IF(1 = TRUE, \'true\', \'false\');\n+-------------------------------+\n| IF(1 = TRUE, \'true\', \'false\') |\n+-------------------------------+\n| true |\n+-------------------------------+\n\nmysql> SELECT IF(2 = TRUE, \'true\', \'false\');\n+-------------------------------+\n| IF(2 = TRUE, \'true\', \'false\') |\n+-------------------------------+\n| false |\n+-------------------------------+\n\nmysql> SELECT IF(2 = FALSE, \'true\', \'false\');\n+--------------------------------+\n| IF(2 = FALSE, \'true\', \'false\') |\n+--------------------------------+\n| false |\n+--------------------------------+\n\nThe last two statements display the results shown because 2 is equal to\nneither 1 nor 0.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (74,7,'JSON_EXTRACT','Syntax:\nJSON_EXTRACT(json_doc, path[, path] ...)\n\nReturns data from a JSON document, selected from the parts of the\ndocument matched by the path arguments. Returns NULL if any argument is\nNULL or no paths locate a value in the document. An error occurs if the\njson_doc argument is not a valid JSON document or any path argument is\nnot a valid path expression.\n\nThe return value consists of all values matched by the path arguments.\nIf it is possible that those arguments could return multiple values,\nthe matched values are autowrapped as an array, in the order\ncorresponding to the paths that produced them. Otherwise, the return\nvalue is the single matched value.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html\n\n','mysql> SELECT JSON_EXTRACT(\'[10, 20, [30, 40]]\', \'$[1]\');\n+--------------------------------------------+\n| JSON_EXTRACT(\'[10, 20, [30, 40]]\', \'$[1]\') |\n+--------------------------------------------+\n| 20 |\n+--------------------------------------------+\nmysql> SELECT JSON_EXTRACT(\'[10, 20, [30, 40]]\', \'$[1]\', \'$[0]\');\n+----------------------------------------------------+\n| JSON_EXTRACT(\'[10, 20, [30, 40]]\', \'$[1]\', \'$[0]\') |\n+----------------------------------------------------+\n| [20, 10] |\n+----------------------------------------------------+\nmysql> SELECT JSON_EXTRACT(\'[10, 20, [30, 40]]\', \'$[2][*]\');\n+-----------------------------------------------+\n| JSON_EXTRACT(\'[10, 20, [30, 40]]\', \'$[2][*]\') |\n+-----------------------------------------------+\n| [30, 40] |\n+-----------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (75,3,'MOD','Syntax:\nMOD(N,M), N % M, N MOD M\n\nModulo operation. Returns the remainder of N divided by M.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT MOD(234, 10);\n -> 4\nmysql> SELECT 253 % 7;\n -> 1\nmysql> SELECT MOD(29,9);\n -> 2\nmysql> SELECT 29 MOD 9;\n -> 2\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
@@ -186,21 +186,21 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (105,27,'SHOW DATABASES','Syntax:\nSHOW {DATABASES | SCHEMAS}\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW DATABASES lists the databases on the MySQL server host. SHOW\nSCHEMAS is a synonym for SHOW DATABASES. The LIKE clause, if present,\nindicates which database names to match. The WHERE clause can be given\nto select rows using more general conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nYou see only those databases for which you have some kind of privilege,\nunless you have the global SHOW DATABASES privilege. You can also get\nthis list using the mysqlshow command.\n\nIf the server was started with the --skip-show-database option, you\ncannot use this statement at all unless you have the SHOW DATABASES\nprivilege.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-databases.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-databases.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (106,32,'SEC_TO_TIME','Syntax:\nSEC_TO_TIME(seconds)\n\nReturns the seconds argument, converted to hours, minutes, and seconds,\nas a TIME value. The range of the result is constrained to that of the\nTIME data type. A warning occurs if the argument corresponds to a value\noutside that range.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT SEC_TO_TIME(2378);\n -> \'00:39:38\'\nmysql> SELECT SEC_TO_TIME(2378) + 0;\n -> 3938\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (107,38,'LOCATE','Syntax:\nLOCATE(substr,str), LOCATE(substr,str,pos)\n\nThe first syntax returns the position of the first occurrence of\nsubstring substr in string str. The second syntax returns the position\nof the first occurrence of substring substr in string str, starting at\nposition pos. Returns 0 if substr is not in str. Returns NULL if substr\nor str is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT LOCATE(\'bar\', \'foobarbar\');\n -> 4\nmysql> SELECT LOCATE(\'xbar\', \'foobar\');\n -> 0\nmysql> SELECT LOCATE(\'bar\', \'foobarbar\', 5);\n -> 7\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (108,27,'SHOW EVENTS','Syntax:\nSHOW EVENTS\n [{FROM | IN} schema_name]\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement displays information about Event Manager events. It\nrequires the EVENT privilege for the database from which the events are\nto be shown.\n\nIn its simplest form, SHOW EVENTS lists all of the events in the\ncurrent schema:\n\nmysql> SELECT CURRENT_USER(), SCHEMA();\n+----------------+----------+\n| CURRENT_USER() | SCHEMA() |\n+----------------+----------+\n| jon@ghidora | myschema |\n+----------------+----------+\n1 row in set (0.00 sec)\n\nmysql> SHOW EVENTS\\G\n*************************** 1. row ***************************\n Db: myschema\n Name: e_daily\n Definer: jon@ghidora\n Time zone: SYSTEM\n Type: RECURRING\n Execute at: NULL\n Interval value: 10\n Interval field: SECOND\n Starts: 2006-02-09 10:41:23\n Ends: NULL\n Status: ENABLED\n Originator: 0\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nTo see events for a specific schema, use the FROM clause. For example,\nto see events for the test schema, use the following statement:\n\nSHOW EVENTS FROM test;\n\nThe LIKE clause, if present, indicates which event names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-events.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-events.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (108,27,'SHOW EVENTS','Syntax:\nSHOW EVENTS\n [{FROM | IN} schema_name]\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement displays information about Event Manager events, which\nare discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html. It\nrequires the EVENT privilege for the database from which the events are\nto be shown.\n\nIn its simplest form, SHOW EVENTS lists all of the events in the\ncurrent schema:\n\nmysql> SELECT CURRENT_USER(), SCHEMA();\n+----------------+----------+\n| CURRENT_USER() | SCHEMA() |\n+----------------+----------+\n| jon@ghidora | myschema |\n+----------------+----------+\n1 row in set (0.00 sec)\n\nmysql> SHOW EVENTS\\G\n*************************** 1. row ***************************\n Db: myschema\n Name: e_daily\n Definer: jon@ghidora\n Time zone: SYSTEM\n Type: RECURRING\n Execute at: NULL\n Interval value: 1\n Interval field: DAY\n Starts: 2018-08-08 11:06:34\n Ends: NULL\n Status: ENABLED\n Originator: 1\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n\nTo see events for a specific schema, use the FROM clause. For example,\nto see events for the test schema, use the following statement:\n\nSHOW EVENTS FROM test;\n\nThe LIKE clause, if present, indicates which event names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-events.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-events.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (109,7,'JSON_INSERT','Syntax:\nJSON_INSERT(json_doc, path, val[, path, val] ...)\n\nInserts data into a JSON document and returns the result. Returns NULL\nif any argument is NULL. An error occurs if the json_doc argument is\nnot a valid JSON document or any path argument is not a valid path\nexpression or contains a * or ** wildcard.\n\nThe path-value pairs are evaluated left to right. The document produced\nby evaluating one pair becomes the new value against which the next\npair is evaluated.\n\nA path-value pair for an existing path in the document is ignored and\ndoes not overwrite the existing document value. A path-value pair for a\nnonexisting path in the document adds the value to the document if the\npath identifies one of these types of values:\n\no A member not present in an existing object. The member is added to\n the object and associated with the new value.\n\no A position past the end of an existing array. The array is extended\n with the new value. If the existing value is not an array, it is\n autowrapped as an array, then extended with the new value.\n\nOtherwise, a path-value pair for a nonexisting path in the document is\nignored and has no effect.\n\nFor a comparison of JSON_INSERT(), JSON_REPLACE(), and JSON_SET(), see\nthe discussion of JSON_SET().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html\n\n','mysql> SET @j = \'{ "a": 1, "b": [2, 3]}\';\nmysql> SELECT JSON_INSERT(@j, \'$.a\', 10, \'$.c\', \'[true, false]\');\n+----------------------------------------------------+\n| JSON_INSERT(@j, \'$.a\', 10, \'$.c\', \'[true, false]\') |\n+----------------------------------------------------+\n| {"a": 1, "b": [2, 3], "c": "[true, false]"} |\n+----------------------------------------------------+\n\nmysql> SELECT JSON_INSERT(@j, \'$.a\', 10, \'$.c\', CAST(\'[true, false]\' AS JSON));\n+------------------------------------------------------------------+\n| JSON_INSERT(@j, \'$.a\', 10, \'$.c\', CAST(\'[true, false]\' AS JSON)) |\n+------------------------------------------------------------------+\n| {"a": 1, "b": [2, 3], "c": [true, false]} |\n+------------------------------------------------------------------+\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (110,7,'JSON_UNQUOTE','Syntax:\nJSON_UNQUOTE(json_val)\n\nUnquotes JSON value and returns the result as a utf8mb4 string. Returns\nNULL if the argument is NULL. An error occurs if the value starts and\nends with double quotes but is not a valid JSON string literal.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html\n\n','mysql> SET @j = \'"abc"\';\nmysql> SELECT @j, JSON_UNQUOTE(@j);\n+-------+------------------+\n| @j | JSON_UNQUOTE(@j) |\n+-------+------------------+\n| "abc" | abc |\n+-------+------------------+\nmysql> SET @j = \'[1, 2, 3]\';\nmysql> SELECT @j, JSON_UNQUOTE(@j);\n+-----------+------------------+\n| @j | JSON_UNQUOTE(@j) |\n+-----------+------------------+\n| [1, 2, 3] | [1, 2, 3] |\n+-----------+------------------+\n\nmysql> SELECT @@sql_mode;\n+------------+\n| @@sql_mode |\n+------------+\n| |\n+------------+\n\nmysql> SELECT JSON_UNQUOTE(\'"\\\\t\\\\u0032"\');\n+------------------------------+\n| JSON_UNQUOTE(\'"\\\\t\\\\u0032"\') |\n+------------------------------+\n| 2 |\n+------------------------------+\n\nmysql> SET @@sql_mode = \'NO_BACKSLASH_ESCAPES\';\nmysql> SELECT JSON_UNQUOTE(\'"\\\\t\\\\u0032"\');\n+------------------------------+\n| JSON_UNQUOTE(\'"\\\\t\\\\u0032"\') |\n+------------------------------+\n| \\t\\u0032 |\n+------------------------------+\n\nmysql> SELECT JSON_UNQUOTE(\'"\\t\\u0032"\');\n+----------------------------+\n| JSON_UNQUOTE(\'"\\t\\u0032"\') |\n+----------------------------+\n| 2 |\n+----------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (111,23,'LONGTEXT','LONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nA TEXT column with a maximum length of 4,294,967,295 or 4GB (232 − 1)\ncharacters. The effective maximum length is less if the value contains\nmultibyte characters. The effective maximum length of LONGTEXT columns\nalso depends on the configured maximum packet size in the client/server\nprotocol and available memory. Each LONGTEXT value is stored using a\n4-byte length prefix that indicates the number of bytes in the value.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (112,27,'KILL','Syntax:\nKILL [CONNECTION | QUERY] processlist_id\n\nEach connection to mysqld runs in a separate thread. You can kill a\nthread with the KILL processlist_id statement.\n\nThread processlist identifiers can be determined from the ID column of\nthe INFORMATION_SCHEMA.PROCESSLIST table, the Id column of SHOW\nPROCESSLIST output, and the PROCESSLIST_ID column of the Performance\nSchema threads table. The value for the current thread is returned by\nthe CONNECTION_ID() function.\n\nKILL permits an optional CONNECTION or QUERY modifier:\n\no KILL CONNECTION is the same as KILL with no modifier: It terminates\n the connection associated with the given processlist_id, after\n terminating any statement the connection is executing.\n\no KILL QUERY terminates the statement the connection is currently\n executing, but leaves the connection itself intact.\n\nIf you have the PROCESS privilege, you can see all threads. If you have\nthe SUPER privilege, you can kill all threads and statements.\nOtherwise, you can see and kill only your own threads and statements.\n\nYou can also use the mysqladmin processlist and mysqladmin kill\ncommands to examine and kill threads.\n\n*Note*:\n\nYou cannot use KILL with the Embedded MySQL Server library because the\nembedded server merely runs inside the threads of the host application.\nIt does not create any connection threads of its own.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/kill.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/kill.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (112,27,'KILL','Syntax:\nKILL [CONNECTION | QUERY] processlist_id\n\nEach connection to mysqld runs in a separate thread. You can kill a\nthread with the KILL processlist_id statement.\n\nThread processlist identifiers can be determined from the ID column of\nthe INFORMATION_SCHEMA PROCESSLIST table, the Id column of SHOW\nPROCESSLIST output, and the PROCESSLIST_ID column of the Performance\nSchema threads table. The value for the current thread is returned by\nthe CONNECTION_ID() function.\n\nKILL permits an optional CONNECTION or QUERY modifier:\n\no KILL CONNECTION is the same as KILL with no modifier: It terminates\n the connection associated with the given processlist_id, after\n terminating any statement the connection is executing.\n\no KILL QUERY terminates the statement the connection is currently\n executing, but leaves the connection itself intact.\n\nIf you have the PROCESS privilege, you can see all threads. If you have\nthe SUPER privilege, you can kill all threads and statements.\nOtherwise, you can see and kill only your own threads and statements.\n\nYou can also use the mysqladmin processlist and mysqladmin kill\ncommands to examine and kill threads.\n\n*Note*:\n\nYou cannot use KILL with the Embedded MySQL Server library because the\nembedded server merely runs inside the threads of the host application.\nIt does not create any connection threads of its own.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/kill.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/kill.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (113,7,'DISJOINT','Disjoint(g1, g2)\n\nMBRDisjoint() and Disjoint() are synonyms. For more information, see\nthe description of MBRDisjoint().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (114,38,'LPAD','Syntax:\nLPAD(str,len,padstr)\n\nReturns the string str, left-padded with the string padstr to a length\nof len characters. If str is longer than len, the return value is\nshortened to len characters.\n\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT LPAD(\'hi\',4,\'??\');\n -> \'??hi\'\nmysql> SELECT LPAD(\'hi\',1,\'??\');\n -> \'h\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (115,7,'OVERLAPS','Overlaps(g1, g2)\n\nMBROverlaps() and Overlaps() are synonyms. For more information, see\nthe description of MBROverlaps().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (116,8,'SET GLOBAL SQL_SLAVE_SKIP_COUNTER','Syntax:\nSET GLOBAL sql_slave_skip_counter = N\n\nThis statement skips the next N events from the master. This is useful\nfor recovering from replication stops caused by a statement.\n\nThis statement is valid only when the slave threads are not running.\nOtherwise, it produces an error.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-global-sql-slave-skip-counter.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-global-sql-slave-skip-counter.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (117,7,'MBREQUAL','MBREqual(g1, g2)\n\nReturns 1 or 0 to indicate whether the minimum bounding rectangles of\nthe two geometries g1 and g2 are the same.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (118,34,'PROCEDURE ANALYSE','Syntax:\nANALYSE([max_elements[,max_memory]])\n\n*Note*:\n\nPROCEDURE ANALYSE() is deprecated as of MySQL 5.7.18, and is removed in\nMySQL 8.0.\n\nANALYSE() examines the result from a query and returns an analysis of\nthe results that suggests optimal data types for each column that may\nhelp reduce table sizes. To obtain this analysis, append PROCEDURE\nANALYSE to the end of a SELECT statement:\n\nSELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])\n\nFor example:\n\nSELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);\n\nThe results show some statistics for the values returned by the query,\nand propose an optimal data type for the columns. This can be helpful\nfor checking your existing tables, or after importing new data. You may\nneed to try different settings for the arguments so that PROCEDURE\nANALYSE() does not suggest the ENUM data type when it is not\nappropriate.\n\nThe arguments are optional and are used as follows:\n\no max_elements (default 256) is the maximum number of distinct values\n that ANALYSE() notices per column. This is used by ANALYSE() to check\n whether the optimal data type should be of type ENUM; if there are\n more than max_elements distinct values, then ENUM is not a suggested\n type.\n\no max_memory (default 8192) is the maximum amount of memory that\n ANALYSE() should allocate per column while trying to find all\n distinct values.\n\nA PROCEDURE clause is not permitted in a UNION statement.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/procedure-analyse.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/procedure-analyse.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (119,9,'HELP_VERSION','This help information was generated from the MySQL 5.7 Reference Manual\non: 2018-06-07 (revision: 57614)\n\nThis information applies to MySQL 5.7 through 5.7.24.\n','','');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (119,9,'HELP_VERSION','This help information was generated from the MySQL 5.7 Reference Manual\non: 2018-10-03 (revision: 59320)\n\nThis information applies to MySQL 5.7 through 5.7.25.\n','','');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (120,38,'CHARACTER_LENGTH','Syntax:\nCHARACTER_LENGTH(str)\n\nCHARACTER_LENGTH() is a synonym for CHAR_LENGTH().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (121,27,'SHOW PRIVILEGES','Syntax:\nSHOW PRIVILEGES\n\nSHOW PRIVILEGES shows the list of system privileges that the MySQL\nserver supports. The exact list of privileges depends on the version of\nyour server.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-privileges.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-privileges.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (122,40,'CREATE TABLESPACE','Syntax:\nCREATE TABLESPACE tablespace_name\n\n InnoDB and NDB:\n ADD DATAFILE \'file_name\'\n\n InnoDB only:\n [FILE_BLOCK_SIZE = value]\n\n NDB only:\n USE LOGFILE GROUP logfile_group\n [EXTENT_SIZE [=] extent_size]\n [INITIAL_SIZE [=] initial_size]\n [AUTOEXTEND_SIZE [=] autoextend_size]\n [MAX_SIZE [=] max_size]\n [NODEGROUP [=] nodegroup_id]\n [WAIT]\n [COMMENT [=] \'string\']\n\n InnoDB and NDB:\n [ENGINE [=] engine_name]\n\nThis statement is used to create a tablespace. The precise syntax and\nsemantics depend on the storage engine used. In standard MySQL 5.7\nreleases, this is always an InnoDB tablespace. MySQL NDB Cluster 7.5\nalso supports tablespaces using the NDB storage engine in addition to\nthose using InnoDB.\n\nConsiderations for InnoDB\n\nAn InnoDB tablespace created using CREATE TABLESPACE is referred to as\na general tablespace. This is a shared tablespace, similar to the\nsystem tablespace. It can hold multiple tables, and supports all table\nrow formats. General tablespaces can be created in a location relative\nto or independent of the MySQL data directory.\n\nAfter creating an InnoDB general tablespace, you can use CREATE TABLE\ntbl_name ... TABLESPACE [=] tablespace_name or ALTER TABLE tbl_name\nTABLESPACE [=] tablespace_name to add tables to the tablespace.\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html.\n\nConsiderations for NDB Cluster\n\nThis statement is used to create a tablespace, which can contain one or\nmore data files, providing storage space for NDB Cluster Disk Data\ntables (see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data.html).\nOne data file is created and added to the tablespace using this\nstatement. Additional data files may be added to the tablespace by\nusing the ALTER TABLESPACE statement (see [HELP ALTER TABLESPACE]).\n\n*Note*:\n\nAll NDB Cluster Disk Data objects share the same namespace. This means\nthat each Disk Data object must be uniquely named (and not merely each\nDisk Data object of a given type). For example, you cannot have a\ntablespace and a log file group with the same name, or a tablespace and\na data file with the same name.\n\nA log file group of one or more UNDO log files must be assigned to the\ntablespace to be created with the USE LOGFILE GROUP clause.\nlogfile_group must be an existing log file group created with CREATE\nLOGFILE GROUP (see [HELP CREATE LOGFILE GROUP]). Multiple tablespaces\nmay use the same log file group for UNDO logging.\n\nWhen setting EXTENT_SIZE or INITIAL_SIZE, you may optionally follow the\nnumber with a one-letter abbreviation for an order of magnitude,\nsimilar to those used in my.cnf. Generally, this is one of the letters\nM (for megabytes) or G (for gigabytes).\n\nINITIAL_SIZE and EXTENT_SIZE are subject to rounding as follows:\n\no EXTENT_SIZE is rounded up to the nearest whole multiple of 32K.\n\no INITIAL_SIZE is rounded down to the nearest whole multiple of 32K;\n this result is rounded up to the nearest whole multiple of\n EXTENT_SIZE (after any rounding).\n\nThe rounding just described is done explicitly, and a warning is issued\nby the MySQL Server when any such rounding is performed. The rounded\nvalues are also used by the NDB kernel for calculating\nINFORMATION_SCHEMA.FILES column values and other purposes. However, to\navoid an unexpected result, we suggest that you always use whole\nmultiples of 32K in specifying these options.\n\nWhen CREATE TABLESPACE is used with ENGINE [=] NDB, a tablespace and\nassociated data file are created on each Cluster data node. You can\nverify that the data files were created and obtain information about\nthem by querying the INFORMATION_SCHEMA.FILES table. (See the example\nlater in this section.)\n\n(See http://dev.mysql.com/doc/refman/5.7/en/files-table.html.)\n\nOptions\n\no ADD DATAFILE: Defines the name of a tablespace data file; this option\n is always required. An InnoDB tablespace supports only a single data\n file, whose name must include a .ibd extension. An NDB Cluster\n tablespace supports multiple data files which can have any legal file\n names; more data files can be added to an NDB Cluster tablespace\n following its creation by using an ALTER TABLESPACE statement.\n\n *Note*:\n\n ALTER TABLESPACE is not supported by InnoDB.\n\n To place the data file in a location outside of the MySQL data\n directory (datadir), include an absolute directory path or a path\n relative to the MySQL data directory. If you do not specify a path,\n the tablespace is created in the MySQL data directory. An isl file is\n created in the MySQL data directory when an InnoDB tablespace is\n created outside of the MySQL data directory.\n\n To avoid conflicts with implicitly created file-per-table\n tablespaces, creating a general tablespace in a subdirectory under\n the MySQL data directory is not supported. Also, when creating a\n general tablespace outside of the MySQL data directory, the directory\n must exist prior to creating the tablespace.\n\n The file_name, including the path (optional), must be quoted with\n single or double quotations marks. File names (not counting any\n ".ibd" extension for InnoDB files) and directory names must be at\n least one byte in length. Zero length file names and directory names\n are not supported.\n\no FILE_BLOCK_SIZE: This option---which is specific to InnoDB, and is\n ignored by NDB---defines the block size for the tablespace data file.\n If you do not specify this option, FILE_BLOCK_SIZE defaults to\n innodb_page_size. FILE_BLOCK_SIZE is required when you intend to use\n the tablespace for storing compressed InnoDB tables\n (ROW_FORMAT=COMPRESSED).\n\n If FILE_BLOCK_SIZE is equal innodb_page_size, the tablespace can\n contain only tables having an uncompressed row format (COMPACT,\n REDUNDANT, or DYNAMIC). The physical page size for tables using\n COMPRESSED differs from that of uncompressed tables; this means that\n compressed tables and uncompressed tables cannot coexist in the same\n tablespace.\n\n For a general tablespace to contain compressed tables,\n FILE_BLOCK_SIZE must be specified, and the FILE_BLOCK_SIZE value must\n be a valid compressed page size in relation to the innodb_page_size\n value. Also, the physical page size of the compressed table\n (KEY_BLOCK_SIZE) must be equal to FILE_BLOCK_SIZE/1024. For example,\n if innodb_page_size=16K, and FILE_BLOCK_SIZE=8K, the KEY_BLOCK_SIZE\n of the table must be 8. For more information, see\n http://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html.\n\no USE LOGFILE GROUP: Required for NDB, this is the name of a log file\n group previously created using CREATE LOGFILE GROUP. Not supported\n for InnoDB, where it fails with an error.\n\no EXTENT_SIZE: This option is specific to NDB, and is not supported by\n InnoDB, where it fails with an error. EXTENT_SIZE sets the size, in\n bytes, of the extents used by any files belonging to the tablespace.\n The default value is 1M. The minimum size is 32K, and theoretical\n maximum is 2G, although the practical maximum size depends on a\n number of factors. In most cases, changing the extent size does not\n have any measurable effect on performance, and the default value is\n recommended for all but the most unusual situations.\n\n An extent is a unit of disk space allocation. One extent is filled\n with as much data as that extent can contain before another extent is\n used. In theory, up to 65,535 (64K) extents may used per data file;\n however, the recommended maximum is 32,768 (32K). The recommended\n maximum size for a single data file is 32G---that is, 32K extents x 1\n MB per extent. In addition, once an extent is allocated to a given\n partition, it cannot be used to store data from a different\n partition; an extent cannot store data from more than one partition.\n This means, for example that a tablespace having a single datafile\n whose INITIAL_SIZE (described in the following item) is 256 MB and\n whose EXTENT_SIZE is 128M has just two extents, and so can be used to\n store data from at most two different disk data table partitions.\n\n You can see how many extents remain free in a given data file by\n querying the INFORMATION_SCHEMA.FILES table, and so derive an\n estimate for how much space remains free in the file. For further\n discussion and examples, see\n http://dev.mysql.com/doc/refman/5.7/en/files-table.html.\n\no INITIAL_SIZE: This option is specific to NDB, and is not supported by\n InnoDB, where it fails with an error.\n\n The INITIAL_SIZE parameter sets the total size in bytes of the data\n file that was specific using ADD DATATFILE. Once this file has been\n created, its size cannot be changed; however, you can add more data\n files to the tablespace using ALTER TABLESPACE ... ADD DATAFILE.\n\n INITIAL_SIZE is optional; its default value is 134217728 (128 MB).\n\n On 32-bit systems, the maximum supported value for INITIAL_SIZE is\n 4294967296 (4 GB).\n\no AUTOEXTEND_SIZE: Currently ignored by MySQL; reserved for possible\n future use. Has no effect in any release of MySQL 5.7 or MySQL NDB\n Cluster 7.5, regardless of the storage engine used.\n\no MAX_SIZE: Currently ignored by MySQL; reserved for possible future\n use. Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster\n 7.5, regardless of the storage engine used.\n\no NODEGROUP: Currently ignored by MySQL; reserved for possible future\n use. Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster\n 7.5, regardless of the storage engine used.\n\no WAIT: Currently ignored by MySQL; reserved for possible future use.\n Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster 7.5,\n regardless of the storage engine used.\n\no COMMENT: Currently ignored by MySQL; reserved for possible future\n use. Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster\n 7.5, regardless of the storage engine used.\n\no ENGINE: Defines the storage engine which uses the tablespace, where\n engine_name is the name of the storage engine. Currently, only the\n InnoDB storage engine is supported by standard MySQL 5.7 releases.\n MySQL NDB Cluster 7.5 supports both NDB and InnoDB tablespaces. The\n value of the default_storage_engine system variable is used for\n ENGINE if the option is not specified.\n\nNotes\n\no For the rules covering the naming of MySQL tablespaces, see\n http://dev.mysql.com/doc/refman/5.7/en/identifiers.html. In addition\n to these rules, the slash character ("/") is not permitted, nor can\n you use names beginning with innodb_, as this prefix is reserved for\n system use.\n\no Tablespaces do not support temporary tables.\n\no The TABLESPACE option may be used with CREATE TABLE or ALTER TABLE to\n assign InnoDB table partitions or subpartitions to a general\n tablespace, a separate file-per-table tablespace, or the system\n tablespace. TABLESPACE option support for table partitions and\n subpartitions was added in MySQL 5.7. All partitions must belong to\n the same storage engine. For more information, see\n http://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html.\n\no innodb_file_per_table, innodb_file_format, and innodb_file_format_max\n settings have no influence on CREATE TABLESPACE operations.\n innodb_file_per_table does not need to be enabled. General\n tablespaces support all table row formats regardless of file format\n settings. Likewise, general tablespaces support the addition of\n tables of any row format using CREATE TABLE ... TABLESPACE,\n regardless of file format settings.\n\no innodb_strict_mode is not applicable to general tablespaces.\n Tablespace management rules are strictly enforced independently of\n innodb_strict_mode. If CREATE TABLESPACE parameters are incorrect or\n incompatible, the operation fails regardless of the\n innodb_strict_mode setting. When a table is added to a general\n tablespace using CREATE TABLE ... TABLESPACE or ALTER TABLE ...\n TABLESPACE, innodb_strict_mode is ignored but the statement is\n evaluated as if innodb_strict_mode is enabled.\n\no Use DROP TABLESPACE to remove a tablespace. All tables must be\n dropped from a tablespace using DROP TABLE prior to dropping the\n tablespace. Before dropping an NDB Cluster tablespace you must also\n remove all its data files using one or more ALTER TABLESPACE ... DROP\n DATATFILE statements. See\n http://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data-object\n s.html.\n\no All parts of an InnoDB table added to an InnoDB general tablespace\n reside in the general tablespace, including indexes and BLOB pages.\n\n For an NDB table assigned to a tablespace, only those columns which\n are not indexed are stored on disk, and actually use the tablespace\n data files. Indexes and indexed columns for all NDB tables are always\n kept in memory.\n\no Similar to the system tablespace, truncating or dropping tables\n stored in a general tablespace creates free space internally in the\n general tablespace .ibd data file which can only be used for new\n InnoDB data. Space is not released back to the operating system as it\n is for file-per-table tablespaces.\n\no A general tablespace is not associated with any database or schema.\n\no ALTER TABLE ... DISCARD TABLESPACE and ALTER TABLE ...IMPORT\n TABLESPACE are not supported for tables that belong to a general\n tablespace.\n\no The server uses tablespace-level metadata locking for DDL that\n references general tablespaces. By comparison, the server uses\n table-level metadata locking for DDL that references file-per-table\n tablespaces.\n\no A generated or existing tablespace cannot be changed to a general\n tablespace.\n\no Tables stored in a general tablespace can only be opened in MySQL\n 5.7.6 or later due to the addition of new table flags.\n\no There is no conflict between general tablespace names and\n file-per-table tablespace names. The "/" character, which is present\n in file-per-table tablespace names, is not permitted in general\n tablespace names.\n\nInnoDB Examples\n\nThis example demonstrates creating a general tablespace and adding\nthree uncompressed tables of different row formats.\n\nmysql> CREATE TABLESPACE `ts1`\n -> ADD DATAFILE \'ts1.ibd\'\n -> ENGINE=INNODB;\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> CREATE TABLE t1 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts1\n -> ROW_FORMAT=REDUNDANT;\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> CREATE TABLE t2 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts1\n -> ROW_FORMAT=COMPACT;\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> CREATE TABLE t3 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts1\n -> ROW_FORMAT=DYNAMIC;\nQuery OK, 0 rows affected (0.00 sec)\n\nThis example demonstrates creating a general tablespace and adding a\ncompressed table. The example assumes a default innodb_page_size of\n16K. The FILE_BLOCK_SIZE of 8192 requires that the compressed table\nhave a KEY_BLOCK_SIZE of 8.\n\nmysql> CREATE TABLESPACE `ts2`\n -> ADD DATAFILE \'ts2.ibd\'\n -> FILE_BLOCK_SIZE = 8192\n -> ENGINE=INNODB;\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> CREATE TABLE t4 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts2\n -> ROW_FORMAT=COMPRESSED\n -> KEY_BLOCK_SIZE=8;\nQuery OK, 0 rows affected (0.00 sec)\n\nNDB Example\n\nSuppose that you wish to create an NDB Cluster Disk Data tablespace\nnamed myts using a datafile named mydata-1.dat. An NDB tablespace\nalways requires the use of a log file group consisting of one or more\nundo log files. For this example, we first create a log file group\nnamed mylg that contains one undo long file named myundo-1.dat, using\nthe CREATE LOGFILE GROUP statement shown here:\n\nmysql> CREATE LOGFILE GROUP myg1\n -> ADD UNDOFILE \'myundo-1.dat\'\n -> ENGINE=NDB;\nQuery OK, 0 rows affected (3.29 sec)\n\nNow you can create the tablespace previously described using the\nfollowing statement:\n\nmysql> CREATE TABLESPACE myts\n -> ADD DATAFILE \'mydata-1.dat\'\n -> USE LOGFILE GROUP mylg\n -> ENGINE=NDB;\nQuery OK, 0 rows affected (2.98 sec)\n\nYou can now create a Disk Data table using a CREATE TABLE statement\nwith the TABLESPACE and STORAGE DISK options, similar to what is shown\nhere:\n\nmysql> CREATE TABLE mytable (\n -> id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> lname VARCHAR(50) NOT NULL,\n -> fname VARCHAR(50) NOT NULL,\n -> dob DATE NOT NULL,\n -> joined DATE NOT NULL,\n -> INDEX(last_name, first_name)\n -> )\n -> TABLESPACE myts STORAGE DISK\n -> ENGINE=NDB;\nQuery OK, 0 rows affected (1.41 sec)\n\nIt is important to note that only the dob and joined columns from\nmytable are actually stored on disk, due to the fact that the id,\nlname, and fname columns are all indexed.\n\nAs mentioned previously, when CREATE TABLESPACE is used with ENGINE [=]\nNDB, a tablespace and associated data file are created on each NDB\nCluster data node. You can verify that the data files were created and\nobtain information about them by querying the INFORMATION_SCHEMA.FILES\ntable, as shown here:\n\nmysql> SELECT FILE_NAME, FILE_TYPE, LOGFILE_GROUP_NAME, STATUS, EXTRA\n -> FROM INFORMATION_SCHEMA.FILES\n -> WHERE TABLESPACE_NAME = \'myts\';\n\n+--------------+------------+--------------------+--------+----------------+\n| file_name | file_type | logfile_group_name | status | extra |\n+--------------+------------+--------------------+--------+----------------+\n| mydata-1.dat | DATAFILE | mylg | NORMAL | CLUSTER_NODE=5 |\n| mydata-1.dat | DATAFILE | mylg | NORMAL | CLUSTER_NODE=6 |\n| NULL | TABLESPACE | mylg | NORMAL | NULL |\n+--------------+------------+--------------------+--------+----------------+\n3 rows in set (0.01 sec)\n\nFor additional information and examples, see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data-objects.\nhtml.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (122,40,'CREATE TABLESPACE','Syntax:\nCREATE TABLESPACE tablespace_name\n\n InnoDB and NDB:\n ADD DATAFILE \'file_name\'\n\n InnoDB only:\n [FILE_BLOCK_SIZE = value]\n\n NDB only:\n USE LOGFILE GROUP logfile_group\n [EXTENT_SIZE [=] extent_size]\n [INITIAL_SIZE [=] initial_size]\n [AUTOEXTEND_SIZE [=] autoextend_size]\n [MAX_SIZE [=] max_size]\n [NODEGROUP [=] nodegroup_id]\n [WAIT]\n [COMMENT [=] \'string\']\n\n InnoDB and NDB:\n [ENGINE [=] engine_name]\n\nThis statement is used to create a tablespace. The precise syntax and\nsemantics depend on the storage engine used. In standard MySQL 5.7\nreleases, this is always an InnoDB tablespace. MySQL NDB Cluster 7.5\nalso supports tablespaces using the NDB storage engine in addition to\nthose using InnoDB.\n\nConsiderations for InnoDB\n\nAn InnoDB tablespace created using CREATE TABLESPACE is referred to as\na general tablespace. This is a shared tablespace, similar to the\nsystem tablespace. It can hold multiple tables, and supports all table\nrow formats. General tablespaces can be created in a location relative\nto or independent of the MySQL data directory.\n\nAfter creating an InnoDB general tablespace, you can use CREATE TABLE\ntbl_name ... TABLESPACE [=] tablespace_name or ALTER TABLE tbl_name\nTABLESPACE [=] tablespace_name to add tables to the tablespace.\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html.\n\nConsiderations for NDB Cluster\n\nThis statement is used to create a tablespace, which can contain one or\nmore data files, providing storage space for NDB Cluster Disk Data\ntables (see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data.html).\nOne data file is created and added to the tablespace using this\nstatement. Additional data files may be added to the tablespace by\nusing the ALTER TABLESPACE statement (see [HELP ALTER TABLESPACE]).\n\n*Note*:\n\nAll NDB Cluster Disk Data objects share the same namespace. This means\nthat each Disk Data object must be uniquely named (and not merely each\nDisk Data object of a given type). For example, you cannot have a\ntablespace and a log file group with the same name, or a tablespace and\na data file with the same name.\n\nA log file group of one or more UNDO log files must be assigned to the\ntablespace to be created with the USE LOGFILE GROUP clause.\nlogfile_group must be an existing log file group created with CREATE\nLOGFILE GROUP (see [HELP CREATE LOGFILE GROUP]). Multiple tablespaces\nmay use the same log file group for UNDO logging.\n\nWhen setting EXTENT_SIZE or INITIAL_SIZE, you may optionally follow the\nnumber with a one-letter abbreviation for an order of magnitude,\nsimilar to those used in my.cnf. Generally, this is one of the letters\nM (for megabytes) or G (for gigabytes).\n\nINITIAL_SIZE and EXTENT_SIZE are subject to rounding as follows:\n\no EXTENT_SIZE is rounded up to the nearest whole multiple of 32K.\n\no INITIAL_SIZE is rounded down to the nearest whole multiple of 32K;\n this result is rounded up to the nearest whole multiple of\n EXTENT_SIZE (after any rounding).\n\nThe rounding just described is done explicitly, and a warning is issued\nby the MySQL Server when any such rounding is performed. The rounded\nvalues are also used by the NDB kernel for calculating\nINFORMATION_SCHEMA.FILES column values and other purposes. However, to\navoid an unexpected result, we suggest that you always use whole\nmultiples of 32K in specifying these options.\n\nWhen CREATE TABLESPACE is used with ENGINE [=] NDB, a tablespace and\nassociated data file are created on each Cluster data node. You can\nverify that the data files were created and obtain information about\nthem by querying the INFORMATION_SCHEMA.FILES table. (See the example\nlater in this section.)\n\n(See http://dev.mysql.com/doc/refman/5.7/en/files-table.html.)\n\nOptions\n\no ADD DATAFILE: Defines the name of a tablespace data file; this option\n is always required. An InnoDB tablespace supports only a single data\n file, whose name must include a .ibd extension. An NDB Cluster\n tablespace supports multiple data files which can have any legal file\n names; more data files can be added to an NDB Cluster tablespace\n following its creation by using an ALTER TABLESPACE statement.\n\n *Note*:\n\n ALTER TABLESPACE is not supported by InnoDB.\n\n To place the data file in a location outside of the MySQL data\n directory (datadir), include an absolute directory path or a path\n relative to the MySQL data directory. If you do not specify a path,\n the tablespace is created in the MySQL data directory. An isl file is\n created in the MySQL data directory when an InnoDB tablespace is\n created outside of the MySQL data directory.\n\n To avoid conflicts with implicitly created file-per-table\n tablespaces, creating a general tablespace in a subdirectory under\n the MySQL data directory is not supported. Also, when creating a\n general tablespace outside of the MySQL data directory, the directory\n must exist prior to creating the tablespace.\n\n The file_name, including the path (optional), must be quoted with\n single or double quotations marks. File names (not counting any\n ".ibd" extension for InnoDB files) and directory names must be at\n least one byte in length. Zero length file names and directory names\n are not supported.\n\no FILE_BLOCK_SIZE: This option---which is specific to InnoDB, and is\n ignored by NDB---defines the block size for the tablespace data file.\n Values can be specified in bytes or kilobytes. For example, an 8\n kilobyte file block size can be specified as 8192 or 8K. If you do\n not specify this option, FILE_BLOCK_SIZE defaults to\n innodb_page_size. FILE_BLOCK_SIZE is required when you intend to use\n the tablespace for storing compressed InnoDB tables\n (ROW_FORMAT=COMPRESSED).\n\n If FILE_BLOCK_SIZE is equal innodb_page_size, the tablespace can\n contain only tables having an uncompressed row format (COMPACT,\n REDUNDANT, or DYNAMIC). The physical page size for tables using\n COMPRESSED differs from that of uncompressed tables; this means that\n compressed tables and uncompressed tables cannot coexist in the same\n tablespace.\n\n For a general tablespace to contain compressed tables,\n FILE_BLOCK_SIZE must be specified, and the FILE_BLOCK_SIZE value must\n be a valid compressed page size in relation to the innodb_page_size\n value. Also, the physical page size of the compressed table\n (KEY_BLOCK_SIZE) must be equal to FILE_BLOCK_SIZE/1024. For example,\n if innodb_page_size=16K, and FILE_BLOCK_SIZE=8K, the KEY_BLOCK_SIZE\n of the table must be 8. For more information, see\n http://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html.\n\no USE LOGFILE GROUP: Required for NDB, this is the name of a log file\n group previously created using CREATE LOGFILE GROUP. Not supported\n for InnoDB, where it fails with an error.\n\no EXTENT_SIZE: This option is specific to NDB, and is not supported by\n InnoDB, where it fails with an error. EXTENT_SIZE sets the size, in\n bytes, of the extents used by any files belonging to the tablespace.\n The default value is 1M. The minimum size is 32K, and theoretical\n maximum is 2G, although the practical maximum size depends on a\n number of factors. In most cases, changing the extent size does not\n have any measurable effect on performance, and the default value is\n recommended for all but the most unusual situations.\n\n An extent is a unit of disk space allocation. One extent is filled\n with as much data as that extent can contain before another extent is\n used. In theory, up to 65,535 (64K) extents may used per data file;\n however, the recommended maximum is 32,768 (32K). The recommended\n maximum size for a single data file is 32G---that is, 32K extents x 1\n MB per extent. In addition, once an extent is allocated to a given\n partition, it cannot be used to store data from a different\n partition; an extent cannot store data from more than one partition.\n This means, for example that a tablespace having a single datafile\n whose INITIAL_SIZE (described in the following item) is 256 MB and\n whose EXTENT_SIZE is 128M has just two extents, and so can be used to\n store data from at most two different disk data table partitions.\n\n You can see how many extents remain free in a given data file by\n querying the INFORMATION_SCHEMA.FILES table, and so derive an\n estimate for how much space remains free in the file. For further\n discussion and examples, see\n http://dev.mysql.com/doc/refman/5.7/en/files-table.html.\n\no INITIAL_SIZE: This option is specific to NDB, and is not supported by\n InnoDB, where it fails with an error.\n\n The INITIAL_SIZE parameter sets the total size in bytes of the data\n file that was specific using ADD DATATFILE. Once this file has been\n created, its size cannot be changed; however, you can add more data\n files to the tablespace using ALTER TABLESPACE ... ADD DATAFILE.\n\n INITIAL_SIZE is optional; its default value is 134217728 (128 MB).\n\n On 32-bit systems, the maximum supported value for INITIAL_SIZE is\n 4294967296 (4 GB).\n\no AUTOEXTEND_SIZE: Currently ignored by MySQL; reserved for possible\n future use. Has no effect in any release of MySQL 5.7 or MySQL NDB\n Cluster 7.5, regardless of the storage engine used.\n\no MAX_SIZE: Currently ignored by MySQL; reserved for possible future\n use. Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster\n 7.5, regardless of the storage engine used.\n\no NODEGROUP: Currently ignored by MySQL; reserved for possible future\n use. Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster\n 7.5, regardless of the storage engine used.\n\no WAIT: Currently ignored by MySQL; reserved for possible future use.\n Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster 7.5,\n regardless of the storage engine used.\n\no COMMENT: Currently ignored by MySQL; reserved for possible future\n use. Has no effect in any release of MySQL 5.7 or MySQL NDB Cluster\n 7.5, regardless of the storage engine used.\n\no ENGINE: Defines the storage engine which uses the tablespace, where\n engine_name is the name of the storage engine. Currently, only the\n InnoDB storage engine is supported by standard MySQL 5.7 releases.\n MySQL NDB Cluster 7.5 supports both NDB and InnoDB tablespaces. The\n value of the default_storage_engine system variable is used for\n ENGINE if the option is not specified.\n\nNotes\n\no For the rules covering the naming of MySQL tablespaces, see\n http://dev.mysql.com/doc/refman/5.7/en/identifiers.html. In addition\n to these rules, the slash character ("/") is not permitted, nor can\n you use names beginning with innodb_, as this prefix is reserved for\n system use.\n\no Tablespaces do not support temporary tables.\n\no innodb_file_per_table, innodb_file_format, and innodb_file_format_max\n settings have no influence on CREATE TABLESPACE operations.\n innodb_file_per_table does not need to be enabled. General\n tablespaces support all table row formats regardless of file format\n settings. Likewise, general tablespaces support the addition of\n tables of any row format using CREATE TABLE ... TABLESPACE,\n regardless of file format settings.\n\no innodb_strict_mode is not applicable to general tablespaces.\n Tablespace management rules are strictly enforced independently of\n innodb_strict_mode. If CREATE TABLESPACE parameters are incorrect or\n incompatible, the operation fails regardless of the\n innodb_strict_mode setting. When a table is added to a general\n tablespace using CREATE TABLE ... TABLESPACE or ALTER TABLE ...\n TABLESPACE, innodb_strict_mode is ignored but the statement is\n evaluated as if innodb_strict_mode is enabled.\n\no Use DROP TABLESPACE to remove a tablespace. All tables must be\n dropped from a tablespace using DROP TABLE prior to dropping the\n tablespace. Before dropping an NDB Cluster tablespace you must also\n remove all its data files using one or more ALTER TABLESPACE ... DROP\n DATATFILE statements. See\n http://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data-object\n s.html.\n\no All parts of an InnoDB table added to an InnoDB general tablespace\n reside in the general tablespace, including indexes and BLOB pages.\n\n For an NDB table assigned to a tablespace, only those columns which\n are not indexed are stored on disk, and actually use the tablespace\n data files. Indexes and indexed columns for all NDB tables are always\n kept in memory.\n\no Similar to the system tablespace, truncating or dropping tables\n stored in a general tablespace creates free space internally in the\n general tablespace .ibd data file which can only be used for new\n InnoDB data. Space is not released back to the operating system as it\n is for file-per-table tablespaces.\n\no A general tablespace is not associated with any database or schema.\n\no ALTER TABLE ... DISCARD TABLESPACE and ALTER TABLE ...IMPORT\n TABLESPACE are not supported for tables that belong to a general\n tablespace.\n\no The server uses tablespace-level metadata locking for DDL that\n references general tablespaces. By comparison, the server uses\n table-level metadata locking for DDL that references file-per-table\n tablespaces.\n\no A generated or existing tablespace cannot be changed to a general\n tablespace.\n\no Tables stored in a general tablespace can only be opened in MySQL\n 5.7.6 or later due to the addition of new table flags.\n\no There is no conflict between general tablespace names and\n file-per-table tablespace names. The "/" character, which is present\n in file-per-table tablespace names, is not permitted in general\n tablespace names.\n\no mysqldump and mysqlpump do not dump InnoDB CREATE TABLESPACE\n statements.\n\nInnoDB Examples\n\nThis example demonstrates creating a general tablespace and adding\nthree uncompressed tables of different row formats.\n\nmysql> CREATE TABLESPACE `ts1`\n -> ADD DATAFILE \'ts1.ibd\'\n -> ENGINE=INNODB;\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> CREATE TABLE t1 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts1\n -> ROW_FORMAT=REDUNDANT;\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> CREATE TABLE t2 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts1\n -> ROW_FORMAT=COMPACT;\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> CREATE TABLE t3 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts1\n -> ROW_FORMAT=DYNAMIC;\nQuery OK, 0 rows affected (0.00 sec)\n\nThis example demonstrates creating a general tablespace and adding a\ncompressed table. The example assumes a default innodb_page_size of\n16KB. The FILE_BLOCK_SIZE of 8192 requires that the compressed table\nhave a KEY_BLOCK_SIZE of 8.\n\nmysql> CREATE TABLESPACE `ts2`\n -> ADD DATAFILE \'ts2.ibd\'\n -> FILE_BLOCK_SIZE = 8192\n -> ENGINE=INNODB;\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> CREATE TABLE t4 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts2\n -> ROW_FORMAT=COMPRESSED\n -> KEY_BLOCK_SIZE=8;\nQuery OK, 0 rows affected (0.00 sec)\n\nNDB Example\n\nSuppose that you wish to create an NDB Cluster Disk Data tablespace\nnamed myts using a datafile named mydata-1.dat. An NDB tablespace\nalways requires the use of a log file group consisting of one or more\nundo log files. For this example, we first create a log file group\nnamed mylg that contains one undo long file named myundo-1.dat, using\nthe CREATE LOGFILE GROUP statement shown here:\n\nmysql> CREATE LOGFILE GROUP myg1\n -> ADD UNDOFILE \'myundo-1.dat\'\n -> ENGINE=NDB;\nQuery OK, 0 rows affected (3.29 sec)\n\nNow you can create the tablespace previously described using the\nfollowing statement:\n\nmysql> CREATE TABLESPACE myts\n -> ADD DATAFILE \'mydata-1.dat\'\n -> USE LOGFILE GROUP mylg\n -> ENGINE=NDB;\nQuery OK, 0 rows affected (2.98 sec)\n\nYou can now create a Disk Data table using a CREATE TABLE statement\nwith the TABLESPACE and STORAGE DISK options, similar to what is shown\nhere:\n\nmysql> CREATE TABLE mytable (\n -> id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> lname VARCHAR(50) NOT NULL,\n -> fname VARCHAR(50) NOT NULL,\n -> dob DATE NOT NULL,\n -> joined DATE NOT NULL,\n -> INDEX(last_name, first_name)\n -> )\n -> TABLESPACE myts STORAGE DISK\n -> ENGINE=NDB;\nQuery OK, 0 rows affected (1.41 sec)\n\nIt is important to note that only the dob and joined columns from\nmytable are actually stored on disk, due to the fact that the id,\nlname, and fname columns are all indexed.\n\nAs mentioned previously, when CREATE TABLESPACE is used with ENGINE [=]\nNDB, a tablespace and associated data file are created on each NDB\nCluster data node. You can verify that the data files were created and\nobtain information about them by querying the INFORMATION_SCHEMA.FILES\ntable, as shown here:\n\nmysql> SELECT FILE_NAME, FILE_TYPE, LOGFILE_GROUP_NAME, STATUS, EXTRA\n -> FROM INFORMATION_SCHEMA.FILES\n -> WHERE TABLESPACE_NAME = \'myts\';\n\n+--------------+------------+--------------------+--------+----------------+\n| file_name | file_type | logfile_group_name | status | extra |\n+--------------+------------+--------------------+--------+----------------+\n| mydata-1.dat | DATAFILE | mylg | NORMAL | CLUSTER_NODE=5 |\n| mydata-1.dat | DATAFILE | mylg | NORMAL | CLUSTER_NODE=6 |\n| NULL | TABLESPACE | mylg | NORMAL | NULL |\n+--------------+------------+--------------------+--------+----------------+\n3 rows in set (0.01 sec)\n\nFor additional information and examples, see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data-objects.\nhtml.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (123,4,'ST_GEOMFROMTEXT','ST_GeomFromText(wkt[, srid]), ST_GeometryFromText(wkt[, srid])\n\nConstructs a geometry value of any type using its WKT representation\nand SRID.\n\nIf the geometry argument is NULL or not a syntactically well-formed\ngeometry, or if the SRID argument is NULL, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (124,38,'INSERT FUNCTION','Syntax:\nINSERT(str,pos,len,newstr)\n\nReturns the string str, with the substring beginning at position pos\nand len characters long replaced by the string newstr. Returns the\noriginal string if pos is not within the length of the string. Replaces\nthe rest of the string from position pos if len is not within the\nlength of the rest of the string. Returns NULL if any argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT INSERT(\'Quadratic\', 3, 4, \'What\');\n -> \'QuWhattic\'\nmysql> SELECT INSERT(\'Quadratic\', -1, 4, \'What\');\n -> \'Quadratic\'\nmysql> SELECT INSERT(\'Quadratic\', 3, 100, \'What\');\n -> \'QuWhat\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (125,15,'XOR','Syntax:\nXOR\n\nLogical XOR. Returns NULL if either operand is NULL. For non-NULL\noperands, evaluates to 1 if an odd number of operands is nonzero,\notherwise 0 is returned.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/logical-operators.html\n\n','mysql> SELECT 1 XOR 1;\n -> 0\nmysql> SELECT 1 XOR 0;\n -> 1\nmysql> SELECT 1 XOR NULL;\n -> NULL\nmysql> SELECT 1 XOR 1 XOR 1;\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/logical-operators.html');
@@ -209,7 +209,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (128,20,'IS NOT','Syntax:\nIS NOT boolean_value\n\nTests a value against a boolean value, where boolean_value can be TRUE,\nFALSE, or UNKNOWN.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;\n -> 1, 1, 0\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (129,3,'SQRT','Syntax:\nSQRT(X)\n\nReturns the square root of a nonnegative number X.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT SQRT(4);\n -> 2\nmysql> SELECT SQRT(20);\n -> 4.4721359549996\nmysql> SELECT SQRT(-16);\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (130,33,'ST_MPOLYFROMWKB','ST_MPolyFromWKB(wkb[, srid]), ST_MultiPolygonFromWKB(wkb[, srid])\n\nConstructs a MultiPolygon value using its WKB representation and SRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (131,40,'CREATE INDEX','Syntax:\nCREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name\n [index_type]\n ON tbl_name (index_col_name,...)\n [index_option]\n [algorithm_option | lock_option] ...\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\nindex_type:\n USING {BTREE | HASH}\n\nalgorithm_option:\n ALGORITHM [=] {DEFAULT|INPLACE|COPY}\n\nlock_option:\n LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n\nCREATE INDEX is mapped to an ALTER TABLE statement to create indexes.\nSee [HELP ALTER TABLE]. CREATE INDEX cannot be used to create a PRIMARY\nKEY; use ALTER TABLE instead. For more information about indexes, see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-index.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-index.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (131,40,'CREATE INDEX','Syntax:\nCREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name\n [index_type]\n ON tbl_name (key_part,...)\n [index_option]\n [algorithm_option | lock_option] ...\n\nkey_part:\n col_name [(length)] [ASC | DESC]\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\nindex_type:\n USING {BTREE | HASH}\n\nalgorithm_option:\n ALGORITHM [=] {DEFAULT | INPLACE | COPY}\n\nlock_option:\n LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}\n\nNormally, you create all indexes on a table at the time the table\nitself is created with CREATE TABLE. See [HELP CREATE TABLE]. This\nguideline is especially important for InnoDB tables, where the primary\nkey determines the physical layout of rows in the data file. CREATE\nINDEX enables you to add indexes to existing tables.\n\nCREATE INDEX is mapped to an ALTER TABLE statement to create indexes.\nSee [HELP ALTER TABLE]. CREATE INDEX cannot be used to create a PRIMARY\nKEY; use ALTER TABLE instead. For more information about indexes, see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-index.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-index.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (132,40,'ALTER DATABASE','Syntax:\nALTER {DATABASE | SCHEMA} [db_name]\n alter_specification ...\nALTER {DATABASE | SCHEMA} db_name\n UPGRADE DATA DIRECTORY NAME\n\nalter_specification:\n [DEFAULT] CHARACTER SET [=] charset_name\n | [DEFAULT] COLLATE [=] collation_name\n\nALTER DATABASE enables you to change the overall characteristics of a\ndatabase. These characteristics are stored in the db.opt file in the\ndatabase directory. To use ALTER DATABASE, you need the ALTER privilege\non the database. ALTER SCHEMA is a synonym for ALTER DATABASE.\n\nThe database name can be omitted from the first syntax, in which case\nthe statement applies to the default database.\n\nNational Language Characteristics\n\nThe CHARACTER SET clause changes the default database character set.\nThe COLLATE clause changes the default database collation.\nhttp://dev.mysql.com/doc/refman/5.7/en/charset.html, discusses\ncharacter set and collation names.\n\nYou can see what character sets and collations are available using,\nrespectively, the SHOW CHARACTER SET and SHOW COLLATION statements. See\n[HELP SHOW CHARACTER SET], and [HELP SHOW COLLATION], for more\ninformation.\n\nIf you change the default character set or collation for a database,\nstored routines that use the database defaults must be dropped and\nrecreated so that they use the new defaults. (In a stored routine,\nvariables with character data types use the database defaults if the\ncharacter set or collation are not specified explicitly. See [HELP\nCREATE PROCEDURE].)\n\nUpgrading from Versions Older than MySQL 5.1\n\nThe syntax that includes the UPGRADE DATA DIRECTORY NAME clause updates\nthe name of the directory associated with the database to use the\nencoding implemented in MySQL 5.1 for mapping database names to\ndatabase directory names (see\nhttp://dev.mysql.com/doc/refman/5.7/en/identifier-mapping.html). This\nclause is for use under these conditions:\n\no It is intended when upgrading MySQL to 5.1 or later from older\n versions.\n\no It is intended to update a database directory name to the current\n encoding format if the name contains special characters that need\n encoding.\n\no The statement is used by mysqlcheck (as invoked by mysql_upgrade).\n\nFor example, if a database in MySQL 5.0 has the name a-b-c, the name\ncontains instances of the - (dash) character. In MySQL 5.0, the\ndatabase directory is also named a-b-c, which is not necessarily safe\nfor all file systems. In MySQL 5.1 and later, the same database name is\nencoded as a@002db@002dc to produce a file system-neutral directory\nname.\n\nWhen a MySQL installation is upgraded to MySQL 5.1 or later from an\nolder version,the server displays a name such as a-b-c (which is in the\nold format) as #mysql50#a-b-c, and you must refer to the name using the\n#mysql50# prefix. Use UPGRADE DATA DIRECTORY NAME in this case to\nexplicitly tell the server to re-encode the database directory name to\nthe current encoding format:\n\nALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;\n\nAfter executing this statement, you can refer to the database as a-b-c\nwithout the special #mysql50# prefix.\n\n*Note*:\n\nThe UPGRADE DATA DIRECTORY NAME clause is deprecated in MySQL 5.7.6 and\nwill be removed in a future version of MySQL. If it is necessary to\nconvert MySQL 5.0 database or table names, a workaround is to upgrade a\nMySQL 5.0 installation to MySQL 5.1 before upgrading to a more recent\nrelease.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-database.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-database.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (133,7,'JSON_ARRAY','Syntax:\nJSON_ARRAY([val[, val] ...])\n\nEvaluates a (possibly empty) list of values and returns a JSON array\ncontaining those values.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html\n\n','mysql> SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME());\n+---------------------------------------------+\n| JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME()) |\n+---------------------------------------------+\n| [1, "abc", null, true, "11:30:24.000000"] |\n+---------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (134,26,'GEOMETRYN','GeometryN(gc, N)\n\nST_GeometryN() and GeometryN() are synonyms. For more information, see\nthe description of ST_GeometryN().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-geometrycollection-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-geometrycollection-property-functions.html');
@@ -235,7 +235,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (154,32,'CURRENT_TIME','Syntax:\nCURRENT_TIME, CURRENT_TIME([fsp])\n\nCURRENT_TIME and CURRENT_TIME() are synonyms for CURTIME().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (155,4,'WKT DEFINITION','The Well-Known Text (WKT) representation of geometry values is designed\nfor exchanging geometry data in ASCII form. The OpenGIS specification\nprovides a Backus-Naur grammar that specifies the formal production\nrules for writing WKT values (see\nhttp://dev.mysql.com/doc/refman/5.7/en/spatial-types.html).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (156,11,'ST_Y','ST_Y(p)\n\nReturns the Y-coordinate value for the Point object p as a\ndouble-precision number.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-point-property-functions.html\n\n','mysql> SELECT ST_Y(Point(56.7, 53.34));\n+--------------------------+\n| ST_Y(Point(56.7, 53.34)) |\n+--------------------------+\n| 53.34 |\n+--------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-point-property-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (157,10,'REVOKE','Syntax:\nREVOKE\n priv_type [(column_list)]\n [, priv_type [(column_list)]] ...\n ON [object_type] priv_level\n FROM user [, user] ...\n\nREVOKE ALL [PRIVILEGES], GRANT OPTION\n FROM user [, user] ...\n\nREVOKE PROXY ON user\n FROM user [, user] ...\n\nThe REVOKE statement enables system administrators to revoke privileges\nfrom MySQL accounts.\n\nWhen the read_only system variable is enabled, REVOKE requires the\nSUPER privilege in addition to any other required privileges described\nin the following discussion.\n\nEach account name uses the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. For example:\n\nREVOKE INSERT ON *.* FROM \'jeffrey\'@\'localhost\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nFor details on the levels at which privileges exist, the permissible\npriv_type, priv_level, and object_type values, and the syntax for\nspecifying users and passwords, see [HELP GRANT]\n\nTo use the first REVOKE syntax, you must have the GRANT OPTION\nprivilege, and you must have the privileges that you are revoking.\n\nTo revoke all privileges, use the second syntax, which drops all\nglobal, database, table, column, and routine privileges for the named\nuser or users:\n\nREVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...\n\nTo use this REVOKE syntax, you must have the global CREATE USER\nprivilege, or the UPDATE privilege for the mysql database.\n\nUser accounts from which privileges are to be revoked must exist.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/revoke.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/revoke.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (157,10,'REVOKE','Syntax:\nREVOKE\n priv_type [(column_list)]\n [, priv_type [(column_list)]] ...\n ON [object_type] priv_level\n FROM user [, user] ...\n\nREVOKE ALL [PRIVILEGES], GRANT OPTION\n FROM user [, user] ...\n\nREVOKE PROXY ON user\n FROM user [, user] ...\n\nThe REVOKE statement enables system administrators to revoke privileges\nfrom MySQL accounts.\n\nWhen the read_only system variable is enabled, REVOKE requires the\nSUPER privilege in addition to any other required privileges described\nin the following discussion.\n\nEach account name uses the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. For example:\n\nREVOKE INSERT ON *.* FROM \'jeffrey\'@\'localhost\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nFor details on the levels at which privileges exist, the permissible\npriv_type, priv_level, and object_type values, and the syntax for\nspecifying users and passwords, see [HELP GRANT].\n\nTo use the first REVOKE syntax, you must have the GRANT OPTION\nprivilege, and you must have the privileges that you are revoking.\n\nTo revoke all privileges, use the second syntax, which drops all\nglobal, database, table, column, and routine privileges for the named\nuser or users:\n\nREVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...\n\nTo use this REVOKE syntax, you must have the global CREATE USER\nprivilege, or the UPDATE privilege for the mysql system database.\n\nUser accounts from which privileges are to be revoked must exist.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/revoke.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/revoke.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (158,32,'LAST_DAY','Syntax:\nLAST_DAY(date)\n\nTakes a date or datetime value and returns the corresponding value for\nthe last day of the month. Returns NULL if the argument is invalid.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT LAST_DAY(\'2003-02-05\');\n -> \'2003-02-28\'\nmysql> SELECT LAST_DAY(\'2004-02-05\');\n -> \'2004-02-29\'\nmysql> SELECT LAST_DAY(\'2004-01-01 01:01:01\');\n -> \'2004-01-31\'\nmysql> SELECT LAST_DAY(\'2003-03-32\');\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (159,23,'MEDIUMINT','MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA medium-sized integer. The signed range is -8388608 to 8388607. The\nunsigned range is 0 to 16777215.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (160,12,'RANDOM_BYTES','Syntax:\nRANDOM_BYTES(len)\n\nThis function returns a binary string of len random bytes generated\nusing the random number generator of the SSL library. Permitted values\nof len range from 1 to 1024. For values outside that range,\nRANDOM_BYTES() generates a warning and returns NULL.\n\nRANDOM_BYTES() can be used to provide the initialization vector for the\nAES_DECRYPT() and AES_ENCRYPT() functions. For use in that context, len\nmust be at least 16. Larger values are permitted, but bytes in excess\nof 16 are ignored.\n\nRANDOM_BYTES() generates a random value, which makes its result\nnondeterministic. Consequently, statements that use this function are\nunsafe for statement-based replication and cannot be stored in the\nquery cache.\n\nThis function is available as of MySQL 5.7.4.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
@@ -265,17 +265,17 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (184,13,'POINTN','PointN(ls, N)\n\nST_PointN() and PointN() are synonyms. For more information, see the\ndescription of ST_PointN().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (185,38,'OCT','Syntax:\nOCT(N)\n\nReturns a string representation of the octal value of N, where N is a\nlonglong (BIGINT) number. This is equivalent to CONV(N,10,8). Returns\nNULL if N is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT OCT(12);\n -> \'14\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (186,32,'SYSDATE','Syntax:\nSYSDATE([fsp])\n\nReturns the current date and time as a value in \'YYYY-MM-DD HH:MM:SS\'\nor YYYYMMDDHHMMSS format, depending on whether the function is used in\na string or numeric context.\n\nIf the fsp argument is given to specify a fractional seconds precision\nfrom 0 to 6, the return value includes a fractional seconds part of\nthat many digits.\n\nSYSDATE() returns the time at which it executes. This differs from the\nbehavior for NOW(), which returns a constant time that indicates the\ntime at which the statement began to execute. (Within a stored function\nor trigger, NOW() returns the time at which the function or triggering\nstatement began to execute.)\n\nmysql> SELECT NOW(), SLEEP(2), NOW();\n+---------------------+----------+---------------------+\n| NOW() | SLEEP(2) | NOW() |\n+---------------------+----------+---------------------+\n| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |\n+---------------------+----------+---------------------+\n\nmysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();\n+---------------------+----------+---------------------+\n| SYSDATE() | SLEEP(2) | SYSDATE() |\n+---------------------+----------+---------------------+\n| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |\n+---------------------+----------+---------------------+\n\nIn addition, the SET TIMESTAMP statement affects the value returned by\nNOW() but not by SYSDATE(). This means that timestamp settings in the\nbinary log have no effect on invocations of SYSDATE().\n\nBecause SYSDATE() can return different values even within the same\nstatement, and is not affected by SET TIMESTAMP, it is nondeterministic\nand therefore unsafe for replication if statement-based binary logging\nis used. If that is a problem, you can use row-based logging.\n\nAlternatively, you can use the --sysdate-is-now option to cause\nSYSDATE() to be an alias for NOW(). This works if the option is used on\nboth the master and the slave.\n\nThe nondeterministic nature of SYSDATE() also means that indexes cannot\nbe used for evaluating expressions that refer to it.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (187,5,'UNINSTALL PLUGIN','Syntax:\nUNINSTALL PLUGIN plugin_name\n\nThis statement removes an installed server plugin. It requires the\nDELETE privilege for the mysql.plugin system table. UNINSTALL PLUGIN is\nthe complement of INSTALL PLUGIN.\n\nplugin_name must be the name of some plugin that is listed in the\nmysql.plugin table. The server executes the plugin\'s deinitialization\nfunction and removes the row for the plugin from the mysql.plugin\ntable, so that subsequent server restarts will not load and initialize\nthe plugin. UNINSTALL PLUGIN does not remove the plugin\'s shared\nlibrary file.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/uninstall-plugin.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/uninstall-plugin.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (187,5,'UNINSTALL PLUGIN','Syntax:\nUNINSTALL PLUGIN plugin_name\n\nThis statement removes an installed server plugin. It requires the\nDELETE privilege for the mysql.plugin system table. UNINSTALL PLUGIN is\nthe complement of INSTALL PLUGIN.\n\nplugin_name must be the name of some plugin that is listed in the\nmysql.plugin table. The server executes the plugin\'s deinitialization\nfunction and removes the row for the plugin from the mysql.plugin\nsystem table, so that subsequent server restarts will not load and\ninitialize the plugin. UNINSTALL PLUGIN does not remove the plugin\'s\nshared library file.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/uninstall-plugin.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/uninstall-plugin.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (188,33,'ASBINARY','AsBinary(g), AsWKB(g)\n\nST_AsBinary(), ST_AsWKB(), AsBinary(), and AsWKB() are synonyms. For\nmore information, see the description of ST_AsBinary().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-format-conversion-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-format-conversion-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (189,33,'ST_MLINEFROMWKB','ST_MLineFromWKB(wkb[, srid]), ST_MultiLineStringFromWKB(wkb[, srid])\n\nConstructs a MultiLineString value using its WKB representation and\nSRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (190,27,'SHOW TABLES','Syntax:\nSHOW [FULL] TABLES\n [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TABLES lists the non-TEMPORARY tables in a given database. You can\nalso get this list using the mysqlshow db_name command. The LIKE\nclause, if present, indicates which table names to match. The WHERE\nclause can be given to select rows using more general conditions, as\ndiscussed in http://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nMatching performed by the LIKE clause is dependent on the setting of\nthe lower_case_table_names system variable.\n\nThis statement also lists any views in the database. The optional FULL\nmodifier causes SHOW TABLES to display a second output column with\nvalues of BASE TABLE for a table and VIEW for a view.\n\nIf you have no privileges for a base table or view, it does not show up\nin the output from SHOW TABLES or mysqlshow db_name.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-tables.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-tables.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (190,27,'SHOW TABLES','Syntax:\nSHOW [FULL] TABLES\n [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TABLES lists the non-TEMPORARY tables in a given database. You can\nalso get this list using the mysqlshow db_name command. The LIKE\nclause, if present, indicates which table names to match. The WHERE\nclause can be given to select rows using more general conditions, as\ndiscussed in http://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nMatching performed by the LIKE clause is dependent on the setting of\nthe lower_case_table_names system variable.\n\nThis statement also lists any views in the database. The optional FULL\nmodifier causes SHOW TABLES to display a second output column with\nvalues of BASE TABLE for a table, VIEW for a view, or SYSTEM VIEW for\nan INFORMATION_SCHEMA table.\n\nIf you have no privileges for a base table or view, it does not show up\nin the output from SHOW TABLES or mysqlshow db_name.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-tables.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-tables.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (191,32,'MAKEDATE','Syntax:\nMAKEDATE(year,dayofyear)\n\nReturns a date, given year and day-of-year values. dayofyear must be\ngreater than 0 or the result is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);\n -> \'2011-01-31\', \'2011-02-01\'\nmysql> SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);\n -> \'2011-12-31\', \'2014-12-31\'\nmysql> SELECT MAKEDATE(2011,0);\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (192,38,'BINARY OPERATOR','Syntax:\nBINARY expr\n\nThe BINARY operator converts the expression to a binary string. A\ncommon use for BINARY is to force a character string comparison to be\ndone byte by byte rather than character by character, in effect\nbecoming case-sensitive. The BINARY operator also causes trailing\nspaces in comparisons to be significant.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/cast-functions.html\n\n','mysql> SELECT \'a\' = \'A\';\n -> 1\nmysql> SELECT BINARY \'a\' = \'A\';\n -> 0\nmysql> SELECT \'a\' = \'a \';\n -> 1\nmysql> SELECT BINARY \'a\' = \'a \';\n -> 0\n','http://dev.mysql.com/doc/refman/5.7/en/cast-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (193,7,'MBROVERLAPS','MBROverlaps(g1, g2)\n\nTwo geometries spatially overlap if they intersect and their\nintersection results in a geometry of the same dimension but not equal\nto either of the given geometries.\n\nThis function returns 1 or 0 to indicate whether the minimum bounding\nrectangles of the two geometries g1 and g2 overlap.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (194,33,'ST_LINEFROMWKB','ST_LineFromWKB(wkb[, srid]), ST_LineStringFromWKB(wkb[, srid])\n\nConstructs a LineString value using its WKB representation and SRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (195,7,'ASYMMETRIC_DERIVE','Syntax:\nASYMMETRIC_DERIVE(pub_key_str, priv_key_str)\n\nDerives a symmetric key using the private key of one party and the\npublic key of another, and returns the resulting key as a binary\nstring. If key derivation fails, the result is NULL.\n\npub_key_str and priv_key_str must be valid key strings in PEM format.\nThey must be created using the DH algorithm.\n\nSuppose that you have two pairs of public and private keys:\n\nSET @dhp = CREATE_DH_PARAMETERS(1024);\nSET @priv1 = CREATE_ASYMMETRIC_PRIV_KEY(\'DH\', @dhp);\nSET @pub1 = CREATE_ASYMMETRIC_PUB_KEY(\'DH\', @priv1);\nSET @priv2 = CREATE_ASYMMETRIC_PRIV_KEY(\'DH\', @dhp);\nSET @pub2 = CREATE_ASYMMETRIC_PUB_KEY(\'DH\', @priv2);\n\nSuppose further that you use the private key from one pair and the\npublic key from the other pair to create a symmetric key string. Then\nthis symmetric key identity relationship holds:\n\nASYMMETRIC_DERIVE(@pub1, @priv2) = ASYMMETRIC_DERIVE(@pub2, @priv1)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (196,28,'INSERT SELECT','Syntax:\nINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [(col_name [, col_name] ...)]\n SELECT ...\n [ON DUPLICATE KEY UPDATE assignment_list]\n\nvalue:\n {expr | DEFAULT}\n\nassignment:\n col_name = value\n\nassignment_list:\n assignment [, assignment] ...\n\nWith INSERT ... SELECT, you can quickly insert many rows into a table\nfrom the result of a SELECT statement, which can select from one or\nmany tables. For example:\n\nINSERT INTO tbl_temp2 (fld_id)\n SELECT tbl_temp1.fld_order_id\n FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/insert-select.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/insert-select.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (197,40,'CREATE PROCEDURE','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n PROCEDURE sp_name ([proc_parameter[,...]])\n [characteristic ...] routine_body\n\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n FUNCTION sp_name ([func_parameter[,...]])\n RETURNS type\n [characteristic ...] routine_body\n\nproc_parameter:\n [ IN | OUT | INOUT ] param_name type\n\nfunc_parameter:\n param_name type\n\ntype:\n Any valid MySQL data type\n\ncharacteristic:\n COMMENT \'string\'\n | LANGUAGE SQL\n | [NOT] DETERMINISTIC\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n\nroutine_body:\n Valid SQL routine statement\n\nThese statements create stored routines. By default, a routine is\nassociated with the default database. To associate the routine\nexplicitly with a given database, specify the name as db_name.sp_name\nwhen you create it.\n\nThe CREATE FUNCTION statement is also used in MySQL to support UDFs\n(user-defined functions). See\nhttp://dev.mysql.com/doc/refman/5.7/en/adding-functions.html. A UDF can\nbe regarded as an external stored function. Stored functions share\ntheir namespace with UDFs. See\nhttp://dev.mysql.com/doc/refman/5.7/en/function-resolution.html, for\nthe rules describing how the server interprets references to different\nkinds of functions.\n\nTo invoke a stored procedure, use the CALL statement (see [HELP CALL]).\nTo invoke a stored function, refer to it in an expression. The function\nreturns a value during expression evaluation.\n\nCREATE PROCEDURE and CREATE FUNCTION require the CREATE ROUTINE\nprivilege. They might also require the SUPER privilege, depending on\nthe DEFINER value, as described later in this section. If binary\nlogging is enabled, CREATE FUNCTION might require the SUPER privilege,\nas described in\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html.\n\nBy default, MySQL automatically grants the ALTER ROUTINE and EXECUTE\nprivileges to the routine creator. This behavior can be changed by\ndisabling the automatic_sp_privileges system variable. See\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-routines-privileges.html.\n\nThe DEFINER and SQL SECURITY clauses specify the security context to be\nused when checking access privileges at routine execution time, as\ndescribed later in this section.\n\nIf the routine name is the same as the name of a built-in SQL function,\na syntax error occurs unless you use a space between the name and the\nfollowing parenthesis when defining the routine or invoking it later.\nFor this reason, avoid using the names of existing SQL functions for\nyour own stored routines.\n\nThe IGNORE_SPACE SQL mode applies to built-in functions, not to stored\nroutines. It is always permissible to have spaces after a stored\nroutine name, regardless of whether IGNORE_SPACE is enabled.\n\nThe parameter list enclosed within parentheses must always be present.\nIf there are no parameters, an empty parameter list of () should be\nused. Parameter names are not case sensitive.\n\nEach parameter is an IN parameter by default. To specify otherwise for\na parameter, use the keyword OUT or INOUT before the parameter name.\n\n*Note*:\n\nSpecifying a parameter as IN, OUT, or INOUT is valid only for a\nPROCEDURE. For a FUNCTION, parameters are always regarded as IN\nparameters.\n\nAn IN parameter passes a value into a procedure. The procedure might\nmodify the value, but the modification is not visible to the caller\nwhen the procedure returns. An OUT parameter passes a value from the\nprocedure back to the caller. Its initial value is NULL within the\nprocedure, and its value is visible to the caller when the procedure\nreturns. An INOUT parameter is initialized by the caller, can be\nmodified by the procedure, and any change made by the procedure is\nvisible to the caller when the procedure returns.\n\nFor each OUT or INOUT parameter, pass a user-defined variable in the\nCALL statement that invokes the procedure so that you can obtain its\nvalue when the procedure returns. If you are calling the procedure from\nwithin another stored procedure or function, you can also pass a\nroutine parameter or local routine variable as an IN or INOUT\nparameter.\n\nRoutine parameters cannot be referenced in statements prepared within\nthe routine; see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html\n.\n\nThe following example shows a simple stored procedure that uses an OUT\nparameter:\n\nmysql> delimiter //\n\nmysql> CREATE PROCEDURE simpleproc (OUT param1 INT)\n -> BEGIN\n -> SELECT COUNT(*) INTO param1 FROM t;\n -> END//\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> delimiter ;\n\nmysql> CALL simpleproc(@a);\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT @a;\n+------+\n| @a |\n+------+\n| 3 |\n+------+\n1 row in set (0.00 sec)\n\nThe example uses the mysql client delimiter command to change the\nstatement delimiter from ; to // while the procedure is being defined.\nThis enables the ; delimiter used in the procedure body to be passed\nthrough to the server rather than being interpreted by mysql itself.\nSee\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-defining.html.\n\nThe RETURNS clause may be specified only for a FUNCTION, for which it\nis mandatory. It indicates the return type of the function, and the\nfunction body must contain a RETURN value statement. If the RETURN\nstatement returns a value of a different type, the value is coerced to\nthe proper type. For example, if a function specifies an ENUM or SET\nvalue in the RETURNS clause, but the RETURN statement returns an\ninteger, the value returned from the function is the string for the\ncorresponding ENUM member of set of SET members.\n\nThe following example function takes a parameter, performs an operation\nusing an SQL function, and returns the result. In this case, it is\nunnecessary to use delimiter because the function definition contains\nno internal ; statement delimiters:\n\nmysql> CREATE FUNCTION hello (s CHAR(20))\nmysql> RETURNS CHAR(50) DETERMINISTIC\n -> RETURN CONCAT(\'Hello, \',s,\'!\');\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT hello(\'world\');\n+----------------+\n| hello(\'world\') |\n+----------------+\n| Hello, world! |\n+----------------+\n1 row in set (0.00 sec)\n\nParameter types and function return types can be declared to use any\nvalid data type. The COLLATE attribute can be used if preceded by the\nCHARACTER SET attribute.\n\nThe routine_body consists of a valid SQL routine statement. This can be\na simple statement such as SELECT or INSERT, or a compound statement\nwritten using BEGIN and END. Compound statements can contain\ndeclarations, loops, and other control structure statements. The syntax\nfor these statements is described in\nhttp://dev.mysql.com/doc/refman/5.7/en/sql-syntax-compound-statements.h\ntml.\n\nMySQL permits routines to contain DDL statements, such as CREATE and\nDROP. MySQL also permits stored procedures (but not stored functions)\nto contain SQL transaction statements such as COMMIT. Stored functions\nmay not contain statements that perform explicit or implicit commit or\nrollback. Support for these statements is not required by the SQL\nstandard, which states that each DBMS vendor may decide whether to\npermit them.\n\nStatements that return a result set can be used within a stored\nprocedure but not within a stored function. This prohibition includes\nSELECT statements that do not have an INTO var_list clause and other\nstatements such as SHOW, EXPLAIN, and CHECK TABLE. For statements that\ncan be determined at function definition time to return a result set, a\nNot allowed to return a result set from a function error occurs\n(ER_SP_NO_RETSET). For statements that can be determined only at\nruntime to return a result set, a PROCEDURE %s can\'t return a result\nset in the given context error occurs (ER_SP_BADSELECT).\n\nUSE statements within stored routines are not permitted. When a routine\nis invoked, an implicit USE db_name is performed (and undone when the\nroutine terminates). The causes the routine to have the given default\ndatabase while it executes. References to objects in databases other\nthan the routine default database should be qualified with the\nappropriate database name.\n\nFor additional information about statements that are not permitted in\nstored routines, see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html\n.\n\nFor information about invoking stored procedures from within programs\nwritten in a language that has a MySQL interface, see [HELP CALL].\n\nMySQL stores the sql_mode system variable setting in effect when a\nroutine is created or altered, and always executes the routine with\nthis setting in force, regardless of the current server SQL mode when\nthe routine begins executing.\n\nThe switch from the SQL mode of the invoker to that of the routine\noccurs after evaluation of arguments and assignment of the resulting\nvalues to routine parameters. If you define a routine in strict SQL\nmode but invoke it in nonstrict mode, assignment of arguments to\nroutine parameters does not take place in strict mode. If you require\nthat expressions passed to a routine be assigned in strict SQL mode,\nyou should invoke the routine with strict mode in effect.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (197,40,'CREATE PROCEDURE','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n PROCEDURE sp_name ([proc_parameter[,...]])\n [characteristic ...] routine_body\n\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n FUNCTION sp_name ([func_parameter[,...]])\n RETURNS type\n [characteristic ...] routine_body\n\nproc_parameter:\n [ IN | OUT | INOUT ] param_name type\n\nfunc_parameter:\n param_name type\n\ntype:\n Any valid MySQL data type\n\ncharacteristic:\n COMMENT \'string\'\n | LANGUAGE SQL\n | [NOT] DETERMINISTIC\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n\nroutine_body:\n Valid SQL routine statement\n\nThese statements create stored routines. By default, a routine is\nassociated with the default database. To associate the routine\nexplicitly with a given database, specify the name as db_name.sp_name\nwhen you create it.\n\nThe CREATE FUNCTION statement is also used in MySQL to support UDFs\n(user-defined functions). See\nhttp://dev.mysql.com/doc/refman/5.7/en/adding-functions.html. A UDF can\nbe regarded as an external stored function. Stored functions share\ntheir namespace with UDFs. See\nhttp://dev.mysql.com/doc/refman/5.7/en/function-resolution.html, for\nthe rules describing how the server interprets references to different\nkinds of functions.\n\nTo invoke a stored procedure, use the CALL statement (see [HELP CALL]).\nTo invoke a stored function, refer to it in an expression. The function\nreturns a value during expression evaluation.\n\nCREATE PROCEDURE and CREATE FUNCTION require the CREATE ROUTINE\nprivilege. They might also require the SUPER privilege, depending on\nthe DEFINER value, as described later in this section. If binary\nlogging is enabled, CREATE FUNCTION might require the SUPER privilege,\nas described in\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html.\n\nBy default, MySQL automatically grants the ALTER ROUTINE and EXECUTE\nprivileges to the routine creator. This behavior can be changed by\ndisabling the automatic_sp_privileges system variable. See\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-routines-privileges.html.\n\nThe DEFINER and SQL SECURITY clauses specify the security context to be\nused when checking access privileges at routine execution time, as\ndescribed later in this section.\n\nIf the routine name is the same as the name of a built-in SQL function,\na syntax error occurs unless you use a space between the name and the\nfollowing parenthesis when defining the routine or invoking it later.\nFor this reason, avoid using the names of existing SQL functions for\nyour own stored routines.\n\nThe IGNORE_SPACE SQL mode applies to built-in functions, not to stored\nroutines. It is always permissible to have spaces after a stored\nroutine name, regardless of whether IGNORE_SPACE is enabled.\n\nThe parameter list enclosed within parentheses must always be present.\nIf there are no parameters, an empty parameter list of () should be\nused. Parameter names are not case sensitive.\n\nEach parameter is an IN parameter by default. To specify otherwise for\na parameter, use the keyword OUT or INOUT before the parameter name.\n\n*Note*:\n\nSpecifying a parameter as IN, OUT, or INOUT is valid only for a\nPROCEDURE. For a FUNCTION, parameters are always regarded as IN\nparameters.\n\nAn IN parameter passes a value into a procedure. The procedure might\nmodify the value, but the modification is not visible to the caller\nwhen the procedure returns. An OUT parameter passes a value from the\nprocedure back to the caller. Its initial value is NULL within the\nprocedure, and its value is visible to the caller when the procedure\nreturns. An INOUT parameter is initialized by the caller, can be\nmodified by the procedure, and any change made by the procedure is\nvisible to the caller when the procedure returns.\n\nFor each OUT or INOUT parameter, pass a user-defined variable in the\nCALL statement that invokes the procedure so that you can obtain its\nvalue when the procedure returns. If you are calling the procedure from\nwithin another stored procedure or function, you can also pass a\nroutine parameter or local routine variable as an OUT or INOUT\nparameter. If you are calling the procedure from within a trigger, you\ncan also pass NEW.col_name as an OUT or INOUT parameter.\n\nRoutine parameters cannot be referenced in statements prepared within\nthe routine; see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html\n.\n\nThe following example shows a simple stored procedure that uses an OUT\nparameter:\n\nmysql> delimiter //\n\nmysql> CREATE PROCEDURE simpleproc (OUT param1 INT)\n -> BEGIN\n -> SELECT COUNT(*) INTO param1 FROM t;\n -> END//\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> delimiter ;\n\nmysql> CALL simpleproc(@a);\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT @a;\n+------+\n| @a |\n+------+\n| 3 |\n+------+\n1 row in set (0.00 sec)\n\nThe example uses the mysql client delimiter command to change the\nstatement delimiter from ; to // while the procedure is being defined.\nThis enables the ; delimiter used in the procedure body to be passed\nthrough to the server rather than being interpreted by mysql itself.\nSee\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-defining.html.\n\nThe RETURNS clause may be specified only for a FUNCTION, for which it\nis mandatory. It indicates the return type of the function, and the\nfunction body must contain a RETURN value statement. If the RETURN\nstatement returns a value of a different type, the value is coerced to\nthe proper type. For example, if a function specifies an ENUM or SET\nvalue in the RETURNS clause, but the RETURN statement returns an\ninteger, the value returned from the function is the string for the\ncorresponding ENUM member of set of SET members.\n\nThe following example function takes a parameter, performs an operation\nusing an SQL function, and returns the result. In this case, it is\nunnecessary to use delimiter because the function definition contains\nno internal ; statement delimiters:\n\nmysql> CREATE FUNCTION hello (s CHAR(20))\nmysql> RETURNS CHAR(50) DETERMINISTIC\n -> RETURN CONCAT(\'Hello, \',s,\'!\');\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT hello(\'world\');\n+----------------+\n| hello(\'world\') |\n+----------------+\n| Hello, world! |\n+----------------+\n1 row in set (0.00 sec)\n\nParameter types and function return types can be declared to use any\nvalid data type. The COLLATE attribute can be used if preceded by the\nCHARACTER SET attribute.\n\nThe routine_body consists of a valid SQL routine statement. This can be\na simple statement such as SELECT or INSERT, or a compound statement\nwritten using BEGIN and END. Compound statements can contain\ndeclarations, loops, and other control structure statements. The syntax\nfor these statements is described in\nhttp://dev.mysql.com/doc/refman/5.7/en/sql-syntax-compound-statements.h\ntml.\n\nMySQL permits routines to contain DDL statements, such as CREATE and\nDROP. MySQL also permits stored procedures (but not stored functions)\nto contain SQL transaction statements such as COMMIT. Stored functions\nmay not contain statements that perform explicit or implicit commit or\nrollback. Support for these statements is not required by the SQL\nstandard, which states that each DBMS vendor may decide whether to\npermit them.\n\nStatements that return a result set can be used within a stored\nprocedure but not within a stored function. This prohibition includes\nSELECT statements that do not have an INTO var_list clause and other\nstatements such as SHOW, EXPLAIN, and CHECK TABLE. For statements that\ncan be determined at function definition time to return a result set, a\nNot allowed to return a result set from a function error occurs\n(ER_SP_NO_RETSET). For statements that can be determined only at\nruntime to return a result set, a PROCEDURE %s can\'t return a result\nset in the given context error occurs (ER_SP_BADSELECT).\n\nUSE statements within stored routines are not permitted. When a routine\nis invoked, an implicit USE db_name is performed (and undone when the\nroutine terminates). The causes the routine to have the given default\ndatabase while it executes. References to objects in databases other\nthan the routine default database should be qualified with the\nappropriate database name.\n\nFor additional information about statements that are not permitted in\nstored routines, see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html\n.\n\nFor information about invoking stored procedures from within programs\nwritten in a language that has a MySQL interface, see [HELP CALL].\n\nMySQL stores the sql_mode system variable setting in effect when a\nroutine is created or altered, and always executes the routine with\nthis setting in force, regardless of the current server SQL mode when\nthe routine begins executing.\n\nThe switch from the SQL mode of the invoker to that of the routine\noccurs after evaluation of arguments and assignment of the resulting\nvalues to routine parameters. If you define a routine in strict SQL\nmode but invoke it in nonstrict mode, assignment of arguments to\nroutine parameters does not take place in strict mode. If you require\nthat expressions passed to a routine be assigned in strict SQL mode,\nyou should invoke the routine with strict mode in effect.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (198,24,'GET DIAGNOSTICS','Syntax:\nGET [CURRENT | STACKED] DIAGNOSTICS\n{\n statement_information_item\n [, statement_information_item] ...\n | CONDITION condition_number\n condition_information_item\n [, condition_information_item] ...\n}\n\nstatement_information_item:\n target = statement_information_item_name\n\ncondition_information_item:\n target = condition_information_item_name\n\nstatement_information_item_name:\n NUMBER\n | ROW_COUNT\n\ncondition_information_item_name:\n CLASS_ORIGIN\n | SUBCLASS_ORIGIN\n | RETURNED_SQLSTATE\n | MESSAGE_TEXT\n | MYSQL_ERRNO\n | CONSTRAINT_CATALOG\n | CONSTRAINT_SCHEMA\n | CONSTRAINT_NAME\n | CATALOG_NAME\n | SCHEMA_NAME\n | TABLE_NAME\n | COLUMN_NAME\n | CURSOR_NAME\n\ncondition_number, target:\n (see following discussion)\n\nSQL statements produce diagnostic information that populates the\ndiagnostics area. The GET DIAGNOSTICS statement enables applications to\ninspect this information. (You can also use SHOW WARNINGS or SHOW\nERRORS to see conditions or errors.)\n\nNo special privileges are required to execute GET DIAGNOSTICS.\n\nThe keyword CURRENT means to retrieve information from the current\ndiagnostics area. The keyword STACKED means to retrieve information\nfrom the second diagnostics area, which is available only if the\ncurrent context is a condition handler. If neither keyword is given,\nthe default is to use the current diagnostics area.\n\nThe GET DIAGNOSTICS statement is typically used in a handler within a\nstored program. It is a MySQL extension that GET [CURRENT] DIAGNOSTICS\nis permitted outside handler context to check the execution of any SQL\nstatement. For example, if you invoke the mysql client program, you can\nenter these statements at the prompt:\n\nmysql> DROP TABLE test.no_such_table;\nERROR 1051 (42S02): Unknown table \'test.no_such_table\'\nmysql> GET DIAGNOSTICS CONDITION 1\n -> @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT;\nmysql> SELECT @p1, @p2;\n+-------+------------------------------------+\n| @p1 | @p2 |\n+-------+------------------------------------+\n| 42S02 | Unknown table \'test.no_such_table\' |\n+-------+------------------------------------+\n\nThis extension applies only to the current diagnostics area. It does\nnot apply to the second diagnostics area because GET STACKED\nDIAGNOSTICS is permitted only if the current context is a condition\nhandler. If that is not the case, a GET STACKED DIAGNOSTICS when\nhandler not active error occurs.\n\nFor a description of the diagnostics area, see\nhttp://dev.mysql.com/doc/refman/5.7/en/diagnostics-area.html. Briefly,\nit contains two kinds of information:\n\no Statement information, such as the number of conditions that occurred\n or the affected-rows count.\n\no Condition information, such as the error code and message. If a\n statement raises multiple conditions, this part of the diagnostics\n area has a condition area for each one. If a statement raises no\n conditions, this part of the diagnostics area is empty.\n\nFor a statement that produces three conditions, the diagnostics area\ncontains statement and condition information like this:\n\nStatement information:\n row count\n ... other statement information items ...\nCondition area list:\n Condition area 1:\n error code for condition 1\n error message for condition 1\n ... other condition information items ...\n Condition area 2:\n error code for condition 2:\n error message for condition 2\n ... other condition information items ...\n Condition area 3:\n error code for condition 3\n error message for condition 3\n ... other condition information items ...\n\nGET DIAGNOSTICS can obtain either statement or condition information,\nbut not both in the same statement:\n\no To obtain statement information, retrieve the desired statement items\n into target variables. This instance of GET DIAGNOSTICS assigns the\n number of available conditions and the rows-affected count to the\n user variables @p1 and @p2:\n\nGET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;\n\no To obtain condition information, specify the condition number and\n retrieve the desired condition items into target variables. This\n instance of GET DIAGNOSTICS assigns the SQLSTATE value and error\n message to the user variables @p3 and @p4:\n\nGET DIAGNOSTICS CONDITION 1\n @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;\n\nThe retrieval list specifies one or more target = item_name\nassignments, separated by commas. Each assignment names a target\nvariable and either a statement_information_item_name or\ncondition_information_item_name designator, depending on whether the\nstatement retrieves statement or condition information.\n\nValid target designators for storing item information can be stored\nprocedure or function parameters, stored program local variables\ndeclared with DECLARE, or user-defined variables.\n\nValid condition_number designators can be stored procedure or function\nparameters, stored program local variables declared with DECLARE,\nuser-defined variables, system variables, or literals. A character\nliteral may include a _charset introducer. A warning occurs if the\ncondition number is not in the range from 1 to the number of condition\nareas that have information. In this case, the warning is added to the\ndiagnostics area without clearing it.\n\nWhen a condition occurs, MySQL does not populate all condition items\nrecognized by GET DIAGNOSTICS. For example:\n\nmysql> GET DIAGNOSTICS CONDITION 1\n -> @p5 = SCHEMA_NAME, @p6 = TABLE_NAME;\nmysql> SELECT @p5, @p6;\n+------+------+\n| @p5 | @p6 |\n+------+------+\n| | |\n+------+------+\n\nIn standard SQL, if there are multiple conditions, the first condition\nrelates to the SQLSTATE value returned for the previous SQL statement.\nIn MySQL, this is not guaranteed. To get the main error, you cannot do\nthis:\n\nGET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;\n\nInstead, retrieve the condition count first, then use it to specify\nwhich condition number to inspect:\n\nGET DIAGNOSTICS @cno = NUMBER;\nGET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;\n\nFor information about permissible statement and condition information\nitems, and which ones are populated when a condition occurs, see\nhttp://dev.mysql.com/doc/refman/5.7/en/diagnostics-area.html#diagnostic\ns-area-information-items.\n\nHere is an example that uses GET DIAGNOSTICS and an exception handler\nin stored procedure context to assess the outcome of an insert\noperation. If the insert was successful, the procedure uses GET\nDIAGNOSTICS to get the rows-affected count. This shows that you can use\nGET DIAGNOSTICS multiple times to retrieve information about a\nstatement as long as the current diagnostics area has not been cleared.\n\nCREATE PROCEDURE do_insert(value INT)\nBEGIN\n -- Declare variables to hold diagnostics area information\n DECLARE code CHAR(5) DEFAULT \'00000\';\n DECLARE msg TEXT;\n DECLARE rows INT;\n DECLARE result TEXT;\n -- Declare exception handler for failed insert\n DECLARE CONTINUE HANDLER FOR SQLEXCEPTION\n BEGIN\n GET DIAGNOSTICS CONDITION 1\n code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;\n END;\n\n -- Perform the insert\n INSERT INTO t1 (int_col) VALUES(value);\n -- Check whether the insert was successful\n IF code = \'00000\' THEN\n GET DIAGNOSTICS rows = ROW_COUNT;\n SET result = CONCAT(\'insert succeeded, row count = \',rows);\n ELSE\n SET result = CONCAT(\'insert failed, error = \',code,\', message = \',msg);\n END IF;\n -- Say what happened\n SELECT result;\nEND;\n\nSuppose that t1.int_col is an integer column that is declared as NOT\nNULL. The procedure produces these results when invoked to insert\nnon-NULL and NULL values, respectively:\n\nmysql> CALL do_insert(1);\n+---------------------------------+\n| result |\n+---------------------------------+\n| insert succeeded, row count = 1 |\n+---------------------------------+\n\nmysql> CALL do_insert(NULL);\n+-------------------------------------------------------------------------+\n| result |\n+-------------------------------------------------------------------------+\n| insert failed, error = 23000, message = Column \'int_col\' cannot be null |\n+-------------------------------------------------------------------------+\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (199,38,'NOT REGEXP','Syntax:\nexpr NOT REGEXP pat, expr NOT RLIKE pat\n\nThis is the same as NOT (expr REGEXP pat).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/regexp.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/regexp.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (200,24,'LEAVE','Syntax:\nLEAVE label\n\nThis statement is used to exit the flow control construct that has the\ngiven label. If the label is for the outermost stored program block,\nLEAVE exits the program.\n\nLEAVE can be used within BEGIN ... END or loop constructs (LOOP,\nREPEAT, WHILE).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/leave.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/leave.html');
@@ -289,21 +289,21 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (208,7,'->>','Syntax:\ncolumn->>path\n\nThis is an improved, unquoting extraction operator available in MySQL\n5.7.13 and later. Whereas the -> operator simply extracts a value, the\n->> operator in addition unquotes the extracted result. In other words,\ngiven a JSON column value column and a path expression path, the\nfollowing three expressions return the same value:\n\no JSON_UNQUOTE( JSON_EXTRACT(column, path) )\n\no JSON_UNQUOTE(column -> path)\n\no column->>path\n\nThe ->> operator can be used wherever JSON_UNQUOTE(JSON_EXTRACT())\nwould be allowed. This includes (but is not limited to) SELECT lists,\nWHERE and HAVING clauses, and ORDER BY and GROUP BY clauses.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html\n\n','mysql> SELECT * FROM jemp WHERE g > 2;\n+-------------------------------+------+\n| c | g |\n+-------------------------------+------+\n| {"id": "3", "name": "Barney"} | 3 |\n| {"id": "4", "name": "Betty"} | 4 |\n+-------------------------------+------+\n2 rows in set (0.01 sec)\n\nmysql> SELECT c->\'$.name\' AS name\n -> FROM jemp WHERE g > 2;\n+----------+\n| name |\n+----------+\n| "Barney" |\n| "Betty" |\n+----------+\n2 rows in set (0.00 sec)\n\nmysql> SELECT JSON_UNQUOTE(c->\'$.name\') AS name\n -> FROM jemp WHERE g > 2;\n+--------+\n| name |\n+--------+\n| Barney |\n| Betty |\n+--------+\n2 rows in set (0.00 sec)\n\nmysql> SELECT c->>\'$.name\' AS name\n -> FROM jemp WHERE g > 2;\n+--------+\n| name |\n+--------+\n| Barney |\n| Betty |\n+--------+\n2 rows in set (0.00 sec)\n\nmysql> CREATE TABLE tj10 (a JSON, b INT);\nQuery OK, 0 rows affected (0.26 sec)\n\nmysql> INSERT INTO tj10 VALUES\n -> (\'[3,10,5,"x",44]\', 33),\n -> (\'[3,10,5,17,[22,"y",66]]\', 0);\nQuery OK, 2 rows affected (0.04 sec)\nRecords: 2 Duplicates: 0 Warnings: 0\n\nmysql> SELECT a->"$[3]", a->"$[4][1]" FROM tj10;\n+-----------+--------------+\n| a->"$[3]" | a->"$[4][1]" |\n+-----------+--------------+\n| "x" | NULL |\n| 17 | "y" |\n+-----------+--------------+\n2 rows in set (0.00 sec)\n\nmysql> SELECT a->>"$[3]", a->>"$[4][1]" FROM tj10;\n+------------+---------------+\n| a->>"$[3]" | a->>"$[4][1]" |\n+------------+---------------+\n| x | NULL |\n| 17 | y |\n+------------+---------------+\n2 rows in set (0.00 sec)\n\nmysql> EXPLAIN SELECT c->>\'$.name\' AS name\n -> FROM jemp WHERE g > 2\\G\n*************************** 1. row ***************************\n id: 1\n select_type: SIMPLE\n table: jemp\n partitions: NULL\n type: range\npossible_keys: i\n key: i\n key_len: 5\n ref: NULL\n rows: 2\n filtered: 100.00\n Extra: Using where\n1 row in set, 1 warning (0.00 sec)\n\nmysql> SHOW WARNINGS\\G\n*************************** 1. row ***************************\n Level: Note\n Code: 1003\nMessage: /* select#1 */ select\njson_unquote(json_extract(`jtest`.`jemp`.`c`,\'$.name\')) AS `name` from\n`jtest`.`jemp` where (`jtest`.`jemp`.`g` > 2)\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (209,27,'FLUSH','Syntax:\nFLUSH [NO_WRITE_TO_BINLOG | LOCAL] {\n flush_option [, flush_option] ...\n | tables_option\n}\n\nflush_option: {\n BINARY LOGS\n | DES_KEY_FILE\n | ENGINE LOGS\n | ERROR LOGS\n | GENERAL LOGS\n | HOSTS\n | LOGS\n | PRIVILEGES\n | OPTIMIZER_COSTS\n | QUERY CACHE\n | RELAY LOGS [FOR CHANNEL channel]\n | SLOW LOGS\n | STATUS\n | USER_RESOURCES\n}\n\ntables_option: {\n TABLES\n | TABLES tbl_name [, tbl_name] ...\n | TABLES WITH READ LOCK\n | TABLES tbl_name [, tbl_name] ... WITH READ LOCK\n | TABLES tbl_name [, tbl_name] ... FOR EXPORT\n}\n\nThe FLUSH statement has several variant forms that clear or reload\nvarious internal caches, flush tables, or acquire locks. To execute\nFLUSH, you must have the RELOAD privilege. Specific flush options might\nrequire additional privileges, as described later.\n\n*Note*:\n\nIt is not possible to issue FLUSH statements within stored functions or\ntriggers. However, you may use FLUSH in stored procedures, so long as\nthese are not called from stored functions or triggers. See\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html\n.\n\nBy default, the server writes FLUSH statements to the binary log so\nthat they replicate to replication slaves. To suppress logging, specify\nthe optional NO_WRITE_TO_BINLOG keyword or its alias LOCAL.\n\n*Note*:\n\nFLUSH LOGS, FLUSH TABLES WITH READ LOCK (with or without a table list),\nand FLUSH TABLES tbl_name ... FOR EXPORT are not written to the binary\nlog in any case because they would cause problems if replicated to a\nslave.\n\nThe FLUSH statement causes an implicit commit. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nThe mysqladmin utility provides a command-line interface to some flush\noperations, using commands such as flush-hosts, flush-logs,\nflush-privileges, flush-status, and flush-tables. See\nhttp://dev.mysql.com/doc/refman/5.7/en/mysqladmin.html.\n\nSending a SIGHUP signal to the server causes several flush operations\nto occur that are similar to various forms of the FLUSH statement. See\nhttp://dev.mysql.com/doc/refman/5.7/en/server-signal-response.html.\n\nThe RESET statement is similar to FLUSH. See [HELP RESET], for\ninformation about using the RESET statement with replication.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/flush.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/flush.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (210,24,'BEGIN END','Syntax:\n[begin_label:] BEGIN\n [statement_list]\nEND [end_label]\n\nBEGIN ... END syntax is used for writing compound statements, which can\nappear within stored programs (stored procedures and functions,\ntriggers, and events). A compound statement can contain multiple\nstatements, enclosed by the BEGIN and END keywords. statement_list\nrepresents a list of one or more statements, each terminated by a\nsemicolon (;) statement delimiter. The statement_list itself is\noptional, so the empty compound statement (BEGIN END) is legal.\n\nBEGIN ... END blocks can be nested.\n\nUse of multiple statements requires that a client is able to send\nstatement strings containing the ; statement delimiter. In the mysql\ncommand-line client, this is handled with the delimiter command.\nChanging the ; end-of-statement delimiter (for example, to //) permit ;\nto be used in a program body. For an example, see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-defining.html.\n\nA BEGIN ... END block can be labeled. See [HELP labels].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/begin-end.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/begin-end.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (211,27,'SHOW PROCEDURE STATUS','Syntax:\nSHOW PROCEDURE STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement is a MySQL extension. It returns characteristics of a\nstored procedure, such as the database, name, type, creator, creation\nand modification dates, and character set information. A similar\nstatement, SHOW FUNCTION STATUS, displays information about stored\nfunctions (see [HELP SHOW FUNCTION STATUS]).\n\nThe LIKE clause, if present, indicates which procedure or function\nnames to match. The WHERE clause can be given to select rows using more\ngeneral conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-procedure-status.html\n\n','mysql> SHOW PROCEDURE STATUS LIKE \'sp1\'\\G\n*************************** 1. row ***************************\n Db: test\n Name: sp1\n Type: PROCEDURE\n Definer: testuser@localhost\n Modified: 2004-08-03 15:29:37\n Created: 2004-08-03 15:29:37\n Security_type: DEFINER\n Comment:\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.7/en/show-procedure-status.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (211,27,'SHOW PROCEDURE STATUS','Syntax:\nSHOW PROCEDURE STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement is a MySQL extension. It returns characteristics of a\nstored procedure, such as the database, name, type, creator, creation\nand modification dates, and character set information. A similar\nstatement, SHOW FUNCTION STATUS, displays information about stored\nfunctions (see [HELP SHOW FUNCTION STATUS]).\n\nThe LIKE clause, if present, indicates which procedure or function\nnames to match. The WHERE clause can be given to select rows using more\ngeneral conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-procedure-status.html\n\n','mysql> SHOW PROCEDURE STATUS LIKE \'sp1\'\\G\n*************************** 1. row ***************************\n Db: test\n Name: sp1\n Type: PROCEDURE\n Definer: testuser@localhost\n Modified: 2018-08-08 13:54:11\n Created: 2018-08-08 13:54:11\n Security_type: DEFINER\n Comment:\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.7/en/show-procedure-status.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (212,16,'STDDEV_POP','Syntax:\nSTDDEV_POP(expr)\n\nReturns the population standard deviation of expr (the square root of\nVAR_POP()). You can also use STD() or STDDEV(), which are equivalent\nbut not standard SQL.\n\nIf there are no matching rows, STDDEV_POP() returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (213,27,'SHOW CHARACTER SET','Syntax:\nSHOW CHARACTER SET\n [LIKE \'pattern\' | WHERE expr]\n\nThe SHOW CHARACTER SET statement shows all available character sets.\nThe LIKE clause, if present, indicates which character set names to\nmatch. The WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html. For example:\n\nmysql> SHOW CHARACTER SET LIKE \'latin%\';\n+---------+-----------------------------+-------------------+--------+\n| Charset | Description | Default collation | Maxlen |\n+---------+-----------------------------+-------------------+--------+\n| latin1 | cp1252 West European | latin1_swedish_ci | 1 |\n| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |\n| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |\n| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |\n+---------+-----------------------------+-------------------+--------+\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-character-set.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-character-set.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (214,16,'JSON_OBJECTAGG','Syntax:\nJSON_OBJECTAGG(key, value)\n\nTakes two column names or expressions as arguments, the first of these\nbeing used as a key and the second as a value, and returns a JSON\nobject containing key-value pairs. Returns NULL if the result contains\nno rows, or in the event of an error. An error occurs if any key name\nis NULL or the number of arguments is not equal to 2.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','mysql> SELECT o_id, attribute, value FROM t3;\n+------+-----------+-------+\n| o_id | attribute | value |\n+------+-----------+-------+\n| 2 | color | red |\n| 2 | fabric | silk |\n| 3 | color | green |\n| 3 | shape | square|\n+------+-----------+-------+\n4 rows in set (0.00 sec)\n\nmysql> SELECT o_id, JSON_OBJECTAGG(attribute, value) FROM t3 GROUP BY o_id;\n+------+----------------------------------------+\n| o_id | JSON_OBJECTAGG(attribute, name) |\n+------+----------------------------------------+\n| 2 | {"color": "red", "fabric": "silk"} |\n| 3 | {"color": "green", "shape": "square"} |\n+------+----------------------------------------+\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (215,7,'INTERSECTS','Intersects(g1, g2)\n\nMBRIntersects() and Intersects() are synonyms. For more information,\nsee the description of MBRIntersects().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (216,24,'LOOP','Syntax:\n[begin_label:] LOOP\n statement_list\nEND LOOP [end_label]\n\nLOOP implements a simple loop construct, enabling repeated execution of\nthe statement list, which consists of one or more statements, each\nterminated by a semicolon (;) statement delimiter. The statements\nwithin the loop are repeated until the loop is terminated. Usually,\nthis is accomplished with a LEAVE statement. Within a stored function,\nRETURN can also be used, which exits the function entirely.\n\nNeglecting to include a loop-termination statement results in an\ninfinite loop.\n\nA LOOP statement can be labeled. For the rules regarding label use, see\n[HELP labels].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/loop.html\n\n','CREATE PROCEDURE doiterate(p1 INT)\nBEGIN\n label1: LOOP\n SET p1 = p1 + 1;\n IF p1 < 10 THEN\n ITERATE label1;\n END IF;\n LEAVE label1;\n END LOOP label1;\n SET @x = p1;\nEND;\n','http://dev.mysql.com/doc/refman/5.7/en/loop.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (217,20,'GREATEST','Syntax:\nGREATEST(value1,value2,...)\n\nWith two or more arguments, returns the largest (maximum-valued)\nargument. The arguments are compared using the same rules as for\nLEAST().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT GREATEST(2,0);\n -> 2\nmysql> SELECT GREATEST(34.0,3.0,5.0,767.0);\n -> 767.0\nmysql> SELECT GREATEST(\'B\',\'A\',\'C\');\n -> \'C\'\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (218,40,'ALTER INSTANCE','Syntax:\nALTER INSTANCE ROTATE INNODB MASTER KEY\n\nALTER INSTANCE, introduced in MySQL 5.7.11, defines actions applicable\nto a MySQL server instance.\n\nThe ALTER INSTANCE ROTATE INNODB MASTER KEY statement is used to rotate\nthe master encryption key used for InnoDB tablespace encryption. A\nkeyring plugin must be loaded to use this statement. For information\nabout keyring plugins, see\nhttp://dev.mysql.com/doc/refman/5.7/en/keyring.html. Key rotation\nrequires the SUPER privilege.\n\nALTER INSTANCE ROTATE INNODB MASTER KEY supports concurrent DML.\nHowever, it cannot be run concurrently with CREATE TABLE ... ENCRYPTION\nor ALTER TABLE ... ENCRYPTION operations, and locks are taken to\nprevent conflicts that could arise from concurrent execution of these\nstatements. If one of the conflicting statements is running, it must\ncomplete before another can proceed.\n\nALTER INSTANCE actions are written to the binary log so that they can\nbe executed on replicated servers.\n\nFor additional ALTER INSTANCE ROTATE INNODB MASTER KEY usage\ninformation, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.htm\nl. For information about keyring plugins, see\nhttp://dev.mysql.com/doc/refman/5.7/en/keyring.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-instance.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-instance.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (218,40,'ALTER INSTANCE','Syntax:\nALTER INSTANCE ROTATE INNODB MASTER KEY\n\nALTER INSTANCE, introduced in MySQL 5.7.11, defines actions applicable\nto a MySQL server instance.\n\nThe ALTER INSTANCE ROTATE INNODB MASTER KEY statement is used to rotate\nthe master encryption key used for InnoDB tablespace encryption. A\nkeyring plugin must be installed and configured to use this statement.\nFor information about keyring plugins, see\nhttp://dev.mysql.com/doc/refman/5.7/en/keyring.html. Key rotation\nrequires the SUPER privilege.\n\nALTER INSTANCE ROTATE INNODB MASTER KEY supports concurrent DML.\nHowever, it cannot be run concurrently with CREATE TABLE ... ENCRYPTION\nor ALTER TABLE ... ENCRYPTION operations, and locks are taken to\nprevent conflicts that could arise from concurrent execution of these\nstatements. If one of the conflicting statements is running, it must\ncomplete before another can proceed.\n\nALTER INSTANCE actions are written to the binary log so that they can\nbe executed on replicated servers.\n\nFor additional ALTER INSTANCE ROTATE INNODB MASTER KEY usage\ninformation, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.htm\nl. For information about keyring plugins, see\nhttp://dev.mysql.com/doc/refman/5.7/en/keyring.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-instance.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-instance.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (219,31,'ST_CONTAINS','ST_Contains(g1, g2)\n\nReturns 1 or 0 to indicate whether g1 completely contains g2. This\ntests the opposite relationship as ST_Within().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (220,16,'BIT_AND','Syntax:\nBIT_AND(expr)\n\nReturns the bitwise AND of all bits in expr. The calculation is\nperformed with 64-bit (BIGINT) precision.\n\nIf there are no matching rows, BIT_AND() returns a neutral value (all\nbits set to 1).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (221,32,'SECOND','Syntax:\nSECOND(time)\n\nReturns the second for time, in the range 0 to 59.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT SECOND(\'10:05:03\');\n -> 3\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (222,7,'MBRCONTAINS','MBRContains(g1, g2)\n\nReturns 1 or 0 to indicate whether the minimum bounding rectangle of g1\ncontains the minimum bounding rectangle of g2. This tests the opposite\nrelationship as MBRWithin().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','mysql> SET @g1 = ST_GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nmysql> SET @g2 = ST_GeomFromText(\'Point(1 1)\');\nmysql> SELECT MBRContains(@g1,@g2), MBRWithin(@g2,@g1);\n+----------------------+--------------------+\n| MBRContains(@g1,@g2) | MBRWithin(@g2,@g1) |\n+----------------------+--------------------+\n| 1 | 1 |\n+----------------------+--------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (223,14,'RELEASE_ALL_LOCKS','Syntax:\nRELEASE_ALL_LOCKS()\n\nReleases all named locks held by the current session and returns the\nnumber of locks released (0 if there were none)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (224,3,'COT','Syntax:\nCOT(X)\n\nReturns the cotangent of X.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT COT(12);\n -> -1.5726734063977\nmysql> SELECT COT(0);\n -> out-of-range error\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (225,27,'SHOW CREATE EVENT','Syntax:\nSHOW CREATE EVENT event_name\n\nThis statement displays the CREATE EVENT statement needed to re-create\na given event. It requires the EVENT privilege for the database from\nwhich the event is to be shown. For example (using the same event\ne_daily defined and then altered in [HELP SHOW EVENTS]):\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-event.html\n\n','mysql> SHOW CREATE EVENT test.e_daily\\G\n*************************** 1. row ***************************\n Event: e_daily\n sql_mode:\n time_zone: SYSTEM\n Create Event: CREATE EVENT `e_daily`\n ON SCHEDULE EVERY 1 DAY\n STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR\n ON COMPLETION NOT PRESERVE\n ENABLE\n COMMENT \'Saves total number of sessions then\n clears the table each day\'\n DO BEGIN\n INSERT INTO site_activity.totals (time, total)\n SELECT CURRENT_TIMESTAMP, COUNT(*)\n FROM site_activity.sessions;\n DELETE FROM site_activity.sessions;\n END\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.7/en/show-create-event.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (225,27,'SHOW CREATE EVENT','Syntax:\nSHOW CREATE EVENT event_name\n\nThis statement displays the CREATE EVENT statement needed to re-create\na given event. It requires the EVENT privilege for the database from\nwhich the event is to be shown. For example (using the same event\ne_daily defined and then altered in [HELP SHOW EVENTS]):\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-event.html\n\n','mysql> SHOW CREATE EVENT myschema.e_daily\\G\n*************************** 1. row ***************************\n Event: e_daily\n sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,\n NO_ZERO_IN_DATE,NO_ZERO_DATE,\n ERROR_FOR_DIVISION_BY_ZERO,\n NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION\n time_zone: SYSTEM\n Create Event: CREATE DEFINER=`jon`@`ghidora` EVENT `e_daily`\n ON SCHEDULE EVERY 1 DAY\n STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR\n ON COMPLETION NOT PRESERVE\n ENABLE\n COMMENT \'Saves total number of sessions then\n clears the table each day\'\n DO BEGIN\n INSERT INTO site_activity.totals (time, total)\n SELECT CURRENT_TIMESTAMP, COUNT(*)\n FROM site_activity.sessions;\n DELETE FROM site_activity.sessions;\n END\ncharacter_set_client: utf8\ncollation_connection: utf8_general_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.7/en/show-create-event.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (226,15,'OR','Syntax:\nOR, ||\n\nLogical OR. When both operands are non-NULL, the result is 1 if any\noperand is nonzero, and 0 otherwise. With a NULL operand, the result is\n1 if the other operand is nonzero, and NULL otherwise. If both operands\nare NULL, the result is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/logical-operators.html\n\n','mysql> SELECT 1 OR 1;\n -> 1\nmysql> SELECT 1 OR 0;\n -> 1\nmysql> SELECT 0 OR 0;\n -> 0\nmysql> SELECT 0 OR NULL;\n -> NULL\nmysql> SELECT 1 OR NULL;\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/logical-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (227,38,'LOAD_FILE','Syntax:\nLOAD_FILE(file_name)\n\nReads the file and returns the file contents as a string. To use this\nfunction, the file must be located on the server host, you must specify\nthe full path name to the file, and you must have the FILE privilege.\nThe file must be readable by all and its size less than\nmax_allowed_packet bytes. If the secure_file_priv system variable is\nset to a nonempty directory name, the file to be loaded must be located\nin that directory.\n\nIf the file does not exist or cannot be read because one of the\npreceding conditions is not satisfied, the function returns NULL.\n\nThe character_set_filesystem system variable controls interpretation of\nfile names that are given as literal strings.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> UPDATE t\n SET blob_col=LOAD_FILE(\'/tmp/picture\')\n WHERE id=1;\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (228,4,'POINTFROMTEXT','PointFromText(wkt[, srid])\n\nST_PointFromText() and PointFromText() are synonyms. For more\ninformation, see the description of ST_PointFromText().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
@@ -340,7 +340,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (259,32,'PERIOD_ADD','Syntax:\nPERIOD_ADD(P,N)\n\nAdds N months to period P (in the format YYMM or YYYYMM). Returns a\nvalue in the format YYYYMM. Note that the period argument P is not a\ndate value.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT PERIOD_ADD(200801,2);\n -> 200803\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (260,38,'RIGHT','Syntax:\nRIGHT(str,len)\n\nReturns the rightmost len characters from the string str, or NULL if\nany argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT RIGHT(\'foobarbar\', 4);\n -> \'rbar\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (261,40,'DROP TABLESPACE','Syntax:\nDROP TABLESPACE tablespace_name\n [ENGINE [=] engine_name]\n\nThis statement drops a tablespace that was previously created using\nCREATE TABLESPACE. It is supported with all MySQL NDB Cluster 7.5\nreleases, and with InnoDB in the standard MySQL Server as well.\n\nENGINE sets the storage engine that uses the tablespace, where\nengine_name is the name of the storage engine. Currently, the values\nInnoDB and NDB are supported. If not set, the value of\ndefault_storage_engine is used. If it is not the same as the storage\nengine used to create the tablespace, the DROP TABLESPACE statement\nfails.\n\nFor an InnoDB tablespace, all tables must be dropped from the\ntablespace prior to a DROP TABLESPACE operation. If the tablespace is\nnot empty, DROP TABLESPACE returns an error.\n\nAs with the InnoDB system tablespace, truncating or dropping InnoDB\ntables stored in a general tablespace creates free space in the\ntablespace .ibd data file, which can only be used for new InnoDB data.\nSpace is not released back to the operating system by such operations\nas it is for file-per-table tablespaces.\n\nAn NDB tablespace to be dropped must not contain any data files; in\nother words, before you can drop an NDB tablespace, you must first drop\neach of its data files using ALTER TABLESPACE ... DROP DATAFILE.\n\nNotes\n\no Tablespaces are not deleted automatically. A tablespace must be\n dropped explicitly using DROP TABLESPACE. DROP DATABASE has no effect\n in this regard, even if the operation drops all tables belonging to\n the tablespace.\n\no A DROP DATABASE operation can drop tables that belong to a general\n tablespace but it cannot drop the tablespace, even if the operation\n drops all tables that belong to the tablespace. The tablespace must\n be dropped explicitly using DROP TABLESPACE tablespace_name.\n\no Similar to the system tablespace, truncating or dropping tables\n stored in a general tablespace creates free space internally in the\n general tablespace .ibd data file which can only be used for new\n InnoDB data. Space is not released back to the operating system as it\n is for file-per-table tablespaces.\n\nInnoDB Example\n\nThis example demonstrates how to drop an InnoDB general tablespace. The\ngeneral tablespace ts1 is created with a single table. Before dropping\nthe tablespace, the table must be dropped.\n\nmysql> CREATE TABLESPACE `ts1`\n -> ADD DATAFILE \'ts1.ibd\'\n -> ENGINE=INNODB;\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> CREATE TABLE t1 (c1 INT PRIMARY KEY)\n -> TABLESPACE ts10\n -> ENGINE=INNODB;\nQuery OK, 0 rows affected (0.02 sec)\n\nmysql> DROP TABLE t1;\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> DROP TABLESPACE ts1;\nQuery OK, 0 rows affected (0.01 sec)\n\nNDB Example\n\nThis example shows how to drop an NDB tablespace myts having a data\nfile named mydata-1.dat after first creating the tablespace, and\nassumes the existence of a log file group named mylg (see [HELP CREATE\nLOGFILE GROUP]).\n\nmysql> CREATE TABLESPACE myts\n -> ADD DATAFILE \'mydata-1.dat\'\n -> USE LOGFILE GROUP mylg\n -> ENGINE=NDB;\n\nYou must remove all data files from the tablespace using ALTER\nTABLESPACE, as shown here, before it can be dropped:\n\nmysql> ALTER TABLESPACE myts\n -> DROP DATAFILE \'mydata-1.dat\'\n -> ENGINE=NDB;\n\nmysql> DROP TABLESPACE myts;\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-tablespace.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-tablespace.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (262,21,'CHECK TABLE','Syntax:\nCHECK TABLE tbl_name [, tbl_name] ... [option] ...\n\noption = {\n FOR UPGRADE\n | QUICK\n | FAST\n | MEDIUM\n | EXTENDED\n | CHANGED\n}\n\nCHECK TABLE checks a table or tables for errors. For MyISAM tables, the\nkey statistics are updated as well. CHECK TABLE can also check views\nfor problems, such as tables that are referenced in the view definition\nthat no longer exist.\n\nTo check a table, you must have some privilege for it.\n\nCHECK TABLE works for InnoDB, MyISAM, ARCHIVE, and CSV tables.\n\nBefore running CHECK TABLE on InnoDB tables, see\nhttp://dev.mysql.com/doc/refman/5.7/en/check-table.html#check-table-inn\nodb.\n\nCHECK TABLE is supported for partitioned tables, and you can use ALTER\nTABLE ... CHECK PARTITION to check one or more partitions; for more\ninformation, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-maintenance.html.\n\nCHECK TABLE ignores virtual generated columns that are not indexed.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/check-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/check-table.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (262,21,'CHECK TABLE','Syntax:\nCHECK TABLE tbl_name [, tbl_name] ... [option] ...\n\noption: {\n FOR UPGRADE\n | QUICK\n | FAST\n | MEDIUM\n | EXTENDED\n | CHANGED\n}\n\nCHECK TABLE checks a table or tables for errors. For MyISAM tables, the\nkey statistics are updated as well. CHECK TABLE can also check views\nfor problems, such as tables that are referenced in the view definition\nthat no longer exist.\n\nTo check a table, you must have some privilege for it.\n\nCHECK TABLE works for InnoDB, MyISAM, ARCHIVE, and CSV tables.\n\nBefore running CHECK TABLE on InnoDB tables, see\nhttp://dev.mysql.com/doc/refman/5.7/en/check-table.html#check-table-inn\nodb.\n\nCHECK TABLE is supported for partitioned tables, and you can use ALTER\nTABLE ... CHECK PARTITION to check one or more partitions; for more\ninformation, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-maintenance.html.\n\nCHECK TABLE ignores virtual generated columns that are not indexed.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/check-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/check-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (263,38,'BIN','Syntax:\nBIN(N)\n\nReturns a string representation of the binary value of N, where N is a\nlonglong (BIGINT) number. This is equivalent to CONV(N,10,2). Returns\nNULL if N is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT BIN(12);\n -> \'1100\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (264,7,'JSON_STORAGE_SIZE','JSON_STORAGE_SIZE(json_val)\n\nThis function returns the number of bytes used to store the binary\nrepresentation of a JSON document. When the argument is a JSON column,\nthis is the space used to store the JSON document. json_val must be a\nvalid JSON document or a string which can be parsed as one. In the case\nwhere it is string, the function returns the amount of storage space in\nthe JSON binary representation that is created by parsing the string as\nJSON and converting it to binary. It returns NULL if the argument is\nNULL.\n\nAn error results when json_val is not NULL, and is not---or cannot be\nsuccessfully parsed as---a JSON document.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-utility-functions.html\n\n','mysql> CREATE TABLE jtable (jcol JSON);\nQuery OK, 0 rows affected (0.42 sec)\n\nmysql> INSERT INTO jtable VALUES\n -> (\'{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}\');\nQuery OK, 1 row affected (0.04 sec)\n\nmysql> SELECT\n -> jcol,\n -> JSON_STORAGE_SIZE(jcol) AS Size\n -> FROM jtable;\n+-----------------------------------------------+------+\n| jcol | Size |\n+-----------------------------------------------+------+\n| {"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"} | 47 |\n+-----------------------------------------------+------+\n1 row in set (0.00 sec)\n\nmysql> UPDATE jtable\nmysql> SET jcol = \'{"a": 4.55, "b": "wxyz", "c": "[true, false]"}\';\nQuery OK, 1 row affected (0.04 sec)\nRows matched: 1 Changed: 1 Warnings: 0\n\nmysql> SELECT\n -> jcol,\n -> JSON_STORAGE_SIZE(jcol) AS Size\n -> FROM jtable;\n+------------------------------------------------+------+\n| jcol | Size |\n+------------------------------------------------+------+\n| {"a": 4.55, "b": "wxyz", "c": "[true, false]"} | 56 |\n+------------------------------------------------+------+\n1 row in set (0.00 sec)\n\nmysql> SET @j = \'[100, "sakila", [1, 3, 5], 425.05]\';\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;\n+------------------------------------+------+\n| @j | Size |\n+------------------------------------+------+\n| [100, "sakila", [1, 3, 5], 425.05] | 45 |\n+------------------------------------+------+\n1 row in set (0.00 sec)\n\nmysql> SET @j = JSON_SET(@j, \'$[1]\', "json");\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;\n+----------------------------------+------+\n| @j | Size |\n+----------------------------------+------+\n| [100, "json", [1, 3, 5], 425.05] | 43 |\n+----------------------------------+------+\n1 row in set (0.00 sec)\n\nmysql> SET @j = JSON_SET(@j, \'$[2][0]\', JSON_ARRAY(10, 20, 30));\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;\n+---------------------------------------------+------+\n| @j | Size |\n+---------------------------------------------+------+\n| [100, "json", [[10, 20, 30], 3, 5], 425.05] | 56 |\n+---------------------------------------------+------+\n1 row in set (0.00 sec)\n\nmysql> SELECT\n -> JSON_STORAGE_SIZE(\'[100, "sakila", [1, 3, 5], 425.05]\') AS A,\n -> JSON_STORAGE_SIZE(\'{"a": 1000, "b": "a", "c": "[1, 3, 5, 7]"}\') AS B,\n -> JSON_STORAGE_SIZE(\'{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}\') AS C,\n -> JSON_STORAGE_SIZE(\'[100, "json", [[10, 20, 30], 3, 5], 425.05]\') AS D;\n+----+----+----+----+\n| A | B | C | D |\n+----+----+----+----+\n| 45 | 44 | 47 | 56 |\n+----+----+----+----+\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/json-utility-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (265,25,'MULTILINESTRING','MultiLineString(ls [, ls] ...)\n\nConstructs a MultiLineString value using LineString or WKB LineString\narguments.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html');
@@ -356,10 +356,10 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (275,19,'BIT_COUNT','Syntax:\nBIT_COUNT(N)\n\nReturns the number of bits that are set in the argument N as an\nunsigned 64-bit integer, or NULL if the argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/bit-functions.html\n\n','mysql> SELECT BIT_COUNT(29), BIT_COUNT(b\'101010\');\n -> 4, 3\n','http://dev.mysql.com/doc/refman/5.7/en/bit-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (276,33,'ST_POINTFROMWKB','ST_PointFromWKB(wkb[, srid])\n\nConstructs a Point value using its WKB representation and SRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (277,7,'JSON_PRETTY','JSON_PRETTY(json_val)\n\nProvides pretty-printing of JSON values similar to that implemented in\nPHP and by other languages and database systems. The value supplied\nmust be a JSON value or a valid string representation of a JSON value.\nExtraneous whitespaces and newlines present in this value have no\neffect on the output. For a NULL value, the function returns NULL. If\nthe value is not a JSON document, or if it cannot cannot be parsed as\none, the function fails with an error.\n\nFormatting of the output from this function adheres to the following\nrules:\n\no Each array element or object member appears on a separate line,\n indented by one additional level as compared to its parent.\n\no Each level of indentation adds two leading spaces.\n\no A comma separating individual array elements or object members is\n printed before the newline that separates the two elements or\n members.\n\no The key and the value of an object member are separated by a colon\n followed by a space (\': \').\n\no An empty object or array is printed on a single line. No space is\n printed between the opening and closing brace.\n\no Special characters in string scalars and key names are escaped\n employing the same rules used by the JSON_QUOTE() function.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-utility-functions.html\n\n','mysql> SELECT JSON_PRETTY(\'123\'); # scalar\n+--------------------+\n| JSON_PRETTY(\'123\') |\n+--------------------+\n| 123 |\n+--------------------+\n\nmysql> SELECT JSON_PRETTY("[1,3,5]"); # array\n+------------------------+\n| JSON_PRETTY("[1,3,5]") |\n+------------------------+\n| [\n 1,\n 3,\n 5\n] |\n+------------------------+\n\nmysql> SELECT JSON_PRETTY(\'{"a":"10","b":"15","x":"25"}\'); # object\n+---------------------------------------------+\n| JSON_PRETTY(\'{"a":"10","b":"15","x":"25"}\') |\n+---------------------------------------------+\n| {\n "a": "10",\n "b": "15",\n "x": "25"\n} |\n+---------------------------------------------+\n\nmysql> SELECT JSON_PRETTY(\'["a",1,{"key1":\n > "value1"},"5", "77" ,\n > {"key2":["value3","valueX",\n > "valueY"]},"j", "2" ]\')\\G # nested arrays and objects\n*************************** 1. row ***************************\nJSON_PRETTY(\'["a",1,{"key1":\n "value1"},"5", "77" ,\n {"key2":["value3","valuex",\n "valuey"]},"j", "2" ]\'): [\n "a",\n 1,\n {\n "key1": "value1"\n },\n "5",\n "77",\n {\n "key2": [\n "value3",\n "valuex",\n "valuey"\n ]\n },\n "j",\n "2"\n]\n','http://dev.mysql.com/doc/refman/5.7/en/json-utility-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (278,7,'ST_MAKEENVELOPE','ST_MakeEnvelope(pt1, pt2)\n\nReturns the rectangle that forms the envelope around two points, as a\nPoint, LineString, or Polygon. If any argument is NULL, the return\nvalue is NULL.\n\nCalculations are done using the Cartesian coordinate system rather than\non a sphere, spheroid, or on earth.\n\nGiven two points pt1 and pt2, ST_MakeEnvelope() creates the result\ngeometry on an abstract plane like this:\n\no If pt1 and pt2 are equal, the result is the point pt1.\n\no Otherwise, if (pt1, pt2) is a vertical or horizontal line segment,\n the result is the line segment (pt1, pt2).\n\no Otherwise, the result is a polygon using pt1 and pt2 as diagonal\n points.\n\nThe result geometry has an SRID of 0.\n\nST_MakeEnvelope() requires Point geometry arguments with an SRID of 0.\nAn ER_WRONG_ARGUMENTS error occurs otherwise.\n\nIf any argument is not a syntactically well-formed geometry byte\nstring, or if any coordinate value of the two points is infinite (that\nis, NaN), an ER_GIS_INVALID_DATA error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html\n\n','mysql> SET @pt1 = ST_GeomFromText(\'POINT(0 0)\');\nmysql> SET @pt2 = ST_GeomFromText(\'POINT(1 1)\');\nmysql> SELECT ST_AsText(ST_MakeEnvelope(@pt1, @pt2));\n+----------------------------------------+\n| ST_AsText(ST_MakeEnvelope(@pt1, @pt2)) |\n+----------------------------------------+\n| POLYGON((0 0,1 0,1 1,0 1,0 0)) |\n+----------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (278,7,'ST_MAKEENVELOPE','ST_MakeEnvelope(pt1, pt2)\n\nReturns the rectangle that forms the envelope around two points, as a\nPoint, LineString, or Polygon. If any argument is NULL, the return\nvalue is NULL.\n\nCalculations are done using the Cartesian coordinate system rather than\non a sphere, spheroid, or on earth.\n\nGiven two points pt1 and pt2, ST_MakeEnvelope() creates the result\ngeometry on an abstract plane like this:\n\no If pt1 and pt2 are equal, the result is the point pt1.\n\no Otherwise, if (pt1, pt2) is a vertical or horizontal line segment,\n the result is the line segment (pt1, pt2).\n\no Otherwise, the result is a polygon using pt1 and pt2 as diagonal\n points.\n\nThe result geometry has an SRID of 0.\n\nST_MakeEnvelope() requires Point geometry arguments with an SRID of 0.\nAn ER_WRONG_ARGUMENTS error occurs otherwise.\n\nIf any argument is not a syntactically well-formed geometry byte\nstring, or if any coordinate value of the two points is infinite or\nNaN, an ER_GIS_INVALID_DATA error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html\n\n','mysql> SET @pt1 = ST_GeomFromText(\'POINT(0 0)\');\nmysql> SET @pt2 = ST_GeomFromText(\'POINT(1 1)\');\nmysql> SELECT ST_AsText(ST_MakeEnvelope(@pt1, @pt2));\n+----------------------------------------+\n| ST_AsText(ST_MakeEnvelope(@pt1, @pt2)) |\n+----------------------------------------+\n| POLYGON((0 0,1 0,1 1,0 1,0 0)) |\n+----------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (279,31,'ST_WITHIN','ST_Within(g1, g2)\n\nReturns 1 or 0 to indicate whether g1 is spatially within g2. This\ntests the opposite relationship as ST_Contains().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (280,3,'ACOS','Syntax:\nACOS(X)\n\nReturns the arc cosine of X, that is, the value whose cosine is X.\nReturns NULL if X is not in the range -1 to 1.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT ACOS(1);\n -> 0\nmysql> SELECT ACOS(1.0001);\n -> NULL\nmysql> SELECT ACOS(0);\n -> 1.5707963267949\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (281,8,'ISOLATION','Syntax:\nSET [GLOBAL | SESSION] TRANSACTION\n transaction_characteristic [, transaction_characteristic] ...\n\ntransaction_characteristic:\n ISOLATION LEVEL level\n | READ WRITE\n | READ ONLY\n\nlevel:\n REPEATABLE READ\n | READ COMMITTED\n | READ UNCOMMITTED\n | SERIALIZABLE\n\nThis statement specifies transaction characteristics. It takes a list\nof one or more characteristic values separated by commas. These\ncharacteristics set the transaction isolation level or access mode. The\nisolation level is used for operations on InnoDB tables. The access\nmode may be specified as to whether transactions operate in read/write\nor read-only mode.\n\nIn addition, SET TRANSACTION can include an optional GLOBAL or SESSION\nkeyword to indicate the scope of the statement.\n\nScope of Transaction Characteristics\n\nYou can set transaction characteristics globally, for the current\nsession, or for the next transaction:\n\no With the GLOBAL keyword, the statement applies globally for all\n subsequent sessions. Existing sessions are unaffected.\n\no With the SESSION keyword, the statement applies to all subsequent\n transactions performed within the current session.\n\no Without any SESSION or GLOBAL keyword, the statement applies to the\n next (not started) transaction performed within the current session.\n Subsequent transactions revert to using the SESSION isolation level.\n\nA global change to transaction characteristics requires the SUPER\nprivilege. Any session is free to change its session characteristics\n(even in the middle of a transaction), or the characteristics for its\nnext transaction.\n\nSET TRANSACTION without GLOBAL or SESSION is not permitted while there\nis an active transaction:\n\nmysql> START TRANSACTION;\nQuery OK, 0 rows affected (0.02 sec)\n\nmysql> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\nERROR 1568 (25001): Transaction characteristics can\'t be changed\nwhile a transaction is in progress\n\nTo set the global default isolation level at server startup, use the\n--transaction-isolation=level option to mysqld on the command line or\nin an option file. Values of level for this option use dashes rather\nthan spaces, so the permissible values are READ-UNCOMMITTED,\nREAD-COMMITTED, REPEATABLE-READ, or SERIALIZABLE. For example, to set\nthe default isolation level to REPEATABLE READ, use these lines in the\n[mysqld] section of an option file:\n\n[mysqld]\ntransaction-isolation = REPEATABLE-READ\n\nIt is possible to check or set the global and session transaction\nisolation levels at runtime by using the transaction_isolation system\nvariable:\n\nSELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;\nSET GLOBAL transaction_isolation=\'REPEATABLE-READ\';\nSET SESSION transaction_isolation=\'SERIALIZABLE\';\n\nPrior to MySQL 5.7.20, use tx_isolation rather than\ntransaction_isolation.\n\nSimilarly, to set the transaction access mode at server startup or at\nruntime, use the --transaction-read-only option or\ntransaction_read_only system variable. By default, these are OFF (the\nmode is read/write) but can be set to ON for a default mode of read\nonly.\n\nPrior to MySQL 5.7.20, use tx_read_only rather than\ntransaction_read_only.\n\nSetting the global or session value of transaction_isolation or\ntransaction_read_only is equivalent to setting the isolation level or\naccess mode with SET GLOBAL TRANSACTION or SET SESSION TRANSACTION.\n\nTransaction Isolation Levels\n\nFor information about transaction isolation levels, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-lev\nels.html.\n\nTransaction Access Mode\n\nThe transaction access mode may be specified with SET TRANSACTION. By\ndefault, a transaction takes place in read/write mode, with both reads\nand writes permitted to tables used in the transaction. This mode may\nbe specified explicitly using an access mode of READ WRITE.\n\nIf the transaction access mode is set to READ ONLY, changes to tables\nare prohibited. This may enable storage engines to make performance\nimprovements that are possible when writes are not permitted.\n\nIt is not permitted to specify both READ WRITE and READ ONLY in the\nsame statement.\n\nIn read-only mode, it remains possible to change tables created with\nthe TEMPORARY keyword using DML statements. Changes made with DDL\nstatements are not permitted, just as with permanent tables.\n\nThe READ WRITE and READ ONLY access modes also may be specified for an\nindividual transaction using the START TRANSACTION statement.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-transaction.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-transaction.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (281,8,'ISOLATION','Syntax:\nSET [GLOBAL | SESSION] TRANSACTION\n transaction_characteristic [, transaction_characteristic] ...\n\ntransaction_characteristic: {\n ISOLATION LEVEL level\n | READ WRITE\n | READ ONLY\n}\n\nlevel: {\n REPEATABLE READ\n | READ COMMITTED\n | READ UNCOMMITTED\n | SERIALIZABLE\n}\n\nThis statement specifies transaction characteristics. It takes a list\nof one or more characteristic values separated by commas. These\ncharacteristics set the transaction isolation level or access mode. The\nisolation level is used for operations on InnoDB tables. The access\nmode may be specified as to whether transactions operate in read/write\nor read-only mode.\n\nIn addition, SET TRANSACTION can include an optional GLOBAL or SESSION\nkeyword to indicate the scope of the statement.\n\nScope of Transaction Characteristics\n\nYou can set transaction characteristics globally, for the current\nsession, or for the next transaction:\n\no With the GLOBAL keyword, the statement applies globally for all\n subsequent sessions. Existing sessions are unaffected.\n\no With the SESSION keyword, the statement applies to all subsequent\n transactions performed within the current session.\n\no Without any SESSION or GLOBAL keyword, the statement applies to the\n next (not started) transaction performed within the current session.\n Subsequent transactions revert to using the SESSION isolation level.\n\nA global change to transaction characteristics requires the SUPER\nprivilege. Any session is free to change its session characteristics\n(even in the middle of a transaction), or the characteristics for its\nnext transaction.\n\nSET TRANSACTION without GLOBAL or SESSION is not permitted while there\nis an active transaction:\n\nmysql> START TRANSACTION;\nQuery OK, 0 rows affected (0.02 sec)\n\nmysql> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\nERROR 1568 (25001): Transaction characteristics can\'t be changed\nwhile a transaction is in progress\n\nTo set the global default isolation level at server startup, use the\n--transaction-isolation=level option to mysqld on the command line or\nin an option file. Values of level for this option use dashes rather\nthan spaces, so the permissible values are READ-UNCOMMITTED,\nREAD-COMMITTED, REPEATABLE-READ, or SERIALIZABLE. For example, to set\nthe default isolation level to REPEATABLE READ, use these lines in the\n[mysqld] section of an option file:\n\n[mysqld]\ntransaction-isolation = REPEATABLE-READ\n\nIt is possible to check or set the global and session transaction\nisolation levels at runtime by using the transaction_isolation system\nvariable:\n\nSELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;\nSET GLOBAL transaction_isolation=\'REPEATABLE-READ\';\nSET SESSION transaction_isolation=\'SERIALIZABLE\';\n\nPrior to MySQL 5.7.20, use tx_isolation rather than\ntransaction_isolation.\n\nSimilarly, to set the transaction access mode at server startup or at\nruntime, use the --transaction-read-only option or\ntransaction_read_only system variable. By default, these are OFF (the\nmode is read/write) but can be set to ON for a default mode of read\nonly.\n\nPrior to MySQL 5.7.20, use tx_read_only rather than\ntransaction_read_only.\n\nSetting the global or session value of transaction_isolation or\ntransaction_read_only is equivalent to setting the isolation level or\naccess mode with SET GLOBAL TRANSACTION or SET SESSION TRANSACTION.\n\nTransaction Isolation Levels\n\nFor information about transaction isolation levels, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-lev\nels.html.\n\nTransaction Access Mode\n\nThe transaction access mode may be specified with SET TRANSACTION. By\ndefault, a transaction takes place in read/write mode, with both reads\nand writes permitted to tables used in the transaction. This mode may\nbe specified explicitly using an access mode of READ WRITE.\n\nIf the transaction access mode is set to READ ONLY, changes to tables\nare prohibited. This may enable storage engines to make performance\nimprovements that are possible when writes are not permitted.\n\nIt is not permitted to specify both READ WRITE and READ ONLY in the\nsame statement.\n\nIn read-only mode, it remains possible to change tables created with\nthe TEMPORARY keyword using DML statements. Changes made with DDL\nstatements are not permitted, just as with permanent tables.\n\nThe READ WRITE and READ ONLY access modes also may be specified for an\nindividual transaction using the START TRANSACTION statement.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-transaction.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-transaction.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (282,3,'SIN','Syntax:\nSIN(X)\n\nReturns the sine of X, where X is given in radians.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT SIN(PI());\n -> 1.2246063538224e-16\nmysql> SELECT ROUND(SIN(PI()));\n -> 0\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (283,26,'ST_BUFFER','ST_Buffer(g, d[, strategy1[, strategy2[, strategy3]]])\n\nReturns a geometry that represents all points whose distance from the\ngeometry value g is less than or equal to a distance of d, or NULL if\nany argument is NULL. The SRID of the geometry argument must be 0\nbecause ST_Buffer() supports only the Cartesian coordinate system. If\nany geometry argument is not a syntactically well-formed geometry, an\nER_GIS_INVALID_DATA error occurs.\n\nIf the geometry argument is empty, ST_Buffer() returns an empty\ngeometry.\n\nIf the distance is 0, ST_Buffer() returns the geometry argument\nunchanged:\n\nmysql> SET @pt = ST_GeomFromText(\'POINT(0 0)\');\nmysql> SELECT ST_AsText(ST_Buffer(@pt, 0));\n+------------------------------+\n| ST_AsText(ST_Buffer(@pt, 0)) |\n+------------------------------+\n| POINT(0 0) |\n+------------------------------+\n\nST_Buffer() supports negative distances for Polygon and MultiPolygon\nvalues, and for geometry collections containing Polygon or MultiPolygon\nvalues. The result may be an empty geometry. An ER_WRONG_ARGUMENTS\nerror occurs for ST_Buffer() with a negative distance for Point,\nMultiPoint, LineString, and MultiLineString values, and for geometry\ncollections not containing any Polygon or MultiPolygon values.\n\nAs of MySQL 5.7.7, ST_Buffer() permits up to three optional strategy\narguments following the distance argument. Strategies influence buffer\ncomputation. These arguments are byte string values produced by the\nST_Buffer_Strategy() function, to be used for point, join, and end\nstrategies:\n\no Point strategies apply to Point and MultiPoint geometries. If no\n point strategy is specified, the default is\n ST_Buffer_Strategy(\'point_circle\', 32).\n\no Join strategies apply to LineString, MultiLineString, Polygon, and\n MultiPolygon geometries. If no join strategy is specified, the\n default is ST_Buffer_Strategy(\'join_round\', 32).\n\no End strategies apply to LineString and MultiLineString geometries. If\n no end strategy is specified, the default is\n ST_Buffer_Strategy(\'end_round\', 32).\n\nUp to one strategy of each type may be specified, and they may be given\nin any order. If multiple strategies of a given type are specified, an\nER_WRONG_ARGUMENTS error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html\n\n','mysql> SET @pt = ST_GeomFromText(\'POINT(0 0)\');\nmysql> SET @pt_strategy = ST_Buffer_Strategy(\'point_square\');\nmysql> SELECT ST_AsText(ST_Buffer(@pt, 2, @pt_strategy));\n+--------------------------------------------+\n| ST_AsText(ST_Buffer(@pt, 2, @pt_strategy)) |\n+--------------------------------------------+\n| POLYGON((-2 -2,2 -2,2 2,-2 2,-2 -2)) |\n+--------------------------------------------+\n\nmysql> SET @ls = ST_GeomFromText(\'LINESTRING(0 0,0 5,5 5)\');\nmysql> SET @end_strategy = ST_Buffer_Strategy(\'end_flat\');\nmysql> SET @join_strategy = ST_Buffer_Strategy(\'join_round\', 10);\nmysql> SELECT ST_AsText(ST_Buffer(@ls, 5, @end_strategy, @join_strategy))\n+---------------------------------------------------------------+\n| ST_AsText(ST_Buffer(@ls, 5, @end_strategy, @join_strategy)) |\n+---------------------------------------------------------------+\n| POLYGON((5 5,5 10,0 10,-3.5355339059327373 8.535533905932738, |\n| -5 5,-5 0,0 0,5 0,5 5)) |\n+---------------------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (284,26,'BUFFER','Buffer(g, d[, strategy1[, strategy2[, strategy3]]])\n\nST_Buffer() and Buffer() are synonyms. For more information, see the\ndescription of ST_Buffer().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html');
@@ -367,32 +367,32 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (286,7,'WAIT_FOR_EXECUTED_GTID_SET','Syntax:\nWAIT_FOR_EXECUTED_GTID_SET(gtid_set[, timeout])\n\nWait until the server has applied all of the transactions whose global\ntransaction identifiers are contained in gtid_set; that is, until the\ncondition GTID_SUBSET(gtid_subset, @@global.gtid_executed) holds. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html\nfor a definition of GTID sets.\n\nIf a timeout is specified, and timeout seconds elapse before all of the\ntransactions in the GTID set have been applied, the function stops\nwaiting. timeout is optional, and the default timeout is 0 seconds, in\nwhich case the function always waits until all of the transactions in\nthe GTID set have been applied.\n\nWAIT_FOR_EXECUTED_GTID_SET() monitors all the GTIDs that are applied on\nthe server, including transactions that arrive from all replication\nchannels and user clients. It does not take into account whether\nreplication channels have been started or stopped.\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html\n\n','mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5\');\n -> 0\n','http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (287,20,'IS','Syntax:\nIS boolean_value\n\nTests a value against a boolean value, where boolean_value can be TRUE,\nFALSE, or UNKNOWN.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;\n -> 1, 1, 1\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (288,32,'GET_FORMAT','Syntax:\nGET_FORMAT({DATE|TIME|DATETIME}, {\'EUR\'|\'USA\'|\'JIS\'|\'ISO\'|\'INTERNAL\'})\n\nReturns a format string. This function is useful in combination with\nthe DATE_FORMAT() and the STR_TO_DATE() functions.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT DATE_FORMAT(\'2003-10-03\',GET_FORMAT(DATE,\'EUR\'));\n -> \'03.10.2003\'\nmysql> SELECT STR_TO_DATE(\'10.31.2003\',GET_FORMAT(DATE,\'USA\'));\n -> \'2003-10-31\'\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (289,2,'ST_CENTROID','ST_Centroid(mpoly)\n\nReturns the mathematical centroid for the MultiPolygon value mpoly as a\nPoint. The result is not guaranteed to be on the MultiPolygon. If the\nargument is NULL or an empty geometry, the return value is NULL.\n\nThis function processes geometry collections by computing the centroid\npoint for components of highest dimension in the collection. Such\ncomponents are extracted and made into a single MultiPolygon,\nMultiLineString, or MultiPoint for centroid computation. If the\nargument is an empty geometry collection, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n -> ST_GeomFromText(\'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))\');\nmysql> SELECT ST_GeometryType(@poly),ST_AsText(ST_Centroid(@poly));\n+------------------------+--------------------------------------------+\n| ST_GeometryType(@poly) | ST_AsText(ST_Centroid(@poly)) |\n+------------------------+--------------------------------------------+\n| POLYGON | POINT(4.958333333333333 4.958333333333333) |\n+------------------------+--------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (289,2,'ST_CENTROID','ST_Centroid({poly|mpoly})\n\nReturns the mathematical centroid for the Polygon or MultiPolygon\nargument as a Point. The result is not guaranteed to be on the\nMultiPolygon. If the argument is NULL or an empty geometry, the return\nvalue is NULL.\n\nThis function processes geometry collections by computing the centroid\npoint for components of highest dimension in the collection. Such\ncomponents are extracted and made into a single MultiPolygon,\nMultiLineString, or MultiPoint for centroid computation. If the\nargument is an empty geometry collection, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n ST_GeomFromText(\'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))\');\nmysql> SELECT ST_GeometryType(@poly),ST_AsText(ST_Centroid(@poly));\n+------------------------+--------------------------------------------+\n| ST_GeometryType(@poly) | ST_AsText(ST_Centroid(@poly)) |\n+------------------------+--------------------------------------------+\n| POLYGON | POINT(4.958333333333333 4.958333333333333) |\n+------------------------+--------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (290,23,'TINYBLOB','TINYBLOB\n\nA BLOB column with a maximum length of 255 (28 − 1) bytes. Each\nTINYBLOB value is stored using a 1-byte length prefix that indicates\nthe number of bytes in the value.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (291,17,'USER','Syntax:\nUSER()\n\nReturns the current MySQL user name and host name as a string in the\nutf8 character set.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT USER();\n -> \'davida@localhost\'\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (292,21,'REPAIR TABLE','Syntax:\nREPAIR [NO_WRITE_TO_BINLOG | LOCAL]\n TABLE tbl_name [, tbl_name] ...\n [QUICK] [EXTENDED] [USE_FRM]\n\nREPAIR TABLE repairs a possibly corrupted table, for certain storage\nengines only.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nAlthough normally you should never have to run REPAIR TABLE, if\ndisaster strikes, this statement is very likely to get back all your\ndata from a MyISAM table. If your tables become corrupted often, try to\nfind the reason for it, to eliminate the need to use REPAIR TABLE. See\nhttp://dev.mysql.com/doc/refman/5.7/en/crashing.html, and\nhttp://dev.mysql.com/doc/refman/5.7/en/myisam-table-problems.html.\n\nREPAIR TABLE checks the table to see whether an upgrade is required. If\nso, it performs the upgrade, following the same rules as CHECK TABLE\n... FOR UPGRADE. See [HELP CHECK TABLE], for more information.\n\n*Important*:\n\no Make a backup of a table before performing a table repair operation;\n under some circumstances the operation might cause data loss.\n Possible causes include but are not limited to file system errors.\n See http://dev.mysql.com/doc/refman/5.7/en/backup-and-recovery.html.\n\no If the server crashes during a REPAIR TABLE operation, it is\n essential after restarting it that you immediately execute another\n REPAIR TABLE statement for the table before performing any other\n operations on it. In the worst case, you might have a new clean index\n file without information about the data file, and then the next\n operation you perform could overwrite the data file. This is an\n unlikely but possible scenario that underscores the value of making a\n backup first.\n\no In the event that a table on the master becomes corrupted and you run\n REPAIR TABLE on it, any resulting changes to the original table are\n not propagated to slaves.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/repair-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/repair-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (293,18,'MERGE','The MERGE storage engine, also known as the MRG_MyISAM engine, is a\ncollection of identical MyISAM tables that can be used as one.\n"Identical" means that all tables have identical column data types and\nindex information. You cannot merge MyISAM tables in which the columns\nare listed in a different order, do not have exactly the same data\ntypes in corresponding columns, or have the indexes in different order.\nHowever, any or all of the MyISAM tables can be compressed with\nmyisampack. See http://dev.mysql.com/doc/refman/5.7/en/myisampack.html.\nDifferences between tables such as these do not matter:\n\no Names of corresponding columns and indexes can differ.\n\no Comments for tables, columns, and indexes can differ.\n\no Table options such as AVG_ROW_LENGTH, MAX_ROWS, or PACK_KEYS can\n differ.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/merge-storage-engine.html\n\n','mysql> CREATE TABLE t1 (\n -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> message CHAR(20)) ENGINE=MyISAM;\nmysql> CREATE TABLE t2 (\n -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> message CHAR(20)) ENGINE=MyISAM;\nmysql> INSERT INTO t1 (message) VALUES (\'Testing\'),(\'table\'),(\'t1\');\nmysql> INSERT INTO t2 (message) VALUES (\'Testing\'),(\'table\'),(\'t2\');\nmysql> CREATE TABLE total (\n -> a INT NOT NULL AUTO_INCREMENT,\n -> message CHAR(20), INDEX(a))\n -> ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;\n','http://dev.mysql.com/doc/refman/5.7/en/merge-storage-engine.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (294,27,'SHOW CREATE USER','Syntax:\nSHOW CREATE USER user\n\nThis statement shows the CREATE USER statement that creates the named\nuser. An error occurs if the user does not exist. The statement\nrequires the SELECT privilege for the mysql database, except to display\ninformation for the current user.\n\nTo name the account, use the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. The host\nname part of the account name, if omitted, defaults to \'%\'. It is also\npossible to specify CURRENT_USER or CURRENT_USER() to refer to the\naccount associated with the current session.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-create-user.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (294,27,'SHOW CREATE USER','Syntax:\nSHOW CREATE USER user\n\nThis statement shows the CREATE USER statement that creates the named\nuser. An error occurs if the user does not exist. The statement\nrequires the SELECT privilege for the mysql system database, except to\ndisplay information for the current user.\n\nTo name the account, use the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. The host\nname part of the account name, if omitted, defaults to \'%\'. It is also\npossible to specify CURRENT_USER or CURRENT_USER() to refer to the\naccount associated with the current session.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-create-user.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (295,31,'ST_DISTANCE','ST_Distance(g1, g2)\n\nReturns the distance between g1 and g2. If either argument is NULL or\nan empty geometry, the return value is NULL.\n\nThis function processes geometry collections by returning the shortest\ndistance among all combinations of the components of the two geometry\narguments.\n\nIf an intermediate or final result produces NaN or a negative number,\nan ER_GIS_INVALID_DATA error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html\n\n','mysql> SET @g1 = Point(1,1);\nmysql> SET @g2 = Point(2,2);\nmysql> SELECT ST_Distance(@g1, @g2);\n+-----------------------+\n| ST_Distance(@g1, @g2) |\n+-----------------------+\n| 1.4142135623730951 |\n+-----------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-object-shapes.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (296,40,'CREATE TABLE','Syntax:\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n (create_definition,...)\n [table_options]\n [partition_options]\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n [(create_definition,...)]\n [table_options]\n [partition_options]\n [IGNORE | REPLACE]\n [AS] query_expression\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n { LIKE old_tbl_name | (LIKE old_tbl_name) }\n\ncreate_definition:\n col_name column_definition\n | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)\n [index_option] ...\n | {INDEX|KEY} [index_name] [index_type] (index_col_name,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]\n [index_name] [index_type] (index_col_name,...)\n [index_option] ...\n | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (index_col_name,...) reference_definition\n | CHECK (expr)\n\ncolumn_definition:\n data_type [NOT NULL | NULL] [DEFAULT default_value]\n [AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]\n [COMMENT \'string\']\n [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]\n [STORAGE {DISK|MEMORY|DEFAULT}]\n [reference_definition]\n | data_type [GENERATED ALWAYS] AS (expression)\n [VIRTUAL | STORED] [NOT NULL | NULL]\n [UNIQUE [KEY]] [[PRIMARY] KEY]\n [COMMENT \'string\']\n\ndata_type:\n BIT[(length)]\n | TINYINT[(length)] [UNSIGNED] [ZEROFILL]\n | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]\n | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]\n | INT[(length)] [UNSIGNED] [ZEROFILL]\n | INTEGER[(length)] [UNSIGNED] [ZEROFILL]\n | BIGINT[(length)] [UNSIGNED] [ZEROFILL]\n | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | DECIMAL[(length[,decimals])] [UNSIGNED] [ZEROFILL]\n | NUMERIC[(length[,decimals])] [UNSIGNED] [ZEROFILL]\n | DATE\n | TIME[(fsp)]\n | TIMESTAMP[(fsp)]\n | DATETIME[(fsp)]\n | YEAR\n | CHAR[(length)]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | VARCHAR(length)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | BINARY[(length)]\n | VARBINARY(length)\n | TINYBLOB\n | BLOB[(length)]\n | MEDIUMBLOB\n | LONGBLOB\n | TINYTEXT\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | TEXT[(length)]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | MEDIUMTEXT\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | LONGTEXT\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | ENUM(value1,value2,value3,...)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | SET(value1,value2,value3,...)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | JSON\n | spatial_type\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\nreference_definition:\n REFERENCES tbl_name (index_col_name,...)\n [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT\n\ntable_options:\n table_option [[,] table_option] ...\n\ntable_option:\n AUTO_INCREMENT [=] value\n | AVG_ROW_LENGTH [=] value\n | [DEFAULT] CHARACTER SET [=] charset_name\n | CHECKSUM [=] {0 | 1}\n | [DEFAULT] COLLATE [=] collation_name\n | COMMENT [=] \'string\'\n | COMPRESSION [=] {\'ZLIB\'|\'LZ4\'|\'NONE\'}\n | CONNECTION [=] \'connect_string\'\n | {DATA|INDEX} DIRECTORY [=] \'absolute path to directory\'\n | DELAY_KEY_WRITE [=] {0 | 1}\n | ENCRYPTION [=] {\'Y\' | \'N\'}\n | ENGINE [=] engine_name\n | INSERT_METHOD [=] { NO | FIRST | LAST }\n | KEY_BLOCK_SIZE [=] value\n | MAX_ROWS [=] value\n | MIN_ROWS [=] value\n | PACK_KEYS [=] {0 | 1 | DEFAULT}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}\n | STATS_AUTO_RECALC [=] {DEFAULT|0|1}\n | STATS_PERSISTENT [=] {DEFAULT|0|1}\n | STATS_SAMPLE_PAGES [=] value\n | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]\n | UNION [=] (tbl_name[,tbl_name]...)\n\npartition_options:\n PARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY [ALGORITHM={1|2}] (column_list)\n | RANGE{(expr) | COLUMNS(column_list)}\n | LIST{(expr) | COLUMNS(column_list)} }\n [PARTITIONS num]\n [SUBPARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY [ALGORITHM={1|2}] (column_list) }\n [SUBPARTITIONS num]\n ]\n [(partition_definition [, partition_definition] ...)]\n\npartition_definition:\n PARTITION partition_name\n [VALUES\n {LESS THAN {(expr | value_list) | MAXVALUE}\n |\n IN (value_list)}]\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'string\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n [(subpartition_definition [, subpartition_definition] ...)]\n\nsubpartition_definition:\n SUBPARTITION logical_name\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'string\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n\nquery_expression:\n SELECT ... (Some valid select or union statement)\n\nCREATE TABLE creates a table with the given name. You must have the\nCREATE privilege for the table.\n\nBy default, tables are created in the default database, using the\nInnoDB storage engine. An error occurs if the table exists, if there is\nno default database, or if the database does not exist.\n\nFor information about the physical representation of a table, see\nhttp://dev.mysql.com/doc/refman/5.7/en/create-table-files.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-table.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (296,40,'CREATE TABLE','Syntax:\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n (create_definition,...)\n [table_options]\n [partition_options]\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n [(create_definition,...)]\n [table_options]\n [partition_options]\n [IGNORE | REPLACE]\n [AS] query_expression\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n { LIKE old_tbl_name | (LIKE old_tbl_name) }\n\ncreate_definition:\n col_name column_definition\n | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (key_part,...)\n [index_option] ...\n | {INDEX|KEY} [index_name] [index_type] (key_part,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]\n [index_name] [index_type] (key_part,...)\n [index_option] ...\n | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (key_part,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (col_name,...) reference_definition\n | CHECK (expr)\n\ncolumn_definition:\n data_type [NOT NULL | NULL] [DEFAULT default_value]\n [AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]\n [COMMENT \'string\']\n [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]\n [STORAGE {DISK|MEMORY|DEFAULT}]\n [reference_definition]\n | data_type [GENERATED ALWAYS] AS (expression)\n [VIRTUAL | STORED] [NOT NULL | NULL]\n [UNIQUE [KEY]] [[PRIMARY] KEY]\n [COMMENT \'string\']\n\ndata_type:\n (see http://dev.mysql.com/doc/refman/5.7/en/data-types.html)\n\nkey_part:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\nreference_definition:\n REFERENCES tbl_name (key_part,...)\n [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT\n\ntable_options:\n table_option [[,] table_option] ...\n\ntable_option:\n AUTO_INCREMENT [=] value\n | AVG_ROW_LENGTH [=] value\n | [DEFAULT] CHARACTER SET [=] charset_name\n | CHECKSUM [=] {0 | 1}\n | [DEFAULT] COLLATE [=] collation_name\n | COMMENT [=] \'string\'\n | COMPRESSION [=] {\'ZLIB\'|\'LZ4\'|\'NONE\'}\n | CONNECTION [=] \'connect_string\'\n | {DATA|INDEX} DIRECTORY [=] \'absolute path to directory\'\n | DELAY_KEY_WRITE [=] {0 | 1}\n | ENCRYPTION [=] {\'Y\' | \'N\'}\n | ENGINE [=] engine_name\n | INSERT_METHOD [=] { NO | FIRST | LAST }\n | KEY_BLOCK_SIZE [=] value\n | MAX_ROWS [=] value\n | MIN_ROWS [=] value\n | PACK_KEYS [=] {0 | 1 | DEFAULT}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}\n | STATS_AUTO_RECALC [=] {DEFAULT|0|1}\n | STATS_PERSISTENT [=] {DEFAULT|0|1}\n | STATS_SAMPLE_PAGES [=] value\n | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]\n | UNION [=] (tbl_name[,tbl_name]...)\n\npartition_options:\n PARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY [ALGORITHM={1|2}] (column_list)\n | RANGE{(expr) | COLUMNS(column_list)}\n | LIST{(expr) | COLUMNS(column_list)} }\n [PARTITIONS num]\n [SUBPARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY [ALGORITHM={1|2}] (column_list) }\n [SUBPARTITIONS num]\n ]\n [(partition_definition [, partition_definition] ...)]\n\npartition_definition:\n PARTITION partition_name\n [VALUES\n {LESS THAN {(expr | value_list) | MAXVALUE}\n |\n IN (value_list)}]\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'string\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n [(subpartition_definition [, subpartition_definition] ...)]\n\nsubpartition_definition:\n SUBPARTITION logical_name\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'string\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n\nquery_expression:\n SELECT ... (Some valid select or union statement)\n\nCREATE TABLE creates a table with the given name. You must have the\nCREATE privilege for the table.\n\nBy default, tables are created in the default database, using the\nInnoDB storage engine. An error occurs if the table exists, if there is\nno default database, or if the database does not exist.\n\nFor information about the physical representation of a table, see\nhttp://dev.mysql.com/doc/refman/5.7/en/create-table-files.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (297,32,'MICROSECOND','Syntax:\nMICROSECOND(expr)\n\nReturns the microseconds from the time or datetime expression expr as a\nnumber in the range from 0 to 999999.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT MICROSECOND(\'12:00:00.123456\');\n -> 123456\nmysql> SELECT MICROSECOND(\'2009-12-31 23:59:59.000010\');\n -> 10\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (298,40,'CREATE SERVER','Syntax:\nCREATE SERVER server_name\n FOREIGN DATA WRAPPER wrapper_name\n OPTIONS (option [, option] ...)\n\noption:\n { HOST character-literal\n | DATABASE character-literal\n | USER character-literal\n | PASSWORD character-literal\n | SOCKET character-literal\n | OWNER character-literal\n | PORT numeric-literal }\n\nThis statement creates the definition of a server for use with the\nFEDERATED storage engine. The CREATE SERVER statement creates a new row\nin the servers table in the mysql database. This statement requires the\nSUPER privilege.\n\nThe server_name should be a unique reference to the server. Server\ndefinitions are global within the scope of the server, it is not\npossible to qualify the server definition to a specific database.\nserver_name has a maximum length of 64 characters (names longer than 64\ncharacters are silently truncated), and is case insensitive. You may\nspecify the name as a quoted string.\n\nThe wrapper_name should be mysql, and may be quoted with single\nquotation marks. Other values for wrapper_name are not currently\nsupported.\n\nFor each option you must specify either a character literal or numeric\nliteral. Character literals are UTF-8, support a maximum length of 64\ncharacters and default to a blank (empty) string. String literals are\nsilently truncated to 64 characters. Numeric literals must be a number\nbetween 0 and 9999, default value is 0.\n\n*Note*:\n\nThe OWNER option is currently not applied, and has no effect on the\nownership or operation of the server connection that is created.\n\nThe CREATE SERVER statement creates an entry in the mysql.servers table\nthat can later be used with the CREATE TABLE statement when creating a\nFEDERATED table. The options that you specify will be used to populate\nthe columns in the mysql.servers table. The table columns are\nServer_name, Host, Db, Username, Password, Port and Socket.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-server.html\n\n','CREATE SERVER s\nFOREIGN DATA WRAPPER mysql\nOPTIONS (USER \'Remote\', HOST \'198.51.100.106\', DATABASE \'test\');\n','http://dev.mysql.com/doc/refman/5.7/en/create-server.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (298,40,'CREATE SERVER','Syntax:\nCREATE SERVER server_name\n FOREIGN DATA WRAPPER wrapper_name\n OPTIONS (option [, option] ...)\n\noption:\n { HOST character-literal\n | DATABASE character-literal\n | USER character-literal\n | PASSWORD character-literal\n | SOCKET character-literal\n | OWNER character-literal\n | PORT numeric-literal }\n\nThis statement creates the definition of a server for use with the\nFEDERATED storage engine. The CREATE SERVER statement creates a new row\nin the servers table in the mysql database. This statement requires the\nSUPER privilege.\n\nThe server_name should be a unique reference to the server. Server\ndefinitions are global within the scope of the server, it is not\npossible to qualify the server definition to a specific database.\nserver_name has a maximum length of 64 characters (names longer than 64\ncharacters are silently truncated), and is case insensitive. You may\nspecify the name as a quoted string.\n\nThe wrapper_name is an identifier and may be quoted with single\nquotation marks.\n\nFor each option you must specify either a character literal or numeric\nliteral. Character literals are UTF-8, support a maximum length of 64\ncharacters and default to a blank (empty) string. String literals are\nsilently truncated to 64 characters. Numeric literals must be a number\nbetween 0 and 9999, default value is 0.\n\n*Note*:\n\nThe OWNER option is currently not applied, and has no effect on the\nownership or operation of the server connection that is created.\n\nThe CREATE SERVER statement creates an entry in the mysql.servers table\nthat can later be used with the CREATE TABLE statement when creating a\nFEDERATED table. The options that you specify will be used to populate\nthe columns in the mysql.servers table. The table columns are\nServer_name, Host, Db, Username, Password, Port and Socket.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-server.html\n\n','CREATE SERVER s\nFOREIGN DATA WRAPPER mysql\nOPTIONS (USER \'Remote\', HOST \'198.51.100.106\', DATABASE \'test\');\n','http://dev.mysql.com/doc/refman/5.7/en/create-server.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (299,7,'ST_DISTANCE_SPHERE','ST_Distance_Sphere(g1, g2 [, radius])\n\nReturns the mimimum spherical distance between two points and/or\nmultipoints on a sphere, in meters, or NULL if any geometry argument is\nNULL or empty.\n\nCalculations use a spherical earth and a configurable radius. The\noptional radius argument should be given in meters. If omitted, the\ndefault radius is 6,370,986 meters. An ER_WRONG_ARGUMENTS error occurs\nif the radius argument is present but not positive.\n\nThe geometry arguments should consist of points that specify\n(longitude, latitude) coordinate values:\n\no Longitude and latitude are the first and second coordinates of the\n point, respectively.\n\no Both coordinates are in degrees.\n\no Longitude values must be in the range (-180, 180]. Positive values\n are east of the prime meridian.\n\no Latitude values must be in the range [-90, 90]. Positive values are\n north of the equator.\n\nSupported argument combinations are (Point, Point), (Point,\nMultiPoint), and (MultiPoint, Point). An ER_GIS_UNSUPPORTED_ARGUMENT\nerror occurs for other combinations.\n\nIf any geometry argument is not a syntactically well-formed geometry\nbyte string, an ER_GIS_INVALID_DATA error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html\n\n','mysql> SET @pt1 = ST_GeomFromText(\'POINT(0 0)\');\nmysql> SET @pt2 = ST_GeomFromText(\'POINT(180 0)\');\nmysql> SELECT ST_Distance_Sphere(@pt1, @pt2);\n+--------------------------------+\n| ST_Distance_Sphere(@pt1, @pt2) |\n+--------------------------------+\n| 20015042.813723423 |\n+--------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (300,33,'ST_POLYFROMWKB','ST_PolyFromWKB(wkb[, srid]), ST_PolygonFromWKB(wkb[, srid])\n\nConstructs a Polygon value using its WKB representation and SRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (301,32,'MAKETIME','Syntax:\nMAKETIME(hour,minute,second)\n\nReturns a time value calculated from the hour, minute, and second\narguments.\n\nThe second argument can have a fractional part.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT MAKETIME(12,15,30);\n -> \'12:15:30\'\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (302,32,'CURDATE','Syntax:\nCURDATE()\n\nReturns the current date as a value in \'YYYY-MM-DD\' or YYYYMMDD format,\ndepending on whether the function is used in a string or numeric\ncontext.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT CURDATE();\n -> \'2008-06-13\'\nmysql> SELECT CURDATE() + 0;\n -> 20080613\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (303,10,'SET PASSWORD','Syntax:\nSET PASSWORD [FOR user] = password_option\n\npassword_option: {\n \'auth_string\'\n | PASSWORD(\'auth_string\')\n}\n\nThe SET PASSWORD statement assigns a password to a MySQL user account.\n\'auth_string\' represents a cleartext (unencrypted) password.\n\n*Note*:\n\no SET PASSWORD ... = PASSWORD(\'auth_string\') syntax is deprecated as of\n MySQL 5.7.6 and will be removed in a future MySQL release.\n\no SET PASSWORD ... = \'auth_string\' syntax is not deprecated, but ALTER\n USER is the preferred statement for account alterations, including\n assigning passwords. For example:\n\nALTER USER user IDENTIFIED BY \'auth_string\';\n\n*Important*:\n\nUnder some circumstances, SET PASSWORD may be recorded in server logs\nor on the client side in a history file such as ~/.mysql_history, which\nmeans that cleartext passwords may be read by anyone having read access\nto that information. For information about the conditions under which\nthis occurs for the server logs and how to control it, see\nhttp://dev.mysql.com/doc/refman/5.7/en/password-logging.html. For\nsimilar information about client-side logging, see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-logging.html.\n\nSET PASSWORD can be used with or without a FOR clause that explicitly\nnames a user account:\n\no With a FOR user clause, the statement sets the password for the named\n account, which must exist:\n\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = \'auth_string\';\n\no With no FOR user clause, the statement sets the password for the\n current user:\n\nSET PASSWORD = \'auth_string\';\n\n Any client who connects to the server using a nonanonymous account\n can change the password for that account. To see which account the\n server authenticated you as, invoke the CURRENT_USER() function:\n\nSELECT CURRENT_USER();\n\nSetting the password for a named account (with a FOR clause) requires\nthe UPDATE privilege for the mysql database. Setting the password for\nyourself (for a nonanonymous account with no FOR clause) requires no\nspecial privileges. When the read_only system variable is enabled, SET\nPASSWORD requires the SUPER privilege in addition to any other required\nprivileges.\n\nIf a FOR user clause is given, the account name uses the format\ndescribed in http://dev.mysql.com/doc/refman/5.7/en/account-names.html.\nFor example:\n\nSET PASSWORD FOR \'bob\'@\'%.example.org\' = \'auth_string\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nThe password can be specified in these ways:\n\no Use a string without PASSWORD()\n\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = \'password\';\n\n SET PASSWORD interprets the string as a cleartext string, passes it\n to the authentication plugin associated with the account, and stores\n the result returned by the plugin in the mysql.user account row. (The\n plugin is given the opportunity to hash the value into the encryption\n format it expects. The plugin may use the value as specified, in\n which case no hashing occurs.)\n\no Use the PASSWORD() function (deprecated as of MySQL 5.7.6)\n\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = PASSWORD(\'password\');\n\n The PASSWORD() argument is the cleartext (unencrypted) password.\n PASSWORD() hashes the password and returns the encrypted password\n string for storage in the mysql.user account row.\n\n The PASSWORD() function hashes the password using the hashing method\n determined by the value of the old_passwords system variable value.\n Be sure that old_passwords has the value corresponding to the hashing\n method expected by the authentication plugin associated with the\n account. For example, if the account uses the mysql_native_password\n plugin, the old_passwords value must be 0:\n\nSET old_passwords = 0;\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = PASSWORD(\'password\');\n\n If the old_passwords value differs from that required by the\n authentication plugin, the hashed password value returned by\n PASSWORD() will not by usable by the plugin and correct\n authentication of client connections will not occur.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-password.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-password.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (303,10,'SET PASSWORD','Syntax:\nSET PASSWORD [FOR user] = password_option\n\npassword_option: {\n \'auth_string\'\n | PASSWORD(\'auth_string\')\n}\n\nThe SET PASSWORD statement assigns a password to a MySQL user account.\n\'auth_string\' represents a cleartext (unencrypted) password.\n\n*Note*:\n\no SET PASSWORD ... = PASSWORD(\'auth_string\') syntax is deprecated as of\n MySQL 5.7.6 and will be removed in a future MySQL release.\n\no SET PASSWORD ... = \'auth_string\' syntax is not deprecated, but ALTER\n USER is the preferred statement for account alterations, including\n assigning passwords. For example:\n\nALTER USER user IDENTIFIED BY \'auth_string\';\n\n*Important*:\n\nUnder some circumstances, SET PASSWORD may be recorded in server logs\nor on the client side in a history file such as ~/.mysql_history, which\nmeans that cleartext passwords may be read by anyone having read access\nto that information. For information about the conditions under which\nthis occurs for the server logs and how to control it, see\nhttp://dev.mysql.com/doc/refman/5.7/en/password-logging.html. For\nsimilar information about client-side logging, see\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-logging.html.\n\nSET PASSWORD can be used with or without a FOR clause that explicitly\nnames a user account:\n\no With a FOR user clause, the statement sets the password for the named\n account, which must exist:\n\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = \'auth_string\';\n\no With no FOR user clause, the statement sets the password for the\n current user:\n\nSET PASSWORD = \'auth_string\';\n\n Any client who connects to the server using a nonanonymous account\n can change the password for that account. (In particular, you can\n change your own password.) To see which account the server\n authenticated you as, invoke the CURRENT_USER() function:\n\nSELECT CURRENT_USER();\n\nSetting the password for a named account (with a FOR clause) requires\nthe UPDATE privilege for the mysql system database. Setting the\npassword for yourself (for a nonanonymous account with no FOR clause)\nrequires no special privileges. When the read_only system variable is\nenabled, SET PASSWORD requires the SUPER privilege in addition to any\nother required privileges.\n\nIf a FOR user clause is given, the account name uses the format\ndescribed in http://dev.mysql.com/doc/refman/5.7/en/account-names.html.\nFor example:\n\nSET PASSWORD FOR \'bob\'@\'%.example.org\' = \'auth_string\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nThe password can be specified in these ways:\n\no Use a string without PASSWORD()\n\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = \'password\';\n\n SET PASSWORD interprets the string as a cleartext string, passes it\n to the authentication plugin associated with the account, and stores\n the result returned by the plugin in the mysql.user account row. (The\n plugin is given the opportunity to hash the value into the encryption\n format it expects. The plugin may use the value as specified, in\n which case no hashing occurs.)\n\no Use the PASSWORD() function (deprecated as of MySQL 5.7.6)\n\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = PASSWORD(\'password\');\n\n The PASSWORD() argument is the cleartext (unencrypted) password.\n PASSWORD() hashes the password and returns the encrypted password\n string for storage in the mysql.user account row.\n\n The PASSWORD() function hashes the password using the hashing method\n determined by the value of the old_passwords system variable value.\n Be sure that old_passwords has the value corresponding to the hashing\n method expected by the authentication plugin associated with the\n account. For example, if the account uses the mysql_native_password\n plugin, the old_passwords value must be 0:\n\nSET old_passwords = 0;\nSET PASSWORD FOR \'jeffrey\'@\'localhost\' = PASSWORD(\'password\');\n\n If the old_passwords value differs from that required by the\n authentication plugin, the hashed password value returned by\n PASSWORD() will not by usable by the plugin and correct\n authentication of client connections will not occur.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-password.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-password.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (304,7,'JSON_QUOTE','Syntax:\nJSON_QUOTE(string)\n\nQuotes a string as a JSON value by wrapping it with double quote\ncharacters and escaping interior quote and other characters, then\nreturning the result as a utf8mb4 string. Returns NULL if the argument\nis NULL.\n\nThis function is typically used to produce a valid JSON string literal\nfor inclusion within a JSON document.\n\nCertain special characters are escaped with backslashes per the escape\nsequences shown in\nhttp://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html\n#json-unquote-character-escape-sequences.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html\n\n','mysql> SELECT JSON_QUOTE(\'null\'), JSON_QUOTE(\'"null"\');\n+--------------------+----------------------+\n| JSON_QUOTE(\'null\') | JSON_QUOTE(\'"null"\') |\n+--------------------+----------------------+\n| "null" | "\\"null\\"" |\n+--------------------+----------------------+\nmysql> SELECT JSON_QUOTE(\'[1, 2, 3]\');\n+-------------------------+\n| JSON_QUOTE(\'[1, 2, 3]\') |\n+-------------------------+\n| "[1, 2, 3]" |\n+-------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (305,17,'DATABASE','Syntax:\nDATABASE()\n\nReturns the default (current) database name as a string in the utf8\ncharacter set. If there is no default database, DATABASE() returns\nNULL. Within a stored routine, the default database is the database\nthat the routine is associated with, which is not necessarily the same\nas the database that is the default in the calling context.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT DATABASE();\n -> \'test\'\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (306,6,'IF FUNCTION','Syntax:\nIF(expr1,expr2,expr3)\n\nIf expr1 is TRUE (expr1 <> 0 and expr1 <> NULL), IF() returns expr2.\nOtherwise, it returns expr3.\n\n*Note*:\n\nThere is also an IF statement, which differs from the IF() function\ndescribed here. See [HELP IF statement].\n\nIf only one of expr2 or expr3 is explicitly NULL, the result type of\nthe IF() function is the type of the non-NULL expression.\n\nThe default return type of IF() (which may matter when it is stored\ninto a temporary table) is calculated as follows:\n\no If expr2 or expr3 produce a string, the result is a string.\n\n If expr2 and expr3 are both strings, the result is case-sensitive if\n either string is case sensitive.\n\no If expr2 or expr3 produce a floating-point value, the result is a\n floating-point value.\n\no If expr2 or expr3 produce an integer, the result is an integer.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html\n\n','mysql> SELECT IF(1>2,2,3);\n -> 3\nmysql> SELECT IF(1<2,\'yes\',\'no\');\n -> \'yes\'\nmysql> SELECT IF(STRCMP(\'test\',\'test1\'),\'no\',\'yes\');\n -> \'no\'\n','http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (307,33,'POINTFROMWKB','PointFromWKB(wkb[, srid])\n\nST_PointFromWKB() and PointFromWKB() are synonyms. For more\ninformation, see the description of ST_PointFromWKB().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (308,3,'POWER','Syntax:\nPOWER(X,Y)\n\nThis is a synonym for POW().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (309,3,'ATAN','Syntax:\nATAN(X)\n\nReturns the arc tangent of X, that is, the value whose tangent is X.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT ATAN(2);\n -> 1.1071487177941\nmysql> SELECT ATAN(-2);\n -> -1.1071487177941\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (310,27,'SHOW PROFILE','Syntax:\nSHOW PROFILE [type [, type] ... ]\n [FOR QUERY n]\n [LIMIT row_count [OFFSET offset]]\n\ntype:\n ALL\n | BLOCK IO\n | CONTEXT SWITCHES\n | CPU\n | IPC\n | MEMORY\n | PAGE FAULTS\n | SOURCE\n | SWAPS\n\nThe SHOW PROFILE and SHOW PROFILES statements display profiling\ninformation that indicates resource usage for statements executed\nduring the course of the current session.\n\n*Note*:\n\nThese statements are deprecated and will be removed in a future MySQL\nrelease. Use the Performance Schema instead; see\nhttp://dev.mysql.com/doc/refman/5.7/en/performance-schema-query-profili\nng.html.\n\nProfiling is controlled by the profiling session variable, which has a\ndefault value of 0 (OFF). Profiling is enabled by setting profiling to\n1 or ON:\n\nmysql> SET profiling = 1;\n\nSHOW PROFILES displays a list of the most recent statements sent to the\nserver. The size of the list is controlled by the\nprofiling_history_size session variable, which has a default value of\n15. The maximum value is 100. Setting the value to 0 has the practical\neffect of disabling profiling.\n\nAll statements are profiled except SHOW PROFILE and SHOW PROFILES, so\nyou will find neither of those statements in the profile list.\nMalformed statements are profiled. For example, SHOW PROFILING is an\nillegal statement, and a syntax error occurs if you try to execute it,\nbut it will show up in the profiling list.\n\nSHOW PROFILE displays detailed information about a single statement.\nWithout the FOR QUERY n clause, the output pertains to the most\nrecently executed statement. If FOR QUERY n is included, SHOW PROFILE\ndisplays information for statement n. The values of n correspond to the\nQuery_ID values displayed by SHOW PROFILES.\n\nThe LIMIT row_count clause may be given to limit the output to\nrow_count rows. If LIMIT is given, OFFSET offset may be added to begin\nthe output offset rows into the full set of rows.\n\nBy default, SHOW PROFILE displays Status and Duration columns. The\nStatus values are like the State values displayed by SHOW PROCESSLIST,\nalthough there might be some minor differences in interpretion for the\ntwo statements for some status values (see\nhttp://dev.mysql.com/doc/refman/5.7/en/thread-information.html).\n\nOptional type values may be specified to display specific additional\ntypes of information:\n\no ALL displays all information\n\no BLOCK IO displays counts for block input and output operations\n\no CONTEXT SWITCHES displays counts for voluntary and involuntary\n context switches\n\no CPU displays user and system CPU usage times\n\no IPC displays counts for messages sent and received\n\no MEMORY is not currently implemented\n\no PAGE FAULTS displays counts for major and minor page faults\n\no SOURCE displays the names of functions from the source code, together\n with the name and line number of the file in which the function\n occurs\n\no SWAPS displays swap counts\n\nProfiling is enabled per session. When a session ends, its profiling\ninformation is lost.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-profile.html\n\n','mysql> SELECT @@profiling;\n+-------------+\n| @@profiling |\n+-------------+\n| 0 |\n+-------------+\n1 row in set (0.00 sec)\n\nmysql> SET profiling = 1;\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> DROP TABLE IF EXISTS t1;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nmysql> CREATE TABLE T1 (id INT);\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> SHOW PROFILES;\n+----------+----------+--------------------------+\n| Query_ID | Duration | Query |\n+----------+----------+--------------------------+\n| 0 | 0.000088 | SET PROFILING = 1 |\n| 1 | 0.000136 | DROP TABLE IF EXISTS t1 |\n| 2 | 0.011947 | CREATE TABLE t1 (id INT) |\n+----------+----------+--------------------------+\n3 rows in set (0.00 sec)\n\nmysql> SHOW PROFILE;\n+----------------------+----------+\n| Status | Duration |\n+----------------------+----------+\n| checking permissions | 0.000040 |\n| creating table | 0.000056 |\n| After create | 0.011363 |\n| query end | 0.000375 |\n| freeing items | 0.000089 |\n| logging slow query | 0.000019 |\n| cleaning up | 0.000005 |\n+----------------------+----------+\n7 rows in set (0.00 sec)\n\nmysql> SHOW PROFILE FOR QUERY 1;\n+--------------------+----------+\n| Status | Duration |\n+--------------------+----------+\n| query end | 0.000107 |\n| freeing items | 0.000008 |\n| logging slow query | 0.000015 |\n| cleaning up | 0.000006 |\n+--------------------+----------+\n4 rows in set (0.00 sec)\n\nmysql> SHOW PROFILE CPU FOR QUERY 2;\n+----------------------+----------+----------+------------+\n| Status | Duration | CPU_user | CPU_system |\n+----------------------+----------+----------+------------+\n| checking permissions | 0.000040 | 0.000038 | 0.000002 |\n| creating table | 0.000056 | 0.000028 | 0.000028 |\n| After create | 0.011363 | 0.000217 | 0.001571 |\n| query end | 0.000375 | 0.000013 | 0.000028 |\n| freeing items | 0.000089 | 0.000010 | 0.000014 |\n| logging slow query | 0.000019 | 0.000009 | 0.000010 |\n| cleaning up | 0.000005 | 0.000003 | 0.000002 |\n+----------------------+----------+----------+------------+\n7 rows in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/show-profile.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (310,27,'SHOW PROFILE','Syntax:\nSHOW PROFILE [type [, type] ... ]\n [FOR QUERY n]\n [LIMIT row_count [OFFSET offset]]\n\ntype: {\n ALL\n | BLOCK IO\n | CONTEXT SWITCHES\n | CPU\n | IPC\n | MEMORY\n | PAGE FAULTS\n | SOURCE\n | SWAPS\n}\n\nThe SHOW PROFILE and SHOW PROFILES statements display profiling\ninformation that indicates resource usage for statements executed\nduring the course of the current session.\n\n*Note*:\n\nThe SHOW PROFILE and SHOW PROFILES statements are deprecated and will\nbe removed in a future MySQL release. Use the Performance Schema\ninstead; see\nhttp://dev.mysql.com/doc/refman/5.7/en/performance-schema-query-profili\nng.html.\n\nTo control profiling, use the profiling session variable, which has a\ndefault value of 0 (OFF). Enable profiling by setting profiling to 1 or\nON:\n\nmysql> SET profiling = 1;\n\nSHOW PROFILES displays a list of the most recent statements sent to the\nserver. The size of the list is controlled by the\nprofiling_history_size session variable, which has a default value of\n15. The maximum value is 100. Setting the value to 0 has the practical\neffect of disabling profiling.\n\nAll statements are profiled except SHOW PROFILE and SHOW PROFILES, so\nyou will find neither of those statements in the profile list.\nMalformed statements are profiled. For example, SHOW PROFILING is an\nillegal statement, and a syntax error occurs if you try to execute it,\nbut it will show up in the profiling list.\n\nSHOW PROFILE displays detailed information about a single statement.\nWithout the FOR QUERY n clause, the output pertains to the most\nrecently executed statement. If FOR QUERY n is included, SHOW PROFILE\ndisplays information for statement n. The values of n correspond to the\nQuery_ID values displayed by SHOW PROFILES.\n\nThe LIMIT row_count clause may be given to limit the output to\nrow_count rows. If LIMIT is given, OFFSET offset may be added to begin\nthe output offset rows into the full set of rows.\n\nBy default, SHOW PROFILE displays Status and Duration columns. The\nStatus values are like the State values displayed by SHOW PROCESSLIST,\nalthough there might be some minor differences in interpretion for the\ntwo statements for some status values (see\nhttp://dev.mysql.com/doc/refman/5.7/en/thread-information.html).\n\nOptional type values may be specified to display specific additional\ntypes of information:\n\no ALL displays all information\n\no BLOCK IO displays counts for block input and output operations\n\no CONTEXT SWITCHES displays counts for voluntary and involuntary\n context switches\n\no CPU displays user and system CPU usage times\n\no IPC displays counts for messages sent and received\n\no MEMORY is not currently implemented\n\no PAGE FAULTS displays counts for major and minor page faults\n\no SOURCE displays the names of functions from the source code, together\n with the name and line number of the file in which the function\n occurs\n\no SWAPS displays swap counts\n\nProfiling is enabled per session. When a session ends, its profiling\ninformation is lost.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-profile.html\n\n','mysql> SELECT @@profiling;\n+-------------+\n| @@profiling |\n+-------------+\n| 0 |\n+-------------+\n1 row in set (0.00 sec)\n\nmysql> SET profiling = 1;\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> DROP TABLE IF EXISTS t1;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nmysql> CREATE TABLE T1 (id INT);\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> SHOW PROFILES;\n+----------+----------+--------------------------+\n| Query_ID | Duration | Query |\n+----------+----------+--------------------------+\n| 0 | 0.000088 | SET PROFILING = 1 |\n| 1 | 0.000136 | DROP TABLE IF EXISTS t1 |\n| 2 | 0.011947 | CREATE TABLE t1 (id INT) |\n+----------+----------+--------------------------+\n3 rows in set (0.00 sec)\n\nmysql> SHOW PROFILE;\n+----------------------+----------+\n| Status | Duration |\n+----------------------+----------+\n| checking permissions | 0.000040 |\n| creating table | 0.000056 |\n| After create | 0.011363 |\n| query end | 0.000375 |\n| freeing items | 0.000089 |\n| logging slow query | 0.000019 |\n| cleaning up | 0.000005 |\n+----------------------+----------+\n7 rows in set (0.00 sec)\n\nmysql> SHOW PROFILE FOR QUERY 1;\n+--------------------+----------+\n| Status | Duration |\n+--------------------+----------+\n| query end | 0.000107 |\n| freeing items | 0.000008 |\n| logging slow query | 0.000015 |\n| cleaning up | 0.000006 |\n+--------------------+----------+\n4 rows in set (0.00 sec)\n\nmysql> SHOW PROFILE CPU FOR QUERY 2;\n+----------------------+----------+----------+------------+\n| Status | Duration | CPU_user | CPU_system |\n+----------------------+----------+----------+------------+\n| checking permissions | 0.000040 | 0.000038 | 0.000002 |\n| creating table | 0.000056 | 0.000028 | 0.000028 |\n| After create | 0.011363 | 0.000217 | 0.001571 |\n| query end | 0.000375 | 0.000013 | 0.000028 |\n| freeing items | 0.000089 | 0.000010 | 0.000014 |\n| logging slow query | 0.000019 | 0.000009 | 0.000010 |\n| cleaning up | 0.000005 | 0.000003 | 0.000002 |\n+----------------------+----------+----------+------------+\n7 rows in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/show-profile.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (311,3,'LN','Syntax:\nLN(X)\n\nReturns the natural logarithm of X; that is, the base-e logarithm of X.\nIf X is less than or equal to 0.0E0, the function returns NULL and (as\nof MySQL 5.7.4) a warning "Invalid argument for logarithm" is reported.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT LN(2);\n -> 0.69314718055995\nmysql> SELECT LN(-2);\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (312,27,'SET CHARACTER SET','Syntax:\nSET {CHARACTER SET | CHARSET}\n {\'charset_name\' | DEFAULT}\n\nThis statement maps all strings sent between the server and the current\nclient with the given mapping. SET CHARACTER SET sets three session\nsystem variables: character_set_client and character_set_results are\nset to the given character set, and character_set_connection to the\nvalue of character_set_database. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-connection.html.\n\ncharset_name may be quoted or unquoted.\n\nThe default character set mapping can be restored by using the value\nDEFAULT. The default depends on the server configuration.\n\nucs2, utf16, and utf32 cannot be used as a client character set, which\nmeans that they do not work for SET CHARACTER SET.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-character-set.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-character-set.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (312,27,'SET CHARACTER SET','Syntax:\nSET {CHARACTER SET | CHARSET}\n {\'charset_name\' | DEFAULT}\n\nThis statement maps all strings sent between the server and the current\nclient with the given mapping. SET CHARACTER SET sets three session\nsystem variables: character_set_client and character_set_results are\nset to the given character set, and character_set_connection to the\nvalue of character_set_database. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-connection.html.\n\ncharset_name may be quoted or unquoted.\n\nThe default character set mapping can be restored by using the value\nDEFAULT. The default depends on the server configuration.\n\nSome character sets cannot be used as the client character set.\nAttempting to use them with SET CHARACTER SET produces an error. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-connection.html#charset-\nconnection-impermissible-client-charset.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-character-set.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-character-set.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (313,24,'RETURN','Syntax:\nRETURN expr\n\nThe RETURN statement terminates execution of a stored function and\nreturns the value expr to the function caller. There must be at least\none RETURN statement in a stored function. There may be more than one\nif the function has multiple exit points.\n\nThis statement is not used in stored procedures, triggers, or events.\nThe LEAVE statement can be used to exit a stored program of those\ntypes.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/return.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/return.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (314,8,'SET SQL_LOG_BIN','Syntax:\nSET sql_log_bin = {0|1}\n\nThe sql_log_bin variable controls whether logging to the binary log is\ndone. The default value is 1 (do logging). To change logging for the\ncurrent session, change the session value of this variable. The session\nuser must have the SUPER privilege to set this variable. Set this\nvariable to 0 for a session to temporarily disable binary logging while\nmaking changes to the master which you do not want to replicate to the\nslave.\n\nThe global sql_log_bin variable is read only and cannot be modified.\nThe global scope is deprecated and will be removed in a future MySQL\nrelease.\n\nIt is not possible to set @@session.sql_log_bin within a transaction or\nsubquery.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-sql-log-bin.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-sql-log-bin.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (314,8,'SET SQL_LOG_BIN','Syntax:\nSET sql_log_bin = {OFF|ON}\n\nThe sql_log_bin variable controls whether logging to the binary log is\nenabled for the current session (assuming that the binary log itself is\nenabled). The default value is ON. To disable or enable binary logging\nfor the current session, set the session sql_log_bin variable to OFF or\nON.\n\nSet this variable to OFF for a session to temporarily disable binary\nlogging while making changes to the master you do not want replicated\nto the slave.\n\nSetting the session value of this system variable is a restricted\noperation. The session user must have privileges sufficient to set\nrestricted session variables. See\nhttp://dev.mysql.com/doc/refman/5.7/en/system-variable-privileges.html.\n\nIt is not possible to set the session value of sql_log_bin within a\ntransaction or subquery.\n\nSetting this variable to OFF prevents GTIDs from being assigned to\ntransactions in the binary log. If you are using GTIDs for replication,\nthis means that even when binary logging is later enabled again, the\nGTIDs written into the log from this point do not account for any\ntransactions that occurred in the meantime, so in effect those\ntransactions are lost.\n\nThe global sql_log_bin variable is read only and cannot be modified.\nThe global scope is deprecated and will be removed in a future MySQL\nrelease.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-sql-log-bin.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-sql-log-bin.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (315,12,'AES_DECRYPT','Syntax:\nAES_DECRYPT(crypt_str,key_str[,init_vector])\n\nThis function decrypts data using the official AES (Advanced Encryption\nStandard) algorithm. For more information, see the description of\nAES_ENCRYPT().\n\nThe optional initialization vector argument, init_vector, is available\nas of MySQL 5.7.4. As of that version, statements that use\nAES_DECRYPT() are unsafe for statement-based replication and cannot be\nstored in the query cache.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (316,17,'COERCIBILITY','Syntax:\nCOERCIBILITY(str)\n\nReturns the collation coercibility value of the string argument.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT COERCIBILITY(\'abc\' COLLATE latin1_swedish_ci);\n -> 0\nmysql> SELECT COERCIBILITY(USER());\n -> 3\nmysql> SELECT COERCIBILITY(\'abc\');\n -> 4\nmysql> SELECT COERCIBILITY(1000);\n -> 5\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (317,23,'INT','INT[(M)] [UNSIGNED] [ZEROFILL]\n\nA normal-size integer. The signed range is -2147483648 to 2147483647.\nThe unsigned range is 0 to 4294967295.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
@@ -407,21 +407,21 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (326,28,'REPLACE','Syntax:\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [(col_name [, col_name] ...)]\n {VALUES | VALUE} (value_list) [, (value_list)] ...\n\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n SET assignment_list\n\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [(col_name [, col_name] ...)]\n SELECT ...\n\nvalue:\n {expr | DEFAULT}\n\nvalue_list:\n value [, value] ...\n\nassignment:\n col_name = value\n\nassignment_list:\n assignment [, assignment] ...\n\nREPLACE works exactly like INSERT, except that if an old row in the\ntable has the same value as a new row for a PRIMARY KEY or a UNIQUE\nindex, the old row is deleted before the new row is inserted. See [HELP\nINSERT].\n\nREPLACE is a MySQL extension to the SQL standard. It either inserts, or\ndeletes and inserts. For another MySQL extension to standard SQL---that\neither inserts or updates---see\nhttp://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html.\n\nDELAYED inserts and replaces were deprecated in MySQL 5.6. In MySQL\n5.7, DELAYED is not supported. The server recognizes but ignores the\nDELAYED keyword, handles the replace as a nondelayed replace, and\ngenerates an ER_WARN_LEGACY_SYNTAX_CONVERTED warning. ("REPLACE DELAYED\nis no longer supported. The statement was converted to REPLACE.") The\nDELAYED keyword will be removed in a future release.\n\n*Note*:\n\nREPLACE makes sense only if a table has a PRIMARY KEY or UNIQUE index.\nOtherwise, it becomes equivalent to INSERT, because there is no index\nto be used to determine whether a new row duplicates another.\n\nValues for all columns are taken from the values specified in the\nREPLACE statement. Any missing columns are set to their default values,\njust as happens for INSERT. You cannot refer to values from the current\nrow and use them in the new row. If you use an assignment such as SET\ncol_name = col_name + 1, the reference to the column name on the right\nhand side is treated as DEFAULT(col_name), so the assignment is\nequivalent to SET col_name = DEFAULT(col_name) + 1.\n\nTo use REPLACE, you must have both the INSERT and DELETE privileges for\nthe table.\n\nIf a generated column is replaced explicitly, the only permitted value\nis DEFAULT. For information about generated columns, see\nhttp://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.h\ntml.\n\nREPLACE supports explicit partition selection using the PARTITION\nkeyword with a list of comma-separated names of partitions,\nsubpartitions, or both. As with INSERT, if it is not possible to insert\nthe new row into any of these partitions or subpartitions, the REPLACE\nstatement fails with the error Found a row not matching the given\npartition set. For more information and examples, see\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-selection.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/replace.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/replace.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (327,32,'CURRENT_TIMESTAMP','Syntax:\nCURRENT_TIMESTAMP, CURRENT_TIMESTAMP([fsp])\n\nCURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (328,26,'ST_SYMDIFFERENCE','ST_SymDifference(g1, g2)\n\nReturns a geometry that represents the point set symmetric difference\nof the geometry values g1 and g2, which is defined as:\n\ng1 symdifference g2 := (g1 union g2) difference (g1 intersection g2)\n\nOr, in function call notation:\n\nST_SymDifference(g1, g2) = ST_Difference(ST_Union(g1, g2), ST_Intersection(g1, g2))\n\nIf any argument is NULL, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html\n\n','mysql> SET @g1 = Point(1,1), @g2 = Point(2,2);\nmysql> SELECT ST_AsText(ST_SymDifference(@g1, @g2));\n+---------------------------------------+\n| ST_AsText(ST_SymDifference(@g1, @g2)) |\n+---------------------------------------+\n| MULTIPOINT((1 1),(2 2)) |\n+---------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (329,7,'GTID_SUBSET','Syntax:\nGTID_SUBSET(subset,set)\n\nGiven two sets of global transaction IDs subset and set, returns true\nif all GTIDs in subset are also in set. Returns false otherwise.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html\n\n','mysql> SELECT GTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\')\\G\n*************************** 1. row ***************************\nGTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\'): 1\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\')\\G\n*************************** 1. row ***************************\nGTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\'): 1\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\')\\G\n*************************** 1. row ***************************\nGTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\'): 0\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (329,7,'GTID_SUBSET','Syntax:\nGTID_SUBSET(set1,set2)\n\nGiven two sets of global transaction IDs set1 and set2, returns true if\nall GTIDs in set1 are also in set2. Returns false otherwise.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html\n\n','mysql> SELECT GTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\')\\G\n*************************** 1. row ***************************\nGTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\'): 1\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\')\\G\n*************************** 1. row ***************************\nGTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\'): 1\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\')\\G\n*************************** 1. row ***************************\nGTID_SUBSET(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\'): 0\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (330,16,'VAR_SAMP','Syntax:\nVAR_SAMP(expr)\n\nReturns the sample variance of expr. That is, the denominator is the\nnumber of rows minus one.\n\nIf there are no matching rows, VAR_SAMP() returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (331,23,'DATETIME','DATETIME[(fsp)]\n\nA date and time combination. The supported range is \'1000-01-01\n00:00:00.000000\' to \'9999-12-31 23:59:59.999999\'. MySQL displays\nDATETIME values in \'YYYY-MM-DD HH:MM:SS[.fraction]\' format, but permits\nassignment of values to DATETIME columns using either strings or\nnumbers.\n\nAn optional fsp value in the range from 0 to 6 may be given to specify\nfractional seconds precision. A value of 0 signifies that there is no\nfractional part. If omitted, the default precision is 0.\n\nAutomatic initialization and updating to the current date and time for\nDATETIME columns can be specified using DEFAULT and ON UPDATE column\ndefinition clauses, as described in\nhttp://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-overview.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (332,8,'CHANGE REPLICATION FILTER','Syntax:\nCHANGE REPLICATION FILTER filter[, filter][, ...]\n\nfilter:\n REPLICATE_DO_DB = (db_list)\n | REPLICATE_IGNORE_DB = (db_list)\n | REPLICATE_DO_TABLE = (tbl_list)\n | REPLICATE_IGNORE_TABLE = (tbl_list)\n | REPLICATE_WILD_DO_TABLE = (wild_tbl_list)\n | REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list)\n | REPLICATE_REWRITE_DB = (db_pair_list)\n\ndb_list:\n db_name[, db_name][, ...]\n\ntbl_list:\n db_name.table_name[, db_table_name][, ...]\nwild_tbl_list:\n \'db_pattern.table_pattern\'[, \'db_pattern.table_pattern\'][, ...]\n\ndb_pair_list:\n (db_pair)[, (db_pair)][, ...]\n\ndb_pair:\n from_db, to_db\n\nCHANGE REPLICATION FILTER sets one or more replication filtering rules\non the slave in the same way as starting the slave mysqld with\nreplication filtering options such as --replicate-do-db or\n--replicate-wild-ignore-table. Unlike the case with the server options,\nthis statement does not require restarting the server to take effect,\nonly that the slave SQL thread be stopped using STOP SLAVE SQL_THREAD\nfirst (and restarted with START SLAVE SQL_THREAD afterwards). CHANGE\nREPLICATION FILTER requires the SUPER privilege.\n\nThe following list shows the CHANGE REPLICATION FILTER options and how\nthey relate to --replicate-* server options:\n\no REPLICATE_DO_DB: Include updates based on database name. Equivalent\n to --replicate-do-db.\n\no REPLICATE_IGNORE_DB: Exclude updates based on database name.\n Equivalent to --replicate-ignore-db.\n\no REPLICATE_DO_TABLE: Include updates based on table name. Equivalent\n to --replicate-do-table.\n\no REPLICATE_IGNORE_TABLE: Exclude updates based on table name.\n Equivalent to --replicate-ignore-table.\n\no REPLICATE_WILD_DO_TABLE: Include updates based on wildcard pattern\n matching table name. Equivalent to --replicate-wild-do-table.\n\no REPLICATE_WILD_IGNORE_TABLE: Exclude updates based on wildcard\n pattern matching table name. Equivalent to\n --replicate-wild-ignore-table.\n\no REPLICATE_REWRITE_DB: Perform updates on slave after substituting new\n name on slave for specified database on master. Equivalent to\n --replicate-rewrite-db.\n\nThe precise effects of REPLICATE_DO_DB and REPLICATE_IGNORE_DB filters\nare dependent on whether statement-based or row-based replication is in\neffect. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-rules.html, for more\ninformation.\n\nMultiple replication filtering rules can be created in a single CHANGE\nREPLICATION FILTER statement by separating the rules with commas, as\nshown here:\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (d1), REPLICATE_IGNORE_DB = (d2);\n\nIssuing the statement just shown is equivalent to starting the slave\nmysqld with the options --replicate-do-db=d1 --replicate-ignore-db=d2.\n\nIf the same filtering rule is specified multiple times, only the last\nsuch rule is actually used. For example, the two statements shown here\nhave exactly the same effect, because the first REPLICATE_DO_DB rule in\nthe first statement is ignored:\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (db1, db2), REPLICATE_DO_DB = (db3, db4);\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (db3,db4);\n\n*Caution*:\n\nThis behavior differs from that of the --replicate-* filter options\nwhere specifying the same option multiple times causes the creation of\nmultiple filter rules.\n\nNames of tables and database not containing any special characters need\nnot be quoted. Values used with REPLICATION_WILD_TABLE and\nREPLICATION_WILD_IGNORE_TABLE are string expressions, possibly\ncontaining (special) wildcard characters, and so must be quoted. This\nis shown in the following example statements:\n\nCHANGE REPLICATION FILTER\n REPLICATE_WILD_DO_TABLE = (\'db1.old%\');\n\nCHANGE REPLICATION FILTER\n REPLICATE_WILD_IGNORE_TABLE = (\'db1.new%\', \'db2.new%\');\n\nValues used with REPLICATE_REWRITE_DB represent pairs of database\nnames; each such value must be enclosed in parentheses. The following\nstatement rewrites statements occurring on database db1 on the master\nto database db2 on the slave:\n\nCHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2));\n\nThe statement just shown contains two sets of parentheses, one\nenclosing the pair of database names, and the other enclosing the\nentire list. This is perhap more easily seen in the following example,\nwhich creates two rewrite-db rules, one rewriting database dbA to dbB,\nand one rewriting database dbC to dbD:\n\nCHANGE REPLICATION FILTER\n REPLICATE_REWRITE_DB = ((dbA, dbB), (dbC, dbD));\n\nThis statement leaves any existing replication filtering rules\nunchanged; to unset all filters of a given type, set the filter\'s value\nto an explicitly empty list, as shown in this example, which removes\nall existing REPLICATE_DO_DB and REPLICATE_IGNORE_DB rules:\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (), REPLICATE_IGNORE_DB = ();\n\nSetting a filter to empty in this way removes all existing rules, does\nnot create any new ones, and does not restore any rules set at mysqld\nstartup using --replicate-* options on the command line or in the\nconfiguration file.\n\nValues employed with REPLICATE_WILD_DO_TABLE and\nREPLICATE_WILD_IGNORE_TABLE must be in the format db_name.tbl_name.\nPrior to MySQL 5.7.5, this was not strictly enforced, although using\nnonconforming values with these options could lead to erroneous results\n(Bug #18095449).\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-rules.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/change-replication-filter.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/change-replication-filter.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (332,8,'CHANGE REPLICATION FILTER','Syntax:\nCHANGE REPLICATION FILTER filter[, filter][, ...]\n\nfilter:\n REPLICATE_DO_DB = (db_list)\n | REPLICATE_IGNORE_DB = (db_list)\n | REPLICATE_DO_TABLE = (tbl_list)\n | REPLICATE_IGNORE_TABLE = (tbl_list)\n | REPLICATE_WILD_DO_TABLE = (wild_tbl_list)\n | REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list)\n | REPLICATE_REWRITE_DB = (db_pair_list)\n\ndb_list:\n db_name[, db_name][, ...]\n\ntbl_list:\n db_name.table_name[, db_table_name][, ...]\nwild_tbl_list:\n \'db_pattern.table_pattern\'[, \'db_pattern.table_pattern\'][, ...]\n\ndb_pair_list:\n (db_pair)[, (db_pair)][, ...]\n\ndb_pair:\n from_db, to_db\n\nCHANGE REPLICATION FILTER sets one or more replication filtering rules\non the slave in the same way as starting the slave mysqld with\nreplication filtering options such as --replicate-do-db or\n--replicate-wild-ignore-table. Unlike the case with the server options,\nthis statement does not require restarting the server to take effect,\nonly that the slave SQL thread be stopped using STOP SLAVE SQL_THREAD\nfirst (and restarted with START SLAVE SQL_THREAD afterwards). CHANGE\nREPLICATION FILTER requires the SUPER privilege.\n\nReplication filters cannot be set on a MySQL server instance that is\nconfigured for Group Replication, because filtering transactions on\nsome servers would make the group unable to reach agreement on a\nconsistent state.\n\nThe following list shows the CHANGE REPLICATION FILTER options and how\nthey relate to --replicate-* server options:\n\no REPLICATE_DO_DB: Include updates based on database name. Equivalent\n to --replicate-do-db.\n\no REPLICATE_IGNORE_DB: Exclude updates based on database name.\n Equivalent to --replicate-ignore-db.\n\no REPLICATE_DO_TABLE: Include updates based on table name. Equivalent\n to --replicate-do-table.\n\no REPLICATE_IGNORE_TABLE: Exclude updates based on table name.\n Equivalent to --replicate-ignore-table.\n\no REPLICATE_WILD_DO_TABLE: Include updates based on wildcard pattern\n matching table name. Equivalent to --replicate-wild-do-table.\n\no REPLICATE_WILD_IGNORE_TABLE: Exclude updates based on wildcard\n pattern matching table name. Equivalent to\n --replicate-wild-ignore-table.\n\no REPLICATE_REWRITE_DB: Perform updates on slave after substituting new\n name on slave for specified database on master. Equivalent to\n --replicate-rewrite-db.\n\nThe precise effects of REPLICATE_DO_DB and REPLICATE_IGNORE_DB filters\nare dependent on whether statement-based or row-based replication is in\neffect. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-rules.html, for more\ninformation.\n\nMultiple replication filtering rules can be created in a single CHANGE\nREPLICATION FILTER statement by separating the rules with commas, as\nshown here:\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (d1), REPLICATE_IGNORE_DB = (d2);\n\nIssuing the statement just shown is equivalent to starting the slave\nmysqld with the options --replicate-do-db=d1 --replicate-ignore-db=d2.\n\nIf the same filtering rule is specified multiple times, only the last\nsuch rule is actually used. For example, the two statements shown here\nhave exactly the same effect, because the first REPLICATE_DO_DB rule in\nthe first statement is ignored:\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (db1, db2), REPLICATE_DO_DB = (db3, db4);\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (db3,db4);\n\n*Caution*:\n\nThis behavior differs from that of the --replicate-* filter options\nwhere specifying the same option multiple times causes the creation of\nmultiple filter rules.\n\nNames of tables and database not containing any special characters need\nnot be quoted. Values used with REPLICATION_WILD_TABLE and\nREPLICATION_WILD_IGNORE_TABLE are string expressions, possibly\ncontaining (special) wildcard characters, and so must be quoted. This\nis shown in the following example statements:\n\nCHANGE REPLICATION FILTER\n REPLICATE_WILD_DO_TABLE = (\'db1.old%\');\n\nCHANGE REPLICATION FILTER\n REPLICATE_WILD_IGNORE_TABLE = (\'db1.new%\', \'db2.new%\');\n\nValues used with REPLICATE_REWRITE_DB represent pairs of database\nnames; each such value must be enclosed in parentheses. The following\nstatement rewrites statements occurring on database db1 on the master\nto database db2 on the slave:\n\nCHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2));\n\nThe statement just shown contains two sets of parentheses, one\nenclosing the pair of database names, and the other enclosing the\nentire list. This is perhap more easily seen in the following example,\nwhich creates two rewrite-db rules, one rewriting database dbA to dbB,\nand one rewriting database dbC to dbD:\n\nCHANGE REPLICATION FILTER\n REPLICATE_REWRITE_DB = ((dbA, dbB), (dbC, dbD));\n\nThis statement leaves any existing replication filtering rules\nunchanged; to unset all filters of a given type, set the filter\'s value\nto an explicitly empty list, as shown in this example, which removes\nall existing REPLICATE_DO_DB and REPLICATE_IGNORE_DB rules:\n\nCHANGE REPLICATION FILTER\n REPLICATE_DO_DB = (), REPLICATE_IGNORE_DB = ();\n\nSetting a filter to empty in this way removes all existing rules, does\nnot create any new ones, and does not restore any rules set at mysqld\nstartup using --replicate-* options on the command line or in the\nconfiguration file.\n\nValues employed with REPLICATE_WILD_DO_TABLE and\nREPLICATE_WILD_IGNORE_TABLE must be in the format db_name.tbl_name.\nPrior to MySQL 5.7.5, this was not strictly enforced, although using\nnonconforming values with these options could lead to erroneous results\n(Bug #18095449).\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-rules.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/change-replication-filter.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/change-replication-filter.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (333,23,'INTEGER','INTEGER[(M)] [UNSIGNED] [ZEROFILL]\n\nThis type is a synonym for INT.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (334,27,'SHOW COLUMNS','Syntax:\nSHOW [FULL] {COLUMNS | FIELDS}\n {FROM | IN} tbl_name\n [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW COLUMNS displays information about the columns in a given table.\nIt also works for views. SHOW COLUMNS displays information only for\nthose columns for which you have some privilege.\n\nYou can use db_name.tbl_name as an alternative to the tbl_name FROM\ndb_name syntax. In other words, these two statements are equivalent:\n\nSHOW COLUMNS FROM mytable FROM mydb;\nSHOW COLUMNS FROM mydb.mytable;\n\nThe optional FULL keyword causes the output to include the column\ncollation and comments, as well as the privileges you have for each\ncolumn.\n\nThe LIKE clause, if present, indicates which column names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nmysql> SHOW COLUMNS FROM City;\n+-------------+----------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+-------------+----------+------+-----+---------+----------------+\n| ID | int(11) | NO | PRI | NULL | auto_increment |\n| Name | char(35) | NO | | | |\n| CountryCode | char(3) | NO | MUL | | |\n| District | char(20) | NO | | | |\n| Population | int(11) | NO | | 0 | |\n+-------------+----------+------+-----+---------+----------------+\n\nThe data types may differ from what you expect them to be based on a\nCREATE TABLE statement because MySQL sometimes changes data types when\nyou create or alter a table. The conditions under which this occurs are\ndescribed in\nhttp://dev.mysql.com/doc/refman/5.7/en/silent-column-changes.html.\n\nSHOW COLUMNS displays the following values for each table column:\n\no Field\n\n The column name.\n\no Type\n\n The column data type.\n\no Collation\n\n The collation for nonbinary string columns, or NULL for other\n columns. This value is displayed only if you use the FULL keyword.\n\no Null\n\n Column nullability. The value is YES if NULL values can be stored in\n the column, NO if not.\n\no Key\n\n Whether the column is indexed:\n\n o If Key is empty, the column either is not indexed or is indexed\n only as a secondary column in a multiple-column, nonunique index.\n\n o If Key is PRI, the column is a PRIMARY KEY or is one of the columns\n in a multiple-column PRIMARY KEY.\n\n o If Key is UNI, the column is the first column of a UNIQUE index. (A\n UNIQUE index permits multiple NULL values, but you can tell whether\n the column permits NULL by checking the Null field.)\n\n o If Key is MUL, the column is the first column of a nonunique index\n in which multiple occurrences of a given value are permitted within\n the column.\n\n If more than one of the Key values applies to a given column of a\n table, Key displays the one with the highest priority, in the order\n PRI, UNI, MUL.\n\n A UNIQUE index may be displayed as PRI if it cannot contain NULL\n values and there is no PRIMARY KEY in the table. A UNIQUE index may\n display as MUL if several columns form a composite UNIQUE index;\n although the combination of the columns is unique, each column can\n still hold multiple occurrences of a given value.\n\no Default\n\n The default value for the column. This is NULL if the column has an\n explicit default of NULL, or if the column definition includes no\n DEFAULT clause.\n\no Extra\n\n Any additional information that is available about a given column.\n The value is nonempty in these cases:\n\n o auto_increment for columns that have the AUTO_INCREMENT attribute\n\n o on update CURRENT_TIMESTAMP for TIMESTAMP or DATETIME columns that\n have the ON UPDATE CURRENT_TIMESTAMP attribute\n\n o VIRTUAL GENERATED or VIRTUAL STORED for generated columns\n\no Privileges\n\n The privileges you have for the column. This value is displayed only\n if you use the FULL keyword.\n\no Comment\n\n Any comment included in the column definition. This value is\n displayed only if you use the FULL keyword.\n\nYou can also obtain information about table columns from\nINFORMATION_SCHEMA, which contains a COLUMNS table. See\nhttp://dev.mysql.com/doc/refman/5.7/en/columns-table.html.\n\nYou can list a table\'s columns with the mysqlshow db_name tbl_name\ncommand.\n\nThe DESCRIBE statement provides information similar to SHOW COLUMNS.\nSee http://dev.mysql.com/doc/refman/5.7/en/describe.html.\n\nThe SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements\nalso provide information about tables. See [HELP SHOW].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-columns.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-columns.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (334,27,'SHOW COLUMNS','Syntax:\nSHOW [FULL] {COLUMNS | FIELDS}\n {FROM | IN} tbl_name\n [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW COLUMNS displays information about the columns in a given table.\nIt also works for views. SHOW COLUMNS displays information only for\nthose columns for which you have some privilege.\n\nmysql> SHOW COLUMNS FROM City;\n+-------------+----------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+-------------+----------+------+-----+---------+----------------+\n| ID | int(11) | NO | PRI | NULL | auto_increment |\n| Name | char(35) | NO | | | |\n| CountryCode | char(3) | NO | MUL | | |\n| District | char(20) | NO | | | |\n| Population | int(11) | NO | | 0 | |\n+-------------+----------+------+-----+---------+----------------+\n\nAn alternative to tbl_name FROM db_name syntax is db_name.tbl_name.\nThese two statements are equivalent:\n\nSHOW COLUMNS FROM mytable FROM mydb;\nSHOW COLUMNS FROM mydb.mytable;\n\nThe optional FULL keyword causes the output to include the column\ncollation and comments, as well as the privileges you have for each\ncolumn.\n\nThe LIKE clause, if present, indicates which column names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nThe data types may differ from what you expect them to be based on a\nCREATE TABLE statement because MySQL sometimes changes data types when\nyou create or alter a table. The conditions under which this occurs are\ndescribed in\nhttp://dev.mysql.com/doc/refman/5.7/en/silent-column-changes.html.\n\nSHOW COLUMNS displays the following values for each table column:\n\no Field\n\n The column name.\n\no Type\n\n The column data type.\n\no Collation\n\n The collation for nonbinary string columns, or NULL for other\n columns. This value is displayed only if you use the FULL keyword.\n\no Null\n\n The column nullability. The value is YES if NULL values can be stored\n in the column, NO if not.\n\no Key\n\n Whether the column is indexed:\n\n o If Key is empty, the column either is not indexed or is indexed\n only as a secondary column in a multiple-column, nonunique index.\n\n o If Key is PRI, the column is a PRIMARY KEY or is one of the columns\n in a multiple-column PRIMARY KEY.\n\n o If Key is UNI, the column is the first column of a UNIQUE index. (A\n UNIQUE index permits multiple NULL values, but you can tell whether\n the column permits NULL by checking the Null field.)\n\n o If Key is MUL, the column is the first column of a nonunique index\n in which multiple occurrences of a given value are permitted within\n the column.\n\n If more than one of the Key values applies to a given column of a\n table, Key displays the one with the highest priority, in the order\n PRI, UNI, MUL.\n\n A UNIQUE index may be displayed as PRI if it cannot contain NULL\n values and there is no PRIMARY KEY in the table. A UNIQUE index may\n display as MUL if several columns form a composite UNIQUE index;\n although the combination of the columns is unique, each column can\n still hold multiple occurrences of a given value.\n\no Default\n\n The default value for the column. This is NULL if the column has an\n explicit default of NULL, or if the column definition includes no\n DEFAULT clause.\n\no Extra\n\n Any additional information that is available about a given column.\n The value is nonempty in these cases:\n\n o auto_increment for columns that have the AUTO_INCREMENT attribute.\n\n o on update CURRENT_TIMESTAMP for TIMESTAMP or DATETIME columns that\n have the ON UPDATE CURRENT_TIMESTAMP attribute.\n\n o VIRTUAL GENERATED or VIRTUAL STORED for generated columns.\n\no Privileges\n\n The privileges you have for the column. This value is displayed only\n if you use the FULL keyword.\n\no Comment\n\n Any comment included in the column definition. This value is\n displayed only if you use the FULL keyword.\n\nTable column information is also available from the INFORMATION_SCHEMA\nCOLUMNS table. See\nhttp://dev.mysql.com/doc/refman/5.7/en/columns-table.html.\n\nYou can list a table\'s columns with the mysqlshow db_name tbl_name\ncommand.\n\nThe DESCRIBE statement provides information similar to SHOW COLUMNS.\nSee http://dev.mysql.com/doc/refman/5.7/en/describe.html.\n\nThe SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements\nalso provide information about tables. See [HELP SHOW].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-columns.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-columns.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (335,23,'TINYINT','TINYINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA very small integer. The signed range is -128 to 127. The unsigned\nrange is 0 to 255.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (336,14,'MASTER_POS_WAIT','Syntax:\nMASTER_POS_WAIT(log_name,log_pos[,timeout][,channel])\n\nThis function is useful for control of master/slave synchronization. It\nblocks until the slave has read and applied all updates up to the\nspecified position in the master log. The return value is the number of\nlog events the slave had to wait for to advance to the specified\nposition. The function returns NULL if the slave SQL thread is not\nstarted, the slave\'s master information is not initialized, the\narguments are incorrect, or an error occurs. It returns -1 if the\ntimeout has been exceeded. If the slave SQL thread stops while\nMASTER_POS_WAIT() is waiting, the function returns NULL. If the slave\nis past the specified position, the function returns immediately.\n\nOn a multithreaded slave, the function waits until expiry of the limit\nset by the slave_checkpoint_group or slave_checkpoint_period system\nvariable, when the checkpoint operation is called to update the status\nof the slave. Depending on the setting for the system variables, the\nfunction might therefore return some time after the specified position\nwas reached.\n\nIf a timeout value is specified, MASTER_POS_WAIT() stops waiting when\ntimeout seconds have elapsed. timeout must be greater than 0; a zero or\nnegative timeout means no timeout.\n\nThe optional channel value enables you to name which replication\nchannel the function applies to. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (337,19,'^','Syntax:\n^\n\nBitwise XOR.\n\nThe result is an unsigned 64-bit integer.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/bit-functions.html\n\n','mysql> SELECT 1 ^ 1;\n -> 0\nmysql> SELECT 1 ^ 0;\n -> 1\nmysql> SELECT 11 ^ 3;\n -> 8\n','http://dev.mysql.com/doc/refman/5.7/en/bit-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (338,40,'DROP VIEW','Syntax:\nDROP VIEW [IF EXISTS]\n view_name [, view_name] ...\n [RESTRICT | CASCADE]\n\nDROP VIEW removes one or more views. You must have the DROP privilege\nfor each view.\n\nIf any views named in the argument list do not exist, the statement\nreturns an error indicating by name which nonexisting views it was\nunable to drop, but also drops all views in the list that do exist.\n\n*Note*:\n\nIn MySQL 8.0, DROP VIEW fails if any views named in the argument list\ndo not exist. Due to the change in behavior, a partially completed DROP\nVIEW operation on a MySQL 5.7 master fails when replicated to a MySQL\n8.0 slave. To avoid this failure scenario, use IF EXISTS syntax in DROP\nVIEW statements to prevent an error from occurring for views that do\nnot exist. For more information, see Atomic Data Definition Statement\nSupport (http://dev.mysql.com/doc/refman/8.0/en/atomic-ddl.html).\n\nThe IF EXISTS clause prevents an error from occurring for views that\ndon\'t exist. When this clause is given, a NOTE is generated for each\nnonexistent view. See [HELP SHOW WARNINGS].\n\nRESTRICT and CASCADE, if given, are parsed and ignored.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-view.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-view.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (339,32,'WEEK','Syntax:\nWEEK(date[,mode])\n\nThis function returns the week number for date. The two-argument form\nof WEEK() enables you to specify whether the week starts on Sunday or\nMonday and whether the return value should be in the range from 0 to 53\nor from 1 to 53. If the mode argument is omitted, the value of the\ndefault_week_format system variable is used. See\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT WEEK(\'2008-02-20\');\n -> 7\nmysql> SELECT WEEK(\'2008-02-20\',0);\n -> 7\nmysql> SELECT WEEK(\'2008-02-20\',1);\n -> 8\nmysql> SELECT WEEK(\'2008-12-31\',1);\n -> 53\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (340,22,'DROP FUNCTION UDF','Syntax:\nDROP FUNCTION function_name\n\nThis statement drops the user-defined function (UDF) named\nfunction_name.\n\nTo drop a function, you must have the DELETE privilege for the mysql\ndatabase. This is because DROP FUNCTION removes a row from the\nmysql.func system table that records the function\'s name, type, and\nshared library name.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-function-udf.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-function-udf.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (340,22,'DROP FUNCTION UDF','Syntax:\nDROP FUNCTION function_name\n\nThis statement drops the user-defined function (UDF) named\nfunction_name.\n\nTo drop a function, you must have the DELETE privilege for the mysql\nsystem database. This is because DROP FUNCTION removes a row from the\nmysql.func system table that records the function\'s name, type, and\nshared library name.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-function-udf.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-function-udf.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (341,7,'ST_VALIDATE','ST_Validate(g)\n\nValidates a geometry according to the OGC specification. A geometry can\nbe syntactically well-formed (WKB value plus SRID) but geometrically\ninvalid. For example, this polygon is geometrically invalid: POLYGON((0\n0, 0 0, 0 0, 0 0, 0 0))\n\nST_Validate() returns the geometry if it is syntactically well-formed\nand is geometrically valid, NULL if the argument is not syntactically\nwell-formed or is not geometrically valid or is NULL.\n\nST_Validate() can be used to filter out invalid geometry data, although\nat a cost. For applications that require more precise results not\ntainted by invalid data, this penalty may be worthwhile.\n\nIf the geometry argument is valid, it is returned as is, except that if\nan input Polygon or MultiPolygon has clockwise rings, those rings are\nreversed before checking for validity. If the geometry is valid, the\nvalue with the reversed rings is returned.\n\nThe only valid empty geometry is represented in the form of an empty\ngeometry collection value. ST_Validate() returns it directly without\nfurther checks in this case.\n\nST_Validate() works only for the Cartesian coordinate system and\nrequires a geometry argument with an SRID of 0. An ER_WRONG_ARGUMENTS\nerror occurs otherwise.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html\n\n','mysql> SET @ls1 = ST_GeomFromText(\'LINESTRING(0 0)\');\nmysql> SET @ls2 = ST_GeomFromText(\'LINESTRING(0 0, 1 1)\');\nmysql> SELECT ST_AsText(ST_Validate(@ls1));\n+------------------------------+\n| ST_AsText(ST_Validate(@ls1)) |\n+------------------------------+\n| NULL |\n+------------------------------+\nmysql> SELECT ST_AsText(ST_Validate(@ls2));\n+------------------------------+\n| ST_AsText(ST_Validate(@ls2)) |\n+------------------------------+\n| LINESTRING(0 0,1 1) |\n+------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-convenience-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (342,38,'UPDATEXML','Syntax:\nUpdateXML(xml_target, xpath_expr, new_xml)\n\nThis function replaces a single portion of a given fragment of XML\nmarkup xml_target with a new XML fragment new_xml, and then returns the\nchanged XML. The portion of xml_target that is replaced matches an\nXPath expression xpath_expr supplied by the user.\n\nIf no expression matching xpath_expr is found, or if multiple matches\nare found, the function returns the original xml_target XML fragment.\nAll three arguments should be strings.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/xml-functions.html\n\n','mysql> SELECT\n -> UpdateXML(\'ccc \', \'/a\', \'fff \') AS val1,\n -> UpdateXML(\'ccc \', \'/b\', \'fff \') AS val2,\n -> UpdateXML(\'ccc \', \'//b\', \'fff \') AS val3,\n -> UpdateXML(\'ccc \', \'/a/d\', \'fff \') AS val4,\n -> UpdateXML(\'ccc \', \'/a/d\', \'fff \') AS val5\n -> \\G\n\n*************************** 1. row ***************************\nval1: fff \nval2: ccc \nval3: fff \nval4: ccc fff \nval5: ccc \n','http://dev.mysql.com/doc/refman/5.7/en/xml-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (343,8,'RESET SLAVE','Syntax:\nRESET SLAVE [ALL] [channel_option]\n\nchannel_option:\n FOR CHANNEL channel\n\nRESET SLAVE makes the slave forget its replication position in the\nmaster\'s binary log. This statement is meant to be used for a clean\nstart: It clears the master info and relay log info repositories,\ndeletes all the relay log files, and starts a new relay log file. It\nalso resets to 0 the replication delay specified with the MASTER_DELAY\noption to CHANGE MASTER TO. RESET SLAVE does not change the values of\ngtid_executed or gtid_purged. To use RESET SLAVE, the slave replication\nthreads must be stopped, so on a running slave use STOP SLAVE before\nissuing RESET SLAVE.\n\n*Note*:\n\nAll relay log files are deleted, even if they have not been completely\nexecuted by the slave SQL thread. (This is a condition likely to exist\non a replication slave if you have issued a STOP SLAVE statement or if\nthe slave is highly loaded.)\n\nThe optional FOR CHANNEL channel clause enables you to name which\nreplication channel the statement applies to. Providing a FOR CHANNEL\nchannel clause applies the RESET SLAVE statement to a specific\nreplication channel. Combining a FOR CHANNEL channel clause with the\nALL option deletes the specified channel. If no channel is named and no\nextra channels exist, the statement applies to the default channel.\nIssuing a RESET SLAVE ALL statement without a FOR CHANNEL channel\nclause when multiple replication channels exist deletes all replication\nchannels and recreates only the default channel. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information.\n\nRESET SLAVE does not change any replication connection parameters such\nas master host, master port, master user, or master password, which are\nretained in memory. This means that START SLAVE can be issued without\nrequiring a CHANGE MASTER TO statement following RESET SLAVE.\n\nConnection parameters are reset by RESET SLAVE ALL. (RESET SLAVE\nfollowed by a restart of the slave mysqld also does this.)\n\nRESET SLAVE causes an implicit commit of an ongoing transaction. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nIf the slave SQL thread was in the middle of replicating temporary\ntables when it was stopped, and RESET SLAVE is issued, these replicated\ntemporary tables are deleted on the slave.\n\nPrior to MySQL 5.7.5, RESET SLAVE also had the effect of resetting both\nthe heartbeat period (Slave_heartbeat_period) and\nSSL_VERIFY_SERVER_CERT. This issue is fixed in MySQL 5.7.5 and later.\n(Bug #18777899, Bug #18778485)\n\nPrior to MySQL 5.7.5, RESET SLAVE ALL did not clear the\nIGNORE_SERVER_IDS list set by CHANGE MASTER TO. In MySQL 5.7.5 and\nlater, the statement clears the list. (Bug #18816897)\n\n*Note*:\n\nWhen used on an NDB Cluster replication slave SQL node, RESET SLAVE\nclears the mysql.ndb_apply_status table. You should keep in mind when\nusing this statement that ndb_apply_status uses the NDB storage engine\nand so is shared by all SQL nodes attached to the slave cluster.\n\nYou can override this behavior by issuing SET GLOBAL\n@@ndb_clear_apply_status=OFF prior to executing RESET SLAVE, which\nkeeps the slave from purging the ndb_apply_status table in such cases.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/reset-slave.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/reset-slave.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (343,8,'RESET SLAVE','Syntax:\nRESET SLAVE [ALL] [channel_option]\n\nchannel_option:\n FOR CHANNEL channel\n\nRESET SLAVE makes the slave forget its replication position in the\nmaster\'s binary log. This statement is meant to be used for a clean\nstart: It clears the master info and relay log info repositories,\ndeletes all the relay log files, and starts a new relay log file. It\nalso resets to 0 the replication delay specified with the MASTER_DELAY\noption to CHANGE MASTER TO. RESET SLAVE does not change the values of\ngtid_executed or gtid_purged.\n\n*Note*:\n\nAll relay log files are deleted, even if they have not been completely\nexecuted by the slave SQL thread. (This is a condition likely to exist\non a replication slave if you have issued a STOP SLAVE statement or if\nthe slave is highly loaded.)\n\nTo use RESET SLAVE, the slave replication threads must be stopped, so\non a running slave use STOP SLAVE before issuing RESET SLAVE. To use\nRESET SLAVE on a Group Replication group member, the member status must\nbe OFFLINE, meaning that the plugin is loaded but the member does not\ncurrently belong to any group. A group member can be taken offline by\nusing a STOP GROUP REPLICATION statement.\n\nThe optional FOR CHANNEL channel clause enables you to name which\nreplication channel the statement applies to. Providing a FOR CHANNEL\nchannel clause applies the RESET SLAVE statement to a specific\nreplication channel. Combining a FOR CHANNEL channel clause with the\nALL option deletes the specified channel. If no channel is named and no\nextra channels exist, the statement applies to the default channel.\nIssuing a RESET SLAVE ALL statement without a FOR CHANNEL channel\nclause when multiple replication channels exist deletes all replication\nchannels and recreates only the default channel. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information.\n\nRESET SLAVE does not change any replication connection parameters such\nas master host, master port, master user, or master password.\n\no From MySQL 5.7.24, when master_info_repository=TABLE is set on the\n server, replication connection parameters are preserved in the\n crash-safe InnoDB table mysql.slave_master_info as part of the RESET\n SLAVE operation. They are also retained in memory. In the event of a\n server crash or deliberate restart after issuing RESET SLAVE but\n before issuing START SLAVE, the replication connection parameters are\n retrieved from the table and reused for the new connection.\n\no When master_info_repository=FILE is set on the server (which is the\n default in MySQL 5.7), replication connection parameters are only\n retained in memory. If the slave mysqld is restarted immediately\n after issuing RESET SLAVE due to a server crash or deliberate\n restart, the connection parameters are lost. In that case, you must\n issue a CHANGE MASTER TO statement after the server start to\n respecify the connection parameters before issuing START SLAVE.\n\nIf you want to reset the connection parameters intentionally, you need\nto use RESET SLAVE ALL, which clears the connection parameters. In that\ncase, you must issue a CHANGE MASTER TO statement after the server\nstart to specify the new connection parameters.\n\nRESET SLAVE causes an implicit commit of an ongoing transaction. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nIf the slave SQL thread was in the middle of replicating temporary\ntables when it was stopped, and RESET SLAVE is issued, these replicated\ntemporary tables are deleted on the slave.\n\nPrior to MySQL 5.7.5, RESET SLAVE also had the effect of resetting both\nthe heartbeat period (Slave_heartbeat_period) and\nSSL_VERIFY_SERVER_CERT. This issue is fixed in MySQL 5.7.5 and later.\n(Bug #18777899, Bug #18778485)\n\nPrior to MySQL 5.7.5, RESET SLAVE ALL did not clear the\nIGNORE_SERVER_IDS list set by CHANGE MASTER TO. In MySQL 5.7.5 and\nlater, the statement clears the list. (Bug #18816897)\n\n*Note*:\n\nWhen used on an NDB Cluster replication slave SQL node, RESET SLAVE\nclears the mysql.ndb_apply_status table. You should keep in mind when\nusing this statement that ndb_apply_status uses the NDB storage engine\nand so is shared by all SQL nodes attached to the slave cluster.\n\nYou can override this behavior by issuing SET GLOBAL\n@@ndb_clear_apply_status=OFF prior to executing RESET SLAVE, which\nkeeps the slave from purging the ndb_apply_status table in such cases.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/reset-slave.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/reset-slave.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (344,7,'ST_POINTFROMGEOHASH','ST_PointFromGeoHash(geohash_str, srid)\n\nReturns a POINT value containing the decoded geohash value, given a\ngeohash string value.\n\nThe X and Y coordinates of the point are the longitude in the range\n[−180, 180] and the latitude in the range [−90, 90], respectively.\n\nIf any argument is NULL, the return value is NULL. If any argument is\ninvalid, an error occurs.\n\nThe srid argument is an unsigned 32-bit integer.\n\nThe remarks in the description of ST_LatFromGeoHash() regarding the\nmaximum number of characters processed from the geohash_str argument\nalso apply to ST_PointFromGeoHash().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-geohash-functions.html\n\n','mysql> SET @gh = ST_GeoHash(45,-20,10);\nmysql> SELECT ST_AsText(ST_PointFromGeoHash(@gh,0));\n+---------------------------------------+\n| ST_AsText(ST_PointFromGeoHash(@gh,0)) |\n+---------------------------------------+\n| POINT(45 -20) |\n+---------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-geohash-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (345,32,'DAY','Syntax:\nDAY(date)\n\nDAY() is a synonym for DAYOFMONTH().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (346,14,'UUID','Syntax:\nUUID()\n\nReturns a Universal Unique Identifier (UUID) generated according to RFC\n4122, "A Universally Unique IDentifier (UUID) URN Namespace"\n(http://www.ietf.org/rfc/rfc4122.txt).\n\nA UUID is designed as a number that is globally unique in space and\ntime. Two calls to UUID() are expected to generate two different\nvalues, even if these calls are performed on two separate devices not\nconnected to each other.\n\n*Warning*:\n\nAlthough UUID() values are intended to be unique, they are not\nnecessarily unguessable or unpredictable. If unpredictability is\nrequired, UUID values should be generated some other way.\n\nUUID() returns a value that conforms to UUID version 1 as described in\nRFC 4122. The value is a 128-bit number represented as a utf8 string of\nfive hexadecimal numbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\nformat:\n\no The first three numbers are generated from the low, middle, and high\n parts of a timestamp. The high part also includes the UUID version\n number.\n\no The fourth number preserves temporal uniqueness in case the timestamp\n value loses monotonicity (for example, due to daylight saving time).\n\no The fifth number is an IEEE 802 node number that provides spatial\n uniqueness. A random number is substituted if the latter is not\n available (for example, because the host device has no Ethernet card,\n or it is unknown how to find the hardware address of an interface on\n the host operating system). In this case, spatial uniqueness cannot\n be guaranteed. Nevertheless, a collision should have very low\n probability.\n\n The MAC address of an interface is taken into account only on FreeBSD\n and Linux. On other operating systems, MySQL uses a randomly\n generated 48-bit number.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','mysql> SELECT UUID();\n -> \'6ccd780c-baba-1026-9564-5b8c656024db\'\n','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
@@ -441,12 +441,12 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (360,6,'IFNULL','Syntax:\nIFNULL(expr1,expr2)\n\nIf expr1 is not NULL, IFNULL() returns expr1; otherwise it returns\nexpr2.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html\n\n','mysql> SELECT IFNULL(1,0);\n -> 1\nmysql> SELECT IFNULL(NULL,10);\n -> 10\nmysql> SELECT IFNULL(1/0,10);\n -> 10\nmysql> SELECT IFNULL(1/0,\'yes\');\n -> \'yes\'\n','http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (361,27,'SHOW FUNCTION CODE','Syntax:\nSHOW FUNCTION CODE func_name\n\nThis statement is similar to SHOW PROCEDURE CODE but for stored\nfunctions. See [HELP SHOW PROCEDURE CODE].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-function-code.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-function-code.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (362,27,'SHOW ERRORS','Syntax:\nSHOW ERRORS [LIMIT [offset,] row_count]\nSHOW COUNT(*) ERRORS\n\nSHOW ERRORS is a diagnostic statement that is similar to SHOW WARNINGS,\nexcept that it displays information only for errors, rather than for\nerrors, warnings, and notes.\n\nThe LIMIT clause has the same syntax as for the SELECT statement. See\nhttp://dev.mysql.com/doc/refman/5.7/en/select.html.\n\nThe SHOW COUNT(*) ERRORS statement displays the number of errors. You\ncan also retrieve this number from the error_count variable:\n\nSHOW COUNT(*) ERRORS;\nSELECT @@error_count;\n\nSHOW ERRORS and error_count apply only to errors, not warnings or\nnotes. In other respects, they are similar to SHOW WARNINGS and\nwarning_count. In particular, SHOW ERRORS cannot display information\nfor more than max_error_count messages, and error_count can exceed the\nvalue of max_error_count if the number of errors exceeds\nmax_error_count.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-errors.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-errors.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (363,27,'SET NAMES','Syntax:\nSET NAMES {\'charset_name\'\n [COLLATE \'collation_name\'] | DEFAULT}\n\nThis statement sets the three session system variables\ncharacter_set_client, character_set_connection, and\ncharacter_set_results to the given character set. Setting\ncharacter_set_connection to charset_name also sets collation_connection\nto the default collation for charset_name. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-connection.html.\n\nThe optional COLLATE clause may be used to specify a collation\nexplicitly. If given, the collation must one of the permitted\ncollations for charset_name.\n\ncharset_name and collation_name may be quoted or unquoted.\n\nThe default mapping can be restored by using a value of DEFAULT. The\ndefault depends on the server configuration.\n\nucs2, utf16, and utf32 cannot be used as a client character set, which\nmeans that they do not work for SET NAMES.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-names.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-names.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (363,27,'SET NAMES','Syntax:\nSET NAMES {\'charset_name\'\n [COLLATE \'collation_name\'] | DEFAULT}\n\nThis statement sets the three session system variables\ncharacter_set_client, character_set_connection, and\ncharacter_set_results to the given character set. Setting\ncharacter_set_connection to charset_name also sets collation_connection\nto the default collation for charset_name. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-connection.html.\n\nThe optional COLLATE clause may be used to specify a collation\nexplicitly. If given, the collation must one of the permitted\ncollations for charset_name.\n\ncharset_name and collation_name may be quoted or unquoted.\n\nThe default mapping can be restored by using a value of DEFAULT. The\ndefault depends on the server configuration.\n\nSome character sets cannot be used as the client character set.\nAttempting to use them with SET NAMES produces an error. See\nhttp://dev.mysql.com/doc/refman/5.7/en/charset-connection.html#charset-\nconnection-impermissible-client-charset.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-names.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-names.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (364,20,'LEAST','Syntax:\nLEAST(value1,value2,...)\n\nWith two or more arguments, returns the smallest (minimum-valued)\nargument. The arguments are compared using the following rules:\n\no If any argument is NULL, the result is NULL. No comparison is needed.\n\no If all arguments are integer-valued, they are compared as integers.\n\no If at least one argument is double precision, they are compared as\n double-precision values. Otherwise, if at least one argument is a\n DECIMAL value, they are compared as DECIMAL values.\n\no If the arguments comprise a mix of numbers and strings, they are\n compared as numbers.\n\no If any argument is a nonbinary (character) string, the arguments are\n compared as nonbinary strings.\n\no In all other cases, the arguments are compared as binary strings.\n\nThe return type of LEAST() is the aggregated type of the comparison\nargument types.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT LEAST(2,0);\n -> 0\nmysql> SELECT LEAST(34.0,3.0,5.0,767.0);\n -> 3.0\nmysql> SELECT LEAST(\'B\',\'A\',\'C\');\n -> \'A\'\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (365,20,'=','=\n\nEqual:\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT 1 = 0;\n -> 0\nmysql> SELECT \'0\' = 0;\n -> 1\nmysql> SELECT \'0.0\' = 0;\n -> 1\nmysql> SELECT \'0.01\' = 0;\n -> 0\nmysql> SELECT \'.01\' = 0.01;\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (366,4,'ST_GEOMCOLLFROMTEXT','ST_GeomCollFromText(wkt[, srid]), ST_GeometryCollectionFromText(wkt[,\nsrid]), ST_GeomCollFromTxt(wkt[, srid])\n\nConstructs a GeometryCollection value using its WKT representation and\nSRID.\n\nIf the geometry argument is NULL or not a syntactically well-formed\ngeometry, or if the SRID argument is NULL, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','mysql> SET @g = "MULTILINESTRING((10 10, 11 11), (9 9, 10 10))";\nmysql> SELECT ST_AsText(ST_GeomCollFromText(@g));\n+--------------------------------------------+\n| ST_AsText(ST_GeomCollFromText(@g)) |\n+--------------------------------------------+\n| MULTILINESTRING((10 10,11 11),(9 9,10 10)) |\n+--------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (367,14,'IS_IPV4_MAPPED','Syntax:\nIS_IPV4_MAPPED(expr)\n\nThis function takes an IPv6 address represented in numeric form as a\nbinary string, as returned by INET6_ATON(). It returns 1 if the\nargument is a valid IPv4-mapped IPv6 address, 0 otherwise. IPv4-mapped\naddresses have the form ::ffff:ipv4_address.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','mysql> SELECT IS_IPV4_MAPPED(INET6_ATON(\'::10.0.5.9\'));\n -> 0\nmysql> SELECT IS_IPV4_MAPPED(INET6_ATON(\'::ffff:10.0.5.9\'));\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (368,10,'CREATE USER','Syntax:\nCREATE USER [IF NOT EXISTS]\n user [auth_option] [, user [auth_option]] ...\n [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]\n [WITH resource_option [resource_option] ...]\n [password_option | lock_option] ...\n\nuser:\n (see )\n\nauth_option: {\n IDENTIFIED BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin\n | IDENTIFIED WITH auth_plugin BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin AS \'hash_string\'\n | IDENTIFIED BY PASSWORD \'hash_string\'\n}\n\ntls_option: {\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n}\n\nresource_option: {\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n}\n\npassword_option: {\n PASSWORD EXPIRE\n | PASSWORD EXPIRE DEFAULT\n | PASSWORD EXPIRE NEVER\n | PASSWORD EXPIRE INTERVAL N DAY\n}\n\nlock_option: {\n ACCOUNT LOCK\n | ACCOUNT UNLOCK\n}\n\nThe CREATE USER statement creates new MySQL accounts. It enables\nauthentication, SSL/TLS, resource-limit, and password-management\nproperties to be established for new accounts, and controls whether\naccounts are initially locked or unlocked.\n\nTo use CREATE USER, you must have the global CREATE USER privilege, or\nthe INSERT privilege for the mysql database. When the read_only system\nvariable is enabled, CREATE USER additionally requires the SUPER\nprivilege.\n\nAn error occurs if you try to create an account that already exists. If\nthe IF NOT EXISTS clause is given, the statement produces a warning for\neach named account that already exists, rather than an error.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-user.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (368,10,'CREATE USER','Syntax:\nCREATE USER [IF NOT EXISTS]\n user [auth_option] [, user [auth_option]] ...\n [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]\n [WITH resource_option [resource_option] ...]\n [password_option | lock_option] ...\n\nuser:\n (see )\n\nauth_option: {\n IDENTIFIED BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin\n | IDENTIFIED WITH auth_plugin BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin AS \'hash_string\'\n | IDENTIFIED BY PASSWORD \'hash_string\'\n}\n\ntls_option: {\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n}\n\nresource_option: {\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n}\n\npassword_option: {\n PASSWORD EXPIRE\n | PASSWORD EXPIRE DEFAULT\n | PASSWORD EXPIRE NEVER\n | PASSWORD EXPIRE INTERVAL N DAY\n}\n\nlock_option: {\n ACCOUNT LOCK\n | ACCOUNT UNLOCK\n}\n\nThe CREATE USER statement creates new MySQL accounts. It enables\nauthentication, SSL/TLS, resource-limit, and password-management\nproperties to be established for new accounts, and controls whether\naccounts are initially locked or unlocked.\n\nTo use CREATE USER, you must have the global CREATE USER privilege, or\nthe INSERT privilege for the mysql system database. When the read_only\nsystem variable is enabled, CREATE USER additionally requires the SUPER\nprivilege.\n\nAn error occurs if you try to create an account that already exists. If\nthe IF NOT EXISTS clause is given, the statement produces a warning for\neach named account that already exists, rather than an error.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-user.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (369,25,'POINT','Point(x, y)\n\nConstructs a Point using its coordinates.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (370,38,'LCASE','Syntax:\nLCASE(str)\n\nLCASE() is a synonym for LOWER().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (371,7,'CREATE_DH_PARAMETERS','CREATE_DH_PARAMETERS(key_len)\n\nCreates a shared secret for generating a DH private/public key pair and\nreturns a binary string that can be passed to\nCREATE_ASYMMETRIC_PRIV_KEY(). If secret generation fails, the result is\nnull.\n\nSupported key_len values: The minimum and maximum key lengths in bits\nare 1,024 and 10,000. These key-length limits are constraints imposed\nby OpenSSL. Server administrators can impose additional limits on\nmaximum key length by setting environment variables. See\nhttp://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-usage.html\n.\n\nFor an example showing how to use the return value for generating\nsymmetric keys, see the description of ASYMMETRIC_DERIVE().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html\n\n','SET @dhp = CREATE_DH_PARAMETERS(1024);\n','http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html');
@@ -460,7 +460,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (379,33,'ST_ASBINARY','ST_AsBinary(g), ST_AsWKB(g)\n\nConverts a value in internal geometry format to its WKB representation\nand returns the binary result.\n\nIf the argument is NULL, the return value is NULL. If the argument is\nnot a syntactically well-formed geometry, an ER_GIS_INVALID_DATA error\noccurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-format-conversion-functions.html\n\n','SELECT ST_AsBinary(g) FROM geom;\n','http://dev.mysql.com/doc/refman/5.7/en/gis-format-conversion-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (380,38,'TO_BASE64','Syntax:\nTO_BASE64(str)\n\nConverts the string argument to base-64 encoded form and returns the\nresult as a character string with the connection character set and\ncollation. If the argument is not a string, it is converted to a string\nbefore conversion takes place. The result is NULL if the argument is\nNULL. Base-64 encoded strings can be decoded using the FROM_BASE64()\nfunction.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT TO_BASE64(\'abc\'), FROM_BASE64(TO_BASE64(\'abc\'));\n -> \'JWJj\', \'abc\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (381,12,'DES_DECRYPT','Syntax:\nDES_DECRYPT(crypt_str[,key_str])\n\nDecrypts a string encrypted with DES_ENCRYPT(). If an error occurs,\nthis function returns NULL.\n\nThis function works only if MySQL has been configured with SSL support.\nSee http://dev.mysql.com/doc/refman/5.7/en/encrypted-connections.html.\n\nIf no key_str argument is given, DES_DECRYPT() examines the first byte\nof the encrypted string to determine the DES key number that was used\nto encrypt the original string, and then reads the key from the DES key\nfile to decrypt the message. For this to work, the user must have the\nSUPER privilege. The key file can be specified with the --des-key-file\nserver option.\n\nIf you pass this function a key_str argument, that string is used as\nthe key for decrypting the message.\n\nIf the crypt_str argument does not appear to be an encrypted string,\nMySQL returns the given crypt_str.\n\n*Note*:\n\nThe DES_ENCRYPT() and DES_DECRYPT() functions are deprecated as of\nMySQL 5.7.6, will be removed in a future MySQL release, and should no\nlonger be used. Consider using AES_ENCRYPT() and AES_DECRYPT() instead.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (382,2,'ST_AREA','ST_Area(poly)\n\nReturns a double-precision number indicating the area of the argument,\nas measured in its spatial reference system. For arguments of dimension\n0 or 1, the result is 0. If the argument is an empty geometry the\nreturn value is 0. If the argument is NULL the return value is NULL.\n\nThe result is the sum of the area values of all components for a\ngeometry collection. If a geometry collection is empty, its area is\nreturned as 0.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n \'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))\';\nmysql> SELECT ST_Area(ST_GeomFromText(@poly));\n+---------------------------------+\n| ST_Area(ST_GeomFromText(@poly)) |\n+---------------------------------+\n| 4 |\n+---------------------------------+\n\nmysql> SET @mpoly =\n -> \'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))\';\nmysql> SELECT ST_Area(ST_GeomFromText(@mpoly));\n+----------------------------------+\n| ST_Area(ST_GeomFromText(@mpoly)) |\n+----------------------------------+\n| 8 |\n+----------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (382,2,'ST_AREA','ST_Area({poly|mpoly})\n\nReturns a double-precision number indicating the area of the Polygon or\nMultiPolygon argument, as measured in its spatial reference system. For\narguments of dimension 0 or 1, the result is 0. If the argument is an\nempty geometry the return value is 0. If the argument is NULL the\nreturn value is NULL.\n\nThe result is the sum of the area values of all components for a\ngeometry collection. If a geometry collection is empty, its area is\nreturned as 0.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n \'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))\';\nmysql> SELECT ST_Area(ST_GeomFromText(@poly));\n+---------------------------------+\n| ST_Area(ST_GeomFromText(@poly)) |\n+---------------------------------+\n| 4 |\n+---------------------------------+\n\nmysql> SET @mpoly =\n \'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))\';\nmysql> SELECT ST_Area(ST_GeomFromText(@mpoly));\n+----------------------------------+\n| ST_Area(ST_GeomFromText(@mpoly)) |\n+----------------------------------+\n| 8 |\n+----------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (383,13,'ENDPOINT','EndPoint(ls)\n\nST_EndPoint() and EndPoint() are synonyms. For more information, see\nthe description of ST_EndPoint().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (384,28,'INSERT','Syntax:\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [(col_name [, col_name] ...)]\n {VALUES | VALUE} (value_list) [, (value_list)] ...\n [ON DUPLICATE KEY UPDATE assignment_list]\n\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n SET assignment_list\n [ON DUPLICATE KEY UPDATE assignment_list]\n\nINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [(col_name [, col_name] ...)]\n SELECT ...\n [ON DUPLICATE KEY UPDATE assignment_list]\n\nvalue:\n {expr | DEFAULT}\n\nvalue_list:\n value [, value] ...\n\nassignment:\n col_name = value\n\nassignment_list:\n assignment [, assignment] ...\n\nINSERT inserts new rows into an existing table. The INSERT ... VALUES\nand INSERT ... SET forms of the statement insert rows based on\nexplicitly specified values. The INSERT ... SELECT form inserts rows\nselected from another table or tables. INSERT with an ON DUPLICATE KEY\nUPDATE clause enables existing rows to be updated if a row to be\ninserted would cause a duplicate value in a UNIQUE index or PRIMARY\nKEY.\n\nFor additional information about INSERT ... SELECT and INSERT ... ON\nDUPLICATE KEY UPDATE, see [HELP INSERT SELECT], and\nhttp://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html.\n\nIn MySQL 5.7, the DELAYED keyword is accepted but ignored by the\nserver. For the reasons for this, see [HELP INSERT DELAYED],\n\nInserting into a table requires the INSERT privilege for the table. If\nthe ON DUPLICATE KEY UPDATE clause is used and a duplicate key causes\nan UPDATE to be performed instead, the statement requires the UPDATE\nprivilege for the columns to be updated. For columns that are read but\nnot modified you need only the SELECT privilege (such as for a column\nreferenced only on the right hand side of an col_name=expr assignment\nin an ON DUPLICATE KEY UPDATE clause).\n\nWhen inserting into a partitioned table, you can control which\npartitions and subpartitions accept new rows. The PARTITION option\ntakes a list of the comma-separated names of one or more partitions or\nsubpartitions (or both) of the table. If any of the rows to be inserted\nby a given INSERT statement do not match one of the partitions listed,\nthe INSERT statement fails with the error Found a row not matching the\ngiven partition set. For more information and examples, see\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-selection.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/insert.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/insert.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (385,16,'COUNT','Syntax:\nCOUNT(expr)\n\nReturns a count of the number of non-NULL values of expr in the rows\nretrieved by a SELECT statement. The result is a BIGINT value.\n\nIf there are no matching rows, COUNT() returns 0.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','mysql> SELECT student.student_name,COUNT(*)\n FROM student,course\n WHERE student.student_id=course.student_id\n GROUP BY student_name;\n','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
@@ -474,12 +474,12 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (393,12,'DECODE','Syntax:\nDECODE(crypt_str,pass_str)\n\nDECODE() decrypts the encrypted string crypt_str using pass_str as the\npassword. crypt_str should be a string returned from ENCODE().\n\n*Note*:\n\nThe ENCODE() and DECODE() functions are deprecated in MySQL 5.7, will\nbe removed in a future MySQL release, and should no longer be used.\nConsider using AES_ENCRYPT() and AES_DECRYPT() instead.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (394,7,'JSON_ARRAY_INSERT','Syntax:\nJSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)\n\nUpdates a JSON document, inserting into an array within the document\nand returning the modified document. Returns NULL if any argument is\nNULL. An error occurs if the json_doc argument is not a valid JSON\ndocument or any path argument is not a valid path expression or\ncontains a * or ** wildcard or does not end with an array element\nidentifier.\n\nThe path-value pairs are evaluated left to right. The document produced\nby evaluating one pair becomes the new value against which the next\npair is evaluated.\n\nPairs for which the path does not identify any array in the JSON\ndocument are ignored. If a path identifies an array element, the\ncorresponding value is inserted at that element position, shifting any\nfollowing values to the right. If a path identifies an array position\npast the end of an array, the value is inserted at the end of the\narray.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html\n\n','mysql> SET @j = \'["a", {"b": [1, 2]}, [3, 4]]\';\nmysql> SELECT JSON_ARRAY_INSERT(@j, \'$[1]\', \'x\');\n+------------------------------------+\n| JSON_ARRAY_INSERT(@j, \'$[1]\', \'x\') |\n+------------------------------------+\n| ["a", "x", {"b": [1, 2]}, [3, 4]] |\n+------------------------------------+\nmysql> SELECT JSON_ARRAY_INSERT(@j, \'$[100]\', \'x\');\n+--------------------------------------+\n| JSON_ARRAY_INSERT(@j, \'$[100]\', \'x\') |\n+--------------------------------------+\n| ["a", {"b": [1, 2]}, [3, 4], "x"] |\n+--------------------------------------+\nmysql> SELECT JSON_ARRAY_INSERT(@j, \'$[1].b[0]\', \'x\');\n+-----------------------------------------+\n| JSON_ARRAY_INSERT(@j, \'$[1].b[0]\', \'x\') |\n+-----------------------------------------+\n| ["a", {"b": ["x", 1, 2]}, [3, 4]] |\n+-----------------------------------------+\nmysql> SELECT JSON_ARRAY_INSERT(@j, \'$[2][1]\', \'y\');\n+---------------------------------------+\n| JSON_ARRAY_INSERT(@j, \'$[2][1]\', \'y\') |\n+---------------------------------------+\n| ["a", {"b": [1, 2]}, [3, "y", 4]] |\n+---------------------------------------+\nmysql> SELECT JSON_ARRAY_INSERT(@j, \'$[0]\', \'x\', \'$[2][1]\', \'y\');\n+----------------------------------------------------+\n| JSON_ARRAY_INSERT(@j, \'$[0]\', \'x\', \'$[2][1]\', \'y\') |\n+----------------------------------------------------+\n| ["x", "a", {"b": [1, 2]}, [3, 4]] |\n+----------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (395,20,'<=>','Syntax:\n<=>\n\nNULL-safe equal. This operator performs an equality comparison like the\n= operator, but returns 1 rather than NULL if both operands are NULL,\nand 0 rather than NULL if one operand is NULL.\n\nThe <=> operator is equivalent to the standard SQL IS NOT DISTINCT FROM\noperator.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;\n -> 1, 1, 0\nmysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;\n -> 1, NULL, NULL\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (396,27,'RESET','Syntax:\nRESET reset_option [, reset_option] ...\n\nreset_option: {\n MASTER\n | QUERY CACHE\n | SLAVE\n}\n\nThe RESET statement is used to clear the state of various server\noperations. You must have the RELOAD privilege to execute RESET.\n\nRESET acts as a stronger version of the FLUSH statement. See [HELP\nFLUSH].\n\nThe RESET statement causes an implicit commit. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nIn MySQL 5.7.1, gtid_next must be set to AUTOMATIC before issuing this\nstatement. This restriction does not apply in MySQL 5.7.2 or later.\n(Bug #16062608, Bug #16715809, Bug #69045)\n\nThe following list describes the permitted RESET statement reset_option\nvalues:\n\no RESET MASTER\n\n Deletes all binary logs listed in the index file, resets the binary\n log index file to be empty, and creates a new binary log file.\n\no RESET QUERY CACHE\n\n Removes all query results from the query cache.\n\n *Note*:\n\n The query cache is deprecated as of MySQL 5.7.20, and is removed in\n MySQL 8.0. Deprecation includes RESET QUERY CACHE.\n\no RESET SLAVE\n\n Makes the slave forget its replication position in the master binary\n logs. Also resets the relay log by deleting any existing relay log\n files and beginning a new one.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/reset.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/reset.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (396,27,'RESET','Syntax:\nRESET reset_option [, reset_option] ...\n\nreset_option: {\n MASTER\n | QUERY CACHE\n | SLAVE\n}\n\nThe RESET statement is used to clear the state of various server\noperations. You must have the RELOAD privilege to execute RESET.\n\nRESET acts as a stronger version of the FLUSH statement. See [HELP\nFLUSH].\n\nThe RESET statement causes an implicit commit. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nThe following list describes the permitted RESET statement reset_option\nvalues:\n\no RESET MASTER\n\n Deletes all binary logs listed in the index file, resets the binary\n log index file to be empty, and creates a new binary log file.\n\no RESET QUERY CACHE\n\n Removes all query results from the query cache.\n\n *Note*:\n\n The query cache is deprecated as of MySQL 5.7.20, and is removed in\n MySQL 8.0. Deprecation includes RESET QUERY CACHE.\n\no RESET SLAVE\n\n Makes the slave forget its replication position in the master binary\n logs. Also resets the relay log by deleting any existing relay log\n files and beginning a new one.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/reset.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/reset.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (397,14,'GET_LOCK','Syntax:\nGET_LOCK(str,timeout)\n\nTries to obtain a lock with a name given by the string str, using a\ntimeout of timeout seconds. A negative timeout value means infinite\ntimeout. The lock is exclusive. While held by one session, other\nsessions cannot obtain a lock of the same name.\n\nReturns 1 if the lock was obtained successfully, 0 if the attempt timed\nout (for example, because another client has previously locked the\nname), or NULL if an error occurred (such as running out of memory or\nthe thread was killed with mysqladmin kill).\n\nA lock obtained with GET_LOCK() is released explicitly by executing\nRELEASE_LOCK() or implicitly when your session terminates (either\nnormally or abnormally). Lock release may also occur with another call\nto GET_LOCK():\n\no Before 5.7.5, only a single simultaneous lock can be acquired and\n GET_LOCK() releases any existing lock.\n\no In MySQL 5.7.5, GET_LOCK() was reimplemented using the metadata\n locking (MDL) subsystem and its capabilities were extended. Multiple\n simultaneous locks can be acquired and GET_LOCK() does not release\n any existing locks. It is even possible for a given session to\n acquire multiple locks for the same name. Other sessions cannot\n acquire a lock with that name until the acquiring session releases\n all its locks for the name.\n\n As a result of the MDL reimplementation, locks acquired with\n GET_LOCK() appear in the Performance Schema metadata_locks table. The\n OBJECT_TYPE column says USER LEVEL LOCK and the OBJECT_NAME column\n indicates the lock name. Also, the capability of acquiring multiple\n locks introduces the possibility of deadlock among clients. When this\n happens, the server chooses a caller and terminates its\n lock-acquisition request with an ER_USER_LOCK_DEADLOCK error. This\n error does not cause transactions to roll back.\n\nThe difference in lock acquisition behavior as of MySQL 5.7.5 can be\nseen by the following example. Suppose that you execute these\nstatements:\n\nSELECT GET_LOCK(\'lock1\',10);\nSELECT GET_LOCK(\'lock2\',10);\nSELECT RELEASE_LOCK(\'lock2\');\nSELECT RELEASE_LOCK(\'lock1\');\n\nIn MySQL 5.7.5 or later, the second GET_LOCK() acquires a second lock\nand both RELEASE_LOCK() calls return 1 (success). Before MySQL 5.7.5,\nthe second GET_LOCK() releases the first lock (\'lock1\') and the second\nRELEASE_LOCK() returns NULL (failure) because there is no \'lock1\' to\nrelease.\n\nMySQL 5.7.5 and later enforces a maximum length on lock names of 64\ncharacters. Previously, no limit was enforced.\n\nLocks obtained with GET_LOCK() are not released when transactions\ncommit or roll back.\n\nGET_LOCK() can be used to implement application locks or to simulate\nrecord locks. Names are locked on a server-wide basis. If a name has\nbeen locked within one session, GET_LOCK() blocks any request by\nanother session for a lock with the same name. This enables clients\nthat agree on a given lock name to use the name to perform cooperative\nadvisory locking. But be aware that it also enables a client that is\nnot among the set of cooperating clients to lock a name, either\ninadvertently or deliberately, and thus prevent any of the cooperating\nclients from locking that name. One way to reduce the likelihood of\nthis is to use lock names that are database-specific or\napplication-specific. For example, use lock names of the form\ndb_name.str or app_name.str.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (398,23,'BIGINT','BIGINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA large integer. The signed range is -9223372036854775808 to\n9223372036854775807. The unsigned range is 0 to 18446744073709551615.\n\nSERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (399,32,'CURTIME','Syntax:\nCURTIME([fsp])\n\nReturns the current time as a value in \'HH:MM:SS\' or HHMMSS format,\ndepending on whether the function is used in a string or numeric\ncontext. The value is expressed in the current time zone.\n\nIf the fsp argument is given to specify a fractional seconds precision\nfrom 0 to 6, the return value includes a fractional seconds part of\nthat many digits.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT CURTIME();\n -> \'23:50:26\'\nmysql> SELECT CURTIME() + 0;\n -> 235026.000000\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (400,37,'ST_DIMENSION','ST_Dimension(g)\n\nReturns the inherent dimension of the geometry value g, or NULL if the\nargument is NULL. The dimension can be −1, 0, 1, or 2. The meaning of\nthese values is given in\nhttp://dev.mysql.com/doc/refman/5.7/en/gis-class-geometry.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html\n\n','mysql> SELECT ST_Dimension(ST_GeomFromText(\'LineString(1 1,2 2)\'));\n+------------------------------------------------------+\n| ST_Dimension(ST_GeomFromText(\'LineString(1 1,2 2)\')) |\n+------------------------------------------------------+\n| 1 |\n+------------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (401,27,'SET','Syntax:\nSET variable_assignment [, variable_assignment] ...\n\nvariable_assignment:\n user_var_name = expr\n | param_name = expr\n | local_var_name = expr\n | [GLOBAL | SESSION]\n system_var_name = expr\n | [@@global. | @@session. | @@]\n system_var_name = expr\n\nSET syntax for variable assignment enables you to assign values to\ndifferent types of variables that affect the operation of the server or\nclients:\n\no System variables. See\n http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n System variables also can be set at server startup, as described in\n http://dev.mysql.com/doc/refman/5.7/en/using-system-variables.html.\n (To display system variable names and values, use the SHOW VARIABLES\n statement; see [HELP SHOW VARIABLES].)\n\no User-defined variables. See\n http://dev.mysql.com/doc/refman/5.7/en/user-variables.html.\n\no Stored procedure and function parameters, and stored program local\n variables. See\n http://dev.mysql.com/doc/refman/5.7/en/stored-program-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-variable.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-variable.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (401,27,'SET','Syntax:\nSET variable = expr [, variable = expr] ...\n\nvariable: {\n user_var_name\n | param_name\n | local_var_name\n | {GLOBAL | @@global.} system_var_name\n | [SESSION | @@session. | @@] system_var_name\n}\n\nSET syntax for variable assignment enables you to assign values to\ndifferent types of variables that affect the operation of the server or\nclients:\n\no User-defined variables. See\n http://dev.mysql.com/doc/refman/5.7/en/user-variables.html.\n\no Stored procedure and function parameters, and stored program local\n variables. See\n http://dev.mysql.com/doc/refman/5.7/en/stored-program-variables.html.\n\no System variables. See\n http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n System variables also can be set at server startup, as described in\n http://dev.mysql.com/doc/refman/5.7/en/using-system-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/set-variable.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/set-variable.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (402,7,'JSON_MERGE','Syntax:\nJSON_MERGE(json_doc, json_doc[, json_doc] ...)\n\nMerges two or more JSON documents. Synonym for JSON_MERGE_PRESERVE();\ndeprecated in MySQL 5.7.22 and subject to removal in a future release.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html\n\n','mysql> SELECT JSON_MERGE(\'[1, 2]\', \'[true, false]\');\n+---------------------------------------+\n| JSON_MERGE(\'[1, 2]\', \'[true, false]\') |\n+---------------------------------------+\n| [1, 2, true, false] |\n+---------------------------------------+\n1 row in set, 1 warning (0.00 sec)\n\nmysql> SHOW WARNINGS\\G\n*************************** 1. row ***************************\n Level: Warning\n Code: 1287\nMessage: \'JSON_MERGE\' is deprecated and will be removed in a future release. \\\n Please use JSON_MERGE_PRESERVE/JSON_MERGE_PATCH instead\n1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (403,28,'LOAD XML','Syntax:\nLOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE [db_name.]tbl_name\n [CHARACTER SET charset_name]\n [ROWS IDENTIFIED BY \'\']\n [IGNORE number {LINES | ROWS}]\n [(field_name_or_user_var\n [, field_name_or_user_var] ...)]\n [SET col_name={expr | DEFAULT},\n [, col_name={expr | DEFAULT}] ...]\n\nThe LOAD XML statement reads data from an XML file into a table. The\nfile_name must be given as a literal string. The tagname in the\noptional ROWS IDENTIFIED BY clause must also be given as a literal\nstring, and must be surrounded by angle brackets (< and >).\n\nLOAD XML acts as the complement of running the mysql client in XML\noutput mode (that is, starting the client with the --xml option). To\nwrite data from a table to an XML file, you can invoke the mysql client\nwith the --xml and -e options from the system shell, as shown here:\n\nshell> mysql --xml -e \'SELECT * FROM mydb.mytable\' > file.xml\n\nTo read the file back into a table, use LOAD XML INFILE. By default,\nthe element is considered to be the equivalent of a database\ntable row; this can be changed using the ROWS IDENTIFIED BY clause.\n\nThis statement supports three different XML formats:\n\no Column names as attributes and column values as attribute values:\n\n
\n\no Column names as tags and column values as the content of these tags:\n\n\n value1 \n value2 \n
\n\no Column names are the name attributes of tags, and values are\n the contents of these tags:\n\n\n value1 \n value2 \n
\n\n This is the format used by other MySQL tools, such as mysqldump.\n\nAll three formats can be used in the same XML file; the import routine\nautomatically detects the format for each row and interprets it\ncorrectly. Tags are matched based on the tag or attribute name and the\ncolumn name.\n\nThe following clauses work essentially the same way for LOAD XML as\nthey do for LOAD DATA:\n\no LOW_PRIORITY or CONCURRENT\n\no LOCAL\n\no REPLACE or IGNORE\n\no CHARACTER SET\n\no SET\n\nSee [HELP LOAD DATA], for more information about these clauses.\n\n(field_name_or_user_var, ...) is a list of one or more comma-separated\nXML fields or user variables. The name of a user variable used for this\npurpose must match the name of a field from the XML file, prefixed with\n@. You can use field names to select only desired fields. User\nvariables can be employed to store the corresponding field values for\nsubsequent re-use.\n\nThe IGNORE number LINES or IGNORE number ROWS clause causes the first\nnumber rows in the XML file to be skipped. It is analogous to the LOAD\nDATA statement\'s IGNORE ... LINES clause.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/load-xml.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/load-xml.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (404,3,'CONV','Syntax:\nCONV(N,from_base,to_base)\n\nConverts numbers between different number bases. Returns a string\nrepresentation of the number N, converted from base from_base to base\nto_base. Returns NULL if any argument is NULL. The argument N is\ninterpreted as an integer, but may be specified as an integer or a\nstring. The minimum base is 2 and the maximum base is 36. If from_base\nis a negative number, N is regarded as a signed number. Otherwise, N is\ntreated as unsigned. CONV() works with 64-bit precision.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT CONV(\'a\',16,2);\n -> \'1010\'\nmysql> SELECT CONV(\'6E\',18,8);\n -> \'172\'\nmysql> SELECT CONV(-17,10,-18);\n -> \'-H\'\nmysql> SELECT CONV(10+\'10\'+\'10\'+X\'0a\',10,10);\n -> \'40\'\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
@@ -489,11 +489,11 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (408,32,'EXTRACT','Syntax:\nEXTRACT(unit FROM date)\n\nThe EXTRACT() function uses the same kinds of unit specifiers as\nDATE_ADD() or DATE_SUB(), but extracts parts from the date rather than\nperforming date arithmetic.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT EXTRACT(YEAR FROM \'2009-07-02\');\n -> 2009\nmysql> SELECT EXTRACT(YEAR_MONTH FROM \'2009-07-02 01:02:03\');\n -> 200907\nmysql> SELECT EXTRACT(DAY_MINUTE FROM \'2009-07-02 01:02:03\');\n -> 20102\nmysql> SELECT EXTRACT(MICROSECOND\n -> FROM \'2003-01-02 10:30:00.000123\');\n -> 123\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (409,12,'ENCRYPT','Syntax:\nENCRYPT(str[,salt])\n\nEncrypts str using the Unix crypt() system call and returns a binary\nstring. The salt argument must be a string with at least two characters\nor the result will be NULL. If no salt argument is given, a random\nvalue is used.\n\n*Note*:\n\nThe ENCRYPT() function is deprecated as of MySQL 5.7.6, will be removed\nin a future MySQL release, and should no longer be used. For one-way\nhashing, consider using SHA2() instead.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SELECT ENCRYPT(\'hello\');\n -> \'VxuFAJXVARROc\'\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (410,27,'SHOW STATUS','Syntax:\nSHOW [GLOBAL | SESSION] STATUS\n [LIKE \'pattern\' | WHERE expr]\n\n*Note*:\n\nAs of MySQL 5.7.6, the value of the show_compatibility_56 system\nvariable affects the information available from and privileges required\nfor the statement described here. For details, see the description of\nthat variable in\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nSHOW STATUS provides server status information (see\nhttp://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html).\nThis statement does not require any privilege. It requires only the\nability to connect to the server.\n\nStatus variable information is also available from these sources:\n\no Performance Schema tables. See\n http://dev.mysql.com/doc/refman/5.7/en/performance-schema-status-vari\n able-tables.html.\n\no The GLOBAL_STATUS and SESSION_STATUS tables. See\n http://dev.mysql.com/doc/refman/5.7/en/status-table.html.\n\no The mysqladmin extended-status command. See\n http://dev.mysql.com/doc/refman/5.7/en/mysqladmin.html.\n\nFor SHOW STATUS, a LIKE clause, if present, indicates which variable\nnames to match. A WHERE clause can be given to select rows using more\ngeneral conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nSHOW STATUS accepts an optional GLOBAL or SESSION variable scope\nmodifier:\n\no With a GLOBAL modifier, the statement displays the global status\n values. A global status variable may represent status for some aspect\n of the server itself (for example, Aborted_connects), or the\n aggregated status over all connections to MySQL (for example,\n Bytes_received and Bytes_sent). If a variable has no global value,\n the session value is displayed.\n\no With a SESSION modifier, the statement displays the status variable\n values for the current connection. If a variable has no session\n value, the global value is displayed. LOCAL is a synonym for SESSION.\n\no If no modifier is present, the default is SESSION.\n\nThe scope for each status variable is listed at\nhttp://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html.\n\nEach invocation of the SHOW STATUS statement uses an internal temporary\ntable and increments the global Created_tmp_tables value.\nWith a LIKE clause, the statement displays only rows for those\nvariables with names that match the pattern:\n\nmysql> SHOW STATUS LIKE \'Key%\';\n+--------------------+----------+\n| Variable_name | Value |\n+--------------------+----------+\n| Key_blocks_used | 14955 |\n| Key_read_requests | 96854827 |\n| Key_reads | 162040 |\n| Key_write_requests | 7589728 |\n| Key_writes | 3813196 |\n+--------------------+----------+\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-status.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-status.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (411,2,'ST_NUMINTERIORRINGS','ST_NumInteriorRing(poly), ST_NumInteriorRings(poly)\n\nReturns the number of interior rings in the Polygon value poly. If the\nargument is NULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n -> \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nmysql> SELECT ST_NumInteriorRings(ST_GeomFromText(@poly));\n+---------------------------------------------+\n| ST_NumInteriorRings(ST_GeomFromText(@poly)) |\n+---------------------------------------------+\n| 1 |\n+---------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (411,2,'ST_NUMINTERIORRINGS','ST_NumInteriorRing(poly), ST_NumInteriorRings(poly)\n\nReturns the number of interior rings in the Polygon value poly. If the\nargument is NULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nmysql> SELECT ST_NumInteriorRings(ST_GeomFromText(@poly));\n+---------------------------------------------+\n| ST_NumInteriorRings(ST_GeomFromText(@poly)) |\n+---------------------------------------------+\n| 1 |\n+---------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (412,7,'JSON_KEYS','Syntax:\nJSON_KEYS(json_doc[, path])\n\nReturns the keys from the top-level value of a JSON object as a JSON\narray, or, if a path argument is given, the top-level keys from the\nselected path. Returns NULL if any argument is NULL, the json_doc\nargument is not an object, or path, if given, does not locate an\nobject. An error occurs if the json_doc argument is not a valid JSON\ndocument or the path argument is not a valid path expression or\ncontains a * or ** wildcard.\n\nThe result array is empty if the selected object is empty. If the\ntop-level value has nested subobjects, the return value does not\ninclude keys from those subobjects.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html\n\n','mysql> SELECT JSON_KEYS(\'{"a": 1, "b": {"c": 30}}\');\n+---------------------------------------+\n| JSON_KEYS(\'{"a": 1, "b": {"c": 30}}\') |\n+---------------------------------------+\n| ["a", "b"] |\n+---------------------------------------+\nmysql> SELECT JSON_KEYS(\'{"a": 1, "b": {"c": 30}}\', \'$.b\');\n+----------------------------------------------+\n| JSON_KEYS(\'{"a": 1, "b": {"c": 30}}\', \'$.b\') |\n+----------------------------------------------+\n| ["c"] |\n+----------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (413,14,'INET6_ATON','Syntax:\nINET6_ATON(expr)\n\nGiven an IPv6 or IPv4 network address as a string, returns a binary\nstring that represents the numeric value of the address in network byte\norder (big endian). Because numeric-format IPv6 addresses require more\nbytes than the largest integer type, the representation returned by\nthis function has the VARBINARY data type: VARBINARY(16) for IPv6\naddresses and VARBINARY(4) for IPv4 addresses. If the argument is not a\nvalid address, INET6_ATON() returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','mysql> SELECT HEX(INET6_ATON(\'fdfe::5a55:caff:fefa:9089\'));\n -> \'FDFE0000000000005A55CAFFFEFA9089\'\nmysql> SELECT HEX(INET6_ATON(\'10.0.5.9\'));\n -> \'0A000509\'\n','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (414,27,'SHOW SLAVE HOSTS','Syntax:\nSHOW SLAVE HOSTS\n\nDisplays a list of replication slaves currently registered with the\nmaster.\n\nSHOW SLAVE HOSTS should be executed on a server that acts as a\nreplication master. The statement displays information about servers\nthat are or have been connected as replication slaves, with each row of\nthe result corresponding to one slave server, as shown here:\n\nmysql> SHOW SLAVE HOSTS;\n+------------+-----------+------+-----------+--------------------------------------+\n| Server_id | Host | Port | Master_id | Slave_UUID |\n+------------+-----------+------+-----------+--------------------------------------+\n| 192168010 | iconnect2 | 3306 | 192168011 | 14cb6624-7f93-11e0-b2c0-c80aa9429562 |\n| 1921680101 | athena | 3306 | 192168011 | 07af4990-f41f-11df-a566-7ac56fdaf645 |\n+------------+-----------+------+-----------+--------------------------------------+\n\no Server_id: The unique server ID of the slave server, as configured in\n the slave server\'s option file, or on the command line with\n --server-id=value.\n\no Host: The host name of the slave server as specified on the slave\n with the --report-host option. This can differ from the machine name\n as configured in the operating system.\n\no User: The slave server user name as, specified on the slave with the\n --report-user option. Statement output includes this column only if\n the master server is started with the --show-slave-auth-info option.\n\no Password: The slave server password as, specified on the slave with\n the --report-password option. Statement output includes this column\n only if the master server is started with the --show-slave-auth-info\n option.\n\no Port: The port on the master to which the slave server is listening,\n as specified on the slave with the --report-port option.\n\n A zero in this column means that the slave port (--report-port) was\n not set.\n\no Master_id: The unique server ID of the master server that the slave\n server is replicating from. This is the server ID of the server on\n which SHOW SLAVE HOSTS is executed, so this same value is listed for\n each row in the result.\n\no Slave_UUID: The globally unique ID of this slave, as generated on the\n slave and found in the slave\'s auto.cnf file.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-slave-hosts.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-slave-hosts.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (415,8,'START TRANSACTION','Syntax:\nSTART TRANSACTION\n [transaction_characteristic [, transaction_characteristic] ...]\n\ntransaction_characteristic:\n WITH CONSISTENT SNAPSHOT\n | READ WRITE\n | READ ONLY\n\nBEGIN [WORK]\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nSET autocommit = {0 | 1}\n\nThese statements provide control over use of transactions:\n\no START TRANSACTION or BEGIN start a new transaction.\n\no COMMIT commits the current transaction, making its changes permanent.\n\no ROLLBACK rolls back the current transaction, canceling its changes.\n\no SET autocommit disables or enables the default autocommit mode for\n the current session.\n\nBy default, MySQL runs with autocommit mode enabled. This means that as\nsoon as you execute a statement that updates (modifies) a table, MySQL\nstores the update on disk to make it permanent. The change cannot be\nrolled back.\n\nTo disable autocommit mode implicitly for a single series of\nstatements, use the START TRANSACTION statement:\n\nSTART TRANSACTION;\nSELECT @A:=SUM(salary) FROM table1 WHERE type=1;\nUPDATE table2 SET summary=@A WHERE type=1;\nCOMMIT;\n\nWith START TRANSACTION, autocommit remains disabled until you end the\ntransaction with COMMIT or ROLLBACK. The autocommit mode then reverts\nto its previous state.\n\nSTART TRANSACTION permits several modifiers that control transaction\ncharacteristics. To specify multiple modifiers, separate them by\ncommas.\n\no The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for\n storage engines that are capable of it. This applies only to InnoDB.\n The effect is the same as issuing a START TRANSACTION followed by a\n SELECT from any InnoDB table. See\n http://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html.\n The WITH CONSISTENT SNAPSHOT modifier does not change the current\n transaction isolation level, so it provides a consistent snapshot\n only if the current isolation level is one that permits a consistent\n read. The only isolation level that permits a consistent read is\n REPEATABLE READ. For all other isolation levels, the WITH CONSISTENT\n SNAPSHOT clause is ignored. As of MySQL 5.7.2, a warning is generated\n when the WITH CONSISTENT SNAPSHOT clause is ignored.\n\no The READ WRITE and READ ONLY modifiers set the transaction access\n mode. They permit or prohibit changes to tables used in the\n transaction. The READ ONLY restriction prevents the transaction from\n modifying or locking both transactional and nontransactional tables\n that are visible to other transactions; the transaction can still\n modify or lock temporary tables.\n\n MySQL enables extra optimizations for queries on InnoDB tables when\n the transaction is known to be read-only. Specifying READ ONLY\n ensures these optimizations are applied in cases where the read-only\n status cannot be determined automatically. See\n http://dev.mysql.com/doc/refman/5.7/en/innodb-performance-ro-txn.html\n for more information.\n\n If no access mode is specified, the default mode applies. Unless the\n default has been changed, it is read/write. It is not permitted to\n specify both READ WRITE and READ ONLY in the same statement.\n\n In read-only mode, it remains possible to change tables created with\n the TEMPORARY keyword using DML statements. Changes made with DDL\n statements are not permitted, just as with permanent tables.\n\n For additional information about transaction access mode, including\n ways to change the default mode, see [HELP ISOLATION].\n\n If the read_only system variable is enabled, explicitly starting a\n transaction with START TRANSACTION READ WRITE requires the SUPER\n privilege.\n\n*Important*:\n\nMany APIs used for writing MySQL client applications (such as JDBC)\nprovide their own methods for starting transactions that can (and\nsometimes should) be used instead of sending a START TRANSACTION\nstatement from the client. See\nhttp://dev.mysql.com/doc/refman/5.7/en/connectors-apis.html, or the\ndocumentation for your API, for more information.\n\nTo disable autocommit mode explicitly, use the following statement:\n\nSET autocommit=0;\n\nAfter disabling autocommit mode by setting the autocommit variable to\nzero, changes to transaction-safe tables (such as those for InnoDB or\nNDB) are not made permanent immediately. You must use COMMIT to store\nyour changes to disk or ROLLBACK to ignore the changes.\n\nautocommit is a session variable and must be set for each session. To\ndisable autocommit mode for each new connection, see the description of\nthe autocommit system variable at\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nBEGIN and BEGIN WORK are supported as aliases of START TRANSACTION for\ninitiating a transaction. START TRANSACTION is standard SQL syntax, is\nthe recommended way to start an ad-hoc transaction, and permits\nmodifiers that BEGIN does not.\n\nThe BEGIN statement differs from the use of the BEGIN keyword that\nstarts a BEGIN ... END compound statement. The latter does not begin a\ntransaction. See [HELP BEGIN END].\n\n*Note*:\n\nWithin all stored programs (stored procedures and functions, triggers,\nand events), the parser treats BEGIN [WORK] as the beginning of a BEGIN\n... END block. Begin a transaction in this context with START\nTRANSACTION instead.\n\nThe optional WORK keyword is supported for COMMIT and ROLLBACK, as are\nthe CHAIN and RELEASE clauses. CHAIN and RELEASE can be used for\nadditional control over transaction completion. The value of the\ncompletion_type system variable determines the default completion\nbehavior. See\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nThe AND CHAIN clause causes a new transaction to begin as soon as the\ncurrent one ends, and the new transaction has the same isolation level\nas the just-terminated transaction. The new transaction also uses the\nsame access mode (READ WRITE or READ ONLY) as the just-terminated\ntransaction. The RELEASE clause causes the server to disconnect the\ncurrent client session after terminating the current transaction.\nIncluding the NO keyword suppresses CHAIN or RELEASE completion, which\ncan be useful if the completion_type system variable is set to cause\nchaining or release completion by default.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/commit.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/commit.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (415,8,'START TRANSACTION','Syntax:\nSTART TRANSACTION\n [transaction_characteristic [, transaction_characteristic] ...]\n\ntransaction_characteristic: {\n WITH CONSISTENT SNAPSHOT\n | READ WRITE\n | READ ONLY\n}\n\nBEGIN [WORK]\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nSET autocommit = {0 | 1}\n\nThese statements provide control over use of transactions:\n\no START TRANSACTION or BEGIN start a new transaction.\n\no COMMIT commits the current transaction, making its changes permanent.\n\no ROLLBACK rolls back the current transaction, canceling its changes.\n\no SET autocommit disables or enables the default autocommit mode for\n the current session.\n\nBy default, MySQL runs with autocommit mode enabled. This means that as\nsoon as you execute a statement that updates (modifies) a table, MySQL\nstores the update on disk to make it permanent. The change cannot be\nrolled back.\n\nTo disable autocommit mode implicitly for a single series of\nstatements, use the START TRANSACTION statement:\n\nSTART TRANSACTION;\nSELECT @A:=SUM(salary) FROM table1 WHERE type=1;\nUPDATE table2 SET summary=@A WHERE type=1;\nCOMMIT;\n\nWith START TRANSACTION, autocommit remains disabled until you end the\ntransaction with COMMIT or ROLLBACK. The autocommit mode then reverts\nto its previous state.\n\nSTART TRANSACTION permits several modifiers that control transaction\ncharacteristics. To specify multiple modifiers, separate them by\ncommas.\n\no The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for\n storage engines that are capable of it. This applies only to InnoDB.\n The effect is the same as issuing a START TRANSACTION followed by a\n SELECT from any InnoDB table. See\n http://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html.\n The WITH CONSISTENT SNAPSHOT modifier does not change the current\n transaction isolation level, so it provides a consistent snapshot\n only if the current isolation level is one that permits a consistent\n read. The only isolation level that permits a consistent read is\n REPEATABLE READ. For all other isolation levels, the WITH CONSISTENT\n SNAPSHOT clause is ignored. As of MySQL 5.7.2, a warning is generated\n when the WITH CONSISTENT SNAPSHOT clause is ignored.\n\no The READ WRITE and READ ONLY modifiers set the transaction access\n mode. They permit or prohibit changes to tables used in the\n transaction. The READ ONLY restriction prevents the transaction from\n modifying or locking both transactional and nontransactional tables\n that are visible to other transactions; the transaction can still\n modify or lock temporary tables.\n\n MySQL enables extra optimizations for queries on InnoDB tables when\n the transaction is known to be read-only. Specifying READ ONLY\n ensures these optimizations are applied in cases where the read-only\n status cannot be determined automatically. See\n http://dev.mysql.com/doc/refman/5.7/en/innodb-performance-ro-txn.html\n for more information.\n\n If no access mode is specified, the default mode applies. Unless the\n default has been changed, it is read/write. It is not permitted to\n specify both READ WRITE and READ ONLY in the same statement.\n\n In read-only mode, it remains possible to change tables created with\n the TEMPORARY keyword using DML statements. Changes made with DDL\n statements are not permitted, just as with permanent tables.\n\n For additional information about transaction access mode, including\n ways to change the default mode, see [HELP ISOLATION].\n\n If the read_only system variable is enabled, explicitly starting a\n transaction with START TRANSACTION READ WRITE requires the SUPER\n privilege.\n\n*Important*:\n\nMany APIs used for writing MySQL client applications (such as JDBC)\nprovide their own methods for starting transactions that can (and\nsometimes should) be used instead of sending a START TRANSACTION\nstatement from the client. See\nhttp://dev.mysql.com/doc/refman/5.7/en/connectors-apis.html, or the\ndocumentation for your API, for more information.\n\nTo disable autocommit mode explicitly, use the following statement:\n\nSET autocommit=0;\n\nAfter disabling autocommit mode by setting the autocommit variable to\nzero, changes to transaction-safe tables (such as those for InnoDB or\nNDB) are not made permanent immediately. You must use COMMIT to store\nyour changes to disk or ROLLBACK to ignore the changes.\n\nautocommit is a session variable and must be set for each session. To\ndisable autocommit mode for each new connection, see the description of\nthe autocommit system variable at\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nBEGIN and BEGIN WORK are supported as aliases of START TRANSACTION for\ninitiating a transaction. START TRANSACTION is standard SQL syntax, is\nthe recommended way to start an ad-hoc transaction, and permits\nmodifiers that BEGIN does not.\n\nThe BEGIN statement differs from the use of the BEGIN keyword that\nstarts a BEGIN ... END compound statement. The latter does not begin a\ntransaction. See [HELP BEGIN END].\n\n*Note*:\n\nWithin all stored programs (stored procedures and functions, triggers,\nand events), the parser treats BEGIN [WORK] as the beginning of a BEGIN\n... END block. Begin a transaction in this context with START\nTRANSACTION instead.\n\nThe optional WORK keyword is supported for COMMIT and ROLLBACK, as are\nthe CHAIN and RELEASE clauses. CHAIN and RELEASE can be used for\nadditional control over transaction completion. The value of the\ncompletion_type system variable determines the default completion\nbehavior. See\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nThe AND CHAIN clause causes a new transaction to begin as soon as the\ncurrent one ends, and the new transaction has the same isolation level\nas the just-terminated transaction. The new transaction also uses the\nsame access mode (READ WRITE or READ ONLY) as the just-terminated\ntransaction. The RELEASE clause causes the server to disconnect the\ncurrent client session after terminating the current transaction.\nIncluding the NO keyword suppresses CHAIN or RELEASE completion, which\ncan be useful if the completion_type system variable is set to cause\nchaining or release completion by default.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/commit.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/commit.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (416,32,'TIME_FORMAT','Syntax:\nTIME_FORMAT(time,format)\n\nThis is used like the DATE_FORMAT() function, but the format string may\ncontain format specifiers only for hours, minutes, seconds, and\nmicroseconds. Other specifiers produce a NULL value or 0.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT TIME_FORMAT(\'100:00:00\', \'%H %k %h %I %l\');\n -> \'100 100 04 04 4\'\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (417,40,'CREATE DATABASE','Syntax:\nCREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name\n [create_specification] ...\n\ncreate_specification:\n [DEFAULT] CHARACTER SET [=] charset_name\n | [DEFAULT] COLLATE [=] collation_name\n\nCREATE DATABASE creates a database with the given name. To use this\nstatement, you need the CREATE privilege for the database. CREATE\nSCHEMA is a synonym for CREATE DATABASE.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-database.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-database.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (418,16,'VAR_POP','Syntax:\nVAR_POP(expr)\n\nReturns the population standard variance of expr. It considers rows as\nthe whole population, not as a sample, so it has the number of rows as\nthe denominator. You can also use VARIANCE(), which is equivalent but\nis not standard SQL.\n\nIf there are no matching rows, VAR_POP() returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
@@ -515,10 +515,10 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (434,24,'DECLARE CONDITION','Syntax:\nDECLARE condition_name CONDITION FOR condition_value\n\ncondition_value:\n mysql_error_code\n | SQLSTATE [VALUE] sqlstate_value\n\nThe DECLARE ... CONDITION statement declares a named error condition,\nassociating a name with a condition that needs specific handling. The\nname can be referred to in a subsequent DECLARE ... HANDLER statement\n(see [HELP DECLARE HANDLER]).\n\nCondition declarations must appear before cursor or handler\ndeclarations.\n\nThe condition_value for DECLARE ... CONDITION indicates the specific\ncondition or class of conditions to associate with the condition name.\nIt can take the following forms:\n\no mysql_error_code: An integer literal indicating a MySQL error code.\n\n Do not use MySQL error code 0 because that indicates success rather\n than an error condition. For a list of MySQL error codes, see\n http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html.\n\no SQLSTATE [VALUE] sqlstate_value: A 5-character string literal\n indicating an SQLSTATE value.\n\n Do not use SQLSTATE values that begin with \'00\' because those\n indicate success rather than an error condition. For a list of\n SQLSTATE values, see\n http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html.\n\nCondition names referred to in SIGNAL or use RESIGNAL statements must\nbe associated with SQLSTATE values, not MySQL error codes.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/declare-condition.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/declare-condition.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (435,32,'MONTHNAME','Syntax:\nMONTHNAME(date)\n\nReturns the full name of the month for date. The language used for the\nname is controlled by the value of the lc_time_names system variable\n(http://dev.mysql.com/doc/refman/5.7/en/locale-support.html).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT MONTHNAME(\'2008-02-03\');\n -> \'February\'\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (436,26,'NUMGEOMETRIES','NumGeometries(gc)\n\nST_NumGeometries() and NumGeometries() are synonyms. For more\ninformation, see the description of ST_NumGeometries().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-geometrycollection-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-geometrycollection-property-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (437,8,'CHANGE MASTER TO','Syntax:\nCHANGE MASTER TO option [, option] ... [ channel_option ]\n\noption:\n MASTER_BIND = \'interface_name\'\n | MASTER_HOST = \'host_name\'\n | MASTER_USER = \'user_name\'\n | MASTER_PASSWORD = \'password\'\n | MASTER_PORT = port_num\n | MASTER_CONNECT_RETRY = interval\n | MASTER_RETRY_COUNT = count\n | MASTER_DELAY = interval\n | MASTER_HEARTBEAT_PERIOD = interval\n | MASTER_LOG_FILE = \'master_log_name\'\n | MASTER_LOG_POS = master_log_pos\n | MASTER_AUTO_POSITION = {0|1}\n | RELAY_LOG_FILE = \'relay_log_name\'\n | RELAY_LOG_POS = relay_log_pos\n | MASTER_SSL = {0|1}\n | MASTER_SSL_CA = \'ca_file_name\'\n | MASTER_SSL_CAPATH = \'ca_directory_name\'\n | MASTER_SSL_CERT = \'cert_file_name\'\n | MASTER_SSL_CRL = \'crl_file_name\'\n | MASTER_SSL_CRLPATH = \'crl_directory_name\'\n | MASTER_SSL_KEY = \'key_file_name\'\n | MASTER_SSL_CIPHER = \'cipher_list\'\n | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}\n | MASTER_TLS_VERSION = \'protocol_list\'\n | IGNORE_SERVER_IDS = (server_id_list)\n\nchannel_option:\n FOR CHANNEL channel\n\nserver_id_list:\n [server_id [, server_id] ... ]\n\nCHANGE MASTER TO changes the parameters that the slave server uses for\nconnecting to the master server, for reading the master binary log, and\nreading the slave relay log. It also updates the contents of the master\ninfo and relay log info repositories (see\nhttp://dev.mysql.com/doc/refman/5.7/en/slave-logs.html). CHANGE MASTER\nTO requires the SUPER privilege.\n\nPrior to MySQL 5.7.4, the slave replication threads must be stopped,\nusing STOP SLAVE if necessary, before issuing this statement. In MySQL\n5.7.4 and later, you can issue CHANGE MASTER TO statements on a running\nslave without doing this, depending on the states of the slave SQL\nthread and slave I/O thread. The rules governing such use are provided\nlater in this section.\n\nWhen using a multithreaded slave (in other words slave_parallel_workers\nis greater than 0), stopping the slave can cause "gaps" in the sequence\nof transactions that have been executed from the relay log, regardless\nof whether the slave was stopped intentionally or otherwise. When such\ngaps exist, issuing CHANGE MASTER TO fails. The solution in this\nsituation is to issue START SLAVE UNTIL SQL_AFTER_MTS_GAPS which\nensures that the gaps are closed.\n\nThe optional FOR CHANNEL channel clause enables you to name which\nreplication channel the statement applies to. Providing a FOR CHANNEL\nchannel clause applies the CHANGE MASTER TO statement to a specific\nreplication channel, and is used to add a new channel or modify an\nexisting channel. For example, to add a new channel called channel2:\n\nCHANGE MASTER TO MASTER_HOST=host1, MASTER_PORT=3002 FOR CHANNEL \'channel2\'\n\nIf no clause is named and no extra channels exist, the statement\napplies to the default channel.\n\nWhen using multiple replication channels, if a CHANGE MASTER TO\nstatement does not name a channel using a FOR CHANNEL channel clause,\nan error occurs. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information.\n\nOptions not specified retain their value, except as indicated in the\nfollowing discussion. Thus, in most cases, there is no need to specify\noptions that do not change. For example, if the password to connect to\nyour MySQL master has changed, issue this statement to tell the slave\nabout the new password:\n\nCHANGE MASTER TO MASTER_PASSWORD=\'new3cret\';\n\nMASTER_HOST, MASTER_USER, MASTER_PASSWORD, and MASTER_PORT provide\ninformation to the slave about how to connect to its master:\n\no MASTER_HOST and MASTER_PORT are the host name (or IP address) of the\n master host and its TCP/IP port.\n\n *Note*:\n\n Replication cannot use Unix socket files. You must be able to connect\n to the master MySQL server using TCP/IP.\n\n If you specify the MASTER_HOST or MASTER_PORT option, the slave\n assumes that the master server is different from before (even if the\n option value is the same as its current value.) In this case, the old\n values for the master binary log file name and position are\n considered no longer applicable, so if you do not specify\n MASTER_LOG_FILE and MASTER_LOG_POS in the statement,\n MASTER_LOG_FILE=\'\' and MASTER_LOG_POS=4 are silently appended to it.\n\n Setting MASTER_HOST=\'\' (that is, setting its value explicitly to an\n empty string) is not the same as not setting MASTER_HOST at all.\n Beginning with MySQL 5.5, trying to set MASTER_HOST to an empty\n string fails with an error. Previously, setting MASTER_HOST to an\n empty string caused START SLAVE subsequently to fail. (Bug #28796)\n\n Values used for MASTER_HOST and other CHANGE MASTER TO options are\n checked for linefeed (\\n or 0x0A) characters; the presence of such\n characters in these values causes the statement to fail with\n ER_MASTER_INFO. (Bug #11758581, Bug #50801)\n\no MASTER_USER and MASTER_PASSWORD are the user name and password of the\n account to use for connecting to the master.\n\n MASTER_USER cannot be made empty; setting MASTER_USER = \'\' or leaving\n it unset when setting a value for MASTER_PASSWORD causes an error\n (Bug #13427949).\n\n The password used for a MySQL Replication slave account in a CHANGE\n MASTER TO statement is limited to 32 characters in length; prior to\n MySQL 5.7.5, if the password was longer, the statement succeeded, but\n any excess characters were silently truncated. In MySQL 5.7.5 and\n later, trying to use a password of more than 32 characters causes\n CHANGE MASTER TO to fail. (Bug #11752299, Bug #43439)\n\n The text of a running CHANGE MASTER TO statement, including values\n for MASTER_USER and MASTER_PASSWORD, can be seen in the output of a\n concurrent SHOW PROCESSLIST statement. (The complete text of a START\n SLAVE statement is also visible to SHOW PROCESSLIST.)\n\nThe MASTER_SSL_xxx options, and the MASTER_TLS_VERSION option, specify\nhow the slave uses encryption and ciphers to secure the replication\nconnection. These options can be changed even on slaves that are\ncompiled without SSL support. They are saved to the master info\nrepository, but are ignored if the slave does not have SSL support\nenabled. The MASTER_SSL_xxx options perform the same functions as the\n--ssl-xxx options described in\nhttp://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-options.htm\nl. The correspondence between the two sets of options, and the use of\nthe MASTER_SSL_xxx and MASTER_TLS_VERSION options to set up a secure\nconnection, is explained in\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-solutions-encrypted-\nconnections.html.\n\nAs of MySQL 5.7.3, setting MASTER_SSL=1 means that the slave connection\nto the master must use SSL, or the connection attempt fails. Before\n5.7.3, the use of an SSL connection by the slave was not enforced with\nMASTER_SSL=1. This is analogous to the client-side meaning of the --ssl\ncommand-line option; see\nhttp://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-options.htm\nl.\n\nMASTER_CONNECT_RETRY specifies how many seconds to wait between connect\nretries. The default is 60.\n\nMASTER_RETRY_COUNT limits the number of reconnection attempts and\nupdates the value of the Master_Retry_Count column in the output of\nSHOW SLAVE STATUS. The default value is 24 * 3600 = 86400.\nMASTER_RETRY_COUNT is intended to replace the older\n--master-retry-count server option, and is now the preferred method for\nsetting this limit. You are encouraged not to rely on\n--master-retry-count in new applications and, when upgrading from\nversions earlier than MySQL 5.6, to update any existing applications\nthat rely on it, so that they use CHANGE MASTER TO ...\nMASTER_RETRY_COUNT instead.\n\nMASTER_DELAY specifies how many seconds behind the master the slave\nmust lag. An event received from the master is not executed until at\nleast interval seconds later than its execution on the master. The\ndefault is 0. An error occurs if interval is not a nonnegative integer\nin the range from 0 to 231−1. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-delayed.html.\n\nFrom MySQL 5.7, a CHANGE MASTER TO statement employing the MASTER_DELAY\noption can be executed on a running slave when the slave SQL thread is\nstopped.\n\nMASTER_BIND is for use on replication slaves having multiple network\ninterfaces, and determines which of the slave\'s network interfaces is\nchosen for connecting to the master.\n\nThe address configured with this option, if any, can be seen in the\nMaster_Bind column of the output from SHOW SLAVE STATUS. If you are\nusing slave status log tables (server started with\n--master-info-repository=TABLE), the value can also be seen as the\nMaster_bind column of the mysql.slave_master_info table.\n\nThe ability to bind a replication slave to a specific network interface\nis also supported by NDB Cluster.\n\nMASTER_HEARTBEAT_PERIOD sets the interval in seconds between\nreplication heartbeats. Whenever the master\'s binary log is updated\nwith an event, the waiting period for the next heartbeat is reset.\ninterval is a decimal value having the range 0 to 4294967 seconds and a\nresolution in milliseconds; the smallest nonzero value is 0.001.\nHeartbeats are sent by the master only if there are no unsent events in\nthe binary log file for a period longer than interval.\n\nPrior to MySQL 5.7.4, not including MASTER_HEARTBEAT_PERIOD caused\nCHANGE MASTER TO to reset the heartbeat period (Slave_heartbeat_period)\nto the default, and Slave_received_heartbeats to 0. (Bug #18185490)\n\nIf you are logging master connection information to tables,\nMASTER_HEARTBEAT_PERIOD can be seen as the value of the Heartbeat\ncolumn of the mysql.slave_master_info table.\n\nSetting interval to 0 disables heartbeats altogether. The default value\nfor interval is equal to the value of slave_net_timeout divided by 2.\n\nSetting @@global.slave_net_timeout to a value less than that of the\ncurrent heartbeat interval results in a warning being issued. The\neffect of issuing RESET SLAVE on the heartbeat interval is to reset it\nto the default value.\n\nMASTER_LOG_FILE and MASTER_LOG_POS are the coordinates at which the\nslave I/O thread should begin reading from the master the next time the\nthread starts. RELAY_LOG_FILE and RELAY_LOG_POS are the coordinates at\nwhich the slave SQL thread should begin reading from the relay log the\nnext time the thread starts. If you specify either of MASTER_LOG_FILE\nor MASTER_LOG_POS, you cannot specify RELAY_LOG_FILE or RELAY_LOG_POS.\nIf you specify either of MASTER_LOG_FILE or MASTER_LOG_POS, you also\ncannot specify MASTER_AUTO_POSITION = 1 (described later in this\nsection). If neither of MASTER_LOG_FILE or MASTER_LOG_POS is specified,\nthe slave uses the last coordinates of the slave SQL thread before\nCHANGE MASTER TO was issued. This ensures that there is no\ndiscontinuity in replication, even if the slave SQL thread was late\ncompared to the slave I/O thread, when you merely want to change, say,\nthe password to use.\n\nFrom MySQL 5.7, a CHANGE MASTER TO statement employing RELAY_LOG_FILE,\nRELAY_LOG_POS, or both options can be executed on a running slave when\nthe slave SQL thread is stopped.\n\nIf MASTER_AUTO_POSITION = 1 is used with CHANGE MASTER TO, the slave\nattempts to connect to the master using the GTID-based replication\nprotocol. From MySQL 5.7, this option can be employed by CHANGE MASTER\nTO only if both the slave SQL and slave I/O threads are stopped.\n\nWhen using GTIDs, the slave tells the master which transactions it has\nalready received, executed, or both. To compute this set, it reads the\nglobal value of gtid_executed and the value of the Retrieved_gtid_set\ncolumn from SHOW SLAVE STATUS. The GTID of the last transmitted\ntransaction is included in Retrieved_gtid_set only when the full\ntransaction is received. The slave computes the following set:\n\nUNION(@@global.gtid_executed, Retrieved_gtid_set)\n\nPrior to MySQL 5.7.5, the GTID of the last transmitted transaction was\nincluded in Retrieved_gtid_set even if the transaction was only\npartially transmitted, and the last received GTID was subtracted from\nthis set. (Bug #17943188) Thus, the slave computed the following set:\n\nUNION(@@global.gtid_executed, Retrieved_gtid_set - last_received_GTID)\n\nThis set is sent to the master as part of the initial handshake, and\nthe master sends back all transactions that it has executed which are\nnot part of the set. If any of these transactions have been already\npurged from the master\'s binary log, the master sends the error\nER_MASTER_HAS_PURGED_REQUIRED_GTIDS to the slave, and replication does\nnot start.\n\nWhen GTID-based replication is employed, the coordinates represented by\nMASTER_LOG_FILE and MASTER_LOG_POS are not used, and global transaction\nidentifiers are used instead. Thus the use of either or both of these\noptions together with MASTER_AUTO_POSITION causes an error.\n\nYou can see whether replication is running with autopositioning enabled\nby checking the output of SHOW SLAVE STATUS. (Bug #15992220)\n\ngtid_mode must also be enabled before issuing CHANGE MASTER TO ...\nMASTER_AUTO_POSITION = 1. Otherwise, the statement fails with an error.\n\nTo revert to the older file-based replication protocol after using\nGTIDs, you can issue a new CHANGE MASTER TO statement that specifies\nMASTER_AUTO_POSITION = 0, as well as at least one of MASTER_LOG_FILE or\nMASTER_LOG_POS.\n\nPrior to MySQL 5.7.4, CHANGE MASTER TO deletes all relay log files and\nstarts a new one, unless you specify RELAY_LOG_FILE or RELAY_LOG_POS.\nIn that case, relay log files are kept; the relay_log_purge global\nvariable is set silently to 0. In MySQL 5.7.4 and later, relay logs are\npreserved if at least one of the slave SQL thread and the slave I/O\nthread is running; if both threads are stopped, all relay log files are\ndeleted unless at least one of RELAY_LOG_FILE or RELAY_LOG_POS is\nspecified.\n\nRELAY_LOG_FILE can use either an absolute or relative path, and uses\nthe same base name as MASTER_LOG_FILE. (Bug #12190)\n\nIGNORE_SERVER_IDS takes a comma-separated list of 0 or more server IDs.\nEvents originating from the corresponding servers are ignored, with the\nexception of log rotation and deletion events, which are still recorded\nin the relay log.\n\nIn circular replication, the originating server normally acts as the\nterminator of its own events, so that they are not applied more than\nonce. Thus, this option is useful in circular replication when one of\nthe servers in the circle is removed. Suppose that you have a circular\nreplication setup with 4 servers, having server IDs 1, 2, 3, and 4, and\nserver 3 fails. When bridging the gap by starting replication from\nserver 2 to server 4, you can include IGNORE_SERVER_IDS = (3) in the\nCHANGE MASTER TO statement that you issue on server 4 to tell it to use\nserver 2 as its master instead of server 3. Doing so causes it to\nignore and not to propagate any statements that originated with the\nserver that is no longer in use.\n\nIf a CHANGE MASTER TO statement is issued without any IGNORE_SERVER_IDS\noption, any existing list is preserved. To clear the list of ignored\nservers, it is necessary to use the option with an empty list:\n\nCHANGE MASTER TO IGNORE_SERVER_IDS = ();\n\nPrior to MySQL 5.7.5, RESET SLAVE ALL has no effect on the server ID\nlist. In MySQL 5.7.5 and later, RESET SLAVE ALL clears\nIGNORE_SERVER_IDS. (Bug #18816897)\n\nIf IGNORE_SERVER_IDS contains the server\'s own ID and the server was\nstarted with the --replicate-same-server-id option enabled, an error\nresults.\n\nThe master info repository and the output of SHOW SLAVE STATUS provide\nthe list of servers that are currently ignored. For more information,\nsee http://dev.mysql.com/doc/refman/5.7/en/slave-logs-status.html, and\n[HELP SHOW SLAVE STATUS].\n\nInvoking CHANGE MASTER TO causes the previous values for MASTER_HOST,\nMASTER_PORT, MASTER_LOG_FILE, and MASTER_LOG_POS to be written to the\nerror log, along with other information about the slave\'s state prior\nto execution.\n\nCHANGE MASTER TO causes an implicit commit of an ongoing transaction.\nSee http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nIn MySQL 5.7.4 and later, the strict requirement to execute STOP SLAVE\nprior to issuing any CHANGE MASTER TO statement (and START SLAVE\nafterward) is removed. Instead of depending on whether the slave is\nstopped, the behavior of CHANGE MASTER TO depends (in MySQL 5.7.4 and\nlater) on the states of the slave SQL thread and slave I/O threads;\nwhich of these threads is stopped or running now determines the options\nthat can or cannot be used with a CHANGE MASTER TO statement at a given\npoint in time. The rules for making this determination are listed here:\n\no If the SQL thread is stopped, you can execute CHANGE MASTER TO using\n any combination that is otherwise allowed of RELAY_LOG_FILE,\n RELAY_LOG_POS, and MASTER_DELAY options, even if the slave I/O thread\n is running. No other options may be used with this statement when the\n I/O thread is running.\n\no If the I/O thread is stopped, you can execute CHANGE MASTER TO using\n any of the options for this statement (in any allowed combination)\n except RELAY_LOG_FILE, RELAY_LOG_POS, or MASTER_DELAY, even when the\n SQL thread is running. These three options may not be used when the\n I/O thread is running.\n\no Both the SQL thread and the I/O thread must be stopped before issuing\n a CHANGE MASTER TO statement that employs MASTER_AUTO_POSITION = 1.\n\nYou can check the current state of the slave SQL and I/O threads using\nSHOW SLAVE STATUS.\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-solutions-switch.htm\nl.\n\nIf you are using statement-based replication and temporary tables, it\nis possible for a CHANGE MASTER TO statement following a STOP SLAVE\nstatement to leave behind temporary tables on the slave. From MySQL\n5.7, a warning (ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO) is issued\nwhenever this occurs. You can avoid this in such cases by making sure\nthat the value of the Slave_open_temp_tables system status variable is\nequal to 0 prior to executing such a CHANGE MASTER TO statement.\n\nCHANGE MASTER TO is useful for setting up a slave when you have the\nsnapshot of the master and have recorded the master binary log\ncoordinates corresponding to the time of the snapshot. After loading\nthe snapshot into the slave to synchronize it with the master, you can\nrun CHANGE MASTER TO MASTER_LOG_FILE=\'log_name\', MASTER_LOG_POS=log_pos\non the slave to specify the coordinates at which the slave should begin\nreading the master binary log.\n\nThe following example changes the master server the slave uses and\nestablishes the master binary log coordinates from which the slave\nbegins reading. This is used when you want to set up the slave to\nreplicate the master:\n\nCHANGE MASTER TO\n MASTER_HOST=\'master2.example.com\',\n MASTER_USER=\'replication\',\n MASTER_PASSWORD=\'password\',\n MASTER_PORT=3306,\n MASTER_LOG_FILE=\'master2-bin.001\',\n MASTER_LOG_POS=4,\n MASTER_CONNECT_RETRY=10;\n\nThe next example shows an operation that is less frequently employed.\nIt is used when the slave has relay log files that you want it to\nexecute again for some reason. To do this, the master need not be\nreachable. You need only use CHANGE MASTER TO and start the SQL thread\n(START SLAVE SQL_THREAD):\n\nCHANGE MASTER TO\n RELAY_LOG_FILE=\'slave-relay-bin.006\',\n RELAY_LOG_POS=4025;\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/change-master-to.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/change-master-to.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (437,8,'CHANGE MASTER TO','Syntax:\nCHANGE MASTER TO option [, option] ... [ channel_option ]\n\noption:\n MASTER_BIND = \'interface_name\'\n | MASTER_HOST = \'host_name\'\n | MASTER_USER = \'user_name\'\n | MASTER_PASSWORD = \'password\'\n | MASTER_PORT = port_num\n | MASTER_CONNECT_RETRY = interval\n | MASTER_RETRY_COUNT = count\n | MASTER_DELAY = interval\n | MASTER_HEARTBEAT_PERIOD = interval\n | MASTER_LOG_FILE = \'master_log_name\'\n | MASTER_LOG_POS = master_log_pos\n | MASTER_AUTO_POSITION = {0|1}\n | RELAY_LOG_FILE = \'relay_log_name\'\n | RELAY_LOG_POS = relay_log_pos\n | MASTER_SSL = {0|1}\n | MASTER_SSL_CA = \'ca_file_name\'\n | MASTER_SSL_CAPATH = \'ca_directory_name\'\n | MASTER_SSL_CERT = \'cert_file_name\'\n | MASTER_SSL_CRL = \'crl_file_name\'\n | MASTER_SSL_CRLPATH = \'crl_directory_name\'\n | MASTER_SSL_KEY = \'key_file_name\'\n | MASTER_SSL_CIPHER = \'cipher_list\'\n | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}\n | MASTER_TLS_VERSION = \'protocol_list\'\n | IGNORE_SERVER_IDS = (server_id_list)\n\nchannel_option:\n FOR CHANNEL channel\n\nserver_id_list:\n [server_id [, server_id] ... ]\n\nCHANGE MASTER TO changes the parameters that the slave server uses for\nconnecting to the master server, for reading the master binary log, and\nreading the slave relay log. It also updates the contents of the master\ninfo and relay log info repositories (see\nhttp://dev.mysql.com/doc/refman/5.7/en/slave-logs.html). CHANGE MASTER\nTO requires the SUPER privilege.\n\nPrior to MySQL 5.7.4, the slave replication threads must be stopped,\nusing STOP SLAVE if necessary, before issuing this statement. In MySQL\n5.7.4 and later, you can issue CHANGE MASTER TO statements on a running\nslave without doing this, depending on the states of the slave SQL\nthread and slave I/O thread. The rules governing such use are provided\nlater in this section.\n\nWhen using a multithreaded slave (in other words slave_parallel_workers\nis greater than 0), stopping the slave can cause "gaps" in the sequence\nof transactions that have been executed from the relay log, regardless\nof whether the slave was stopped intentionally or otherwise. When such\ngaps exist, issuing CHANGE MASTER TO fails. The solution in this\nsituation is to issue START SLAVE UNTIL SQL_AFTER_MTS_GAPS which\nensures that the gaps are closed.\n\nThe optional FOR CHANNEL channel clause enables you to name which\nreplication channel the statement applies to. Providing a FOR CHANNEL\nchannel clause applies the CHANGE MASTER TO statement to a specific\nreplication channel, and is used to add a new channel or modify an\nexisting channel. For example, to add a new channel called channel2:\n\nCHANGE MASTER TO MASTER_HOST=host1, MASTER_PORT=3002 FOR CHANNEL \'channel2\'\n\nIf no clause is named and no extra channels exist, the statement\napplies to the default channel.\n\nWhen using multiple replication channels, if a CHANGE MASTER TO\nstatement does not name a channel using a FOR CHANNEL channel clause,\nan error occurs. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information.\n\nOptions not specified retain their value, except as indicated in the\nfollowing discussion. Thus, in most cases, there is no need to specify\noptions that do not change. For example, if the password to connect to\nyour MySQL master has changed, issue this statement to tell the slave\nabout the new password:\n\nCHANGE MASTER TO MASTER_PASSWORD=\'new3cret\';\n\nMASTER_HOST, MASTER_USER, MASTER_PASSWORD, and MASTER_PORT provide\ninformation to the slave about how to connect to its master:\n\no MASTER_HOST and MASTER_PORT are the host name (or IP address) of the\n master host and its TCP/IP port.\n\n *Note*:\n\n Replication cannot use Unix socket files. You must be able to connect\n to the master MySQL server using TCP/IP.\n\n If you specify the MASTER_HOST or MASTER_PORT option, the slave\n assumes that the master server is different from before (even if the\n option value is the same as its current value.) In this case, the old\n values for the master binary log file name and position are\n considered no longer applicable, so if you do not specify\n MASTER_LOG_FILE and MASTER_LOG_POS in the statement,\n MASTER_LOG_FILE=\'\' and MASTER_LOG_POS=4 are silently appended to it.\n\n Setting MASTER_HOST=\'\' (that is, setting its value explicitly to an\n empty string) is not the same as not setting MASTER_HOST at all.\n Beginning with MySQL 5.5, trying to set MASTER_HOST to an empty\n string fails with an error. Previously, setting MASTER_HOST to an\n empty string caused START SLAVE subsequently to fail. (Bug #28796)\n\n Values used for MASTER_HOST and other CHANGE MASTER TO options are\n checked for linefeed (\\n or 0x0A) characters; the presence of such\n characters in these values causes the statement to fail with\n ER_MASTER_INFO. (Bug #11758581, Bug #50801)\n\no MASTER_USER and MASTER_PASSWORD are the user name and password of the\n account to use for connecting to the master.\n\n MASTER_USER cannot be made empty; setting MASTER_USER = \'\' or leaving\n it unset when setting a value for MASTER_PASSWORD causes an error\n (Bug #13427949).\n\n The password used for a MySQL Replication slave account in a CHANGE\n MASTER TO statement is limited to 32 characters in length; prior to\n MySQL 5.7.5, if the password was longer, the statement succeeded, but\n any excess characters were silently truncated. In MySQL 5.7.5 and\n later, trying to use a password of more than 32 characters causes\n CHANGE MASTER TO to fail. (Bug #11752299, Bug #43439)\n\n The text of a running CHANGE MASTER TO statement, including values\n for MASTER_USER and MASTER_PASSWORD, can be seen in the output of a\n concurrent SHOW PROCESSLIST statement. (The complete text of a START\n SLAVE statement is also visible to SHOW PROCESSLIST.)\n\nThe MASTER_SSL_xxx options, and the MASTER_TLS_VERSION option, specify\nhow the slave uses encryption and ciphers to secure the replication\nconnection. These options can be changed even on slaves that are\ncompiled without SSL support. They are saved to the master info\nrepository, but are ignored if the slave does not have SSL support\nenabled. The MASTER_SSL_xxx options perform the same functions as the\n--ssl-xxx options described in\nhttp://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-options.htm\nl. The correspondence between the two sets of options, and the use of\nthe MASTER_SSL_xxx and MASTER_TLS_VERSION options to set up a secure\nconnection, is explained in\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-solutions-encrypted-\nconnections.html.\n\nAs of MySQL 5.7.3, setting MASTER_SSL=1 means that the slave connection\nto the master must use SSL, or the connection attempt fails. Before\n5.7.3, the use of an SSL connection by the slave was not enforced with\nMASTER_SSL=1. This is analogous to the client-side meaning of the --ssl\ncommand-line option; see\nhttp://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-options.htm\nl.\n\nMASTER_CONNECT_RETRY specifies how many seconds to wait between connect\nretries. The default is 60.\n\nMASTER_RETRY_COUNT limits the number of reconnection attempts and\nupdates the value of the Master_Retry_Count column in the output of\nSHOW SLAVE STATUS. The default value is 24 * 3600 = 86400.\nMASTER_RETRY_COUNT is intended to replace the older\n--master-retry-count server option, and is now the preferred method for\nsetting this limit. You are encouraged not to rely on\n--master-retry-count in new applications and, when upgrading from\nversions earlier than MySQL 5.6, to update any existing applications\nthat rely on it, so that they use CHANGE MASTER TO ...\nMASTER_RETRY_COUNT instead.\n\nMASTER_DELAY specifies how many seconds behind the master the slave\nmust lag. An event received from the master is not executed until at\nleast interval seconds later than its execution on the master. The\ndefault is 0. An error occurs if interval is not a nonnegative integer\nin the range from 0 to 231−1. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-delayed.html.\n\nFrom MySQL 5.7, a CHANGE MASTER TO statement employing the MASTER_DELAY\noption can be executed on a running slave when the slave SQL thread is\nstopped.\n\nMASTER_BIND is for use on replication slaves having multiple network\ninterfaces, and determines which of the slave\'s network interfaces is\nchosen for connecting to the master.\n\nThe address configured with this option, if any, can be seen in the\nMaster_Bind column of the output from SHOW SLAVE STATUS. If you are\nusing slave status log tables (server started with\n--master-info-repository=TABLE), the value can also be seen as the\nMaster_bind column of the mysql.slave_master_info table.\n\nThe ability to bind a replication slave to a specific network interface\nis also supported by NDB Cluster.\n\nMASTER_HEARTBEAT_PERIOD sets the interval in seconds between\nreplication heartbeats. Whenever the master\'s binary log is updated\nwith an event, the waiting period for the next heartbeat is reset.\ninterval is a decimal value having the range 0 to 4294967 seconds and a\nresolution in milliseconds; the smallest nonzero value is 0.001.\nHeartbeats are sent by the master only if there are no unsent events in\nthe binary log file for a period longer than interval.\n\nPrior to MySQL 5.7.4, not including MASTER_HEARTBEAT_PERIOD caused\nCHANGE MASTER TO to reset the heartbeat period (Slave_heartbeat_period)\nto the default, and Slave_received_heartbeats to 0. (Bug #18185490)\n\nIf you are logging master connection information to tables,\nMASTER_HEARTBEAT_PERIOD can be seen as the value of the Heartbeat\ncolumn of the mysql.slave_master_info table.\n\nSetting interval to 0 disables heartbeats altogether. The default value\nfor interval is equal to the value of slave_net_timeout divided by 2.\n\nSetting @@global.slave_net_timeout to a value less than that of the\ncurrent heartbeat interval results in a warning being issued. The\neffect of issuing RESET SLAVE on the heartbeat interval is to reset it\nto the default value.\n\nMASTER_LOG_FILE and MASTER_LOG_POS are the coordinates at which the\nslave I/O thread should begin reading from the master the next time the\nthread starts. RELAY_LOG_FILE and RELAY_LOG_POS are the coordinates at\nwhich the slave SQL thread should begin reading from the relay log the\nnext time the thread starts. If you specify either of MASTER_LOG_FILE\nor MASTER_LOG_POS, you cannot specify RELAY_LOG_FILE or RELAY_LOG_POS.\nIf you specify either of MASTER_LOG_FILE or MASTER_LOG_POS, you also\ncannot specify MASTER_AUTO_POSITION = 1 (described later in this\nsection). If neither of MASTER_LOG_FILE or MASTER_LOG_POS is specified,\nthe slave uses the last coordinates of the slave SQL thread before\nCHANGE MASTER TO was issued. This ensures that there is no\ndiscontinuity in replication, even if the slave SQL thread was late\ncompared to the slave I/O thread, when you merely want to change, say,\nthe password to use.\n\nFrom MySQL 5.7, a CHANGE MASTER TO statement employing RELAY_LOG_FILE,\nRELAY_LOG_POS, or both options can be executed on a running slave when\nthe slave SQL thread is stopped. Prior to MySQL 5.7.4, CHANGE MASTER TO\ndeletes all relay log files and starts a new one, unless you specify\nRELAY_LOG_FILE or RELAY_LOG_POS. In that case, relay log files are\nkept; the relay_log_purge global variable is set silently to 0. In\nMySQL 5.7.4 and later, relay logs are preserved if at least one of the\nslave SQL thread and the slave I/O thread is running; if both threads\nare stopped, all relay log files are deleted unless at least one of\nRELAY_LOG_FILE or RELAY_LOG_POS is specified.\n\nRELAY_LOG_FILE can use either an absolute or relative path, and uses\nthe same base name as MASTER_LOG_FILE. (Bug #12190)\n\nWhen MASTER_AUTO_POSITION = 1 is used with CHANGE MASTER TO, the slave\nattempts to connect to the master using the GTID-based replication\nprotocol. From MySQL 5.7, this option can be employed by CHANGE MASTER\nTO only if both the slave SQL and slave I/O threads are stopped. Both\nthe slave and the master must have GTIDs enabled (GTID_MODE=ON,\nON_PERMISSIVE, or OFF_PERMISSIVE on the slave, and GTID_MODE=ON on the\nmaster). Auto-positioning is used for the connection, so the\ncoordinates represented by MASTER_LOG_FILE and MASTER_LOG_POS are not\nused, and the use of either or both of these options together with\nMASTER_AUTO_POSITION = 1 causes an error. If multi-source replication\nis enabled on the slave, you need to set the MASTER_AUTO_POSITION = 1\noption for each applicable replication channel.\n\nWith MASTER_AUTO_POSITION = 1 set, in the initial connection handshake,\nthe slave sends a GTID set containing the transactions that it has\nalready received, committed, or both. The master responds by sending\nall transactions recorded in its binary log whose GTID is not included\nin the GTID set sent by the slave. This exchange ensures that the\nmaster only sends the transactions with a GTID that the slave has not\nalready recorded or committed. If the slave receives transactions from\nmore than one master, as in the case of a diamond topology, the\nauto-skip function ensures that the transactions are not applied twice.\nFor details of how the GTID set sent by the slave is computed, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-gtids-auto-positioni\nng.html.\n\nIf any of the transactions that should be sent by the master have been\npurged from the master\'s binary log, or added to the set of GTIDs in\nthe gtid_purged system variable by another method, the master sends the\nerror ER_MASTER_HAS_PURGED_REQUIRED_GTIDS to the slave, and replication\ndoes not start. Also, if during the exchange of transactions it is\nfound that the slave has recorded or committed transactions with the\nmaster\'s UUID in the GTID, but the master itself has not committed\nthem, the master sends the error ER_SLAVE_HAS_MORE_GTIDS_THAN_MASTER to\nthe slave and replication does not start. For information on how to\nhandle these situations, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-gtids-auto-positioni\nng.html.\n\nYou can see whether replication is running with auto-positioning\nenabled by checking the Performance Schema\nreplication_connection_status table or the output of SHOW SLAVE STATUS.\nDisabling the MASTER_AUTO_POSITION option again makes the slave revert\nto file-based replication, in which case you must also specify one or\nboth of the MASTER_LOG_FILE or MASTER_LOG_POS options.\n\nIGNORE_SERVER_IDS takes a comma-separated list of 0 or more server IDs.\nEvents originating from the corresponding servers are ignored, with the\nexception of log rotation and deletion events, which are still recorded\nin the relay log.\n\nIn circular replication, the originating server normally acts as the\nterminator of its own events, so that they are not applied more than\nonce. Thus, this option is useful in circular replication when one of\nthe servers in the circle is removed. Suppose that you have a circular\nreplication setup with 4 servers, having server IDs 1, 2, 3, and 4, and\nserver 3 fails. When bridging the gap by starting replication from\nserver 2 to server 4, you can include IGNORE_SERVER_IDS = (3) in the\nCHANGE MASTER TO statement that you issue on server 4 to tell it to use\nserver 2 as its master instead of server 3. Doing so causes it to\nignore and not to propagate any statements that originated with the\nserver that is no longer in use.\n\nIf a CHANGE MASTER TO statement is issued without any IGNORE_SERVER_IDS\noption, any existing list is preserved. To clear the list of ignored\nservers, it is necessary to use the option with an empty list:\n\nCHANGE MASTER TO IGNORE_SERVER_IDS = ();\n\nPrior to MySQL 5.7.5, RESET SLAVE ALL has no effect on the server ID\nlist. In MySQL 5.7.5 and later, RESET SLAVE ALL clears\nIGNORE_SERVER_IDS. (Bug #18816897)\n\nIf IGNORE_SERVER_IDS contains the server\'s own ID and the server was\nstarted with the --replicate-same-server-id option enabled, an error\nresults.\n\nThe master info repository and the output of SHOW SLAVE STATUS provide\nthe list of servers that are currently ignored. For more information,\nsee http://dev.mysql.com/doc/refman/5.7/en/slave-logs-status.html, and\n[HELP SHOW SLAVE STATUS].\n\nInvoking CHANGE MASTER TO causes the previous values for MASTER_HOST,\nMASTER_PORT, MASTER_LOG_FILE, and MASTER_LOG_POS to be written to the\nerror log, along with other information about the slave\'s state prior\nto execution.\n\nCHANGE MASTER TO causes an implicit commit of an ongoing transaction.\nSee http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\nIn MySQL 5.7.4 and later, the strict requirement to execute STOP SLAVE\nprior to issuing any CHANGE MASTER TO statement (and START SLAVE\nafterward) is removed. Instead of depending on whether the slave is\nstopped, the behavior of CHANGE MASTER TO depends (in MySQL 5.7.4 and\nlater) on the states of the slave SQL thread and slave I/O threads;\nwhich of these threads is stopped or running now determines the options\nthat can or cannot be used with a CHANGE MASTER TO statement at a given\npoint in time. The rules for making this determination are listed here:\n\no If the SQL thread is stopped, you can execute CHANGE MASTER TO using\n any combination that is otherwise allowed of RELAY_LOG_FILE,\n RELAY_LOG_POS, and MASTER_DELAY options, even if the slave I/O thread\n is running. No other options may be used with this statement when the\n I/O thread is running.\n\no If the I/O thread is stopped, you can execute CHANGE MASTER TO using\n any of the options for this statement (in any allowed combination)\n except RELAY_LOG_FILE, RELAY_LOG_POS, or MASTER_DELAY, even when the\n SQL thread is running. These three options may not be used when the\n I/O thread is running.\n\no Both the SQL thread and the I/O thread must be stopped before issuing\n a CHANGE MASTER TO statement that employs MASTER_AUTO_POSITION = 1.\n\nYou can check the current state of the slave SQL and I/O threads using\nSHOW SLAVE STATUS.\n\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-solutions-switch.htm\nl.\n\nIf you are using statement-based replication and temporary tables, it\nis possible for a CHANGE MASTER TO statement following a STOP SLAVE\nstatement to leave behind temporary tables on the slave. From MySQL\n5.7, a warning (ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO) is issued\nwhenever this occurs. You can avoid this in such cases by making sure\nthat the value of the Slave_open_temp_tables system status variable is\nequal to 0 prior to executing such a CHANGE MASTER TO statement.\n\nCHANGE MASTER TO is useful for setting up a slave when you have the\nsnapshot of the master and have recorded the master binary log\ncoordinates corresponding to the time of the snapshot. After loading\nthe snapshot into the slave to synchronize it with the master, you can\nrun CHANGE MASTER TO MASTER_LOG_FILE=\'log_name\', MASTER_LOG_POS=log_pos\non the slave to specify the coordinates at which the slave should begin\nreading the master binary log.\n\nThe following example changes the master server the slave uses and\nestablishes the master binary log coordinates from which the slave\nbegins reading. This is used when you want to set up the slave to\nreplicate the master:\n\nCHANGE MASTER TO\n MASTER_HOST=\'master2.example.com\',\n MASTER_USER=\'replication\',\n MASTER_PASSWORD=\'password\',\n MASTER_PORT=3306,\n MASTER_LOG_FILE=\'master2-bin.001\',\n MASTER_LOG_POS=4,\n MASTER_CONNECT_RETRY=10;\n\nThe next example shows an operation that is less frequently employed.\nIt is used when the slave has relay log files that you want it to\nexecute again for some reason. To do this, the master need not be\nreachable. You need only use CHANGE MASTER TO and start the SQL thread\n(START SLAVE SQL_THREAD):\n\nCHANGE MASTER TO\n RELAY_LOG_FILE=\'slave-relay-bin.006\',\n RELAY_LOG_POS=4025;\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/change-master-to.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/change-master-to.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (438,32,'TIMESTAMP FUNCTION','Syntax:\nTIMESTAMP(expr), TIMESTAMP(expr1,expr2)\n\nWith a single argument, this function returns the date or datetime\nexpression expr as a datetime value. With two arguments, it adds the\ntime expression expr2 to the date or datetime expression expr1 and\nreturns the result as a datetime value.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT TIMESTAMP(\'2003-12-31\');\n -> \'2003-12-31 00:00:00\'\nmysql> SELECT TIMESTAMP(\'2003-12-31 12:00:00\',\'12:00:00\');\n -> \'2004-01-01 00:00:00\'\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (439,40,'DROP DATABASE','Syntax:\nDROP {DATABASE | SCHEMA} [IF EXISTS] db_name\n\nDROP DATABASE drops all tables in the database and deletes the\ndatabase. Be very careful with this statement! To use DROP DATABASE,\nyou need the DROP privilege on the database. DROP SCHEMA is a synonym\nfor DROP DATABASE.\n\n*Important*:\n\nWhen a database is dropped, privileges granted specifically for the\ndatabase are not automatically dropped. They must be dropped manually.\nSee [HELP GRANT].\n\nIF EXISTS is used to prevent an error from occurring if the database\ndoes not exist.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-database.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-database.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (440,27,'SHOW GRANTS','Syntax:\nSHOW GRANTS [FOR user]\n\nThis statement displays the privileges that are assigned to a MySQL\nuser account, in the form of GRANT statements that must be executed to\nduplicate the privilege assignments.\n\n*Note*:\n\nTo display nonprivilege information for MySQL accounts, use the SHOW\nCREATE USER statement. See [HELP SHOW CREATE USER].\n\nSHOW GRANTS requires the SELECT privilege for the mysql database,\nexcept to display privileges for the current user.\n\nTo name the account for SHOW GRANTS, use the same format as for the\nGRANT statement; for example, \'jeffrey\'@\'localhost\':\n\nmysql> SHOW GRANTS FOR \'jeffrey\'@\'localhost\';\n+------------------------------------------------------------------+\n| Grants for jeffrey@localhost |\n+------------------------------------------------------------------+\n| GRANT USAGE ON *.* TO `jeffrey`@`localhost` |\n| GRANT SELECT, INSERT, UPDATE ON `db1`.* TO `jeffrey`@`localhost` |\n+------------------------------------------------------------------+\n\nThe host part, if omitted, defaults to \'%\'. For additional information\nabout specifying account names, see\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html.\n\nTo display the privileges granted to the current user (the account you\nare using to connect to the server), you can use any of the following\nstatements:\n\nSHOW GRANTS;\nSHOW GRANTS FOR CURRENT_USER;\nSHOW GRANTS FOR CURRENT_USER();\n\nIf SHOW GRANTS FOR CURRENT_USER (or any of the equivalent syntaxes) is\nused in definer context, such as within a stored procedure that\nexecutes with definer rather than invoker privileges), the grants\ndisplayed are those of the definer and not the invoker.\n\nSHOW GRANTS does not display privileges that are available to the named\naccount but are granted to a different account. For example, if an\nanonymous account exists, the named account might be able to use its\nprivileges, but SHOW GRANTS does not display them.\n\nSHOW GRANTS output does not include IDENTIFIED BY PASSWORD clauses. Use\nthe SHOW CREATE USER statement instead. See [HELP SHOW CREATE USER].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-grants.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-grants.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (440,27,'SHOW GRANTS','Syntax:\nSHOW GRANTS [FOR user]\n\nThis statement displays the privileges that are assigned to a MySQL\nuser account, in the form of GRANT statements that must be executed to\nduplicate the privilege assignments.\n\n*Note*:\n\nTo display nonprivilege information for MySQL accounts, use the SHOW\nCREATE USER statement. See [HELP SHOW CREATE USER].\n\nSHOW GRANTS requires the SELECT privilege for the mysql system\ndatabase, except to display privileges for the current user.\n\nTo name the account for SHOW GRANTS, use the same format as for the\nGRANT statement; for example, \'jeffrey\'@\'localhost\':\n\nmysql> SHOW GRANTS FOR \'jeffrey\'@\'localhost\';\n+------------------------------------------------------------------+\n| Grants for jeffrey@localhost |\n+------------------------------------------------------------------+\n| GRANT USAGE ON *.* TO `jeffrey`@`localhost` |\n| GRANT SELECT, INSERT, UPDATE ON `db1`.* TO `jeffrey`@`localhost` |\n+------------------------------------------------------------------+\n\nThe host part, if omitted, defaults to \'%\'. For additional information\nabout specifying account names, see\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html.\n\nTo display the privileges granted to the current user (the account you\nare using to connect to the server), you can use any of the following\nstatements:\n\nSHOW GRANTS;\nSHOW GRANTS FOR CURRENT_USER;\nSHOW GRANTS FOR CURRENT_USER();\n\nIf SHOW GRANTS FOR CURRENT_USER (or any of the equivalent syntaxes) is\nused in definer context, such as within a stored procedure that\nexecutes with definer rather than invoker privileges, the grants\ndisplayed are those of the definer and not the invoker.\n\nSHOW GRANTS does not display privileges that are available to the named\naccount but are granted to a different account. For example, if an\nanonymous account exists, the named account might be able to use its\nprivileges, but SHOW GRANTS does not display them.\n\nSHOW GRANTS output does not include IDENTIFIED BY PASSWORD clauses. Use\nthe SHOW CREATE USER statement instead. See [HELP SHOW CREATE USER].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-grants.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-grants.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (441,7,'JSON_CONTAINS_PATH','Syntax:\nJSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)\n\nReturns 0 or 1 to indicate whether a JSON document contains data at a\ngiven path or paths. Returns NULL if any argument is NULL. An error\noccurs if the json_doc argument is not a valid JSON document, any path\nargument is not a valid path expression, or one_or_all is not \'one\' or\n\'all\'.\n\nTo check for a specific value at a path, use JSON_CONTAINS() instead.\n\nThe return value is 0 if no specified path exists within the document.\nOtherwise, the return value depends on the one_or_all argument:\n\no \'one\': 1 if at least one path exists within the document, 0\n otherwise.\n\no \'all\': 1 if all paths exist within the document, 0 otherwise.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html\n\n','mysql> SET @j = \'{"a": 1, "b": 2, "c": {"d": 4}}\';\nmysql> SELECT JSON_CONTAINS_PATH(@j, \'one\', \'$.a\', \'$.e\');\n+---------------------------------------------+\n| JSON_CONTAINS_PATH(@j, \'one\', \'$.a\', \'$.e\') |\n+---------------------------------------------+\n| 1 |\n+---------------------------------------------+\nmysql> SELECT JSON_CONTAINS_PATH(@j, \'all\', \'$.a\', \'$.e\');\n+---------------------------------------------+\n| JSON_CONTAINS_PATH(@j, \'all\', \'$.a\', \'$.e\') |\n+---------------------------------------------+\n| 0 |\n+---------------------------------------------+\nmysql> SELECT JSON_CONTAINS_PATH(@j, \'one\', \'$.c.d\');\n+----------------------------------------+\n| JSON_CONTAINS_PATH(@j, \'one\', \'$.c.d\') |\n+----------------------------------------+\n| 1 |\n+----------------------------------------+\nmysql> SELECT JSON_CONTAINS_PATH(@j, \'one\', \'$.a.d\');\n+----------------------------------------+\n| JSON_CONTAINS_PATH(@j, \'one\', \'$.a.d\') |\n+----------------------------------------+\n| 0 |\n+----------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (442,33,'ST_MPOINTFROMWKB','ST_MPointFromWKB(wkb[, srid]), ST_MultiPointFromWKB(wkb[, srid])\n\nConstructs a MultiPoint value using its WKB representation and SRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (443,3,'CRC32','Syntax:\nCRC32(expr)\n\nComputes a cyclic redundancy check value and returns a 32-bit unsigned\nvalue. The result is NULL if the argument is NULL. The argument is\nexpected to be a string and (if possible) is treated as one if it is\nnot.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT CRC32(\'MySQL\');\n -> 3259397556\nmysql> SELECT CRC32(\'mysql\');\n -> 2501908538\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
@@ -536,7 +536,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (455,32,'DAYOFMONTH','Syntax:\nDAYOFMONTH(date)\n\nReturns the day of the month for date, in the range 1 to 31, or 0 for\ndates such as \'0000-00-00\' or \'2008-00-00\' that have a zero day part.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT DAYOFMONTH(\'2007-02-03\');\n -> 3\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (456,32,'UNIX_TIMESTAMP','Syntax:\nUNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)\n\nIf called with no argument, returns a Unix timestamp (seconds since\n\'1970-01-01 00:00:00\' UTC). The return value is an integer if no\nargument is given or the argument does not include a fractional seconds\npart, or DECIMAL if an argument is given that includes a fractional\nseconds part.\n\nIf UNIX_TIMESTAMP() is called with a date argument, it returns the\nvalue of the argument as seconds since \'1970-01-01 00:00:00\' UTC. The\ndate argument may be a DATE, DATETIME, or TIMESTAMP string, or a number\nin YYMMDD, YYMMDDHHMMSS, YYYYMMDD, or YYYYMMDDHHMMSS format. If the\nargument includes a time part, it may optionally include a fractional\nseconds part. The server interprets date as a value in the current time\nzone and converts it to an internal value in UTC. Clients can set their\ntime zone as described in\nhttp://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT UNIX_TIMESTAMP();\n -> 1447431666\nmysql> SELECT UNIX_TIMESTAMP(\'2015-11-13 10:20:19\');\n -> 1447431619\nmysql> SELECT UNIX_TIMESTAMP(\'2015-11-13 10:20:19.012\');\n -> 1447431619.012\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (457,26,'ST_INTERSECTION','ST_Intersection(g1, g2)\n\nReturns a geometry that represents the point set intersection of the\ngeometry values g1 and g2. If any argument is NULL, the return value is\nNULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html\n\n','mysql> SET @g1 = ST_GeomFromText(\'LineString(1 1, 3 3)\');\nmysql> SET @g2 = ST_GeomFromText(\'LineString(1 3, 3 1)\');\nmysql> SELECT ST_AsText(ST_Intersection(@g1, @g2));\n+--------------------------------------+\n| ST_AsText(ST_Intersection(@g1, @g2)) |\n+--------------------------------------+\n| POINT(2 2) |\n+--------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (458,10,'RENAME USER','Syntax:\nRENAME USER old_user TO new_user\n [, old_user TO new_user] ...\n\nThe RENAME USER statement renames existing MySQL accounts. An error\noccurs for old accounts that do not exist or new accounts that already\nexist.\n\nTo use RENAME USER, you must have the global CREATE USER privilege, or\nthe UPDATE privilege for the mysql database. When the read_only system\nvariable is enabled, RENAME USER additionally requires the SUPER\nprivilege.\n\nEach account name uses the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. For example:\n\nRENAME USER \'jeffrey\'@\'localhost\' TO \'jeff\'@\'127.0.0.1\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nRENAME USER causes the privileges held by the old user to be those held\nby the new user. However, RENAME USER does not automatically drop or\ninvalidate databases or objects within them that the old user created.\nThis includes stored programs or views for which the DEFINER attribute\nnames the old user. Attempts to access such objects may produce an\nerror if they execute in definer security context. (For information\nabout security context, see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-security.html.)\n\nThe privilege changes take effect as indicated in\nhttp://dev.mysql.com/doc/refman/5.7/en/privilege-changes.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/rename-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/rename-user.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (458,10,'RENAME USER','Syntax:\nRENAME USER old_user TO new_user\n [, old_user TO new_user] ...\n\nThe RENAME USER statement renames existing MySQL accounts. An error\noccurs for old accounts that do not exist or new accounts that already\nexist.\n\nTo use RENAME USER, you must have the global CREATE USER privilege, or\nthe UPDATE privilege for the mysql system database. When the read_only\nsystem variable is enabled, RENAME USER additionally requires the SUPER\nprivilege.\n\nEach account name uses the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. For example:\n\nRENAME USER \'jeffrey\'@\'localhost\' TO \'jeff\'@\'127.0.0.1\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nRENAME USER causes the privileges held by the old user to be those held\nby the new user. However, RENAME USER does not automatically drop or\ninvalidate databases or objects within them that the old user created.\nThis includes stored programs or views for which the DEFINER attribute\nnames the old user. Attempts to access such objects may produce an\nerror if they execute in definer security context. (For information\nabout security context, see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-security.html.)\n\nThe privilege changes take effect as indicated in\nhttp://dev.mysql.com/doc/refman/5.7/en/privilege-changes.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/rename-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/rename-user.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (459,13,'NUMPOINTS','NumPoints(ls)\n\nST_NumPoints() and NumPoints() are synonyms. For more information, see\nthe description of ST_NumPoints().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (460,40,'ALTER LOGFILE GROUP','Syntax:\nALTER LOGFILE GROUP logfile_group\n ADD UNDOFILE \'file_name\'\n [INITIAL_SIZE [=] size]\n [WAIT]\n ENGINE [=] engine_name\n\nThis statement adds an UNDO file named \'file_name\' to an existing log\nfile group logfile_group. An ALTER LOGFILE GROUP statement has one and\nonly one ADD UNDOFILE clause. No DROP UNDOFILE clause is currently\nsupported.\n\n*Note*:\n\nAll NDB Cluster Disk Data objects share the same namespace. This means\nthat each Disk Data object must be uniquely named (and not merely each\nDisk Data object of a given type). For example, you cannot have a\ntablespace and an undo log file with the same name, or an undo log file\nand a data file with the same name.\n\nThe optional INITIAL_SIZE parameter sets the UNDO file\'s initial size\nin bytes; if not specified, the initial size defaults to 134217728 (128\nMB). You may optionally follow size with a one-letter abbreviation for\nan order of magnitude, similar to those used in my.cnf. Generally, this\nis one of the letters M (megabytes) or G (gigabytes). (Bug #13116514,\nBug #16104705, Bug #62858)\n\nOn 32-bit systems, the maximum supported value for INITIAL_SIZE is\n4294967296 (4 GB). (Bug #29186)\n\nThe minimum allowed value for INITIAL_SIZE is 1048576 (1 MB). (Bug\n#29574)\n\n*Note*:\n\nWAIT is parsed but otherwise ignored. This keyword currently has no\neffect, and is intended for future expansion.\n\nThe ENGINE parameter (required) determines the storage engine which is\nused by this log file group, with engine_name being the name of the\nstorage engine. Currently, the only accepted values for engine_name are\n"NDBCLUSTER" and "NDB". The two values are equivalent.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-logfile-group.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-logfile-group.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (461,32,'LOCALTIMESTAMP','Syntax:\nLOCALTIMESTAMP, LOCALTIMESTAMP([fsp])\n\nLOCALTIMESTAMP and LOCALTIMESTAMP() are synonyms for NOW().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
@@ -551,7 +551,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (470,23,'AUTO_INCREMENT','The AUTO_INCREMENT attribute can be used to generate a unique identity\nfor new rows:\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html\n\n','CREATE TABLE animals (\n id MEDIUMINT NOT NULL AUTO_INCREMENT,\n name CHAR(30) NOT NULL,\n PRIMARY KEY (id)\n);\n\nINSERT INTO animals (name) VALUES\n (\'dog\'),(\'cat\'),(\'penguin\'),\n (\'lax\'),(\'whale\'),(\'ostrich\');\n\nSELECT * FROM animals;\n','http://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (471,12,'UNCOMPRESS','Syntax:\nUNCOMPRESS(string_to_uncompress)\n\nUncompresses a string compressed by the COMPRESS() function. If the\nargument is not a compressed value, the result is NULL. This function\nrequires MySQL to have been compiled with a compression library such as\nzlib. Otherwise, the return value is always NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SELECT UNCOMPRESS(COMPRESS(\'any string\'));\n -> \'any string\'\nmysql> SELECT UNCOMPRESS(\'any string\');\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (472,4,'GEOMCOLLFROMTEXT','GeomCollFromText(wkt[, srid]), GeometryCollectionFromText(wkt[, srid])\n\nST_GeomCollFromText(), ST_GeometryCollectionFromText(),\nST_GeomCollFromTxt(), GeomCollFromText(), and\nGeometryCollectionFromText() are synonyms. For more information, see\nthe description of ST_GeomCollFromText().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (473,2,'ST_INTERIORRINGN','ST_InteriorRingN(poly, N)\n\nReturns the N-th interior ring for the Polygon value poly as a\nLineString. Rings are numbered beginning with 1. If the argument is\nNULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n -> \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nmysql> SELECT ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1));\n+-------------------------------------------------------+\n| ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1)) |\n+-------------------------------------------------------+\n| LINESTRING(1 1,1 2,2 2,2 1,1 1) |\n+-------------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (473,2,'ST_INTERIORRINGN','ST_InteriorRingN(poly, N)\n\nReturns the N-th interior ring for the Polygon value poly as a\nLineString. Rings are numbered beginning with 1. If the argument is\nNULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nmysql> SELECT ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1));\n+-------------------------------------------------------+\n| ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1)) |\n+-------------------------------------------------------+\n| LINESTRING(1 1,1 2,2 2,2 1,1 1) |\n+-------------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (474,17,'LAST_INSERT_ID','Syntax:\nLAST_INSERT_ID(), LAST_INSERT_ID(expr)\n\nWith no argument, LAST_INSERT_ID() returns a BIGINT UNSIGNED (64-bit)\nvalue representing the first automatically generated value successfully\ninserted for an AUTO_INCREMENT column as a result of the most recently\nexecuted INSERT statement. The value of LAST_INSERT_ID() remains\nunchanged if no rows are successfully inserted.\n\nWith an argument, LAST_INSERT_ID() returns an unsigned integer.\n\nFor example, after inserting a row that generates an AUTO_INCREMENT\nvalue, you can get the value like this:\n\nmysql> SELECT LAST_INSERT_ID();\n -> 195\n\nThe currently executing statement does not affect the value of\nLAST_INSERT_ID(). Suppose that you generate an AUTO_INCREMENT value\nwith one statement, and then refer to LAST_INSERT_ID() in a\nmultiple-row INSERT statement that inserts rows into a table with its\nown AUTO_INCREMENT column. The value of LAST_INSERT_ID() will remain\nstable in the second statement; its value for the second and later rows\nis not affected by the earlier row insertions. (However, if you mix\nreferences to LAST_INSERT_ID() and LAST_INSERT_ID(expr), the effect is\nundefined.)\n\nIf the previous statement returned an error, the value of\nLAST_INSERT_ID() is undefined. For transactional tables, if the\nstatement is rolled back due to an error, the value of LAST_INSERT_ID()\nis left undefined. For manual ROLLBACK, the value of LAST_INSERT_ID()\nis not restored to that before the transaction; it remains as it was at\nthe point of the ROLLBACK.\n\nPrior to MySQL 5.7.3, this function was not replicated correctly if\nreplication filtering rules were in use. (Bug #17234370, Bug #69861)\n\nWithin the body of a stored routine (procedure or function) or a\ntrigger, the value of LAST_INSERT_ID() changes the same way as for\nstatements executed outside the body of these kinds of objects. The\neffect of a stored routine or trigger upon the value of\nLAST_INSERT_ID() that is seen by following statements depends on the\nkind of routine:\n\no If a stored procedure executes statements that change the value of\n LAST_INSERT_ID(), the changed value is seen by statements that follow\n the procedure call.\n\no For stored functions and triggers that change the value, the value is\n restored when the function or trigger ends, so following statements\n will not see a changed value.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (475,3,'FLOOR','Syntax:\nFLOOR(X)\n\nReturns the largest integer value not greater than X.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT FLOOR(1.23), FLOOR(-1.23);\n -> 1, -2\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (476,3,'COS','Syntax:\nCOS(X)\n\nReturns the cosine of X, where X is given in radians.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT COS(PI());\n -> -1\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
@@ -566,7 +566,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (485,40,'DROP TABLE','Syntax:\nDROP [TEMPORARY] TABLE [IF EXISTS]\n tbl_name [, tbl_name] ...\n [RESTRICT | CASCADE]\n\nDROP TABLE removes one or more tables. You must have the DROP privilege\nfor each table.\n\nBe careful with this statement! It removes the table definition and all\ntable data. For a partitioned table, it permanently removes the table\ndefinition, all its partitions, and all data stored in those\npartitions. It also removes partition definitions associated with the\ndropped table.\n\nDROP TABLE causes an implicit commit, except when used with the\nTEMPORARY keyword. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\n*Important*:\n\nWhen a table is dropped, privileges granted specifically for the table\nare not automatically dropped. They must be dropped manually. See [HELP\nGRANT].\n\nIf any tables named in the argument list do not exist, the statement\nreturns an error indicating by name which nonexisting tables it was\nunable to drop, but also drops all tables in the list that do exist.\n\nUse IF EXISTS to prevent an error from occurring for tables that do not\nexist. Instead of an error, a NOTE is generated for each nonexistent\ntable; these notes can be displayed with SHOW WARNINGS. See [HELP SHOW\nWARNINGS].\n\nIF EXISTS can also be useful for dropping tables in unusual\ncircumstances under which there is an .frm file but no table managed by\nthe storage engine. (For example, if an abnormal server exit occurs\nafter removal of the table from the storage engine but before .frm file\nremoval.)\n\nThe TEMPORARY keyword has the following effects:\n\no The statement drops only TEMPORARY tables.\n\no The statement does not cause an implicit commit.\n\no No access rights are checked. A TEMPORARY table is visible only with\n the session that created it, so no check is necessary.\n\nUsing TEMPORARY is a good way to ensure that you do not accidentally\ndrop a non-TEMPORARY table.\n\nThe RESTRICT and CASCADE keywords do nothing. They are permitted to\nmake porting easier from other database systems.\n\nDROP TABLE is not supported with all innodb_force_recovery settings.\nSee\nhttp://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (486,3,'POW','Syntax:\nPOW(X,Y)\n\nReturns the value of X raised to the power of Y.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT POW(2,2);\n -> 4\nmysql> SELECT POW(2,-2);\n -> 0.25\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (487,32,'NOW','Syntax:\nNOW([fsp])\n\nReturns the current date and time as a value in \'YYYY-MM-DD HH:MM:SS\'\nor YYYYMMDDHHMMSS format, depending on whether the function is used in\na string or numeric context. The value is expressed in the current time\nzone.\n\nIf the fsp argument is given to specify a fractional seconds precision\nfrom 0 to 6, the return value includes a fractional seconds part of\nthat many digits.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT NOW();\n -> \'2007-12-15 23:50:26\'\nmysql> SELECT NOW() + 0;\n -> 20071215235026.000000\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (488,27,'SHOW ENGINES','Syntax:\nSHOW [STORAGE] ENGINES\n\nSHOW ENGINES displays status information about the server\'s storage\nengines. This is particularly useful for checking whether a storage\nengine is supported, or to see what the default engine is. This\ninformation can also be obtained from the INFORMATION_SCHEMA ENGINES\ntable. See http://dev.mysql.com/doc/refman/5.7/en/engines-table.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-engines.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-engines.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (488,27,'SHOW ENGINES','Syntax:\nSHOW [STORAGE] ENGINES\n\nSHOW ENGINES displays status information about the server\'s storage\nengines. This is particularly useful for checking whether a storage\nengine is supported, or to see what the default engine is.\n\nFor information about MySQL storage engines, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html, and\nhttp://dev.mysql.com/doc/refman/5.7/en/storage-engines.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-engines.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-engines.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (489,4,'ST_POINTFROMTEXT','ST_PointFromText(wkt[, srid])\n\nConstructs a Point value using its WKT representation and SRID.\n\nIf the geometry argument is NULL or not a syntactically well-formed\ngeometry, or if the SRID argument is NULL, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (490,13,'ST_ENDPOINT','ST_EndPoint(ls)\n\nReturns the Point that is the endpoint of the LineString value ls. If\nthe argument is NULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html\n\n','mysql> SET @ls = \'LineString(1 1,2 2,3 3)\';\nmysql> SELECT ST_AsText(ST_EndPoint(ST_GeomFromText(@ls)));\n+----------------------------------------------+\n| ST_AsText(ST_EndPoint(ST_GeomFromText(@ls))) |\n+----------------------------------------------+\n| POINT(3 3) |\n+----------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-linestring-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (491,14,'IS_IPV6','Syntax:\nIS_IPV6(expr)\n\nReturns 1 if the argument is a valid IPv6 address specified as a\nstring, 0 otherwise. This function does not consider IPv4 addresses to\nbe valid IPv6 addresses.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','mysql> SELECT IS_IPV6(\'10.0.5.9\'), IS_IPV6(\'::1\');\n -> 0, 1\n','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
@@ -583,7 +583,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (502,27,'LOAD INDEX','Syntax:\nLOAD INDEX INTO CACHE\n tbl_index_list [, tbl_index_list] ...\n\ntbl_index_list:\n tbl_name\n [PARTITION (partition_list | ALL)]\n [[INDEX|KEY] (index_name[, index_name] ...)]\n [IGNORE LEAVES]\n\npartition_list:\n partition_name[, partition_name][, ...]\n\nThe LOAD INDEX INTO CACHE statement preloads a table index into the key\ncache to which it has been assigned by an explicit CACHE INDEX\nstatement, or into the default key cache otherwise.\n\nLOAD INDEX INTO CACHE is used only for MyISAM tables. In MySQL 5.7, it\nis also supported for partitioned MyISAM tables; in addition, indexes\non partitioned tables can be preloaded for one, several, or all\npartitions.\n\nThe IGNORE LEAVES modifier causes only blocks for the nonleaf nodes of\nthe index to be preloaded.\n\nIGNORE LEAVES is also supported for partitioned MyISAM tables.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/load-index.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/load-index.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (503,28,'UNION','Syntax:\nSELECT ...\nUNION [ALL | DISTINCT] SELECT ...\n[UNION [ALL | DISTINCT] SELECT ...]\n\nUNION is used to combine the result from multiple SELECT statements\ninto a single result set.\n\nThe column names from the first SELECT statement are used as the column\nnames for the results returned. Selected columns listed in\ncorresponding positions of each SELECT statement should have the same\ndata type. (For example, the first column selected by the first\nstatement should have the same type as the first column selected by the\nother statements.)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/union.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/union.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (504,32,'TO_DAYS','Syntax:\nTO_DAYS(date)\n\nGiven a date date, returns a day number (the number of days since year\n0).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT TO_DAYS(950501);\n -> 728779\nmysql> SELECT TO_DAYS(\'2007-10-07\');\n -> 733321\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (505,27,'SHOW INDEX','Syntax:\nSHOW {INDEX | INDEXES | KEYS}\n {FROM | IN} tbl_name\n [{FROM | IN} db_name]\n [WHERE expr]\n\nSHOW INDEX returns table index information. The format resembles that\nof the SQLStatistics call in ODBC. This statement requires some\nprivilege for any column in the table.\n\nYou can use db_name.tbl_name as an alternative to the tbl_name FROM\ndb_name syntax. These two statements are equivalent:\n\nSHOW INDEX FROM mytable FROM mydb;\nSHOW INDEX FROM mydb.mytable;\n\nThe WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nmysql> SHOW INDEX FROM City\\G\n*************************** 1. row ***************************\n Table: city\n Non_unique: 0\n Key_name: PRIMARY\n Seq_in_index: 1\n Column_name: ID\n Collation: A\n Cardinality: 4321\n Sub_part: NULL\n Packed: NULL\n Null: \n Index_type: BTREE\n Comment: \nIndex_comment: \n*************************** 2. row ***************************\n Table: city\n Non_unique: 1\n Key_name: CountryCode\n Seq_in_index: 1\n Column_name: CountryCode\n Collation: A\n Cardinality: 4321\n Sub_part: NULL\n Packed: NULL\n Null: \n Index_type: BTREE\n Comment: \nIndex_comment: \n\nSHOW INDEX returns the following fields:\n\no Table\n\n The name of the table.\n\no Non_unique\n\n 0 if the index cannot contain duplicates, 1 if it can.\n\no Key_name\n\n The name of the index. If the index is the primary key, the name is\n always PRIMARY.\n\no Seq_in_index\n\n The column sequence number in the index, starting with 1.\n\no Column_name\n\n The column name.\n\no Collation\n\n How the column is sorted in the index. This can have values A\n (ascending) or NULL (not sorted).\n\no Cardinality\n\n An estimate of the number of unique values in the index. To update\n this number, run ANALYZE TABLE or (for MyISAM tables) myisamchk -a.\n\n Cardinality is counted based on statistics stored as integers, so the\n value is not necessarily exact even for small tables. The higher the\n cardinality, the greater the chance that MySQL uses the index when\n doing joins.\n\no Sub_part\n\n The index prefix. That is, the number of indexed characters if the\n column is only partly indexed, NULL if the entire column is indexed.\n\n *Note*:\n\n Prefix limits are measured in bytes, whereas the prefix length in\n CREATE TABLE, ALTER TABLE, and CREATE INDEX statements is interpreted\n as number of characters for nonbinary string types (CHAR, VARCHAR,\n TEXT) and number of bytes for binary string types (BINARY, VARBINARY,\n BLOB). Take this into account when specifying a prefix length for a\n nonbinary string column that uses a multibyte character set.\n\n For additional information about index prefixes, see\n http://dev.mysql.com/doc/refman/5.7/en/column-indexes.html, and [HELP\n CREATE INDEX].\n\no Packed\n\n Indicates how the key is packed. NULL if it is not.\n\no Null\n\n Contains YES if the column may contain NULL values and \'\' if not.\n\no Index_type\n\n The index method used (BTREE, FULLTEXT, HASH, RTREE).\n\no Comment\n\n Information about the index not described in its own column, such as\n disabled if the index is disabled.\n\no Index_comment\n\n Any comment provided for the index with a COMMENT attribute when the\n index was created.\n\nYou can also obtain information about table indexes from\nINFORMATION_SCHEMA, which contains a STATISTICS table. See\nhttp://dev.mysql.com/doc/refman/5.7/en/statistics-table.html.\n\nYou can list a table\'s indexes with the mysqlshow -k db_name tbl_name\ncommand.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-index.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-index.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (505,27,'SHOW INDEX','Syntax:\nSHOW {INDEX | INDEXES | KEYS}\n {FROM | IN} tbl_name\n [{FROM | IN} db_name]\n [WHERE expr]\n\nSHOW INDEX returns table index information. The format resembles that\nof the SQLStatistics call in ODBC. This statement requires some\nprivilege for any column in the table.\n\nmysql> SHOW INDEX FROM City\\G\n*************************** 1. row ***************************\n Table: city\n Non_unique: 0\n Key_name: PRIMARY\n Seq_in_index: 1\n Column_name: ID\n Collation: A\n Cardinality: 4188\n Sub_part: NULL\n Packed: NULL\n Null:\n Index_type: BTREE\n Comment:\nIndex_comment:\n*************************** 2. row ***************************\n Table: city\n Non_unique: 1\n Key_name: CountryCode\n Seq_in_index: 1\n Column_name: CountryCode\n Collation: A\n Cardinality: 232\n Sub_part: NULL\n Packed: NULL\n Null:\n Index_type: BTREE\n Comment:\nIndex_comment:\n\nAn alternative to tbl_name FROM db_name syntax is db_name.tbl_name.\nThese two statements are equivalent:\n\nSHOW INDEX FROM mytable FROM mydb;\nSHOW INDEX FROM mydb.mytable;\n\nThe WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.7/en/extended-show.html.\n\nSHOW INDEX returns the following fields:\n\no Table\n\n The name of the table.\n\no Non_unique\n\n 0 if the index cannot contain duplicates, 1 if it can.\n\no Key_name\n\n The name of the index. If the index is the primary key, the name is\n always PRIMARY.\n\no Seq_in_index\n\n The column sequence number in the index, starting with 1.\n\no Column_name\n\n The name of the column.\n\no Collation\n\n How the column is sorted in the index. This can have values A\n (ascending) or NULL (not sorted).\n\no Cardinality\n\n An estimate of the number of unique values in the index. To update\n this number, run ANALYZE TABLE or (for MyISAM tables) myisamchk -a.\n\n Cardinality is counted based on statistics stored as integers, so the\n value is not necessarily exact even for small tables. The higher the\n cardinality, the greater the chance that MySQL uses the index when\n doing joins.\n\no Sub_part\n\n The index prefix. That is, the number of indexed characters if the\n column is only partly indexed, NULL if the entire column is indexed.\n\n *Note*:\n\n Prefix limits are measured in bytes. However, prefix lengths for\n index specifications in CREATE TABLE, ALTER TABLE, and CREATE INDEX\n statements are interpreted as number of characters for nonbinary\n string types (CHAR, VARCHAR, TEXT) and number of bytes for binary\n string types (BINARY, VARBINARY, BLOB). Take this into account when\n specifying a prefix length for a nonbinary string column that uses a\n multibyte character set.\n\n For additional information about index prefixes, see\n http://dev.mysql.com/doc/refman/5.7/en/column-indexes.html, and [HELP\n CREATE INDEX].\n\no Packed\n\n Indicates how the key is packed. NULL if it is not.\n\no Null\n\n Contains YES if the column may contain NULL values and \'\' if not.\n\no Index_type\n\n The index method used (BTREE, FULLTEXT, HASH, RTREE).\n\no Comment\n\n Information about the index not described in its own column, such as\n disabled if the index is disabled.\n\no Index_comment\n\n Any comment provided for the index with a COMMENT attribute when the\n index was created.\n\nInformation about table indexes is also available from the\nINFORMATION_SCHEMA STATISTICS table. See\nhttp://dev.mysql.com/doc/refman/5.7/en/statistics-table.html.\n\nYou can list a table\'s indexes with the mysqlshow -k db_name tbl_name\ncommand.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-index.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-index.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (506,27,'SHOW CREATE DATABASE','Syntax:\nSHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name\n\nShows the CREATE DATABASE statement that creates the named database. If\nthe SHOW statement includes an IF NOT EXISTS clause, the output too\nincludes such a clause. SHOW CREATE SCHEMA is a synonym for SHOW CREATE\nDATABASE.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-create-database.html\n\n','mysql> SHOW CREATE DATABASE test\\G\n*************************** 1. row ***************************\n Database: test\nCreate Database: CREATE DATABASE `test`\n /*!40100 DEFAULT CHARACTER SET latin1 */\n\nmysql> SHOW CREATE SCHEMA test\\G\n*************************** 1. row ***************************\n Database: test\nCreate Database: CREATE DATABASE `test`\n /*!40100 DEFAULT CHARACTER SET latin1 */\n','http://dev.mysql.com/doc/refman/5.7/en/show-create-database.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (507,15,'!','Syntax:\nNOT, !\n\nLogical NOT. Evaluates to 1 if the operand is 0, to 0 if the operand is\nnonzero, and NOT NULL returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/logical-operators.html\n\n','mysql> SELECT NOT 10;\n -> 0\nmysql> SELECT NOT 0;\n -> 1\nmysql> SELECT NOT NULL;\n -> NULL\nmysql> SELECT ! (1+1);\n -> 0\nmysql> SELECT ! 1+1;\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/logical-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (508,24,'DECLARE HANDLER','Syntax:\nDECLARE handler_action HANDLER\n FOR condition_value [, condition_value] ...\n statement\n\nhandler_action:\n CONTINUE\n | EXIT\n | UNDO\n\ncondition_value:\n mysql_error_code\n | SQLSTATE [VALUE] sqlstate_value\n | condition_name\n | SQLWARNING\n | NOT FOUND\n | SQLEXCEPTION\n\nThe DECLARE ... HANDLER statement specifies a handler that deals with\none or more conditions. If one of these conditions occurs, the\nspecified statement executes. statement can be a simple statement such\nas SET var_name = value, or a compound statement written using BEGIN\nand END (see [HELP BEGIN END]).\n\nHandler declarations must appear after variable or condition\ndeclarations.\n\nThe handler_action value indicates what action the handler takes after\nexecution of the handler statement:\n\no CONTINUE: Execution of the current program continues.\n\no EXIT: Execution terminates for the BEGIN ... END compound statement\n in which the handler is declared. This is true even if the condition\n occurs in an inner block.\n\no UNDO: Not supported.\n\nThe condition_value for DECLARE ... HANDLER indicates the specific\ncondition or class of conditions that activates the handler. It can\ntake the following forms:\n\no mysql_error_code: An integer literal indicating a MySQL error code,\n such as 1051 to specify "unknown table":\n\nDECLARE CONTINUE HANDLER FOR 1051\n BEGIN\n -- body of handler\n END;\n\n Do not use MySQL error code 0 because that indicates success rather\n than an error condition. For a list of MySQL error codes, see\n http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html.\n\no SQLSTATE [VALUE] sqlstate_value: A 5-character string literal\n indicating an SQLSTATE value, such as \'42S01\' to specify "unknown\n table":\n\nDECLARE CONTINUE HANDLER FOR SQLSTATE \'42S02\'\n BEGIN\n -- body of handler\n END;\n\n Do not use SQLSTATE values that begin with \'00\' because those\n indicate success rather than an error condition. For a list of\n SQLSTATE values, see\n http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html.\n\no condition_name: A condition name previously specified with DECLARE\n ... CONDITION. A condition name can be associated with a MySQL error\n code or SQLSTATE value. See [HELP DECLARE CONDITION].\n\no SQLWARNING: Shorthand for the class of SQLSTATE values that begin\n with \'01\'.\n\nDECLARE CONTINUE HANDLER FOR SQLWARNING\n BEGIN\n -- body of handler\n END;\n\no NOT FOUND: Shorthand for the class of SQLSTATE values that begin with\n \'02\'. This is relevant within the context of cursors and is used to\n control what happens when a cursor reaches the end of a data set. If\n no more rows are available, a No Data condition occurs with SQLSTATE\n value \'02000\'. To detect this condition, you can set up a handler for\n it or for a NOT FOUND condition.\n\nDECLARE CONTINUE HANDLER FOR NOT FOUND\n BEGIN\n -- body of handler\n END;\n\n For another example, see\n http://dev.mysql.com/doc/refman/5.7/en/cursors.html. The NOT FOUND\n condition also occurs for SELECT ... INTO var_list statements that\n retrieve no rows.\n\no SQLEXCEPTION: Shorthand for the class of SQLSTATE values that do not\n begin with \'00\', \'01\', or \'02\'.\n\nDECLARE CONTINUE HANDLER FOR SQLEXCEPTION\n BEGIN\n -- body of handler\n END;\n\nFor information about how the server chooses handlers when a condition\noccurs, see http://dev.mysql.com/doc/refman/5.7/en/handler-scope.html.\n\nIf a condition occurs for which no handler has been declared, the\naction taken depends on the condition class:\n\no For SQLEXCEPTION conditions, the stored program terminates at the\n statement that raised the condition, as if there were an EXIT\n handler. If the program was called by another stored program, the\n calling program handles the condition using the handler selection\n rules applied to its own handlers.\n\no For SQLWARNING conditions, the program continues executing, as if\n there were a CONTINUE handler.\n\no For NOT FOUND conditions, if the condition was raised normally, the\n action is CONTINUE. If it was raised by SIGNAL or RESIGNAL, the\n action is EXIT.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/declare-handler.html\n\n','mysql> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> delimiter //\n\nmysql> CREATE PROCEDURE handlerdemo ()\n -> BEGIN\n -> DECLARE CONTINUE HANDLER FOR SQLSTATE \'23000\' SET @x2 = 1;\n -> SET @x = 1;\n -> INSERT INTO test.t VALUES (1);\n -> SET @x = 2;\n -> INSERT INTO test.t VALUES (1);\n -> SET @x = 3;\n -> END;\n -> //\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> CALL handlerdemo()//\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT @x//\n +------+\n | @x |\n +------+\n | 3 |\n +------+\n 1 row in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/declare-handler.html');
@@ -593,10 +593,10 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (512,40,'TRUNCATE TABLE','Syntax:\nTRUNCATE [TABLE] tbl_name\n\nTRUNCATE TABLE empties a table completely. It requires the DROP\nprivilege.\n\nLogically, TRUNCATE TABLE is similar to a DELETE statement that deletes\nall rows, or a sequence of DROP TABLE and CREATE TABLE statements. To\nachieve high performance, it bypasses the DML method of deleting data.\nThus, it cannot be rolled back, it does not cause ON DELETE triggers to\nfire, and it cannot be performed for InnoDB tables with parent-child\nforeign key relationships.\n\nAlthough TRUNCATE TABLE is similar to DELETE, it is classified as a DDL\nstatement rather than a DML statement. It differs from DELETE in the\nfollowing ways:\n\no Truncate operations drop and re-create the table, which is much\n faster than deleting rows one by one, particularly for large tables.\n\no Truncate operations cause an implicit commit, and so cannot be rolled\n back. See\n http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\no Truncation operations cannot be performed if the session holds an\n active table lock.\n\no TRUNCATE TABLE fails for an InnoDB table or NDB table if there are\n any FOREIGN KEY constraints from other tables that reference the\n table. Foreign key constraints between columns of the same table are\n permitted.\n\no Truncation operations do not return a meaningful value for the number\n of deleted rows. The usual result is "0 rows affected," which should\n be interpreted as "no information."\n\no As long as the table format file tbl_name.frm is valid, the table can\n be re-created as an empty table with TRUNCATE TABLE, even if the data\n or index files have become corrupted.\n\no Any AUTO_INCREMENT value is reset to its start value. This is true\n even for MyISAM and InnoDB, which normally do not reuse sequence\n values.\n\no When used with partitioned tables, TRUNCATE TABLE preserves the\n partitioning; that is, the data and index files are dropped and\n re-created, while the partition definitions (.par) file is\n unaffected.\n\no The TRUNCATE TABLE statement does not invoke ON DELETE triggers.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/truncate-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/truncate-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (513,32,'CURRENT_DATE','Syntax:\nCURRENT_DATE, CURRENT_DATE()\n\nCURRENT_DATE and CURRENT_DATE() are synonyms for CURDATE().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (514,8,'START SLAVE','Syntax:\nSTART SLAVE [thread_types] [until_option] [connection_options] [channel_option]\n\nthread_types:\n [thread_type [, thread_type] ... ]\n\nthread_type:\n IO_THREAD | SQL_THREAD\n\nuntil_option:\n UNTIL { {SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS} = gtid_set\n | MASTER_LOG_FILE = \'log_name\', MASTER_LOG_POS = log_pos\n | RELAY_LOG_FILE = \'log_name\', RELAY_LOG_POS = log_pos\n | SQL_AFTER_MTS_GAPS }\n\nconnection_options:\n [USER=\'user_name\'] [PASSWORD=\'user_pass\'] [DEFAULT_AUTH=\'plugin_name\'] [PLUGIN_DIR=\'plugin_dir\']\n\n\nchannel_option:\n FOR CHANNEL channel\n\ngtid_set:\n uuid_set [, uuid_set] ...\n | \'\'\n\nuuid_set:\n uuid:interval[:interval]...\n\nuuid:\n hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh\n\nh:\n [0-9,A-F]\n\ninterval:\n n[-n]\n\n (n >= 1)\n\nSTART SLAVE with no thread_type options starts both of the slave\nthreads. The I/O thread reads events from the master server and stores\nthem in the relay log. The SQL thread reads events from the relay log\nand executes them. START SLAVE requires the SUPER privilege.\n\nIf START SLAVE succeeds in starting the slave threads, it returns\nwithout any error. However, even in that case, it might be that the\nslave threads start and then later stop (for example, because they do\nnot manage to connect to the master or read its binary log, or some\nother problem). START SLAVE does not warn you about this. You must\ncheck the slave\'s error log for error messages generated by the slave\nthreads, or check that they are running satisfactorily with SHOW SLAVE\nSTATUS.\n\nIn MySQL 5.7, START SLAVE causes an implicit commit of an ongoing\ntransaction. See\nhttp://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html.\n\ngtid_next must be set to AUTOMATIC before issuing this statement.\n\nThe optional FOR CHANNEL channel clause enables you to name which\nreplication channel the statement applies to. Providing a FOR CHANNEL\nchannel clause applies the START SLAVE statement to a specific\nreplication channel. If no clause is named and no extra channels exist,\nthe statement applies to the default channel. If a START SLAVE\nstatement does not have a channel defined when using multiple channels,\nthis statement starts the specified threads for all channels. This\nstatement is disallowed for the group_replication_recovery channel. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information.\n\nMySQL supports pluggable user-password authentication with START SLAVE\nwith the USER, PASSWORD, DEFAULT_AUTH and PLUGIN_DIR options, as\ndescribed in the following list:\n\no USER: User name. Cannot be set to an empty or null string, or left\n unset if PASSWORD is used.\n\no PASSWORD: Password.\n\no DEFAULT_AUTH: Name of plugin; default is MySQL native authentication.\n\no PLUGIN_DIR: Location of plugin.\n\nYou cannot use the SQL_THREAD option when specifying any of USER,\nPASSWORD, DEFAULT_AUTH, or PLUGIN_DIR, unless the IO_THREAD option is\nalso provided.\n\nSee\nhttp://dev.mysql.com/doc/refman/5.7/en/pluggable-authentication.html,\nfor more information.\n\nIf an insecure connection is used with any these options, the server\nissues the warning Sending passwords in plain text without SSL/TLS is\nextremely insecure.\n\nSTART SLAVE ... UNTIL supports two additional options for use with\nglobal transaction identifiers (GTIDs) (see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html). Each of\nthese takes a set of one or more global transaction identifiers\ngtid_set as an argument (see\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html#\nreplication-gtids-concepts-gtid-sets, for more information).\n\nWhen no thread_type is specified, START SLAVE UNTIL SQL_BEFORE_GTIDS\ncauses the slave SQL thread to process transactions until it has\nreached the first transaction whose GTID is listed in the gtid_set.\nSTART SLAVE UNTIL SQL_AFTER_GTIDS causes the slave threads to process\nall transactions until the last transaction in the gtid_set has been\nprocessed by both threads. In other words, START SLAVE UNTIL\nSQL_BEFORE_GTIDS causes the slave SQL thread to process all\ntransactions occurring before the first GTID in the gtid_set is\nreached, and START SLAVE UNTIL SQL_AFTER_GTIDS causes the slave threads\nto handle all transactions, including those whose GTIDs are found in\ngtid_set, until each has encountered a transaction whose GTID is not\npart of the set. SQL_BEFORE_GTIDS and SQL_AFTER_GTIDS each support the\nSQL_THREAD and IO_THREAD options, although using IO_THREAD with them\ncurrently has no effect.\n\nFor example, START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS =\n3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56 causes the slave SQL thread\nto process all transactions originating from the master whose\nserver_uuid is 3E11FA47-71CA-11E1-9E33-C80AA9429562 until it encounters\nthe transaction having sequence number 11; it then stops without\nprocessing this transaction. In other words, all transactions up to and\nincluding the transaction with sequence number 10 are processed.\nExecuting START SLAVE SQL_THREAD UNTIL SQL_AFTER_GTIDS =\n3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56, on the other hand, would\ncause the slave SQL thread to obtain all transactions just mentioned\nfrom the master, including all of the transactions having the sequence\nnumbers 11 through 56, and then to stop without processing any\nadditional transactions; that is, the transaction having sequence\nnumber 56 would be the last transaction fetched by the slave SQL\nthread.\n\nPrior to MySQL 5.7.3, SQL_AFTER_GTIDS did not stop the slave once the\nindicated transaction was completed, but waited until another GTID\nevent was received (Bug #14767986).\n\nWhen using a multithreaded slave, there is a chance of gaps in the\nsequence of transactions that have been executed from the relay log in\nthe following cases:\n\no killing the coordinator thread\n\no after an error occurs in the worker threads\n\no mysqld shuts down unexpectedly\n\nUse the START SLAVE UNTIL SQL_AFTER_MTS_GAPS statement to cause a\nmultithreaded slave\'s worker threads to only run until no more gaps are\nfound in the relay log, and then to stop. This statement can take an\nSQL_THREAD option, but the effects of the statement remain unchanged.\nIt has no effect on the slave I/O thread (and cannot be used with the\nIO_THREAD option).\n\nIssuing START SLAVE on a multithreaded slave with gaps in the sequence\nof transactions executed from the relay log generates a warning. In\nsuch a situation, the solution is to use START SLAVE UNTIL\nSQL_AFTER_MTS_GAPS, then issue RESET SLAVE to remove any remaining\nrelay logs. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-features-transaction\n-inconsistencies.html for more information.\n\nTo change a failed multithreaded slave to single-threaded mode, you can\nissue the following series of statements, in the order shown:\n\nSTART SLAVE UNTIL SQL_AFTER_MTS_GAPS;\n\nSET @@GLOBAL.slave_parallel_workers = 0;\n\nSTART SLAVE SQL_THREAD;\n\n*Note*:\n\nIt is possible to view the entire text of a running START SLAVE ...\nstatement, including any USER or PASSWORD values used, in the output of\nSHOW PROCESSLIST. This is also true for the text of a running CHANGE\nMASTER TO statement, including any values it employs for MASTER_USER or\nMASTER_PASSWORD.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/start-slave.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/start-slave.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (515,2,'AREA','Area(poly)\n\nST_Area() and Area() are synonyms. For more information, see the\ndescription of ST_Area().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (515,2,'AREA','Area({poly|mpoly})\n\nST_Area() and Area() are synonyms. For more information, see the\ndescription of ST_Area().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (516,27,'SHOW WARNINGS','Syntax:\nSHOW WARNINGS [LIMIT [offset,] row_count]\nSHOW COUNT(*) WARNINGS\n\nSHOW WARNINGS is a diagnostic statement that displays information about\nthe conditions (errors, warnings, and notes) resulting from executing a\nstatement in the current session. Warnings are generated for DML\nstatements such as INSERT, UPDATE, and LOAD DATA INFILE as well as DDL\nstatements such as CREATE TABLE and ALTER TABLE.\n\nThe LIMIT clause has the same syntax as for the SELECT statement. See\nhttp://dev.mysql.com/doc/refman/5.7/en/select.html.\n\nSHOW WARNINGS is also used following EXPLAIN, to display the extended\ninformation generated by EXPLAIN. See\nhttp://dev.mysql.com/doc/refman/5.7/en/explain-extended.html.\n\nSHOW WARNINGS displays information about the conditions resulting from\nexecution of the most recent nondiagnostic statement in the current\nsession. If the most recent statement resulted in an error during\nparsing, SHOW WARNINGS shows the resulting conditions, regardless of\nstatement type (diagnostic or nondiagnostic).\n\nThe SHOW COUNT(*) WARNINGS diagnostic statement displays the total\nnumber of errors, warnings, and notes. You can also retrieve this\nnumber from the warning_count system variable:\n\nSHOW COUNT(*) WARNINGS;\nSELECT @@warning_count;\n\nA difference in these statements is that the first is a diagnostic\nstatement that does not clear the message list. The second, because it\nis a SELECT statement is considered nondiagnostic and does clear the\nmessage list.\n\nA related diagnostic statement, SHOW ERRORS, shows only error\nconditions (it excludes warnings and notes), and SHOW COUNT(*) ERRORS\nstatement displays the total number of errors. See [HELP SHOW ERRORS].\nGET DIAGNOSTICS can be used to examine information for individual\nconditions. See [HELP GET DIAGNOSTICS].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-warnings.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-warnings.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (517,4,'ST_LINEFROMTEXT','ST_LineFromText(wkt[, srid]), ST_LineStringFromText(wkt[, srid])\n\nConstructs a LineString value using its WKT representation and SRID.\n\nIf the geometry argument is NULL or not a syntactically well-formed\ngeometry, or if the SRID argument is NULL, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (518,10,'DROP USER','Syntax:\nDROP USER [IF EXISTS] user [, user] ...\n\nThe DROP USER statement removes one or more MySQL accounts and their\nprivileges. It removes privilege rows for the account from all grant\ntables.\n\nTo use DROP USER, you must have the global CREATE USER privilege, or\nthe DELETE privilege for the mysql database. When the read_only system\nvariable is enabled, DROP USER additionally requires the SUPER\nprivilege.\n\nAn error occurs if you try to drop an account that does not exist. If\nthe IF EXISTS clause is given, the statement produces a warning for\neach named user that does not exist, rather than an error.\n\nEach account name uses the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. For example:\n\nDROP USER \'jeffrey\'@\'localhost\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-user.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (518,10,'DROP USER','Syntax:\nDROP USER [IF EXISTS] user [, user] ...\n\nThe DROP USER statement removes one or more MySQL accounts and their\nprivileges. It removes privilege rows for the account from all grant\ntables.\n\nTo use DROP USER, you must have the global CREATE USER privilege, or\nthe DELETE privilege for the mysql system database. When the read_only\nsystem variable is enabled, DROP USER additionally requires the SUPER\nprivilege.\n\nAn error occurs if you try to drop an account that does not exist. If\nthe IF EXISTS clause is given, the statement produces a warning for\neach named user that does not exist, rather than an error.\n\nEach account name uses the format described in\nhttp://dev.mysql.com/doc/refman/5.7/en/account-names.html. For example:\n\nDROP USER \'jeffrey\'@\'localhost\';\n\nThe host name part of the account name, if omitted, defaults to \'%\'.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-user.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (519,38,'SUBSTRING','Syntax:\nSUBSTRING(str,pos), SUBSTRING(str FROM pos), SUBSTRING(str,pos,len),\nSUBSTRING(str FROM pos FOR len)\n\nThe forms without a len argument return a substring from string str\nstarting at position pos. The forms with a len argument return a\nsubstring len characters long from string str, starting at position\npos. The forms that use FROM are standard SQL syntax. It is also\npossible to use a negative value for pos. In this case, the beginning\nof the substring is pos characters from the end of the string, rather\nthan the beginning. A negative value may be used for pos in any of the\nforms of this function.\n\nFor all forms of SUBSTRING(), the position of the first character in\nthe string from which the substring is to be extracted is reckoned as\n1.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT SUBSTRING(\'Quadratically\',5);\n -> \'ratically\'\nmysql> SELECT SUBSTRING(\'foobarbar\' FROM 4);\n -> \'barbar\'\nmysql> SELECT SUBSTRING(\'Quadratically\',5,6);\n -> \'ratica\'\nmysql> SELECT SUBSTRING(\'Sakila\', -3);\n -> \'ila\'\nmysql> SELECT SUBSTRING(\'Sakila\', -5, 3);\n -> \'aki\'\nmysql> SELECT SUBSTRING(\'Sakila\' FROM -4 FOR 2);\n -> \'ki\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (520,37,'ISEMPTY','IsEmpty(g)\n\nST_IsEmpty() and IsEmpty() are synonyms. For more information, see the\ndescription of ST_IsEmpty().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (521,27,'SHOW FUNCTION STATUS','Syntax:\nSHOW FUNCTION STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement is similar to SHOW PROCEDURE STATUS but for stored\nfunctions. See [HELP SHOW PROCEDURE STATUS].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-function-status.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-function-status.html');
@@ -623,7 +623,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (542,16,'GROUP_CONCAT','Syntax:\nGROUP_CONCAT(expr)\n\nThis function returns a string result with the concatenated non-NULL\nvalues from a group. It returns NULL if there are no non-NULL values.\nThe full syntax is as follows:\n\nGROUP_CONCAT([DISTINCT] expr [,expr ...]\n [ORDER BY {unsigned_integer | col_name | expr}\n [ASC | DESC] [,col_name ...]]\n [SEPARATOR str_val])\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html\n\n','mysql> SELECT student_name,\n GROUP_CONCAT(test_score)\n FROM student\n GROUP BY student_name;\n','http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (543,17,'BENCHMARK','Syntax:\nBENCHMARK(count,expr)\n\nThe BENCHMARK() function executes the expression expr repeatedly count\ntimes. It may be used to time how quickly MySQL processes the\nexpression. The result value is always 0. The intended use is from\nwithin the mysql client, which reports query execution times:\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT BENCHMARK(1000000,AES_ENCRYPT(\'hello\',\'goodbye\'));\n+---------------------------------------------------+\n| BENCHMARK(1000000,AES_ENCRYPT(\'hello\',\'goodbye\')) |\n+---------------------------------------------------+\n| 0 |\n+---------------------------------------------------+\n1 row in set (4.74 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (544,38,'FROM_BASE64','Syntax:\nFROM_BASE64(str)\n\nTakes a string encoded with the base-64 encoded rules used by\nTO_BASE64() and returns the decoded result as a binary string. The\nresult is NULL if the argument is NULL or not a valid base-64 string.\nSee the description of TO_BASE64() for details about the encoding and\ndecoding rules.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT TO_BASE64(\'abc\'), FROM_BASE64(TO_BASE64(\'abc\'));\n -> \'JWJj\', \'abc\'\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (545,27,'SHOW ENGINE','Syntax:\nSHOW ENGINE engine_name {STATUS | MUTEX}\n\nSHOW ENGINE displays operational information about a storage engine. It\nrequires the PROCESS privilege. The statement has these variants:\n\nSHOW ENGINE INNODB STATUS\nSHOW ENGINE INNODB MUTEX\nSHOW ENGINE PERFORMANCE_SCHEMA STATUS\n\nSHOW ENGINE INNODB STATUS displays extensive information from the\nstandard InnoDB Monitor about the state of the InnoDB storage engine.\nFor information about the standard monitor and other InnoDB Monitors\nthat provide information about InnoDB processing, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-monitors.html.\n\nSHOW ENGINE INNODB MUTEX displays InnoDB mutex and rw-lock statistics.\n\n*Note*:\n\nInnoDB mutexes and rwlocks can also be monitored using Performance\nSchema tables. See\nhttp://dev.mysql.com/doc/refman/5.7/en/monitor-innodb-mutex-waits-perfo\nrmance-schema.html.\n\nSHOW ENGINE INNODB MUTEX output was removed in MySQL 5.7.2. It was\nrevised and reintroduced in MySQL 5.7.8.\n\nIn MySQL 5.7.8, mutex statistics collection is configured dynamically\nusing the following options:\n\no To enable the collection of mutex statistics, run:\n\nSET GLOBAL innodb_monitor_enable=\'latch\';\n\no To reset mutex statistics, run:\n\nSET GLOBAL innodb_monitor_reset=\'latch\';\n\no To disable the collection of mutex statistics, run:\n\nSET GLOBAL innodb_monitor_disable=\'latch\';\n\nCollection of mutex statistics for SHOW ENGINE INNODB MUTEX can also be\nenabled by setting innodb_monitor_enable=\'all\', or disabled by setting\ninnodb_monitor_disable=\'all\'.\n\nSHOW ENGINE INNODB MUTEX output has the following columns:\n\no Type\n\n Always InnoDB.\n\no Name\n\n Prior to MySQL 5.7.8, the Name field reports the source file where\n the mutex is implemented, and the line number in the file where the\n mutex is created. The line number is specific to your version of\n MySQL. As of MySQL 5.7.8, only the mutex name is reported. File name\n and line number are still reported for rwlocks.\n\no Status\n\n The mutex status.\n\n Prior to MySQL 5.7.8, the Status field displays several values if\n WITH_DEBUG was defined at MySQL compilation time. If WITH_DEBUG was\n not defined, the statement displays only the os_waits value. In the\n latter case (without WITH_DEBUG), the information on which the output\n is based is insufficient to distinguish regular mutexes and mutexes\n that protect rwlocks (which permit multiple readers or a single\n writer). Consequently, the output may appear to contain multiple rows\n for the same mutex. Pre-MySQL 5.7.8 Status field values include:\n\n o count indicates how many times the mutex was requested.\n\n o spin_waits indicates how many times the spinlock had to run.\n\n o spin_rounds indicates the number of spinlock rounds. (spin_rounds\n divided by spin_waits provides the average round count.)\n\n o os_waits indicates the number of operating system waits. This\n occurs when the spinlock did not work (the mutex was not locked\n during the spinlock and it was necessary to yield to the operating\n system and wait).\n\n o os_yields indicates the number of times a thread trying to lock a\n mutex gave up its timeslice and yielded to the operating system (on\n the presumption that permitting other threads to run will free the\n mutex so that it can be locked).\n\n o os_wait_times indicates the amount of time (in ms) spent in\n operating system waits. In MySQL 5.7 timing is disabled and this\n value is always 0.\n\n As of MySQL 5.7.8, the Status field reports the number of spins,\n waits, and calls. Statistics for low-level operating system mutexes,\n which are implemented outside of InnoDB, are not reported.\n\n o spins indicates the number of spins.\n\n o waits indicates the number of mutex waits.\n\n o calls indicates how many times the mutex was requested.\n\nSHOW ENGINE INNODB MUTEX skips the mutexes and rw-locks of buffer pool\nblocks, as the amount of output can be overwhelming on systems with a\nlarge buffer pool. (There is one mutex and one rw-lock in each 16K\nbuffer pool block, and there are 65,536 blocks per gigabyte.) SHOW\nENGINE INNODB MUTEX also does not list any mutexes or rw-locks that\nhave never been waited on (os_waits=0). Thus, SHOW ENGINE INNODB MUTEX\nonly displays information about mutexes and rw-locks outside of the\nbuffer pool that have caused at least one OS-level wait.\n\nUse SHOW ENGINE PERFORMANCE_SCHEMA STATUS to inspect the internal\noperation of the Performance Schema code:\n\nmysql> SHOW ENGINE PERFORMANCE_SCHEMA STATUS\\G\n...\n*************************** 3. row ***************************\n Type: performance_schema\n Name: events_waits_history.size\nStatus: 76\n*************************** 4. row ***************************\n Type: performance_schema\n Name: events_waits_history.count\nStatus: 10000\n*************************** 5. row ***************************\n Type: performance_schema\n Name: events_waits_history.memory\nStatus: 760000\n...\n*************************** 57. row ***************************\n Type: performance_schema\n Name: performance_schema.memory\nStatus: 26459600\n...\n\nThis statement is intended to help the DBA understand the effects that\ndifferent Performance Schema options have on memory requirements.\n\nName values consist of two parts, which name an internal buffer and a\nbuffer attribute, respectively. Interpret buffer names as follows:\n\no An internal buffer that is not exposed as a table is named within\n parentheses. Examples: (pfs_cond_class).size,\n (pfs_mutex_class).memory.\n\no An internal buffer that is exposed as a table in the\n performance_schema database is named after the table, without\n parentheses. Examples: events_waits_history.size,\n mutex_instances.count.\n\no A value that applies to the Performance Schema as a whole begins with\n performance_schema. Example: performance_schema.memory.\n\nBuffer attributes have these meanings:\n\no size is the size of the internal record used by the implementation,\n such as the size of a row in a table. size values cannot be changed.\n\no count is the number of internal records, such as the number of rows\n in a table. count values can be changed using Performance Schema\n configuration options.\n\no For a table, tbl_name.memory is the product of size and count. For\n the Performance Schema as a whole, performance_schema.memory is the\n sum of all the memory used (the sum of all other memory values).\n\nIn some cases, there is a direct relationship between a Performance\nSchema configuration parameter and a SHOW ENGINE value. For example,\nevents_waits_history_long.count corresponds to\nperformance_schema_events_waits_history_long_size. In other cases, the\nrelationship is more complex. For example, events_waits_history.count\ncorresponds to performance_schema_events_waits_history_size (the number\nof rows per thread) multiplied by\nperformance_schema_max_thread_instances ( the number of threads).\n\nSHOW ENGINE NDB STATUS If the server has the NDB storage engine\nenabled, SHOW ENGINE NDB STATUS displays cluster status information\nsuch as the number of connected data nodes, the cluster connectstring,\nand cluster binary log epochs, as well as counts of various Cluster API\nobjects created by the MySQL Server when connected to the cluster.\nSample output from this statement is shown here:\n\nmysql> SHOW ENGINE NDB STATUS;\n+------------+-----------------------+--------------------------------------------------+\n| Type | Name | Status |\n+------------+-----------------------+--------------------------------------------------+\n| ndbcluster | connection | cluster_node_id=7,\n connected_host=198.51.100.103, connected_port=1186, number_of_data_nodes=4,\n number_of_ready_data_nodes=3, connect_count=0 |\n| ndbcluster | NdbTransaction | created=6, free=0, sizeof=212 |\n| ndbcluster | NdbOperation | created=8, free=8, sizeof=660 |\n| ndbcluster | NdbIndexScanOperation | created=1, free=1, sizeof=744 |\n| ndbcluster | NdbIndexOperation | created=0, free=0, sizeof=664 |\n| ndbcluster | NdbRecAttr | created=1285, free=1285, sizeof=60 |\n| ndbcluster | NdbApiSignal | created=16, free=16, sizeof=136 |\n| ndbcluster | NdbLabel | created=0, free=0, sizeof=196 |\n| ndbcluster | NdbBranch | created=0, free=0, sizeof=24 |\n| ndbcluster | NdbSubroutine | created=0, free=0, sizeof=68 |\n| ndbcluster | NdbCall | created=0, free=0, sizeof=16 |\n| ndbcluster | NdbBlob | created=1, free=1, sizeof=264 |\n| ndbcluster | NdbReceiver | created=4, free=0, sizeof=68 |\n| ndbcluster | binlog | latest_epoch=155467, latest_trans_epoch=148126,\n latest_received_binlog_epoch=0, latest_handled_binlog_epoch=0,\n latest_applied_binlog_epoch=0 |\n+------------+-----------------------+--------------------------------------------------+\n\nThe Status column in each of these rows provides information about the\nMySQL server\'s connection to the cluster and about the cluster binary\nlog\'s status, respectively. The Status information is in the form of\ncomma-delimited set of name/value pairs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-engine.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-engine.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (545,27,'SHOW ENGINE','Syntax:\nSHOW ENGINE engine_name {STATUS | MUTEX}\n\nSHOW ENGINE displays operational information about a storage engine. It\nrequires the PROCESS privilege. The statement has these variants:\n\nSHOW ENGINE INNODB STATUS\nSHOW ENGINE INNODB MUTEX\nSHOW ENGINE PERFORMANCE_SCHEMA STATUS\n\nSHOW ENGINE INNODB STATUS displays extensive information from the\nstandard InnoDB Monitor about the state of the InnoDB storage engine.\nFor information about the standard monitor and other InnoDB Monitors\nthat provide information about InnoDB processing, see\nhttp://dev.mysql.com/doc/refman/5.7/en/innodb-monitors.html.\n\nSHOW ENGINE INNODB MUTEX displays InnoDB mutex and rw-lock statistics.\n\n*Note*:\n\nInnoDB mutexes and rwlocks can also be monitored using Performance\nSchema tables. See\nhttp://dev.mysql.com/doc/refman/5.7/en/monitor-innodb-mutex-waits-perfo\nrmance-schema.html.\n\nSHOW ENGINE INNODB MUTEX output was removed in MySQL 5.7.2. It was\nrevised and reintroduced in MySQL 5.7.8.\n\nIn MySQL 5.7.8, mutex statistics collection is configured dynamically\nusing the following options:\n\no To enable the collection of mutex statistics, run:\n\nSET GLOBAL innodb_monitor_enable=\'latch\';\n\no To reset mutex statistics, run:\n\nSET GLOBAL innodb_monitor_reset=\'latch\';\n\no To disable the collection of mutex statistics, run:\n\nSET GLOBAL innodb_monitor_disable=\'latch\';\n\nCollection of mutex statistics for SHOW ENGINE INNODB MUTEX can also be\nenabled by setting innodb_monitor_enable=\'all\', or disabled by setting\ninnodb_monitor_disable=\'all\'.\n\nSHOW ENGINE INNODB MUTEX output has these columns:\n\no Type\n\n Always InnoDB.\n\no Name\n\n Prior to MySQL 5.7.8, the Name field reports the source file where\n the mutex is implemented, and the line number in the file where the\n mutex is created. The line number is specific to your version of\n MySQL. As of MySQL 5.7.8, only the mutex name is reported. File name\n and line number are still reported for rwlocks.\n\no Status\n\n The mutex status.\n\n Prior to MySQL 5.7.8, the Status field displays several values if\n WITH_DEBUG was defined at MySQL compilation time. If WITH_DEBUG was\n not defined, the statement displays only the os_waits value. In the\n latter case (without WITH_DEBUG), the information on which the output\n is based is insufficient to distinguish regular mutexes and mutexes\n that protect rwlocks (which permit multiple readers or a single\n writer). Consequently, the output may appear to contain multiple rows\n for the same mutex. Pre-MySQL 5.7.8 Status field values include:\n\n o count indicates how many times the mutex was requested.\n\n o spin_waits indicates how many times the spinlock had to run.\n\n o spin_rounds indicates the number of spinlock rounds. (spin_rounds\n divided by spin_waits provides the average round count.)\n\n o os_waits indicates the number of operating system waits. This\n occurs when the spinlock did not work (the mutex was not locked\n during the spinlock and it was necessary to yield to the operating\n system and wait).\n\n o os_yields indicates the number of times a thread trying to lock a\n mutex gave up its timeslice and yielded to the operating system (on\n the presumption that permitting other threads to run will free the\n mutex so that it can be locked).\n\n o os_wait_times indicates the amount of time (in ms) spent in\n operating system waits. In MySQL 5.7 timing is disabled and this\n value is always 0.\n\n As of MySQL 5.7.8, the Status field reports the number of spins,\n waits, and calls. Statistics for low-level operating system mutexes,\n which are implemented outside of InnoDB, are not reported.\n\n o spins indicates the number of spins.\n\n o waits indicates the number of mutex waits.\n\n o calls indicates how many times the mutex was requested.\n\nSHOW ENGINE INNODB MUTEX skips the mutexes and rw-locks of buffer pool\nblocks, as the amount of output can be overwhelming on systems with a\nlarge buffer pool. (There is one mutex and one rw-lock in each 16K\nbuffer pool block, and there are 65,536 blocks per gigabyte.) SHOW\nENGINE INNODB MUTEX also does not list any mutexes or rw-locks that\nhave never been waited on (os_waits=0). Thus, SHOW ENGINE INNODB MUTEX\nonly displays information about mutexes and rw-locks outside of the\nbuffer pool that have caused at least one OS-level wait.\n\nUse SHOW ENGINE PERFORMANCE_SCHEMA STATUS to inspect the internal\noperation of the Performance Schema code:\n\nmysql> SHOW ENGINE PERFORMANCE_SCHEMA STATUS\\G\n...\n*************************** 3. row ***************************\n Type: performance_schema\n Name: events_waits_history.size\nStatus: 76\n*************************** 4. row ***************************\n Type: performance_schema\n Name: events_waits_history.count\nStatus: 10000\n*************************** 5. row ***************************\n Type: performance_schema\n Name: events_waits_history.memory\nStatus: 760000\n...\n*************************** 57. row ***************************\n Type: performance_schema\n Name: performance_schema.memory\nStatus: 26459600\n...\n\nThis statement is intended to help the DBA understand the effects that\ndifferent Performance Schema options have on memory requirements.\n\nName values consist of two parts, which name an internal buffer and a\nbuffer attribute, respectively. Interpret buffer names as follows:\n\no An internal buffer that is not exposed as a table is named within\n parentheses. Examples: (pfs_cond_class).size,\n (pfs_mutex_class).memory.\n\no An internal buffer that is exposed as a table in the\n performance_schema database is named after the table, without\n parentheses. Examples: events_waits_history.size,\n mutex_instances.count.\n\no A value that applies to the Performance Schema as a whole begins with\n performance_schema. Example: performance_schema.memory.\n\nBuffer attributes have these meanings:\n\no size is the size of the internal record used by the implementation,\n such as the size of a row in a table. size values cannot be changed.\n\no count is the number of internal records, such as the number of rows\n in a table. count values can be changed using Performance Schema\n configuration options.\n\no For a table, tbl_name.memory is the product of size and count. For\n the Performance Schema as a whole, performance_schema.memory is the\n sum of all the memory used (the sum of all other memory values).\n\nIn some cases, there is a direct relationship between a Performance\nSchema configuration parameter and a SHOW ENGINE value. For example,\nevents_waits_history_long.count corresponds to\nperformance_schema_events_waits_history_long_size. In other cases, the\nrelationship is more complex. For example, events_waits_history.count\ncorresponds to performance_schema_events_waits_history_size (the number\nof rows per thread) multiplied by\nperformance_schema_max_thread_instances ( the number of threads).\n\nSHOW ENGINE NDB STATUS If the server has the NDB storage engine\nenabled, SHOW ENGINE NDB STATUS displays cluster status information\nsuch as the number of connected data nodes, the cluster connectstring,\nand cluster binary log epochs, as well as counts of various Cluster API\nobjects created by the MySQL Server when connected to the cluster.\nSample output from this statement is shown here:\n\nmysql> SHOW ENGINE NDB STATUS;\n+------------+-----------------------+--------------------------------------------------+\n| Type | Name | Status |\n+------------+-----------------------+--------------------------------------------------+\n| ndbcluster | connection | cluster_node_id=7,\n connected_host=198.51.100.103, connected_port=1186, number_of_data_nodes=4,\n number_of_ready_data_nodes=3, connect_count=0 |\n| ndbcluster | NdbTransaction | created=6, free=0, sizeof=212 |\n| ndbcluster | NdbOperation | created=8, free=8, sizeof=660 |\n| ndbcluster | NdbIndexScanOperation | created=1, free=1, sizeof=744 |\n| ndbcluster | NdbIndexOperation | created=0, free=0, sizeof=664 |\n| ndbcluster | NdbRecAttr | created=1285, free=1285, sizeof=60 |\n| ndbcluster | NdbApiSignal | created=16, free=16, sizeof=136 |\n| ndbcluster | NdbLabel | created=0, free=0, sizeof=196 |\n| ndbcluster | NdbBranch | created=0, free=0, sizeof=24 |\n| ndbcluster | NdbSubroutine | created=0, free=0, sizeof=68 |\n| ndbcluster | NdbCall | created=0, free=0, sizeof=16 |\n| ndbcluster | NdbBlob | created=1, free=1, sizeof=264 |\n| ndbcluster | NdbReceiver | created=4, free=0, sizeof=68 |\n| ndbcluster | binlog | latest_epoch=155467, latest_trans_epoch=148126,\n latest_received_binlog_epoch=0, latest_handled_binlog_epoch=0,\n latest_applied_binlog_epoch=0 |\n+------------+-----------------------+--------------------------------------------------+\n\nThe Status column in each of these rows provides information about the\nMySQL server\'s connection to the cluster and about the cluster binary\nlog\'s status, respectively. The Status information is in the form of\ncomma-delimited set of name/value pairs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-engine.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-engine.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (546,14,'NAME_CONST','Syntax:\nNAME_CONST(name,value)\n\nReturns the given value. When used to produce a result set column,\nNAME_CONST() causes the column to have the given name. The arguments\nshould be constants.\n\nmysql> SELECT NAME_CONST(\'myname\', 14);\n+--------+\n| myname |\n+--------+\n| 14 |\n+--------+\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (547,14,'RELEASE_LOCK','Syntax:\nRELEASE_LOCK(str)\n\nReleases the lock named by the string str that was obtained with\nGET_LOCK(). Returns 1 if the lock was released, 0 if the lock was not\nestablished by this thread (in which case the lock is not released),\nand NULL if the named lock did not exist. The lock does not exist if it\nwas never obtained by a call to GET_LOCK() or if it has previously been\nreleased.\n\nThe DO statement is convenient to use with RELEASE_LOCK(). See [HELP\nDO].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (548,32,'WEEKDAY','Syntax:\nWEEKDAY(date)\n\nReturns the weekday index for date (0 = Monday, 1 = Tuesday, ... 6 =\nSunday).\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT WEEKDAY(\'2008-02-03 22:23:00\');\n -> 6\nmysql> SELECT WEEKDAY(\'2007-11-06\');\n -> 1\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
@@ -643,7 +643,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (562,14,'IS_USED_LOCK','Syntax:\nIS_USED_LOCK(str)\n\nChecks whether the lock named str is in use (that is, locked). If so,\nit returns the connection identifier of the client session that holds\nthe lock. Otherwise, it returns NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (563,4,'POLYFROMTEXT','PolyFromText(wkt[, srid]), PolygonFromText(wkt[, srid])\n\nST_PolyFromText(), ST_PolygonFromText(), PolyFromText(), and\nPolygonFromText() are synonyms. For more information, see the\ndescription of ST_PolyFromText().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (564,37,'ST_SRID','ST_SRID(g)\n\nReturns an integer indicating the spatial reference system ID\nassociated with the geometry value g, or NULL if the argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html\n\n','mysql> SELECT ST_SRID(ST_GeomFromText(\'LineString(1 1,2 2)\',101));\n+-----------------------------------------------------+\n| ST_SRID(ST_GeomFromText(\'LineString(1 1,2 2)\',101)) |\n+-----------------------------------------------------+\n| 101 |\n+-----------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (565,10,'ALTER USER','Syntax:\nALTER USER [IF EXISTS]\n user [auth_option] [, user [auth_option]] ...\n [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]\n [WITH resource_option [resource_option] ...]\n [password_option | lock_option] ...\n\nALTER USER [IF EXISTS]\n USER() IDENTIFIED BY \'auth_string\'\n\nuser:\n (see )\n\nauth_option: {\n IDENTIFIED BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin\n | IDENTIFIED WITH auth_plugin BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin AS \'hash_string\'\n}\n\ntls_option: {\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n}\n\nresource_option: {\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n}\n\npassword_option: {\n PASSWORD EXPIRE\n | PASSWORD EXPIRE DEFAULT\n | PASSWORD EXPIRE NEVER\n | PASSWORD EXPIRE INTERVAL N DAY\n}\n\nlock_option: {\n ACCOUNT LOCK\n | ACCOUNT UNLOCK\n}\n\nThe ALTER USER statement modifies MySQL accounts. It enables\nauthentication, SSL/TLS, resource-limit, and password-management\nproperties to be modified for existing accounts, and enables account\nlocking and unlocking.\n\nTo use ALTER USER, you must have the global CREATE USER privilege or\nthe UPDATE privilege for the mysql database. When the read_only system\nvariable is enabled, ALTER USER additionally requires the SUPER\nprivilege.\n\nBy default, an error occurs if you try to modify a user that does not\nexist. If the IF EXISTS clause is given, the statement produces a\nwarning for each named user that does not exist, rather than an error.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-user.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (565,10,'ALTER USER','Syntax:\nALTER USER [IF EXISTS]\n user [auth_option] [, user [auth_option]] ...\n [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]\n [WITH resource_option [resource_option] ...]\n [password_option | lock_option] ...\n\nALTER USER [IF EXISTS]\n USER() IDENTIFIED BY \'auth_string\'\n\nuser:\n (see )\n\nauth_option: {\n IDENTIFIED BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin\n | IDENTIFIED WITH auth_plugin BY \'auth_string\'\n | IDENTIFIED WITH auth_plugin AS \'hash_string\'\n}\n\ntls_option: {\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n}\n\nresource_option: {\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n}\n\npassword_option: {\n PASSWORD EXPIRE\n | PASSWORD EXPIRE DEFAULT\n | PASSWORD EXPIRE NEVER\n | PASSWORD EXPIRE INTERVAL N DAY\n}\n\nlock_option: {\n ACCOUNT LOCK\n | ACCOUNT UNLOCK\n}\n\nThe ALTER USER statement modifies MySQL accounts. It enables\nauthentication, SSL/TLS, resource-limit, and password-management\nproperties to be modified for existing accounts, and enables account\nlocking and unlocking.\n\nTo use ALTER USER, you must have the global CREATE USER privilege or\nthe UPDATE privilege for the mysql system database. When the read_only\nsystem variable is enabled, ALTER USER additionally requires the SUPER\nprivilege.\n\nBy default, an error occurs if you try to modify a user that does not\nexist. If the IF EXISTS clause is given, the statement produces a\nwarning for each named user that does not exist, rather than an error.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-user.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-user.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (566,12,'DES_ENCRYPT','Syntax:\nDES_ENCRYPT(str[,{key_num|key_str}])\n\nEncrypts the string with the given key using the Triple-DES algorithm.\n\nThis function works only if MySQL has been configured with SSL support.\nSee http://dev.mysql.com/doc/refman/5.7/en/encrypted-connections.html.\n\nThe encryption key to use is chosen based on the second argument to\nDES_ENCRYPT(), if one was given. With no argument, the first key from\nthe DES key file is used. With a key_num argument, the given key number\n(0 to 9) from the DES key file is used. With a key_str argument, the\ngiven key string is used to encrypt str.\n\nThe key file can be specified with the --des-key-file server option.\n\nThe return string is a binary string where the first character is\nCHAR(128 | key_num). If an error occurs, DES_ENCRYPT() returns NULL.\n\nThe 128 is added to make it easier to recognize an encrypted key. If\nyou use a string key, key_num is 127.\n\nThe string length for the result is given by this formula:\n\nnew_len = orig_len + (8 - (orig_len % 8)) + 1\n\nEach line in the DES key file has the following format:\n\nkey_num des_key_str\n\nEach key_num value must be a number in the range from 0 to 9. Lines in\nthe file may be in any order. des_key_str is the string that is used to\nencrypt the message. There should be at least one space between the\nnumber and the key. The first key is the default key that is used if\nyou do not specify any key argument to DES_ENCRYPT().\n\nYou can tell MySQL to read new key values from the key file with the\nFLUSH DES_KEY_FILE statement. This requires the RELOAD privilege.\n\nOne benefit of having a set of default keys is that it gives\napplications a way to check for the existence of encrypted column\nvalues, without giving the end user the right to decrypt those values.\n\n*Note*:\n\nThe DES_ENCRYPT() and DES_DECRYPT() functions are deprecated as of\nMySQL 5.7.6, will be removed in a future MySQL release, and should no\nlonger be used. Consider using AES_ENCRYPT() and AES_DECRYPT() instead.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SELECT customer_address FROM customer_table \n > WHERE crypted_credit_card = DES_ENCRYPT(\'credit_card_number\');\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (567,3,'CEIL','Syntax:\nCEIL(X)\n\nCEIL() is a synonym for CEILING().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (568,7,'WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS','Syntax:\nWAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(gtid_set[, timeout][,channel])\n\nWAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() is similar to\nWAIT_FOR_EXECUTED_GTID_SET() in that it waits until all of the\ntransactions whose global transaction identifiers are contained in\ngtid_set have been applied, or until timeout seconds have elapsed,\nwhichever occurs first. However, WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()\napplies to a specific replication channel, and stops only after the\ntransactions have been applied on the specified channel, for which the\napplier must be running. In contrast, WAIT_FOR_EXECUTED_GTID_SET()\nstops after the transactions have been applied, regardless of where\nthey were applied (on any replication channel or any user client), and\nwhether or not any replication channels are running.\n\nThe channel option names which replication channel the function applies\nto. If no channel is named and no channels other than the default\nreplication channel exist, the function applies to the default\nreplication channel. If multiple replication channels exist, you must\nspecify a channel as otherwise it is not known which replication\nchannel the function applies to. See\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-channels.html for\nmore information on replication channels.\n\n*Note*:\n\nBecause WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() applies to a specific\nreplication channel, if an expected transaction arrives on a different\nreplication channel or from a user client, for example in a failover or\nmanual recovery situation, the function can hang indefinitely if no\ntimeout is set. Use WAIT_FOR_EXECUTED_GTID_SET() instead to ensure\ncorrect handling of transactions in these situations.\n\nGTID sets used with WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() are represented\nas strings and must be quoted in the same way as for\nWAIT_FOR_EXECUTED_GTID_SET(). For WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(),\nthe return value for the function is an arbitrary positive number. If\nGTID-based replication is not active (that is, if the value of the\ngtid_mode variable is OFF), then this value is undefined and\nWAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() returns NULL. If the slave is not\nrunning then the function also returns NULL.\n\ngtid_mode cannot be changed to OFF while any client is using this\nfunction to wait for GTIDs to be applied.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html');
@@ -660,12 +660,12 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (579,40,'DROP PROCEDURE','Syntax:\nDROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name\n\nThis statement is used to drop a stored procedure or function. That is,\nthe specified routine is removed from the server. You must have the\nALTER ROUTINE privilege for the routine. (If the\nautomatic_sp_privileges system variable is enabled, that privilege and\nEXECUTE are granted automatically to the routine creator when the\nroutine is created and dropped from the creator when the routine is\ndropped. See\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-routines-privileges.html.\n)\n\nThe IF EXISTS clause is a MySQL extension. It prevents an error from\noccurring if the procedure or function does not exist. A warning is\nproduced that can be viewed with SHOW WARNINGS.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/drop-procedure.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/drop-procedure.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (580,7,'ST_LATFROMGEOHASH','ST_LatFromGeoHash(geohash_str)\n\nReturns the latitude from a geohash string value, as a DOUBLE value in\nthe range [−90, 90].\n\nIf the argument is NULL, the return value is NULL. If the argument is\ninvalid, an error occurs.\n\nThe ST_LatFromGeoHash() decoding function reads no more than 433\ncharacters from the geohash_str argument. That represents the upper\nlimit on information in the internal representation of coordinate\nvalues. Characters past the 433rd are ignored, even if they are\notherwise illegal and produce an error.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-geohash-functions.html\n\n','mysql> SELECT ST_LatFromGeoHash(ST_GeoHash(45,-20,10));\n+------------------------------------------+\n| ST_LatFromGeoHash(ST_GeoHash(45,-20,10)) |\n+------------------------------------------+\n| -20 |\n+------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-geohash-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (581,7,'ST_GEOMFROMGEOJSON','ST_GeomFromGeoJSON(str [, options [, srid]])\n\nParses a string str representing a GeoJSON object and returns a\ngeometry.\n\nIf any argument is NULL, the return value is NULL. If any non-NULL\nargument is invalid, an error occurs.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-geojson-functions.html\n\n','mysql> SET @json = \'{ "type": "Point", "coordinates": [102.0, 0.0]}\';\nmysql> SELECT ST_AsText(ST_GeomFromGeoJSON(@json));\n+--------------------------------------+\n| ST_AsText(ST_GeomFromGeoJSON(@json)) |\n+--------------------------------------+\n| POINT(102 0) |\n+--------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/spatial-geojson-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (582,5,'INSTALL PLUGIN','Syntax:\nINSTALL PLUGIN plugin_name SONAME \'shared_library_name\'\n\nThis statement installs a server plugin. It requires the INSERT\nprivilege for the mysql.plugin system table.\n\nplugin_name is the name of the plugin as defined in the plugin\ndescriptor structure contained in the library file (see\nhttp://dev.mysql.com/doc/refman/5.7/en/plugin-data-structures.html).\nPlugin names are not case-sensitive. For maximal compatibility, plugin\nnames should be limited to ASCII letters, digits, and underscore\nbecause they are used in C source files, shell command lines, M4 and\nBourne shell scripts, and SQL environments.\n\nshared_library_name is the name of the shared library that contains the\nplugin code. The name includes the file name extension (for example,\nlibmyplugin.so, libmyplugin.dll, or libmyplugin.dylib).\n\nThe shared library must be located in the plugin directory (the\ndirectory named by the plugin_dir system variable). The library must be\nin the plugin directory itself, not in a subdirectory. By default,\nplugin_dir is the plugin directory under the directory named by the\npkglibdir configuration variable, but it can be changed by setting the\nvalue of plugin_dir at server startup. For example, set its value in a\nmy.cnf file:\n\n[mysqld]\nplugin_dir=/path/to/plugin/directory\n\nIf the value of plugin_dir is a relative path name, it is taken to be\nrelative to the MySQL base directory (the value of the basedir system\nvariable).\n\nINSTALL PLUGIN loads and initializes the plugin code to make the plugin\navailable for use. A plugin is initialized by executing its\ninitialization function, which handles any setup that the plugin must\nperform before it can be used. When the server shuts down, it executes\nthe deinitialization function for each plugin that is loaded so that\nthe plugin has a chance to perform any final cleanup.\n\nINSTALL PLUGIN also registers the plugin by adding a line that\nindicates the plugin name and library file name to the mysql.plugin\ntable. At server startup, the server loads and initializes any plugin\nthat is listed in the mysql.plugin table. This means that a plugin is\ninstalled with INSTALL PLUGIN only once, not every time the server\nstarts. Plugin loading at startup does not occur if the server is\nstarted with the --skip-grant-tables option.\n\nA plugin library can contain multiple plugins. For each of them to be\ninstalled, use a separate INSTALL PLUGIN statement. Each statement\nnames a different plugin, but all of them specify the same library\nname.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/install-plugin.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/install-plugin.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (582,5,'INSTALL PLUGIN','Syntax:\nINSTALL PLUGIN plugin_name SONAME \'shared_library_name\'\n\nThis statement installs a server plugin. It requires the INSERT\nprivilege for the mysql.plugin system table.\n\nplugin_name is the name of the plugin as defined in the plugin\ndescriptor structure contained in the library file (see\nhttp://dev.mysql.com/doc/refman/5.7/en/plugin-data-structures.html).\nPlugin names are not case-sensitive. For maximal compatibility, plugin\nnames should be limited to ASCII letters, digits, and underscore\nbecause they are used in C source files, shell command lines, M4 and\nBourne shell scripts, and SQL environments.\n\nshared_library_name is the name of the shared library that contains the\nplugin code. The name includes the file name extension (for example,\nlibmyplugin.so, libmyplugin.dll, or libmyplugin.dylib).\n\nThe shared library must be located in the plugin directory (the\ndirectory named by the plugin_dir system variable). The library must be\nin the plugin directory itself, not in a subdirectory. By default,\nplugin_dir is the plugin directory under the directory named by the\npkglibdir configuration variable, but it can be changed by setting the\nvalue of plugin_dir at server startup. For example, set its value in a\nmy.cnf file:\n\n[mysqld]\nplugin_dir=/path/to/plugin/directory\n\nIf the value of plugin_dir is a relative path name, it is taken to be\nrelative to the MySQL base directory (the value of the basedir system\nvariable).\n\nINSTALL PLUGIN loads and initializes the plugin code to make the plugin\navailable for use. A plugin is initialized by executing its\ninitialization function, which handles any setup that the plugin must\nperform before it can be used. When the server shuts down, it executes\nthe deinitialization function for each plugin that is loaded so that\nthe plugin has a chance to perform any final cleanup.\n\nINSTALL PLUGIN also registers the plugin by adding a line that\nindicates the plugin name and library file name to the mysql.plugin\nsystem table. At server startup, the server loads and initializes any\nplugin that is listed in mysql.plugin. This means that a plugin is\ninstalled with INSTALL PLUGIN only once, not every time the server\nstarts. Plugin loading at startup does not occur if the server is\nstarted with the --skip-grant-tables option.\n\nA plugin library can contain multiple plugins. For each of them to be\ninstalled, use a separate INSTALL PLUGIN statement. Each statement\nnames a different plugin, but all of them specify the same library\nname.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/install-plugin.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/install-plugin.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (583,24,'DECLARE CURSOR','Syntax:\nDECLARE cursor_name CURSOR FOR select_statement\n\nThis statement declares a cursor and associates it with a SELECT\nstatement that retrieves the rows to be traversed by the cursor. To\nfetch the rows later, use a FETCH statement. The number of columns\nretrieved by the SELECT statement must match the number of output\nvariables specified in the FETCH statement.\n\nThe SELECT statement cannot have an INTO clause.\n\nCursor declarations must appear before handler declarations and after\nvariable and condition declarations.\n\nA stored program may contain multiple cursor declarations, but each\ncursor declared in a given block must have a unique name. For an\nexample, see http://dev.mysql.com/doc/refman/5.7/en/cursors.html.\n\nFor information available through SHOW statements, it is possible in\nmany cases to obtain equivalent information by using a cursor with an\nINFORMATION_SCHEMA table.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/declare-cursor.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/declare-cursor.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (584,28,'LOAD DATA','Syntax:\nLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [CHARACTER SET charset_name]\n [{FIELDS | COLUMNS}\n [TERMINATED BY \'string\']\n [[OPTIONALLY] ENCLOSED BY \'char\']\n [ESCAPED BY \'char\']\n ]\n [LINES\n [STARTING BY \'string\']\n [TERMINATED BY \'string\']\n ]\n [IGNORE number {LINES | ROWS}]\n [(col_name_or_user_var\n [, col_name_or_user_var] ...)]\n [SET col_name={expr | DEFAULT},\n [, col_name={expr | DEFAULT}] ...]\n\nThe LOAD DATA INFILE statement reads rows from a text file into a table\nat a very high speed. LOAD DATA INFILE is the complement of SELECT ...\nINTO OUTFILE. (See\nhttp://dev.mysql.com/doc/refman/5.7/en/select-into.html.) To write data\nfrom a table to a file, use SELECT ... INTO OUTFILE. To read the file\nback into a table, use LOAD DATA INFILE. The syntax of the FIELDS and\nLINES clauses is the same for both statements. Both clauses are\noptional, but FIELDS must precede LINES if both are specified.\n\nYou can also load data files by using the mysqlimport utility; it\noperates by sending a LOAD DATA INFILE statement to the server. The\n--local option causes mysqlimport to read data files from the client\nhost. You can specify the --compress option to get better performance\nover slow networks if the client and server support the compressed\nprotocol. See http://dev.mysql.com/doc/refman/5.7/en/mysqlimport.html.\n\nFor more information about the efficiency of INSERT versus LOAD DATA\nINFILE and speeding up LOAD DATA INFILE, see\nhttp://dev.mysql.com/doc/refman/5.7/en/insert-optimization.html.\n\nThe file name must be given as a literal string. On Windows, specify\nbackslashes in path names as forward slashes or doubled backslashes.\nThe character_set_filesystem system variable controls the\ninterpretation of the file name.\n\nLOAD DATA supports explicit partition selection using the PARTITION\noption with a list of one or more comma-separated names of partitions,\nsubpartitions, or both. When this option is used, if any rows from the\nfile cannot be inserted into any of the partitions or subpartitions\nnamed in the list, the statement fails with the error Found a row not\nmatching the given partition set. For more information and examples,\nsee http://dev.mysql.com/doc/refman/5.7/en/partitioning-selection.html.\n\nFor partitioned tables using storage engines that employ table locks,\nsuch as MyISAM, LOAD DATA cannot prune any partition locks. This does\nnot apply to tables using storage engines which employ row-level\nlocking, such as InnoDB. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations-locking\n.html.\n\nThe server uses the character set indicated by the\ncharacter_set_database system variable to interpret the information in\nthe file. SET NAMES and the setting of character_set_client do not\naffect interpretation of input. If the contents of the input file use a\ncharacter set that differs from the default, it is usually preferable\nto specify the character set of the file by using the CHARACTER SET\nclause. A character set of binary specifies "no conversion."\n\nLOAD DATA INFILE interprets all fields in the file as having the same\ncharacter set, regardless of the data types of the columns into which\nfield values are loaded. For proper interpretation of file contents,\nyou must ensure that it was written with the correct character set. For\nexample, if you write a data file with mysqldump -T or by issuing a\nSELECT ... INTO OUTFILE statement in mysql, be sure to use a\n--default-character-set option so that output is written in the\ncharacter set to be used when the file is loaded with LOAD DATA INFILE.\n\n*Note*:\n\nIt is not possible to load data files that use the ucs2, utf16,\nutf16le, or utf32 character set.\n\nIf you use LOW_PRIORITY, execution of the LOAD DATA statement is\ndelayed until no other clients are reading from the table. This affects\nonly storage engines that use only table-level locking (such as MyISAM,\nMEMORY, and MERGE).\n\nIf you specify CONCURRENT with a MyISAM table that satisfies the\ncondition for concurrent inserts (that is, it contains no free blocks\nin the middle), other threads can retrieve data from the table while\nLOAD DATA is executing. This option affects the performance of LOAD\nDATA a bit, even if no other thread is using the table at the same\ntime.\n\nWith row-based replication, CONCURRENT is replicated regardless of\nMySQL version. With statement-based replication CONCURRENT is not\nreplicated prior to MySQL 5.5.1 (see Bug #34628). For more information,\nsee\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-features-load-data.h\ntml.\n\nThe LOCAL keyword affects expected location of the file and error\nhandling, as described later. LOCAL works only if your server and your\nclient both have been configured to permit it. For example, if mysqld\nwas started with the local_infile system variable disabled, LOCAL does\nnot work. See\nhttp://dev.mysql.com/doc/refman/5.7/en/load-data-local.html.\n\nThe LOCAL keyword affects where the file is expected to be found:\n\no If LOCAL is specified, the file is read by the client program on the\n client host and sent to the server. The file can be given as a full\n path name to specify its exact location. If given as a relative path\n name, the name is interpreted relative to the directory in which the\n client program was started.\n\n When using LOCAL with LOAD DATA, a copy of the file is created in the\n server\'s temporary directory. This is not the directory determined by\n the value of tmpdir or slave_load_tmpdir, but rather the operating\n system\'s temporary directory, and is not configurable in the MySQL\n Server. (Typically the system temporary directory is /tmp on Linux\n systems and C:\\WINDOWS\\TEMP on Windows.) Lack of sufficient space for\n the copy in this directory can cause the LOAD DATA LOCAL statement to\n fail.\n\no If LOCAL is not specified, the file must be located on the server\n host and is read directly by the server. The server uses the\n following rules to locate the file:\n\n o If the file name is an absolute path name, the server uses it as\n given.\n\n o If the file name is a relative path name with one or more leading\n components, the server searches for the file relative to the\n server\'s data directory.\n\n o If a file name with no leading components is given, the server\n looks for the file in the database directory of the default\n database.\n\nIn the non-LOCAL case, these rules mean that a file named as\n./myfile.txt is read from the server\'s data directory, whereas the file\nnamed as myfile.txt is read from the database directory of the default\ndatabase. For example, if db1 is the default database, the following\nLOAD DATA statement reads the file data.txt from the database directory\nfor db1, even though the statement explicitly loads the file into a\ntable in the db2 database:\n\nLOAD DATA INFILE \'data.txt\' INTO TABLE db2.my_table;\n\nNon-LOCAL load operations read text files located on the server. For\nsecurity reasons, such operations require that you have the FILE\nprivilege. See\nhttp://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html. Also,\nnon-LOCAL load operations are subject to the secure_file_priv system\nvariable setting. If the variable value is a nonempty directory name,\nthe file to be loaded must be located in that directory. If the\nvariable value is empty (which is insecure), the file need only be\nreadable by the server.\n\nUsing LOCAL is a bit slower than letting the server access the files\ndirectly, because the contents of the file must be sent over the\nconnection by the client to the server. On the other hand, you do not\nneed the FILE privilege to load local files.\n\nLOCAL also affects error handling:\n\no With LOAD DATA INFILE, data-interpretation and duplicate-key errors\n terminate the operation.\n\no With LOAD DATA LOCAL INFILE, data-interpretation and duplicate-key\n errors become warnings and the operation continues because the server\n has no way to stop transmission of the file in the middle of the\n operation. For duplicate-key errors, this is the same as if IGNORE is\n specified. IGNORE is explained further later in this section.\n\nThe REPLACE and IGNORE keywords control handling of input rows that\nduplicate existing rows on unique key values:\n\no If you specify REPLACE, input rows replace existing rows. In other\n words, rows that have the same value for a primary key or unique\n index as an existing row. See [HELP REPLACE].\n\no If you specify IGNORE, rows that duplicate an existing row on a\n unique key value are discarded. For more information, see\n http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#ignore-strict-co\n mparison.\n\no If you do not specify either option, the behavior depends on whether\n the LOCAL keyword is specified. Without LOCAL, an error occurs when a\n duplicate key value is found, and the rest of the text file is\n ignored. With LOCAL, the default behavior is the same as if IGNORE is\n specified; this is because the server has no way to stop transmission\n of the file in the middle of the operation.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/load-data.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/load-data.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (584,28,'LOAD DATA','Syntax:\nLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE tbl_name\n [PARTITION (partition_name [, partition_name] ...)]\n [CHARACTER SET charset_name]\n [{FIELDS | COLUMNS}\n [TERMINATED BY \'string\']\n [[OPTIONALLY] ENCLOSED BY \'char\']\n [ESCAPED BY \'char\']\n ]\n [LINES\n [STARTING BY \'string\']\n [TERMINATED BY \'string\']\n ]\n [IGNORE number {LINES | ROWS}]\n [(col_name_or_user_var\n [, col_name_or_user_var] ...)]\n [SET col_name={expr | DEFAULT},\n [, col_name={expr | DEFAULT}] ...]\n\nThe LOAD DATA INFILE statement reads rows from a text file into a table\nat a very high speed. LOAD DATA INFILE is the complement of SELECT ...\nINTO OUTFILE. (See\nhttp://dev.mysql.com/doc/refman/5.7/en/select-into.html.) To write data\nfrom a table to a file, use SELECT ... INTO OUTFILE. To read the file\nback into a table, use LOAD DATA INFILE. The syntax of the FIELDS and\nLINES clauses is the same for both statements. Both clauses are\noptional, but FIELDS must precede LINES if both are specified.\n\nYou can also load data files by using the mysqlimport utility; it\noperates by sending a LOAD DATA INFILE statement to the server. The\n--local option causes mysqlimport to read data files from the client\nhost. You can specify the --compress option to get better performance\nover slow networks if the client and server support the compressed\nprotocol. See http://dev.mysql.com/doc/refman/5.7/en/mysqlimport.html.\n\nFor more information about the efficiency of INSERT versus LOAD DATA\nINFILE and speeding up LOAD DATA INFILE, see\nhttp://dev.mysql.com/doc/refman/5.7/en/insert-optimization.html.\n\nThe file name must be given as a literal string. On Windows, specify\nbackslashes in path names as forward slashes or doubled backslashes.\nThe character_set_filesystem system variable controls the\ninterpretation of the file name.\n\nLOAD DATA supports explicit partition selection using the PARTITION\noption with a list of one or more comma-separated names of partitions,\nsubpartitions, or both. When this option is used, if any rows from the\nfile cannot be inserted into any of the partitions or subpartitions\nnamed in the list, the statement fails with the error Found a row not\nmatching the given partition set. For more information and examples,\nsee http://dev.mysql.com/doc/refman/5.7/en/partitioning-selection.html.\n\nFor partitioned tables using storage engines that employ table locks,\nsuch as MyISAM, LOAD DATA cannot prune any partition locks. This does\nnot apply to tables using storage engines which employ row-level\nlocking, such as InnoDB. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations-locking\n.html.\n\nThe server uses the character set indicated by the\ncharacter_set_database system variable to interpret the information in\nthe file. SET NAMES and the setting of character_set_client do not\naffect interpretation of input. If the contents of the input file use a\ncharacter set that differs from the default, it is usually preferable\nto specify the character set of the file by using the CHARACTER SET\nclause. A character set of binary specifies "no conversion."\n\nLOAD DATA INFILE interprets all fields in the file as having the same\ncharacter set, regardless of the data types of the columns into which\nfield values are loaded. For proper interpretation of file contents,\nyou must ensure that it was written with the correct character set. For\nexample, if you write a data file with mysqldump -T or by issuing a\nSELECT ... INTO OUTFILE statement in mysql, be sure to use a\n--default-character-set option so that output is written in the\ncharacter set to be used when the file is loaded with LOAD DATA INFILE.\n\n*Note*:\n\nIt is not possible to load data files that use the ucs2, utf16,\nutf16le, or utf32 character set.\n\nIf you use LOW_PRIORITY, execution of the LOAD DATA statement is\ndelayed until no other clients are reading from the table. This affects\nonly storage engines that use only table-level locking (such as MyISAM,\nMEMORY, and MERGE).\n\nIf you specify CONCURRENT with a MyISAM table that satisfies the\ncondition for concurrent inserts (that is, it contains no free blocks\nin the middle), other threads can retrieve data from the table while\nLOAD DATA is executing. This option affects the performance of LOAD\nDATA a bit, even if no other thread is using the table at the same\ntime.\n\nWith row-based replication, CONCURRENT is replicated regardless of\nMySQL version. With statement-based replication CONCURRENT is not\nreplicated prior to MySQL 5.5.1 (see Bug #34628). For more information,\nsee\nhttp://dev.mysql.com/doc/refman/5.7/en/replication-features-load-data.h\ntml.\n\nThe LOCAL keyword affects expected location of the file and error\nhandling, as described later. LOCAL works only if your server and your\nclient both have been configured to permit it. For example, if mysqld\nwas started with the local_infile system variable disabled, LOCAL does\nnot work. See\nhttp://dev.mysql.com/doc/refman/5.7/en/load-data-local.html.\n\nThe LOCAL keyword affects where the file is expected to be found:\n\no If LOCAL is specified, the file is read by the client program on the\n client host and sent to the server. The file can be given as a full\n path name to specify its exact location. If given as a relative path\n name, the name is interpreted relative to the directory in which the\n client program was started.\n\n When using LOCAL with LOAD DATA, a copy of the file is created in the\n directory where the MySQL server stores temporary files. See\n http://dev.mysql.com/doc/refman/5.7/en/temporary-files.html. Lack of\n sufficient space for the copy in this directory can cause the LOAD\n DATA LOCAL statement to fail.\n\no If LOCAL is not specified, the file must be located on the server\n host and is read directly by the server. The server uses the\n following rules to locate the file:\n\n o If the file name is an absolute path name, the server uses it as\n given.\n\n o If the file name is a relative path name with one or more leading\n components, the server searches for the file relative to the\n server\'s data directory.\n\n o If a file name with no leading components is given, the server\n looks for the file in the database directory of the default\n database.\n\nIn the non-LOCAL case, these rules mean that a file named as\n./myfile.txt is read from the server\'s data directory, whereas the file\nnamed as myfile.txt is read from the database directory of the default\ndatabase. For example, if db1 is the default database, the following\nLOAD DATA statement reads the file data.txt from the database directory\nfor db1, even though the statement explicitly loads the file into a\ntable in the db2 database:\n\nLOAD DATA INFILE \'data.txt\' INTO TABLE db2.my_table;\n\nNon-LOCAL load operations read text files located on the server. For\nsecurity reasons, such operations require that you have the FILE\nprivilege. See\nhttp://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html. Also,\nnon-LOCAL load operations are subject to the secure_file_priv system\nvariable setting. If the variable value is a nonempty directory name,\nthe file to be loaded must be located in that directory. If the\nvariable value is empty (which is insecure), the file need only be\nreadable by the server.\n\nUsing LOCAL is a bit slower than letting the server access the files\ndirectly, because the contents of the file must be sent over the\nconnection by the client to the server. On the other hand, you do not\nneed the FILE privilege to load local files.\n\nLOCAL also affects error handling:\n\no With LOAD DATA INFILE, data-interpretation and duplicate-key errors\n terminate the operation.\n\no With LOAD DATA LOCAL INFILE, data-interpretation and duplicate-key\n errors become warnings and the operation continues because the server\n has no way to stop transmission of the file in the middle of the\n operation. For duplicate-key errors, this is the same as if IGNORE is\n specified. IGNORE is explained further later in this section.\n\nThe REPLACE and IGNORE keywords control handling of input rows that\nduplicate existing rows on unique key values:\n\no If you specify REPLACE, input rows replace existing rows. In other\n words, rows that have the same value for a primary key or unique\n index as an existing row. See [HELP REPLACE].\n\no If you specify IGNORE, rows that duplicate an existing row on a\n unique key value are discarded. For more information, see\n http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#ignore-strict-co\n mparison.\n\no If you do not specify either option, the behavior depends on whether\n the LOCAL keyword is specified. Without LOCAL, an error occurs when a\n duplicate key value is found, and the rest of the text file is\n ignored. With LOCAL, the default behavior is the same as if IGNORE is\n specified; this is because the server has no way to stop transmission\n of the file in the middle of the operation.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/load-data.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/load-data.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (585,32,'LOCALTIME','Syntax:\nLOCALTIME, LOCALTIME([fsp])\n\nLOCALTIME and LOCALTIME() are synonyms for NOW().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (586,33,'ST_GEOMFROMWKB','ST_GeomFromWKB(wkb[, srid]), ST_GeometryFromWKB(wkb[, srid])\n\nConstructs a geometry value of any type using its WKB representation\nand SRID.\n\nThe result is NULL if the WKB or SRID argument is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (587,12,'SHA1','Syntax:\nSHA1(str), SHA(str)\n\nCalculates an SHA-1 160-bit checksum for the string, as described in\nRFC 3174 (Secure Hash Algorithm). The value is returned as a string of\n40 hexadecimal digits, or NULL if the argument was NULL. One of the\npossible uses for this function is as a hash key. See the notes at the\nbeginning of this section about storing hash values efficiently. You\ncan also use SHA1() as a cryptographic function for storing passwords.\nSHA() is synonymous with SHA1().\n\nThe return value is a string in the connection character set.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SELECT SHA1(\'abc\');\n -> \'a9993e364706816aba3e25717850c26c9cd0d89d\'\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (587,12,'SHA1','Syntax:\nSHA1(str), SHA(str)\n\nCalculates an SHA-1 160-bit checksum for the string, as described in\nRFC 3174 (Secure Hash Algorithm). The value is returned as a string of\n40 hexadecimal digits, or NULL if the argument was NULL. One of the\npossible uses for this function is as a hash key. See the notes at the\nbeginning of this section about storing hash values efficiently. SHA()\nis synonymous with SHA1().\n\nThe return value is a string in the connection character set.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SELECT SHA1(\'abc\');\n -> \'a9993e364706816aba3e25717850c26c9cd0d89d\'\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (588,23,'BLOB','BLOB[(M)]\n\nA BLOB column with a maximum length of 65,535 (216 − 1) bytes. Each\nBLOB value is stored using a 2-byte length prefix that indicates the\nnumber of bytes in the value.\n\nAn optional length M can be given for this type. If this is done, MySQL\ncreates the column as the smallest BLOB type large enough to hold\nvalues M bytes long.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (589,12,'PASSWORD','Syntax:\nPASSWORD(str)\n\n*Note*:\n\nThis function is deprecated as of MySQL 5.7.6 and will be removed in a\nfuture MySQL release.\n\nReturns a hashed password string calculated from the cleartext password\nstr. The return value is a string in the connection character set, or\nNULL if the argument is NULL. This function is the SQL interface to the\nalgorithm used by the server to encrypt MySQL passwords for storage in\nthe mysql.user grant table.\n\nThe old_passwords system variable controls the password hashing method\nused by the PASSWORD() function. It also influences password hashing\nperformed by CREATE USER and GRANT statements that specify a password\nusing an IDENTIFIED BY clause.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (590,32,'UTC_DATE','Syntax:\nUTC_DATE, UTC_DATE()\n\nReturns the current UTC date as a value in \'YYYY-MM-DD\' or YYYYMMDD\nformat, depending on whether the function is used in a string or\nnumeric context.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT UTC_DATE(), UTC_DATE() + 0;\n -> \'2003-08-14\', 20030814\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
@@ -673,16 +673,16 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (592,23,'BIT','BIT[(M)]\n\nA bit-value type. M indicates the number of bits per value, from 1 to\n64. The default is 1 if M is omitted.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (593,8,'XA','Syntax:\nXA {START|BEGIN} xid [JOIN|RESUME]\n\nXA END xid [SUSPEND [FOR MIGRATE]]\n\nXA PREPARE xid\n\nXA COMMIT xid [ONE PHASE]\n\nXA ROLLBACK xid\n\nXA RECOVER [CONVERT XID]\n\nFor XA START, the JOIN and RESUME clauses are not supported.\n\nFor XA END the SUSPEND [FOR MIGRATE] clause is not supported.\n\nEach XA statement begins with the XA keyword, and most of them require\nan xid value. An xid is an XA transaction identifier. It indicates\nwhich transaction the statement applies to. xid values are supplied by\nthe client, or generated by the MySQL server. An xid value has from one\nto three parts:\n\nxid: gtrid [, bqual [, formatID ]]\n\ngtrid is a global transaction identifier, bqual is a branch qualifier,\nand formatID is a number that identifies the format used by the gtrid\nand bqual values. As indicated by the syntax, bqual and formatID are\noptional. The default bqual value is \'\' if not given. The default\nformatID value is 1 if not given.\n\ngtrid and bqual must be string literals, each up to 64 bytes (not\ncharacters) long. gtrid and bqual can be specified in several ways. You\ncan use a quoted string (\'ab\'), hex string (X\'6162\', 0x6162), or bit\nvalue (b\'nnnn\').\n\nformatID is an unsigned integer.\n\nThe gtrid and bqual values are interpreted in bytes by the MySQL\nserver\'s underlying XA support routines. However, while an SQL\nstatement containing an XA statement is being parsed, the server works\nwith some specific character set. To be safe, write gtrid and bqual as\nhex strings.\n\nxid values typically are generated by the Transaction Manager. Values\ngenerated by one TM must be different from values generated by other\nTMs. A given TM must be able to recognize its own xid values in a list\nof values returned by the XA RECOVER statement.\n\nXA START xid starts an XA transaction with the given xid value. Each XA\ntransaction must have a unique xid value, so the value must not\ncurrently be used by another XA transaction. Uniqueness is assessed\nusing the gtrid and bqual values. All following XA statements for the\nXA transaction must be specified using the same xid value as that given\nin the XA START statement. If you use any of those statements but\nspecify an xid value that does not correspond to some existing XA\ntransaction, an error occurs.\n\nOne or more XA transactions can be part of the same global transaction.\nAll XA transactions within a given global transaction must use the same\ngtrid value in the xid value. For this reason, gtrid values must be\nglobally unique so that there is no ambiguity about which global\ntransaction a given XA transaction is part of. The bqual part of the\nxid value must be different for each XA transaction within a global\ntransaction. (The requirement that bqual values be different is a\nlimitation of the current MySQL XA implementation. It is not part of\nthe XA specification.)\n\nThe XA RECOVER statement returns information for those XA transactions\non the MySQL server that are in the PREPARED state. (See\nhttp://dev.mysql.com/doc/refman/5.7/en/xa-states.html.) The output\nincludes a row for each such XA transaction on the server, regardless\nof which client started it.\n\nXA RECOVER output rows look like this (for an example xid value\nconsisting of the parts \'abc\', \'def\', and 7):\n\nmysql> XA RECOVER;\n+----------+--------------+--------------+--------+\n| formatID | gtrid_length | bqual_length | data |\n+----------+--------------+--------------+--------+\n| 7 | 3 | 3 | abcdef |\n+----------+--------------+--------------+--------+\n\nThe output columns have the following meanings:\n\no formatID is the formatID part of the transaction xid\n\no gtrid_length is the length in bytes of the gtrid part of the xid\n\no bqual_length is the length in bytes of the bqual part of the xid\n\no data is the concatenation of the gtrid and bqual parts of the xid\n\nXID values may contain nonprintable characters. As of MySQL 5.7.5, XA\nRECOVER permits an optional CONVERT XID clause so that clients can\nrequest XID values in hexadecimal.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/xa-statements.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/xa-statements.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (594,7,'EQUALS','Equals(g1, g2)\n\nMBREquals() and Equals() are synonyms. For more information, see the\ndescription of MBREquals().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions-mbr.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (595,2,'CENTROID','Centroid(mpoly)\n\nST_Centroid() and Centroid() are synonyms. For more information, see\nthe description of ST_Centroid().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (595,2,'CENTROID','Centroid({poly|mpoly})\n\nST_Centroid() and Centroid() are synonyms. For more information, see\nthe description of ST_Centroid().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (596,38,'OCTET_LENGTH','Syntax:\nOCTET_LENGTH(str)\n\nOCTET_LENGTH() is a synonym for LENGTH().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (597,32,'UTC_TIMESTAMP','Syntax:\nUTC_TIMESTAMP, UTC_TIMESTAMP([fsp])\n\nReturns the current UTC date and time as a value in \'YYYY-MM-DD\nHH:MM:SS\' or YYYYMMDDHHMMSS format, depending on whether the function\nis used in a string or numeric context.\n\nIf the fsp argument is given to specify a fractional seconds precision\nfrom 0 to 6, the return value includes a fractional seconds part of\nthat many digits.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;\n -> \'2003-08-14 18:08:04\', 20030814180804.000000\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (598,12,'AES_ENCRYPT','Syntax:\nAES_ENCRYPT(str,key_str[,init_vector])\n\nAES_ENCRYPT() and AES_DECRYPT() implement encryption and decryption of\ndata using the official AES (Advanced Encryption Standard) algorithm,\npreviously known as "Rijndael." The AES standard permits various key\nlengths. By default these functions implement AES with a 128-bit key\nlength. As of MySQL 5.7.4, key lengths of 196 or 256 bits can be used,\nas described later. The key length is a trade off between performance\nand security.\n\nAES_ENCRYPT() encrypts the string str using the key string key_str and\nreturns a binary string containing the encrypted output. AES_DECRYPT()\ndecrypts the encrypted string crypt_str using the key string key_str\nand returns the original cleartext string. If either function argument\nis NULL, the function returns NULL.\n\nThe str and crypt_str arguments can be any length, and padding is\nautomatically added to str so it is a multiple of a block as required\nby block-based algorithms such as AES. This padding is automatically\nremoved by the AES_DECRYPT() function. The length of crypt_str can be\ncalculated using this formula:\n\n16 * (trunc(string_length / 16) + 1)\n\nFor a key length of 128 bits, the most secure way to pass a key to the\nkey_str argument is to create a truly random 128-bit value and pass it\nas a binary value. For example:\n\nINSERT INTO t\nVALUES (1,AES_ENCRYPT(\'text\',UNHEX(\'F3229A0B371ED2D9441B830D21A390C3\')));\n\nA passphrase can be used to generate an AES key by hashing the\npassphrase. For example:\n\nINSERT INTO t\nVALUES (1,AES_ENCRYPT(\'text\', UNHEX(SHA2(\'My secret passphrase\',512))));\n\nDo not pass a password or passphrase directly to crypt_str, hash it\nfirst. Previous versions of this documentation suggested the former\napproach, but it is no longer recommended as the examples shown here\nare more secure.\n\nIf AES_DECRYPT() detects invalid data or incorrect padding, it returns\nNULL. However, it is possible for AES_DECRYPT() to return a non-NULL\nvalue (possibly garbage) if the input data or the key is invalid.\n\nAs of MySQL 5.7.4, AES_ENCRYPT() and AES_DECRYPT() permit control of\nthe block encryption mode and take an optional init_vector\ninitialization vector argument:\n\no The block_encryption_mode system variable controls the mode for\n block-based encryption algorithms. Its default value is aes-128-ecb,\n which signifies encryption using a key length of 128 bits and ECB\n mode. For a description of the permitted values of this variable, see\n http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\no The optional init_vector argument provides an initialization vector\n for block encryption modes that require it.\n\nFor modes that require the optional init_vector argument, it must be 16\nbytes or longer (bytes in excess of 16 are ignored). An error occurs if\ninit_vector is missing.\n\nFor modes that do not require init_vector, it is ignored and a warning\nis generated if it is specified.\n\nA random string of bytes to use for the initialization vector can be\nproduced by calling RANDOM_BYTES(16). For encryption modes that require\nan initialization vector, the same vector must be used for encryption\nand decryption.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html\n\n','mysql> SET block_encryption_mode = \'aes-256-cbc\';\nmysql> SET @key_str = SHA2(\'My secret passphrase\',512);\nmysql> SET @init_vector = RANDOM_BYTES(16);\nmysql> SET @crypt_str = AES_ENCRYPT(\'text\',@key_str,@init_vector);\nmysql> SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector);\n+-----------------------------------------------+\n| AES_DECRYPT(@crypt_str,@key_str,@init_vector) |\n+-----------------------------------------------+\n| text |\n+-----------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (599,3,'+','Syntax:\n+\n\nAddition:\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html\n\n','mysql> SELECT 3+5;\n -> 8\n','http://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (600,7,'GTID_SUBTRACT','Syntax:\nGTID_SUBTRACT(set,subset)\n\nGiven two sets of global transaction IDs subset and set, returns only\nthose GTIDs from set that are not in subset.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html\n\n','mysql> SELECT GTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21\')\\G\n*************************** 1. row ***************************\nGTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21\'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:22-57\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\')\\G\n*************************** 1. row ***************************\nGTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:26-57\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24\')\\G\n*************************** 1. row ***************************\nGTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24\'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:21-22:25-57\n1 row in set (0.01 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (600,7,'GTID_SUBTRACT','Syntax:\nGTID_SUBTRACT(set1,set2)\n\nGiven two sets of global transaction IDs set1 and set2, returns only\nthose GTIDs from set1 that are not in set2.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html\n\n','mysql> SELECT GTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21\')\\G\n*************************** 1. row ***************************\nGTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:21\'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:22-57\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\')\\G\n*************************** 1. row ***************************\nGTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25\'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:26-57\n1 row in set (0.00 sec)\n\nmysql> SELECT GTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n -> \'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24\')\\G\n*************************** 1. row ***************************\nGTID_SUBTRACT(\'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57\',\n \'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24\'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:21-22:25-57\n1 row in set (0.01 sec)\n','http://dev.mysql.com/doc/refman/5.7/en/gtid-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (601,14,'INET_NTOA','Syntax:\nINET_NTOA(expr)\n\nGiven a numeric IPv4 network address in network byte order, returns the\ndotted-quad string representation of the address as a string in the\nconnection character set. INET_NTOA() returns NULL if it does not\nunderstand its argument.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html\n\n','mysql> SELECT INET_NTOA(167773449);\n -> \'10.0.5.9\'\n','http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (602,32,'DAYOFWEEK','Syntax:\nDAYOFWEEK(date)\n\nReturns the weekday index for date (1 = Sunday, 2 = Monday, ..., 7 =\nSaturday). These index values correspond to the ODBC standard.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html\n\n','mysql> SELECT DAYOFWEEK(\'2007-02-03\');\n -> 7\n','http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (603,3,'CEILING','Syntax:\nCEILING(X)\n\nReturns the smallest integer value not less than X.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT CEILING(1.23);\n -> 2\nmysql> SELECT CEILING(-1.23);\n -> -1\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (604,27,'SHOW PROCESSLIST','Syntax:\nSHOW [FULL] PROCESSLIST\n\nSHOW PROCESSLIST shows you which threads are running. You can also get\nthis information from the INFORMATION_SCHEMA PROCESSLIST table or the\nmysqladmin processlist command. If you have the PROCESS privilege, you\ncan see all threads. Otherwise, you can see only your own threads (that\nis, threads associated with the MySQL account that you are using). If\nyou do not use the FULL keyword, only the first 100 characters of each\nstatement are shown in the Info field.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-processlist.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-processlist.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (604,27,'SHOW PROCESSLIST','Syntax:\nSHOW [FULL] PROCESSLIST\n\nSHOW PROCESSLIST shows which threads are running. If you have the\nPROCESS privilege, you can see all threads. Otherwise, you can see only\nyour own threads (that is, threads associated with the MySQL account\nthat you are using). If you do not use the FULL keyword, only the first\n100 characters of each statement are shown in the Info field.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/show-processlist.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/show-processlist.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (605,33,'LINEFROMWKB','LineFromWKB(wkb[, srid]), LineStringFromWKB(wkb[, srid])\n\nST_LineFromWKB(), ST_LineStringFromWKB(), LineFromWKB(), and\nLineStringFromWKB() are synonyms. For more information, see the\ndescription of ST_LineFromWKB().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (606,37,'GEOMETRYTYPE','GeometryType(g)\n\nST_GeometryType() and GeometryType() are synonyms. For more\ninformation, see the description of ST_GeometryType().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-general-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (607,40,'CREATE VIEW','Syntax:\nCREATE\n [OR REPLACE]\n [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]\n [DEFINER = { user | CURRENT_USER }]\n [SQL SECURITY { DEFINER | INVOKER }]\n VIEW view_name [(column_list)]\n AS select_statement\n [WITH [CASCADED | LOCAL] CHECK OPTION]\n\nThe CREATE VIEW statement creates a new view, or replaces an existing\nview if the OR REPLACE clause is given. If the view does not exist,\nCREATE OR REPLACE VIEW is the same as CREATE VIEW. If the view does\nexist, CREATE OR REPLACE VIEW replaces it.\n\nFor information about restrictions on view use, see\nhttp://dev.mysql.com/doc/refman/5.7/en/view-restrictions.html.\n\nThe select_statement is a SELECT statement that provides the definition\nof the view. (Selecting from the view selects, in effect, using the\nSELECT statement.) The select_statement can select from base tables or\nother views.\n\nThe view definition is "frozen" at creation time and is not affected by\nsubsequent changes to the definitions of the underlying tables. For\nexample, if a view is defined as SELECT * on a table, new columns added\nto the table later do not become part of the view, and columns dropped\nfrom the table will result in an error when selecting from the view.\n\nThe ALGORITHM clause affects how MySQL processes the view. The DEFINER\nand SQL SECURITY clauses specify the security context to be used when\nchecking access privileges at view invocation time. The WITH CHECK\nOPTION clause can be given to constrain inserts or updates to rows in\ntables referenced by the view. These clauses are described later in\nthis section.\n\nThe CREATE VIEW statement requires the CREATE VIEW privilege for the\nview, and some privilege for each column selected by the SELECT\nstatement. For columns used elsewhere in the SELECT statement, you must\nhave the SELECT privilege. If the OR REPLACE clause is present, you\nmust also have the DROP privilege for the view. CREATE VIEW might also\nrequire the SUPER privilege, depending on the DEFINER value, as\ndescribed later in this section.\n\nWhen a view is referenced, privilege checking occurs as described later\nin this section.\n\nA view belongs to a database. By default, a new view is created in the\ndefault database. To create the view explicitly in a given database,\nuse db_name.view_name syntax to qualify the view name with the database\nname:\n\nCREATE VIEW test.v AS SELECT * FROM t;\n\nUnqualified table or view names in the SELECT statement are also\ninterpreted with respect to the default database. A view can refer to\ntables or views in other databases by qualifying the table or view name\nwith the appropriate database name.\n\nWithin a database, base tables and views share the same namespace, so a\nbase table and a view cannot have the same name.\n\nColumns retrieved by the SELECT statement can be simple references to\ntable columns, or expressions that use functions, constant values,\noperators, and so forth.\n\nA view must have unique column names with no duplicates, just like a\nbase table. By default, the names of the columns retrieved by the\nSELECT statement are used for the view column names. To define explicit\nnames for the view columns, specify the optional column_list clause as\na list of comma-separated identifiers. The number of names in\ncolumn_list must be the same as the number of columns retrieved by the\nSELECT statement.\n\nA view can be created from many kinds of SELECT statements. It can\nrefer to base tables or other views. It can use joins, UNION, and\nsubqueries. The SELECT need not even refer to any tables:\n\nCREATE VIEW v_today (today) AS SELECT CURRENT_DATE;\n\nThe following example defines a view that selects two columns from\nanother table as well as an expression calculated from those columns:\n\nmysql> CREATE TABLE t (qty INT, price INT);\nmysql> INSERT INTO t VALUES(3, 50);\nmysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;\nmysql> SELECT * FROM v;\n+------+-------+-------+\n| qty | price | value |\n+------+-------+-------+\n| 3 | 50 | 150 |\n+------+-------+-------+\n\nA view definition is subject to the following restrictions:\n\no The SELECT statement cannot refer to system variables or user-defined\n variables.\n\no Within a stored program, the SELECT statement cannot refer to program\n parameters or local variables.\n\no The SELECT statement cannot refer to prepared statement parameters.\n\no Any table or view referred to in the definition must exist. If, after\n the view has been created, a table or view that the definition refers\n to is dropped, use of the view results in an error. To check a view\n definition for problems of this kind, use the CHECK TABLE statement.\n\no The definition cannot refer to a TEMPORARY table, and you cannot\n create a TEMPORARY view.\n\no You cannot associate a trigger with a view.\n\no Aliases for column names in the SELECT statement are checked against\n the maximum column length of 64 characters (not the maximum alias\n length of 256 characters).\n\nORDER BY is permitted in a view definition, but it is ignored if you\nselect from a view using a statement that has its own ORDER BY.\n\nFor other options or clauses in the definition, they are added to the\noptions or clauses of the statement that references the view, but the\neffect is undefined. For example, if a view definition includes a LIMIT\nclause, and you select from the view using a statement that has its own\nLIMIT clause, it is undefined which limit applies. This same principle\napplies to options such as ALL, DISTINCT, or SQL_SMALL_RESULT that\nfollow the SELECT keyword, and to clauses such as INTO, FOR UPDATE,\nLOCK IN SHARE MODE, and PROCEDURE.\n\nThe results obtained from a view may be affected if you change the\nquery processing environment by changing system variables:\n\nmysql> CREATE VIEW v (mycol) AS SELECT \'abc\';\nQuery OK, 0 rows affected (0.01 sec)\n\nmysql> SET sql_mode = \'\';\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT "mycol" FROM v;\n+-------+\n| mycol |\n+-------+\n| mycol |\n+-------+\n1 row in set (0.01 sec)\n\nmysql> SET sql_mode = \'ANSI_QUOTES\';\nQuery OK, 0 rows affected (0.00 sec)\n\nmysql> SELECT "mycol" FROM v;\n+-------+\n| mycol |\n+-------+\n| abc |\n+-------+\n1 row in set (0.00 sec)\n\nThe DEFINER and SQL SECURITY clauses determine which MySQL account to\nuse when checking access privileges for the view when a statement is\nexecuted that references the view. The valid SQL SECURITY\ncharacteristic values are DEFINER (the default) and INVOKER. These\nindicate that the required privileges must be held by the user who\ndefined or invoked the view, respectively.\n\nIf a user value is given for the DEFINER clause, it should be a MySQL\naccount specified as \'user_name\'@\'host_name\', CURRENT_USER, or\nCURRENT_USER(). The default DEFINER value is the user who executes the\nCREATE VIEW statement. This is the same as specifying DEFINER =\nCURRENT_USER explicitly.\n\nIf the DEFINER clause is present, these rules determine the valid\nDEFINER user values:\n\no If you do not have the SUPER privilege, the only valid user value is\n your own account, either specified literally or by using\n CURRENT_USER. You cannot set the definer to some other account.\n\no If you have the SUPER privilege, you can specify any syntactically\n valid account name. If the account does not exist, a warning is\n generated.\n\no Although it is possible to create a view with a nonexistent DEFINER\n account, an error occurs when the view is referenced if the SQL\n SECURITY value is DEFINER but the definer account does not exist.\n\nFor more information about view security, see\nhttp://dev.mysql.com/doc/refman/5.7/en/stored-programs-security.html.\n\nWithin a view definition, CURRENT_USER returns the view\'s DEFINER value\nby default. For views defined with the SQL SECURITY INVOKER\ncharacteristic, CURRENT_USER returns the account for the view\'s\ninvoker. For information about user auditing within views, see\nhttp://dev.mysql.com/doc/refman/5.7/en/account-activity-auditing.html.\n\nWithin a stored routine that is defined with the SQL SECURITY DEFINER\ncharacteristic, CURRENT_USER returns the routine\'s DEFINER value. This\nalso affects a view defined within such a routine, if the view\ndefinition contains a DEFINER value of CURRENT_USER.\n\nMySQL checks view privileges like this:\n\no At view definition time, the view creator must have the privileges\n needed to use the top-level objects accessed by the view. For\n example, if the view definition refers to table columns, the creator\n must have some privilege for each column in the select list of the\n definition, and the SELECT privilege for each column used elsewhere\n in the definition. If the definition refers to a stored function,\n only the privileges needed to invoke the function can be checked. The\n privileges required at function invocation time can be checked only\n as it executes: For different invocations, different execution paths\n within the function might be taken.\n\no The user who references a view must have appropriate privileges to\n access it (SELECT to select from it, INSERT to insert into it, and so\n forth.)\n\no When a view has been referenced, privileges for objects accessed by\n the view are checked against the privileges held by the view DEFINER\n account or invoker, depending on whether the SQL SECURITY\n characteristic is DEFINER or INVOKER, respectively.\n\no If reference to a view causes execution of a stored function,\n privilege checking for statements executed within the function depend\n on whether the function SQL SECURITY characteristic is DEFINER or\n INVOKER. If the security characteristic is DEFINER, the function runs\n with the privileges of the DEFINER account. If the characteristic is\n INVOKER, the function runs with the privileges determined by the\n view\'s SQL SECURITY characteristic.\n\nExample: A view might depend on a stored function, and that function\nmight invoke other stored routines. For example, the following view\ninvokes a stored function f():\n\nCREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);\n\nSuppose that f() contains a statement such as this:\n\nIF name IS NULL then\n CALL p1();\nELSE\n CALL p2();\nEND IF;\n\nThe privileges required for executing statements within f() need to be\nchecked when f() executes. This might mean that privileges are needed\nfor p1() or p2(), depending on the execution path within f(). Those\nprivileges must be checked at runtime, and the user who must possess\nthe privileges is determined by the SQL SECURITY values of the view v\nand the function f().\n\nThe DEFINER and SQL SECURITY clauses for views are extensions to\nstandard SQL. In standard SQL, views are handled using the rules for\nSQL SECURITY DEFINER. The standard says that the definer of the view,\nwhich is the same as the owner of the view\'s schema, gets applicable\nprivileges on the view (for example, SELECT) and may grant them. MySQL\nhas no concept of a schema "owner", so MySQL adds a clause to identify\nthe definer. The DEFINER clause is an extension where the intent is to\nhave what the standard has; that is, a permanent record of who defined\nthe view. This is why the default DEFINER value is the account of the\nview creator.\n\nThe optional ALGORITHM clause is a MySQL extension to standard SQL. It\naffects how MySQL processes the view. ALGORITHM takes three values:\nMERGE, TEMPTABLE, or UNDEFINED. For more information, see\nhttp://dev.mysql.com/doc/refman/5.7/en/view-algorithms.html, as well as\nhttp://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html.\n\nSome views are updatable. That is, you can use them in statements such\nas UPDATE, DELETE, or INSERT to update the contents of the underlying\ntable. For a view to be updatable, there must be a one-to-one\nrelationship between the rows in the view and the rows in the\nunderlying table. There are also certain other constructs that make a\nview nonupdatable.\n\nA generated column in a view is considered updatable because it is\npossible to assign to it. However, if such a column is updated\nexplicitly, the only permitted value is DEFAULT. For information about\ngenerated columns, see\nhttp://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.h\ntml.\n\nThe WITH CHECK OPTION clause can be given for an updatable view to\nprevent inserts or updates to rows except those for which the WHERE\nclause in the select_statement is true.\n\nIn a WITH CHECK OPTION clause for an updatable view, the LOCAL and\nCASCADED keywords determine the scope of check testing when the view is\ndefined in terms of another view. The LOCAL keyword restricts the CHECK\nOPTION only to the view being defined. CASCADED causes the checks for\nunderlying views to be evaluated as well. When neither keyword is\ngiven, the default is CASCADED.\n\nFor more information about updatable views and the WITH CHECK OPTION\nclause, see\nhttp://dev.mysql.com/doc/refman/5.7/en/view-updatability.html, and\nhttp://dev.mysql.com/doc/refman/5.7/en/view-check-option.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-view.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/create-view.html');
@@ -694,14 +694,14 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (613,7,'JSON_DEPTH','Syntax:\nJSON_DEPTH(json_doc)\n\nReturns the maximum depth of a JSON document. Returns NULL if the\nargument is NULL. An error occurs if the argument is not a valid JSON\ndocument.\n\nAn empty array, empty object, or scalar value has depth 1. A nonempty\narray containing only elements of depth 1 or nonempty object containing\nonly member values of depth 1 has depth 2. Otherwise, a JSON document\nhas depth greater than 2.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html\n\n','mysql> SELECT JSON_DEPTH(\'{}\'), JSON_DEPTH(\'[]\'), JSON_DEPTH(\'true\');\n+------------------+------------------+--------------------+\n| JSON_DEPTH(\'{}\') | JSON_DEPTH(\'[]\') | JSON_DEPTH(\'true\') |\n+------------------+------------------+--------------------+\n| 1 | 1 | 1 |\n+------------------+------------------+--------------------+\nmysql> SELECT JSON_DEPTH(\'[10, 20]\'), JSON_DEPTH(\'[[], {}]\');\n+------------------------+------------------------+\n| JSON_DEPTH(\'[10, 20]\') | JSON_DEPTH(\'[[], {}]\') |\n+------------------------+------------------------+\n| 2 | 2 |\n+------------------------+------------------------+\nmysql> SELECT JSON_DEPTH(\'[10, {"a": 20}]\');\n+-------------------------------+\n| JSON_DEPTH(\'[10, {"a": 20}]\') |\n+-------------------------------+\n| 3 |\n+-------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (614,24,'LABELS','Syntax:\n[begin_label:] BEGIN\n [statement_list]\nEND [end_label]\n\n[begin_label:] LOOP\n statement_list\nEND LOOP [end_label]\n\n[begin_label:] REPEAT\n statement_list\nUNTIL search_condition\nEND REPEAT [end_label]\n\n[begin_label:] WHILE search_condition DO\n statement_list\nEND WHILE [end_label]\n\nLabels are permitted for BEGIN ... END blocks and for the LOOP, REPEAT,\nand WHILE statements. Label use for those statements follows these\nrules:\n\no begin_label must be followed by a colon.\n\no begin_label can be given without end_label. If end_label is present,\n it must be the same as begin_label.\n\no end_label cannot be given without begin_label.\n\no Labels at the same nesting level must be distinct.\n\no Labels can be up to 16 characters long.\n\nTo refer to a label within the labeled construct, use an ITERATE or\nLEAVE statement. The following example uses those statements to\ncontinue iterating or terminate the loop:\n\nCREATE PROCEDURE doiterate(p1 INT)\nBEGIN\n label1: LOOP\n SET p1 = p1 + 1;\n IF p1 < 10 THEN ITERATE label1; END IF;\n LEAVE label1;\n END LOOP label1;\nEND;\n\nThe scope of a block label does not include the code for handlers\ndeclared within the block. For details, see [HELP DECLARE HANDLER].\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/statement-labels.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/statement-labels.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (615,33,'MPOINTFROMWKB','MPointFromWKB(wkb[, srid]), MultiPointFromWKB(wkb[, srid])\n\nST_MPointFromWKB(), ST_MultiPointFromWKB(), MPointFromWKB(), and\nMultiPointFromWKB() are synonyms. For more information, see the\ndescription of ST_MPointFromWKB().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkb-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (616,40,'ALTER TABLE','Syntax:\nALTER TABLE tbl_name\n [alter_specification [, alter_specification] ...]\n [partition_options]\n\nalter_specification:\n table_options\n | ADD [COLUMN] col_name column_definition\n [FIRST | AFTER col_name]\n | ADD [COLUMN] (col_name column_definition,...)\n | ADD {INDEX|KEY} [index_name]\n [index_type] (index_col_name,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]] PRIMARY KEY\n [index_type] (index_col_name,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]]\n UNIQUE [INDEX|KEY] [index_name]\n [index_type] (index_col_name,...) [index_option] ...\n | ADD FULLTEXT [INDEX|KEY] [index_name]\n (index_col_name,...) [index_option] ...\n | ADD SPATIAL [INDEX|KEY] [index_name]\n (index_col_name,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]]\n FOREIGN KEY [index_name] (index_col_name,...)\n reference_definition\n | ALGORITHM [=] {DEFAULT|INPLACE|COPY}\n | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}\n | CHANGE [COLUMN] old_col_name new_col_name column_definition\n [FIRST|AFTER col_name]\n | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]\n | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n | {DISABLE|ENABLE} KEYS\n | {DISCARD|IMPORT} TABLESPACE\n | DROP [COLUMN] col_name\n | DROP {INDEX|KEY} index_name\n | DROP PRIMARY KEY\n | DROP FOREIGN KEY fk_symbol\n | FORCE\n | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n | MODIFY [COLUMN] col_name column_definition\n [FIRST | AFTER col_name]\n | ORDER BY col_name [, col_name] ...\n | RENAME {INDEX|KEY} old_index_name TO new_index_name\n | RENAME [TO|AS] new_tbl_name\n | {WITHOUT|WITH} VALIDATION\n | ADD PARTITION (partition_definition)\n | DROP PARTITION partition_names\n | DISCARD PARTITION {partition_names | ALL} TABLESPACE\n | IMPORT PARTITION {partition_names | ALL} TABLESPACE\n | TRUNCATE PARTITION {partition_names | ALL}\n | COALESCE PARTITION number\n | REORGANIZE PARTITION partition_names INTO (partition_definitions)\n | EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH|WITHOUT} VALIDATION]\n | ANALYZE PARTITION {partition_names | ALL}\n | CHECK PARTITION {partition_names | ALL}\n | OPTIMIZE PARTITION {partition_names | ALL}\n | REBUILD PARTITION {partition_names | ALL}\n | REPAIR PARTITION {partition_names | ALL}\n | REMOVE PARTITIONING\n | UPGRADE PARTITIONING\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\ntable_options:\n table_option [[,] table_option] ...\n\ntable_option:\n AUTO_INCREMENT [=] value\n | AVG_ROW_LENGTH [=] value\n | [DEFAULT] CHARACTER SET [=] charset_name\n | CHECKSUM [=] {0 | 1}\n | [DEFAULT] COLLATE [=] collation_name\n | COMMENT [=] \'string\'\n | COMPRESSION [=] {\'ZLIB\'|\'LZ4\'|\'NONE\'}\n | CONNECTION [=] \'connect_string\'\n | {DATA|INDEX} DIRECTORY [=] \'absolute path to directory\'\n | DELAY_KEY_WRITE [=] {0 | 1}\n | ENCRYPTION [=] {\'Y\' | \'N\'}\n | ENGINE [=] engine_name\n | INSERT_METHOD [=] { NO | FIRST | LAST }\n | KEY_BLOCK_SIZE [=] value\n | MAX_ROWS [=] value\n | MIN_ROWS [=] value\n | PACK_KEYS [=] {0 | 1 | DEFAULT}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}\n | STATS_AUTO_RECALC [=] {DEFAULT|0|1}\n | STATS_PERSISTENT [=] {DEFAULT|0|1}\n | STATS_SAMPLE_PAGES [=] value\n | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]\n | UNION [=] (tbl_name[,tbl_name]...)\n\npartition_options:\n (see CREATE TABLE options)\n\nALTER TABLE changes the structure of a table. For example, you can add\nor delete columns, create or destroy indexes, change the type of\nexisting columns, or rename columns or the table itself. You can also\nchange characteristics such as the storage engine used for the table or\nthe table comment.\n\no To use ALTER TABLE, you need ALTER, CREATE, and INSERT privileges for\n the table. Renaming a table requires ALTER and DROP on the old table,\n ALTER, CREATE, and INSERT on the new table.\n\no Following the table name, specify the alterations to be made. If none\n are given, ALTER TABLE does nothing.\n\no The syntax for many of the permissible alterations is similar to\n clauses of the CREATE TABLE statement. column_definition clauses use\n the same syntax for ADD and CHANGE as for CREATE TABLE. For more\n information, see [HELP CREATE TABLE].\n\no The word COLUMN is optional and can be omitted.\n\no Multiple ADD, ALTER, DROP, and CHANGE clauses are permitted in a\n single ALTER TABLE statement, separated by commas. This is a MySQL\n extension to standard SQL, which permits only one of each clause per\n ALTER TABLE statement. For example, to drop multiple columns in a\n single statement, do this:\n\nALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;\n\no If a storage engine does not support an attempted ALTER TABLE\n operation, a warning may result. Such warnings can be displayed with\n SHOW WARNINGS. See [HELP SHOW WARNINGS]. For information on\n troubleshooting ALTER TABLE, see\n http://dev.mysql.com/doc/refman/5.7/en/alter-table-problems.html.\n\no For information about generated columns, see\n http://dev.mysql.com/doc/refman/5.7/en/alter-table-generated-columns.\n html.\n\no For usage examples, see\n http://dev.mysql.com/doc/refman/5.7/en/alter-table-examples.html.\n\no With the mysql_info() C API function, you can find out how many rows\n were copied by ALTER TABLE. See\n http://dev.mysql.com/doc/refman/5.7/en/mysql-info.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-table.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (616,40,'ALTER TABLE','Syntax:\nALTER TABLE tbl_name\n [alter_specification [, alter_specification] ...]\n [partition_options]\n\nalter_specification:\n table_options\n | ADD [COLUMN] col_name column_definition\n [FIRST | AFTER col_name]\n | ADD [COLUMN] (col_name column_definition,...)\n | ADD {INDEX|KEY} [index_name]\n [index_type] (key_part,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]] PRIMARY KEY\n [index_type] (key_part,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]]\n UNIQUE [INDEX|KEY] [index_name]\n [index_type] (key_part,...) [index_option] ...\n | ADD FULLTEXT [INDEX|KEY] [index_name]\n (key_part,...) [index_option] ...\n | ADD SPATIAL [INDEX|KEY] [index_name]\n (key_part,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]]\n FOREIGN KEY [index_name] (col_name,...)\n reference_definition\n | ALGORITHM [=] {DEFAULT|INPLACE|COPY}\n | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}\n | CHANGE [COLUMN] old_col_name new_col_name column_definition\n [FIRST|AFTER col_name]\n | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]\n | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n | {DISABLE|ENABLE} KEYS\n | {DISCARD|IMPORT} TABLESPACE\n | DROP [COLUMN] col_name\n | DROP {INDEX|KEY} index_name\n | DROP PRIMARY KEY\n | DROP FOREIGN KEY fk_symbol\n | FORCE\n | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n | MODIFY [COLUMN] col_name column_definition\n [FIRST | AFTER col_name]\n | ORDER BY col_name [, col_name] ...\n | RENAME {INDEX|KEY} old_index_name TO new_index_name\n | RENAME [TO|AS] new_tbl_name\n | {WITHOUT|WITH} VALIDATION\n | ADD PARTITION (partition_definition)\n | DROP PARTITION partition_names\n | DISCARD PARTITION {partition_names | ALL} TABLESPACE\n | IMPORT PARTITION {partition_names | ALL} TABLESPACE\n | TRUNCATE PARTITION {partition_names | ALL}\n | COALESCE PARTITION number\n | REORGANIZE PARTITION partition_names INTO (partition_definitions)\n | EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH|WITHOUT} VALIDATION]\n | ANALYZE PARTITION {partition_names | ALL}\n | CHECK PARTITION {partition_names | ALL}\n | OPTIMIZE PARTITION {partition_names | ALL}\n | REBUILD PARTITION {partition_names | ALL}\n | REPAIR PARTITION {partition_names | ALL}\n | REMOVE PARTITIONING\n | UPGRADE PARTITIONING\n\nkey_part:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\ntable_options:\n table_option [[,] table_option] ...\n\ntable_option:\n AUTO_INCREMENT [=] value\n | AVG_ROW_LENGTH [=] value\n | [DEFAULT] CHARACTER SET [=] charset_name\n | CHECKSUM [=] {0 | 1}\n | [DEFAULT] COLLATE [=] collation_name\n | COMMENT [=] \'string\'\n | COMPRESSION [=] {\'ZLIB\'|\'LZ4\'|\'NONE\'}\n | CONNECTION [=] \'connect_string\'\n | {DATA|INDEX} DIRECTORY [=] \'absolute path to directory\'\n | DELAY_KEY_WRITE [=] {0 | 1}\n | ENCRYPTION [=] {\'Y\' | \'N\'}\n | ENGINE [=] engine_name\n | INSERT_METHOD [=] { NO | FIRST | LAST }\n | KEY_BLOCK_SIZE [=] value\n | MAX_ROWS [=] value\n | MIN_ROWS [=] value\n | PACK_KEYS [=] {0 | 1 | DEFAULT}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}\n | STATS_AUTO_RECALC [=] {DEFAULT|0|1}\n | STATS_PERSISTENT [=] {DEFAULT|0|1}\n | STATS_SAMPLE_PAGES [=] value\n | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]\n | UNION [=] (tbl_name[,tbl_name]...)\n\npartition_options:\n (see CREATE TABLE options)\n\nALTER TABLE changes the structure of a table. For example, you can add\nor delete columns, create or destroy indexes, change the type of\nexisting columns, or rename columns or the table itself. You can also\nchange characteristics such as the storage engine used for the table or\nthe table comment.\n\no To use ALTER TABLE, you need ALTER, CREATE, and INSERT privileges for\n the table. Renaming a table requires ALTER and DROP on the old table,\n ALTER, CREATE, and INSERT on the new table.\n\no Following the table name, specify the alterations to be made. If none\n are given, ALTER TABLE does nothing.\n\no The syntax for many of the permissible alterations is similar to\n clauses of the CREATE TABLE statement. column_definition clauses use\n the same syntax for ADD and CHANGE as for CREATE TABLE. For more\n information, see [HELP CREATE TABLE].\n\no The word COLUMN is optional and can be omitted.\n\no Multiple ADD, ALTER, DROP, and CHANGE clauses are permitted in a\n single ALTER TABLE statement, separated by commas. This is a MySQL\n extension to standard SQL, which permits only one of each clause per\n ALTER TABLE statement. For example, to drop multiple columns in a\n single statement, do this:\n\nALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;\n\no If a storage engine does not support an attempted ALTER TABLE\n operation, a warning may result. Such warnings can be displayed with\n SHOW WARNINGS. See [HELP SHOW WARNINGS]. For information on\n troubleshooting ALTER TABLE, see\n http://dev.mysql.com/doc/refman/5.7/en/alter-table-problems.html.\n\no For information about generated columns, see\n http://dev.mysql.com/doc/refman/5.7/en/alter-table-generated-columns.\n html.\n\no For usage examples, see\n http://dev.mysql.com/doc/refman/5.7/en/alter-table-examples.html.\n\no With the mysql_info() C API function, you can find out how many rows\n were copied by ALTER TABLE. See\n http://dev.mysql.com/doc/refman/5.7/en/mysql-info.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-table.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (617,23,'CHAR BYTE','The CHAR BYTE data type is an alias for the BINARY data type. This is a\ncompatibility feature.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (618,4,'ST_MLINEFROMTEXT','ST_MLineFromText(wkt[, srid]), ST_MultiLineStringFromText(wkt[, srid])\n\nConstructs a MultiLineString value using its WKT representation and\nSRID.\n\nIf the geometry argument is NULL or not a syntactically well-formed\ngeometry, or if the SRID argument is NULL, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/gis-wkt-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (619,20,'>','Syntax:\n>\n\nGreater than:\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT 2 > 2;\n -> 0\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (620,21,'ANALYZE TABLE','Syntax:\nANALYZE [NO_WRITE_TO_BINLOG | LOCAL]\n TABLE tbl_name [, tbl_name] ...\n\nANALYZE TABLE performs a key distribution analysis and stores the\ndistribution for the named table or tables. For MyISAM tables, this\nstatement is equivalent to using myisamchk --analyze.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nANALYZE TABLE works with InnoDB, NDB, and MyISAM tables. It does not\nwork with views.\n\nANALYZE TABLE is supported for partitioned tables, and you can use\nALTER TABLE ... ANALYZE PARTITION to analyze one or more partitions;\nfor more information, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.7/en/partitioning-maintenance.html.\n\nDuring the analysis, the table is locked with a read lock for InnoDB\nand MyISAM.\n\nBy default, the server writes ANALYZE TABLE statements to the binary\nlog so that they replicate to replication slaves. To suppress logging,\nspecify the optional NO_WRITE_TO_BINLOG keyword or its alias LOCAL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/analyze-table.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/analyze-table.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (621,2,'ST_EXTERIORRING','ST_ExteriorRing(poly)\n\nReturns the exterior ring of the Polygon value poly as a LineString. If\nthe argument is NULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n -> \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nmysql> SELECT ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly)));\n+----------------------------------------------------+\n| ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly))) |\n+----------------------------------------------------+\n| LINESTRING(0 0,0 3,3 3,3 0,0 0) |\n+----------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (621,2,'ST_EXTERIORRING','ST_ExteriorRing(poly)\n\nReturns the exterior ring of the Polygon value poly as a LineString. If\nthe argument is NULL or an empty geometry, the return value is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html\n\n','mysql> SET @poly =\n \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nmysql> SELECT ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly)));\n+----------------------------------------------------+\n| ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly))) |\n+----------------------------------------------------+\n| LINESTRING(0 0,0 3,3 3,3 0,0 0) |\n+----------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.7/en/gis-polygon-property-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (622,38,'FIELD','Syntax:\nFIELD(str,str1,str2,str3,...)\n\nReturns the index (position) of str in the str1, str2, str3, ... list.\nReturns 0 if str is not found.\n\nIf all arguments to FIELD() are strings, all arguments are compared as\nstrings. If all arguments are numbers, they are compared as numbers.\nOtherwise, the arguments are compared as double.\n\nIf str is NULL, the return value is 0 because NULL fails equality\ncomparison with any value. FIELD() is the complement of ELT().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-functions.html\n\n','mysql> SELECT FIELD(\'Bb\', \'Aa\', \'Bb\', \'Cc\', \'Dd\', \'Ff\');\n -> 2\nmysql> SELECT FIELD(\'Gg\', \'Aa\', \'Bb\', \'Cc\', \'Dd\', \'Ff\');\n -> 0\n','http://dev.mysql.com/doc/refman/5.7/en/string-functions.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (623,40,'CONSTRAINT','MySQL supports foreign keys, which let you cross-reference related data\nacross tables, and foreign key constraints, which help keep this\nspread-out data consistent. The essential syntax for a foreign key\nconstraint definition in a CREATE TABLE or ALTER TABLE statement looks\nlike this:\n\n[CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (index_col_name, ...)\n REFERENCES tbl_name (index_col_name,...)\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html\n\n','CREATE TABLE product (\n category INT NOT NULL, id INT NOT NULL,\n price DECIMAL,\n PRIMARY KEY(category, id)\n) ENGINE=INNODB;\n\nCREATE TABLE customer (\n id INT NOT NULL,\n PRIMARY KEY (id)\n) ENGINE=INNODB;\n\nCREATE TABLE product_order (\n no INT NOT NULL AUTO_INCREMENT,\n product_category INT NOT NULL,\n product_id INT NOT NULL,\n customer_id INT NOT NULL,\n\n PRIMARY KEY(no),\n INDEX (product_category, product_id),\n INDEX (customer_id),\n\n FOREIGN KEY (product_category, product_id)\n REFERENCES product(category, id)\n ON UPDATE CASCADE ON DELETE RESTRICT,\n\n FOREIGN KEY (customer_id)\n REFERENCES customer(id)\n) ENGINE=INNODB;\n','http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (623,40,'CONSTRAINT','MySQL supports foreign keys, which let you cross-reference related data\nacross tables, and foreign key constraints, which help keep this\nspread-out data consistent. The essential syntax for a foreign key\nconstraint definition in a CREATE TABLE or ALTER TABLE statement looks\nlike this:\n\n[CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (col_name, ...)\n REFERENCES tbl_name (col_name,...)\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html\n\n','CREATE TABLE product (\n category INT NOT NULL, id INT NOT NULL,\n price DECIMAL,\n PRIMARY KEY(category, id)\n) ENGINE=INNODB;\n\nCREATE TABLE customer (\n id INT NOT NULL,\n PRIMARY KEY (id)\n) ENGINE=INNODB;\n\nCREATE TABLE product_order (\n no INT NOT NULL AUTO_INCREMENT,\n product_category INT NOT NULL,\n product_id INT NOT NULL,\n customer_id INT NOT NULL,\n\n PRIMARY KEY(no),\n INDEX (product_category, product_id),\n INDEX (customer_id),\n\n FOREIGN KEY (product_category, product_id)\n REFERENCES product(category, id)\n ON UPDATE CASCADE ON DELETE RESTRICT,\n\n FOREIGN KEY (customer_id)\n REFERENCES customer(id)\n) ENGINE=INNODB;\n','http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (624,7,'CREATE_ASYMMETRIC_PRIV_KEY','Syntax:\nCREATE_ASYMMETRIC_PRIV_KEY(algorithm, {key_len|dh_secret})\n\nCreates a private key using the given algorithm and key length or DH\nsecret, and returns the key as a binary string in PEM format. If key\ngeneration fails, the result is NULL.\n\nSupported algorithm values: \'RSA\', \'DSA\', \'DH\'\n\nSupported key_len values: The minimum key length in bits is 1,024. The\nmaximum key length depends on the algorithm: 16,384 for RSA and 10,000\nfor DSA. These key-length limits are constraints imposed by OpenSSL.\nServer administrators can impose additional limits on maximum key\nlength by setting environment variables. See\nhttp://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-usage.html\n.\n\nFor DH keys, pass a shared DH secret instead of a key length. To create\nthe secret, pass the key length to CREATE_DH_PARAMETERS().\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html\n\n','SET @priv = CREATE_ASYMMETRIC_PRIV_KEY(\'DSA\', 2048);\nSET @pub = CREATE_ASYMMETRIC_PUB_KEY(\'DSA\', @priv);\n','http://dev.mysql.com/doc/refman/5.7/en/enterprise-encryption-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (625,40,'ALTER TABLESPACE','Syntax:\nALTER TABLESPACE tablespace_name\n {ADD|DROP} DATAFILE \'file_name\'\n [INITIAL_SIZE [=] size]\n [WAIT]\n ENGINE [=] engine_name\n\nThis statement can be used either to add a new data file, or to drop a\ndata file from a tablespace.\n\nThe ADD DATAFILE variant enables you to specify an initial size using\nan INITIAL_SIZE clause, where size is measured in bytes; the default\nvalue is 134217728 (128 MB). You may optionally follow size with a\none-letter abbreviation for an order of magnitude, similar to those\nused in my.cnf. Generally, this is one of the letters M (megabytes) or\nG (gigabytes).\n\n*Note*:\n\nAll NDB Cluster Disk Data objects share the same namespace. This means\nthat each Disk Data object must be uniquely named (and not merely each\nDisk Data object of a given type). For example, you cannot have a\ntablespace and an data file with the same name, or an undo log file and\na tablespace with the same name.\n\nOn 32-bit systems, the maximum supported value for INITIAL_SIZE is\n4294967296 (4 GB). (Bug #29186)\n\nINITIAL_SIZE is rounded, explicitly, as for CREATE TABLESPACE.\n\nOnce a data file has been created, its size cannot be changed; however,\nyou can add more data files to the tablespace using additional ALTER\nTABLESPACE ... ADD DATAFILE statements.\n\nUsing DROP DATAFILE with ALTER TABLESPACE drops the data file\n\'file_name\' from the tablespace. You cannot drop a data file from a\ntablespace which is in use by any table; in other words, the data file\nmust be empty (no extents used). See\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data-objects.\nhtml. In addition, any data file to be dropped must previously have\nbeen added to the tablespace with CREATE TABLESPACE or ALTER\nTABLESPACE.\n\nBoth ALTER TABLESPACE ... ADD DATAFILE and ALTER TABLESPACE ... DROP\nDATAFILE require an ENGINE clause which specifies the storage engine\nused by the tablespace. Currently, the only accepted values for\nengine_name are NDB and NDBCLUSTER.\n\nWAIT is parsed but otherwise ignored, and so has no effect in MySQL\n5.7. It is intended for future expansion.\n\nWhen ALTER TABLESPACE ... ADD DATAFILE is used with ENGINE = NDB, a\ndata file is created on each Cluster data node. You can verify that the\ndata files were created and obtain information about them by querying\nthe INFORMATION_SCHEMA.FILES table. For example, the following query\nshows all data files belonging to the tablespace named newts:\n\nmysql> SELECT LOGFILE_GROUP_NAME, FILE_NAME, EXTRA\n -> FROM INFORMATION_SCHEMA.FILES\n -> WHERE TABLESPACE_NAME = \'newts\' AND FILE_TYPE = \'DATAFILE\';\n+--------------------+--------------+----------------+\n| LOGFILE_GROUP_NAME | FILE_NAME | EXTRA |\n+--------------------+--------------+----------------+\n| lg_3 | newdata.dat | CLUSTER_NODE=3 |\n| lg_3 | newdata.dat | CLUSTER_NODE=4 |\n| lg_3 | newdata2.dat | CLUSTER_NODE=3 |\n| lg_3 | newdata2.dat | CLUSTER_NODE=4 |\n+--------------------+--------------+----------------+\n2 rows in set (0.03 sec)\n\nSee http://dev.mysql.com/doc/refman/5.7/en/files-table.html.\n\nALTER TABLESPACE is useful only with Disk Data storage for NDB Cluster.\nSee\nhttp://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/alter-tablespace.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/alter-tablespace.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (626,23,'ENUM','ENUM(\'value1\',\'value2\',...) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nAn enumeration. A string object that can have only one value, chosen\nfrom the list of values \'value1\', \'value2\', ..., NULL or the special \'\'\nerror value. ENUM values are represented internally as integers.\n\nAn ENUM column can have a maximum of 65,535 distinct elements. (The\npractical limit is less than 3000.) A table can have no more than 255\nunique element list definitions among its ENUM and SET columns\nconsidered as a group. For more information on these limits, see\nhttp://dev.mysql.com/doc/refman/5.7/en/limits-frm-file.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html');
@@ -720,7 +720,7 @@ INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (639,3,'RADIANS','Syntax:\nRADIANS(X)\n\nReturns the argument X, converted from degrees to radians. (Note that\nπ radians equals 180 degrees.)\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html\n\n','mysql> SELECT RADIANS(90);\n -> 1.5707963267949\n','http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (640,17,'COLLATION','Syntax:\nCOLLATION(str)\n\nReturns the collation of the string argument.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT COLLATION(\'abc\');\n -> \'latin1_swedish_ci\'\nmysql> SELECT COLLATION(_utf8\'abc\');\n -> \'utf8_general_ci\'\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (641,20,'COALESCE','Syntax:\nCOALESCE(value,...)\n\nReturns the first non-NULL value in the list, or NULL if there are no\nnon-NULL values.\n\nThe return type of COALESCE() is the aggregated type of the argument\ntypes.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html\n\n','mysql> SELECT COALESCE(NULL,1);\n -> 1\nmysql> SELECT COALESCE(NULL,NULL,NULL);\n -> NULL\n','http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html');
-INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (642,17,'VERSION','Syntax:\nVERSION()\n\nReturns a string that indicates the MySQL server version. The string\nuses the utf8 character set. The value might have a suffix in addition\nto the version number. See the description of the version system\nvariable in\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT VERSION();\n -> \'5.7.24-standard\'\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
+INSERT INTO help_topic (help_topic_id,help_category_id,name,description,example,url) VALUES (642,17,'VERSION','Syntax:\nVERSION()\n\nReturns a string that indicates the MySQL server version. The string\nuses the utf8 character set. The value might have a suffix in addition\nto the version number. See the description of the version system\nvariable in\nhttp://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html\n\n','mysql> SELECT VERSION();\n -> \'5.7.25-standard\'\n','http://dev.mysql.com/doc/refman/5.7/en/information-functions.html');
INSERT INTO help_keyword (help_keyword_id,name) VALUES (0,'JOIN');
INSERT INTO help_keyword (help_keyword_id,name) VALUES (1,'HOST');
@@ -1629,6 +1629,7 @@ INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (209,109);
INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (434,109);
INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (540,109);
INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (437,109);
+INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (303,109);
INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (583,109);
INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (533,110);
INSERT INTO help_relation (help_topic_id,help_keyword_id) VALUES (516,110);
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 05f85dba8e13..2fe2f4ca709b 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -21,7 +21,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/sql/auth
${CMAKE_SOURCE_DIR}/regex
- ${ZLIB_INCLUDE_DIR}
${SSL_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}/sql
${LZ4_INCLUDE_DIR}
diff --git a/sql/auth/sql_authentication.cc b/sql/auth/sql_authentication.cc
index 851ba5eff8f2..8cb945bf3e50 100644
--- a/sql/auth/sql_authentication.cc
+++ b/sql/auth/sql_authentication.cc
@@ -189,9 +189,9 @@ Rsa_authentication_keys::read_key_file(RSA **key_ptr,
*/
if ((key_file= fopen(key_file_path.c_ptr(), "r")) == NULL)
{
- sql_print_information("RSA %s key file not found: %s."
- " Some authentication plugins will not work.",
- key_type, key_file_path.c_ptr());
+ sql_print_warning("RSA %s key file not found: %s."
+ " Some authentication plugins will not work.",
+ key_type, key_file_path.c_ptr());
}
else
{
@@ -460,7 +460,11 @@ bool auth_plugin_supports_expiration(const char *plugin_name)
static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used)
{
THD *thd= current_thd;
- if (passwd_used == 2)
+
+ if (thd->is_error())
+ sql_print_information("%s", thd->get_stmt_da()->message_text());
+
+ else if (passwd_used == 2)
{
my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
mpvio->auth_info.user_name,
@@ -2198,8 +2202,7 @@ acl_authenticate(THD *thd, enum_server_command command,
if (parse_com_change_user_packet(&mpvio,
mpvio.protocol->get_packet_length()))
{
- if (!thd->is_error())
- login_failed_error(&mpvio, mpvio.auth_info.password_used);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
server_mpvio_update_thd(thd, &mpvio);
DBUG_RETURN(1);
}
@@ -2317,8 +2320,7 @@ acl_authenticate(THD *thd, enum_server_command command,
acl_log_connect(mpvio.auth_info.user_name, mpvio.auth_info.host_or_ip,
mpvio.auth_info.authenticated_as, mpvio.db.str, thd, command);
}
- if (!thd->is_error())
- login_failed_error(&mpvio, mpvio.auth_info.password_used);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
DBUG_RETURN (1);
}
@@ -2357,8 +2359,7 @@ acl_authenticate(THD *thd, enum_server_command command,
Host_errors errors;
errors.m_proxy_user= 1;
inc_host_errors(mpvio.ip, &errors);
- if (!thd->is_error())
- login_failed_error(&mpvio, mpvio.auth_info.password_used);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
DBUG_RETURN(1);
}
@@ -2377,8 +2378,7 @@ acl_authenticate(THD *thd, enum_server_command command,
Host_errors errors;
errors.m_proxy_user_acl= 1;
inc_host_errors(mpvio.ip, &errors);
- if (!thd->is_error())
- login_failed_error(&mpvio, mpvio.auth_info.password_used);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
mysql_mutex_unlock(&acl_cache->lock);
DBUG_RETURN(1);
}
@@ -2428,8 +2428,7 @@ acl_authenticate(THD *thd, enum_server_command command,
Host_errors errors;
errors.m_ssl= 1;
inc_host_errors(mpvio.ip, &errors);
- if (!thd->is_error())
- login_failed_error(&mpvio, thd->password);
+ login_failed_error(&mpvio, thd->password);
DBUG_RETURN(1);
}
@@ -2557,6 +2556,7 @@ acl_authenticate(THD *thd, enum_server_command command,
Host_errors errors;
errors.m_default_database= 1;
inc_host_errors(mpvio.ip, &errors);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
DBUG_RETURN(1);
}
}
diff --git a/sql/auth/sql_authorization.cc b/sql/auth/sql_authorization.cc
index c00b8bfe2fb1..2385ae13d13a 100644
--- a/sql/auth/sql_authorization.cc
+++ b/sql/auth/sql_authorization.cc
@@ -236,7 +236,6 @@ bool Sql_cmd_update::multi_update_precheck(THD *thd, TABLE_LIST *tables)
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
{
- SELECT_LEX *select_lex= thd->lex->select_lex;
TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
DBUG_ENTER("multi_delete_precheck");
@@ -259,13 +258,6 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
}
thd->lex->query_tables_own_last= save_query_tables_own_last;
- if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
- !select_lex->where_cond())
- {
- my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
- ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
- DBUG_RETURN(TRUE);
- }
DBUG_RETURN(FALSE);
}
diff --git a/sql/auth/sql_user.cc b/sql/auth/sql_user.cc
index efe4d4245fc2..a8404638a8ed 100644
--- a/sql/auth/sql_user.cc
+++ b/sql/auth/sql_user.cc
@@ -779,15 +779,19 @@ bool change_password(THD *thd, const char *host, const char *user,
thd->lex->alter_password.account_locked= false;
thd->lex->alter_password.update_password_expired_fields= false;
+
/*
- When @@log-backward-compatible-user-definitions variable is ON
- and its a slave thread, then the password is already hashed. So
- do not generate another hash.
- */
- if (opt_log_builtin_as_identified_by_password &&
- thd->slave_thread)
+ In case its a slave thread or a binlog applier thread, the password
+ is already hashed. Do not generate another hash!
+ */
+ if (thd->slave_thread || thd->is_binlog_applier())
+ {
+ /* Password is in hash form */
+ combo->uses_authentication_string_clause= true;
+ /* Password is not plain text */
combo->uses_identified_by_clause= false;
-
+ }
+
if (set_and_validate_user_attributes(thd, combo, what_to_set,
true, "SET PASSWORD"))
{
diff --git a/sql/binlog.cc b/sql/binlog.cc
index 7522c5ed650f..d74e6f04cb55 100644
--- a/sql/binlog.cc
+++ b/sql/binlog.cc
@@ -2387,9 +2387,9 @@ THD *Stage_manager::Mutex_queue::fetch_and_empty()
DBUG_RETURN(result);
}
-void Stage_manager::wait_count_or_timeout(ulong count, ulong usec, StageID stage)
+void Stage_manager::wait_count_or_timeout(ulong count, long usec, StageID stage)
{
- ulong to_wait=
+ long to_wait=
DBUG_EVALUATE_IF("bgc_set_infinite_delay", LONG_MAX, usec);
/*
For testing purposes while waiting for inifinity
@@ -2397,9 +2397,9 @@ void Stage_manager::wait_count_or_timeout(ulong count, ulong usec, StageID stage
small intervals. Otherwise, waiting 0.1 * infinite
is too long.
*/
- ulong delta=
+ long delta=
DBUG_EVALUATE_IF("bgc_set_infinite_delay", 100000,
- max(1, (to_wait * 0.1)));
+ max(1, (to_wait * 0.1)));
while (to_wait > 0 && (count == 0 || static_cast(m_queue[stage].get_size()) < count))
{
diff --git a/sql/binlog.h b/sql/binlog.h
index d95dd8d27735..b32d10c6cefd 100644
--- a/sql/binlog.h
+++ b/sql/binlog.h
@@ -248,7 +248,7 @@ class Stage_manager {
session is waiting on
@param stage which stage queue size to compare count against.
*/
- void wait_count_or_timeout(ulong count, ulong usec, StageID stage);
+ void wait_count_or_timeout(ulong count, long usec, StageID stage);
void signal_done(THD *queue);
diff --git a/sql/field.cc b/sql/field.cc
index 86c7093ed5ee..fe3fd9b28437 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6420,7 +6420,7 @@ Field_year::store(const char *from, size_t len,const CHARSET_INFO *cs)
type_conversion_status Field_year::store(double nr)
{
- if (nr < 0.0 || nr >= 2155.0)
+ if (nr < 0.0 || nr > 2155.0)
{
(void) Field_year::store((longlong) -1, FALSE);
return TYPE_WARN_OUT_OF_RANGE;
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index b8716ba20f0d..2e46c4b7158d 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -325,9 +325,23 @@ static void do_copy_next_number(Copy_field *copy)
static void do_copy_blob(Copy_field *copy)
{
- ulong length=((Field_blob*) copy->from_field())->get_length();
- ((Field_blob*) copy->to_field())->store_length(length);
+ ulong from_length=((Field_blob*) copy->from_field())->get_length();
+ ((Field_blob*) copy->to_field())->store_length(from_length);
memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*));
+ ulong to_length=((Field_blob*) copy->to_field())->get_length();
+ if (to_length < from_length)
+ {
+ if (copy->to_field()->table->in_use->is_strict_mode())
+ {
+ copy->to_field()->set_warning(Sql_condition::SL_WARNING,
+ ER_DATA_TOO_LONG, 1);
+ }
+ else
+ {
+ copy->to_field()->set_warning(Sql_condition::SL_WARNING,
+ WARN_DATA_TRUNCATED, 1);
+ }
+ }
}
static void do_conv_blob(Copy_field *copy)
diff --git a/sql/handler.cc b/sql/handler.cc
index 28b93c8c4877..607bc9cd1718 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2847,8 +2847,11 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root)
void handler::ha_statistic_increment(ulonglong SSV::*offset) const
{
- DBUG_ASSERT(!table->in_use->status_var_aggregated);
- (table->in_use->status_var.*offset)++;
+ if (table && table->in_use)
+ {
+ DBUG_ASSERT(!table->in_use->status_var_aggregated);
+ (table->in_use->status_var.*offset)++;
+ }
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 2e813f5a4bc0..5c0c423e1c84 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3708,6 +3708,7 @@ String *Item_func_rpad::val_str(String *str)
char *to;
/* must be longlong to avoid truncation */
longlong count= args[1]->val_int();
+ /* Avoid modifying this string as it may affect args[0] */
String *res= args[0]->val_str(str);
String *rpad= args[2]->val_str(&rpad_str);
@@ -3751,10 +3752,15 @@ String *Item_func_rpad::val_str(String *str)
const size_t res_char_length= res->numchars();
+ // String to pad is big enough
if (count <= static_cast(res_char_length))
- { // String to pad is big enough
- res->length(res->charpos((int) count)); // Shorten result if longer
- return (res);
+ {
+ int res_charpos= res->charpos((int)count);
+ if (tmp_value.alloc(res_charpos))
+ return NULL;
+ (void)tmp_value.copy(*res);
+ tmp_value.length(res_charpos); // Shorten result if longer
+ return &tmp_value;
}
const size_t pad_char_length= rpad->numchars();
@@ -3776,6 +3782,10 @@ String *Item_func_rpad::val_str(String *str)
}
/* Must be done before alloc_buffer */
const size_t res_byte_length= res->length();
+ /*
+ alloc_buffer() doesn't modify 'res' because 'res' is guaranteed too short
+ at this stage.
+ */
if (!(res= alloc_buffer(res, str, &tmp_value,
static_cast(byte_count))))
{
@@ -3836,6 +3846,7 @@ String *Item_func_lpad::val_str(String *str)
/* must be longlong to avoid truncation */
longlong count= args[1]->val_int();
size_t byte_count;
+ /* Avoid modifying this string as it may affect args[0] */
String *res= args[0]->val_str(&tmp_value);
String *pad= args[2]->val_str(&lpad_str);
@@ -3876,8 +3887,12 @@ String *Item_func_lpad::val_str(String *str)
if (count <= static_cast(res_char_length))
{
- res->length(res->charpos((int) count));
- return res;
+ int res_charpos= res->charpos((int)count);
+ if (tmp_value.alloc(res_charpos))
+ return NULL;
+ (void)tmp_value.copy(*res);
+ tmp_value.length(res_charpos); // Shorten result if longer
+ return &tmp_value;
}
pad_char_length= pad->numchars();
diff --git a/sql/log.cc b/sql/log.cc
index f888a7fc95fb..966dbdc0871a 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -2326,7 +2326,7 @@ void init_error_log()
}
-bool open_error_log(const char *filename)
+bool open_error_log(const char *filename, bool get_lock)
{
DBUG_ASSERT(filename);
int retries= 2, errors= 0;
@@ -2346,9 +2346,13 @@ bool open_error_log(const char *filename)
if (errors)
{
char errbuf[MYSYS_STRERROR_SIZE];
- sql_print_error("Could not open file '%s' for error logging: %s",
- filename, my_strerror(errbuf, sizeof(errbuf), errno));
+ if (get_lock)
+ mysql_mutex_unlock(&LOCK_error_log);
+ sql_print_error(ER_DEFAULT(ER_CANT_OPEN_ERROR_LOG), filename,
+ ": ", my_strerror(errbuf, sizeof(errbuf), errno));
flush_error_log_messages();
+ if (get_lock)
+ mysql_mutex_lock(&LOCK_error_log);
return true;
}
@@ -2383,10 +2387,10 @@ bool reopen_error_log()
if (!error_log_file)
return false;
mysql_mutex_lock(&LOCK_error_log);
- bool result= open_error_log(error_log_file);
+ bool result= open_error_log(error_log_file, true);
mysql_mutex_unlock(&LOCK_error_log);
if (result)
- my_error(ER_UNKNOWN_ERROR, MYF(0));
+ my_error(ER_CANT_OPEN_ERROR_LOG, MYF(0), error_log_file, ".", "");
return result;
}
diff --git a/sql/log.h b/sql/log.h
index fc1b1b3c7523..17ba572191ae 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -909,8 +909,9 @@ void init_error_log();
have been buffered by calling flush_error_log_messages().
@param filename Name of error log file
+ @param get_lock Should we acquire LOCK_error_log?
*/
-bool open_error_log(const char *filename);
+bool open_error_log(const char *filename, bool get_lock);
/**
Free any error log resources.
diff --git a/sql/log_event.cc b/sql/log_event.cc
index fd1f5ae2c994..2c50a13e4e1f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -5031,6 +5031,13 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
}
compare_errors:
+ /* Parser errors shall be ignored when (GTID) skipping statements */
+ if (thd->is_error() &&
+ thd->get_stmt_da()->mysql_errno() == ER_PARSE_ERROR &&
+ gtid_pre_statement_checks(thd) == GTID_STATEMENT_SKIP)
+ {
+ thd->get_stmt_da()->reset_diagnostics_area();
+ }
/*
In the slave thread, we may sometimes execute some DROP / * 40005
TEMPORARY * / TABLE that come from parts of binlogs (likely if we
@@ -10165,7 +10172,7 @@ Rows_log_event::row_operations_scan_and_key_setup()
DBUG_ASSERT (m_key_index < MAX_KEY);
// Allocate buffer for key searches
m_key= (uchar*)my_malloc(key_memory_log_event,
- MAX_KEY_LENGTH, MYF(MY_WME));
+ m_key_info->key_length, MYF(MY_WME));
if (!m_key)
error= HA_ERR_OUT_OF_MEM;
goto err;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4636c0f9bb4a..bffe8753c857 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -489,7 +489,7 @@ ulonglong max_binlog_cache_size=0;
ulong slave_max_allowed_packet= 0;
ulong binlog_stmt_cache_size=0;
int32 opt_binlog_max_flush_queue_time= 0;
-ulong opt_binlog_group_commit_sync_delay= 0;
+long opt_binlog_group_commit_sync_delay= 0;
ulong opt_binlog_group_commit_sync_no_delay_count= 0;
ulonglong max_binlog_stmt_cache_size=0;
ulong query_cache_size=0;
@@ -725,7 +725,6 @@ mysql_cond_t COND_server_started;
mysql_mutex_t LOCK_reset_gtid_table;
mysql_mutex_t LOCK_compress_gtid_table;
mysql_cond_t COND_compress_gtid_table;
-mysql_mutex_t LOCK_group_replication_handler;
#if !defined (EMBEDDED_LIBRARY) && !defined(_WIN32)
mysql_mutex_t LOCK_socket_listener_active;
mysql_cond_t COND_socket_listener_active;
@@ -3499,8 +3498,6 @@ static int init_thread_environment()
mysql_mutex_init(key_LOCK_global_index_stats,
&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_LOCK_group_replication_handler,
- &LOCK_group_replication_handler, MY_MUTEX_INIT_FAST);
#ifndef EMBEDDED_LIBRARY
Events::init_mutexes();
#if defined(_WIN32)
@@ -4128,8 +4125,9 @@ static int init_server_components()
*/
log_error_dest= errorlog_filename_buff;
- if (open_error_log(errorlog_filename_buff))
+ if (open_error_log(errorlog_filename_buff, false))
unireg_abort(MYSQLD_ABORT_EXIT);
+
#ifdef _WIN32
FreeConsole(); // Remove window
#endif
@@ -9139,7 +9137,6 @@ PSI_mutex_key key_mts_gaq_LOCK;
PSI_mutex_key key_thd_timer_mutex;
PSI_mutex_key key_LOCK_offline_mode;
PSI_mutex_key key_LOCK_default_password_lifetime;
-PSI_mutex_key key_LOCK_group_replication_handler;
#ifdef HAVE_REPLICATION
PSI_mutex_key key_commit_order_manager_mutex;
@@ -9230,7 +9227,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_gtid_ensure_index_mutex, "Gtid_state", PSI_FLAG_GLOBAL},
{ &key_LOCK_query_plan, "THD::LOCK_query_plan", PSI_FLAG_VOLATILITY_SESSION},
{ &key_LOCK_cost_const, "Cost_constant_cache::LOCK_cost_const",
- PSI_FLAG_GLOBAL},
+ PSI_FLAG_GLOBAL},
{ &key_LOCK_current_cond, "THD::LOCK_current_cond", PSI_FLAG_VOLATILITY_SESSION},
{ &key_mts_temp_table_LOCK, "key_mts_temp_table_LOCK", 0},
{ &key_LOCK_reset_gtid_table, "LOCK_reset_gtid_table", PSI_FLAG_GLOBAL},
@@ -9242,8 +9239,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_mutex_slave_worker_hash, "Relay_log_info::slave_worker_hash_lock", 0},
#endif
{ &key_LOCK_offline_mode, "LOCK_offline_mode", PSI_FLAG_GLOBAL},
- { &key_LOCK_default_password_lifetime, "LOCK_default_password_lifetime", PSI_FLAG_GLOBAL},
- { &key_LOCK_group_replication_handler, "LOCK_group_replication_handler", PSI_FLAG_GLOBAL}
+ { &key_LOCK_default_password_lifetime, "LOCK_default_password_lifetime", PSI_FLAG_GLOBAL}
};
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
diff --git a/sql/mysqld.h b/sql/mysqld.h
index c146a3e1a461..6354b92c8fff 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -260,7 +260,7 @@ extern ulong open_files_limit;
extern ulong binlog_cache_size, binlog_stmt_cache_size;
extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size;
extern int32 opt_binlog_max_flush_queue_time;
-extern ulong opt_binlog_group_commit_sync_delay;
+extern long opt_binlog_group_commit_sync_delay;
extern ulong opt_binlog_group_commit_sync_no_delay_count;
extern ulong max_binlog_size, max_relay_log_size;
extern ulong slave_max_allowed_packet;
@@ -480,7 +480,6 @@ extern PSI_mutex_key key_mts_gaq_LOCK;
extern PSI_mutex_key key_thd_timer_mutex;
extern PSI_mutex_key key_LOCK_offline_mode;
extern PSI_mutex_key key_LOCK_default_password_lifetime;
-extern PSI_mutex_key key_LOCK_group_replication_handler;
#ifdef HAVE_REPLICATION
extern PSI_mutex_key key_commit_order_manager_mutex;
@@ -885,7 +884,6 @@ extern mysql_rwlock_t LOCK_system_variables_hash;
extern mysql_rwlock_t LOCK_consistent_snapshot;
extern mysql_cond_t COND_manager;
extern int32 thread_running;
-extern mysql_mutex_t LOCK_group_replication_handler;
extern mysql_mutex_t LOCK_keyring_operations;
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 11ffa527ca73..f372cbe9f944 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -6024,21 +6024,21 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
/**
- If EXPLAIN, add a warning that the index cannot be
- used for range access due to either type conversion or different
- collations on the field used for comparison
+ If EXPLAIN or if the --safe-updates option is enabled, add a warning that
+ the index cannot be used for range access due to either type conversion or
+ different collations on the field used for comparison
@param param PARAM from test_quick_select
@param key_num Key number
@param field Field in the predicate
- */
-static void
-if_explain_warn_index_not_applicable(const RANGE_OPT_PARAM *param,
- const uint key_num,
- const Field *field)
+*/
+static void warn_index_not_applicable(const RANGE_OPT_PARAM *param,
+ const uint key_num, const Field *field)
{
+ THD *thd= param->thd;
if (param->using_real_indexes &&
- param->thd->lex->describe)
+ (param->thd->lex->describe ||
+ thd->variables.option_bits & OPTION_SAFE_UPDATES))
push_warning_printf(
param->thd,
Sql_condition::SL_WARNING,
@@ -7071,7 +7071,7 @@ get_mm_parts(RANGE_OPT_PARAM *param, Item_func *cond_func, Field *field,
key_part->image_type,
type, value))
{
- if_explain_warn_index_not_applicable(param, key_part->key, field);
+ warn_index_not_applicable(param, key_part->key, field);
DBUG_RETURN(NULL);
}
@@ -7382,7 +7382,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, Item *conf_func, Field *field,
if (!comparable_in_index(conf_func, field, key_part->image_type,
type, value))
{
- if_explain_warn_index_not_applicable(param, key_part->key, field);
+ warn_index_not_applicable(param, key_part->key, field);
goto end;
}
diff --git a/sql/rpl_group_replication.cc b/sql/rpl_group_replication.cc
index b005eec56d83..b87e3bd23e28 100644
--- a/sql/rpl_group_replication.cc
+++ b/sql/rpl_group_replication.cc
@@ -22,177 +22,50 @@
#include "log.h"
-/*
- Group Replication plugin handler.
-*/
-Group_replication_handler::
-Group_replication_handler(const char* plugin_name_arg)
- :plugin(NULL), plugin_handle(NULL)
-{
- plugin_name.assign(plugin_name_arg);
-}
-
-Group_replication_handler::~Group_replication_handler()
-{
- if (plugin_handle)
- plugin_handle->stop();
-}
-
-int Group_replication_handler::init()
-{
- int error= 0;
- if (!plugin_handle)
- if ((error = plugin_init()))
- return error;
- return 0;
-}
-
-int Group_replication_handler::start()
-{
- if (plugin_handle)
- return plugin_handle->start();
- return 1;
-}
-
-int Group_replication_handler::stop()
-{
- if (plugin_handle)
- return plugin_handle->stop();
- return 1;
-}
-
-bool Group_replication_handler::is_running()
-{
- if (plugin_handle)
- return plugin_handle->is_running();
- return false;
-}
-
-int
-Group_replication_handler::
-set_retrieved_certification_info(View_change_log_event* view_change_event)
-{
- if (plugin_handle)
- return plugin_handle->set_retrieved_certification_info(view_change_event);
- return 1;
-}
-
-bool
-Group_replication_handler::
-get_connection_status_info(
- const GROUP_REPLICATION_CONNECTION_STATUS_CALLBACKS& callbacks)
-{
- if (plugin_handle)
- return plugin_handle->get_connection_status_info(callbacks);
- return true;
-}
-
-bool
-Group_replication_handler::
-get_group_members_info(
- unsigned int index,
- const GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS& callbacks)
-{
- if (plugin_handle)
- return plugin_handle->get_group_members_info(index, callbacks);
- return true;
-}
-
-bool
-Group_replication_handler::
-get_group_member_stats_info(
- const GROUP_REPLICATION_GROUP_MEMBER_STATS_CALLBACKS& callbacks)
-{
- if (plugin_handle)
- return plugin_handle->get_group_member_stats_info(callbacks);
- return true;
-}
-
-unsigned int Group_replication_handler::get_members_number_info()
-{
- if (plugin_handle)
- return plugin_handle->get_members_number_info();
- return 0;
-}
-int Group_replication_handler::plugin_init()
-{
- plugin= my_plugin_lock_by_name(0, to_lex_cstring(plugin_name.c_str()),
- MYSQL_GROUP_REPLICATION_PLUGIN);
- if (plugin)
- {
- plugin_handle= (st_mysql_group_replication*) plugin_decl(plugin)->info;
- plugin_unlock(0, plugin);
- }
- else
- {
- plugin_handle= NULL;
- return 1;
- }
- return 0;
-}
-
-Group_replication_handler* group_replication_handler= NULL;
+/**
+ Static name of Group Replication plugin.
+*/
+LEX_CSTRING group_replication_plugin_name= {
+ C_STRING_WITH_LEN("group_replication")
+};
/*
Group Replication plugin handler function accessors.
*/
#ifdef HAVE_REPLICATION
-int group_replication_init(const char* plugin_name)
+int group_replication_init()
{
- if (initialize_channel_service_interface())
- {
- return 1;
- }
-
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (group_replication_handler == NULL)
- {
- group_replication_handler= new Group_replication_handler(plugin_name);
-
- if (group_replication_handler)
- {
- int ret= group_replication_handler->init();
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
- }
- }
- mysql_mutex_unlock(&LOCK_group_replication_handler);
-
- return 1;
+ return initialize_channel_service_interface();
}
#endif
-int group_replication_cleanup()
+
+bool is_group_replication_plugin_loaded()
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (group_replication_handler != NULL)
- {
- delete group_replication_handler;
- group_replication_handler= NULL;
- }
- else
+ bool result= false;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return 1;
+ plugin_unlock(0, plugin);
+ result= true;
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return 0;
-}
-
-bool is_group_replication_plugin_loaded()
-{
- if (group_replication_handler)
- return true;
- return false;
+ return result;
}
int group_replication_start()
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ int result= 1;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
/*
We need to take global_sid_lock because
@@ -208,111 +81,160 @@ int group_replication_start()
gtid_mode_lock.
*/
gtid_mode_lock->rdlock();
- int ret= group_replication_handler->start();
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->start();
gtid_mode_lock->unlock();
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+
+ plugin_unlock(0, plugin);
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- sql_print_error("Group Replication plugin is not installed.");
- return 1;
+ else
+ {
+ sql_print_error("Group Replication plugin is not installed.");
+ }
+
+ return result;
}
int group_replication_stop()
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ int result= 1;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- int ret= group_replication_handler->stop();
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->stop();
+
+ plugin_unlock(0, plugin);
+ }
+ else
+ {
+ sql_print_error("Group Replication plugin is not installed.");
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- sql_print_error("Group Replication plugin is not installed.");
- return 1;
+ return result;
}
bool is_group_replication_running()
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ bool result= false;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- bool ret= group_replication_handler->is_running();
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->is_running();
+
+ plugin_unlock(0, plugin);
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return false;
+ return result;
}
int set_group_replication_retrieved_certification_info(View_change_log_event *view_change_event)
{
- if (is_group_replication_plugin_loaded())
- return group_replication_handler->set_retrieved_certification_info(view_change_event);
- return 1;
+ int result= 1;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
+ {
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->set_retrieved_certification_info(view_change_event);
+
+ plugin_unlock(0, plugin);
+ }
+
+ return result;
}
bool get_group_replication_connection_status_info(
const GROUP_REPLICATION_CONNECTION_STATUS_CALLBACKS& callbacks)
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ bool result= true;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- int ret= group_replication_handler->get_connection_status_info(callbacks);
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->get_connection_status_info(callbacks);
+
+ plugin_unlock(0, plugin);
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return true;
+ return result;
}
bool get_group_replication_group_members_info(
unsigned int index,
const GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS& callbacks)
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ bool result= true;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- bool ret=
- group_replication_handler->get_group_members_info(index, callbacks);
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->get_group_members_info(index, callbacks);
+
+ plugin_unlock(0, plugin);
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return true;
+ return result;
}
bool get_group_replication_group_member_stats_info(
const GROUP_REPLICATION_GROUP_MEMBER_STATS_CALLBACKS& callbacks)
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ bool result= true;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- bool ret= group_replication_handler->get_group_member_stats_info(callbacks);
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->get_group_member_stats_info(callbacks);
+
+ plugin_unlock(0, plugin);
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return true;
+ return result;
}
unsigned int get_group_replication_members_number_info()
{
- mysql_mutex_lock(&LOCK_group_replication_handler);
- if (is_group_replication_plugin_loaded())
+ unsigned int result= 0;
+
+ plugin_ref plugin= my_plugin_lock_by_name(0,
+ group_replication_plugin_name,
+ MYSQL_GROUP_REPLICATION_PLUGIN);
+ if (plugin != NULL)
{
- unsigned int ret= group_replication_handler->get_members_number_info();
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return ret;
+ st_mysql_group_replication *plugin_handle=
+ (st_mysql_group_replication*) plugin_decl(plugin)->info;
+ result= plugin_handle->get_members_number_info();
+
+ plugin_unlock(0, plugin);
}
- mysql_mutex_unlock(&LOCK_group_replication_handler);
- return 0;
+ return result;
}
diff --git a/sql/rpl_group_replication.h b/sql/rpl_group_replication.h
index 9988982be85f..f169eb139a9a 100644
--- a/sql/rpl_group_replication.h
+++ b/sql/rpl_group_replication.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -23,41 +23,14 @@
#include "replication.h"
#include "log_event.h"
+#include "mysql/plugin_group_replication.h"
-/*
- Group Replication plugin handler.
-*/
-class Group_replication_handler
-{
-public:
- Group_replication_handler(const char *plugin_name_arg);
- ~Group_replication_handler();
- int init();
- int start();
- int stop();
- bool is_running();
- int set_retrieved_certification_info(View_change_log_event *view_change_event);
- bool get_connection_status_info(
- const GROUP_REPLICATION_CONNECTION_STATUS_CALLBACKS& callbacks);
- bool get_group_members_info(
- unsigned int index,
- const GROUP_REPLICATION_GROUP_MEMBERS_CALLBACKS& callbacks);
- bool get_group_member_stats_info(
- const GROUP_REPLICATION_GROUP_MEMBER_STATS_CALLBACKS& callbacks);
- unsigned int get_members_number_info();
+class View_change_log_event;
-private:
- std::string plugin_name;
- plugin_ref plugin;
- st_mysql_group_replication *plugin_handle;
- int plugin_init();
-};
/*
Group Replication plugin handler function accessors.
*/
-int group_replication_init(const char* plugin_name);
-int group_replication_cleanup();
bool is_group_replication_plugin_loaded();
int group_replication_start();
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 0328dd26e2e3..f030c63d7acf 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -132,7 +132,8 @@ Master_info::Master_info(
checksum_alg_before_fd(binary_log::BINLOG_CHECKSUM_ALG_UNDEF),
retry_count(master_retry_count),
mi_description_event(NULL),
- auto_position(false)
+ auto_position(false),
+ reset(false)
{
host[0] = 0; user[0] = 0; bind_addr[0] = 0;
password[0]= 0; start_password[0]= 0;
@@ -208,6 +209,7 @@ void Master_info::end_info()
handler->end_info();
inited = 0;
+ reset = true;
DBUG_VOID_RETURN;
}
@@ -246,16 +248,25 @@ int Master_info::flush_info(bool force)
DBUG_ENTER("Master_info::flush_info");
DBUG_PRINT("enter",("master_pos: %lu", (ulong) master_log_pos));
- if (!inited)
+ bool skip_flushing = !inited;
+ /*
+ A Master_info of a channel that was inited and then reset must be flushed
+ into the repository or else its connection configuration will be lost in
+ case the server restarts before starting the channel again.
+ */
+ if (force && reset) skip_flushing= false;
+
+ if (skip_flushing)
DBUG_RETURN(0);
/*
We update the sync_period at this point because only here we
now that we are handling a master info. This needs to be
update every time we call flush because the option maybe
- dinamically set.
+ dynamically set.
*/
- handler->set_sync_period(sync_masterinfo_period);
+ if (inited)
+ handler->set_sync_period(sync_masterinfo_period);
if (write_info(handler))
goto err;
@@ -306,6 +317,7 @@ int Master_info::mi_init_info()
}
inited= 1;
+ reset= false;
if (flush_info(TRUE))
goto err;
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 26ca88675e29..97a4c424c08b 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -501,6 +501,9 @@ friend class Rpl_info_factory;
@param THD thd the THD object of current thread
*/
void wait_until_no_reference(THD *thd);
+
+ /* Set true when the Master_info object was cleared by a RESET SLAVE */
+ bool reset;
};
int change_master_server_id_cmp(ulong *id1, ulong *id2);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 26405f875761..ad5a4b5a2c7e 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1304,7 +1304,15 @@ int Relay_log_info::purge_relay_logs(THD *thd, bool just_reset,
if (!inited)
{
DBUG_PRINT("info", ("inited == 0"));
- if (error_on_rli_init_info)
+ if (error_on_rli_init_info ||
+ /*
+ mi->reset means that the channel was reset but still exists. Channel
+ shall have the index and the first relay log file.
+
+ Those files shall be remove in a following RESET SLAVE ALL (even when
+ channel was not inited again).
+ */
+ (mi->reset && delete_only))
{
ln_without_channel_name= relay_log.generate_name(opt_relay_logname,
"-relay-bin", buffer);
@@ -1393,13 +1401,6 @@ int Relay_log_info::purge_relay_logs(THD *thd, bool just_reset,
cur_log_fd= -1;
}
- if (relay_log.reset_logs(thd, delete_only))
- {
- *errmsg = "Failed during log reset";
- error=1;
- goto err;
- }
-
/**
Clear the retrieved gtid set for this channel.
global_sid_lock->wrlock() is needed.
@@ -1408,6 +1409,13 @@ int Relay_log_info::purge_relay_logs(THD *thd, bool just_reset,
(const_cast(get_gtid_set()))->clear();
global_sid_lock->unlock();
+ if (relay_log.reset_logs(thd, delete_only))
+ {
+ *errmsg = "Failed during log reset";
+ error=1;
+ goto err;
+ }
+
/* Save name of used relay log file */
set_group_relay_log_name(relay_log.get_log_fname());
set_event_relay_log_name(relay_log.get_log_fname());
diff --git a/sql/rpl_slave.cc b/sql/rpl_slave.cc
index db06aafedebb..5685e2751cbb 100644
--- a/sql/rpl_slave.cc
+++ b/sql/rpl_slave.cc
@@ -459,7 +459,7 @@ int init_slave()
mi= it->second;
/* If server id is not set, start_slave_thread() will say it */
- if (mi && mi->host[0])
+ if (mi && mi->host[0] && mi->rli->inited)
{
/* same as in start_slave() cache the global var values into rli's members */
mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
@@ -477,6 +477,11 @@ int init_slave()
mi->get_channel());
}
}
+ else
+ {
+ sql_print_information("Failed to start slave threads for channel '%s'",
+ mi->get_channel());
+ }
}
}
@@ -550,7 +555,9 @@ bool start_slave(THD *thd)
{
mi= it->second;
- channel_configured= mi && mi->inited && mi->host[0]; // channel properly configured.
+ channel_configured= mi && // Master_info exists
+ (mi->inited || mi->reset) // It is inited or was reset
+ && mi->host[0]; // host is set
if (channel_configured)
{
@@ -10422,7 +10429,8 @@ int reset_slave(THD *thd)
Master_info *mi= 0;
int result= 0;
- mi_map::iterator it;
+ mi_map::iterator it, gr_channel_map_it;
+
if (thd->lex->reset_slave_info.all)
{
/* First do reset_slave for default channel */
@@ -10444,6 +10452,26 @@ int reset_slave(THD *thd)
break;
it= channel_map.begin();
}
+ /* RESET group replication specific channels */
+ gr_channel_map_it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
+ while (gr_channel_map_it != channel_map.end(GROUP_REPLICATION_CHANNEL))
+ {
+ mi= gr_channel_map_it->second;
+ DBUG_ASSERT(mi);
+ /*
+ We cannot RESET a group replication channel while the group
+ replication is running.
+ */
+ if (is_group_replication_running())
+ {
+ my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
+ "RESET SLAVE ALL FOR CHANNEL", mi->get_channel());
+ DBUG_RETURN(1);
+ }
+ if ((result= reset_slave(thd, mi, thd->lex->reset_slave_info.all)))
+ break;
+ gr_channel_map_it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
+ }
}
else
{
@@ -10456,6 +10484,27 @@ int reset_slave(THD *thd)
break;
it++;
}
+ /*
+ RESET group replication specific channels.
+
+ We cannot RESET a group replication channel while the group
+ replication is running.
+ */
+ gr_channel_map_it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
+ while (gr_channel_map_it != channel_map.end(GROUP_REPLICATION_CHANNEL))
+ {
+ mi= gr_channel_map_it->second;
+ DBUG_ASSERT(mi);
+ if (is_group_replication_running())
+ {
+ my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
+ "RESET SLAVE FOR CHANNEL", mi->get_channel());
+ DBUG_RETURN(1);
+ }
+ if ((result= reset_slave(thd, mi, thd->lex->reset_slave_info.all)))
+ break;
+ gr_channel_map_it++;
+ }
}
DBUG_RETURN(result);
@@ -10483,7 +10532,8 @@ int reset_slave(THD *thd, Master_info* mi, bool reset_all)
const char* errmsg= "Unknown error occured while reseting slave";
DBUG_ENTER("reset_slave");
- bool no_init_after_delete= false;
+ bool is_default_channel= strcmp(mi->get_channel(),
+ channel_map.get_default_channel()) == 0;
/*
RESET SLAVE command should ignore 'read-only' and 'super_read_only'
@@ -10508,18 +10558,10 @@ int reset_slave(THD *thd, Master_info* mi, bool reset_all)
// delete relay logs, clear relay log coordinates
-
- /*
- For named channels, we have to delete the index and log files
- and not init them
- */
- if (strcmp(mi->get_channel(), channel_map.get_default_channel()))
- no_init_after_delete= true;
-
if ((error= mi->rli->purge_relay_logs(thd,
1 /* just reset */,
&errmsg,
- no_init_after_delete)))
+ reset_all && !is_default_channel)))
{
my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
error= ER_RELAY_LOG_FAIL;
@@ -10539,7 +10581,25 @@ int reset_slave(THD *thd, Master_info* mi, bool reset_all)
goto err;
}
if (!reset_all)
+ {
mi->init_master_log_pos();
+ mi->master_uuid[0]= 0;
+ /*
+ This shall prevent the channel to vanish if server is restarted
+ after this RESET SLAVE and before the channel be started.
+ */
+ if (mi->reset &&
+ opt_mi_repository_id == INFO_REPOSITORY_TABLE &&
+ opt_rli_repository_id == INFO_REPOSITORY_TABLE &&
+ mi->flush_info(true))
+ {
+ error= ER_MASTER_INFO;
+ my_error(ER_MASTER_INFO, MYF(0));
+ unlock_slave_threads(mi);
+ mi->channel_unlock();
+ goto err;
+ }
+ }
unlock_slave_threads(mi);
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index b3b3fafe5ee0..ac8bae86c3d2 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -3825,22 +3825,22 @@ ER_NO_RAID_COMPILED
swe "Denna version av MySQL är inte kompilerad med RAID"
ukr "Ця версія MySQL не зкомпільована з підтримкою RAID"
ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
- cze "Update tabulky bez WHERE s klíčem není v módu bezpečných update dovoleno"
- dan "Du bruger sikker opdaterings modus ('safe update mode') og du forsøgte at opdatere en tabel uden en WHERE klausul, der gør brug af et KEY felt"
- nla "U gebruikt 'safe update mode' en u probeerde een tabel te updaten zonder een WHERE met een KEY kolom"
- eng "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column"
- est "Katse muuta tabelit turvalises rezhiimis ilma WHERE klauslita"
- fre "Vous êtes en mode 'safe update' et vous essayez de faire un UPDATE sans clause WHERE utilisant un index"
- ger "MySQL läuft im sicheren Aktualisierungsmodus (safe update mode). Sie haben versucht, eine Tabelle zu aktualisieren, ohne in der WHERE-Klausel ein KEY-Feld anzugeben"
- hun "On a biztonsagos update modot hasznalja, es WHERE that uses a KEY column"
- ita "In modalita` 'safe update' si e` cercato di aggiornare una tabella senza clausola WHERE su una chiave"
- jpn "'safe update mode'で、索引を利用するWHERE句の無い更新処理を実行しようとしました。"
- por "Você está usando modo de atualização seguro e tentou atualizar uma tabela sem uma cláusula WHERE que use uma coluna chave"
- rus "Вы работаете в режиме безопасных обновлений (safe update mode) и попробовали изменить таблицу без использования ключевого столбца в части WHERE"
- serbian "Vi koristite safe update mod servera, a probali ste da promenite podatke bez 'WHERE' komande koja koristi kolonu ključa"
- spa "Tu estás usando modo de actualización segura y tentado actualizar una tabla sin un WHERE que usa una KEY columna"
- swe "Du använder 'säker uppdateringsmod' och försökte uppdatera en tabell utan en WHERE-sats som använder sig av en nyckel"
- ukr "Ви у режимі безпечного оновлення та намагаєтесь оновити таблицю без оператора WHERE, що використовує KEY стовбець"
+ cze "Update tabulky bez WHERE s klíčem není v módu bezpečných update dovoleno. %s"
+ dan "Du bruger sikker opdaterings modus ('safe update mode') og du forsøgte at opdatere en tabel uden en WHERE klausul, der gør brug af et KEY felt. %s"
+ nla "U gebruikt 'safe update mode' en u probeerde een tabel te updaten zonder een WHERE met een KEY kolom. %s"
+ eng "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. %s"
+ est "Katse muuta tabelit turvalises rezhiimis ilma WHERE klauslita. %s"
+ fre "Vous êtes en mode 'safe update' et vous essayez de faire un UPDATE sans clause WHERE utilisant un index. %s"
+ ger "MySQL läuft im sicheren Aktualisierungsmodus (safe update mode). Sie haben versucht, eine Tabelle zu aktualisieren, ohne in der WHERE-Klausel ein KEY-Feld anzugeben. %s"
+ hun "On a biztonsagos update modot hasznalja, es WHERE that uses a KEY column. %s"
+ ita "In modalita` 'safe update' si e` cercato di aggiornare una tabella senza clausola WHERE su una chiave. %s"
+ jpn "'safe update mode'で、索引を利用するWHERE句の無い更新処理を実行しようとしました。. %s"
+ por "Você está usando modo de atualização seguro e tentou atualizar uma tabela sem uma cláusula WHERE que use uma coluna chave. %s"
+ rus "Вы работаете в режиме безопасных обновлений (safe update mode) и попробовали изменить таблицу без использования ключевого столбца в части WHERE. %s"
+ serbian "Vi koristite safe update mod servera, a probali ste da promenite podatke bez 'WHERE' komande koja koristi kolonu ključa. %s"
+ spa "Tu estás usando modo de actualización segura y tentado actualizar una tabla sin un WHERE que usa una KEY columna. %s"
+ swe "Du använder 'säker uppdateringsmod' och försökte uppdatera en tabell utan en WHERE-sats som använder sig av en nyckel. %s"
+ ukr "Ви у режимі безпечного оновлення та намагаєтесь оновити таблицю без оператора WHERE, що використовує KEY стовбець. %s"
ER_KEY_DOES_NOT_EXITS 42000 S1009
cze "Klíč '%-.192s' v tabulce '%-.192s' neexistuje"
dan "Nøglen '%-.192s' eksisterer ikke i tabellen '%-.192s'"
@@ -7771,6 +7771,9 @@ WARN_DEPRECATED_MAXDB_SQL_MODE_FOR_TIMESTAMP
ER_XA_REPLICATION_FILTERS
eng "The use of replication filters with XA transactions is not supported, and can lead to an undefined state in the replication slave."
+ER_CANT_OPEN_ERROR_LOG
+ eng "Could not open file '%s' for error logging%s%s"
+
ER_COMPRESSED_COLUMN_USED_AS_KEY
eng "Compressed column '%-.192s' is not allowed in the key list"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 2ae027e845e8..7747ce11ce1c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2236,6 +2236,8 @@ void sp_parser_data::start_parsing_sp_body(THD *thd, sp_head *sp)
m_saved_free_list= thd->free_list;
thd->mem_root= sp->get_persistent_mem_root();
+ set_memroot_max_capacity(thd->mem_root, m_saved_memroot->max_capacity);
+ set_memroot_error_reporting(thd->mem_root, m_saved_memroot->error_for_capacity_exceeded);
thd->free_list= NULL;
}
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 9a23757dea45..03b0cd4b2114 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -343,8 +343,11 @@ bool Sql_cmd_alter_table::execute(THD *thd)
if (!thd->lex->is_ignore() && thd->is_strict_mode())
thd->push_internal_handler(&strict_handler);
+ Partition_in_shared_ts_error_handler partition_in_shared_ts_handler;
+ thd->push_internal_handler(&partition_in_shared_ts_handler);
result= mysql_alter_table(thd, select_lex->db, lex->name.str,
&create_info, first_table, &alter_info);
+ thd->pop_internal_handler();
if (!thd->lex->is_ignore() && thd->is_strict_mode())
thd->pop_internal_handler();
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d78d41e28961..bfd637bc2b34 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -246,6 +246,28 @@ bool Strict_error_handler::handle_condition(THD *thd,
return false;
}
+/**
+ Implementation of Partition_in_shared_ts error handler.
+ This internal handler is to make sure that deprecation warning is not
+ displayed again if already displayed once.
+*/
+bool Partition_in_shared_ts_error_handler::handle_condition(
+ THD *thd,
+ uint sql_errno,
+ const char *sqlstate,
+ Sql_condition::enum_severity_level *level,
+ const char *msg)
+{
+ if (sql_errno == ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT &&
+ strstr(msg, "InnoDB : A table partition in a shared tablespace") != NULL) {
+ if (m_is_already_reported == false) {
+ m_is_already_reported= true;
+ thd->get_stmt_da()->push_warning(thd, sql_errno, sqlstate, *level, msg);
+ }
+ return true;
+ }
+ return false;
+}
/**
This internal handler is used to trap ER_NO_SUCH_TABLE and
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 969c073b5309..66c7e68dc24a 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -769,6 +769,28 @@ class Strict_error_handler : public Internal_error_handler
enum_set_select_behavior m_set_select_behavior;
};
+/**
+ This internal handler is to make sure that deprecation warning is not
+ displayed again if already displayed once.
+*/
+
+class Partition_in_shared_ts_error_handler : public Internal_error_handler
+{
+public:
+ Partition_in_shared_ts_error_handler()
+ : m_is_already_reported(false)
+ {}
+
+ virtual bool handle_condition(THD *thd,
+ uint sql_errno,
+ const char* sqlstate,
+ Sql_condition::enum_severity_level *level,
+ const char* msg);
+
+private:
+ bool m_is_already_reported;
+};
+
void update_indexed_column_map(TABLE *table, MY_BITMAP *read_set);
#endif /* SQL_BASE_INCLUDED */
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index ded1d2bf32d5..dfa43dac1f23 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -136,13 +136,6 @@ bool Sql_cmd_delete::mysql_delete(THD *thd, ha_rows limit)
DBUG_RETURN(true);
const_cond= (!conds || conds->const_item());
- if (safe_update && const_cond)
- {
- my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
- ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
- DBUG_RETURN(TRUE);
- }
-
const_cond_result= const_cond && (!conds || conds->val_int());
if (thd->is_error())
{
@@ -192,6 +185,14 @@ bool Sql_cmd_delete::mysql_delete(THD *thd, ha_rows limit)
goto exit_without_my_ok;
}
+ /* Do not allow deletion of all records if safe_update is set. */
+ if (safe_update)
+ {
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0),
+ thd->get_stmt_da()->get_first_condition_message());
+ DBUG_RETURN(true);
+ }
+
DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
if (!(error=table->file->ha_delete_all_rows()))
{
@@ -321,13 +322,22 @@ bool Sql_cmd_delete::mysql_delete(THD *thd, ha_rows limit)
/* If running in safe sql mode, don't allow updates without keys */
if (table->quick_keys.is_clear_all())
{
- thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
- if (safe_update && !using_limit)
+ thd->server_status|= SERVER_QUERY_NO_INDEX_USED;
+
+ /*
+ Safe update error isn't returned if:
+ 1) It is an EXPLAIN statement OR
+ 2) LIMIT is present.
+
+ Append the first warning (if any) to the error message. This allows the
+ user to understand why index access couldn't be chosen.
+ */
+ if (!thd->lex->is_explain() && safe_update && !using_limit)
{
free_underlaid_joins(thd, select_lex);
- my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
- ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
- DBUG_RETURN(TRUE);
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0),
+ thd->get_stmt_da()->get_first_condition_message());
+ DBUG_RETURN(true);
}
}
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 94be40537656..d1b86b7ac481 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -497,6 +497,12 @@ bool Diagnostics_area::has_sql_condition(uint sql_errno) const
return false;
}
+const char * Diagnostics_area::get_first_condition_message()
+{
+ if (m_conditions_list.elements())
+ return m_conditions_list.front()->message_text();
+ return "";
+}
void Diagnostics_area::reset_condition_info(THD *thd)
{
diff --git a/sql/sql_error.h b/sql/sql_error.h
index 65be5fc055b0..e850703b6707 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -484,6 +484,8 @@ class Diagnostics_area
Sql_condition_iterator sql_conditions() const
{ return m_conditions_list; }
+ const char * get_first_condition_message();
+
/** Make sure there is room for the given number of conditions. */
void reserve_number_of_conditions(THD *thd, uint count);
diff --git a/sql/sql_optimizer.cc b/sql/sql_optimizer.cc
index dbb24041ffa5..dfa263935f05 100644
--- a/sql/sql_optimizer.cc
+++ b/sql/sql_optimizer.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -6427,7 +6427,14 @@ static bool find_eq_ref_candidate(TABLE_LIST *tl, table_map sj_inner_tables)
if (!(keyuse->used_tables & sj_inner_tables) &&
!(keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL))
{
- bound_parts|= (key_part_map)1 << keyuse->keypart;
+ /*
+ Consider only if the resulting condition does not pass a NULL
+ value through. Especially needed for a UNIQUE index on NULLable
+ columns where a duplicate row is possible with NULL values.
+ */
+ if (keyuse->null_rejecting || !keyuse->val->maybe_null ||
+ !keyinfo->key_part[keyuse->keypart].field->maybe_null())
+ bound_parts|= (key_part_map)1 << keyuse->keypart;
}
keyuse++;
} while (keyuse->key == key && keyuse->table_ref == tl);
@@ -6863,14 +6870,14 @@ static uint get_semi_join_select_list_index(Item_field *item_field)
}
/**
- @brief
- If EXPLAIN EXTENDED, add warning that an index cannot be used for
- ref access
+ @brief
+ If EXPLAIN EXTENDED or if the --safe-updates option is enabled, add a
+ warning that an index cannot be used for ref access
@details
- If EXPLAIN EXTENDED, add a warning for each index that cannot be
- used for ref access due to either type conversion or different
- collations on the field used for comparison
+ If EXPLAIN EXTENDED or if the --safe-updates option is enabled, add a
+ warning for each index that cannot be used for ref access due to either type
+ conversion or different collations on the field used for comparison
Example type conversion (char compared to int):
@@ -6884,13 +6891,14 @@ static uint get_semi_join_select_list_index(Item_field *item_field)
@param thd Thread for the connection that submitted the query
@param field Field used in comparision
- @param cant_use_indexes Indexes that cannot be used for lookup
+ @param cant_use_index Indexes that cannot be used for lookup
*/
-static void
-warn_index_not_applicable(THD *thd, const Field *field,
- const key_map cant_use_index)
+static void
+warn_index_not_applicable(THD *thd, const Field *field,
+ const key_map cant_use_index)
{
- if (thd->lex->describe)
+ if (thd->lex->describe ||
+ thd->variables.option_bits & OPTION_SAFE_UPDATES)
for (uint j=0 ; j < field->table->s->keys ; j++)
if (cant_use_index.is_set(j))
push_warning_printf(thd,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index abc1bbc1657e..65ae036d1963 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2605,6 +2605,8 @@ mysql_execute_command(THD *thd, bool first_level)
TABLE_LIST *all_tables;
/* most outer SELECT_LEX_UNIT of query */
SELECT_LEX_UNIT *const unit= lex->unit;
+ // keep GTID violation state in order to roll it back on statement failure
+ bool gtid_consistency_violation_state = thd->has_gtid_consistency_violation;
DBUG_ASSERT(select_lex->master_unit() == unit);
struct system_variables *per_query_variables_backup= NULL;
@@ -3466,6 +3468,10 @@ case SQLCOM_PREPARE:
/* Push Strict_error_handler */
if (!thd->lex->is_ignore() && thd->is_strict_mode())
thd->push_internal_handler(&strict_handler);
+
+ Partition_in_shared_ts_error_handler partition_in_shared_ts_handler;
+ thd->push_internal_handler(&partition_in_shared_ts_handler);
+
/* regular create */
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
{
@@ -3479,6 +3485,9 @@ case SQLCOM_PREPARE:
res= mysql_create_table(thd, create_table,
&create_info, &alter_info);
}
+
+ thd->pop_internal_handler();
+
/* Pop Strict_error_handler */
if (!thd->lex->is_ignore() && thd->is_strict_mode())
thd->pop_internal_handler();
@@ -5390,8 +5399,15 @@ case SQLCOM_PREPARE:
}
#endif
- if (!(res || thd->is_error()))
- binlog_gtid_end_transaction(thd);
+ if (!res && !thd->is_error()) { // if statement succeeded
+ binlog_gtid_end_transaction(thd); // finalize GTID life-cycle
+ DEBUG_SYNC(thd, "persist_new_state_after_statement_succeeded");
+ } else if (!gtid_consistency_violation_state && // if the consistency state
+ thd->has_gtid_consistency_violation) { // was set by the failing
+ // statement
+ gtid_state->end_gtid_violating_transaction(thd); // just roll it back
+ DEBUG_SYNC(thd, "restore_previous_state_after_statement_failed");
+ }
DBUG_RETURN(res || thd->is_error());
}
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index dbe9346dc591..74c2e1e6add4 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -125,10 +125,12 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
result= 1;
if ((options & REFRESH_SLOW_LOG) && opt_slow_log)
- query_logger.reopen_log_file(QUERY_LOG_SLOW);
+ if (query_logger.reopen_log_file(QUERY_LOG_SLOW))
+ result= 1;
if ((options & REFRESH_GENERAL_LOG) && opt_general_log)
- query_logger.reopen_log_file(QUERY_LOG_GENERAL);
+ if (query_logger.reopen_log_file(QUERY_LOG_GENERAL))
+ result= 1;
if (options & REFRESH_ENGINE_LOG)
if (ha_flush_logs(NULL))
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2ad09e01534c..080078bb186a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -2343,11 +2343,22 @@ bool error_if_full_join(JOIN *join)
for (uint i= 0; i < join->primary_tables; i++)
{
JOIN_TAB *const tab= join->best_ref[i];
+ THD *thd = join->thd;
- if (tab->type() == JT_ALL && (!tab->quick()))
+ /*
+ Safe update error isn't returned if:
+ 1) It is an EXPLAIN statement OR
+ 2) Table is not the target.
+
+ Append the first warning (if any) to the error message. Allows the user
+ to understand why index access couldn't be chosen.
+ */
+
+ if (!thd->lex->is_explain() && tab->table()->pos_in_table_list->updating &&
+ tab->type() == JT_ALL)
{
- my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
- ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0),
+ thd->get_stmt_da()->get_first_condition_message());
return true;
}
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index bdca2c1182ff..d466cf71c09a 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -531,12 +531,21 @@ bool mysql_update(THD *thd,
/* If running in safe sql mode, don't allow updates without keys */
if (table->quick_keys.is_clear_all())
{
- thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
- if (safe_update && !using_limit)
+ thd->server_status|= SERVER_QUERY_NO_INDEX_USED;
+
+ /*
+ No safe update error will be returned if:
+ 1) Statement is an EXPLAIN OR
+ 2) LIMIT is present.
+
+ Append the first warning (if any) to the error message. Allows the user
+ to understand why index access couldn't be chosen.
+ */
+ if (!thd->lex->is_explain() && safe_update && !using_limit)
{
- my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
- ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
- goto exit_without_my_ok;
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0),
+ thd->get_stmt_da()->get_first_condition_message());
+ DBUG_RETURN(true);
}
}
if (select_lex->has_ft_funcs() && init_ftfuncs(thd, select_lex))
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b0fe4abec076..c570f47300d3 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5585,56 +5585,47 @@ opt_part_values:
{
LEX *lex= Lex;
partition_info *part_info= lex->part_info;
- if (! lex->is_partition_management())
+ if (part_info->part_type == NOT_A_PARTITION)
+ part_info->part_type= HASH_PARTITION;
+ else if (part_info->part_type == RANGE_PARTITION)
{
- if (part_info->part_type == RANGE_PARTITION)
- {
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
- MYSQL_YYABORT;
- }
- if (part_info->part_type == LIST_PARTITION)
- {
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "LIST", "IN");
- MYSQL_YYABORT;
- }
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
+ "RANGE", "LESS THAN");
+ MYSQL_YYABORT;
+ }
+ else if (part_info->part_type == LIST_PARTITION)
+ {
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
+ "LIST", "IN");
+ MYSQL_YYABORT;
}
- else
- part_info->part_type= HASH_PARTITION;
}
| VALUES LESS_SYM THAN_SYM
{
LEX *lex= Lex;
partition_info *part_info= lex->part_info;
- if (! lex->is_partition_management())
+ if (part_info->part_type == NOT_A_PARTITION)
+ part_info->part_type= RANGE_PARTITION;
+ else if (part_info->part_type != RANGE_PARTITION)
{
- if (part_info->part_type != RANGE_PARTITION)
- {
- my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
- MYSQL_YYABORT;
- }
+ my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
+ "RANGE", "LESS THAN");
+ MYSQL_YYABORT;
}
- else
- part_info->part_type= RANGE_PARTITION;
}
part_func_max {}
| VALUES IN_SYM
{
LEX *lex= Lex;
partition_info *part_info= lex->part_info;
- if (! lex->is_partition_management())
+ if (part_info->part_type == NOT_A_PARTITION)
+ part_info->part_type= LIST_PARTITION;
+ else if (part_info->part_type != LIST_PARTITION)
{
- if (part_info->part_type != LIST_PARTITION)
- {
- my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "LIST", "IN");
- MYSQL_YYABORT;
- }
+ my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
+ "LIST", "IN");
+ MYSQL_YYABORT;
}
- else
- part_info->part_type= LIST_PARTITION;
}
part_values_in {}
;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index a273173fdd9c..2550b642bdf3 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -760,7 +760,7 @@ static Sys_var_int32 Sys_binlog_max_flush_queue_time(
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
DEPRECATED(""));
-static Sys_var_ulong Sys_binlog_group_commit_sync_delay(
+static Sys_var_long Sys_binlog_group_commit_sync_delay(
"binlog_group_commit_sync_delay",
"The number of microseconds the server waits for the "
"binary log group commit sync queue to fill before "
diff --git a/sql/table.h b/sql/table.h
index 9d3f838aa423..d0b9d3f1fe47 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1700,11 +1700,21 @@ typedef struct st_lex_alter {
bool account_locked;
} LEX_ALTER;
+/*
+ This structure holds the specifications related to
+ mysql user and the associated auth details.
+*/
typedef struct st_lex_user {
LEX_CSTRING user;
LEX_CSTRING host;
LEX_CSTRING plugin;
LEX_CSTRING auth;
+/*
+ The following flags are indicators for the SQL syntax used while
+ parsing CREATE/ALTER user. While other members are self-explanatory,
+ 'uses_authentication_string_clause' signifies if the password is in
+ hash form (if the var was set to true) or not.
+*/
bool uses_identified_by_clause;
bool uses_identified_with_clause;
bool uses_authentication_string_clause;
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 1e0a91063bed..e5e33f6bc68e 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -1428,7 +1428,7 @@ bool ha_federated::create_where_from_key(String *to,
}
break;
}
- // fallthrough
+ // Fall through
case HA_READ_KEY_OR_NEXT:
DBUG_PRINT("info", ("federated HA_READ_KEY_OR_NEXT %d", i));
if (emit_key_part_name(&tmp, key_part) ||
@@ -1448,7 +1448,7 @@ bool ha_federated::create_where_from_key(String *to,
goto err;
break;
}
- // fallthrough
+ // Fall through
case HA_READ_KEY_OR_PREV:
DBUG_PRINT("info", ("federated HA_READ_KEY_OR_PREV %d", i));
if (emit_key_part_name(&tmp, key_part) ||
diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h
index 5fbf4a93ce07..041489a0d2d9 100644
--- a/storage/heap/ha_heap.h
+++ b/storage/heap/ha_heap.h
@@ -64,6 +64,7 @@ class ha_heap: public handler
uint max_supported_key_part_length(HA_CREATE_INFO
*create_info MY_ATTRIBUTE((unused))) const
{ return HP_MAX_KEY_LENGTH; }
+
double scan_time()
{ return (double) (stats.records+stats.deleted) / 20.0+10; }
double read_time(uint index, uint ranges, ha_rows rows)
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index d7aec0d54d9f..f3380976049f 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -233,7 +233,14 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
case HA_KEYTYPE_VARTEXT1:
case HA_KEYTYPE_VARBINARY2:
case HA_KEYTYPE_VARTEXT2:
- length+= 2;
+ /*
+ For BTREE algorithm, key length, greater than or equal
+ to 255, is packed on 3 bytes.
+ */
+ if(keyinfo->algorithm == HA_KEY_ALG_BTREE)
+ length += size_to_store_key_length(keyinfo->seg[j].length);
+ else
+ length += 2;
break;
default:
break;
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index f3ab59a23ad9..1c30ea9399c1 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -6814,6 +6814,11 @@ dict_foreign_qualify_index(
return(false);
}
+ if (index->type & DICT_SPATIAL) {
+ /* Spatial index cannot be used as foreign keys */
+ return(false);
+ }
+
for (ulint i = 0; i < n_cols; i++) {
dict_field_t* field;
const char* col_name;
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index ed4ec02859f1..3b1fd8cce07a 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -385,8 +385,7 @@ rtr_pcur_getnext_from_path(
if (mode != PAGE_CUR_RTREE_INSERT
&& mode != PAGE_CUR_RTREE_LOCATE
&& mode >= PAGE_CUR_CONTAIN
- && btr_cur->rtr_info->need_prdt_lock
- && found) {
+ && btr_cur->rtr_info->need_prdt_lock) {
lock_prdt_t prdt;
trx_t* trx = thr_get_trx(
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index c7852c380410..ab74584fb866 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -381,6 +381,9 @@ static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
"all" /* IBUF_USE_ALL */
};
+/* Deprecation warning text */
+const char PARTITION_IN_SHARED_TABLESPACE_WARNING[] =
+ "InnoDB : A table partition in a shared tablespace";
/* This tablespace name is reserved by InnoDB in order to explicitly
create a file_per_table tablespace for the table. */
@@ -2646,6 +2649,9 @@ innobase_get_lower_case_table_names(void)
return(lower_case_table_names);
}
+/** return one of the temporary dir from tmpdir
+@return temporary directory */
+char *innobase_mysql_tmpdir(void) { return (mysql_tmpdir); }
/** Creates a temporary file in the location specified by the parameter
path. If the path is NULL, then it will be created in tmpdir.
@@ -3744,7 +3750,7 @@ ha_innobase::reset_template(void)
m_prebuilt->keep_other_fields_on_keyread = 0;
m_prebuilt->read_just_key = 0;
m_prebuilt->in_fts_query = 0;
- m_prebuilt->m_end_range = false;
+ m_prebuilt->m_end_range = false;
/* Reset index condition pushdown state. */
if (m_prebuilt->idx_cond) {
@@ -11967,16 +11973,21 @@ create_table_info_t::create_option_tablespace_is_valid()
if (THDVAR(m_thd, strict_mode)) {
/* Return error if STRICT mode is enabled. */
my_printf_error(ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: innodb_file_per_table option"
- " not supported for temporary tables.", MYF(0));
+ "InnoDB: TABLESPACE=%s option"
+ " is disallowed for temporary tables"
+ " with INNODB_STRICT_NODE=ON. This option is"
+ " deprecated and will be removed in a future release",
+ MYF(0), m_create_info->tablespace);
return(false);
}
/* STRICT mode turned off. Proceed with the
execution with a warning. */
push_warning_printf(m_thd, Sql_condition::SL_WARNING,
ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: innodb_file_per_table option ignored"
- " while creating temporary table with INNODB_STRICT_MODE=OFF.");
+ "InnoDB: TABLESPACE=%s option is ignored."
+ " This option is deprecated and will be"
+ " removed in a future release.",
+ m_create_info->tablespace);
}
return(true);
}
@@ -12922,6 +12933,13 @@ create_table_info_t::innobase_table_flags()
m_flags2 |= DICT_TF2_INTRINSIC;
innodb_row_format = REC_FORMAT_DYNAMIC;
}
+ if (m_create_info->tablespace != NULL &&
+ strcmp(m_create_info->tablespace, reserved_temporary_space_name) == 0) {
+ push_warning_printf(m_thd, Sql_condition::SL_WARNING,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: TABLESPACE=innodb_temporary option is"
+ " deprecated and will be removed in a future release.");
+ }
}
/* Set the table flags */
@@ -16928,11 +16946,15 @@ ha_innobase::end_stmt()
/* This transaction had called ha_innobase::start_stmt() */
trx_t* trx = m_prebuilt->trx;
-
+ trx_mutex_enter(trx);
if (trx->lock.start_stmt) {
- TrxInInnoDB::end_stmt(trx);
-
trx->lock.start_stmt = false;
+ trx_mutex_exit(trx);
+
+ TrxInInnoDB::end_stmt(trx);
+ }
+ else {
+ trx_mutex_exit(trx);
}
return(0);
@@ -17059,12 +17081,16 @@ ha_innobase::start_stmt(
++trx->will_lock;
}
+ trx_mutex_enter(trx);
/* Only do it once per transaction. */
if (!trx->lock.start_stmt && lock_type != TL_UNLOCK) {
+ trx->lock.start_stmt = true;
+ trx_mutex_exit(trx);
TrxInInnoDB::begin_stmt(trx);
-
- trx->lock.start_stmt = true;
+ }
+ else {
+ trx_mutex_exit(trx);
}
DBUG_RETURN(0);
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index d905cbe4e0d1..555280002077 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -22,6 +22,9 @@ this program; if not, write to the Free Software Foundation, Inc.,
system clustered index when there is no primary key. */
extern const char innobase_index_reserve_name[];
+/* Deprecation warning text */
+extern const char PARTITION_IN_SHARED_TABLESPACE_WARNING[];
+
/* "innodb_file_per_table" tablespace name is reserved by InnoDB in order
to explicitly create a file_per_table tablespace for the table. */
extern const char reserved_file_per_table_space_name[];
@@ -689,6 +692,18 @@ const HA_CREATE_INFO* create_info)
reserved_system_space_name)));
}
+/** Check if tablespace is shared tablespace.
+@param[in] tablespace_name Name of the tablespace
+@return true if tablespace is a shared tablespace. */
+UNIV_INLINE
+bool is_shared_tablespace(const char *tablespace_name) {
+ if (tablespace_name != NULL && tablespace_name[0] != '\0' &&
+ (strcmp(tablespace_name, reserved_file_per_table_space_name) != 0)) {
+ return true;
+ }
+ return false;
+}
+
/** Parse hint for table and its indexes, and update the information
in dictionary.
@param[in] thd Connection thread
diff --git a/storage/innobase/handler/ha_innopart.cc b/storage/innobase/handler/ha_innopart.cc
index d4fd342d08b3..dbe2dc42b63e 100644
--- a/storage/innobase/handler/ha_innopart.cc
+++ b/storage/innobase/handler/ha_innopart.cc
@@ -2739,6 +2739,12 @@ ha_innopart::create(
tablespace_name);
DBUG_ENTER("ha_innopart::create");
+
+ if (is_shared_tablespace(create_info->tablespace)) {
+ push_deprecated_warn_no_replacement(
+ ha_thd(), PARTITION_IN_SHARED_TABLESPACE_WARNING);
+ }
+
ut_ad(create_info != NULL);
ut_ad(m_part_info == form->part_info);
ut_ad(table_share != NULL);
@@ -2858,6 +2864,11 @@ ha_innopart::create(
set_create_info_dir(part_elem, create_info);
if (!form->part_info->is_sub_partitioned()) {
+ if (is_shared_tablespace(part_elem->tablespace_name)) {
+ push_deprecated_warn_no_replacement(
+ ha_thd(), PARTITION_IN_SHARED_TABLESPACE_WARNING);
+ }
+
error = info.prepare_create_table(partition_name);
if (error != 0) {
goto cleanup;
@@ -2878,6 +2889,11 @@ ha_innopart::create(
while ((sub_elem = sub_it++)) {
ut_ad(sub_elem->partition_name != NULL);
+ if (is_shared_tablespace(sub_elem->tablespace_name)) {
+ push_deprecated_warn_no_replacement(
+ ha_thd(), PARTITION_IN_SHARED_TABLESPACE_WARNING);
+ }
+
/* 'table' will be
#P##SP#.
Append the sub-partition name to
@@ -3002,13 +3018,24 @@ ha_innopart::create(
DBUG_RETURN(error);
cleanup:
- trx_rollback_for_mysql(info.trx());
+ trx_rollback_for_mysql(info.trx());
- row_mysql_unlock_data_dictionary(info.trx());
+ row_mysql_unlock_data_dictionary(info.trx());
- trx_free_for_mysql(info.trx());
+ ulint dummy;
+ char norm_name[FN_REFLEN];
- DBUG_RETURN(error);
+ normalize_table_name(norm_name, name);
+
+ uint lent = (uint)strlen(norm_name);
+ ut_a(lent < FN_REFLEN);
+ norm_name[lent] = '#';
+ norm_name[lent + 1] = 0;
+
+ row_drop_database_for_mysql(norm_name, info.trx(), &dummy);
+
+ trx_free_for_mysql(info.trx());
+ DBUG_RETURN(error);
}
/** Discards or imports an InnoDB tablespace.
@@ -4260,6 +4287,15 @@ ha_innopart::external_lock(
ut_ad(table->quiesce == QUIESCE_START);
+ if (dict_table_is_discarded(table)) {
+ ib_senderrf(m_prebuilt->trx->mysql_thd,
+ IB_LOG_LEVEL_ERROR,
+ ER_TABLESPACE_DISCARDED,
+ table->name.m_name);
+
+ return (HA_ERR_NO_SUCH_TABLE);
+ }
+
row_quiesce_table_start(table,
m_prebuilt->trx);
@@ -4427,6 +4463,11 @@ ha_innopart::create_new_partition(
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
+ if (tablespace_is_shared_space(create_info)) {
+ push_deprecated_warn_no_replacement(
+ ha_thd(), PARTITION_IN_SHARED_TABLESPACE_WARNING);
+ }
+
error = ha_innobase::create(norm_name, table, create_info);
create_info->tablespace = tablespace_name_backup;
create_info->data_file_name = data_file_name_backup;
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 36802c1f1719..7153937f246c 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -6512,6 +6512,8 @@ ha_innobase::inplace_alter_table(
/* Read the clustered index of the table and build
indexes based on this information using temporary
files and merge sort. */
+ DEBUG_SYNC_C("alter_table_update_log");
+
DBUG_EXECUTE_IF("innodb_OOM_inplace_alter",
error = DB_OUT_OF_MEMORY; goto oom;);
error = row_merge_build_indexes(
@@ -6570,11 +6572,23 @@ ha_innobase::inplace_alter_table(
table. Either way, we should be seeing and
reporting a bogus duplicate key error. */
dup_key = NULL;
- } else {
- DBUG_ASSERT(m_prebuilt->trx->error_key_num
- < ha_alter_info->key_count);
+ } else if (m_prebuilt->trx->error_key_num == 0) {
dup_key = &ha_alter_info->key_info_buffer[
m_prebuilt->trx->error_key_num];
+ } else {
+ /* Check if there is generated cluster index column */
+ if (ctx->num_to_add_index > ha_alter_info->key_count) {
+ DBUG_ASSERT(m_prebuilt->trx->error_key_num
+ <= ha_alter_info->key_count);
+ dup_key = &ha_alter_info->key_info_buffer[
+ m_prebuilt->trx->error_key_num - 1];
+ }
+ else {
+ DBUG_ASSERT(m_prebuilt->trx->error_key_num
+ < ha_alter_info->key_count);
+ dup_key = &ha_alter_info->key_info_buffer[
+ m_prebuilt->trx->error_key_num];
+ }
}
print_keydup_error(altered_table, dup_key, MYF(0));
break;
@@ -7785,10 +7799,19 @@ commit_try_rebuild(
FTS_DOC_ID. */
dup_key = NULL;
} else {
- DBUG_ASSERT(err_key <
- ha_alter_info->key_count);
- dup_key = &ha_alter_info
- ->key_info_buffer[err_key];
+ /* Check if there is generated cluster index column */
+ if (ctx->num_to_add_index > ha_alter_info->key_count) {
+ DBUG_ASSERT(err_key <=
+ ha_alter_info->key_count);
+ dup_key = &ha_alter_info
+ ->key_info_buffer[err_key - 1];
+ }
+ else {
+ DBUG_ASSERT(err_key <
+ ha_alter_info->key_count);
+ dup_key = &ha_alter_info
+ ->key_info_buffer[err_key];
+ }
}
print_keydup_error(altered_table, dup_key, MYF(0));
DBUG_RETURN(true);
@@ -9320,6 +9343,12 @@ ha_innopart::prepare_inplace_alter_table(
thd = ha_thd();
+ if (ha_alter_info->create_info->used_fields & HA_CREATE_USED_TABLESPACE
+ && tablespace_is_shared_space(ha_alter_info->create_info)) {
+ push_deprecated_warn_no_replacement(
+ ha_thd(), PARTITION_IN_SHARED_TABLESPACE_WARNING);
+ }
+
/* Clean up all ins/upd nodes. */
clear_ins_upd_nodes();
/* Based on Sql_alloc class, return NULL for new on failure. */
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index d91283b83571..83ae12d3dfbe 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -2559,6 +2559,11 @@ os_file_get_status(
bool read_only);
#if !defined(UNIV_HOTBACKUP)
+/** return one of the tmpdir path
+@return tmporary dir*/
+char *innobase_mysql_tmpdir(void);
+
+
/** Creates a temporary file in the location specified by the parameter
path. If the path is NULL then it will be created on --tmpdir location.
This function is defined in ha_innodb.cc.
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 7490f9e0ad86..8210693c1103 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -47,7 +47,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_BUGFIX MYSQL_VERSION_PATCH
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 25
+#define PERCONA_INNODB_VERSION 26
#endif
/* The following is the InnoDB version as shown in
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 3e7e317e8c08..2f3673e5cbf2 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1868,6 +1868,11 @@ row_ins_check_foreign_constraint(
thr->lock_state = QUE_THR_LOCK_NOLOCK;
+ if(trx->error_state != DB_SUCCESS) {
+ err = trx->error_state;
+ goto exit_func;
+ }
+
DBUG_PRINT("to_be_dropped",
("table: %s", check_table->name.m_name));
if (check_table->to_be_dropped) {
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 5ea880b6c848..3be8bd16ffdf 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1038,7 +1038,7 @@ row_log_table_low_redundant(
old_pk_size = rec_get_converted_size_temp(
new_index, old_pk->fields, old_pk->n_fields,
- ventry, &old_pk_extra_size);
+ NULL, &old_pk_extra_size);
ut_ad(old_pk_extra_size < 0x100);
mrec_size += 1/*old_pk_extra_size*/ + old_pk_size;
}
@@ -1860,6 +1860,7 @@ row_log_table_apply_insert_low(
}
do {
+ n_index++;
if (!(index = dict_table_get_next_index(index))) {
break;
}
@@ -2440,14 +2441,16 @@ row_log_table_apply_update(
dtuple_t* old_row;
row_ext_t* old_ext;
- if (dict_table_get_next_index(index)) {
+ if (dict_index_t* index_next = dict_table_get_next_index(index)) {
/* Construct the row corresponding to the old value of
the record. */
old_row = row_build(
- ROW_COPY_DATA, index, btr_pcur_get_rec(&pcur),
- cur_offsets, NULL, NULL, NULL, &old_ext, heap);
+ ROW_COPY_DATA, index, btr_pcur_get_rec(&pcur),
+ cur_offsets, NULL, NULL, NULL, &old_ext, heap);
+ if (dict_index_has_virtual(index_next)) {
+ dtuple_copy_v_fields(old_row, update->old_vrow);
+ }
ut_ad(old_row);
-
DBUG_PRINT("ib_alter_table",
("update table " IB_ID_FMT
"(index " IB_ID_FMT "): %s to %s",
@@ -2480,6 +2483,8 @@ row_log_table_apply_update(
}
while ((index = dict_table_get_next_index(index)) != NULL) {
+
+ n_index++;
if (error != DB_SUCCESS) {
break;
}
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 83a580880e7a..ad9603042801 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -3859,21 +3859,27 @@ int
row_merge_file_create_low(
const char* path)
{
- int fd;
+ int fd;
+ if (path == NULL) {
+ path = innobase_mysql_tmpdir();
+ }
#ifdef UNIV_PFS_IO
/* This temp file open does not go through normal
file APIs, add instrumentation to register with
performance schema */
struct PSI_file_locker* locker = NULL;
- PSI_file_locker_state state;
- locker = PSI_FILE_CALL(get_thread_file_name_locker)(
- &state, innodb_temp_file_key.m_value, PSI_FILE_OPEN,
- "Innodb Merge Temp File", &locker);
- if (locker != NULL) {
+ char *filepath = NULL;
+ filepath =
+ fil_make_filepath(path, "Innodb Merge Temp File", NO_EXT, false);
+ PSI_file_locker_state state;
+ locker = PSI_FILE_CALL(get_thread_file_name_locker)(
+ &state, innodb_temp_file_key.m_value, PSI_FILE_OPEN, filepath,
+ &locker);
+ if (locker != NULL) {
PSI_FILE_CALL(start_file_open_wait)(locker,
__FILE__,
__LINE__);
- }
+ }
#endif
fd = innobase_mysql_tmpfile(path);
#ifdef UNIV_PFS_IO
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 3ffe5ee23a6b..71a7cc649d32 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -6116,6 +6116,9 @@ row_rename_table_for_mysql(
" = TO_BINARY(:old_table_name);\n"
"END;\n"
, FALSE, trx);
+ if (err != DB_SUCCESS) {
+ goto end;
+ }
} else if (n_constraints_to_drop > 0) {
/* Drop some constraints of tmp tables. */
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 8d374286dbc6..dd8cd83cd034 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -278,6 +278,7 @@ row_build_index_entry_low(
continue;
}
+
if ((!ind_field || ind_field->prefix_len == 0)
&& (!dfield_is_ext(dfield)
|| dict_index_is_clust(index))) {
@@ -298,7 +299,8 @@ row_build_index_entry_low(
stored off-page. */
ut_ad(col->ord_part);
- if (ext) {
+ if (ext && !dict_col_is_virtual(col)) {
+
/* See if the column is stored externally. */
const byte* buf = row_ext_lookup(ext, col_no,
&len);
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 45ac779582a0..b8619b658a3d 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -5290,7 +5290,7 @@ row_search_mvcc(
passed to InnoDB when there is no ICP and number of
loops in row_search_mvcc for rows found but not
reporting due to search views etc. */
- if (prev_rec != NULL
+ if (prev_rec != NULL && !prebuilt->innodb_api
&& prebuilt->m_mysql_handler->end_range != NULL
&& prebuilt->idx_cond == NULL && end_loop >= 100) {
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 05afc5a385b9..62a20d9ca776 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -267,9 +267,10 @@ row_upd_check_references_constraints(
if it is interrupted. So if the foreign table is
undergoing a truncate, ignore the FK check. */
- if (foreign_table != NULL
- && fil_space_is_being_truncated(
- foreign_table->space)) {
+ if (foreign_table != NULL &&
+ (dict_table_is_discarded(foreign_table)
+ || fil_space_is_being_truncated(
+ foreign_table->space))) {
continue;
}
@@ -1985,6 +1986,7 @@ row_upd_store_v_row(
}
dfield_copy_data(dfield, upd_field->old_v_val);
+ dfield_dup(dfield, node->heap);
break;
}
@@ -2005,6 +2007,7 @@ row_upd_store_v_row(
update->old_vrow,
col_no);
dfield_copy_data(dfield, vfield);
+ dfield_dup(dfield, node->heap);
}
} else {
/* Need to compute, this happens when
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 7717a02a2a2f..ad836f9f85f3 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -876,7 +876,7 @@ int ha_myisam::write_row(uchar *buf)
If we have an auto_increment column and we are writing a changed row
or a new row, then update the auto_increment value in the record.
*/
- if (table->next_number_field && buf == table->record[0])
+ if (table && table->next_number_field && buf == table->record[0])
{
if ((error= update_auto_increment()))
return error;
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index e823efd50793..ad74615dae2a 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -1718,6 +1718,12 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, uchar *buf,
MYISAM_SHARE *share=info->s;
DBUG_ENTER("_mi_read_rnd_dynamic_record");
+ DBUG_EXECUTE_IF("catch_file_offset_deviation",
+ {
+ if (filepos)
+ DBUG_RETURN(HA_ERR_RECORD_DELETED);
+ });
+
info_read=0;
if (info->lock_type == F_UNLCK)
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 5fda19d0cbdf..5dd5c3fb96c1 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -377,6 +377,7 @@ int ha_myisammrg::open(const char *name, int mode MY_ATTRIBUTE((unused)),
/* retrieve children table list. */
if (is_cloned)
{
+ DEBUG_SYNC(current_thd, "before_myrg_open");
/*
Open and attaches the MyISAM tables,that are under the MERGE table
parent, on the MyISAM storage engine interface directly within the
@@ -394,6 +395,13 @@ int ha_myisammrg::open(const char *name, int mode MY_ATTRIBUTE((unused)),
file->children_attached= TRUE;
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+ /*
+ There may arise a scenario where it might end up with two different
+ MYMERGE_INFO data if any one of the child table is updated in
+ between myrg_open() and the last ha_myisammrg::info(). So we need make
+ sure that the MYMERGE_INFO data are in sync.
+ */
+ table->file->info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
}
else if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this)))
{
diff --git a/storage/ndb/CMakeLists.txt b/storage/ndb/CMakeLists.txt
index 871774372645..f1ef60f9d81f 100644
--- a/storage/ndb/CMakeLists.txt
+++ b/storage/ndb/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -185,7 +185,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_BINARY_DIR}/include
# Util library includes
- ${ZLIB_INCLUDE_DIR}
${EDITLINE_INCLUDE_DIR})
# The root of storage/ndb/
diff --git a/storage/ndb/ndb_configure.cmake b/storage/ndb/ndb_configure.cmake
index efeaf408cb62..111ad03aeb36 100644
--- a/storage/ndb/ndb_configure.cmake
+++ b/storage/ndb/ndb_configure.cmake
@@ -1,5 +1,5 @@
-# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -228,10 +228,9 @@ IF(NOT DEFINED WITH_ZLIB)
# Hardcode use of the bundled zlib if not set by MySQL
MESSAGE(STATUS "Using bundled zlib (hardcoded)")
SET(ZLIB_LIBRARY zlib)
- SET(ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/zlib)
+ INCLUDE_DIRECTORIES(SYSTEM ${CMAKE_SOURCE_DIR}/zlib)
ENDIF()
NDB_REQUIRE_VARIABLE(ZLIB_LIBRARY)
-NDB_REQUIRE_VARIABLE(ZLIB_INCLUDE_DIR)
IF(WITH_CLASSPATH)
MESSAGE(STATUS "Using supplied classpath: ${WITH_CLASSPATH}")
diff --git a/storage/ndb/src/common/util/ndbzio.c b/storage/ndb/src/common/util/ndbzio.c
index 5852ec075a01..2a2a5f4c4053 100644
--- a/storage/ndb/src/common/util/ndbzio.c
+++ b/storage/ndb/src/common/util/ndbzio.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -45,11 +45,11 @@
* This is a casual hack to do static memory allocation
* (needed by NDB)
*/
-#include "../../../../zlib/zutil.h"
-#include "../../../../zlib/zconf.h"
-#include "../../../../zlib/inftrees.h"
-#include "../../../../zlib/inflate.h"
-#include "../../../../zlib/deflate.h"
+#include
+#include
+#include
+#include
+#include
#include
diff --git a/storage/perfschema/table_replication_applier_configuration.cc b/storage/perfschema/table_replication_applier_configuration.cc
index a88e0f82846d..cf3e9d4e97fb 100644
--- a/storage/perfschema/table_replication_applier_configuration.cc
+++ b/storage/perfschema/table_replication_applier_configuration.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -65,7 +65,7 @@ table_replication_applier_configuration::m_share=
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_applier_configuration::get_row_count,
- sizeof(PFS_simple_index), /* ref length */
+ sizeof(pos_t), /* ref length */
&m_table_lock,
&m_field_def,
false, /* checked */
@@ -103,12 +103,10 @@ ha_rows table_replication_applier_configuration::get_row_count()
int table_replication_applier_configuration::rnd_next(void)
{
Master_info *mi;
- int res= HA_ERR_END_OF_FILE;
-
channel_map.rdlock();
for (m_pos.set_at(&m_next_pos);
- m_pos.m_index < channel_map.get_max_channels() && res != 0;
+ m_pos.m_index < channel_map.get_max_channels();
m_pos.next())
{
mi= channel_map.get_mi_at_pos(m_pos.m_index);
@@ -117,12 +115,13 @@ int table_replication_applier_configuration::rnd_next(void)
{
make_row(mi);
m_next_pos.set_after(&m_pos);
- res= 0;
+ channel_map.unlock();
+ return 0;
}
}
channel_map.unlock();
- return res;
+ return HA_ERR_END_OF_FILE;
}
int table_replication_applier_configuration::rnd_pos(const void *pos)
diff --git a/storage/perfschema/table_replication_applier_configuration.h b/storage/perfschema/table_replication_applier_configuration.h
index e5ec69a64b8e..4088c346495d 100644
--- a/storage/perfschema/table_replication_applier_configuration.h
+++ b/storage/perfschema/table_replication_applier_configuration.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -48,6 +48,8 @@ struct st_row_applier_config {
/** Table PERFORMANCE_SCHEMA.replication_applier_configuration */
class table_replication_applier_configuration: public PFS_engine_table
{
+ typedef PFS_simple_index pos_t;
+
private:
void make_row(Master_info *mi);
@@ -60,9 +62,9 @@ class table_replication_applier_configuration: public PFS_engine_table
/** True is the current row exists. */
bool m_row_exists;
/** Current position. */
- PFS_simple_index m_pos;
+ pos_t m_pos;
/** Next position. */
- PFS_simple_index m_next_pos;
+ pos_t m_next_pos;
protected:
/**
diff --git a/storage/perfschema/table_replication_applier_status.cc b/storage/perfschema/table_replication_applier_status.cc
index e0824b056feb..fc8044b5dd93 100644
--- a/storage/perfschema/table_replication_applier_status.cc
+++ b/storage/perfschema/table_replication_applier_status.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -74,7 +74,7 @@ table_replication_applier_status::m_share=
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_applier_status::get_row_count, /* records */
- sizeof(PFS_simple_index), /* ref length */
+ sizeof(pos_t), /* ref length */
&m_table_lock,
&m_field_def,
false, /* checked */
@@ -110,12 +110,10 @@ ha_rows table_replication_applier_status::get_row_count()
int table_replication_applier_status::rnd_next(void)
{
Master_info *mi;
- int res= HA_ERR_END_OF_FILE;
-
channel_map.rdlock();
for(m_pos.set_at(&m_next_pos);
- m_pos.m_index < channel_map.get_max_channels() && res != 0;
+ m_pos.m_index < channel_map.get_max_channels();
m_pos.next())
{
mi= channel_map.get_mi_at_pos(m_pos.m_index);
@@ -124,12 +122,13 @@ int table_replication_applier_status::rnd_next(void)
{
make_row(mi);
m_next_pos.set_after(&m_pos);
- res= 0;
+ channel_map.unlock();
+ return 0;
}
}
channel_map.unlock();
- return res;
+ return HA_ERR_END_OF_FILE;
}
diff --git a/storage/perfschema/table_replication_applier_status.h b/storage/perfschema/table_replication_applier_status.h
index 955439be6daf..5b6f0793d030 100644
--- a/storage/perfschema/table_replication_applier_status.h
+++ b/storage/perfschema/table_replication_applier_status.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -59,6 +59,8 @@ struct st_row_applier_status {
/** Table PERFORMANCE_SCHEMA.replication_applier_status */
class table_replication_applier_status: public PFS_engine_table
{
+ typedef PFS_simple_index pos_t;
+
private:
void make_row(Master_info *mi);
@@ -71,9 +73,9 @@ class table_replication_applier_status: public PFS_engine_table
/** True is the current row exists. */
bool m_row_exists;
/** Current position. */
- PFS_simple_index m_pos;
+ pos_t m_pos;
/** Next position. */
- PFS_simple_index m_next_pos;
+ pos_t m_next_pos;
protected:
/**
diff --git a/storage/perfschema/table_replication_applier_status_by_coordinator.cc b/storage/perfschema/table_replication_applier_status_by_coordinator.cc
index 5f2427bed67f..9ed252f7ba23 100644
--- a/storage/perfschema/table_replication_applier_status_by_coordinator.cc
+++ b/storage/perfschema/table_replication_applier_status_by_coordinator.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -85,7 +85,7 @@ table_replication_applier_status_by_coordinator::m_share=
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_applier_status_by_coordinator::get_row_count,
- sizeof(PFS_simple_index), /* ref length */
+ sizeof(pos_t), /* ref length */
&m_table_lock,
&m_field_def,
false, /* checked */
@@ -122,12 +122,10 @@ ha_rows table_replication_applier_status_by_coordinator::get_row_count()
int table_replication_applier_status_by_coordinator::rnd_next(void)
{
Master_info *mi;
- int res= HA_ERR_END_OF_FILE;
-
channel_map.rdlock();
for(m_pos.set_at(&m_next_pos);
- m_pos.m_index < channel_map.get_max_channels() && res != 0;
+ m_pos.m_index < channel_map.get_max_channels();
m_pos.next())
{
mi= channel_map.get_mi_at_pos(m_pos.m_index);
@@ -144,12 +142,13 @@ int table_replication_applier_status_by_coordinator::rnd_next(void)
{
make_row(mi);
m_next_pos.set_after(&m_pos);
- res= 0;
+ channel_map.unlock();
+ return 0;
}
}
channel_map.unlock();
- return res;
+ return HA_ERR_END_OF_FILE;
}
int table_replication_applier_status_by_coordinator::rnd_pos(const void *pos)
diff --git a/storage/perfschema/table_replication_applier_status_by_coordinator.h b/storage/perfschema/table_replication_applier_status_by_coordinator.h
index 30a1f39ee466..269ea111a4be 100644
--- a/storage/perfschema/table_replication_applier_status_by_coordinator.h
+++ b/storage/perfschema/table_replication_applier_status_by_coordinator.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -65,6 +65,8 @@ struct st_row_coordinator {
/** Table PERFORMANCE_SCHEMA.replication_applier_status_by_coordinator */
class table_replication_applier_status_by_coordinator: public PFS_engine_table
{
+ typedef PFS_simple_index pos_t;
+
private:
void make_row(Master_info *mi);
@@ -77,9 +79,9 @@ class table_replication_applier_status_by_coordinator: public PFS_engine_table
/** True is the current row exists. */
bool m_row_exists;
/** Current position. */
- PFS_simple_index m_pos;
+ pos_t m_pos;
/** Next position. */
- PFS_simple_index m_next_pos;
+ pos_t m_next_pos;
protected:
/**
diff --git a/storage/perfschema/table_replication_applier_status_by_worker.cc b/storage/perfschema/table_replication_applier_status_by_worker.cc
index e4e99dc23259..e5914b20dcad 100644
--- a/storage/perfschema/table_replication_applier_status_by_worker.cc
+++ b/storage/perfschema/table_replication_applier_status_by_worker.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -94,7 +94,7 @@ table_replication_applier_status_by_worker::m_share=
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_applier_status_by_worker::get_row_count, /*records*/
- sizeof(PFS_simple_index), /* ref length */
+ sizeof(pos_t), /* ref length */
&m_table_lock,
&m_field_def,
false, /* checked */
@@ -109,8 +109,7 @@ PFS_engine_table* table_replication_applier_status_by_worker::create(void)
table_replication_applier_status_by_worker
::table_replication_applier_status_by_worker()
: PFS_engine_table(&m_share, &m_pos),
- m_row_exists(false), m_pos(), m_next_pos(),
- m_applier_pos(0), m_applier_next_pos(0)
+ m_row_exists(false), m_pos(), m_next_pos()
{}
table_replication_applier_status_by_worker
@@ -121,8 +120,6 @@ void table_replication_applier_status_by_worker::reset_position(void)
{
m_pos.reset();
m_next_pos.reset();
- m_applier_pos.m_index=0;
- m_applier_next_pos.m_index=0;
}
ha_rows table_replication_applier_status_by_worker::get_row_count()
@@ -138,52 +135,47 @@ int table_replication_applier_status_by_worker::rnd_next(void)
{
Slave_worker *worker;
Master_info *mi;
- int res= HA_ERR_END_OF_FILE;
+ size_t wc;
channel_map.rdlock();
- /*
- For each SQL Thread in all channels get the respective Master_info and
- construct a row to display its status in
- 'replication_applier_status_by_worker' table in case of single threaded
- slave mode.
- */
- for(m_applier_pos.set_at(&m_applier_next_pos);
- m_applier_pos.m_index < channel_map.get_max_channels();
- m_applier_pos.next())
- {
- mi= channel_map.get_mi_at_pos(m_applier_pos.m_index);
-
- if (mi && mi->host[0] && mi->rli && mi->rli->get_worker_count()==0)
- {
- make_row(mi);
- m_applier_next_pos.set_after(&m_applier_pos);
-
- channel_map.unlock();
- return 0;
- }
- }
-
for (m_pos.set_at(&m_next_pos);
- m_pos.has_more_channels(channel_map.get_max_channels()) && res != 0;
+ m_pos.has_more_channels(channel_map.get_max_channels());
m_pos.next_channel())
{
mi= channel_map.get_mi_at_pos(m_pos.m_index_1);
if (mi && mi->host[0])
{
- worker= mi->rli->get_worker(m_pos.m_index_2);
- if (worker)
+ wc= mi->rli->get_worker_count();
+
+ if (wc == 0)
{
- make_row(worker);
- m_next_pos.set_after(&m_pos);
- res= 0;
+ /* Single Thread Slave */
+ make_row(mi);
+ m_next_pos.set_channel_after(&m_pos);
+ channel_map.unlock();
+ return 0;
+ }
+
+ for (; m_pos.m_index_2 < wc; m_pos.next_worker())
+ {
+ /* Multi Thread Slave */
+
+ worker = mi->rli->get_worker(m_pos.m_index_2);
+ if (worker)
+ {
+ make_row(worker);
+ m_next_pos.set_after(&m_pos);
+ channel_map.unlock();
+ return 0;
+ }
}
}
}
channel_map.unlock();
- return res;
+ return HA_ERR_END_OF_FILE;
}
int table_replication_applier_status_by_worker::rnd_pos(const void *pos)
@@ -191,6 +183,7 @@ int table_replication_applier_status_by_worker::rnd_pos(const void *pos)
Slave_worker *worker;
Master_info *mi;
int res= HA_ERR_RECORD_DELETED;
+ size_t wc;
set_position(pos);
@@ -201,22 +194,26 @@ int table_replication_applier_status_by_worker::rnd_pos(const void *pos)
if (!mi || !mi->rli || !mi->host[0])
goto end;
- DBUG_ASSERT(m_pos.m_index_1 < mi->rli->get_worker_count());
- /*
- Display SQL Thread's status only in the case of single threaded mode.
- */
- if (mi->rli->get_worker_count() == 0)
+ wc = mi->rli->get_worker_count();
+
+ if (wc == 0)
{
+ /* Single Thread Slave */
make_row(mi);
- res= 0;
- goto end;
+ res=0;
}
- worker= mi->rli->get_worker(m_pos.m_index_2);
-
- if (worker != NULL)
+ else
{
- make_row(worker);
- res= 0;
+ /* Multi Thread Slave */
+ if (m_pos.m_index_2 < wc)
+ {
+ worker = mi->rli->get_worker(m_pos.m_index_2);
+ if (worker != NULL)
+ {
+ make_row(worker);
+ res=0;
+ }
+ }
}
end:
diff --git a/storage/perfschema/table_replication_applier_status_by_worker.h b/storage/perfschema/table_replication_applier_status_by_worker.h
index ed0ce7480b26..f58493d7c0cc 100644
--- a/storage/perfschema/table_replication_applier_status_by_worker.h
+++ b/storage/perfschema/table_replication_applier_status_by_worker.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -74,14 +74,16 @@ struct st_row_worker {
};
/**
- Index 1 for replication channel
- Index 2 for worker
+ Position in table replication_applier_status_by_worker.
+ Index 1 for replication channel.
+ Index 2 for worker:
+ - position [0] is for Single Thread Slave (Master_info)
+ - position [1] .. [N] is for Multi Thread Slave (Slave_worker)
*/
-struct workers_per_channel
-:public PFS_double_index
+struct pos_replication_applier_status_by_worker : public PFS_double_index
{
- workers_per_channel()
- :PFS_double_index(0,0)
+
+ pos_replication_applier_status_by_worker() : PFS_double_index(0, 0)
{}
inline void reset(void)
@@ -98,12 +100,26 @@ struct workers_per_channel
m_index_1++;
m_index_2= 0;
}
+
+ inline void next_worker()
+ {
+ m_index_2++;
+ }
+
+ inline void
+ set_channel_after(const pos_replication_applier_status_by_worker *other)
+ {
+ m_index_1 = other->m_index_1 + 1;
+ m_index_2 = 0;
+ }
};
/** Table PERFORMANCE_SCHEMA.replication_applier_status_by_worker */
class table_replication_applier_status_by_worker: public PFS_engine_table
{
+ typedef pos_replication_applier_status_by_worker pos_t;
+
private:
void make_row(Slave_worker *);
/*
@@ -121,13 +137,9 @@ class table_replication_applier_status_by_worker: public PFS_engine_table
/** True is the current row exists. */
bool m_row_exists;
/** Current position. */
- workers_per_channel m_pos;
- /** Next position. */
- workers_per_channel m_next_pos;
- /** Current position. */
- PFS_simple_index m_applier_pos;
+ pos_t m_pos;
/** Next position. */
- PFS_simple_index m_applier_next_pos;
+ pos_t m_next_pos;
protected:
/**
diff --git a/storage/perfschema/table_replication_connection_configuration.cc b/storage/perfschema/table_replication_connection_configuration.cc
index 8fe04802aac2..633c9862c587 100644
--- a/storage/perfschema/table_replication_connection_configuration.cc
+++ b/storage/perfschema/table_replication_connection_configuration.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -147,7 +147,7 @@ table_replication_connection_configuration::m_share=
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_connection_configuration::get_row_count, /* records */
- sizeof(PFS_simple_index), /* ref length */
+ sizeof(pos_t), /* ref length */
&m_table_lock,
&m_field_def,
false, /* checked */
@@ -189,12 +189,10 @@ ha_rows table_replication_connection_configuration::get_row_count()
int table_replication_connection_configuration::rnd_next(void)
{
Master_info *mi;
- int res= HA_ERR_END_OF_FILE;
-
channel_map.rdlock();
for (m_pos.set_at(&m_next_pos);
- m_pos.m_index < channel_map.get_max_channels() && res != 0;
+ m_pos.m_index < channel_map.get_max_channels();
m_pos.next())
{
mi= channel_map.get_mi_at_pos(m_pos.m_index);
@@ -203,12 +201,13 @@ int table_replication_connection_configuration::rnd_next(void)
{
make_row(mi);
m_next_pos.set_after(&m_pos);
- res= 0;
+ channel_map.unlock();
+ return 0;
}
}
channel_map.unlock();
- return res;
+ return HA_ERR_END_OF_FILE;
}
int table_replication_connection_configuration::rnd_pos(const void *pos)
diff --git a/storage/perfschema/table_replication_connection_configuration.h b/storage/perfschema/table_replication_connection_configuration.h
index f71aecefd0ef..925530cf171e 100644
--- a/storage/perfschema/table_replication_connection_configuration.h
+++ b/storage/perfschema/table_replication_connection_configuration.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -93,6 +93,8 @@ struct st_row_connect_config {
/** Table PERFORMANCE_SCHEMA.TABLE_REPLICATION_CONNECTION_CONFIGURATION. */
class table_replication_connection_configuration: public PFS_engine_table
{
+ typedef PFS_simple_index pos_t;
+
private:
void make_row(Master_info *);
@@ -105,9 +107,9 @@ class table_replication_connection_configuration: public PFS_engine_table
/** Current row */
st_row_connect_config m_row;
/** Current position. */
- PFS_simple_index m_pos;
+ pos_t m_pos;
/** Next position. */
- PFS_simple_index m_next_pos;
+ pos_t m_next_pos;
protected:
/**
diff --git a/storage/perfschema/table_replication_connection_status.cc b/storage/perfschema/table_replication_connection_status.cc
index 72ac8c1fc920..66ce8cd1fafa 100644
--- a/storage/perfschema/table_replication_connection_status.cc
+++ b/storage/perfschema/table_replication_connection_status.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -151,7 +151,7 @@ table_replication_connection_status::m_share=
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_connection_status::get_row_count, /* records */
- sizeof(PFS_simple_index), /* ref length */
+ sizeof(pos_t), /* ref length */
&m_table_lock,
&m_field_def,
false, /* checked */
@@ -190,12 +190,10 @@ ha_rows table_replication_connection_status::get_row_count()
int table_replication_connection_status::rnd_next(void)
{
Master_info *mi= NULL;
- int res= HA_ERR_END_OF_FILE;
-
channel_map.rdlock();
for (m_pos.set_at(&m_next_pos);
- m_pos.m_index < channel_map.get_max_channels() && res != 0;
+ m_pos.m_index < channel_map.get_max_channels();
m_pos.next())
{
mi= channel_map.get_mi_at_pos(m_pos.m_index);
@@ -204,12 +202,13 @@ int table_replication_connection_status::rnd_next(void)
{
make_row(mi);
m_next_pos.set_after(&m_pos);
- res= 0;
+ channel_map.unlock();
+ return 0;
}
}
channel_map.unlock();
- return res;
+ return HA_ERR_END_OF_FILE;
}
int table_replication_connection_status::rnd_pos(const void *pos)
diff --git a/storage/perfschema/table_replication_connection_status.h b/storage/perfschema/table_replication_connection_status.h
index 6c95da19235a..dbd70e37f987 100644
--- a/storage/perfschema/table_replication_connection_status.h
+++ b/storage/perfschema/table_replication_connection_status.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
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
@@ -91,6 +91,8 @@ struct st_row_connect_status {
/** Table PERFORMANCE_SCHEMA.REPLICATION_CONNECTION_STATUS. */
class table_replication_connection_status: public PFS_engine_table
{
+ typedef PFS_simple_index pos_t;
+
private:
void make_row(Master_info *mi);
@@ -103,9 +105,9 @@ class table_replication_connection_status: public PFS_engine_table
/** Current row */
st_row_connect_status m_row;
/** Current position. */
- PFS_simple_index m_pos;
+ pos_t m_pos;
/** Next position. */
- PFS_simple_index m_next_pos;
+ pos_t m_next_pos;
protected:
/**
diff --git a/support-files/build-tags b/support-files/build-tags
index c37485e32f9a..14af22b3ef1e 100755
--- a/support-files/build-tags
+++ b/support-files/build-tags
@@ -1,12 +1,41 @@
-#! /bin/sh
+#! /bin/bash
-rm -f TAGS
+# Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# 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
+
+tagstyle=${1:-etags}
+
+common_opts="--langmap=C++:+.ic,YACC:+.yy -I MY_ATTRIBUTE+"
+case $tagstyle in
+ "etags") tagfile=TAGS
+ tagopt="-e $common_opts"
+ ;;
+ "ctags") tagfile=tags
+ tagopt="--fields=+l $common_opts"
+ ;;
+ *) echo "$0 [etags|ctags]"
+ exit 1
+ ;;
+esac
+
+rm -f $tagfile
filter='\.cpp$\|\.cc$\|\.c$\|\.h$\|sql_yacc\.yy$\|\.hpp$\|\.ic$'
list="find . -type f"
git rev-parse >/dev/null 2>/dev/null && list="git ls-files"
-$list |grep $filter |while read f;
-do
- etags -o TAGS --append $f
-done
+ctags $tagopt -o $tagfile $( $list | grep $filter )
+
+echo "wrote file `pwd`/$tagfile"
diff --git a/unittest/gunit/CMakeLists.txt b/unittest/gunit/CMakeLists.txt
index beca81be13fe..4f5eddb0aa5c 100644
--- a/unittest/gunit/CMakeLists.txt
+++ b/unittest/gunit/CMakeLists.txt
@@ -45,6 +45,7 @@ IF(LOCAL_GMOCK_ZIP
ENDIF()
IF (WITH_GMOCK)
+ FILE(TO_CMAKE_PATH "${WITH_GMOCK}" WITH_GMOCK)
## Did we get a full path name, including file name?
IF (${WITH_GMOCK} MATCHES ".*\\.zip")
GET_FILENAME_COMPONENT(GMOCK_DIR ${WITH_GMOCK} PATH)
@@ -204,7 +205,6 @@ ENDIF()
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libbinlogevents/include
- ${ZLIB_INCLUDE_DIR}
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/sql/auth
diff --git a/unittest/gunit/dynarray-t.cc b/unittest/gunit/dynarray-t.cc
index c640246e1923..d452c1403e9b 100644
--- a/unittest/gunit/dynarray-t.cc
+++ b/unittest/gunit/dynarray-t.cc
@@ -458,9 +458,9 @@ TEST_F(MemRootTest, ResizeGrow)
TEST_F(MemRootTest, ResizeShrink)
{
+ size_t counter= 0;
Mem_root_array array(m_mem_root_p);
array.reserve(100);
- size_t counter= 0;
DestroyCounter foo(&counter);
array.resize(10, foo);
EXPECT_EQ(0U, counter);
diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt
index ed21a4039f68..359624055693 100644
--- a/zlib/CMakeLists.txt
+++ b/zlib/CMakeLists.txt
@@ -1,35 +1,148 @@
+
# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
-#
+#
# 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.
-#
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
# 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.
-#
+# GNU General Public License, version 2.0, 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
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
+
+project(zlib C)
+
+set(VERSION "1.2.11")
+
+include(CheckTypeSize)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckCSourceCompiles)
+
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(stdint.h HAVE_STDINT_H)
+check_include_file(stddef.h HAVE_STDDEF_H)
+
+#
+# Check to see if we have large file support
+#
+set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
+# We add these other definitions here because CheckTypeSize.cmake
+# in CMake 2.4.x does not automatically do so and we want
+# compatibility with CMake 2.4.x.
+if(HAVE_SYS_TYPES_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
+endif()
+if(HAVE_STDINT_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
+endif()
+if(HAVE_STDDEF_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
+endif()
+check_type_size(off64_t OFF64_T)
+if(HAVE_OFF64_T)
+ add_definitions(-D_LARGEFILE64_SOURCE=1)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
+
+#
+# Check for fseeko
+#
+check_function_exists(fseeko HAVE_FSEEKO)
+if(NOT HAVE_FSEEKO)
+ add_definitions(-DNO_FSEEKO)
+endif()
+
+#
+# Check for unistd.h
+#
+check_include_file(unistd.h Z_HAVE_UNISTD_H)
-INCLUDE_DIRECTORIES(
-${CMAKE_SOURCE_DIR}/include
-${CMAKE_SOURCE_DIR}/zlib
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY
+ )
+include_directories(
+ SYSTEM ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+#============================================================================
+# zlib
+#============================================================================
+
+set(ZLIB_PUBLIC_HDRS
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
+ zlib.h
+)
+set(ZLIB_PRIVATE_HDRS
+ crc32.h
+ deflate.h
+ gzguts.h
+ inffast.h
+ inffixed.h
+ inflate.h
+ inftrees.h
+ trees.h
+ zutil.h
)
-SET(ZLIB_SOURCES
- adler32.c
- compress.c
- crc32.c
- deflate.c
- gzio.c
- infback.c
- inffast.c
- inflate.c
- inftrees.c
- trees.c
- uncompr.c
- zutil.c
+set(ZLIB_SRCS
+ adler32.c
+ compress.c
+ crc32.c
+ deflate.c
+ gzclose.c
+ gzlib.c
+ gzread.c
+ gzwrite.c
+ inflate.c
+ infback.c
+ inftrees.c
+ inffast.c
+ trees.c
+ uncompr.c
+ zutil.c
)
-ADD_CONVENIENCE_LIBRARY(zlib ${ZLIB_SOURCES})
+if(NOT MINGW)
+ set(ZLIB_DLL_SRCS
+ win32/zlib1.rc # If present will override custom build rule below.
+ )
+endif()
+
+# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
+ "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
+
+ADD_CONVENIENCE_LIBRARY(zlib STATIC
+ ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+
+if(NOT CYGWIN)
+ # This property causes shared libraries on Linux to have the full version
+ # encoded into their final filename. We disable this on Cygwin because
+ # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
+ # seems to be the default.
+ #
+ # This has no effect with MSVC, on that platform the version info for
+ # the DLL comes from the resource file win32/zlib1.rc
+ set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
+endif()
+
+if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ # On unix-like platforms the library is almost always called libz
+ set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
+elseif(UNIX)
+ # On unix-like platforms the library is almost always called libz
+ set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
+ if(NOT APPLE)
+ set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
+ endif()
+endif()
diff --git a/zlib/ChangeLog b/zlib/ChangeLog
index 7f6869d3235e..30199a65a03d 100644
--- a/zlib/ChangeLog
+++ b/zlib/ChangeLog
@@ -1,6 +1,666 @@
ChangeLog file for zlib
+Changes in 1.2.11 (15 Jan 2017)
+- Fix deflate stored bug when pulling last block from window
+- Permit immediate deflateParams changes before any deflate input
+
+Changes in 1.2.10 (2 Jan 2017)
+- Avoid warnings on snprintf() return value
+- Fix bug in deflate_stored() for zero-length input
+- Fix bug in gzwrite.c that produced corrupt gzip files
+- Remove files to be installed before copying them in Makefile.in
+- Add warnings when compiling with assembler code
+
+Changes in 1.2.9 (31 Dec 2016)
+- Fix contrib/minizip to permit unzipping with desktop API [Zouzou]
+- Improve contrib/blast to return unused bytes
+- Assure that gzoffset() is correct when appending
+- Improve compress() and uncompress() to support large lengths
+- Fix bug in test/example.c where error code not saved
+- Remedy Coverity warning [Randers-Pehrson]
+- Improve speed of gzprintf() in transparent mode
+- Fix inflateInit2() bug when windowBits is 16 or 32
+- Change DEBUG macro to ZLIB_DEBUG
+- Avoid uninitialized access by gzclose_w()
+- Allow building zlib outside of the source directory
+- Fix bug that accepted invalid zlib header when windowBits is zero
+- Fix gzseek() problem on MinGW due to buggy _lseeki64 there
+- Loop on write() calls in gzwrite.c in case of non-blocking I/O
+- Add --warn (-w) option to ./configure for more compiler warnings
+- Reject a window size of 256 bytes if not using the zlib wrapper
+- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE
+- Add --debug (-d) option to ./configure to define ZLIB_DEBUG
+- Fix bugs in creating a very large gzip header
+- Add uncompress2() function, which returns the input size used
+- Assure that deflateParams() will not switch functions mid-block
+- Dramatically speed up deflation for level 0 (storing)
+- Add gzfread(), duplicating the interface of fread()
+- Add gzfwrite(), duplicating the interface of fwrite()
+- Add deflateGetDictionary() function
+- Use snprintf() for later versions of Microsoft C
+- Fix *Init macros to use z_ prefix when requested
+- Replace as400 with os400 for OS/400 support [Monnerat]
+- Add crc32_z() and adler32_z() functions with size_t lengths
+- Update Visual Studio project files [AraHaan]
+
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Roß]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix uninitialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no library use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminancy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assmebler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+ Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+ _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling errors in zlib.h [Willem, Sobrado]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+ binary compatibility -- a normal version and a 64-bit offset version,
+ per the Large File Support Extension when _LARGEFILE64_SOURCE is
+ defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+ is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+ [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+ trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include and #include "zlib.h" in
+ gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+ Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+ the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+ for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+ doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+ that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+ un-versioned, the patch adds versioning only for symbols introduced in
+ zlib-1.2.0 or later. It also declares as local those symbols which are
+ not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+ NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
Changes in 1.2.3 (18 July 2005)
- Apply security vulnerability fixes to contrib/infback9 as well
- Clean up some text files (carriage returns, trailing space)
@@ -13,7 +673,7 @@ Changes in 1.2.2.4 (11 July 2005)
compile
- Fix some spelling errors in comments [Betts]
- Correct inflateInit2() error return documentation in zlib.h
-- Added zran.c example of compressed data random access to examples
+- Add zran.c example of compressed data random access to examples
directory, shows use of inflatePrime()
- Fix cast for assignments to strm->state in inflate.c and infback.c
- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
@@ -561,7 +1221,7 @@ Changes in 1.0.6 (19 Jan 1998)
386 asm code replacing longest_match().
contrib/iostream/ by Kevin Ruland
A C++ I/O streams interface to the zlib gz* functions
- contrib/iostream2/ by Tyge L�vset
+ contrib/iostream2/ by Tyge Løvset
Another C++ I/O streams interface
contrib/untgz/ by "Pedro A. Aranda Guti\irrez"
A very simple tar.gz file extractor using zlib
@@ -650,7 +1310,7 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
- fix array overlay in deflate.c which sometimes caused bad compressed data
- fix inflate bug with empty stored block
- fix MSDOS medium model which was broken in 0.99
-- fix deflateParams() which could generated bad compressed data.
+- fix deflateParams() which could generate bad compressed data.
- Bytef is define'd instead of typedef'ed (work around Borland bug)
- added an INDEX file
- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
diff --git a/zlib/FAQ b/zlib/FAQ
index 441d910daa18..99b7cf92e454 100644
--- a/zlib/FAQ
+++ b/zlib/FAQ
@@ -3,8 +3,8 @@
If your question is not there, please check the zlib home page
-http://www.zlib.org which may have more recent information.
-The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
1. Is zlib Y2K-compliant?
@@ -13,54 +13,51 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
2. Where can I get a Windows DLL version?
- The zlib sources can be compiled without change to produce a DLL.
- See the file win32/DLL_FAQ.txt in the zlib distribution.
- Pointers to the precompiled DLL are found in the zlib web site at
- http://www.zlib.org.
+ The zlib sources can be compiled without change to produce a DLL. See the
+ file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
+ precompiled DLL are found in the zlib web site at http://zlib.net/ .
3. Where can I get a Visual Basic interface to zlib?
See
- * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
- * contrib/visual-basic.txt in the zlib distribution
+ * http://marknelson.us/1997/01/01/zlib-engine/
* win32/DLL_FAQ.txt in the zlib distribution
4. compress() returns Z_BUF_ERROR.
- Make sure that before the call of compress, the length of the compressed
- buffer is equal to the total size of the compressed buffer and not
- zero. For Visual Basic, check that this parameter is passed by reference
+ Make sure that before the call of compress(), the length of the compressed
+ buffer is equal to the available size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
("as any"), not by value ("as long").
5. deflate() or inflate() returns Z_BUF_ERROR.
- Before making the call, make sure that avail_in and avail_out are not
- zero. When setting the parameter flush equal to Z_FINISH, also make sure
- that avail_out is big enough to allow processing all pending input.
- Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
- inflate() can be made with more input or output space. A Z_BUF_ERROR
- may in fact be unavoidable depending on how the functions are used, since
- it is not possible to tell whether or not there is more output pending
- when strm.avail_out returns with zero.
+ Before making the call, make sure that avail_in and avail_out are not zero.
+ When setting the parameter flush equal to Z_FINISH, also make sure that
+ avail_out is big enough to allow processing all pending input. Note that a
+ Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+ made with more input or output space. A Z_BUF_ERROR may in fact be
+ unavoidable depending on how the functions are used, since it is not
+ possible to tell whether or not there is more output pending when
+ strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
+ heavily annotated example.
6. Where's the zlib documentation (man pages, etc.)?
- It's in zlib.h for the moment, and Francis S. Lin has converted it to a
- web page zlib.html. Volunteers to transform this to Unix-style man pages,
- please contact us (zlib@gzip.org). Examples of zlib usage are in the files
- example.c and minigzip.c.
+ It's in zlib.h . Examples of zlib usage are in the files test/example.c
+ and test/minigzip.c, with more in examples/ .
7. Why don't you use GNU autoconf or libtool or ...?
- Because we would like to keep zlib as a very small and simple
- package. zlib is rather portable and doesn't need much configuration.
+ Because we would like to keep zlib as a very small and simple package.
+ zlib is rather portable and doesn't need much configuration.
8. I found a bug in zlib.
- Most of the time, such problems are due to an incorrect usage of
- zlib. Please try to reproduce the problem with a small program and send
- the corresponding source to us at zlib@gzip.org . Do not send
- multi-megabyte data files without prior agreement.
+ Most of the time, such problems are due to an incorrect usage of zlib.
+ Please try to reproduce the problem with a small program and send the
+ corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
+ data files without prior agreement.
9. Why do I get "undefined reference to gzputc"?
@@ -82,13 +79,15 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
12. Can zlib handle .Z files?
- No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
the code of uncompress on your own.
13. How can I make a Unix shared library?
- make clean
- ./configure -s
+ By default a shared (and a static) library is built for Unix. So:
+
+ make distclean
+ ./configure
make
14. How do I install a shared zlib library on Unix?
@@ -99,8 +98,10 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
However, many flavors of Unix come with a shared zlib already installed.
Before going to the trouble of compiling a shared version of zlib and
- trying to install it, you may want to check if it's already there! If you
- can #include , it's there. The -lz option will probably link to it.
+ trying to install it, you may want to check if it's already there! If you
+ can #include , it's there. The -lz option will probably link to
+ it. You can check the version at the top of zlib.h or with the
+ ZLIB_VERSION symbol defined in zlib.h .
15. I have a question about OttoPDF.
@@ -109,8 +110,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
16. Can zlib decode Flate data in an Adobe PDF file?
- Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
- To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+ Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+ http://sourceforge.net/projects/acroformtool/ .
17. Why am I getting this "register_frame_info not found" error on Solaris?
@@ -121,67 +122,67 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
symbol __register_frame_info: referenced symbol not found
The symbol __register_frame_info is not part of zlib, it is generated by
- the C compiler (cc or gcc). You must recompile applications using zlib
- which have this problem. This problem is specific to Solaris. See
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
http://www.sunfreeware.com for Solaris versions of zlib and applications
using zlib.
18. Why does gzip give an error on a file I make with compress/deflate?
The compress and deflate functions produce data in the zlib format, which
- is different and incompatible with the gzip format. The gz* functions in
- zlib on the other hand use the gzip format. Both the zlib and gzip
- formats use the same compressed data format internally, but have different
- headers and trailers around the compressed data.
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip formats
+ use the same compressed data format internally, but have different headers
+ and trailers around the compressed data.
19. Ok, so why are there two different formats?
- The gzip format was designed to retain the directory information about
- a single file, such as the name and last modification date. The zlib
- format on the other hand was designed for in-memory and communication
- channel applications, and has a much more compact header and trailer and
- uses a faster integrity check than gzip.
+ The gzip format was designed to retain the directory information about a
+ single file, such as the name and last modification date. The zlib format
+ on the other hand was designed for in-memory and communication channel
+ applications, and has a much more compact header and trailer and uses a
+ faster integrity check than gzip.
20. Well that's nice, but how do I make a gzip file in memory?
You can request that deflate write the gzip format instead of the zlib
- format using deflateInit2(). You can also request that inflate decode
- the gzip format using inflateInit2(). Read zlib.h for more details.
+ format using deflateInit2(). You can also request that inflate decode the
+ gzip format using inflateInit2(). Read zlib.h for more details.
21. Is zlib thread-safe?
- Yes. However any library routines that zlib uses and any application-
- provided memory allocation routines must also be thread-safe. zlib's gz*
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
functions use stdio library routines, and most of zlib's functions use the
- library memory allocation routines by default. zlib's Init functions allow
- for the application to provide custom memory allocation routines.
+ library memory allocation routines by default. zlib's *Init* functions
+ allow for the application to provide custom memory allocation routines.
Of course, you should only operate on any given zlib or gzip stream from a
single thread at a time.
22. Can I use zlib in my commercial application?
- Yes. Please read the license in zlib.h.
+ Yes. Please read the license in zlib.h.
23. Is zlib under the GNU license?
- No. Please read the license in zlib.h.
+ No. Please read the license in zlib.h.
24. The license says that altered source versions must be "plainly marked". So
what exactly do I need to do to meet that requirement?
- You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
particular, the final version number needs to be changed to "f", and an
- identification string should be appended to ZLIB_VERSION. Version numbers
+ identification string should be appended to ZLIB_VERSION. Version numbers
x.x.x.f are reserved for modifications to zlib by others than the zlib
- maintainers. For example, if the version of the base zlib you are altering
+ maintainers. For example, if the version of the base zlib you are altering
is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
- ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
update the version strings in deflate.c and inftrees.c.
For altered source distributions, you should also note the origin and
nature of the changes in zlib.h, as well as in ChangeLog and README, along
- with the dates of the alterations. The origin should include at least your
+ with the dates of the alterations. The origin should include at least your
name (or your company's name), and an email address to contact for help or
issues with the library.
@@ -197,105 +198,112 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
26. Will zlib work on a 64-bit machine?
- It should. It has been tested on 64-bit machines, and has no dependence
- on any data types being limited to 32-bits in length. If you have any
+ Yes. It has been tested on 64-bit machines, and has no dependence on any
+ data types being limited to 32-bits in length. If you have any
difficulties, please provide a complete problem report to zlib@gzip.org
27. Will zlib decompress data from the PKWare Data Compression Library?
- No. The PKWare DCL uses a completely different compressed data format
- than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ No. The PKWare DCL uses a completely different compressed data format than
+ does PKZIP and zlib. However, you can look in zlib's contrib/blast
directory for a possible solution to your problem.
28. Can I access data randomly in a compressed stream?
- No, not without some preparation. If when compressing you periodically
- use Z_FULL_FLUSH, carefully write all the pending data at those points,
- and keep an index of those locations, then you can start decompression
- at those points. You have to be careful to not use Z_FULL_FLUSH too
- often, since it can significantly degrade compression.
+ No, not without some preparation. If when compressing you periodically use
+ Z_FULL_FLUSH, carefully write all the pending data at those points, and
+ keep an index of those locations, then you can start decompression at those
+ points. You have to be careful to not use Z_FULL_FLUSH too often, since it
+ can significantly degrade compression. Alternatively, you can scan a
+ deflate stream once to generate an index, and then use that index for
+ random access. See examples/zran.c .
29. Does zlib work on MVS, OS/390, CICS, etc.?
- We don't know for sure. We have heard occasional reports of success on
- these systems. If you do use it on one of these, please provide us with
- a report, instructions, and patches that we can reference when we get
- these questions. Thanks.
+ It has in the past, but we have not heard of any recent evidence. There
+ were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+ If you know of recent, successful applications of zlib on these operating
+ systems, please let us know. Thanks.
-30. Is there some simpler, easier to read version of inflate I can look at
- to understand the deflate format?
+30. Is there some simpler, easier to read version of inflate I can look at to
+ understand the deflate format?
- First off, you should read RFC 1951. Second, yes. Look in zlib's
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
contrib/puff directory.
31. Does zlib infringe on any patents?
- As far as we know, no. In fact, that was originally the whole point behind
- zlib. Look here for some more information:
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
http://www.gzip.org/#faq11
32. Can zlib work with greater than 4 GB of data?
- Yes. inflate() and deflate() will process any amount of data correctly.
+ Yes. inflate() and deflate() will process any amount of data correctly.
Each call of inflate() or deflate() is limited to input and output chunks
of the maximum value that can be stored in the compiler's "unsigned int"
- type, but there is no limit to the number of chunks. Note however that the
- strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
counters are provided as a convenience and are not used internally by
- inflate() or deflate(). The application can easily set up its own counters
+ inflate() or deflate(). The application can easily set up its own counters
updated after each call of inflate() or deflate() to count beyond 4 GB.
compress() and uncompress() may be limited to 4 GB, since they operate in a
- single call. gzseek() and gztell() may be limited to 4 GB depending on how
- zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
- The word "may" appears several times above since there is a 4 GB limit
- only if the compiler's "long" type is 32 bits. If the compiler's "long"
- type is 64 bits, then the limit is 16 exabytes.
+ The word "may" appears several times above since there is a 4 GB limit only
+ if the compiler's "long" type is 32 bits. If the compiler's "long" type is
+ 64 bits, then the limit is 16 exabytes.
33. Does zlib have any security vulnerabilities?
- The only one that we are aware of is potentially in gzprintf(). If zlib
- is compiled to use sprintf() or vsprintf(), then there is no protection
- against a buffer overflow of a 4K string space, other than the caller of
- gzprintf() assuring that the output will not exceed 4K. On the other
- hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
- normally be the case, then there is no vulnerability. The ./configure
- script will display warnings if an insecure variation of sprintf() will
- be used by gzprintf(). Also the zlibCompileFlags() function will return
- information on what variant of sprintf() is used by gzprintf().
+ The only one that we are aware of is potentially in gzprintf(). If zlib is
+ compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of an 8K string space (or other value as set by
+ gzbuffer()), other than the caller of gzprintf() assuring that the output
+ will not exceed 8K. On the other hand, if zlib is compiled to use
+ snprintf() or vsnprintf(), which should normally be the case, then there is
+ no vulnerability. The ./configure script will display warnings if an
+ insecure variation of sprintf() will be used by gzprintf(). Also the
+ zlibCompileFlags() function will return information on what variant of
+ sprintf() is used by gzprintf().
If you don't have snprintf() or vsnprintf() and would like one, you can
find a portable implementation here:
http://www.ijs.si/software/snprintf/
- Note that you should be using the most recent version of zlib. Versions
- 1.1.3 and before were subject to a double-free vulnerability.
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability, and versions
+ 1.2.1 and 1.2.2 were subject to an access exception when decompressing
+ invalid compressed data.
34. Is there a Java version of zlib?
Probably what you want is to use zlib in Java. zlib is already included
as part of the Java SDK in the java.util.zip package. If you really want
a version of zlib written in the Java language, look on the zlib home
- page for links: http://www.zlib.org/
+ page for links: http://zlib.net/ .
35. I get this or that compiler or source-code scanner warning when I crank it
up to maximally-pedantic. Can't you guys write proper code?
Many years ago, we gave up attempting to avoid warnings on every compiler
- in the universe. It just got to be a waste of time, and some compilers
- were downright silly. So now, we simply make sure that the code always
- works.
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly as well as contradicted each other. So now, we simply
+ make sure that the code always works.
36. Valgrind (or some similar memory access checker) says that deflate is
performing a conditional jump that depends on an uninitialized value.
Isn't that a bug?
- No. That is intentional for performance reasons, and the output of
- deflate is not affected. This only started showing up recently since
- zlib 1.2.x uses malloc() by default for allocations, whereas earlier
- versions used calloc(), which zeros out the allocated memory.
+ No. That is intentional for performance reasons, and the output of deflate
+ is not affected. This only started showing up recently since zlib 1.2.x
+ uses malloc() by default for allocations, whereas earlier versions used
+ calloc(), which zeros out the allocated memory. Even though the code was
+ correct, versions 1.2.4 and later was changed to not stimulate these
+ checkers.
37. Will zlib read the (insert any ancient or arcane format here) compressed
data format?
@@ -305,20 +313,21 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
38. How can I encrypt/decrypt zip files with zlib?
- zlib doesn't support encryption. The original PKZIP encryption is very weak
- and can be broken with freely available programs. To get strong encryption,
- use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
- For PKZIP compatible "encryption", look at http://www.info-zip.org/
+ zlib doesn't support encryption. The original PKZIP encryption is very
+ weak and can be broken with freely available programs. To get strong
+ encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+ compression. For PKZIP compatible "encryption", look at
+ http://www.info-zip.org/
39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
- "gzip" is the gzip format, and "deflate" is the zlib format. They should
- probably have called the second one "zlib" instead to avoid confusion
- with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion with
+ the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
correctly points to the zlib specification in RFC 1950 for the "deflate"
transfer encoding, there have been reports of servers and browsers that
incorrectly produce or expect raw deflate data per the deflate
- specficiation in RFC 1951, most notably Microsoft. So even though the
+ specification in RFC 1951, most notably Microsoft. So even though the
"deflate" transfer encoding using the zlib format would be the more
efficient approach (and in fact exactly what the zlib format was designed
for), using the "gzip" transfer encoding is probably more reliable due to
@@ -328,12 +337,32 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
40. Does zlib support the new "Deflate64" format introduced by PKWare?
- No. PKWare has apparently decided to keep that format proprietary, since
- they have not documented it as they have previous compression formats.
- In any case, the compression improvements are so modest compared to other
- more modern approaches, that it's not worth the effort to implement.
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats. In
+ any case, the compression improvements are so modest compared to other more
+ modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+ There are no zip functions in zlib. You are probably using minizip by
+ Giles Vollant, which is found in the contrib directory of zlib. It is not
+ part of zlib. In fact none of the stuff in contrib is part of zlib. The
+ files in there are not supported by the zlib authors. You need to contact
+ the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+ Since it's part of zlib, doesn't that mean that all of zlib falls under the
+ GNU GPL?
+
+ No. The files in contrib are not part of zlib. They were contributed by
+ other authors and are provided as a convenience to the user within the zlib
+ distribution. Each item in contrib has its own license.
+
+43. Is zlib subject to export controls? What is its ECCN?
+
+ zlib is not subject to export controls, and so is classified as EAR99.
-41. Can you please sign these lengthy legal documents and fax them back to us
+44. Can you please sign these lengthy legal documents and fax them back to us
so that we can use your software in our product?
No. Go away. Shoo.
diff --git a/zlib/INDEX b/zlib/INDEX
index 0587e5902bd1..2ba064120486 100644
--- a/zlib/INDEX
+++ b/zlib/INDEX
@@ -1,23 +1,37 @@
+CMakeLists.txt cmake build file
ChangeLog history of changes
FAQ Frequently Asked Questions about zlib
INDEX this file
-Makefile makefile for Unix (generated by configure)
-Makefile.in makefile for Unix (template for configure)
+Makefile dummy Makefile that tells you to ./configure
+Makefile.in template for Unix Makefile
README guess what
-algorithm.txt description of the (de)compression algorithm
configure configure script for Unix
-zconf.in.h template for zconf.h (used by configure)
+make_vms.com makefile for VMS
+test/example.c zlib usages examples for build testing
+test/minigzip.c minimal gzip-like functionality for build testing
+test/infcover.c inf*.c code coverage for build coverage testing
+treebuild.xml XML description of source file dependencies
+zconf.h.cmakein zconf.h template for cmake
+zconf.h.in zconf.h template for configure
+zlib.3 Man page for zlib
+zlib.3.pdf Man page in PDF format
+zlib.map Linux symbol information
+zlib.pc.in Template for pkg-config descriptor
+zlib.pc.cmakein zlib.pc template for cmake
+zlib2ansi perl script to convert source files for C++ compilation
amiga/ makefiles for Amiga SAS C
-as400/ makefiles for IBM AS/400
+as400/ makefiles for AS/400
+doc/ documentation for formats and algorithms
msdos/ makefiles for MSDOS
+nintendods/ makefile for Nintendo DS
old/ makefiles for various architectures and zlib documentation
files that have not yet been updated for zlib 1.2.x
-projects/ projects for various Integrated Development Environments
qnx/ makefiles for QNX
+watcom/ makefiles for OpenWatcom
win32/ makefiles for Windows
- zlib public header files (must be kept):
+ zlib public header files (required for library use):
zconf.h
zlib.h
@@ -28,7 +42,11 @@ crc32.c
crc32.h
deflate.c
deflate.h
-gzio.c
+gzclose.c
+gzguts.h
+gzlib.c
+gzread.c
+gzwrite.c
infback.c
inffast.c
inffast.h
@@ -43,9 +61,8 @@ uncompr.c
zutil.c
zutil.h
- source files for sample programs:
-example.c
-minigzip.c
+ source files for sample programs
+See examples/README.examples
- unsupported contribution by third parties
+ unsupported contributions by third parties
See contrib/README.contrib
diff --git a/zlib/README b/zlib/README
index 758cc50020df..51106de47532 100644
--- a/zlib/README
+++ b/zlib/README
@@ -1,56 +1,52 @@
ZLIB DATA COMPRESSION LIBRARY
-zlib 1.2.3 is a general purpose data compression library. All the code is
+zlib 1.2.11 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
-http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
-and rfc1952.txt (gzip format). These documents are also available in other
-formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
All functions of the compression library are documented in the file zlib.h
-(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
-of the library is given in the file example.c which also tests that the library
-is working correctly. Another example is given in the file minigzip.c. The
-compression library itself is composed of all source files except example.c and
-minigzip.c.
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly. Another example is given in the file
+test/minigzip.c. The compression library itself is composed of all source
+files in the root directory.
To compile all files and run the test program, follow the instructions given at
-the top of Makefile. In short "make test; make install" should work for most
-machines. For Unix: "./configure; make test; make install". For MSDOS, use one
-of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
+the top of Makefile.in. In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix. For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+make_vms.com.
Questions about zlib should be sent to , or to Gilles Vollant
- for the Windows DLL version. The zlib home page is
-http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
-please check this site to verify that you have the latest version of zlib;
-otherwise get the latest version and check whether the problem still exists or
-not.
+ for the Windows DLL version. The zlib home page is
+http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
-PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
-for help.
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
-Mark Nelson wrote an article about zlib for the Jan. 1997
-issue of Dr. Dobb's Journal; a copy of the article is available in
-http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+Mark Nelson wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
-The changes made in version 1.2.3 are documented in the file ChangeLog.
+The changes made in version 1.2.11 are documented in the file ChangeLog.
-Unsupported third party contributions are provided in directory "contrib".
+Unsupported third party contributions are provided in directory contrib/ .
-A Java implementation of zlib is available in the Java Development Kit
-http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
-See the zlib home page http://www.zlib.org for details.
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
-A Perl interface to zlib written by Paul Marquess is in the
-CPAN (Comprehensive Perl Archive Network) sites
-http://www.cpan.org/modules/by-module/Compress/
+A Perl interface to zlib written by Paul Marquess is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
A Python interface to zlib written by A.M. Kuchling is
available in Python 1.5 and later versions, see
-http://www.python.org/doc/lib/module-zlib.html
+http://docs.python.org/library/zlib.html .
-A zlib binding for TCL written by Andreas Kupries is
-availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant , is available in the
@@ -74,25 +70,21 @@ Notes for some targets:
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
other compilers. Use "make test" to check your compiler.
-- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+- gzdopen is not supported on RISCOS or BEOS.
- For PalmOs, see http://palmzlib.sourceforge.net/
-- When building a shared, i.e. dynamic library on Mac OS X, the library must be
- installed before testing (do "make install" before "make test"), since the
- library location is specified in the library.
-
Acknowledgments:
- The deflate format used by zlib was defined by Phil Katz. The deflate
- and zlib specifications were written by L. Peter Deutsch. Thanks to all the
- people who reported problems and suggested various improvements in zlib;
- they are too numerous to cite here.
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
Copyright notice:
- (C) 1995-2004 Jean-loup Gailly and Mark Adler
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -113,13 +105,11 @@ Copyright notice:
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
-If you use the zlib library in a product, we would appreciate *not*
-receiving lengthy legal documents to sign. The sources are provided
-for free but without warranty of any kind. The library has been
-entirely written by Jean-loup Gailly and Mark Adler; it does not
-include third-party code.
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
-If you redistribute modified sources, we would appreciate that you include
-in the file ChangeLog history information documenting your changes. Please
-read the FAQ for more information on the distribution of modified source
-versions.
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/zlib/README.MySQL b/zlib/README.MySQL
deleted file mode 100644
index c17d3eeb6f99..000000000000
--- a/zlib/README.MySQL
+++ /dev/null
@@ -1,16 +0,0 @@
-This an incomplete version of the zlib library -- it excludes some of the
-platform-specific project files, contributed code, and examples from the
-original zlib distribution. You can find the original distribution at
-
- http://www.gzip.org/zlib/
- or
- http://www.zlib.net/
-
-Revision history:
-
-20.01.2006. The following files were changed as part of #15787 fix:
- makefile.am
- gzio.c
- zconf.h
- README.mysql
-
diff --git a/zlib/adler32.c b/zlib/adler32.c
index 007ba26277c8..e82e8eedd132 100644
--- a/zlib/adler32.c
+++ b/zlib/adler32.c
@@ -1,14 +1,15 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2011, 2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
-#define ZLIB_INTERNAL
-#include "zlib.h"
+#include "zutil.h"
-#define BASE 65521UL /* largest prime smaller than 65536 */
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521U /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
@@ -18,46 +19,51 @@
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
-/* use NO_DIVIDE if your processor does not do division in hardware */
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
#ifdef NO_DIVIDE
-# define MOD(a) \
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
+ CHOP(a); \
if (a >= BASE) a -= BASE; \
} while (0)
-# define MOD4(a) \
+# define MOD(a) \
do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
+ CHOP(a); \
+ MOD28(a); \
+ } while (0)
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
#endif
/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
+uLong ZEXPORT adler32_z(adler, buf, len)
uLong adler;
const Bytef *buf;
- uInt len;
+ z_size_t len;
{
unsigned long sum2;
unsigned n;
@@ -89,7 +95,7 @@ uLong ZEXPORT adler32(adler, buf, len)
}
if (adler >= BASE)
adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
+ MOD28(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
@@ -125,25 +131,56 @@ uLong ZEXPORT adler32(adler, buf, len)
}
/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ return adler32_z(adler, buf, len);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
uLong adler1;
uLong adler2;
- z_off_t len2;
+ z_off64_t len2;
{
unsigned long sum1;
unsigned long sum2;
unsigned rem;
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+
/* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/zlib/algorithm.txt b/zlib/algorithm.txt
deleted file mode 100644
index b022dde312a1..000000000000
--- a/zlib/algorithm.txt
+++ /dev/null
@@ -1,209 +0,0 @@
-1. Compression algorithm (deflate)
-
-The deflation algorithm used by gzip (also zip and zlib) is a variation of
-LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
-the input data. The second occurrence of a string is replaced by a
-pointer to the previous string, in the form of a pair (distance,
-length). Distances are limited to 32K bytes, and lengths are limited
-to 258 bytes. When a string does not occur anywhere in the previous
-32K bytes, it is emitted as a sequence of literal bytes. (In this
-description, `string' must be taken as an arbitrary sequence of bytes,
-and is not restricted to printable characters.)
-
-Literals or match lengths are compressed with one Huffman tree, and
-match distances are compressed with another tree. The trees are stored
-in a compact form at the start of each block. The blocks can have any
-size (except that the compressed data for one block must fit in
-available memory). A block is terminated when deflate() determines that
-it would be useful to start another block with fresh trees. (This is
-somewhat similar to the behavior of LZW-based _compress_.)
-
-Duplicated strings are found using a hash table. All input strings of
-length 3 are inserted in the hash table. A hash index is computed for
-the next 3 bytes. If the hash chain for this index is not empty, all
-strings in the chain are compared with the current input string, and
-the longest match is selected.
-
-The hash chains are searched starting with the most recent strings, to
-favor small distances and thus take advantage of the Huffman encoding.
-The hash chains are singly linked. There are no deletions from the
-hash chains, the algorithm simply discards matches that are too old.
-
-To avoid a worst-case situation, very long hash chains are arbitrarily
-truncated at a certain length, determined by a runtime option (level
-parameter of deflateInit). So deflate() does not always find the longest
-possible match but generally finds a match which is long enough.
-
-deflate() also defers the selection of matches with a lazy evaluation
-mechanism. After a match of length N has been found, deflate() searches for
-a longer match at the next input byte. If a longer match is found, the
-previous match is truncated to a length of one (thus producing a single
-literal byte) and the process of lazy evaluation begins again. Otherwise,
-the original match is kept, and the next match search is attempted only N
-steps later.
-
-The lazy match evaluation is also subject to a runtime parameter. If
-the current match is long enough, deflate() reduces the search for a longer
-match, thus speeding up the whole process. If compression ratio is more
-important than speed, deflate() attempts a complete second search even if
-the first match is already long enough.
-
-The lazy match evaluation is not performed for the fastest compression
-modes (level parameter 1 to 3). For these fast modes, new strings
-are inserted in the hash table only when no match was found, or
-when the match is not too long. This degrades the compression ratio
-but saves time since there are both fewer insertions and fewer searches.
-
-
-2. Decompression algorithm (inflate)
-
-2.1 Introduction
-
-The key question is how to represent a Huffman code (or any prefix code) so
-that you can decode fast. The most important characteristic is that shorter
-codes are much more common than longer codes, so pay attention to decoding the
-short codes fast, and let the long codes take longer to decode.
-
-inflate() sets up a first level table that covers some number of bits of
-input less than the length of longest code. It gets that many bits from the
-stream, and looks it up in the table. The table will tell if the next
-code is that many bits or less and how many, and if it is, it will tell
-the value, else it will point to the next level table for which inflate()
-grabs more bits and tries to decode a longer code.
-
-How many bits to make the first lookup is a tradeoff between the time it
-takes to decode and the time it takes to build the table. If building the
-table took no time (and if you had infinite memory), then there would only
-be a first level table to cover all the way to the longest code. However,
-building the table ends up taking a lot longer for more bits since short
-codes are replicated many times in such a table. What inflate() does is
-simply to make the number of bits in the first table a variable, and then
-to set that variable for the maximum speed.
-
-For inflate, which has 286 possible codes for the literal/length tree, the size
-of the first table is nine bits. Also the distance trees have 30 possible
-values, and the size of the first table is six bits. Note that for each of
-those cases, the table ended up one bit longer than the ``average'' code
-length, i.e. the code length of an approximately flat code which would be a
-little more than eight bits for 286 symbols and a little less than five bits
-for 30 symbols.
-
-
-2.2 More details on the inflate table lookup
-
-Ok, you want to know what this cleverly obfuscated inflate tree actually
-looks like. You are correct that it's not a Huffman tree. It is simply a
-lookup table for the first, let's say, nine bits of a Huffman symbol. The
-symbol could be as short as one bit or as long as 15 bits. If a particular
-symbol is shorter than nine bits, then that symbol's translation is duplicated
-in all those entries that start with that symbol's bits. For example, if the
-symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
-symbol is nine bits long, it appears in the table once.
-
-If the symbol is longer than nine bits, then that entry in the table points
-to another similar table for the remaining bits. Again, there are duplicated
-entries as needed. The idea is that most of the time the symbol will be short
-and there will only be one table look up. (That's whole idea behind data
-compression in the first place.) For the less frequent long symbols, there
-will be two lookups. If you had a compression method with really long
-symbols, you could have as many levels of lookups as is efficient. For
-inflate, two is enough.
-
-So a table entry either points to another table (in which case nine bits in
-the above example are gobbled), or it contains the translation for the symbol
-and the number of bits to gobble. Then you start again with the next
-ungobbled bit.
-
-You may wonder: why not just have one lookup table for how ever many bits the
-longest symbol is? The reason is that if you do that, you end up spending
-more time filling in duplicate symbol entries than you do actually decoding.
-At least for deflate's output that generates new trees every several 10's of
-kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
-would take too long if you're only decoding several thousand symbols. At the
-other extreme, you could make a new table for every bit in the code. In fact,
-that's essentially a Huffman tree. But then you spend two much time
-traversing the tree while decoding, even for short symbols.
-
-So the number of bits for the first lookup table is a trade of the time to
-fill out the table vs. the time spent looking at the second level and above of
-the table.
-
-Here is an example, scaled down:
-
-The code being decoded, with 10 symbols, from 1 to 6 bits long:
-
-A: 0
-B: 10
-C: 1100
-D: 11010
-E: 11011
-F: 11100
-G: 11101
-H: 11110
-I: 111110
-J: 111111
-
-Let's make the first table three bits long (eight entries):
-
-000: A,1
-001: A,1
-010: A,1
-011: A,1
-100: B,2
-101: B,2
-110: -> table X (gobble 3 bits)
-111: -> table Y (gobble 3 bits)
-
-Each entry is what the bits decode as and how many bits that is, i.e. how
-many bits to gobble. Or the entry points to another table, with the number of
-bits to gobble implicit in the size of the table.
-
-Table X is two bits long since the longest code starting with 110 is five bits
-long:
-
-00: C,1
-01: C,1
-10: D,2
-11: E,2
-
-Table Y is three bits long since the longest code starting with 111 is six
-bits long:
-
-000: F,2
-001: F,2
-010: G,2
-011: G,2
-100: H,2
-101: H,2
-110: I,3
-111: J,3
-
-So what we have here are three tables with a total of 20 entries that had to
-be constructed. That's compared to 64 entries for a single table. Or
-compared to 16 entries for a Huffman tree (six two entry tables and one four
-entry table). Assuming that the code ideally represents the probability of
-the symbols, it takes on the average 1.25 lookups per symbol. That's compared
-to one lookup for the single table, or 1.66 lookups per symbol for the
-Huffman tree.
-
-There, I think that gives you a picture of what's going on. For inflate, the
-meaning of a particular symbol is often more than just a letter. It can be a
-byte (a "literal"), or it can be either a length or a distance which
-indicates a base value and a number of bits to fetch after the code that is
-added to the base value. Or it might be the special end-of-block code. The
-data structures created in inftrees.c try to encode all that information
-compactly in the tables.
-
-
-Jean-loup Gailly Mark Adler
-jloup@gzip.org madler@alumni.caltech.edu
-
-
-References:
-
-[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
-Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
-pp. 337-343.
-
-``DEFLATE Compressed Data Format Specification'' available in
-http://www.ietf.org/rfc/rfc1951.txt
diff --git a/zlib/amiga/Makefile.pup b/zlib/amiga/Makefile.pup
new file mode 100644
index 000000000000..8940c120fbb9
--- /dev/null
+++ b/zlib/amiga/Makefile.pup
@@ -0,0 +1,69 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+
+LIBNAME = libzip.a
+
+CC = scppc
+CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
+ OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
+AR = ppc-amigaos-ar cr
+RANLIB = ppc-amigaos-ranlib
+LD = ppc-amigaos-ld -r
+LDFLAGS = -o
+LDLIBS = LIB:scppc.a LIB:end.o
+RM = delete quiet
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example minigzip
+
+check: test
+test: all
+ example
+ echo hello world | minigzip | minigzip -d
+
+$(LIBNAME): $(OBJS)
+ $(AR) $@ $(OBJS)
+ -$(RANLIB) $@
+
+example: example.o $(LIBNAME)
+ $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+minigzip: minigzip.o $(LIBNAME)
+ $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+mostlyclean: clean
+clean:
+ $(RM) *.o example minigzip $(LIBNAME) foo.gz
+
+zip:
+ zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
+ descrip.mms *.[ch]
+
+tgz:
+ cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
+ zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/zlib/amiga/Makefile.sas b/zlib/amiga/Makefile.sas
new file mode 100644
index 000000000000..749e2915271d
--- /dev/null
+++ b/zlib/amiga/Makefile.sas
@@ -0,0 +1,68 @@
+# SMakefile for zlib
+# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
+# Osma Ahvenlampi
+# Amiga, SAS/C 6.56 & Smake
+
+CC=sc
+CFLAGS=OPT
+#CFLAGS=OPT CPU=68030
+#CFLAGS=DEBUG=LINE
+LDFLAGS=LIB z.lib
+
+SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
+ NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
+ DEF=POSTINC
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: SCOPTIONS example minigzip
+
+check: test
+test: all
+ example
+ echo hello world | minigzip | minigzip -d
+
+install: z.lib
+ copy clone zlib.h zconf.h INCLUDE:
+ copy clone z.lib LIB:
+
+z.lib: $(OBJS)
+ oml z.lib r $(OBJS)
+
+example: example.o z.lib
+ $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o z.lib
+ $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
+
+mostlyclean: clean
+clean:
+ -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
+
+SCOPTIONS: Makefile.sas
+ copy to $@ 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+ left = *destLen;
+ *destLen = 0;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
@@ -46,15 +41,26 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
+ stream.next_out = dest;
+ stream.avail_out = 0;
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
- err = deflateEnd(&stream);
- return err;
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
+ sourceLen -= stream.avail_in;
+ }
+ err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
+ } while (err == Z_OK);
+
+ *destLen = stream.total_out;
+ deflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK : err;
}
/* ===========================================================================
@@ -75,5 +81,6 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
uLong ZEXPORT compressBound (sourceLen)
uLong sourceLen;
{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13;
}
diff --git a/zlib/crc32.c b/zlib/crc32.c
index 5bbf9c6d4b85..9580440c0e6b 100644
--- a/zlib/crc32.c
+++ b/zlib/crc32.c
@@ -1,5 +1,5 @@
/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown for his contribution of faster
@@ -17,6 +17,8 @@
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32().
+
+ DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
*/
#ifdef MAKECRCH
@@ -28,37 +30,15 @@
#include "zutil.h" /* for STDC and FAR definitions */
-#define local static
-
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+# define BYFOUR
+#endif
#ifdef BYFOUR
-# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
+ const unsigned char FAR *, z_size_t));
local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
+ const unsigned char FAR *, z_size_t));
# define TBLS 8
#else
# define TBLS 1
@@ -68,14 +48,16 @@
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
#ifdef DYNAMIC_CRC_TABLE
local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
+local z_crc_t FAR crc_table[TBLS][256];
local void make_crc_table OF((void));
#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
+ local void write_table OF((FILE *, const z_crc_t FAR *));
#endif /* MAKECRCH */
/*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
@@ -105,9 +87,9 @@ local void make_crc_table OF((void));
*/
local void make_crc_table()
{
- unsigned long c;
+ z_crc_t c;
int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
+ z_crc_t poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
@@ -119,13 +101,13 @@ local void make_crc_table()
first = 0;
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
+ poly = 0;
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+ poly |= (z_crc_t)1 << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
+ c = (z_crc_t)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
@@ -136,11 +118,11 @@ local void make_crc_table()
and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
- crc_table[4][n] = REV(c);
+ crc_table[4][n] = ZSWAP32(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
+ crc_table[k + 4][n] = ZSWAP32(c);
}
}
#endif /* BYFOUR */
@@ -162,7 +144,7 @@ local void make_crc_table()
if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "local const z_crc_t FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]);
# ifdef BYFOUR
@@ -182,12 +164,13 @@ local void make_crc_table()
#ifdef MAKECRCH
local void write_table(out, table)
FILE *out;
- const unsigned long FAR *table;
+ const z_crc_t FAR *table;
{
int n;
for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */
@@ -202,13 +185,13 @@ local void write_table(out, table)
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
-const unsigned long FAR * ZEXPORT get_crc_table()
+const z_crc_t FAR * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
+ return (const z_crc_t FAR *)crc_table;
}
/* ========================================================================= */
@@ -216,10 +199,10 @@ const unsigned long FAR * ZEXPORT get_crc_table()
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
+unsigned long ZEXPORT crc32_z(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
- unsigned len;
+ z_size_t len;
{
if (buf == Z_NULL) return 0UL;
@@ -230,7 +213,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
#ifdef BYFOUR
if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
+ z_crc_t endian;
endian = 1;
if (*((unsigned char *)(&endian)))
@@ -250,8 +233,29 @@ unsigned long ZEXPORT crc32(crc, buf, len)
return crc ^ 0xffffffffUL;
}
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ uInt len;
+{
+ return crc32_z(crc, buf, len);
+}
+
#ifdef BYFOUR
+/*
+ This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
+ integer pointer type. This violates the strict aliasing rule, where a
+ compiler can assume, for optimization purposes, that two pointers to
+ fundamentally different types won't ever point to the same memory. This can
+ manifest as a problem only if one of the pointers is written to. This code
+ only reads from those pointers. So long as this code remains isolated in
+ this compilation unit, there won't be a problem. For this reason, this code
+ should not be copied and pasted into a compilation unit in which other code
+ writes to the buffer that is passed to these routines.
+ */
+
/* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
@@ -262,19 +266,19 @@ unsigned long ZEXPORT crc32(crc, buf, len)
local unsigned long crc32_little(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
- unsigned len;
+ z_size_t len;
{
- u4 c;
- const u4 FAR *buf4;
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
- c = (u4)crc;
+ c = (z_crc_t)crc;
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--;
}
- buf4 = (const u4 FAR *)(const void FAR *)buf;
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
@@ -293,7 +297,7 @@ local unsigned long crc32_little(crc, buf, len)
}
/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
+#define DOBIG4 c ^= *buf4++; \
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
@@ -302,20 +306,19 @@ local unsigned long crc32_little(crc, buf, len)
local unsigned long crc32_big(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
- unsigned len;
+ z_size_t len;
{
- u4 c;
- const u4 FAR *buf4;
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
- c = REV((u4)crc);
+ c = ZSWAP32((z_crc_t)crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--;
}
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
while (len >= 32) {
DOBIG32;
len -= 32;
@@ -324,14 +327,13 @@ local unsigned long crc32_big(crc, buf, len)
DOBIG4;
len -= 4;
}
- buf4++;
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len);
c = ~c;
- return (unsigned long)(REV(c));
+ return (unsigned long)(ZSWAP32(c));
}
#endif /* BYFOUR */
@@ -367,22 +369,22 @@ local void gf2_matrix_square(square, mat)
}
/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+local uLong crc32_combine_(crc1, crc2, len2)
uLong crc1;
uLong crc2;
- z_off_t len2;
+ z_off64_t len2;
{
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
- /* degenerate case */
- if (len2 == 0)
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
return crc1;
/* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
@@ -421,3 +423,20 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2)
crc1 ^= crc2;
return crc1;
}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/zlib/crc32.h b/zlib/crc32.h
index 8053b6117c02..9e0c77810251 100644
--- a/zlib/crc32.h
+++ b/zlib/crc32.h
@@ -2,7 +2,7 @@
* Generated automatically by crc32.c
*/
-local const unsigned long FAR crc_table[TBLS][256] =
+local const z_crc_t FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
diff --git a/zlib/deflate.c b/zlib/deflate.c
index b00bdca88894..1ec761448de9 100644
--- a/zlib/deflate.c
+++ b/zlib/deflate.c
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -37,7 +37,7 @@
* REFERENCES
*
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
+ * Available in http://tools.ietf.org/html/rfc1951
*
* A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
@@ -52,7 +52,7 @@
#include "deflate.h"
const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
+ " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -73,27 +73,29 @@ typedef enum {
typedef block_state (*compress_func) OF((deflate_state *s, int flush));
/* Compression function. Returns the block state after the call. */
+local int deflateStateCheck OF((z_streamp strm));
+local void slide_hash OF((deflate_state *s));
local void fill_window OF((deflate_state *s));
local block_state deflate_stored OF((deflate_state *s, int flush));
local block_state deflate_fast OF((deflate_state *s, int flush));
#ifndef FASTEST
local block_state deflate_slow OF((deflate_state *s, int flush));
#endif
+local block_state deflate_rle OF((deflate_state *s, int flush));
+local block_state deflate_huff OF((deflate_state *s, int flush));
local void lm_init OF((deflate_state *s));
local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifndef FASTEST
+local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
#ifdef ASMV
+# pragma message("Assembler code may have bugs -- use at your own risk")
void match_init OF((void)); /* asm code initialization */
uInt longest_match OF((deflate_state *s, IPos cur_match));
#else
local uInt longest_match OF((deflate_state *s, IPos cur_match));
#endif
-#endif
-local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match,
int length));
#endif
@@ -110,11 +112,6 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
#endif
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
/* Values for max_lazy_match, good_match and max_chain_length, depending on
* the desired pack level (0..9). The values given below have been tuned to
* exclude worst case performance for pathological files. Better values may be
@@ -154,18 +151,14 @@ local const config configuration_table[10] = {
* meaning.
*/
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
/* ===========================================================================
* Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
+ * IN assertion: all calls to UPDATE_HASH are made with consecutive input
+ * characters, so that a running hash key can be computed from the previous
+ * key instead of complete recalculation each time.
*/
#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask)
@@ -176,9 +169,9 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
* the previous length of the hash chain.
* If this file is compiled with -DFASTEST, the compression level is forced
* to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
+ * IN assertion: all calls to INSERT_STRING are made with consecutive input
+ * characters and the first MIN_MATCH bytes of str are valid (except for
+ * the last MIN_MATCH-1 bytes of the input file).
*/
#ifdef FASTEST
#define INSERT_STRING(s, str, match_head) \
@@ -200,6 +193,37 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
s->head[s->hash_size-1] = NIL; \
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+/* ===========================================================================
+ * Slide the hash table when sliding the window down (could be avoided with 32
+ * bit values at the expense of memory usage). We slide even when level == 0 to
+ * keep the hash table consistent if we switch back to level > 0 later.
+ */
+local void slide_hash(s)
+ deflate_state *s;
+{
+ unsigned n, m;
+ Posf *p;
+ uInt wsize = s->w_size;
+
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m - wsize : NIL);
+ } while (--n);
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m - wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+}
+
/* ========================================================================= */
int ZEXPORT deflateInit_(strm, level, version, stream_size)
z_streamp strm;
@@ -241,10 +265,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
strm->msg = Z_NULL;
if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
+#endif
}
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
#ifdef FASTEST
if (level != 0) level = 1;
@@ -264,7 +297,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
#endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
+ strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
return Z_STREAM_ERROR;
}
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
@@ -272,14 +305,15 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (s == Z_NULL) return Z_MEM_ERROR;
strm->state = (struct internal_state FAR *)s;
s->strm = strm;
+ s->status = INIT_STATE; /* to pass state test in deflateReset() */
s->wrap = wrap;
s->gzhead = Z_NULL;
- s->w_bits = windowBits;
+ s->w_bits = (uInt)windowBits;
s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1;
- s->hash_bits = memLevel + 7;
+ s->hash_bits = (uInt)memLevel + 7;
s->hash_size = 1 << s->hash_bits;
s->hash_mask = s->hash_size - 1;
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
@@ -288,6 +322,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+ s->high_water = 0; /* nothing written to s->window yet */
+
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
@@ -297,7 +333,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) {
s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ strm->msg = ERR_MSG(Z_MEM_ERROR);
deflateEnd (strm);
return Z_MEM_ERROR;
}
@@ -311,6 +347,31 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
return deflateReset(strm);
}
+/* =========================================================================
+ * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
+ */
+local int deflateStateCheck (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+ if (strm == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+ return 1;
+ s = strm->state;
+ if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
+#ifdef GZIP
+ s->status != GZIP_STATE &&
+#endif
+ s->status != EXTRA_STATE &&
+ s->status != NAME_STATE &&
+ s->status != COMMENT_STATE &&
+ s->status != HCRC_STATE &&
+ s->status != BUSY_STATE &&
+ s->status != FINISH_STATE))
+ return 1;
+ return 0;
+}
+
/* ========================================================================= */
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
z_streamp strm;
@@ -318,49 +379,97 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
uInt dictLength;
{
deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
+ uInt str, n;
+ int wrap;
+ unsigned avail;
+ z_const unsigned char *next;
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ if (deflateStateCheck(strm) || dictionary == Z_NULL)
return Z_STREAM_ERROR;
-
s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
+ wrap = s->wrap;
+ if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+ return Z_STREAM_ERROR;
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
- dictionary += dictLength - length; /* use the tail of the dictionary */
+ /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+ if (wrap == 1)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+ s->wrap = 0; /* avoid computing Adler-32 in read_buf */
+
+ /* if dictionary would fill window, just replace the history */
+ if (dictLength >= s->w_size) {
+ if (wrap == 0) { /* already empty otherwise */
+ CLEAR_HASH(s);
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ dictionary += dictLength - s->w_size; /* use the tail */
+ dictLength = s->w_size;
}
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
+ /* insert dictionary into window and hash */
+ avail = strm->avail_in;
+ next = strm->next_in;
+ strm->avail_in = dictLength;
+ strm->next_in = (z_const Bytef *)dictionary;
+ fill_window(s);
+ while (s->lookahead >= MIN_MATCH) {
+ str = s->strstart;
+ n = s->lookahead - (MIN_MATCH-1);
+ do {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ } while (--n);
+ s->strstart = str;
+ s->lookahead = MIN_MATCH-1;
+ fill_window(s);
}
- if (hash_head) hash_head = 0; /* to make compiler happy */
+ s->strstart += s->lookahead;
+ s->block_start = (long)s->strstart;
+ s->insert = s->lookahead;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ strm->next_in = next;
+ strm->avail_in = avail;
+ s->wrap = wrap;
return Z_OK;
}
/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
+int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
z_streamp strm;
+ Bytef *dictionary;
+ uInt *dictLength;
{
deflate_state *s;
+ uInt len;
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ if (deflateStateCheck(strm))
+ return Z_STREAM_ERROR;
+ s = strm->state;
+ len = s->strstart + s->lookahead;
+ if (len > s->w_size)
+ len = s->w_size;
+ if (dictionary != Z_NULL && len)
+ zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
+ if (dictLength != Z_NULL)
+ *dictLength = len;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (deflateStateCheck(strm)) {
return Z_STREAM_ERROR;
}
@@ -375,7 +484,11 @@ int ZEXPORT deflateReset (strm)
if (s->wrap < 0) {
s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
}
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ s->status =
+#ifdef GZIP
+ s->wrap == 2 ? GZIP_STATE :
+#endif
+ s->wrap ? INIT_STATE : BUSY_STATE;
strm->adler =
#ifdef GZIP
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
@@ -384,31 +497,70 @@ int ZEXPORT deflateReset (strm)
s->last_flush = Z_NO_FLUSH;
_tr_init(s);
- lm_init(s);
return Z_OK;
}
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ int ret;
+
+ ret = deflateResetKeep(strm);
+ if (ret == Z_OK)
+ lm_init(strm->state);
+ return ret;
+}
+
/* ========================================================================= */
int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm;
gz_headerp head;
{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+ if (deflateStateCheck(strm) || strm->state->wrap != 2)
+ return Z_STREAM_ERROR;
strm->state->gzhead = head;
return Z_OK;
}
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+ unsigned *pending;
+ int *bits;
+ z_streamp strm;
+{
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ if (pending != Z_NULL)
+ *pending = strm->state->pending;
+ if (bits != Z_NULL)
+ *bits = strm->state->bi_valid;
+ return Z_OK;
+}
+
/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
int value;
{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ deflate_state *s;
+ int put;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+ if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ return Z_BUF_ERROR;
+ do {
+ put = Buf_size - s->bi_valid;
+ if (put > bits)
+ put = bits;
+ s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+ s->bi_valid += put;
+ _tr_flush_bits(s);
+ value >>= put;
+ bits -= put;
+ } while (bits);
return Z_OK;
}
@@ -420,9 +572,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
{
deflate_state *s;
compress_func func;
- int err = Z_OK;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
#ifdef FASTEST
@@ -435,11 +586,23 @@ int ZEXPORT deflateParams(strm, level, strategy)
}
func = configuration_table[s->level].func;
- if (func != configuration_table[level].func && strm->total_in != 0) {
+ if ((strategy != s->strategy || func != configuration_table[level].func) &&
+ s->high_water) {
/* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
+ int err = deflate(strm, Z_BLOCK);
+ if (err == Z_STREAM_ERROR)
+ return err;
+ if (strm->avail_out == 0)
+ return Z_BUF_ERROR;
}
if (s->level != level) {
+ if (s->level == 0 && s->matches != 0) {
+ if (s->matches == 1)
+ slide_hash(s);
+ else
+ CLEAR_HASH(s);
+ s->matches = 0;
+ }
s->level = level;
s->max_lazy_match = configuration_table[level].max_lazy;
s->good_match = configuration_table[level].good_length;
@@ -447,7 +610,7 @@ int ZEXPORT deflateParams(strm, level, strategy)
s->max_chain_length = configuration_table[level].max_chain;
}
s->strategy = strategy;
- return err;
+ return Z_OK;
}
/* ========================================================================= */
@@ -460,12 +623,12 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
{
deflate_state *s;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
+ s->good_match = (uInt)good_length;
+ s->max_lazy_match = (uInt)max_lazy;
s->nice_match = nice_length;
- s->max_chain_length = max_chain;
+ s->max_chain_length = (uInt)max_chain;
return Z_OK;
}
@@ -481,33 +644,68 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
* resulting from using fixed blocks instead of stored blocks, which deflate
* can emit on compressed data for some combinations of the parameters.
*
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel. But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
deflate_state *s;
- uLong destLen;
+ uLong complen, wraplen;
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+ /* conservative upper bound for compressed data */
+ complen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
- /* if can't get parameters, return conservative bound */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
+ /* if can't get parameters, return conservative bound plus zlib wrapper */
+ if (deflateStateCheck(strm))
+ return complen + 6;
- /* if not default parameters, return conservative bound */
+ /* compute wrapper length */
s = strm->state;
+ switch (s->wrap) {
+ case 0: /* raw deflate */
+ wraplen = 0;
+ break;
+ case 1: /* zlib wrapper */
+ wraplen = 6 + (s->strstart ? 4 : 0);
+ break;
+#ifdef GZIP
+ case 2: /* gzip wrapper */
+ wraplen = 18;
+ if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
+ Bytef *str;
+ if (s->gzhead->extra != Z_NULL)
+ wraplen += 2 + s->gzhead->extra_len;
+ str = s->gzhead->name;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ str = s->gzhead->comment;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ if (s->gzhead->hcrc)
+ wraplen += 2;
+ }
+ break;
+#endif
+ default: /* for compiler happiness */
+ wraplen = 6;
+ }
+
+ /* if not default parameters, return conservative bound */
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
+ return complen + wraplen;
/* default settings: return tight bound for that case */
- return compressBound(sourceLen);
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13 - 6 + wraplen;
}
/* =========================================================================
@@ -524,30 +722,43 @@ local void putShortMSB (s, b)
}
/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
+ * Flush as much pending output as possible. All deflate() output, except for
+ * some deflate_stored() output, goes through this function so some
+ * applications may wish to modify it to avoid allocating a large
+ * strm->next_out buffer and copying into it. (See also read_buf()).
*/
local void flush_pending(strm)
z_streamp strm;
{
- unsigned len = strm->state->pending;
+ unsigned len;
+ deflate_state *s = strm->state;
+ _tr_flush_bits(s);
+ len = s->pending;
if (len > strm->avail_out) len = strm->avail_out;
if (len == 0) return;
- zmemcpy(strm->next_out, strm->state->pending_out, len);
+ zmemcpy(strm->next_out, s->pending_out, len);
strm->next_out += len;
- strm->state->pending_out += len;
+ s->pending_out += len;
strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
+ strm->avail_out -= len;
+ s->pending -= len;
+ if (s->pending == 0) {
+ s->pending_out = s->pending_buf;
}
}
+/* ===========================================================================
+ * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
+ */
+#define HCRC_UPDATE(beg) \
+ do { \
+ if (s->gzhead->hcrc && s->pending > (beg)) \
+ strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
+ s->pending - (beg)); \
+ } while (0)
+
/* ========================================================================= */
int ZEXPORT deflate (strm, flush)
z_streamp strm;
@@ -556,230 +767,229 @@ int ZEXPORT deflate (strm, flush)
int old_flush; /* value of flush param for previous deflate call */
deflate_state *s;
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
+ if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
return Z_STREAM_ERROR;
}
s = strm->state;
if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
(s->status == FINISH_STATE && flush != Z_FINISH)) {
ERR_RETURN(strm, Z_STREAM_ERROR);
}
if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
- s->strm = strm; /* just in case */
old_flush = s->last_flush;
s->last_flush = flush;
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
/* Write the header */
if (s->status == INIT_STATE) {
-#ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
+ /* zlib header */
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
else
-#endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ putShortMSB(s, header);
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+#ifdef GZIP
+ if (s->status == GZIP_STATE) {
+ /* gzip header */
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == Z_NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
s->status = BUSY_STATE;
- putShortMSB(s, header);
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != Z_NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
}
- strm->adler = adler32(0L, Z_NULL, 0);
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
}
}
-#ifdef GZIP
if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
+ if (s->gzhead->extra != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
+ while (s->pending + left > s->pending_buf_size) {
+ uInt copy = s->pending_buf_size - s->pending;
+ zmemcpy(s->pending_buf + s->pending,
+ s->gzhead->extra + s->gzindex, copy);
+ s->pending = s->pending_buf_size;
+ HCRC_UPDATE(beg);
+ s->gzindex += copy;
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
}
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
+ beg = 0;
+ left -= copy;
}
+ zmemcpy(s->pending_buf + s->pending,
+ s->gzhead->extra + s->gzindex, left);
+ s->pending += left;
+ HCRC_UPDATE(beg);
+ s->gzindex = 0;
}
- else
- s->status = NAME_STATE;
+ s->status = NAME_STATE;
}
if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
+ if (s->gzhead->name != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
int val;
-
do {
if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
+ HCRC_UPDATE(beg);
flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
}
+ beg = 0;
}
val = s->gzhead->name[s->gzindex++];
put_byte(s, val);
} while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
+ HCRC_UPDATE(beg);
+ s->gzindex = 0;
}
- else
- s->status = COMMENT_STATE;
+ s->status = COMMENT_STATE;
}
if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
+ if (s->gzhead->comment != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
int val;
-
do {
if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
+ HCRC_UPDATE(beg);
flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
}
+ beg = 0;
}
val = s->gzhead->comment[s->gzindex++];
put_byte(s, val);
} while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
+ HCRC_UPDATE(beg);
}
- else
- s->status = HCRC_STATE;
+ s->status = HCRC_STATE;
}
if (s->status == HCRC_STATE) {
if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
+ if (s->pending + 2 > s->pending_buf_size) {
flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
}
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
}
- else
- s->status = BUSY_STATE;
- }
-#endif
+ s->status = BUSY_STATE;
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
+ /* Compression must start with an empty pending buffer */
flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
+ if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
}
+#endif
/* Start a new block or continue the current one.
*/
@@ -787,7 +997,10 @@ int ZEXPORT deflate (strm, flush)
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
block_state bstate;
- bstate = (*(configuration_table[s->level].func))(s, flush);
+ bstate = s->level == 0 ? deflate_stored(s, flush) :
+ s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+ s->strategy == Z_RLE ? deflate_rle(s, flush) :
+ (*(configuration_table[s->level].func))(s, flush);
if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE;
@@ -808,13 +1021,18 @@ int ZEXPORT deflate (strm, flush)
if (bstate == block_done) {
if (flush == Z_PARTIAL_FLUSH) {
_tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
+ } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
_tr_stored_block(s, (char*)0, 0L, 0);
/* For a full flush, this empty block will be recognized
* as a special marker by inflate_sync().
*/
if (flush == Z_FULL_FLUSH) {
CLEAR_HASH(s); /* forget history */
+ if (s->lookahead == 0) {
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
}
}
flush_pending(strm);
@@ -824,7 +1042,6 @@ int ZEXPORT deflate (strm, flush)
}
}
}
- Assert(strm->avail_out > 0, "bug2");
if (flush != Z_FINISH) return Z_OK;
if (s->wrap <= 0) return Z_STREAM_END;
@@ -861,18 +1078,9 @@ int ZEXPORT deflateEnd (strm)
{
int status;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
/* Deallocate in reverse order of allocations: */
TRY_FREE(strm, strm->state->pending_buf);
@@ -903,18 +1111,18 @@ int ZEXPORT deflateCopy (dest, source)
ushf *overlay;
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ if (deflateStateCheck(source) || dest == Z_NULL) {
return Z_STREAM_ERROR;
}
ss = source->state;
- zmemcpy(dest, source, sizeof(z_stream));
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
+ zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
@@ -930,8 +1138,8 @@ int ZEXPORT deflateCopy (dest, source)
}
/* following zmemcpy do not work for 16-bit MSDOS */
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
@@ -953,7 +1161,7 @@ int ZEXPORT deflateCopy (dest, source)
* allocating a large strm->next_in buffer and copying from it.
* (See also flush_pending()).
*/
-local int read_buf(strm, buf, size)
+local unsigned read_buf(strm, buf, size)
z_streamp strm;
Bytef *buf;
unsigned size;
@@ -965,19 +1173,19 @@ local int read_buf(strm, buf, size)
strm->avail_in -= len;
+ zmemcpy(buf, strm->next_in, len);
if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
+ strm->adler = adler32(strm->adler, buf, len);
}
#ifdef GZIP
else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
+ strm->adler = crc32(strm->adler, buf, len);
}
#endif
- zmemcpy(buf, strm->next_in, len);
strm->next_in += len;
strm->total_in += len;
- return (int)len;
+ return len;
}
/* ===========================================================================
@@ -1000,6 +1208,7 @@ local void lm_init (s)
s->strstart = 0;
s->block_start = 0L;
s->lookahead = 0;
+ s->insert = 0;
s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0;
s->ins_h = 0;
@@ -1029,10 +1238,10 @@ local uInt longest_match(s, cur_match)
IPos cur_match; /* current match */
{
unsigned chain_length = s->max_chain_length;/* max hash chain length */
- Bytef *scan = s->window + s->strstart; /* current string */
- Bytef *match; /* matched string */
- int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = (int)s->prev_length; /* best match length so far */
int nice_match = s->nice_match; /* stop if match long enough */
IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
s->strstart - (IPos)MAX_DIST(s) : NIL;
@@ -1046,13 +1255,13 @@ local uInt longest_match(s, cur_match)
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
- Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- ush scan_start = *(ushf*)scan;
- ush scan_end = *(ushf*)(scan+best_len-1);
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
#else
- Bytef *strend = s->window + s->strstart + MAX_MATCH;
- Byte scan_end1 = scan[best_len-1];
- Byte scan_end = scan[best_len];
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
#endif
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
@@ -1067,7 +1276,7 @@ local uInt longest_match(s, cur_match)
/* Do not look for matches beyond the end of the input. This is necessary
* to make deflate deterministic.
*/
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+ if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
@@ -1167,19 +1376,20 @@ local uInt longest_match(s, cur_match)
return s->lookahead;
}
#endif /* ASMV */
-#endif /* FASTEST */
+
+#else /* FASTEST */
/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
+ * Optimized version for FASTEST only
*/
-local uInt longest_match_fast(s, cur_match)
+local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
- Bytef *scan = s->window + s->strstart; /* current string */
- Bytef *match; /* matched string */
- int len; /* length of current match */
- Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
@@ -1225,7 +1435,13 @@ local uInt longest_match_fast(s, cur_match)
return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
}
-#ifdef DEBUG
+#endif /* FASTEST */
+
+#ifdef ZLIB_DEBUG
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
/* ===========================================================================
* Check that the match at match_start is indeed a match.
*/
@@ -1251,7 +1467,7 @@ local void check_match(s, start, match, length)
}
#else
# define check_match(s, start, match, length)
-#endif /* DEBUG */
+#endif /* ZLIB_DEBUG */
/* ===========================================================================
* Fill the window when the lookahead becomes insufficient.
@@ -1266,11 +1482,12 @@ local void check_match(s, start, match, length)
local void fill_window(s)
deflate_state *s;
{
- unsigned n, m;
- Posf *p;
+ unsigned n;
unsigned more; /* Amount of free space at the end of the window. */
uInt wsize = s->w_size;
+ Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
do {
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
@@ -1292,39 +1509,14 @@ local void fill_window(s)
*/
if (s->strstart >= wsize+MAX_DIST(s)) {
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
s->match_start -= wsize;
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- /* %%% avoid this when Z_RLE */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
+ slide_hash(s);
more += wsize;
}
- if (s->strm->avail_in == 0) return;
+ if (s->strm->avail_in == 0) break;
/* If there was no sliding:
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
@@ -1343,99 +1535,283 @@ local void fill_window(s)
s->lookahead += n;
/* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+ if (s->lookahead + s->insert >= MIN_MATCH) {
+ uInt str = s->strstart - s->insert;
+ s->ins_h = s->window[str];
+ UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
#if MIN_MATCH != 3
Call UPDATE_HASH() MIN_MATCH-3 more times
#endif
+ while (s->insert) {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ s->insert--;
+ if (s->lookahead + s->insert < MIN_MATCH)
+ break;
+ }
}
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
* but this is not important since only literal bytes will be emitted.
*/
} while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+ /* If the WIN_INIT bytes after the end of the current data have never been
+ * written, then zero those bytes in order to avoid memory check reports of
+ * the use of uninitialized (or uninitialised as Julian writes) bytes by
+ * the longest match routines. Update the high water mark for the next
+ * time through here. WIN_INIT is set to MAX_MATCH since the longest match
+ * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+ */
+ if (s->high_water < s->window_size) {
+ ulg curr = s->strstart + (ulg)(s->lookahead);
+ ulg init;
+
+ if (s->high_water < curr) {
+ /* Previous high water mark below current data -- zero WIN_INIT
+ * bytes or up to end of window, whichever is less.
+ */
+ init = s->window_size - curr;
+ if (init > WIN_INIT)
+ init = WIN_INIT;
+ zmemzero(s->window + curr, (unsigned)init);
+ s->high_water = curr + init;
+ }
+ else if (s->high_water < (ulg)curr + WIN_INIT) {
+ /* High water mark at or above current data, but below current data
+ * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+ * to end of window, whichever is less.
+ */
+ init = (ulg)curr + WIN_INIT - s->high_water;
+ if (init > s->window_size - s->high_water)
+ init = s->window_size - s->high_water;
+ zmemzero(s->window + s->high_water, (unsigned)init);
+ s->high_water += init;
+ }
+ }
+
+ Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+ "not enough room for search");
}
/* ===========================================================================
* Flush the current block, with given end-of-file flag.
* IN assertion: strstart is set to the end of the current match.
*/
-#define FLUSH_BLOCK_ONLY(s, eof) { \
+#define FLUSH_BLOCK_ONLY(s, last) { \
_tr_flush_block(s, (s->block_start >= 0L ? \
(charf *)&s->window[(unsigned)s->block_start] : \
(charf *)Z_NULL), \
(ulg)((long)s->strstart - s->block_start), \
- (eof)); \
+ (last)); \
s->block_start = s->strstart; \
flush_pending(s->strm); \
Tracev((stderr,"[FLUSH]")); \
}
/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+#define FLUSH_BLOCK(s, last) { \
+ FLUSH_BLOCK_ONLY(s, last); \
+ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
}
+/* Maximum stored block length in deflate format (not including header). */
+#define MAX_STORED 65535
+
+/* Minimum of a and b. */
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
/* ===========================================================================
* Copy without compression as much as possible from the input stream, return
* the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
+ *
+ * In case deflateParams() is used to later switch to a non-zero compression
+ * level, s->matches (otherwise unused when storing) keeps track of the number
+ * of hash table slides to perform. If s->matches is 1, then one hash table
+ * slide will be done when switching. If s->matches is 2, the maximum value
+ * allowed here, then the hash table will be cleared, since two or more slides
+ * is the same as a clear.
+ *
+ * deflate_stored() is written to minimize the number of times an input byte is
+ * copied. It is most efficient with large input and output buffers, which
+ * maximizes the opportunites to have a single copy from next_in to next_out.
*/
local block_state deflate_stored(s, flush)
deflate_state *s;
int flush;
{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
+ /* Smallest worthy block size when not flushing or finishing. By default
+ * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
+ * large input and output buffers, the stored block size will be larger.
*/
- ulg max_block_size = 0xffff;
- ulg max_start;
+ unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
+ /* Copy as many min_block or larger stored blocks directly to next_out as
+ * possible. If flushing, copy the remaining available input to next_out as
+ * stored blocks, if there is enough space.
+ */
+ unsigned len, left, have, last = 0;
+ unsigned used = s->strm->avail_in;
+ do {
+ /* Set len to the maximum size block that we can copy directly with the
+ * available input data and output space. Set left to how much of that
+ * would be copied from what's left in the window.
+ */
+ len = MAX_STORED; /* maximum deflate stored block length */
+ have = (s->bi_valid + 42) >> 3; /* number of header bytes */
+ if (s->strm->avail_out < have) /* need room for header */
+ break;
+ /* maximum stored block length that will fit in avail_out: */
+ have = s->strm->avail_out - have;
+ left = s->strstart - s->block_start; /* bytes left in window */
+ if (len > (ulg)left + s->strm->avail_in)
+ len = left + s->strm->avail_in; /* limit len to the input */
+ if (len > have)
+ len = have; /* limit len to the output */
+
+ /* If the stored block would be less than min_block in length, or if
+ * unable to copy all of the available input when flushing, then try
+ * copying to the window and the pending buffer instead. Also don't
+ * write an empty block when flushing -- deflate() does that.
+ */
+ if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
+ flush == Z_NO_FLUSH ||
+ len != left + s->strm->avail_in))
+ break;
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+ /* Make a dummy stored block in pending to get the header bytes,
+ * including any pending bits. This also updates the debugging counts.
+ */
+ last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
+ _tr_stored_block(s, (char *)0, 0L, last);
+
+ /* Replace the lengths in the dummy stored block with len. */
+ s->pending_buf[s->pending - 4] = len;
+ s->pending_buf[s->pending - 3] = len >> 8;
+ s->pending_buf[s->pending - 2] = ~len;
+ s->pending_buf[s->pending - 1] = ~len >> 8;
+
+ /* Write the stored block header bytes. */
+ flush_pending(s->strm);
+
+#ifdef ZLIB_DEBUG
+ /* Update debugging counts for the data about to be copied. */
+ s->compressed_len += len << 3;
+ s->bits_sent += len << 3;
+#endif
- if (s->lookahead == 0) break; /* flush the current block */
+ /* Copy uncompressed bytes from the window to next_out. */
+ if (left) {
+ if (left > len)
+ left = len;
+ zmemcpy(s->strm->next_out, s->window + s->block_start, left);
+ s->strm->next_out += left;
+ s->strm->avail_out -= left;
+ s->strm->total_out += left;
+ s->block_start += left;
+ len -= left;
}
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
+
+ /* Copy uncompressed bytes directly from next_in to next_out, updating
+ * the check value.
+ */
+ if (len) {
+ read_buf(s->strm, s->strm->next_out, len);
+ s->strm->next_out += len;
+ s->strm->avail_out -= len;
+ s->strm->total_out += len;
}
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
+ } while (last == 0);
+
+ /* Update the sliding window with the last s->w_size bytes of the copied
+ * data, or append all of the copied data to the existing window if less
+ * than s->w_size bytes were copied. Also update the number of bytes to
+ * insert in the hash tables, in the event that deflateParams() switches to
+ * a non-zero compression level.
+ */
+ used -= s->strm->avail_in; /* number of input bytes directly copied */
+ if (used) {
+ /* If any input was used, then no unused input remains in the window,
+ * therefore s->block_start == s->strstart.
*/
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
+ if (used >= s->w_size) { /* supplant the previous history */
+ s->matches = 2; /* clear hash */
+ zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
+ s->strstart = s->w_size;
}
+ else {
+ if (s->window_size - s->strstart <= used) {
+ /* Slide the window down. */
+ s->strstart -= s->w_size;
+ zmemcpy(s->window, s->window + s->w_size, s->strstart);
+ if (s->matches < 2)
+ s->matches++; /* add a pending slide_hash() */
+ }
+ zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
+ s->strstart += used;
+ }
+ s->block_start = s->strstart;
+ s->insert += MIN(used, s->w_size - s->insert);
+ }
+ if (s->high_water < s->strstart)
+ s->high_water = s->strstart;
+
+ /* If the last block was written to next_out, then done. */
+ if (last)
+ return finish_done;
+
+ /* If flushing and all input has been consumed, then done. */
+ if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
+ s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
+ return block_done;
+
+ /* Fill the window with any remaining input. */
+ have = s->window_size - s->strstart - 1;
+ if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
+ /* Slide the window down. */
+ s->block_start -= s->w_size;
+ s->strstart -= s->w_size;
+ zmemcpy(s->window, s->window + s->w_size, s->strstart);
+ if (s->matches < 2)
+ s->matches++; /* add a pending slide_hash() */
+ have += s->w_size; /* more space now */
+ }
+ if (have > s->strm->avail_in)
+ have = s->strm->avail_in;
+ if (have) {
+ read_buf(s->strm, s->window + s->strstart, have);
+ s->strstart += have;
+ }
+ if (s->high_water < s->strstart)
+ s->high_water = s->strstart;
+
+ /* There was not enough avail_out to write a complete worthy or flushed
+ * stored block to next_out. Write a stored block to pending instead, if we
+ * have enough input for a worthy block, or if flushing and there is enough
+ * room for the remaining input as a stored block in the pending buffer.
+ */
+ have = (s->bi_valid + 42) >> 3; /* number of header bytes */
+ /* maximum stored block length that will fit in pending: */
+ have = MIN(s->pending_buf_size - have, MAX_STORED);
+ min_block = MIN(have, s->w_size);
+ left = s->strstart - s->block_start;
+ if (left >= min_block ||
+ ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
+ s->strm->avail_in == 0 && left <= have)) {
+ len = MIN(left, have);
+ last = flush == Z_FINISH && s->strm->avail_in == 0 &&
+ len == left ? 1 : 0;
+ _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
+ s->block_start += len;
+ flush_pending(s->strm);
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+
+ /* We've done all we can with the available input and output. */
+ return last ? finish_started : need_more;
}
/* ===========================================================================
@@ -1449,7 +1825,7 @@ local block_state deflate_fast(s, flush)
deflate_state *s;
int flush;
{
- IPos hash_head = NIL; /* head of the hash chain */
+ IPos hash_head; /* head of the hash chain */
int bflush; /* set if current block must be flushed */
for (;;) {
@@ -1469,6 +1845,7 @@ local block_state deflate_fast(s, flush)
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
+ hash_head = NIL;
if (s->lookahead >= MIN_MATCH) {
INSERT_STRING(s, s->strstart, hash_head);
}
@@ -1481,19 +1858,8 @@ local block_state deflate_fast(s, flush)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
-#ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#endif
- /* longest_match() or longest_match_fast() sets match_start */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
}
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length);
@@ -1541,8 +1907,14 @@ local block_state deflate_fast(s, flush)
}
if (bflush) FLUSH_BLOCK(s, 0);
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
#ifndef FASTEST
@@ -1555,7 +1927,7 @@ local block_state deflate_slow(s, flush)
deflate_state *s;
int flush;
{
- IPos hash_head = NIL; /* head of hash chain */
+ IPos hash_head; /* head of hash chain */
int bflush; /* set if current block must be flushed */
/* Process the input block. */
@@ -1576,6 +1948,7 @@ local block_state deflate_slow(s, flush)
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
+ hash_head = NIL;
if (s->lookahead >= MIN_MATCH) {
INSERT_STRING(s, s->strstart, hash_head);
}
@@ -1591,12 +1964,8 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED
#if TOO_FAR <= 32767
@@ -1669,12 +2038,17 @@ local block_state deflate_slow(s, flush)
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
s->match_available = 0;
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
#endif /* FASTEST */
-#if 0
/* ===========================================================================
* For Z_RLE, simply look for runs of bytes, generate matches only of distance
* one. Do not maintain a hash table. (It will be regenerated if this run of
@@ -1684,43 +2058,52 @@ local block_state deflate_rle(s, flush)
deflate_state *s;
int flush;
{
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
+ int bflush; /* set if current block must be flushed */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan, *strend; /* scan goes up to strend for length of run */
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
+ * for the longest run, plus one for the unrolled loop.
*/
- if (s->lookahead < MAX_MATCH) {
+ if (s->lookahead <= MAX_MATCH) {
fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+ if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */
}
/* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ s->match_length = 0;
+ if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
+ prev = *scan;
+ if (prev == *++scan && prev == *++scan && prev == *++scan) {
+ strend = s->window + s->strstart + MAX_MATCH;
+ do {
+ } while (prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ scan < strend);
+ s->match_length = MAX_MATCH - (uInt)(strend - scan);
+ if (s->match_length > s->lookahead)
+ s->match_length = s->lookahead;
+ }
+ Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
}
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+ _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+ s->strstart += s->match_length;
+ s->match_length = 0;
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart]));
@@ -1730,7 +2113,51 @@ local block_state deflate_rle(s, flush)
}
if (bflush) FLUSH_BLOCK(s, 0);
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we have a literal to write. */
+ if (s->lookahead == 0) {
+ fill_window(s);
+ if (s->lookahead == 0) {
+ if (flush == Z_NO_FLUSH)
+ return need_more;
+ break; /* flush the current block */
+ }
+ }
+
+ /* Output a literal byte */
+ s->match_length = 0;
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
-#endif
diff --git a/zlib/deflate.h b/zlib/deflate.h
index 05a5ab3a2c12..23ecdd312bc0 100644
--- a/zlib/deflate.h
+++ b/zlib/deflate.h
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
- * Copyright (C) 1995-2004 Jean-loup Gailly
+ * Copyright (C) 1995-2016 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -48,13 +48,19 @@
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
-#define INIT_STATE 42
-#define EXTRA_STATE 69
-#define NAME_STATE 73
-#define COMMENT_STATE 91
-#define HCRC_STATE 103
-#define BUSY_STATE 113
-#define FINISH_STATE 666
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE 42 /* zlib header -> BUSY_STATE */
+#ifdef GZIP
+# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */
+#endif
+#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */
+#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */
+#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */
+#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */
+#define BUSY_STATE 113 /* deflate -> FINISH_STATE */
+#define FINISH_STATE 666 /* stream complete */
/* Stream status */
@@ -80,7 +86,7 @@ typedef struct static_tree_desc_s static_tree_desc;
typedef struct tree_desc_s {
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
+ const static_tree_desc *stat_desc; /* the corresponding static tree */
} FAR tree_desc;
typedef ush Pos;
@@ -97,11 +103,11 @@ typedef struct internal_state {
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
+ ulg pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
+ ulg gzindex; /* where in extra, name, or comment */
+ Byte method; /* can only be DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
@@ -188,7 +194,7 @@ typedef struct internal_state {
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
+ /* Didn't use ct_data typedef below to suppress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
@@ -244,9 +250,9 @@ typedef struct internal_state {
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
+ uInt insert; /* bytes at end of window left to insert */
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
@@ -260,12 +266,19 @@ typedef struct internal_state {
* are always zero.
*/
+ ulg high_water;
+ /* High water mark offset in window for initialized bytes -- bytes above
+ * this are set to zero in order to avoid memory check warnings when
+ * longest match routines access bytes past the input. This is then
+ * updated to the new high water mark.
+ */
+
} FAR deflate_state;
/* Output a byte on the stream.
* IN assertion: there is enough room in pending_buf.
*/
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
@@ -278,14 +291,19 @@ typedef struct internal_state {
* distances are limited to MAX_DIST instead of WSIZE.
*/
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+ memory checker errors from longest match routines */
+
/* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
@@ -294,15 +312,15 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
* used.
*/
-#ifndef DEBUG
+#ifndef ZLIB_DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
+ extern uch ZLIB_INTERNAL _length_code[];
+ extern uch ZLIB_INTERNAL _dist_code[];
#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
+ extern const uch ZLIB_INTERNAL _length_code[];
+ extern const uch ZLIB_INTERNAL _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
@@ -313,8 +331,8 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
flush = (s->last_lit == s->lit_bufsize-1); \
}
# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
+ { uch len = (uch)(length); \
+ ush dist = (ush)(distance); \
s->d_buf[s->last_lit] = dist; \
s->l_buf[s->last_lit++] = len; \
dist--; \
diff --git a/zlib/gzclose.c b/zlib/gzclose.c
new file mode 100644
index 000000000000..caeb99a3177f
--- /dev/null
+++ b/zlib/gzclose.c
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+ That way the other gzclose functions can be used instead to avoid linking in
+ unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+ gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+ gz_statep state;
+
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+ return gzclose_r(file);
+#endif
+}
diff --git a/zlib/gzguts.h b/zlib/gzguts.h
new file mode 100644
index 000000000000..990a4d251493
--- /dev/null
+++ b/zlib/gzguts.h
@@ -0,0 +1,218 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+# ifndef _LARGEFILE_SOURCE
+# define _LARGEFILE_SOURCE 1
+# endif
+# ifdef _FILE_OFFSET_BITS
+# undef _FILE_OFFSET_BITS
+# endif
+#endif
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include
+#include "zlib.h"
+#ifdef STDC
+# include
+# include
+# include
+#endif
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include
+
+#ifdef _WIN32
+# include
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+# include
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define WIDECHAR
+#endif
+
+#ifdef WINAPI_FAMILY
+# define open _open
+# define read _read
+# define write _write
+# define close _close
+#endif
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+# ifdef VMS
+# define NO_vsnprintf
+# endif
+# ifdef __OS400__
+# define NO_vsnprintf
+# endif
+# ifdef __MVS__
+# define NO_vsnprintf
+# endif
+#endif
+
+/* unlike snprintf (which is required in C99), _snprintf does not guarantee
+ null termination of the result -- however this is only used in gzlib.c where
+ the result is assured to fit in the space provided */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# define snprintf _snprintf
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+ define "local" for the non-static meaning of "static", for readability
+ (compile with -Dlocal if your debugger can't find static symbols) */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+ extern voidp malloc OF((uInt size));
+ extern void free OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+# include
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+# ifndef NO_STRERROR
+# include
+# define zstrerror() strerror(errno)
+# else
+# define zstrerror() "stdio error (consult errno)"
+# endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+ twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0 /* look for a gzip header */
+#define COPY 1 /* copy input directly */
+#define GZIP 2 /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+ /* exposed contents for gzgetc() macro */
+ struct gzFile_s x; /* "x" for exposed */
+ /* x.have: number of bytes available at x.next */
+ /* x.next: next output data to deliver or write */
+ /* x.pos: current position in uncompressed data */
+ /* used for both reading and writing */
+ int mode; /* see gzip modes above */
+ int fd; /* file descriptor */
+ char *path; /* path or fd for error messages */
+ unsigned size; /* buffer size, zero if not allocated yet */
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */
+ unsigned char *in; /* input buffer (double-sized when writing) */
+ unsigned char *out; /* output buffer (double-sized when reading) */
+ int direct; /* 0 if processing gzip, 1 if transparent */
+ /* just for reading */
+ int how; /* 0: get header, 1: copy, 2: decompress */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ int eof; /* true if end of input file reached */
+ int past; /* true if read requested past end */
+ /* just for writing */
+ int level; /* compression level */
+ int strategy; /* compression strategy */
+ /* seek request */
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */
+ int seek; /* true if seek request pending */
+ /* error information */
+ int err; /* error code */
+ char *msg; /* error message */
+ /* zlib inflate or deflate stream */
+ z_stream strm; /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+ value -- needed when comparing unsigned to z_off64_t, which is signed
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/zlib/gzio.c b/zlib/gzio.c
deleted file mode 100644
index ed4e77ca7e9d..000000000000
--- a/zlib/gzio.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
- */
-
-/* @(#) $Id$ */
-
-/* Need to be included "early" to control other headers */
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-#include
-
-#include "zutil.h"
-
-#ifdef NO_DEFLATE /* for compatibility with old definition */
-# define NO_GZCOMPRESS
-#endif
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#ifdef __MVS__
-# pragma map (fdopen , "\174\174FDOPEN")
- FILE *fdopen(int, const char *);
-#endif
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- z_off_t start; /* start of compressed data in file (header skipped) */
- z_off_t in; /* bytes into deflate or inflate */
- z_off_t out; /* bytes out of deflate or inflate */
- int back; /* one character push-back */
- int last; /* true if push-back is last character */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->in = 0;
- s->out = 0;
- s->back = EOF;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else if (*p == 'R') {
- strategy = Z_RLE;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->start = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * start anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->start = ftell(s->file) - s->stream.avail_in;
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[46]; /* allow for up to 128-bit integers */
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Assure two bytes in the buffer so we can peek ahead -- handle case
- where first byte of header is at the end of the buffer after the last
- gzip segment */
- len = s->stream.avail_in;
- if (len < 2) {
- if (len) s->inbuf[0] = s->stream.next_in[0];
- errno = 0;
- len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
- if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
- s->stream.avail_in += len;
- s->stream.next_in = s->inbuf;
- if (s->stream.avail_in < 2) {
- s->transparent = s->stream.avail_in;
- return;
- }
- }
-
- /* Peek ahead to check the gzip magic header */
- if (s->stream.next_in[0] != gz_magic[0] ||
- s->stream.next_in[1] != gz_magic[1]) {
- s->transparent = 1;
- return;
- }
- s->stream.avail_in -= 2;
- s->stream.next_in += 2;
-
- /* Check the rest of the gzip header */
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- if (s->stream.avail_out && s->back != EOF) {
- *next_out++ = s->back;
- s->stream.next_out++;
- s->stream.avail_out--;
- s->back = EOF;
- s->out++;
- start++;
- if (s->last) {
- s->z_err = Z_STREAM_END;
- return 1;
- }
- }
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -=
- (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
- }
- len -= s->stream.avail_out;
- s->in += len;
- s->out += len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may be
- * different from s->out in case of concatenated .gz files.
- * Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- inflateReset(&(s->stream));
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- if (len == s->stream.avail_out &&
- (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
- return -1;
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Push one byte back onto the stream.
-*/
-int ZEXPORT gzungetc(c, file)
- int c;
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
- s->back = c;
- s->out--;
- s->last = (s->z_err == Z_STREAM_END);
- if (s->last) s->z_err = Z_OK;
- s->z_eof = 0;
- return c;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_GZCOMPRESS
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- voidpc buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- buf[sizeof(buf) - 1] = 0;
- va_start(va, format);
-#ifdef NO_vsnprintf
-# ifdef HAS_vsprintf_void
- (void)vsprintf(buf, format, va);
- va_end(va);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = vsprintf(buf, format, va);
- va_end(va);
-# endif
-#else
-# ifdef HAS_vsnprintf_void
- (void)vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
- len = strlen(buf);
-# else
- len = vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-# endif
-#endif
- if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
- buf[sizeof(buf) - 1] = 0;
-#ifdef NO_snprintf
-# ifdef HAS_sprintf_void
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#else
-# ifdef HAS_snprintf_void
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(buf);
-# else
- len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#endif
- if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), flush);
- s->out -= s->stream.avail_out;
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_GZCOMPRESS */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- if (s->inbuf == Z_NULL) return -1L;
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return s->in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->in = s->out = offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if (offset >= s->out) {
- offset -= s->out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- if (s->outbuf == Z_NULL) return -1L;
- }
- if (offset && s->back != EOF) {
- s->back = EOF;
- s->out++;
- offset--;
- if (s->last) s->z_err = Z_STREAM_END;
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return s->out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
- if (!s->transparent) (void)inflateReset(&s->stream);
- s->in = 0;
- s->out = 0;
- return fseek(s->file, s->start, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- /* With concatenated compressed files that can have embedded
- * crc trailers, z_eof is no longer the only/best indicator of EOF
- * on a gz_stream. Handle end-of-stream error explicitly here.
- */
- if (s == NULL || s->mode != 'r') return 0;
- if (s->z_eof) return 1;
- return s->z_err == Z_STREAM_END;
-}
-
-/* ===========================================================================
- Returns 1 if reading and doing so transparently, otherwise zero.
-*/
-int ZEXPORT gzdirect (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return 0;
- return s->transparent;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return Z_STREAM_ERROR;
-#else
- if (do_flush (file, Z_FINISH) != Z_OK)
- return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, (uLong)(s->in & 0xffffffff));
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-#ifdef STDC
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-/* ===========================================================================
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char * ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
-
-/* ===========================================================================
- Clear the error and end-of-file flags, and do the same for the real file.
-*/
-void ZEXPORT gzclearerr (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return;
- if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
- s->z_eof = 0;
- clearerr(s->file);
-}
diff --git a/zlib/gzlib.c b/zlib/gzlib.c
new file mode 100644
index 000000000000..4105e6aff925
--- /dev/null
+++ b/zlib/gzlib.c
@@ -0,0 +1,637 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+# define LSEEK _lseeki64
+#else
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define LSEEK lseek64
+#else
+# define LSEEK lseek
+#endif
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const void *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+ string and return a pointer to it. Typically, the values for ERROR come
+ from GetLastError.
+
+ The string pointed to shall not be modified by the application, but may be
+ overwritten by a subsequent call to gz_strwinerror
+
+ The gz_strwinerror function does not change the current setting of
+ GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+ gz_statep state;
+{
+ state->x.have = 0; /* no output data available */
+ if (state->mode == GZ_READ) { /* for reading ... */
+ state->eof = 0; /* not at end of file */
+ state->past = 0; /* have not read past end yet */
+ state->how = LOOK; /* look for gzip header */
+ }
+ state->seek = 0; /* no seek request pending */
+ gz_error(state, Z_OK, NULL); /* clear error */
+ state->x.pos = 0; /* no uncompressed data yet */
+ state->strm.avail_in = 0; /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+ const void *path;
+ int fd;
+ const char *mode;
+{
+ gz_statep state;
+ z_size_t len;
+ int oflag;
+#ifdef O_CLOEXEC
+ int cloexec = 0;
+#endif
+#ifdef O_EXCL
+ int exclusive = 0;
+#endif
+
+ /* check input */
+ if (path == NULL)
+ return NULL;
+
+ /* allocate gzFile structure to return */
+ state = (gz_statep)malloc(sizeof(gz_state));
+ if (state == NULL)
+ return NULL;
+ state->size = 0; /* no buffers allocated yet */
+ state->want = GZBUFSIZE; /* requested buffer size */
+ state->msg = NULL; /* no error message yet */
+
+ /* interpret mode */
+ state->mode = GZ_NONE;
+ state->level = Z_DEFAULT_COMPRESSION;
+ state->strategy = Z_DEFAULT_STRATEGY;
+ state->direct = 0;
+ while (*mode) {
+ if (*mode >= '0' && *mode <= '9')
+ state->level = *mode - '0';
+ else
+ switch (*mode) {
+ case 'r':
+ state->mode = GZ_READ;
+ break;
+#ifndef NO_GZCOMPRESS
+ case 'w':
+ state->mode = GZ_WRITE;
+ break;
+ case 'a':
+ state->mode = GZ_APPEND;
+ break;
+#endif
+ case '+': /* can't read and write at the same time */
+ free(state);
+ return NULL;
+ case 'b': /* ignore -- will request binary anyway */
+ break;
+#ifdef O_CLOEXEC
+ case 'e':
+ cloexec = 1;
+ break;
+#endif
+#ifdef O_EXCL
+ case 'x':
+ exclusive = 1;
+ break;
+#endif
+ case 'f':
+ state->strategy = Z_FILTERED;
+ break;
+ case 'h':
+ state->strategy = Z_HUFFMAN_ONLY;
+ break;
+ case 'R':
+ state->strategy = Z_RLE;
+ break;
+ case 'F':
+ state->strategy = Z_FIXED;
+ break;
+ case 'T':
+ state->direct = 1;
+ break;
+ default: /* could consider as an error, but just ignore */
+ ;
+ }
+ mode++;
+ }
+
+ /* must provide an "r", "w", or "a" */
+ if (state->mode == GZ_NONE) {
+ free(state);
+ return NULL;
+ }
+
+ /* can't force transparent read */
+ if (state->mode == GZ_READ) {
+ if (state->direct) {
+ free(state);
+ return NULL;
+ }
+ state->direct = 1; /* for empty file */
+ }
+
+ /* save the path name for error messages */
+#ifdef WIDECHAR
+ if (fd == -2) {
+ len = wcstombs(NULL, path, 0);
+ if (len == (z_size_t)-1)
+ len = 0;
+ }
+ else
+#endif
+ len = strlen((const char *)path);
+ state->path = (char *)malloc(len + 1);
+ if (state->path == NULL) {
+ free(state);
+ return NULL;
+ }
+#ifdef WIDECHAR
+ if (fd == -2)
+ if (len)
+ wcstombs(state->path, path, len + 1);
+ else
+ *(state->path) = 0;
+ else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+ strcpy(state->path, path);
+#endif
+
+ /* compute the flags for open() */
+ oflag =
+#ifdef O_LARGEFILE
+ O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+ O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+ (cloexec ? O_CLOEXEC : 0) |
+#endif
+ (state->mode == GZ_READ ?
+ O_RDONLY :
+ (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+ (exclusive ? O_EXCL : 0) |
+#endif
+ (state->mode == GZ_WRITE ?
+ O_TRUNC :
+ O_APPEND)));
+
+ /* open the file with the appropriate flags (or just use fd) */
+ state->fd = fd > -1 ? fd : (
+#ifdef WIDECHAR
+ fd == -2 ? _wopen(path, oflag, 0666) :
+#endif
+ open((const char *)path, oflag, 0666));
+ if (state->fd == -1) {
+ free(state->path);
+ free(state);
+ return NULL;
+ }
+ if (state->mode == GZ_APPEND) {
+ LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
+ state->mode = GZ_WRITE; /* simplify later checks */
+ }
+
+ /* save the current position for rewinding (only if reading) */
+ if (state->mode == GZ_READ) {
+ state->start = LSEEK(state->fd, 0, SEEK_CUR);
+ if (state->start == -1) state->start = 0;
+ }
+
+ /* initialize stream */
+ gz_reset(state);
+
+ /* return stream */
+ return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+ int fd;
+ const char *mode;
+{
+ char *path; /* identifier for error messages */
+ gzFile gz;
+
+ if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
+ return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(path, 7 + 3 * sizeof(int), "", fd);
+#else
+ sprintf(path, "", fd); /* for debugging */
+#endif
+ gz = gz_open(path, fd, mode);
+ free(path);
+ return gz;
+}
+
+/* -- see zlib.h -- */
+#ifdef WIDECHAR
+gzFile ZEXPORT gzopen_w(path, mode)
+ const wchar_t *path;
+ const char *mode;
+{
+ return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+ gzFile file;
+ unsigned size;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* make sure we haven't already allocated memory */
+ if (state->size != 0)
+ return -1;
+
+ /* check and set requested size */
+ if ((size << 1) < size)
+ return -1; /* need to be able to double it */
+ if (size < 2)
+ size = 2; /* need two bytes to check magic header */
+ state->want = size;
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* back up and start over */
+ if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+ return -1;
+ gz_reset(state);
+ return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+ gzFile file;
+ z_off64_t offset;
+ int whence;
+{
+ unsigned n;
+ z_off64_t ret;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* check that there's no error */
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* can only seek from start or relative to current position */
+ if (whence != SEEK_SET && whence != SEEK_CUR)
+ return -1;
+
+ /* normalize offset to a SEEK_CUR specification */
+ if (whence == SEEK_SET)
+ offset -= state->x.pos;
+ else if (state->seek)
+ offset += state->skip;
+ state->seek = 0;
+
+ /* if within raw area while reading, just go there */
+ if (state->mode == GZ_READ && state->how == COPY &&
+ state->x.pos + offset >= 0) {
+ ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+ if (ret == -1)
+ return -1;
+ state->x.have = 0;
+ state->eof = 0;
+ state->past = 0;
+ state->seek = 0;
+ gz_error(state, Z_OK, NULL);
+ state->strm.avail_in = 0;
+ state->x.pos += offset;
+ return state->x.pos;
+ }
+
+ /* calculate skip amount, rewinding if needed for back seek when reading */
+ if (offset < 0) {
+ if (state->mode != GZ_READ) /* writing -- can't go backwards */
+ return -1;
+ offset += state->x.pos;
+ if (offset < 0) /* before start of file! */
+ return -1;
+ if (gzrewind(file) == -1) /* rewind, then skip to offset */
+ return -1;
+ }
+
+ /* if reading, skip what's in output buffer (one less gzgetc() check) */
+ if (state->mode == GZ_READ) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+ (unsigned)offset : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ offset -= n;
+ }
+
+ /* request skip (if not zero) */
+ if (offset) {
+ state->seek = 1;
+ state->skip = offset;
+ }
+ return state->x.pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ z_off64_t ret;
+
+ ret = gzseek64(file, (z_off64_t)offset, whence);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* return position */
+ return state->x.pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gztell64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+ gzFile file;
+{
+ z_off64_t offset;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* compute and return effective offset in file */
+ offset = LSEEK(state->fd, 0, SEEK_CUR);
+ if (offset == -1)
+ return -1;
+ if (state->mode == GZ_READ) /* reading */
+ offset -= state->strm.avail_in; /* don't count buffered input */
+ return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gzoffset64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return 0;
+
+ /* return end-of-file state */
+ return state->mode == GZ_READ ? state->past : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return NULL;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return NULL;
+
+ /* return error information */
+ if (errnum != NULL)
+ *errnum = state->err;
+ return state->err == Z_MEM_ERROR ? "out of memory" :
+ (state->msg == NULL ? "" : state->msg);
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return;
+
+ /* clear error and end-of-file */
+ if (state->mode == GZ_READ) {
+ state->eof = 0;
+ state->past = 0;
+ }
+ gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+ state->msg accordingly. Free any previous error message already there. Do
+ not try to free or allocate space if the error is Z_MEM_ERROR (out of
+ memory). Simply save the error message as a static string. If there is an
+ allocation failure constructing the error message, then convert the error to
+ out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+ gz_statep state;
+ int err;
+ const char *msg;
+{
+ /* free previously allocated message and clear */
+ if (state->msg != NULL) {
+ if (state->err != Z_MEM_ERROR)
+ free(state->msg);
+ state->msg = NULL;
+ }
+
+ /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+ if (err != Z_OK && err != Z_BUF_ERROR)
+ state->x.have = 0;
+
+ /* set error code, and if no message, then done */
+ state->err = err;
+ if (msg == NULL)
+ return;
+
+ /* for an out of memory error, return literal string when requested */
+ if (err == Z_MEM_ERROR)
+ return;
+
+ /* construct error message with path */
+ if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+ NULL) {
+ state->err = Z_MEM_ERROR;
+ return;
+ }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+ "%s%s%s", state->path, ": ", msg);
+#else
+ strcpy(state->msg, state->path);
+ strcat(state->msg, ": ");
+ strcat(state->msg, msg);
+#endif
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+ available) -- we need to do this to cover cases where 2's complement not
+ used, since C standard permits 1's complement and sign-bit representations,
+ otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+ unsigned p, q;
+
+ p = 1;
+ do {
+ q = p;
+ p <<= 1;
+ p++;
+ } while (p > q);
+ return q >> 1;
+}
+#endif
diff --git a/zlib/gzread.c b/zlib/gzread.c
new file mode 100644
index 000000000000..956b91ea7d9e
--- /dev/null
+++ b/zlib/gzread.c
@@ -0,0 +1,654 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_look OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_fetch OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
+ state->fd, and update state->eof, state->err, and state->msg as appropriate.
+ This function needs to loop on read(), since read() is not guaranteed to
+ read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+ gz_statep state;
+ unsigned char *buf;
+ unsigned len;
+ unsigned *have;
+{
+ int ret;
+ unsigned get, max = ((unsigned)-1 >> 2) + 1;
+
+ *have = 0;
+ do {
+ get = len - *have;
+ if (get > max)
+ get = max;
+ ret = read(state->fd, buf + *have, get);
+ if (ret <= 0)
+ break;
+ *have += (unsigned)ret;
+ } while (*have < len);
+ if (ret < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (ret == 0)
+ state->eof = 1;
+ return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+ error, 0 otherwise. Note that the eof flag is set when the end of the input
+ file is reached, even though there may be unused data in the buffer. Once
+ that data has been used, no more attempts will be made to read the file.
+ If strm->avail_in != 0, then the current data is moved to the beginning of
+ the input buffer, and then the remainder of the buffer is loaded with the
+ available data from the input file. */
+local int gz_avail(state)
+ gz_statep state;
+{
+ unsigned got;
+ z_streamp strm = &(state->strm);
+
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+ if (state->eof == 0) {
+ if (strm->avail_in) { /* copy what's there to the start */
+ unsigned char *p = state->in;
+ unsigned const char *q = strm->next_in;
+ unsigned n = strm->avail_in;
+ do {
+ *p++ = *q++;
+ } while (--n);
+ }
+ if (gz_load(state, state->in + strm->avail_in,
+ state->size - strm->avail_in, &got) == -1)
+ return -1;
+ strm->avail_in += got;
+ strm->next_in = state->in;
+ }
+ return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
+ If this is the first time in, allocate required memory. state->how will be
+ left unchanged if there is no more input data available, will be set to COPY
+ if there is no gzip header and direct copying will be performed, or it will
+ be set to GZIP for decompression. If direct copying, then leftover input
+ data from the input buffer will be copied to the output buffer. In that
+ case, all further file reads will be directly to either the output buffer or
+ a user buffer. If decompressing, the inflate state will be initialized.
+ gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ /* allocate read buffers and inflate memory */
+ if (state->size == 0) {
+ /* allocate buffers */
+ state->in = (unsigned char *)malloc(state->want);
+ state->out = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL || state->out == NULL) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ state->size = state->want;
+
+ /* allocate inflate memory */
+ state->strm.zalloc = Z_NULL;
+ state->strm.zfree = Z_NULL;
+ state->strm.opaque = Z_NULL;
+ state->strm.avail_in = 0;
+ state->strm.next_in = Z_NULL;
+ if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
+ free(state->out);
+ free(state->in);
+ state->size = 0;
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ }
+
+ /* get at least the magic bytes in the input buffer */
+ if (strm->avail_in < 2) {
+ if (gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0)
+ return 0;
+ }
+
+ /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+ a logical dilemma here when considering the case of a partially written
+ gzip file, to wit, if a single 31 byte is written, then we cannot tell
+ whether this is a single-byte file, or just a partially written gzip
+ file -- for here we assume that if a gzip file is being written, then
+ the header will be written in a single operation, so that reading a
+ single byte is sufficient indication that it is not a gzip file) */
+ if (strm->avail_in > 1 &&
+ strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+ inflateReset(strm);
+ state->how = GZIP;
+ state->direct = 0;
+ return 0;
+ }
+
+ /* no gzip header -- if we were decoding gzip before, then this is trailing
+ garbage. Ignore the trailing garbage and finish. */
+ if (state->direct == 0) {
+ strm->avail_in = 0;
+ state->eof = 1;
+ state->x.have = 0;
+ return 0;
+ }
+
+ /* doing raw i/o, copy any leftover input to output -- this assumes that
+ the output buffer is larger than the input buffer, which also assures
+ space for gzungetc() */
+ state->x.next = state->out;
+ if (strm->avail_in) {
+ memcpy(state->x.next, strm->next_in, strm->avail_in);
+ state->x.have = strm->avail_in;
+ strm->avail_in = 0;
+ }
+ state->how = COPY;
+ state->direct = 1;
+ return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+ On return, state->x.have and state->x.next point to the just decompressed
+ data. If the gzip stream completes, state->how is reset to LOOK to look for
+ the next gzip stream or raw data, once state->x.have is depleted. Returns 0
+ on success, -1 on failure. */
+local int gz_decomp(state)
+ gz_statep state;
+{
+ int ret = Z_OK;
+ unsigned had;
+ z_streamp strm = &(state->strm);
+
+ /* fill output buffer up to end of deflate stream */
+ had = strm->avail_out;
+ do {
+ /* get more input for inflate() */
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0) {
+ gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+ break;
+ }
+
+ /* decompress and handle errors */
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: inflate stream corrupt");
+ return -1;
+ }
+ if (ret == Z_MEM_ERROR) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
+ gz_error(state, Z_DATA_ERROR,
+ strm->msg == NULL ? "compressed data error" : strm->msg);
+ return -1;
+ }
+ } while (strm->avail_out && ret != Z_STREAM_END);
+
+ /* update available output */
+ state->x.have = had - strm->avail_out;
+ state->x.next = strm->next_out - state->x.have;
+
+ /* if the gzip stream completed successfully, look for another */
+ if (ret == Z_STREAM_END)
+ state->how = LOOK;
+
+ /* good decompression */
+ return 0;
+}
+
+/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
+ Data is either copied from the input file or decompressed from the input
+ file depending on state->how. If state->how is LOOK, then a gzip header is
+ looked for to determine whether to copy or decompress. Returns -1 on error,
+ otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
+ end of the input file has been reached and all data has been processed. */
+local int gz_fetch(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ do {
+ switch(state->how) {
+ case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
+ if (gz_look(state) == -1)
+ return -1;
+ if (state->how == LOOK)
+ return 0;
+ break;
+ case COPY: /* -> COPY */
+ if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+ == -1)
+ return -1;
+ state->x.next = state->out;
+ return 0;
+ case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
+ strm->avail_out = state->size << 1;
+ strm->next_out = state->out;
+ if (gz_decomp(state) == -1)
+ return -1;
+ }
+ } while (state->x.have == 0 && (!state->eof || strm->avail_in));
+ return 0;
+}
+
+/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ unsigned n;
+
+ /* skip over len bytes or reach end-of-file, whichever comes first */
+ while (len)
+ /* skip over whatever is in output buffer */
+ if (state->x.have) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+ (unsigned)len : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ len -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0)
+ break;
+
+ /* need more data to skip -- load up output buffer */
+ else {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/* Read len bytes into buf from file, or less than len up to the end of the
+ input. Return the number of bytes read. If zero is returned, either the
+ end of file was reached, or there was an error. state->err must be
+ consulted in that case to determine which. */
+local z_size_t gz_read(state, buf, len)
+ gz_statep state;
+ voidp buf;
+ z_size_t len;
+{
+ z_size_t got;
+ unsigned n;
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* get len bytes to buf, or less than len if at the end */
+ got = 0;
+ do {
+ /* set n to the maximum amount of len that fits in an unsigned int */
+ n = -1;
+ if (n > len)
+ n = len;
+
+ /* first just try copying data from the output buffer */
+ if (state->x.have) {
+ if (state->x.have < n)
+ n = state->x.have;
+ memcpy(buf, state->x.next, n);
+ state->x.next += n;
+ state->x.have -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0) {
+ state->past = 1; /* tried to read past end */
+ break;
+ }
+
+ /* need output data -- for small len or new stream load up our output
+ buffer */
+ else if (state->how == LOOK || n < (state->size << 1)) {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return 0;
+ continue; /* no progress yet -- go back to copy above */
+ /* the copy above assures that we will leave with space in the
+ output buffer, allowing at least one gzungetc() to succeed */
+ }
+
+ /* large len -- read directly into user buffer */
+ else if (state->how == COPY) { /* read directly */
+ if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
+ return 0;
+ }
+
+ /* large len -- decompress directly into user buffer */
+ else { /* state->how == GZIP */
+ state->strm.avail_out = n;
+ state->strm.next_out = (unsigned char *)buf;
+ if (gz_decomp(state) == -1)
+ return 0;
+ n = state->x.have;
+ state->x.have = 0;
+ }
+
+ /* update progress */
+ len -= n;
+ buf = (char *)buf + n;
+ got += n;
+ state->x.pos += n;
+ } while (len);
+
+ /* return number of bytes read into user buffer */
+ return got;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids a flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
+ return -1;
+ }
+
+ /* read len or fewer bytes to buf */
+ len = gz_read(state, buf, len);
+
+ /* check for an error */
+ if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* return the number of bytes read (this is assured to fit in an int) */
+ return (int)len;
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfread(buf, size, nitems, file)
+ voidp buf;
+ z_size_t size;
+ z_size_t nitems;
+ gzFile file;
+{
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return 0;
+
+ /* compute bytes to read -- error on overflow */
+ len = nitems * size;
+ if (size && len / size != nitems) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+ return 0;
+ }
+
+ /* read len or fewer bytes to buf, return the number of full items read */
+ return len ? gz_read(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+#else
+# undef gzgetc
+#endif
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ int ret;
+ unsigned char buf[1];
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* try output buffer (no need to check for skip request) */
+ if (state->x.have) {
+ state->x.have--;
+ state->x.pos++;
+ return *(state->x.next)++;
+ }
+
+ /* nothing there -- try gz_read() */
+ ret = gz_read(state, buf, 1);
+ return ret < 1 ? -1 : buf[0];
+}
+
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+ return gzgetc(file);
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* can't push EOF */
+ if (c < 0)
+ return -1;
+
+ /* if output buffer empty, put byte at end (allows more pushing) */
+ if (state->x.have == 0) {
+ state->x.have = 1;
+ state->x.next = state->out + (state->size << 1) - 1;
+ state->x.next[0] = (unsigned char)c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+ }
+
+ /* if no room, give up (must have already done a gzungetc()) */
+ if (state->x.have == (state->size << 1)) {
+ gz_error(state, Z_DATA_ERROR, "out of room to push characters");
+ return -1;
+ }
+
+ /* slide output data if needed and insert byte before existing data */
+ if (state->x.next == state->out) {
+ unsigned char *src = state->out + state->x.have;
+ unsigned char *dest = state->out + (state->size << 1);
+ while (src > state->out)
+ *--dest = *--src;
+ state->x.next = dest;
+ }
+ state->x.have++;
+ state->x.next--;
+ state->x.next[0] = (unsigned char)c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ unsigned left, n;
+ char *str;
+ unsigned char *eol;
+ gz_statep state;
+
+ /* check parameters and get internal structure */
+ if (file == NULL || buf == NULL || len < 1)
+ return NULL;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return NULL;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return NULL;
+ }
+
+ /* copy output bytes up to new line or len - 1, whichever comes first --
+ append a terminating zero to the string (we don't check for a zero in
+ the contents, let the user worry about that) */
+ str = buf;
+ left = (unsigned)len - 1;
+ if (left) do {
+ /* assure that something is in the output buffer */
+ if (state->x.have == 0 && gz_fetch(state) == -1)
+ return NULL; /* error */
+ if (state->x.have == 0) { /* end of file */
+ state->past = 1; /* read past end */
+ break; /* return what we have */
+ }
+
+ /* look for end-of-line in current output buffer */
+ n = state->x.have > left ? left : state->x.have;
+ eol = (unsigned char *)memchr(state->x.next, '\n', n);
+ if (eol != NULL)
+ n = (unsigned)(eol - state->x.next) + 1;
+
+ /* copy through end-of-line, or remainder if not found */
+ memcpy(buf, state->x.next, n);
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ left -= n;
+ buf += n;
+ } while (left && eol == NULL);
+
+ /* return terminated string, or if nothing, end of file */
+ if (buf == str)
+ return NULL;
+ buf[0] = 0;
+ return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* if the state is not known, but we can find out, then do so (this is
+ mainly for right after a gzopen() or gzdopen()) */
+ if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+ (void)gz_look(state);
+
+ /* return 1 if transparent, 0 if processing a gzip stream */
+ return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+ gzFile file;
+{
+ int ret, err;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're reading */
+ if (state->mode != GZ_READ)
+ return Z_STREAM_ERROR;
+
+ /* free memory and close file */
+ if (state->size) {
+ inflateEnd(&(state->strm));
+ free(state->out);
+ free(state->in);
+ }
+ err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ ret = close(state->fd);
+ free(state);
+ return ret ? Z_ERRNO : err;
+}
diff --git a/zlib/gzwrite.c b/zlib/gzwrite.c
new file mode 100644
index 000000000000..c7b5651d70b9
--- /dev/null
+++ b/zlib/gzwrite.c
@@ -0,0 +1,665 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
+
+/* Initialize state for writing a gzip file. Mark initialization by setting
+ state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
+ success. */
+local int gz_init(state)
+ gz_statep state;
+{
+ int ret;
+ z_streamp strm = &(state->strm);
+
+ /* allocate input buffer (double size for gzprintf) */
+ state->in = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* only need output buffer and deflate state if compressing */
+ if (!state->direct) {
+ /* allocate output buffer */
+ state->out = (unsigned char *)malloc(state->want);
+ if (state->out == NULL) {
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* allocate deflate memory, set up for gzip compression */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+ ret = deflateInit2(strm, state->level, Z_DEFLATED,
+ MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+ if (ret != Z_OK) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ strm->next_in = NULL;
+ }
+
+ /* mark state as initialized */
+ state->size = state->want;
+
+ /* initialize write buffer if compressing */
+ if (!state->direct) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = strm->next_out;
+ }
+ return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+ Return -1 if there is an error writing to the output file or if gz_init()
+ fails to allocate memory, otherwise 0. flush is assumed to be a valid
+ deflate() flush value. If flush is Z_FINISH, then the deflate() state is
+ reset to start a new gzip stream. If gz->direct is true, then simply write
+ to the output file without compressing, and ignore flush. */
+local int gz_comp(state, flush)
+ gz_statep state;
+ int flush;
+{
+ int ret, writ;
+ unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
+ z_streamp strm = &(state->strm);
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return -1;
+
+ /* write directly if requested */
+ if (state->direct) {
+ while (strm->avail_in) {
+ put = strm->avail_in > max ? max : strm->avail_in;
+ writ = write(state->fd, strm->next_in, put);
+ if (writ < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ strm->avail_in -= (unsigned)writ;
+ strm->next_in += writ;
+ }
+ return 0;
+ }
+
+ /* run deflate() on provided input until it produces no more output */
+ ret = Z_OK;
+ do {
+ /* write out current buffer contents if full, or if flushing, but if
+ doing Z_FINISH then don't write until we get to Z_STREAM_END */
+ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+ (flush != Z_FINISH || ret == Z_STREAM_END))) {
+ while (strm->next_out > state->x.next) {
+ put = strm->next_out - state->x.next > (int)max ? max :
+ (unsigned)(strm->next_out - state->x.next);
+ writ = write(state->fd, state->x.next, put);
+ if (writ < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ state->x.next += writ;
+ }
+ if (strm->avail_out == 0) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = state->out;
+ }
+ }
+
+ /* compress */
+ have = strm->avail_out;
+ ret = deflate(strm, flush);
+ if (ret == Z_STREAM_ERROR) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: deflate stream corrupt");
+ return -1;
+ }
+ have -= strm->avail_out;
+ } while (have);
+
+ /* if that completed a deflate stream, allow another to start */
+ if (flush == Z_FINISH)
+ deflateReset(strm);
+
+ /* all done, no errors */
+ return 0;
+}
+
+/* Compress len zeros to output. Return -1 on a write error or memory
+ allocation failure by gz_comp(), or 0 on success. */
+local int gz_zero(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ int first;
+ unsigned n;
+ z_streamp strm = &(state->strm);
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+
+ /* compress len zeros (len guaranteed > 0) */
+ first = 1;
+ while (len) {
+ n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+ (unsigned)len : state->size;
+ if (first) {
+ memset(state->in, 0, n);
+ first = 0;
+ }
+ strm->avail_in = n;
+ strm->next_in = state->in;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+ len -= n;
+ }
+ return 0;
+}
+
+/* Write len bytes from buf to file. Return the number of bytes written. If
+ the returned value is less than len, then there was an error. */
+local z_size_t gz_write(state, buf, len)
+ gz_statep state;
+ voidpc buf;
+ z_size_t len;
+{
+ z_size_t put = len;
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* for small len, copy to input buffer, otherwise compress directly */
+ if (len < state->size) {
+ /* copy to input buffer, compress when full */
+ do {
+ unsigned have, copy;
+
+ if (state->strm.avail_in == 0)
+ state->strm.next_in = state->in;
+ have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
+ state->in);
+ copy = state->size - have;
+ if (copy > len)
+ copy = len;
+ memcpy(state->in + have, buf, copy);
+ state->strm.avail_in += copy;
+ state->x.pos += copy;
+ buf = (const char *)buf + copy;
+ len -= copy;
+ if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ } while (len);
+ }
+ else {
+ /* consume whatever's left in the input buffer */
+ if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* directly compress user buffer to file */
+ state->strm.next_in = (z_const Bytef *)buf;
+ do {
+ unsigned n = (unsigned)-1;
+ if (n > len)
+ n = len;
+ state->strm.avail_in = n;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ len -= n;
+ } while (len);
+ }
+
+ /* input was all buffered or compressed */
+ return put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids a flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+ return 0;
+ }
+
+ /* write len bytes from buf (the return value will fit in an int) */
+ return (int)gz_write(state, buf, len);
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
+ voidpc buf;
+ z_size_t size;
+ z_size_t nitems;
+ gzFile file;
+{
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* compute bytes to read -- error on overflow */
+ len = nitems * size;
+ if (size && len / size != nitems) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+ return 0;
+ }
+
+ /* write len bytes to buf, return the number of full items written */
+ return len ? gz_write(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned have;
+ unsigned char buf[1];
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* try writing to input buffer for speed (state->size == 0 if buffer not
+ initialized) */
+ if (state->size) {
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ if (have < state->size) {
+ state->in[have] = (unsigned char)c;
+ strm->avail_in++;
+ state->x.pos++;
+ return c & 0xff;
+ }
+ }
+
+ /* no room in buffer or not initialized, use gz_write() */
+ buf[0] = (unsigned char)c;
+ if (gz_write(state, buf, 1) != 1)
+ return -1;
+ return c & 0xff;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+ gzFile file;
+ const char *str;
+{
+ int ret;
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* write string */
+ len = strlen(str);
+ ret = gz_write(state, str, len);
+ return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#include
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
+{
+ int len;
+ unsigned left;
+ char *next;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return state->err;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* do the printf() into the input buffer, put length in len -- the input
+ buffer is double-sized just for this function, so there is guaranteed to
+ be state->size bytes available after the current contents */
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
+ next[state->size - 1] = 0;
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(next, format, va);
+ for (len = 0; len < state->size; len++)
+ if (next[len] == 0) break;
+# else
+ len = vsprintf(next, format, va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(next, state->size, format, va);
+ len = strlen(next);
+# else
+ len = vsnprintf(next, state->size, format, va);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, compress first half if past that */
+ strm->avail_in += (unsigned)len;
+ state->x.pos += len;
+ if (strm->avail_in >= state->size) {
+ left = strm->avail_in - state->size;
+ strm->avail_in = state->size;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return state->err;
+ memcpy(state->in, state->in + state->size, left);
+ strm->next_in = state->in;
+ strm->avail_in = left;
+ }
+ return len;
+}
+
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+ va_list va;
+ int ret;
+
+ va_start(va, format);
+ ret = gzvprintf(file, format, va);
+ va_end(va);
+ return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ unsigned len, left;
+ char *next;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that can really pass pointer in ints */
+ if (sizeof(int) != sizeof(void *))
+ return Z_STREAM_ERROR;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return state->error;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->error;
+ }
+
+ /* do the printf() into the input buffer, put length in len -- the input
+ buffer is double-sized just for this function, so there is guaranteed to
+ be state->size bytes available after the current contents */
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ next = (char *)(strm->next_in + strm->avail_in);
+ next[state->size - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
+ a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < size; len++)
+ if (next[len] == 0)
+ break;
+# else
+ len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
+ a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(next);
+# else
+ len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len == 0 || len >= state->size || next[state->size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, compress first half if past that */
+ strm->avail_in += len;
+ state->x.pos += len;
+ if (strm->avail_in >= state->size) {
+ left = strm->avail_in - state->size;
+ strm->avail_in = state->size;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return state->err;
+ memcpy(state->in, state->in + state->size, left);
+ strm->next_in = state->in;
+ strm->avail_in = left;
+ }
+ return (int)len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* check flush parameter */
+ if (flush < 0 || flush > Z_FINISH)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* compress remaining data with requested flush */
+ (void)gz_comp(state, flush);
+ return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* if no change is requested, then do nothing */
+ if (level == state->level && strategy == state->strategy)
+ return Z_OK;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* change compression parameters for subsequent input */
+ if (state->size) {
+ /* flush previous input with previous parameters before changing */
+ if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
+ return state->err;
+ deflateParams(strm, level, strategy);
+ }
+ state->level = level;
+ state->strategy = strategy;
+ return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+ gzFile file;
+{
+ int ret = Z_OK;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing */
+ if (state->mode != GZ_WRITE)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ ret = state->err;
+ }
+
+ /* flush, free memory, and close file */
+ if (gz_comp(state, Z_FINISH) == -1)
+ ret = state->err;
+ if (state->size) {
+ if (!state->direct) {
+ (void)deflateEnd(&(state->strm));
+ free(state->out);
+ }
+ free(state->in);
+ }
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ if (close(state->fd) == -1)
+ ret = Z_ERRNO;
+ free(state);
+ return ret;
+}
diff --git a/zlib/infback.c b/zlib/infback.c
index 455dbc9ee843..59679ecbfc5d 100644
--- a/zlib/infback.c
+++ b/zlib/infback.c
@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -42,20 +42,29 @@ int stream_size;
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
+#endif
}
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->dmax = 32768U;
- state->wbits = windowBits;
+ state->wbits = (uInt)windowBits;
state->wsize = 1U << windowBits;
state->window = window;
- state->write = 0;
+ state->wnext = 0;
state->whave = 0;
return Z_OK;
}
@@ -246,14 +255,14 @@ out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
+ z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
+ code here; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
@@ -389,19 +398,18 @@ void FAR *out_desc;
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
}
else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
@@ -411,16 +419,16 @@ void FAR *out_desc;
copy = 3 + BITS(2);
DROPBITS(2);
}
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
@@ -438,7 +446,16 @@ void FAR *out_desc;
/* handle error breaks in while */
if (state->mode == BAD) break;
- /* build code tables */
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
@@ -474,28 +491,28 @@ void FAR *out_desc;
/* get a literal, length, or end-of-block code */
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->lencode[last.val +
+ here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
+ DROPBITS(here.bits);
+ state->length = (unsigned)here.val;
/* process literal */
- if (this.op == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
+ "inflate: literal 0x%02x\n", here.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
@@ -504,21 +521,21 @@ void FAR *out_desc;
}
/* process end of block */
- if (this.op & 32) {
+ if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
- if (this.op & 64) {
+ if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
+ state->extra = (unsigned)(here.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
@@ -528,30 +545,30 @@ void FAR *out_desc;
/* get distance code */
for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if ((this.op & 0xf0) == 0) {
- last = this;
+ if ((here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->distcode[last.val +
+ here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
- DROPBITS(this.bits);
- if (this.op & 64) {
+ DROPBITS(here.bits);
+ if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
- state->offset = (unsigned)this.val;
+ state->offset = (unsigned)here.val;
/* get distance extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
+ state->extra = (unsigned)(here.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
diff --git a/zlib/inffast.c b/zlib/inffast.c
index bbee92ed1e6b..0dbd1dbc09f2 100644
--- a/zlib/inffast.c
+++ b/zlib/inffast.c
@@ -1,5 +1,5 @@
/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,26 +8,9 @@
#include "inflate.h"
#include "inffast.h"
-#ifndef ASMINF
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
+#ifdef ASMINF
+# pragma message("Assembler code may have bugs -- use at your own risk")
#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
/*
Decode literal, length, and distance codes and write out the resulting
@@ -64,13 +47,13 @@
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
-void inflate_fast(strm, start)
+void ZLIB_INTERNAL inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
@@ -79,7 +62,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
+ unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
@@ -87,7 +70,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
+ code here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
@@ -96,9 +79,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
+ in = strm->next_in;
last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
+ out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
@@ -106,7 +89,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
#endif
wsize = state->wsize;
whave = state->whave;
- write = state->write;
+ wnext = state->wnext;
window = state->window;
hold = state->hold;
bits = state->bits;
@@ -119,29 +102,29 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
input data or output space */
do {
if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
- this = lcode[hold & lmask];
+ here = lcode[hold & lmask];
dolen:
- op = (unsigned)(this.bits);
+ op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
- op = (unsigned)(this.op);
+ op = (unsigned)(here.op);
if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
+ "inflate: literal 0x%02x\n", here.val));
+ *out++ = (unsigned char)(here.val);
}
else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
+ len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
@@ -150,25 +133,25 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
- this = dcode[hold & dmask];
+ here = dcode[hold & dmask];
dodist:
- op = (unsigned)(this.bits);
+ op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
- op = (unsigned)(this.op);
+ op = (unsigned)(here.op);
if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
+ dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
}
@@ -187,79 +170,101 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
+ if (state->sane) {
+ strm->msg =
+ (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (len <= op - whave) {
+ do {
+ *out++ = 0;
+ } while (--len);
+ continue;
+ }
+ len -= op - whave;
+ do {
+ *out++ = 0;
+ } while (--op > whave);
+ if (op == 0) {
+ from = out - dist;
+ do {
+ *out++ = *from++;
+ } while (--len);
+ continue;
+ }
+#endif
}
- from = window - OFF;
- if (write == 0) { /* very common case */
+ from = window;
+ if (wnext == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
if (op < len) { /* some from end of window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
+ from = window;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
- from += write - op;
+ from += wnext - op;
if (op < len) { /* some from window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
len -= 3;
}
if (len) {
- PUP(out) = PUP(from);
+ *out++ = *from++;
if (len > 1)
- PUP(out) = PUP(from);
+ *out++ = *from++;
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
len -= 3;
} while (len > 2);
if (len) {
- PUP(out) = PUP(from);
+ *out++ = *from++;
if (len > 1)
- PUP(out) = PUP(from);
+ *out++ = *from++;
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
@@ -269,7 +274,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
@@ -291,8 +296,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
hold &= (1U << bits) - 1;
/* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
+ strm->next_in = in;
+ strm->next_out = out;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
@@ -305,7 +310,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
+ - Three separate decoding do-loops for direct, window, and wnext == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
diff --git a/zlib/inffast.h b/zlib/inffast.h
index 1e88d2d97b56..e5c1aa4ca8cd 100644
--- a/zlib/inffast.h
+++ b/zlib/inffast.h
@@ -1,5 +1,5 @@
/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2003, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,4 +8,4 @@
subject to change. Applications should only use zlib.h.
*/
-void inflate_fast OF((z_streamp strm, unsigned start));
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/zlib/inffixed.h b/zlib/inffixed.h
index 75ed4b5978de..d62832776948 100644
--- a/zlib/inffixed.h
+++ b/zlib/inffixed.h
@@ -2,9 +2,9 @@
* Generated automatically by makefixed().
*/
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
diff --git a/zlib/inflate.c b/zlib/inflate.c
index 50830e2f7625..ac333e8c2eda 100644
--- a/zlib/inflate.c
+++ b/zlib/inflate.c
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -45,7 +45,7 @@
* - Rearrange window copies in inflate_fast() for speed and simplification
* - Unroll last copy for window match in inflate_fast()
* - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
* - Make op and len in inflate_fast() unsigned for consistency
* - Add FAR to lcode and dcode declarations in inflate_fast()
* - Simplified bad distance check in inflate_fast()
@@ -92,53 +92,104 @@
#endif
/* function prototypes */
+local int inflateStateCheck OF((z_streamp strm));
local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
#ifdef BUILDFIXED
void makefixed OF((void));
#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
unsigned len));
-int ZEXPORT inflateReset(strm)
+local int inflateStateCheck(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
+ if (strm == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+ return 1;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state == Z_NULL || state->strm != strm ||
+ state->mode < HEAD || state->mode > SYNC)
+ return 1;
+ return 0;
+}
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
+ if (state->wrap) /* to support ill-conceived Java test suite */
+ strm->adler = state->wrap & 1;
state->mode = HEAD;
state->last = 0;
state->havedict = 0;
state->dmax = 32768U;
state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->write = 0;
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
+ state->sane = 1;
+ state->back = -1;
Tracev((stderr, "inflate: reset\n"));
return Z_OK;
}
-int ZEXPORT inflatePrime(strm, bits, value)
+int ZEXPORT inflateReset(strm)
z_streamp strm;
-int bits;
-int value;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
+ state->wsize = 0;
+ state->whave = 0;
+ state->wnext = 0;
+ return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+ int wrap;
+ struct inflate_state FAR *state;
+
+ /* get the state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >> 4) + 5;
+#ifdef GUNZIP
+ if (windowBits < 48)
+ windowBits &= 15;
+#endif
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return Z_STREAM_ERROR;
+ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+ ZFREE(strm, state->window);
+ state->window = Z_NULL;
+ }
+
+ /* update state and reset the rest of it */
+ state->wrap = wrap;
+ state->wbits = (unsigned)windowBits;
+ return inflateReset(strm);
}
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
@@ -147,6 +198,7 @@ int windowBits;
const char *version;
int stream_size;
{
+ int ret;
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
@@ -155,33 +207,33 @@ int stream_size;
if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
+#endif
}
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
state = (struct inflate_state FAR *)
ZALLOC(strm, 1, sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
-#endif
- }
- if (windowBits < 8 || windowBits > 15) {
+ state->strm = strm;
+ state->window = Z_NULL;
+ state->mode = HEAD; /* to pass state test in inflateReset2() */
+ ret = inflateReset2(strm, windowBits);
+ if (ret != Z_OK) {
ZFREE(strm, state);
strm->state = Z_NULL;
- return Z_STREAM_ERROR;
}
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
+ return ret;
}
int ZEXPORT inflateInit_(strm, version, stream_size)
@@ -192,6 +244,27 @@ int stream_size;
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
}
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits < 0) {
+ state->hold = 0;
+ state->bits = 0;
+ return Z_OK;
+ }
+ if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += (unsigned)value << state->bits;
+ state->bits += (uInt)bits;
+ return Z_OK;
+}
+
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
@@ -286,8 +359,8 @@ void makefixed()
low = 0;
for (;;) {
if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
+ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+ state.lencode[low].bits, state.lencode[low].val);
if (++low == size) break;
putchar(',');
}
@@ -320,12 +393,13 @@ void makefixed()
output will fall in the output data, making match copies simpler and faster.
The advantage may be dependent on the size of the processor's data caches.
*/
-local int updatewindow(strm, out)
+local int updatewindow(strm, end, copy)
z_streamp strm;
-unsigned out;
+const Bytef *end;
+unsigned copy;
{
struct inflate_state FAR *state;
- unsigned copy, dist;
+ unsigned dist;
state = (struct inflate_state FAR *)strm->state;
@@ -340,30 +414,29 @@ unsigned out;
/* if window not in use yet, initialize */
if (state->wsize == 0) {
state->wsize = 1U << state->wbits;
- state->write = 0;
+ state->wnext = 0;
state->whave = 0;
}
/* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
+ zmemcpy(state->window, end - state->wsize, state->wsize);
+ state->wnext = 0;
state->whave = state->wsize;
}
else {
- dist = state->wsize - state->write;
+ dist = state->wsize - state->wnext;
if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ zmemcpy(state->window + state->wnext, end - copy, dist);
copy -= dist;
if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
+ zmemcpy(state->window, end - copy, copy);
+ state->wnext = copy;
state->whave = state->wsize;
}
else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
if (state->whave < state->wsize) state->whave += dist;
}
}
@@ -464,11 +537,6 @@ unsigned out;
bits -= bits & 7; \
} while (0)
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
/*
inflate() uses a state machine to process as much input data and generate as
much output data as possible before returning. The state machine is
@@ -556,7 +624,7 @@ z_streamp strm;
int flush;
{
struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
+ z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
@@ -564,7 +632,7 @@ int flush;
unsigned in, out; /* save starting available input and output */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
+ code here; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
@@ -574,12 +642,7 @@ int flush;
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
- /* XXXMYSQL: To assert that put is never used uninitialized */
-#ifdef DEBUG
- put = NULL;
-#endif /* DEBUG */
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
(strm->next_in == Z_NULL && strm->avail_in != 0))
return Z_STREAM_ERROR;
@@ -599,6 +662,8 @@ int flush;
NEEDBITS(16);
#ifdef GUNZIP
if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ if (state->wbits == 0)
+ state->wbits = 15;
state->check = crc32(0L, Z_NULL, 0);
CRC2(state->check, hold);
INITBITS();
@@ -624,7 +689,9 @@ int flush;
}
DROPBITS(4);
len = BITS(4) + 8;
- if (len > state->wbits) {
+ if (state->wbits == 0)
+ state->wbits = len;
+ if (len > 15 || len > state->wbits) {
strm->msg = (char *)"invalid window size";
state->mode = BAD;
break;
@@ -651,14 +718,16 @@ int flush;
}
if (state->head != Z_NULL)
state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
INITBITS();
state->mode = TIME;
case TIME:
NEEDBITS(32);
if (state->head != Z_NULL)
state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC4(state->check, hold);
INITBITS();
state->mode = OS;
case OS:
@@ -667,7 +736,8 @@ int flush;
state->head->xflags = (int)(hold & 0xff);
state->head->os = (int)(hold >> 8);
}
- if (state->flags & 0x0200) CRC2(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
INITBITS();
state->mode = EXLEN;
case EXLEN:
@@ -676,7 +746,8 @@ int flush;
state->length = (unsigned)(hold);
if (state->head != Z_NULL)
state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
INITBITS();
}
else if (state->head != Z_NULL)
@@ -694,7 +765,7 @@ int flush;
len + copy > state->head->extra_max ?
state->head->extra_max - len : copy);
}
- if (state->flags & 0x0200)
+ if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
@@ -713,9 +784,9 @@ int flush;
if (state->head != Z_NULL &&
state->head->name != Z_NULL &&
state->length < state->head->name_max)
- state->head->name[state->length++] = len;
+ state->head->name[state->length++] = (Bytef)len;
} while (len && copy < have);
- if (state->flags & 0x0200)
+ if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
@@ -734,9 +805,9 @@ int flush;
if (state->head != Z_NULL &&
state->head->comment != Z_NULL &&
state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
+ state->head->comment[state->length++] = (Bytef)len;
} while (len && copy < have);
- if (state->flags & 0x0200)
+ if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
@@ -748,7 +819,7 @@ int flush;
case HCRC:
if (state->flags & 0x0200) {
NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
+ if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
strm->msg = (char *)"header crc mismatch";
state->mode = BAD;
break;
@@ -765,7 +836,7 @@ int flush;
#endif
case DICTID:
NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
+ strm->adler = state->check = ZSWAP32(hold);
INITBITS();
state->mode = DICT;
case DICT:
@@ -776,7 +847,7 @@ int flush;
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = TYPE;
case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
+ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
case TYPEDO:
if (state->last) {
BYTEBITS();
@@ -796,7 +867,11 @@ int flush;
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
+ state->mode = LEN_; /* decode codes */
+ if (flush == Z_TREES) {
+ DROPBITS(2);
+ goto inf_leave;
+ }
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
@@ -821,6 +896,9 @@ int flush;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
+ state->mode = COPY_;
+ if (flush == Z_TREES) goto inf_leave;
+ case COPY_:
state->mode = COPY;
case COPY:
copy = state->length;
@@ -828,8 +906,6 @@ int flush;
if (copy > have) copy = have;
if (copy > left) copy = left;
if (copy == 0) goto inf_leave;
- /* XXXMYSQL: Assert that put is not uninitialized */
- Assert ( put != NULL, "put is uninitialized" );
zmemcpy(put, next, copy);
have -= copy;
next += copy;
@@ -868,7 +944,7 @@ int flush;
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
+ state->lencode = (const code FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
@@ -883,19 +959,18 @@ int flush;
case CODELENS:
while (state->have < state->nlen + state->ndist) {
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
}
else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
@@ -905,16 +980,16 @@ int flush;
copy = 3 + BITS(2);
DROPBITS(2);
}
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
@@ -932,9 +1007,18 @@ int flush;
/* handle error breaks in while */
if (state->mode == BAD) break;
- /* build code tables */
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
+ state->lencode = (const code FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
@@ -943,7 +1027,7 @@ int flush;
state->mode = BAD;
break;
}
- state->distcode = (code const FAR *)(state->next);
+ state->distcode = (const code FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
@@ -953,88 +1037,102 @@ int flush;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN_;
+ if (flush == Z_TREES) goto inf_leave;
+ case LEN_:
state->mode = LEN;
case LEN:
if (have >= 6 && left >= 258) {
RESTORE();
inflate_fast(strm, out);
LOAD();
+ if (state->mode == TYPE)
+ state->back = -1;
break;
}
+ state->back = 0;
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->lencode[last.val +
+ here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
+ state->back += last.bits;
}
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
- if ((int)(this.op) == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ state->length = (unsigned)here.val;
+ if ((int)(here.op) == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
+ "inflate: literal 0x%02x\n", here.val));
state->mode = LIT;
break;
}
- if (this.op & 32) {
+ if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
+ state->back = -1;
state->mode = TYPE;
break;
}
- if (this.op & 64) {
+ if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
- state->extra = (unsigned)(this.op) & 15;
+ state->extra = (unsigned)(here.op) & 15;
state->mode = LENEXT;
case LENEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
+ state->back += state->extra;
}
Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->was = state->length;
state->mode = DIST;
case DIST:
for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if ((this.op & 0xf0) == 0) {
- last = this;
+ if ((here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->distcode[last.val +
+ here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
+ state->back += last.bits;
}
- DROPBITS(this.bits);
- if (this.op & 64) {
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
- state->offset = (unsigned)this.val;
- state->extra = (unsigned)(this.op) & 15;
+ state->offset = (unsigned)here.val;
+ state->extra = (unsigned)(here.op) & 15;
state->mode = DISTEXT;
case DISTEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
+ state->back += state->extra;
}
#ifdef INFLATE_STRICT
if (state->offset > state->dmax) {
@@ -1043,11 +1141,6 @@ int flush;
break;
}
#endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
Tracevv((stderr, "inflate: distance %u\n", state->offset));
state->mode = MATCH;
case MATCH:
@@ -1055,17 +1148,35 @@ int flush;
copy = out - left;
if (state->offset > copy) { /* copy from window */
copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
+ if (copy > state->whave) {
+ if (state->sane) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ Trace((stderr, "inflate.c too far\n"));
+ copy -= state->whave;
+ if (copy > state->length) copy = state->length;
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = 0;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+#endif
+ }
+ if (copy > state->wnext) {
+ copy -= state->wnext;
from = state->window + (state->wsize - copy);
}
else
- from = state->window + (state->write - copy);
+ from = state->window + (state->wnext - copy);
if (copy > state->length) copy = state->length;
}
else { /* copy from output */
- /* XXXMYSQL: Assert that put is not uninitialized */
- Assert ( put != NULL, "put is uninitialized" );
from = put - state->offset;
copy = state->length;
}
@@ -1089,18 +1200,15 @@ int flush;
out -= left;
strm->total_out += out;
state->total += out;
- if (out) {
- /* XXXMYSQL: Assert that put is not uninitialized */
- Assert ( put != NULL, "put is uninitialized" );
+ if ((state->wrap & 4) && out)
strm->adler = state->check =
UPDATE(state->check, put - out, out);
- }
out = left;
- if ((
+ if ((state->wrap & 4) && (
#ifdef GUNZIP
state->flags ? hold :
#endif
- REVERSE(hold)) != state->check) {
+ ZSWAP32(hold)) != state->check) {
strm->msg = (char *)"incorrect data check";
state->mode = BAD;
break;
@@ -1144,8 +1252,9 @@ int flush;
*/
inf_leave:
RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
+ if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+ (state->mode < CHECK || flush != Z_FINISH)))
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
state->mode = MEM;
return Z_MEM_ERROR;
}
@@ -1154,11 +1263,12 @@ int flush;
strm->total_in += in;
strm->total_out += out;
state->total += out;
- if (state->wrap && out)
+ if ((state->wrap & 4) && out)
strm->adler = state->check =
UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
+ strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0) +
+ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
ret = Z_BUF_ERROR;
return ret;
@@ -1168,7 +1278,7 @@ int ZEXPORT inflateEnd(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ if (inflateStateCheck(strm))
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->window != Z_NULL) ZFREE(strm, state->window);
@@ -1178,43 +1288,59 @@ z_streamp strm;
return Z_OK;
}
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* copy dictionary */
+ if (state->whave && dictionary != Z_NULL) {
+ zmemcpy(dictionary, state->window + state->wnext,
+ state->whave - state->wnext);
+ zmemcpy(dictionary + state->whave - state->wnext,
+ state->window, state->wnext);
+ }
+ if (dictLength != Z_NULL)
+ *dictLength = state->whave;
+ return Z_OK;
+}
+
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
struct inflate_state FAR *state;
- unsigned long id;
+ unsigned long dictid;
+ int ret;
/* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->wrap != 0 && state->mode != DICT)
return Z_STREAM_ERROR;
- /* check for correct dictionary id */
+ /* check for correct dictionary identifier */
if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
+ dictid = adler32(0L, Z_NULL, 0);
+ dictid = adler32(dictid, dictionary, dictLength);
+ if (dictid != state->check)
return Z_DATA_ERROR;
}
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
+ /* copy dictionary to window using updatewindow(), which will amend the
+ existing dictionary if appropriate */
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
+ if (ret) {
state->mode = MEM;
return Z_MEM_ERROR;
}
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
state->havedict = 1;
Tracev((stderr, "inflate: dictionary set\n"));
return Z_OK;
@@ -1227,7 +1353,7 @@ gz_headerp head;
struct inflate_state FAR *state;
/* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
@@ -1250,7 +1376,7 @@ gz_headerp head;
*/
local unsigned syncsearch(have, buf, len)
unsigned FAR *have;
-unsigned char FAR *buf;
+const unsigned char FAR *buf;
unsigned len;
{
unsigned got;
@@ -1280,7 +1406,7 @@ z_streamp strm;
struct inflate_state FAR *state;
/* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
@@ -1327,7 +1453,7 @@ z_streamp strm;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
return state->mode == STORED && state->bits == 0;
}
@@ -1342,8 +1468,7 @@ z_streamp source;
unsigned wsize;
/* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ if (inflateStateCheck(source) || dest == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)source->state;
@@ -1362,8 +1487,9 @@ z_streamp source;
}
/* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+ copy->strm = dest;
if (state->lencode >= state->codes &&
state->lencode <= state->codes + ENOUGH - 1) {
copy->lencode = copy->codes + (state->lencode - state->codes);
@@ -1378,3 +1504,58 @@ z_streamp source;
dest->state = (struct internal_state FAR *)copy;
return Z_OK;
}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ state->sane = !subvert;
+ return Z_OK;
+#else
+ (void)subvert;
+ state->sane = 1;
+ return Z_DATA_ERROR;
+#endif
+}
+
+int ZEXPORT inflateValidate(strm, check)
+z_streamp strm;
+int check;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (check)
+ state->wrap |= 4;
+ else
+ state->wrap &= ~4;
+ return Z_OK;
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm))
+ return -(1L << 16);
+ state = (struct inflate_state FAR *)strm->state;
+ return (long)(((unsigned long)((long)state->back)) << 16) +
+ (state->mode == COPY ? state->length :
+ (state->mode == MATCH ? state->was - state->length : 0));
+}
+
+unsigned long ZEXPORT inflateCodesUsed(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (inflateStateCheck(strm)) return (unsigned long)-1;
+ state = (struct inflate_state FAR *)strm->state;
+ return (unsigned long)(state->next - state->codes);
+}
diff --git a/zlib/inflate.h b/zlib/inflate.h
index 07bd3e78a7c7..a46cce6b6d05 100644
--- a/zlib/inflate.h
+++ b/zlib/inflate.h
@@ -1,5 +1,5 @@
/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -18,7 +18,7 @@
/* Possible inflate modes between inflate() calls */
typedef enum {
- HEAD, /* i: waiting for magic header */
+ HEAD = 16180, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
@@ -32,11 +32,13 @@ typedef enum {
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
+ COPY_, /* i/o: same as COPY below, but only first time in */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
+ LEN_, /* i: same as LEN below, but only first time in */
+ LEN, /* i: waiting for length/lit/eob code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
@@ -53,19 +55,21 @@ typedef enum {
/*
State transitions between above modes -
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
+ (most modes can go to BAD or MEM on error -- not shown for clarity)
Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
+ HEAD -> (gzip) or (zlib) or (raw)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+ HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
+ (raw) -> TYPEDO
Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
+ TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+ STORED -> COPY_ -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN_
+ LEN_ -> LEN
+ Read deflate codes in fixed or dynamic block:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
@@ -73,11 +77,14 @@ typedef enum {
CHECK -> LENGTH -> DONE
*/
-/* state maintained between inflate() calls. Approximately 7K bytes. */
+/* State maintained between inflate() calls -- approximately 7K bytes, not
+ including the allocated sliding window, which is up to 32K bytes. */
struct inflate_state {
+ z_streamp strm; /* pointer back to this zlib stream */
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
+ bit 2 true to validate check value */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
@@ -88,7 +95,7 @@ struct inflate_state {
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
+ unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
@@ -112,4 +119,7 @@ struct inflate_state {
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
+ int sane; /* if false, allow invalid distance too far */
+ int back; /* bits back of last unprocessed length/lit */
+ unsigned was; /* initial length of match */
};
diff --git a/zlib/inftrees.c b/zlib/inftrees.c
index 8a9c13ff03d8..2ea08fc13ea8 100644
--- a/zlib/inftrees.c
+++ b/zlib/inftrees.c
@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
+ " inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -29,7 +29,7 @@ const char inflate_copyright[] =
table index bits. It will differ if the request is greater than the
longest code or if it is less than the shortest code.
*/
-int inflate_table(type, lens, codes, table, bits, work)
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
codetype type;
unsigned short FAR *lens;
unsigned codes;
@@ -50,11 +50,11 @@ unsigned short FAR *work;
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
+ code here; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
+ unsigned match; /* use base and extra for symbol >= match */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -115,15 +115,15 @@ unsigned short FAR *work;
if (count[max] != 0) break;
if (root > max) root = max;
if (max == 0) { /* no symbols to code at all */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)1;
- this.val = (unsigned short)0;
- *(*table)++ = this; /* make a table to force an error */
- *(*table)++ = this;
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)1;
+ here.val = (unsigned short)0;
+ *(*table)++ = here; /* make a table to force an error */
+ *(*table)++ = here;
*bits = 1;
return 0; /* no symbols, but wait for decoding to report error */
}
- for (min = 1; min <= MAXBITS; min++)
+ for (min = 1; min < max; min++)
if (count[min] != 0) break;
if (root < min) root = min;
@@ -166,11 +166,10 @@ unsigned short FAR *work;
entered in the tables.
used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
sym increments through all symbols, and the loop terminates when
all codes of length max, i.e. all codes, have been processed. This
@@ -182,19 +181,17 @@ unsigned short FAR *work;
switch (type) {
case CODES:
base = extra = work; /* dummy value--not used */
- end = 19;
+ match = 20;
break;
case LENS:
base = lbase;
- base -= 257;
extra = lext;
- extra -= 257;
- end = 256;
+ match = 257;
break;
- default: /* DISTS */
+ default: /* DISTS */
base = dbase;
extra = dext;
- end = -1;
+ match = 0;
}
/* initialize state for loop */
@@ -209,24 +206,25 @@ unsigned short FAR *work;
mask = used - 1; /* mask for comparing low */
/* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
- this.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
+ here.bits = (unsigned char)(len - drop);
+ if (work[sym] + 1U < match) {
+ here.op = (unsigned char)0;
+ here.val = work[sym];
}
- else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
+ else if (work[sym] >= match) {
+ here.op = (unsigned char)(extra[work[sym] - match]);
+ here.val = base[work[sym] - match];
}
else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
+ here.op = (unsigned char)(32 + 64); /* end of block */
+ here.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
@@ -235,7 +233,7 @@ unsigned short FAR *work;
min = fill; /* save offset to next table */
do {
fill -= incr;
- next[(huff >> drop) + fill] = this;
+ next[(huff >> drop) + fill] = here;
} while (fill != 0);
/* backwards increment the len-bit code huff */
@@ -277,7 +275,8 @@ unsigned short FAR *work;
/* check for enough space */
used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
return 1;
/* point entry in root table to sub-table */
@@ -288,38 +287,14 @@ unsigned short FAR *work;
}
}
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- this.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = this;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
+ next[huff] = here;
}
/* set return parameters */
diff --git a/zlib/inftrees.h b/zlib/inftrees.h
index b1104c87e769..baa53a0b1a19 100644
--- a/zlib/inftrees.h
+++ b/zlib/inftrees.h
@@ -1,5 +1,5 @@
/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2005, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -35,21 +35,28 @@ typedef struct {
01000000 - invalid code
*/
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
-/* Type of code to build for inftable() */
+/* Type of code to build for inflate_table() */
typedef enum {
CODES,
LENS,
DISTS
} codetype;
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));
diff --git a/zlib/make_vms.com b/zlib/make_vms.com
new file mode 100644
index 000000000000..65e9d0cbc8e1
--- /dev/null
+++ b/zlib/make_vms.com
@@ -0,0 +1,867 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$!
+$! In case of problems with the install you might contact me at
+$! zinser@zinser.no-ip.info(preferred) or
+$! martin.zinser@eurexchange.com (work)
+$!
+$! Make procedure history for Zlib
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20060120 First version to receive a number
+$! 0.02 20061008 Adapt to new Makefile.in
+$! 0.03 20091224 Add support for large file check
+$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
+$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
+$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
+$! subdir path, update module search in makefile.in
+$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
+$! shared image creation
+$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
+$! image
+$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)).
+$! "" -> automatic, preference: MMK, MMS, built-in.
+$!
+$ on error then goto err_exit
+$!
+$ true = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ tt = tmpnam + ".txt"
+$ tc = tmpnam + ".c"
+$ th = tmpnam + ".h"
+$ define/nolog tconfig 'th'
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ s_case = False
+$!
+$! Setup variables holding "config" information
+$!
+$ Make = "''p1'"
+$ name = "Zlib"
+$ version = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file = "zlib.h"
+$ ccopt = "/include = []"
+$ lopts = ""
+$ dnsrl = ""
+$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in"
+$ conf_check_string = ""
+$ linkonly = false
+$ optfile = name + ".opt"
+$ mapfile = name + ".map"
+$ libdefs = ""
+$ vax = f$getsyi("HW_MODEL").lt.1024
+$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
+$ ia64 = f$getsyi("HW_MODEL").ge.4096
+$!
+$! 2012-03-05 SMS.
+$! Why is this needed? And if it is needed, why not simply ".not. vax"?
+$!
+$!!! if axp .or. ia64 then set proc/parse=extended
+$!
+$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL")
+$ mydef = F$parse(whoami,,,"DEVICE")
+$ mydir = f$parse(whoami,,,"DIRECTORY") - "]["
+$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
+$!
+$! Check for MMK/MMS
+$!
+$ if (Make .eqs. "")
+$ then
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$ else
+$ Make = f$edit( Make, "trim")
+$ endif
+$!
+$ gosub find_version
+$!
+$ open/write topt tmp.opt
+$ open/write optf 'optfile'
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ close topt
+$ close optf
+$!
+$ if its_decc
+$ then
+$ ccopt = "/prefix=all" + ccopt
+$ if f$trnlnm("SYS") .eqs. ""
+$ then
+$ if axp
+$ then
+$ define sys sys$library:
+$ else
+$ ccopt = "/decc" + ccopt
+$ define sys decc$library_include:
+$ endif
+$ endif
+$!
+$! 2012-03-05 SMS.
+$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX?
+$!
+$ if axp .or. ia64
+$ then
+$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)"
+$ s_case = true
+$ endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build a fake configure input header
+$!
+$ open/write conf_hin config.hin
+$ write conf_hin "#undef _LARGEFILE64_SOURCE"
+$ close conf_hin
+$!
+$!
+$ i = 0
+$FIND_ACONF:
+$ fname = f$element(i,"#",aconf_in_file)
+$ if fname .eqs. "#" then goto AMISS_ERR
+$ if f$search(fname) .eqs. ""
+$ then
+$ i = i + 1
+$ goto find_aconf
+$ endif
+$ open/read/err=aconf_err aconf_in 'fname'
+$ open/write aconf zconf.h
+$ACONF_LOOP:
+$ read/end_of_file=aconf_exit aconf_in line
+$ work = f$edit(line, "compress,trim")
+$ if f$extract(0,6,work) .nes. "#undef"
+$ then
+$ if f$extract(0,12,work) .nes. "#cmakedefine"
+$ then
+$ write aconf line
+$ endif
+$ else
+$ cdef = f$element(1," ",work)
+$ gosub check_config
+$ endif
+$ goto aconf_loop
+$ACONF_EXIT:
+$ write aconf ""
+$ write aconf "/* VMS specifics added by make_vms.com: */"
+$ write aconf "#define VMS 1"
+$ write aconf "#include "
+$ write aconf "#include "
+$ write aconf "#ifdef _LARGEFILE"
+$ write aconf "# define off64_t __off64_t"
+$ write aconf "# define fopen64 fopen"
+$ write aconf "# define fseeko64 fseeko"
+$ write aconf "# define lseek64 lseek"
+$ write aconf "# define ftello64 ftell"
+$ write aconf "#endif"
+$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)"
+$ write aconf "# define HAVE_VSNPRINTF"
+$ write aconf "#endif"
+$ close aconf_in
+$ close aconf
+$ if f$search("''th'") .nes. "" then delete 'th';*
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$ then
+$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;*
+$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;*
+$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+ adler32.c zlib.h zconf.h
+$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+ compress.c zlib.h zconf.h
+$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+ crc32.c zlib.h zconf.h
+$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+ deflate.c deflate.h zutil.h zlib.h zconf.h
+$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" -
+ gzclose.c zutil.h zlib.h zconf.h
+$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" -
+ gzlib.c zutil.h zlib.h zconf.h
+$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" -
+ gzread.c zutil.h zlib.h zconf.h
+$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" -
+ gzwrite.c zutil.h zlib.h zconf.h
+$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+ infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+ inffast.c zutil.h zlib.h zconf.h inffast.h
+$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+ inflate.c zutil.h zlib.h zconf.h infblock.h
+$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+ inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+ trees.c deflate.h zutil.h zlib.h zconf.h
+$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+ uncompr.c zlib.h zconf.h
+$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+ zutil.c zutil.h zlib.h zconf.h
+$ write sys$output "Building Zlib ..."
+$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$ write sys$output "Building example..."
+$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" -
+ [.test]example.c zlib.h zconf.h
+$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$ write sys$output "Building minigzip..."
+$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" -
+ [.test]minigzip.c zlib.h zconf.h
+$ call make minigzip.exe -
+ "LINK minigzip,libz.olb/lib" -
+ minigzip.obj libz.olb
+$ else
+$ gosub crea_mms
+$ write sys$output "Make ''name' ''version' with ''Make' "
+$ 'make'
+$ endif
+$!
+$! Create shareable image
+$!
+$ gosub crea_olist
+$ write sys$output "Creating libzshr.exe"
+$ call map_2_shopt 'mapfile' 'optfile'
+$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt
+$ write sys$output "Zlib build completed"
+$ delete/nolog tmp.opt;*
+$ exit
+$AMISS_ERR:
+$ write sys$output "No source for config.hin found."
+$ write sys$output "Tried any of ''aconf_in_file'"
+$ goto err_exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ close/nolog optf
+$ close/nolog topt
+$ close/nolog aconf_in
+$ close/nolog aconf
+$ close/nolog out
+$ close/nolog min
+$ close/nolog mod
+$ close/nolog h_in
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8 What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$ Argument = P'arg
+$ If Argument .Eqs. "" Then Goto Exit
+$ El=0
+$Loop2:
+$ File = F$Element(El," ",Argument)
+$ If File .Eqs. " " Then Goto Endl
+$ AFile = ""
+$Loop3:
+$ OFile = AFile
+$ AFile = F$Search(File)
+$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$ Goto Loop3
+$NextEL:
+$ El = El + 1
+$ Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20041206 First version to receive a number
+$! 0.02 20060126 Add new "HELP" target
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$ cparm = f$edit(p'i',"upcase")
+$!
+$! Check if parameter actually contains something
+$!
+$ if f$edit(cparm,"trim") .nes. ""
+$ then
+$ if cparm .eqs. "DEBUG"
+$ then
+$ ccopt = ccopt + "/noopt/deb"
+$ lopts = lopts + "/deb"
+$ endif
+$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ ccopt = ccopt + f$extract(start,len,cparm)
+$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+ then s_case = true
+$ endif
+$ if cparm .eqs. "LINK" then linkonly = true
+$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ lopts = lopts + f$extract(start,len,cparm)
+$ endif
+$ if f$locate("CC=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ cc_com = f$extract(start,len,cparm)
+ if (cc_com .nes. "DECC") .and. -
+ (cc_com .nes. "VAXC") .and. -
+ (cc_com .nes. "GNUC")
+$ then
+$ write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$ write sys$output "Use DECC, VAXC, or GNUC instead"
+$ else
+$ if cc_com .eqs. "DECC" then its_decc = true
+$ if cc_com .eqs. "VAXC" then its_vaxc = true
+$ if cc_com .eqs. "GNUC" then its_gnuc = true
+$ endif
+$ endif
+$ if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ mmks = f$extract(start,len,cparm)
+$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$ then
+$ make = mmks
+$ else
+$ write sys$output "Unsupported make choice ''mmks' ignored"
+$ write sys$output "Use MMK or MMS instead"
+$ endif
+$ endif
+$ if cparm .eqs. "HELP" then gosub bhelp
+$ endif
+$ i = i + 1
+$ goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$! Version history
+$! 0.01 20040223 First version to receive a number
+$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists
+$! 0.03 20060202 Extend handling of GNU C
+$! 0.04 20090402 Compaq -> hp
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$ if its_decc
+$ then
+$ write sys$output "CC compiler check ... hp C"
+$ if f$trnlnm("decc$no_rooted_search_lists") .nes. ""
+$ then
+$ dnrsl = f$trnlnm("decc$no_rooted_search_lists")
+$ endif
+$ define/nolog decc$no_rooted_search_lists 1
+$ else
+$ if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$ if its_gnuc
+$ then
+$ write sys$output "CC compiler check ... GNU C"
+$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib"
+$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib"
+$ cc = "gcc"
+$ endif
+$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share"
+$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share"
+$ endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+#
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
+ gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
+ deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+ inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ write out "all : example.exe minigzip.exe libz.olb"
+$ copy sys$input: out
+$ deck
+ @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+ @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+ link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+ link $(LOPTS) minigzip,libz.olb/lib
+
+clean :
+ delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj : crc32.c zutil.h zlib.h zconf.h
+deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj : [.test]example.c zlib.h zconf.h
+gzclose.obj : gzclose.c zutil.h zlib.h zconf.h
+gzlib.obj : gzlib.c zutil.h zlib.h zconf.h
+gzread.obj : gzread.c zutil.h zlib.h zconf.h
+gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h
+inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : [.test]minigzip.c zlib.h zconf.h
+trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : uncompr.c zlib.h zconf.h
+zutil.obj : zutil.c zutil.h zlib.h zconf.h
+infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check_list = "OBJZ =#OBJG ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ i = 0
+$SRC_CHECK_LOOP:
+$ src_check = f$element(i, "#", src_check_list)
+$ i = i+1
+$ if src_check .eqs. "#" then goto mrloop
+$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$ write mod f$parse(srcfil,,,"NAME"), ".obj"
+$ i = i + 1
+$ goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$ version = 'f$element(2," ",rec)'
+$ goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$CHECK_CONFIG:
+$!
+$ in_ldef = f$locate(cdef,libdefs)
+$ if (in_ldef .lt. f$length(libdefs))
+$ then
+$ write aconf "#define ''cdef' 1"
+$ libdefs = f$extract(0,in_ldef,libdefs) + -
+ f$extract(in_ldef + f$length(cdef) + 1, -
+ f$length(libdefs) - in_ldef - f$length(cdef) - 1, -
+ libdefs)
+$ else
+$ if (f$type('cdef') .eqs. "INTEGER")
+$ then
+$ write aconf "#define ''cdef' ", 'cdef'
+$ else
+$ if (f$type('cdef') .eqs. "STRING")
+$ then
+$ write aconf "#define ''cdef' ", """", '''cdef'', """"
+$ else
+$ gosub check_cc_def
+$ endif
+$ endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check if this is a define relating to the properties of the C/C++
+$! compiler
+$!
+$ CHECK_CC_DEF:
+$ if (cdef .eqs. "_LARGEFILE64_SOURCE")
+$ then
+$ copy sys$input: 'tc'
+$ deck
+#include "tconfig"
+#define _LARGEFILE
+#include
+
+int main(){
+FILE *fp;
+ fp = fopen("temp.txt","r");
+ fseeko(fp,1,SEEK_SET);
+ fclose(fp);
+}
+
+$ eod
+$ test_inv = false
+$ comm_h = false
+$ gosub cc_prop_check
+$ return
+$ endif
+$ write aconf "/* ", line, " */"
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler
+$!
+$! Version history
+$! 0.01 20031020 First version to receive a number
+$! 0.02 20031022 Added logic for defines with value
+$! 0.03 20040309 Make sure local config file gets not deleted
+$! 0.04 20041230 Also write include for configure run
+$! 0.05 20050103 Add processing of "comment defines"
+$CC_PROP_CHECK:
+$ cc_prop = true
+$ is_need = false
+$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true)
+$ if f$search(th) .eqs. "" then create 'th'
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'
+$ if .not. ($status) then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam',tmp.opt/opt
+$ if .not. ($status) then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'.*;*/exclude='th'
+$ if (cc_prop .and. .not. is_need) .or. -
+ (.not. cc_prop .and. is_need)
+$ then
+$ write sys$output "Checking for ''cdef'... yes"
+$ if f$type('cdef_val'_yes) .nes. ""
+$ then
+$ if f$type('cdef_val'_yes) .eqs. "INTEGER" -
+ then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes)
+$ if f$type('cdef_val'_yes) .eqs. "STRING" -
+ then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes)
+$ else
+$ call write_config f$fao("#define !AS 1",cdef)
+$ endif
+$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. -
+ (cdef .eqs. "_LARGEFILE64_SOURCE") then -
+ call write_config f$string("#define _LARGEFILE 1")
+$ else
+$ write sys$output "Checking for ''cdef'... no"
+$ if (comm_h)
+$ then
+ call write_config f$fao("/* !AS */",line)
+$ else
+$ if f$type('cdef_val'_no) .nes. ""
+$ then
+$ if f$type('cdef_val'_no) .eqs. "INTEGER" -
+ then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no)
+$ if f$type('cdef_val'_no) .eqs. "STRING" -
+ then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no)
+$ else
+$ call write_config f$fao("#undef !AS",cdef)
+$ endif
+$ endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler with multiple result values
+$!
+$! Version history
+$! 0.01 20040127 First version
+$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05
+$CC_MPROP_CHECK:
+$ cc_prop = true
+$ i = 1
+$ idel = 1
+$ MT_LOOP:
+$ if f$type(result_'i') .eqs. "STRING"
+$ then
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'_'i'
+$ if .not. ($status) then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam'_'i',tmp.opt/opt
+$ if .not. ($status) then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'_'i'.*;*
+$ if (cc_prop)
+$ then
+$ write sys$output "Checking for ''cdef'... ", mdef_'i'
+$ if f$type(mdef_'i') .eqs. "INTEGER" -
+ then call write_config f$fao("#define !AS !UL",cdef,mdef_'i')
+$ if f$type('cdef_val'_yes) .eqs. "STRING" -
+ then call write_config f$fao("#define !AS !AS",cdef,mdef_'i')
+$ goto msym_clean
+$ else
+$ i = i + 1
+$ goto mt_loop
+$ endif
+$ endif
+$ write sys$output "Checking for ''cdef'... no"
+$ call write_config f$fao("#undef !AS",cdef)
+$ MSYM_CLEAN:
+$ if (idel .le. msym_max)
+$ then
+$ delete/sym mdef_'idel'
+$ idel = idel + 1
+$ goto msym_clean
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Write configuration to both permanent and temporary config file
+$!
+$! Version history
+$! 0.01 20031029 First version to receive a number
+$!
+$WRITE_CONFIG: SUBROUTINE
+$ write aconf 'p1'
+$ open/append confh 'th'
+$ write confh 'p1'
+$ close confh
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Analyze the project map file and create the symbol vector for a shareable
+$! image from it
+$!
+$! Version history
+$! 0.01 20120128 First version
+$! 0.02 20120226 Add pre-load logic
+$!
+$ MAP_2_SHOPT: Subroutine
+$!
+$ SAY := "WRITE_ SYS$OUTPUT"
+$!
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available"
+$ goto exit_m2s
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$ SAY "MAP_2_SHOPT: Error, no output file provided"
+$ goto exit_m2s
+$ ENDIF
+$!
+$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary"
+$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread"
+$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary"
+$ module4 = "inflateSync#uncompress#zlibVersion#compress"
+$ open/read map 'p1
+$ if axp .or. ia64
+$ then
+$ open/write aopt a.opt
+$ open/write bopt b.opt
+$ write aopt " CASE_SENSITIVE=YES"
+$ write bopt "SYMBOL_VECTOR= (-"
+$ mod_sym_num = 1
+$ MOD_SYM_LOOP:
+$ if f$type(module'mod_sym_num') .nes. ""
+$ then
+$ mod_in = 0
+$ MOD_SYM_IN:
+$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$ if shared_proc .nes. "#"
+$ then
+$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+ f$edit(shared_proc,"upcase"),shared_proc)
+$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$ mod_in = mod_in + 1
+$ goto mod_sym_in
+$ endif
+$ mod_sym_num = mod_sym_num + 1
+$ goto mod_sym_loop
+$ endif
+$MAP_LOOP:
+$ read/end=map_end map line
+$ if (f$locate("{",line).lt. f$length(line)) .or. -
+ (f$locate("global:", line) .lt. f$length(line))
+$ then
+$ proc = true
+$ goto map_loop
+$ endif
+$ if f$locate("}",line).lt. f$length(line) then proc = false
+$ if f$locate("local:", line) .lt. f$length(line) then proc = false
+$ if proc
+$ then
+$ shared_proc = f$edit(line,"collapse")
+$ chop_semi = f$locate(";", shared_proc)
+$ if chop_semi .lt. f$length(shared_proc) then -
+ shared_proc = f$extract(0, chop_semi, shared_proc)
+$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+ f$edit(shared_proc,"upcase"),shared_proc)
+$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$ endif
+$ goto map_loop
+$MAP_END:
+$ close/nolog aopt
+$ close/nolog bopt
+$ open/append libopt 'p2'
+$ open/read aopt a.opt
+$ open/read bopt b.opt
+$ALOOP:
+$ read/end=aloop_end aopt line
+$ write libopt line
+$ goto aloop
+$ALOOP_END:
+$ close/nolog aopt
+$ sv = ""
+$BLOOP:
+$ read/end=bloop_end bopt svn
+$ if (svn.nes."")
+$ then
+$ if (sv.nes."") then write libopt sv
+$ sv = svn
+$ endif
+$ goto bloop
+$BLOOP_END:
+$ write libopt f$extract(0,f$length(sv)-2,sv), "-"
+$ write libopt ")"
+$ close/nolog bopt
+$ delete/nolog/noconf a.opt;*,b.opt;*
+$ else
+$ if vax
+$ then
+$ open/append libopt 'p2'
+$ mod_sym_num = 1
+$ VMOD_SYM_LOOP:
+$ if f$type(module'mod_sym_num') .nes. ""
+$ then
+$ mod_in = 0
+$ VMOD_SYM_IN:
+$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$ if shared_proc .nes. "#"
+$ then
+$ write libopt f$fao("UNIVERSAL=!AS",-
+ f$edit(shared_proc,"upcase"))
+$ mod_in = mod_in + 1
+$ goto vmod_sym_in
+$ endif
+$ mod_sym_num = mod_sym_num + 1
+$ goto vmod_sym_loop
+$ endif
+$VMAP_LOOP:
+$ read/end=vmap_end map line
+$ if (f$locate("{",line).lt. f$length(line)) .or. -
+ (f$locate("global:", line) .lt. f$length(line))
+$ then
+$ proc = true
+$ goto vmap_loop
+$ endif
+$ if f$locate("}",line).lt. f$length(line) then proc = false
+$ if f$locate("local:", line) .lt. f$length(line) then proc = false
+$ if proc
+$ then
+$ shared_proc = f$edit(line,"collapse")
+$ chop_semi = f$locate(";", shared_proc)
+$ if chop_semi .lt. f$length(shared_proc) then -
+ shared_proc = f$extract(0, chop_semi, shared_proc)
+$ write libopt f$fao("UNIVERSAL=!AS",-
+ f$edit(shared_proc,"upcase"))
+$ endif
+$ goto vmap_loop
+$VMAP_END:
+$ else
+$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)"
+$ write sys$output "No options file created"
+$ endif
+$ endif
+$ EXIT_M2S:
+$ close/nolog map
+$ close/nolog libopt
+$ endsubroutine
diff --git a/zlib/msdos/Makefile.bor b/zlib/msdos/Makefile.bor
new file mode 100644
index 000000000000..3d12a2c25270
--- /dev/null
+++ b/zlib/msdos/Makefile.bor
@@ -0,0 +1,115 @@
+# Makefile for zlib
+# Borland C++
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.bor"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C++, Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# memory model: one of s, m, c, l (small, medium, compact, large)
+MODEL=l
+
+# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
+CC=bcc
+LD=bcc
+AR=tlib
+
+# compiler flags
+# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
+CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
+
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del zlib_*.bak
+ -del foo.gz
diff --git a/zlib/msdos/Makefile.dj2 b/zlib/msdos/Makefile.dj2
new file mode 100644
index 000000000000..59d2037d69c4
--- /dev/null
+++ b/zlib/msdos/Makefile.dj2
@@ -0,0 +1,104 @@
+# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.dj2; make test -fmakefile.dj2
+#
+# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
+#
+# make install -fmakefile.dj2
+#
+# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
+# in the sample below if the pattern of the DJGPP distribution is to
+# be followed. Remember that, while 'es around <=> are ignored in
+# makefiles, they are *not* in batch files or in djgpp.env.
+# - - - - -
+# [make]
+# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
+# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
+# BUTT=-m486
+# - - - - -
+# Alternately, these variables may be defined below, overriding the values
+# in djgpp.env, as
+# INCLUDE_PATH=c:\usr\include
+# LIBRARY_PATH=c:\usr\lib
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DZLIB_DEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lz
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=libz.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+check: test
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+libz.a: $(OBJS) $(OBJA)
+ $(AR) $@ $(OBJS) $(OBJA)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
+
+.PHONY : uninstall clean
+
+install: $(INCL) $(LIBS)
+ -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
+ -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
+ $(INSTALL) zlib.h $(INCLUDE_PATH)
+ $(INSTALL) zconf.h $(INCLUDE_PATH)
+ $(INSTALL) libz.a $(LIBRARY_PATH)
+
+uninstall:
+ $(RM) $(INCLUDE_PATH)\zlib.h
+ $(RM) $(INCLUDE_PATH)\zconf.h
+ $(RM) $(LIBRARY_PATH)\libz.a
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) libz.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/zlib/msdos/Makefile.emx b/zlib/msdos/Makefile.emx
new file mode 100644
index 000000000000..e30f67bed68e
--- /dev/null
+++ b/zlib/msdos/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.emx; make test -fmakefile.emx
+#
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DZLIB_DEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+ $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) zlib.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/zlib/msdos/Makefile.msc b/zlib/msdos/Makefile.msc
new file mode 100644
index 000000000000..ae8378615ec6
--- /dev/null
+++ b/zlib/msdos/Makefile.msc
@@ -0,0 +1,112 @@
+# Makefile for zlib
+# Microsoft C 5.1 or later
+# Last updated: 19-Mar-2003
+
+# To use, do "make makefile.msc"
+# To compile in small model, set below: MODEL=S
+
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Microsoft C 5.1 and later -------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Memory model: one of S, M, C, L (small, medium, compact, large)
+MODEL=L
+
+CC=cl
+CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
+#-Ox generates bad code with MSC 5.1
+LIB_CFLAGS=-Zl $(CFLAGS)
+
+LD=link
+LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
+# "/farcall/packcode" are only useful for `large code' memory models
+# but should be a "no-op" for small code models.
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(LIB_CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ if exist $(ZLIB_LIB) del $(ZLIB_LIB)
+ lib $(ZLIB_LIB) $(OBJ1);
+ lib $(ZLIB_LIB) $(OBJ2);
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
+
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del *.map
+ -del zlib_*.bak
+ -del foo.gz
diff --git a/zlib/msdos/Makefile.tc b/zlib/msdos/Makefile.tc
new file mode 100644
index 000000000000..5aec82a9d58c
--- /dev/null
+++ b/zlib/msdos/Makefile.tc
@@ -0,0 +1,100 @@
+# Makefile for zlib
+# Turbo C 2.01, Turbo C++ 1.01
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.tc"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to CFLAGS below:
+# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
+MODEL=l
+CC=tcc
+LD=tcc
+AR=tlib
+# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+CFLAGS=-O2 -G -Z -m$(MODEL)
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del zlib_*.bak
+ -del foo.gz
diff --git a/zlib/nintendods/README b/zlib/nintendods/README
new file mode 100644
index 000000000000..ba7a37dbe8e9
--- /dev/null
+++ b/zlib/nintendods/README
@@ -0,0 +1,5 @@
+This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template.
+
+Eduardo Costa
+January 3, 2009
+
diff --git a/zlib/old/Makefile.emx b/zlib/old/Makefile.emx
new file mode 100644
index 000000000000..612b03791583
--- /dev/null
+++ b/zlib/old/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.emx; make test -fmakefile.emx
+#
+
+CC=gcc -Zwin32
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DZLIB_DEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+ gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+ $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) zlib.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/zlib/old/Makefile.riscos b/zlib/old/Makefile.riscos
new file mode 100644
index 000000000000..57e29d3fba91
--- /dev/null
+++ b/zlib/old/Makefile.riscos
@@ -0,0 +1,151 @@
+# Project: zlib_1_03
+# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
+# test works out-of-the-box, installs `somewhere' on demand
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags =
+LibFileflags = -c -l -o $@
+Squeezeflags = -o $@
+
+# change the line below to where _you_ want the library installed.
+libdest = lib:zlib
+
+# Final targets:
+@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
+ @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
+ @.o.uncompr @.o.zutil
+ LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
+ @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
+ @.o.trees @.o.uncompr @.o.zutil
+test: @.minigzip @.example @.lib
+ @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
+ @echo running tests: hang on.
+ @/@.minigzip -f -9 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -f -1 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -h -9 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -h -1 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -9 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -1 libc
+ @/@.minigzip -d libc-gz
+ @diff @.lib @.libc
+ @echo that should have reported '@.lib and @.libc identical' if you have diff.
+ @/@.example @.fred @.fred
+ @echo that will have given lots of hello!'s.
+
+@.minigzip: @.o.minigzip @.lib C:o.Stubs
+ Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
+@.example: @.o.example @.lib C:o.Stubs
+ Link $(Linkflags) @.o.example @.lib C:o.Stubs
+
+install: @.lib
+ cdir $(libdest)
+ cdir $(libdest).h
+ @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
+ @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
+ @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV
+ @echo okay, installed zlib in $(libdest)
+
+clean:; remove @.minigzip
+ remove @.example
+ remove @.libc
+ -wipe @.o.* F~r~cV
+ remove @.fred
+
+# User-editable dependencies:
+.c.o:
+ cc $(ccflags) -o $@ $<
+
+# Static dependencies:
+
+# Dynamic dependencies:
+o.example: c.example
+o.example: h.zlib
+o.example: h.zconf
+o.minigzip: c.minigzip
+o.minigzip: h.zlib
+o.minigzip: h.zconf
+o.adler32: c.adler32
+o.adler32: h.zlib
+o.adler32: h.zconf
+o.compress: c.compress
+o.compress: h.zlib
+o.compress: h.zconf
+o.crc32: c.crc32
+o.crc32: h.zlib
+o.crc32: h.zconf
+o.deflate: c.deflate
+o.deflate: h.deflate
+o.deflate: h.zutil
+o.deflate: h.zlib
+o.deflate: h.zconf
+o.gzio: c.gzio
+o.gzio: h.zutil
+o.gzio: h.zlib
+o.gzio: h.zconf
+o.infblock: c.infblock
+o.infblock: h.zutil
+o.infblock: h.zlib
+o.infblock: h.zconf
+o.infblock: h.infblock
+o.infblock: h.inftrees
+o.infblock: h.infcodes
+o.infblock: h.infutil
+o.infcodes: c.infcodes
+o.infcodes: h.zutil
+o.infcodes: h.zlib
+o.infcodes: h.zconf
+o.infcodes: h.inftrees
+o.infcodes: h.infblock
+o.infcodes: h.infcodes
+o.infcodes: h.infutil
+o.infcodes: h.inffast
+o.inffast: c.inffast
+o.inffast: h.zutil
+o.inffast: h.zlib
+o.inffast: h.zconf
+o.inffast: h.inftrees
+o.inffast: h.infblock
+o.inffast: h.infcodes
+o.inffast: h.infutil
+o.inffast: h.inffast
+o.inflate: c.inflate
+o.inflate: h.zutil
+o.inflate: h.zlib
+o.inflate: h.zconf
+o.inflate: h.infblock
+o.inftrees: c.inftrees
+o.inftrees: h.zutil
+o.inftrees: h.zlib
+o.inftrees: h.zconf
+o.inftrees: h.inftrees
+o.inftrees: h.inffixed
+o.infutil: c.infutil
+o.infutil: h.zutil
+o.infutil: h.zlib
+o.infutil: h.zconf
+o.infutil: h.infblock
+o.infutil: h.inftrees
+o.infutil: h.infcodes
+o.infutil: h.infutil
+o.trees: c.trees
+o.trees: h.deflate
+o.trees: h.zutil
+o.trees: h.zlib
+o.trees: h.zconf
+o.trees: h.trees
+o.uncompr: c.uncompr
+o.uncompr: h.zlib
+o.uncompr: h.zconf
+o.zutil: c.zutil
+o.zutil: h.zutil
+o.zutil: h.zlib
+o.zutil: h.zconf
diff --git a/zlib/old/README b/zlib/old/README
new file mode 100644
index 000000000000..800bf079827b
--- /dev/null
+++ b/zlib/old/README
@@ -0,0 +1,3 @@
+This directory contains files that have not been updated for zlib 1.2.x
+
+(Volunteers are encouraged to help clean this up. Thanks.)
diff --git a/zlib/old/descrip.mms b/zlib/old/descrip.mms
new file mode 100644
index 000000000000..7066da5b557e
--- /dev/null
+++ b/zlib/old/descrip.mms
@@ -0,0 +1,48 @@
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+
+cc_defs =
+c_deb =
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
+ deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
+ inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : example.exe minigzip.exe
+ @ write sys$output " Example applications available"
+libz.olb : libz.olb($(OBJS))
+ @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+ link example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+ link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+ delete *.obj;*,libz.olb;*
+
+
+# Other dependencies.
+adler32.obj : zutil.h zlib.h zconf.h
+compress.obj : zlib.h zconf.h
+crc32.obj : zutil.h zlib.h zconf.h
+deflate.obj : deflate.h zutil.h zlib.h zconf.h
+example.obj : zlib.h zconf.h
+gzio.obj : zutil.h zlib.h zconf.h
+infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+inflate.obj : zutil.h zlib.h zconf.h infblock.h
+inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
+infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
+minigzip.obj : zlib.h zconf.h
+trees.obj : deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : zlib.h zconf.h
+zutil.obj : zutil.h zlib.h zconf.h
diff --git a/zlib/old/os2/Makefile.os2 b/zlib/old/os2/Makefile.os2
new file mode 100644
index 000000000000..bb426c0d8e68
--- /dev/null
+++ b/zlib/old/os2/Makefile.os2
@@ -0,0 +1,136 @@
+# Makefile for zlib under OS/2 using GCC (PGCC)
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+# cp Makefile.os2 ..
+# cd ..
+# make -f Makefile.os2 test
+
+# This makefile will build a static library z.lib, a shared library
+# z.dll and a import library zdll.lib. You can use either z.lib or
+# zdll.lib by specifying either -lz or -lzdll on gcc's command line
+
+CC=gcc -Zomf -s
+
+CFLAGS=-O6 -Wall
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+#################### BUG WARNING: #####################
+## infcodes.c hits a bug in pgcc-1.0, so you have to use either
+## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
+## This bug is reportedly fixed in pgcc >1.0, but this was not tested
+CFLAGS+=-fno-force-mem
+
+LDFLAGS=-s -L. -lzdll -Zcrtdll
+LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
+
+VER=1.1.0
+ZLIB=z.lib
+SHAREDLIB=z.dll
+SHAREDLIBIMP=zdll.lib
+LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
+
+AR=emxomfar cr
+IMPLIB=emximp
+RANLIB=echo
+TAR=tar
+SHELL=bash
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+ zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
+ algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
+ nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \
+ contrib/asm386/*.asm contrib/asm386/*.c \
+ contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
+ contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
+ contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
+
+all: example.exe minigzip.exe
+
+test: all
+ @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ echo hello world | ./minigzip | ./minigzip -d || \
+ echo ' *** minigzip test FAILED ***' ; \
+ if ./example; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; \
+ fi
+
+$(ZLIB): $(OBJS)
+ $(AR) $@ $(OBJS)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+$(SHAREDLIB): $(OBJS) os2/z.def
+ $(LDSHARED) -o $@ $^
+
+$(SHAREDLIBIMP): os2/z.def
+ $(IMPLIB) -o $@ $^
+
+example.exe: example.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip.exe: minigzip.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+clean:
+ rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
+
+distclean: clean
+
+zip:
+ mv Makefile Makefile~; cp -p Makefile.in Makefile
+ rm -f test.c ztest*.c
+ v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+ zip -ul9 zlib$$v $(DISTFILES)
+ mv Makefile~ Makefile
+
+dist:
+ mv Makefile Makefile~; cp -p Makefile.in Makefile
+ rm -f test.c ztest*.c
+ d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+ rm -f $$d.tar.gz; \
+ if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+ files=""; \
+ for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+ cd ..; \
+ GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+ if test ! -d $$d; then rm -f $$d; fi
+ mv Makefile~ Makefile
+
+tags:
+ etags *.[ch]
+
+depend:
+ makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
+infcodes.o: zutil.h zlib.h zconf.h
+infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h
+inffast.o: infblock.h infcodes.h infutil.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h infblock.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/zlib/old/os2/zlib.def b/zlib/old/os2/zlib.def
new file mode 100644
index 000000000000..4c753f1a3b99
--- /dev/null
+++ b/zlib/old/os2/zlib.def
@@ -0,0 +1,51 @@
+;
+; Slightly modified version of ../nt/zlib.dnt :-)
+;
+
+LIBRARY Z
+DESCRIPTION "Zlib compression library for OS/2"
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+ adler32
+ compress
+ crc32
+ deflate
+ deflateCopy
+ deflateEnd
+ deflateInit2_
+ deflateInit_
+ deflateParams
+ deflateReset
+ deflateSetDictionary
+ gzclose
+ gzdopen
+ gzerror
+ gzflush
+ gzopen
+ gzread
+ gzwrite
+ inflate
+ inflateEnd
+ inflateInit2_
+ inflateInit_
+ inflateReset
+ inflateSetDictionary
+ inflateSync
+ uncompress
+ zlibVersion
+ gzprintf
+ gzputc
+ gzgetc
+ gzseek
+ gzrewind
+ gztell
+ gzeof
+ gzsetparams
+ zError
+ inflateSyncPoint
+ get_crc_table
+ compress2
+ gzputs
+ gzgets
diff --git a/zlib/old/visual-basic.txt b/zlib/old/visual-basic.txt
new file mode 100644
index 000000000000..57efe58124ee
--- /dev/null
+++ b/zlib/old/visual-basic.txt
@@ -0,0 +1,160 @@
+See below some functions declarations for Visual Basic.
+
+Frequently Asked Question:
+
+Q: Each time I use the compress function I get the -5 error (not enough
+ room in the output buffer).
+
+A: Make sure that the length of the compressed buffer is passed by
+ reference ("as any"), not by value ("as long"). Also check that
+ before the call of compress this length is equal to the total size of
+ the compressed buffer and not zero.
+
+
+From: "Jon Caruana"
+Subject: Re: How to port zlib declares to vb?
+Date: Mon, 28 Oct 1996 18:33:03 -0600
+
+Got the answer! (I haven't had time to check this but it's what I got, and
+looks correct):
+
+He has the following routines working:
+ compress
+ uncompress
+ gzopen
+ gzwrite
+ gzread
+ gzclose
+
+Declares follow: (Quoted from Carlos Rios , in Vb4 form)
+
+#If Win16 Then 'Use Win16 calls.
+Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
+ String, comprLen As Any, ByVal buf As String, ByVal buflen
+ As Long) As Integer
+Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
+ As String, uncomprLen As Any, ByVal compr As String, ByVal
+ lcompr As Long) As Integer
+Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
+ String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
+ Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+ As Integer
+Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
+ Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+ As Integer
+Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
+ Long) As Integer
+#Else
+Declare Function compress Lib "ZLIB32.DLL"
+ (ByVal compr As String, comprLen As Any, ByVal buf As
+ String, ByVal buflen As Long) As Integer
+Declare Function uncompress Lib "ZLIB32.DLL"
+ (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
+ String, ByVal lcompr As Long) As Long
+Declare Function gzopen Lib "ZLIB32.DLL"
+ (ByVal file As String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB32.DLL"
+ (ByVal file As Long, ByVal uncompr As String, ByVal
+ uncomprLen As Long) As Long
+Declare Function gzwrite Lib "ZLIB32.DLL"
+ (ByVal file As Long, ByVal uncompr As String, ByVal
+ uncomprLen As Long) As Long
+Declare Function gzclose Lib "ZLIB32.DLL"
+ (ByVal file As Long) As Long
+#End If
+
+-Jon Caruana
+jon-net@usa.net
+Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
+
+
+Here is another example from Michael that he
+says conforms to the VB guidelines, and that solves the problem of not
+knowing the uncompressed size by storing it at the end of the file:
+
+'Calling the functions:
+'bracket meaning: [optional] {Range of possible values}
+'Call subCompressFile( [, , [level of compression {1..9}]])
+'Call subUncompressFile()
+
+Option Explicit
+Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
+Private Const SUCCESS As Long = 0
+Private Const strFilExt As String = ".cpr"
+Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
+ByVal level As Integer) As Long
+Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
+As Long
+
+Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
+strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
+ Dim strCprPth As String
+ Dim lngOriSiz As Long
+ Dim lngCprSiz As Long
+ Dim bytaryOri() As Byte
+ Dim bytaryCpr() As Byte
+ lngOriSiz = FileLen(strargOriFilPth)
+ ReDim bytaryOri(lngOriSiz - 1)
+ Open strargOriFilPth For Binary Access Read As #1
+ Get #1, , bytaryOri()
+ Close #1
+ strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
+'Select file path and name
+ strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
+strFilExt, "", strFilExt) 'Add file extension if not exists
+ lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
+more space then original file size
+ ReDim bytaryCpr(lngCprSiz - 1)
+ If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
+SUCCESS Then
+ lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
+ ReDim Preserve bytaryCpr(lngCprSiz - 1)
+ Open strCprPth For Binary Access Write As #1
+ Put #1, , bytaryCpr()
+ Put #1, , lngOriSiz 'Add the the original size value to the end
+(last 4 bytes)
+ Close #1
+ Else
+ MsgBox "Compression error"
+ End If
+ Erase bytaryCpr
+ Erase bytaryOri
+End Sub
+
+Public Sub subUncompressFile(ByVal strargFilPth As String)
+ Dim bytaryCpr() As Byte
+ Dim bytaryOri() As Byte
+ Dim lngOriSiz As Long
+ Dim lngCprSiz As Long
+ Dim strOriPth As String
+ lngCprSiz = FileLen(strargFilPth)
+ ReDim bytaryCpr(lngCprSiz - 1)
+ Open strargFilPth For Binary Access Read As #1
+ Get #1, , bytaryCpr()
+ Close #1
+ 'Read the original file size value:
+ lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
+ + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
+ + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
+ + bytaryCpr(lngCprSiz - 4)
+ ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
+ ReDim bytaryOri(lngOriSiz - 1)
+ If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
+Then
+ strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
+ Open strOriPth For Binary Access Write As #1
+ Put #1, , bytaryOri()
+ Close #1
+ Else
+ MsgBox "Uncompression error"
+ End If
+ Erase bytaryCpr
+ Erase bytaryOri
+End Sub
+Public Property Get lngPercentSmaller() As Long
+ lngPercentSmaller = lngpvtPcnSml
+End Property
diff --git a/zlib/os400/README400 b/zlib/os400/README400
new file mode 100644
index 000000000000..4f98334f5ac5
--- /dev/null
+++ b/zlib/os400/README400
@@ -0,0 +1,48 @@
+ ZLIB version 1.2.11 for OS/400 installation instructions
+
+1) Download and unpack the zlib tarball to some IFS directory.
+ (i.e.: /path/to/the/zlib/ifs/source/directory)
+
+ If the installed IFS command suppors gzip format, this is straightforward,
+else you have to unpack first to some directory on a system supporting it,
+then move the whole directory to the IFS via the network (via SMB or FTP).
+
+2) Edit the configuration parameters in the compilation script.
+
+ EDTF STMF('/path/to/the/zlib/ifs/source/directory/os400/make.sh')
+
+Tune the parameters according to your needs if not matching the defaults.
+Save the file and exit after edition.
+
+3) Enter qshell, then work in the zlib OS/400 specific directory.
+
+ QSH
+ cd /path/to/the/zlib/ifs/source/directory/os400
+
+4) Compile and install
+
+ sh make.sh
+
+The script will:
+- create the libraries, objects and IFS directories for the zlib environment,
+- compile all modules,
+- create a service program,
+- create a static and a dynamic binding directory,
+- install header files for C/C++ and for ILE/RPG, both for compilation in
+ DB2 and IFS environments.
+
+That's all.
+
+
+Notes: For OS/400 ILE RPG programmers, a /copy member defining the ZLIB
+ API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
+ In the ILE environment, the same definitions are available from
+ file zlib.inc located in the same IFS include directory as the
+ C/C++ header files.
+ Please read comments in this member for more information.
+
+ Remember that most foreign textual data are ASCII coded: this
+ implementation does not handle conversion from/to ASCII, so
+ text data code conversions must be done explicitely.
+
+ Mainly for the reason above, always open zipped files in binary mode.
diff --git a/zlib/os400/bndsrc b/zlib/os400/bndsrc
new file mode 100644
index 000000000000..5e6e0a2f0af3
--- /dev/null
+++ b/zlib/os400/bndsrc
@@ -0,0 +1,119 @@
+STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.1.3 entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("adler32")
+ EXPORT SYMBOL("compress")
+ EXPORT SYMBOL("compress2")
+ EXPORT SYMBOL("crc32")
+ EXPORT SYMBOL("get_crc_table")
+ EXPORT SYMBOL("deflate")
+ EXPORT SYMBOL("deflateEnd")
+ EXPORT SYMBOL("deflateSetDictionary")
+ EXPORT SYMBOL("deflateCopy")
+ EXPORT SYMBOL("deflateReset")
+ EXPORT SYMBOL("deflateParams")
+ EXPORT SYMBOL("deflatePrime")
+ EXPORT SYMBOL("deflateInit_")
+ EXPORT SYMBOL("deflateInit2_")
+ EXPORT SYMBOL("gzopen")
+ EXPORT SYMBOL("gzdopen")
+ EXPORT SYMBOL("gzsetparams")
+ EXPORT SYMBOL("gzread")
+ EXPORT SYMBOL("gzwrite")
+ EXPORT SYMBOL("gzprintf")
+ EXPORT SYMBOL("gzputs")
+ EXPORT SYMBOL("gzgets")
+ EXPORT SYMBOL("gzputc")
+ EXPORT SYMBOL("gzgetc")
+ EXPORT SYMBOL("gzflush")
+ EXPORT SYMBOL("gzseek")
+ EXPORT SYMBOL("gzrewind")
+ EXPORT SYMBOL("gztell")
+ EXPORT SYMBOL("gzeof")
+ EXPORT SYMBOL("gzclose")
+ EXPORT SYMBOL("gzerror")
+ EXPORT SYMBOL("inflate")
+ EXPORT SYMBOL("inflateEnd")
+ EXPORT SYMBOL("inflateSetDictionary")
+ EXPORT SYMBOL("inflateSync")
+ EXPORT SYMBOL("inflateReset")
+ EXPORT SYMBOL("inflateInit_")
+ EXPORT SYMBOL("inflateInit2_")
+ EXPORT SYMBOL("inflateSyncPoint")
+ EXPORT SYMBOL("uncompress")
+ EXPORT SYMBOL("zlibVersion")
+ EXPORT SYMBOL("zError")
+ EXPORT SYMBOL("z_errmsg")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.1 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("compressBound")
+ EXPORT SYMBOL("deflateBound")
+ EXPORT SYMBOL("deflatePending")
+ EXPORT SYMBOL("gzungetc")
+ EXPORT SYMBOL("gzclearerr")
+ EXPORT SYMBOL("inflateBack")
+ EXPORT SYMBOL("inflateBackEnd")
+ EXPORT SYMBOL("inflateBackInit_")
+ EXPORT SYMBOL("inflateCopy")
+ EXPORT SYMBOL("zlibCompileFlags")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.4 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("adler32_combine")
+ EXPORT SYMBOL("adler32_combine64")
+ EXPORT SYMBOL("crc32_combine")
+ EXPORT SYMBOL("crc32_combine64")
+ EXPORT SYMBOL("deflateSetHeader")
+ EXPORT SYMBOL("deflateTune")
+ EXPORT SYMBOL("gzbuffer")
+ EXPORT SYMBOL("gzclose_r")
+ EXPORT SYMBOL("gzclose_w")
+ EXPORT SYMBOL("gzdirect")
+ EXPORT SYMBOL("gzoffset")
+ EXPORT SYMBOL("gzoffset64")
+ EXPORT SYMBOL("gzopen64")
+ EXPORT SYMBOL("gzseek64")
+ EXPORT SYMBOL("gztell64")
+ EXPORT SYMBOL("inflateGetHeader")
+ EXPORT SYMBOL("inflateMark")
+ EXPORT SYMBOL("inflatePrime")
+ EXPORT SYMBOL("inflateReset2")
+ EXPORT SYMBOL("inflateUndermine")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.6 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("deflateResetKeep")
+ EXPORT SYMBOL("gzgetc_")
+ EXPORT SYMBOL("inflateResetKeep")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.8 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("gzvprintf")
+ EXPORT SYMBOL("inflateGetDictionary")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.9 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("adler32_z")
+ EXPORT SYMBOL("crc32_z")
+ EXPORT SYMBOL("deflateGetDictionary")
+ EXPORT SYMBOL("gzfread")
+ EXPORT SYMBOL("gzfwrite")
+ EXPORT SYMBOL("inflateCodesUsed")
+ EXPORT SYMBOL("inflateValidate")
+ EXPORT SYMBOL("uncompress2")
+
+ENDPGMEXP
diff --git a/zlib/os400/make.sh b/zlib/os400/make.sh
new file mode 100644
index 000000000000..19eec117a678
--- /dev/null
+++ b/zlib/os400/make.sh
@@ -0,0 +1,366 @@
+#!/bin/sh
+#
+# ZLIB compilation script for the OS/400.
+#
+#
+# This is a shell script since make is not a standard component of OS/400.
+
+
+################################################################################
+#
+# Tunable configuration parameters.
+#
+################################################################################
+
+TARGETLIB='ZLIB' # Target OS/400 program library
+STATBNDDIR='ZLIB_A' # Static binding directory.
+DYNBNDDIR='ZLIB' # Dynamic binding directory.
+SRVPGM="ZLIB" # Service program.
+IFSDIR='/zlib' # IFS support base directory.
+TGTCCSID='500' # Target CCSID of objects
+DEBUG='*NONE' # Debug level
+OPTIMIZE='40' # Optimisation level
+OUTPUT='*NONE' # Compilation output option.
+TGTRLS='V6R1M0' # Target OS release
+
+export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM IFSDIR
+export TGTCCSID DEBUG OPTIMIZE OUTPUT TGTRLS
+
+
+################################################################################
+#
+# OS/400 specific definitions.
+#
+################################################################################
+
+LIBIFSNAME="/QSYS.LIB/${TARGETLIB}.LIB"
+
+
+################################################################################
+#
+# Procedures.
+#
+################################################################################
+
+# action_needed dest [src]
+#
+# dest is an object to build
+# if specified, src is an object on which dest depends.
+#
+# exit 0 (succeeds) if some action has to be taken, else 1.
+
+action_needed()
+
+{
+ [ ! -e "${1}" ] && return 0
+ [ "${2}" ] || return 1
+ [ "${1}" -ot "${2}" ] && return 0
+ return 1
+}
+
+
+# make_module module_name source_name [additional_definitions]
+#
+# Compile source name into module if needed.
+# As side effect, append the module name to variable MODULES.
+# Set LINK to "YES" if the module has been compiled.
+
+make_module()
+
+{
+ MODULES="${MODULES} ${1}"
+ MODIFSNAME="${LIBIFSNAME}/${1}.MODULE"
+ CSRC="`basename \"${2}\"`"
+
+ if action_needed "${MODIFSNAME}" "${2}"
+ then :
+ elif [ ! "`sed -e \"//,/<\\\\/source>/!d\" \
+ -e '/ tmphdrfile
+
+ # Need to translate to target CCSID.
+
+ CMD="CPY OBJ('`pwd`/tmphdrfile') TOOBJ('${DEST}')"
+ CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+ system "${CMD}"
+ # touch -r "${HFILE}" "${DEST}"
+ rm -f tmphdrfile
+ fi
+
+ IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`"
+
+ if action_needed "${IFSFILE}" "${DEST}"
+ then rm -f "${IFSFILE}"
+ ln -s "${DEST}" "${IFSFILE}"
+ fi
+done
+
+
+# Install the ILE/RPG header file.
+
+
+HFILE="${SCRIPTDIR}/zlib.inc"
+DEST="${SRCPF}/ZLIB.INC.MBR"
+
+if action_needed "${DEST}" "${HFILE}"
+then CMD="CPY OBJ('${HFILE}') TOOBJ('${DEST}')"
+ CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+ system "${CMD}"
+ # touch -r "${HFILE}" "${DEST}"
+fi
+
+IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`"
+
+if action_needed "${IFSFILE}" "${DEST}"
+then rm -f "${IFSFILE}"
+ ln -s "${DEST}" "${IFSFILE}"
+fi
+
+
+# Create and compile the identification source file.
+
+echo '#pragma comment(user, "ZLIB version '"${VERSION}"'")' > os400.c
+echo '#pragma comment(user, __DATE__)' >> os400.c
+echo '#pragma comment(user, __TIME__)' >> os400.c
+echo '#pragma comment(copyright, "Copyright (C) 1995-2017 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c
+make_module OS400 os400.c
+LINK= # No need to rebuild service program yet.
+MODULES=
+
+
+# Get source list.
+
+CSOURCES=`sed -e '/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Library
+
+ Medium
+
+ 2.0
+
+
+
+ zlib
+ zlib
+ alain.bonnefoy@icbt.com
+ Public
+ public
+ www.gzip.org/zlib
+
+
+ Jean-Loup Gailly,Mark Adler
+ www.gzip.org/zlib
+
+ zlib@gzip.org
+
+
+ A massively spiffy yet delicately unobtrusive compression library.
+ zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.
+ http://www.gzip.org/zlib
+
+
+
+
+ 1.2.11
+ Medium
+ Stable
+
+
+
+
+
+
+ No License
+
+
+
+ Software Development/Libraries and Extensions/C Libraries
+ zlib,compression
+ qnx6
+ qnx6
+ None
+ Developer
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Install
+ Post
+ No
+ Ignore
+
+ No
+ Optional
+
+
+
+
+
+
+
+
+
+
+
+
+ InstallOver
+ zlib
+
+
+
+
+
+
+
+
+
+
+
+
+ InstallOver
+ zlib-dev
+
+
+
+
+
+
+
+
+
diff --git a/zlib/test/example.c b/zlib/test/example.c
new file mode 100644
index 000000000000..eee17ce7c159
--- /dev/null
+++ b/zlib/test/example.c
@@ -0,0 +1,602 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include
+
+#ifdef STDC
+# include
+# include
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+static z_const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+static const char dictionary[] = "hello";
+static uLong dictId; /* Adler32 value of the dictionary */
+
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ (void)q;
+ return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+ (void)q;
+ free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+ const char *fname; /* compressed file name */
+ Byte *uncompr;
+ uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+ int err;
+ int len = (int)strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char*)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ if (gzungetc(' ', file) != ' ') {
+ fprintf(stderr, "gzungetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, (int)uncomprLen);
+ if (strlen((char*)uncompr) != 7) { /* " hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello + 6)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+ }
+
+ gzclose(file);
+#endif
+}
+
+#endif /* Z_SOLO */
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uInt len = (uInt)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, (int)sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ (int)sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+ ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+
+#ifdef Z_SOLO
+ (void)argc;
+ (void)argv;
+#else
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ uncompr, uncomprLen);
+#endif
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ free(compr);
+ free(uncompr);
+
+ return 0;
+}
diff --git a/zlib/test/infcover.c b/zlib/test/infcover.c
new file mode 100644
index 000000000000..2be01646cec3
--- /dev/null
+++ b/zlib/test/infcover.c
@@ -0,0 +1,671 @@
+/* infcover.c -- test zlib's inflate routines with full code coverage
+ * Copyright (C) 2011, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* to use, do: ./configure --cover && make cover */
+
+#include
+#include
+#include
+#include
+#include "zlib.h"
+
+/* get definition of internal structure so we can mess with it (see pull()),
+ and so we can call inflate_trees() (see cover5()) */
+#define ZLIB_INTERNAL
+#include "inftrees.h"
+#include "inflate.h"
+
+#define local static
+
+/* -- memory tracking routines -- */
+
+/*
+ These memory tracking routines are provided to zlib and track all of zlib's
+ allocations and deallocations, check for LIFO operations, keep a current
+ and high water mark of total bytes requested, optionally set a limit on the
+ total memory that can be allocated, and when done check for memory leaks.
+
+ They are used as follows:
+
+ z_stream strm;
+ mem_setup(&strm) initializes the memory tracking and sets the
+ zalloc, zfree, and opaque members of strm to use
+ memory tracking for all zlib operations on strm
+ mem_limit(&strm, limit) sets a limit on the total bytes requested -- a
+ request that exceeds this limit will result in an
+ allocation failure (returns NULL) -- setting the
+ limit to zero means no limit, which is the default
+ after mem_setup()
+ mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used
+ mem_high(&strm, "msg") prints to stderr "msg" and the high water mark
+ mem_done(&strm, "msg") ends memory tracking, releases all allocations
+ for the tracking as well as leaked zlib blocks, if
+ any. If there was anything unusual, such as leaked
+ blocks, non-FIFO frees, or frees of addresses not
+ allocated, then "msg" and information about the
+ problem is printed to stderr. If everything is
+ normal, nothing is printed. mem_done resets the
+ strm members to Z_NULL to use the default memory
+ allocation routines on the next zlib initialization
+ using strm.
+ */
+
+/* these items are strung together in a linked list, one for each allocation */
+struct mem_item {
+ void *ptr; /* pointer to allocated memory */
+ size_t size; /* requested size of allocation */
+ struct mem_item *next; /* pointer to next item in list, or NULL */
+};
+
+/* this structure is at the root of the linked list, and tracks statistics */
+struct mem_zone {
+ struct mem_item *first; /* pointer to first item in list, or NULL */
+ size_t total, highwater; /* total allocations, and largest total */
+ size_t limit; /* memory allocation limit, or 0 if no limit */
+ int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */
+};
+
+/* memory allocation routine to pass to zlib */
+local void *mem_alloc(void *mem, unsigned count, unsigned size)
+{
+ void *ptr;
+ struct mem_item *item;
+ struct mem_zone *zone = mem;
+ size_t len = count * (size_t)size;
+
+ /* induced allocation failure */
+ if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
+ return NULL;
+
+ /* perform allocation using the standard library, fill memory with a
+ non-zero value to make sure that the code isn't depending on zeros */
+ ptr = malloc(len);
+ if (ptr == NULL)
+ return NULL;
+ memset(ptr, 0xa5, len);
+
+ /* create a new item for the list */
+ item = malloc(sizeof(struct mem_item));
+ if (item == NULL) {
+ free(ptr);
+ return NULL;
+ }
+ item->ptr = ptr;
+ item->size = len;
+
+ /* insert item at the beginning of the list */
+ item->next = zone->first;
+ zone->first = item;
+
+ /* update the statistics */
+ zone->total += item->size;
+ if (zone->total > zone->highwater)
+ zone->highwater = zone->total;
+
+ /* return the allocated memory */
+ return ptr;
+}
+
+/* memory free routine to pass to zlib */
+local void mem_free(void *mem, void *ptr)
+{
+ struct mem_item *item, *next;
+ struct mem_zone *zone = mem;
+
+ /* if no zone, just do a free */
+ if (zone == NULL) {
+ free(ptr);
+ return;
+ }
+
+ /* point next to the item that matches ptr, or NULL if not found -- remove
+ the item from the linked list if found */
+ next = zone->first;
+ if (next) {
+ if (next->ptr == ptr)
+ zone->first = next->next; /* first one is it, remove from list */
+ else {
+ do { /* search the linked list */
+ item = next;
+ next = item->next;
+ } while (next != NULL && next->ptr != ptr);
+ if (next) { /* if found, remove from linked list */
+ item->next = next->next;
+ zone->notlifo++; /* not a LIFO free */
+ }
+
+ }
+ }
+
+ /* if found, update the statistics and free the item */
+ if (next) {
+ zone->total -= next->size;
+ free(next);
+ }
+
+ /* if not found, update the rogue count */
+ else
+ zone->rogue++;
+
+ /* in any case, do the requested free with the standard library function */
+ free(ptr);
+}
+
+/* set up a controlled memory allocation space for monitoring, set the stream
+ parameters to the controlled routines, with opaque pointing to the space */
+local void mem_setup(z_stream *strm)
+{
+ struct mem_zone *zone;
+
+ zone = malloc(sizeof(struct mem_zone));
+ assert(zone != NULL);
+ zone->first = NULL;
+ zone->total = 0;
+ zone->highwater = 0;
+ zone->limit = 0;
+ zone->notlifo = 0;
+ zone->rogue = 0;
+ strm->opaque = zone;
+ strm->zalloc = mem_alloc;
+ strm->zfree = mem_free;
+}
+
+/* set a limit on the total memory allocation, or 0 to remove the limit */
+local void mem_limit(z_stream *strm, size_t limit)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ zone->limit = limit;
+}
+
+/* show the current total requested allocations in bytes */
+local void mem_used(z_stream *strm, char *prefix)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
+}
+
+/* show the high water allocation in bytes */
+local void mem_high(z_stream *strm, char *prefix)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
+}
+
+/* release the memory allocation zone -- if there are any surprises, notify */
+local void mem_done(z_stream *strm, char *prefix)
+{
+ int count = 0;
+ struct mem_item *item, *next;
+ struct mem_zone *zone = strm->opaque;
+
+ /* show high water mark */
+ mem_high(strm, prefix);
+
+ /* free leftover allocations and item structures, if any */
+ item = zone->first;
+ while (item != NULL) {
+ free(item->ptr);
+ next = item->next;
+ free(item);
+ item = next;
+ count++;
+ }
+
+ /* issue alerts about anything unexpected */
+ if (count || zone->total)
+ fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
+ prefix, zone->total, count);
+ if (zone->notlifo)
+ fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
+ if (zone->rogue)
+ fprintf(stderr, "** %s: %d frees not recognized\n",
+ prefix, zone->rogue);
+
+ /* free the zone and delete from the stream */
+ free(zone);
+ strm->opaque = Z_NULL;
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+}
+
+/* -- inflate test routines -- */
+
+/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This
+ decodes liberally, in that hex digits can be adjacent, in which case two in
+ a row writes a byte. Or they can be delimited by any non-hex character,
+ where the delimiters are ignored except when a single hex digit is followed
+ by a delimiter, where that single digit writes a byte. The returned data is
+ allocated and must eventually be freed. NULL is returned if out of memory.
+ If the length is not needed, then len can be NULL. */
+local unsigned char *h2b(const char *hex, unsigned *len)
+{
+ unsigned char *in, *re;
+ unsigned next, val;
+
+ in = malloc((strlen(hex) + 1) >> 1);
+ if (in == NULL)
+ return NULL;
+ next = 0;
+ val = 1;
+ do {
+ if (*hex >= '0' && *hex <= '9')
+ val = (val << 4) + *hex - '0';
+ else if (*hex >= 'A' && *hex <= 'F')
+ val = (val << 4) + *hex - 'A' + 10;
+ else if (*hex >= 'a' && *hex <= 'f')
+ val = (val << 4) + *hex - 'a' + 10;
+ else if (val != 1 && val < 32) /* one digit followed by delimiter */
+ val += 240; /* make it look like two digits */
+ if (val > 255) { /* have two digits */
+ in[next++] = val & 0xff; /* save the decoded byte */
+ val = 1; /* start over */
+ }
+ } while (*hex++); /* go through the loop with the terminating null */
+ if (len != NULL)
+ *len = next;
+ re = realloc(in, next);
+ return re == NULL ? in : re;
+}
+
+/* generic inflate() run, where hex is the hexadecimal input data, what is the
+ text to include in an error message, step is how much input data to feed
+ inflate() on each call, or zero to feed it all, win is the window bits
+ parameter to inflateInit2(), len is the size of the output buffer, and err
+ is the error code expected from the first inflate() call (the second
+ inflate() call is expected to return Z_STREAM_END). If win is 47, then
+ header information is collected with inflateGetHeader(). If a zlib stream
+ is looking for a dictionary, then an empty dictionary is provided.
+ inflate() is run until all of the input data is consumed. */
+local void inf(char *hex, char *what, unsigned step, int win, unsigned len,
+ int err)
+{
+ int ret;
+ unsigned have;
+ unsigned char *in, *out;
+ z_stream strm, copy;
+ gz_header head;
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, win);
+ if (ret != Z_OK) {
+ mem_done(&strm, what);
+ return;
+ }
+ out = malloc(len); assert(out != NULL);
+ if (win == 47) {
+ head.extra = out;
+ head.extra_max = len;
+ head.name = out;
+ head.name_max = len;
+ head.comment = out;
+ head.comm_max = len;
+ ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
+ }
+ in = h2b(hex, &have); assert(in != NULL);
+ if (step == 0 || step > have)
+ step = have;
+ strm.avail_in = step;
+ have -= step;
+ strm.next_in = in;
+ do {
+ strm.avail_out = len;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
+ if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
+ break;
+ if (ret == Z_NEED_DICT) {
+ ret = inflateSetDictionary(&strm, in, 1);
+ assert(ret == Z_DATA_ERROR);
+ mem_limit(&strm, 1);
+ ret = inflateSetDictionary(&strm, out, 0);
+ assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ ((struct inflate_state *)strm.state)->mode = DICT;
+ ret = inflateSetDictionary(&strm, out, 0);
+ assert(ret == Z_OK);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
+ }
+ ret = inflateCopy(©, &strm); assert(ret == Z_OK);
+ ret = inflateEnd(©); assert(ret == Z_OK);
+ err = 9; /* don't care next time around */
+ have += strm.avail_in;
+ strm.avail_in = step > have ? have : step;
+ have -= strm.avail_in;
+ } while (strm.avail_in);
+ free(in);
+ free(out);
+ ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, what);
+}
+
+/* cover all of the lines in inflate.c up to inflate() */
+local void cover_support(void)
+{
+ int ret;
+ z_stream strm;
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit(&strm); assert(ret == Z_OK);
+ mem_used(&strm, "inflate init");
+ ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
+ ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
+ ret = inflateSetDictionary(&strm, Z_NULL, 0);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "prime");
+
+ inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
+ inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
+ inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
+ inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
+ inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
+ assert(ret == Z_VERSION_ERROR);
+ mem_done(&strm, "wrong version");
+
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit(&strm); assert(ret == Z_OK);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ fputs("inflate built-in memory routines\n", stderr);
+}
+
+/* cover all inflate() header and trailer cases and code after inflate() */
+local void cover_wrap(void)
+{
+ int ret;
+ z_stream strm, copy;
+ unsigned char dict[257];
+
+ ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR);
+ ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
+ ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR);
+ fputs("inflate bad parameters\n", stderr);
+
+ inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
+ inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
+ inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
+ inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
+ inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
+ inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
+ inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
+ Z_DATA_ERROR);
+ inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
+ 0, 47, 0, Z_STREAM_END);
+ inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
+ inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
+ inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, -8);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x63";
+ strm.avail_out = 1;
+ strm.next_out = (void *)&ret;
+ mem_limit(&strm, 1);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ memset(dict, 0, 257);
+ ret = inflateSetDictionary(&strm, dict, 257);
+ assert(ret == Z_OK);
+ mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
+ ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x80";
+ ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
+ strm.avail_in = 4;
+ strm.next_in = (void *)"\0\0\xff\xff";
+ ret = inflateSync(&strm); assert(ret == Z_OK);
+ (void)inflateSyncPoint(&strm);
+ ret = inflateCopy(©, &strm); assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
+ (void)inflateMark(&strm);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "miscellaneous, force memory errors");
+}
+
+/* input and output functions for inflateBack() */
+local unsigned pull(void *desc, unsigned char **buf)
+{
+ static unsigned int next = 0;
+ static unsigned char dat[] = {0x63, 0, 2, 0};
+ struct inflate_state *state;
+
+ if (desc == Z_NULL) {
+ next = 0;
+ return 0; /* no input (already provided at next_in) */
+ }
+ state = (void *)((z_stream *)desc)->state;
+ if (state != Z_NULL)
+ state->mode = SYNC; /* force an otherwise impossible situation */
+ return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
+}
+
+local int push(void *desc, unsigned char *buf, unsigned len)
+{
+ buf += len;
+ return desc != Z_NULL; /* force error if desc not null */
+}
+
+/* cover inflateBack() up to common deflate data cases and after those */
+local void cover_back(void)
+{
+ int ret;
+ z_stream strm;
+ unsigned char win[32768];
+
+ ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
+ assert(ret == Z_VERSION_ERROR);
+ ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR);
+ ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
+ fputs("inflateBack bad parameters\n", stderr);
+
+ mem_setup(&strm);
+ ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x03";
+ ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+ assert(ret == Z_STREAM_END);
+ /* force output error */
+ strm.avail_in = 3;
+ strm.next_in = (void *)"\x63\x00";
+ ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
+ assert(ret == Z_BUF_ERROR);
+ /* force mode error by mucking with state */
+ ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateBackEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "inflateBack bad state");
+
+ ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
+ ret = inflateBackEnd(&strm); assert(ret == Z_OK);
+ fputs("inflateBack built-in memory routines\n", stderr);
+}
+
+/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
+local int try(char *hex, char *id, int err)
+{
+ int ret;
+ unsigned len, size;
+ unsigned char *in, *out, *win;
+ char *prefix;
+ z_stream strm;
+
+ /* convert to hex */
+ in = h2b(hex, &len);
+ assert(in != NULL);
+
+ /* allocate work areas */
+ size = len << 3;
+ out = malloc(size);
+ assert(out != NULL);
+ win = malloc(32768);
+ assert(win != NULL);
+ prefix = malloc(strlen(id) + 6);
+ assert(prefix != NULL);
+
+ /* first with inflate */
+ strcpy(prefix, id);
+ strcat(prefix, "-late");
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, err < 0 ? 47 : -15);
+ assert(ret == Z_OK);
+ strm.avail_in = len;
+ strm.next_in = in;
+ do {
+ strm.avail_out = size;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_TREES);
+ assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
+ if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
+ break;
+ } while (strm.avail_in || strm.avail_out == 0);
+ if (err) {
+ assert(ret == Z_DATA_ERROR);
+ assert(strcmp(id, strm.msg) == 0);
+ }
+ inflateEnd(&strm);
+ mem_done(&strm, prefix);
+
+ /* then with inflateBack */
+ if (err >= 0) {
+ strcpy(prefix, id);
+ strcat(prefix, "-back");
+ mem_setup(&strm);
+ ret = inflateBackInit(&strm, 15, win);
+ assert(ret == Z_OK);
+ strm.avail_in = len;
+ strm.next_in = in;
+ ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+ assert(ret != Z_STREAM_ERROR);
+ if (err) {
+ assert(ret == Z_DATA_ERROR);
+ assert(strcmp(id, strm.msg) == 0);
+ }
+ inflateBackEnd(&strm);
+ mem_done(&strm, prefix);
+ }
+
+ /* clean up */
+ free(prefix);
+ free(win);
+ free(out);
+ free(in);
+ return ret;
+}
+
+/* cover deflate data cases in both inflate() and inflateBack() */
+local void cover_inflate(void)
+{
+ try("0 0 0 0 0", "invalid stored block lengths", 1);
+ try("3 0", "fixed", 0);
+ try("6", "invalid block type", 1);
+ try("1 1 0 fe ff 0", "stored", 0);
+ try("fc 0 0", "too many length or distance symbols", 1);
+ try("4 0 fe ff", "invalid code lengths set", 1);
+ try("4 0 24 49 0", "invalid bit length repeat", 1);
+ try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
+ try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
+ try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
+ "invalid literal/lengths set", 1);
+ try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
+ try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
+ try("2 7e ff ff", "invalid distance code", 1);
+ try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
+
+ /* also trailer mismatch just in inflate() */
+ try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
+ try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
+ "incorrect length check", -1);
+ try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
+ try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
+ "long code", 0);
+ try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
+ try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
+ "long distance and extra", 0);
+ try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
+ inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
+ Z_STREAM_END);
+ inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
+}
+
+/* cover remaining lines in inftrees.c */
+local void cover_trees(void)
+{
+ int ret;
+ unsigned bits;
+ unsigned short lens[16], work[16];
+ code *next, table[ENOUGH_DISTS];
+
+ /* we need to call inflate_table() directly in order to manifest not-
+ enough errors, since zlib insures that enough is always enough */
+ for (bits = 0; bits < 15; bits++)
+ lens[bits] = (unsigned short)(bits + 1);
+ lens[15] = 15;
+ next = table;
+ bits = 15;
+ ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+ assert(ret == 1);
+ next = table;
+ bits = 1;
+ ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+ assert(ret == 1);
+ fputs("inflate_table not enough errors\n", stderr);
+}
+
+/* cover remaining inffast.c decoding and window copying */
+local void cover_fast(void)
+{
+ inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
+ " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
+ inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
+ " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
+ "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
+ inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
+ inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
+ "contiguous and wrap around window", 6, -8, 259, Z_OK);
+ inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
+ Z_STREAM_END);
+}
+
+int main(void)
+{
+ fprintf(stderr, "%s\n", zlibVersion());
+ cover_support();
+ cover_wrap();
+ cover_back();
+ cover_inflate();
+ cover_trees();
+ cover_fast();
+ return 0;
+}
diff --git a/zlib/test/minigzip.c b/zlib/test/minigzip.c
new file mode 100644
index 000000000000..e22fb08c0a29
--- /dev/null
+++ b/zlib/test/minigzip.c
@@ -0,0 +1,651 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include
+
+#ifdef STDC
+# include
+# include
+#endif
+
+#ifdef USE_MMAP
+# include
+# include
+# include
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+# include
+# include
+# ifdef UNDER_CE
+# include
+# endif
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# define snprintf _snprintf
+#endif
+
+#ifdef VMS
+# define unlink delete
+# define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+# define unlink remove
+# define GZ_SUFFIX "-gz"
+# define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include /* for fileno */
+#endif
+
+#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+ extern int unlink OF((const char *));
+#endif
+#endif
+
+#if defined(UNDER_CE)
+# include
+# define perror(s) pwinerror(s)
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+ message string and return a pointer to it. Typically, the values
+ for ERROR come from GetLastError.
+
+ The string pointed to shall not be modified by the application,
+ but may be overwritten by a subsequent call to strwinerror
+
+ The strwinerror function does not change the current setting
+ of GetLastError. */
+
+static char *strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+static void pwinerror (s)
+ const char *s;
+{
+ if (s && *s)
+ fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
+ else
+ fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
+}
+
+#endif /* UNDER_CE */
+
+#ifndef GZ_SUFFIX
+# define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN 16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+# define local static
+ /* Needed for systems with limitation on stack size. */
+#else
+# define local
+#endif
+
+#ifdef Z_SOLO
+/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
+
+#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
+# include /* for unlink() */
+#endif
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ (void)q;
+ return calloc(n, m);
+}
+
+void myfree(q, p)
+ void *q, *p;
+{
+ (void)q;
+ free(p);
+}
+
+typedef struct gzFile_s {
+ FILE *file;
+ int write;
+ int err;
+ char *msg;
+ z_stream strm;
+} *gzFile;
+
+gzFile gzopen OF((const char *, const char *));
+gzFile gzdopen OF((int, const char *));
+gzFile gz_open OF((const char *, int, const char *));
+
+gzFile gzopen(path, mode)
+const char *path;
+const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+gzFile gzdopen(fd, mode)
+int fd;
+const char *mode;
+{
+ return gz_open(NULL, fd, mode);
+}
+
+gzFile gz_open(path, fd, mode)
+ const char *path;
+ int fd;
+ const char *mode;
+{
+ gzFile gz;
+ int ret;
+
+ gz = malloc(sizeof(struct gzFile_s));
+ if (gz == NULL)
+ return NULL;
+ gz->write = strchr(mode, 'w') != NULL;
+ gz->strm.zalloc = myalloc;
+ gz->strm.zfree = myfree;
+ gz->strm.opaque = Z_NULL;
+ if (gz->write)
+ ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
+ else {
+ gz->strm.next_in = 0;
+ gz->strm.avail_in = Z_NULL;
+ ret = inflateInit2(&(gz->strm), 15 + 16);
+ }
+ if (ret != Z_OK) {
+ free(gz);
+ return NULL;
+ }
+ gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
+ fopen(path, gz->write ? "wb" : "rb");
+ if (gz->file == NULL) {
+ gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
+ free(gz);
+ return NULL;
+ }
+ gz->err = 0;
+ gz->msg = "";
+ return gz;
+}
+
+int gzwrite OF((gzFile, const void *, unsigned));
+
+int gzwrite(gz, buf, len)
+ gzFile gz;
+ const void *buf;
+ unsigned len;
+{
+ z_stream *strm;
+ unsigned char out[BUFLEN];
+
+ if (gz == NULL || !gz->write)
+ return 0;
+ strm = &(gz->strm);
+ strm->next_in = (void *)buf;
+ strm->avail_in = len;
+ do {
+ strm->next_out = out;
+ strm->avail_out = BUFLEN;
+ (void)deflate(strm, Z_NO_FLUSH);
+ fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+ } while (strm->avail_out == 0);
+ return len;
+}
+
+int gzread OF((gzFile, void *, unsigned));
+
+int gzread(gz, buf, len)
+ gzFile gz;
+ void *buf;
+ unsigned len;
+{
+ int ret;
+ unsigned got;
+ unsigned char in[1];
+ z_stream *strm;
+
+ if (gz == NULL || gz->write)
+ return 0;
+ if (gz->err)
+ return 0;
+ strm = &(gz->strm);
+ strm->next_out = (void *)buf;
+ strm->avail_out = len;
+ do {
+ got = fread(in, 1, 1, gz->file);
+ if (got == 0)
+ break;
+ strm->next_in = in;
+ strm->avail_in = 1;
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_DATA_ERROR) {
+ gz->err = Z_DATA_ERROR;
+ gz->msg = strm->msg;
+ return 0;
+ }
+ if (ret == Z_STREAM_END)
+ inflateReset(strm);
+ } while (strm->avail_out);
+ return len - strm->avail_out;
+}
+
+int gzclose OF((gzFile));
+
+int gzclose(gz)
+ gzFile gz;
+{
+ z_stream *strm;
+ unsigned char out[BUFLEN];
+
+ if (gz == NULL)
+ return Z_STREAM_ERROR;
+ strm = &(gz->strm);
+ if (gz->write) {
+ strm->next_in = Z_NULL;
+ strm->avail_in = 0;
+ do {
+ strm->next_out = out;
+ strm->avail_out = BUFLEN;
+ (void)deflate(strm, Z_FINISH);
+ fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+ } while (strm->avail_out == 0);
+ deflateEnd(strm);
+ }
+ else
+ inflateEnd(strm);
+ fclose(gz->file);
+ free(gz);
+ return Z_OK;
+}
+
+const char *gzerror OF((gzFile, int *));
+
+const char *gzerror(gz, err)
+ gzFile gz;
+ int *err;
+{
+ *err = gz->err;
+ return gz->msg;
+}
+
+#endif
+
+static char *prog;
+
+void error OF((const char *msg));
+void gz_compress OF((FILE *in, gzFile out));
+#ifdef USE_MMAP
+int gz_compress_mmap OF((FILE *in, gzFile out));
+#endif
+void gz_uncompress OF((gzFile in, FILE *out));
+void file_compress OF((char *file, char *mode));
+void file_uncompress OF((char *file));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+ const char *msg;
+{
+ fprintf(stderr, "%s: %s\n", prog, msg);
+ exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+ FILE *in;
+ gzFile out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+#ifdef USE_MMAP
+ /* Try first compressing with mmap. If mmap fails (minigzip used in a
+ * pipe), use the normal fread loop.
+ */
+ if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+ for (;;) {
+ len = (int)fread(buf, 1, sizeof(buf), in);
+ if (ferror(in)) {
+ perror("fread");
+ exit(1);
+ }
+ if (len == 0) break;
+
+ if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+ }
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+ FILE *in;
+ gzFile out;
+{
+ int len;
+ int err;
+ int ifd = fileno(in);
+ caddr_t buf; /* mmap'ed buffer for the entire input file */
+ off_t buf_len; /* length of the input file */
+ struct stat sb;
+
+ /* Determine the size of the file, needed for mmap: */
+ if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+ buf_len = sb.st_size;
+ if (buf_len <= 0) return Z_ERRNO;
+
+ /* Now do the actual mmap: */
+ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+ if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+ /* Compress the whole file at once: */
+ len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+ if (len != (int)buf_len) error(gzerror(out, &err));
+
+ munmap(buf, buf_len);
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+ return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+ gzFile in;
+ FILE *out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+ for (;;) {
+ len = gzread(in, buf, sizeof(buf));
+ if (len < 0) error (gzerror(in, &err));
+ if (len == 0) break;
+
+ if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+ error("failed fwrite");
+ }
+ }
+ if (fclose(out)) error("failed fclose");
+
+ if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+ char *file;
+ char *mode;
+{
+ local char outfile[MAX_NAME_LEN];
+ FILE *in;
+ gzFile out;
+
+ if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
+ fprintf(stderr, "%s: filename too long\n", prog);
+ exit(1);
+ }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
+#else
+ strcpy(outfile, file);
+ strcat(outfile, GZ_SUFFIX);
+#endif
+
+ in = fopen(file, "rb");
+ if (in == NULL) {
+ perror(file);
+ exit(1);
+ }
+ out = gzopen(outfile, mode);
+ if (out == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+ exit(1);
+ }
+ gz_compress(in, out);
+
+ unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+ char *file;
+{
+ local char buf[MAX_NAME_LEN];
+ char *infile, *outfile;
+ FILE *out;
+ gzFile in;
+ unsigned len = strlen(file);
+
+ if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
+ fprintf(stderr, "%s: filename too long\n", prog);
+ exit(1);
+ }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(buf, sizeof(buf), "%s", file);
+#else
+ strcpy(buf, file);
+#endif
+
+ if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+ infile = file;
+ outfile = buf;
+ outfile[len-3] = '\0';
+ } else {
+ outfile = file;
+ infile = buf;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
+#else
+ strcat(infile, GZ_SUFFIX);
+#endif
+ }
+ in = gzopen(infile, "rb");
+ if (in == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+ exit(1);
+ }
+ out = fopen(outfile, "wb");
+ if (out == NULL) {
+ perror(file);
+ exit(1);
+ }
+
+ gz_uncompress(in, out);
+
+ unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ * -c : write to standard output
+ * -d : decompress
+ * -f : compress with Z_FILTERED
+ * -h : compress with Z_HUFFMAN_ONLY
+ * -r : compress with Z_RLE
+ * -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int copyout = 0;
+ int uncompr = 0;
+ gzFile file;
+ char *bname, outmode[20];
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
+#else
+ strcpy(outmode, "wb6 ");
+#endif
+
+ prog = argv[0];
+ bname = strrchr(argv[0], '/');
+ if (bname)
+ bname++;
+ else
+ bname = argv[0];
+ argc--, argv++;
+
+ if (!strcmp(bname, "gunzip"))
+ uncompr = 1;
+ else if (!strcmp(bname, "zcat"))
+ copyout = uncompr = 1;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "-c") == 0)
+ copyout = 1;
+ else if (strcmp(*argv, "-d") == 0)
+ uncompr = 1;
+ else if (strcmp(*argv, "-f") == 0)
+ outmode[3] = 'f';
+ else if (strcmp(*argv, "-h") == 0)
+ outmode[3] = 'h';
+ else if (strcmp(*argv, "-r") == 0)
+ outmode[3] = 'R';
+ else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+ (*argv)[2] == 0)
+ outmode[2] = (*argv)[1];
+ else
+ break;
+ argc--, argv++;
+ }
+ if (outmode[3] == ' ')
+ outmode[3] = 0;
+ if (argc == 0) {
+ SET_BINARY_MODE(stdin);
+ SET_BINARY_MODE(stdout);
+ if (uncompr) {
+ file = gzdopen(fileno(stdin), "rb");
+ if (file == NULL) error("can't gzdopen stdin");
+ gz_uncompress(file, stdout);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+ gz_compress(stdin, file);
+ }
+ } else {
+ if (copyout) {
+ SET_BINARY_MODE(stdout);
+ }
+ do {
+ if (uncompr) {
+ if (copyout) {
+ file = gzopen(*argv, "rb");
+ if (file == NULL)
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
+ else
+ gz_uncompress(file, stdout);
+ } else {
+ file_uncompress(*argv);
+ }
+ } else {
+ if (copyout) {
+ FILE * in = fopen(*argv, "rb");
+
+ if (in == NULL) {
+ perror(*argv);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+
+ gz_compress(in, file);
+ }
+
+ } else {
+ file_compress(*argv, outmode);
+ }
+ }
+ } while (argv++, --argc);
+ }
+ return 0;
+}
diff --git a/zlib/treebuild.xml b/zlib/treebuild.xml
new file mode 100644
index 000000000000..fd75525f9959
--- /dev/null
+++ b/zlib/treebuild.xml
@@ -0,0 +1,116 @@
+
+
+
+ zip compression library
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/zlib/trees.c b/zlib/trees.c
index 78024e8d4cc0..1f64ae3ec670 100644
--- a/zlib/trees.c
+++ b/zlib/trees.c
@@ -1,5 +1,6 @@
/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -35,7 +36,7 @@
#include "deflate.h"
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
# include
#endif
@@ -73,11 +74,6 @@ local const uch bl_order[BL_CODES]
* probability, to avoid transmitting the lengths for unused bit length codes.
*/
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
/* ===========================================================================
* Local data. These are initialized only once.
*/
@@ -126,13 +122,13 @@ struct static_tree_desc_s {
int max_length; /* max bit length for the codes */
};
-local static_tree_desc static_l_desc =
+local const static_tree_desc static_l_desc =
{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-local static_tree_desc static_d_desc =
+local const static_tree_desc static_d_desc =
{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-local static_tree_desc static_bl_desc =
+local const static_tree_desc static_bl_desc =
{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
/* ===========================================================================
@@ -150,24 +146,22 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
local int build_bl_tree OF((deflate_state *s));
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+ const ct_data *dtree));
+local int detect_data_type OF((deflate_state *s));
local unsigned bi_reverse OF((unsigned value, int length));
local void bi_windup OF((deflate_state *s));
local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
#ifdef GEN_TREES_H
local void gen_trees_header OF((void));
#endif
-#ifndef DEBUG
+#ifndef ZLIB_DEBUG
# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
/* Send a code of the given tree. c and tree must not have side effects */
-#else /* DEBUG */
+#else /* !ZLIB_DEBUG */
# define send_code(s, c, tree) \
{ if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
send_bits(s, tree[c].Code, tree[c].Len); }
@@ -186,7 +180,7 @@ local void gen_trees_header OF((void));
* Send a value on a given number of bits.
* IN assertion: length <= 16 and value fits in length bits.
*/
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
local void send_bits OF((deflate_state *s, int value, int length));
local void send_bits(s, value, length)
@@ -203,31 +197,31 @@ local void send_bits(s, value, length)
* unused bits in value.
*/
if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
+ s->bi_buf |= (ush)value << s->bi_valid;
put_short(s, s->bi_buf);
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
s->bi_valid += length - Buf_size;
} else {
- s->bi_buf |= value << s->bi_valid;
+ s->bi_buf |= (ush)value << s->bi_valid;
s->bi_valid += length;
}
}
-#else /* !DEBUG */
+#else /* !ZLIB_DEBUG */
#define send_bits(s, value, length) \
{ int len = length;\
if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
+ int val = (int)value;\
+ s->bi_buf |= (ush)val << s->bi_valid;\
put_short(s, s->bi_buf);\
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
s->bi_valid += len - Buf_size;\
} else {\
- s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_buf |= (ush)(value) << s->bi_valid;\
s->bi_valid += len;\
}\
}
-#endif /* DEBUG */
+#endif /* ZLIB_DEBUG */
/* the arguments must not have side effects */
@@ -250,11 +244,13 @@ local void tr_static_init()
if (static_init_done) return;
/* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
static_l_desc.static_tree = static_ltree;
static_l_desc.extra_bits = extra_lbits;
static_d_desc.static_tree = static_dtree;
static_d_desc.extra_bits = extra_dbits;
static_bl_desc.extra_bits = extra_blbits;
+#endif
/* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0;
@@ -319,7 +315,7 @@ local void tr_static_init()
* Genererate the file trees.h describing the static trees.
*/
#ifdef GEN_TREES_H
-# ifndef DEBUG
+# ifndef ZLIB_DEBUG
# include
# endif
@@ -348,13 +344,14 @@ void gen_trees_header()
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
}
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
for (i = 0; i < DIST_CODE_LEN; i++) {
fprintf(header, "%2u%s", _dist_code[i],
SEPARATOR(i, DIST_CODE_LEN-1, 20));
}
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ fprintf(header,
+ "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
fprintf(header, "%2u%s", _length_code[i],
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
@@ -379,7 +376,7 @@ void gen_trees_header()
/* ===========================================================================
* Initialize the tree data structures for a new zlib stream.
*/
-void _tr_init(s)
+void ZLIB_INTERNAL _tr_init(s)
deflate_state *s;
{
tr_static_init();
@@ -395,8 +392,7 @@ void _tr_init(s)
s->bi_buf = 0;
s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
s->compressed_len = 0L;
s->bits_sent = 0L;
#endif
@@ -524,12 +520,12 @@ local void gen_bitlen(s, desc)
xbits = 0;
if (n >= base) xbits = extra[n-base];
f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ s->opt_len += (ulg)f * (unsigned)(bits + xbits);
+ if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
}
if (overflow == 0) return;
- Trace((stderr,"\nbit length overflow\n"));
+ Tracev((stderr,"\nbit length overflow\n"));
/* This happens for example on obj2 and pic of the Calgary corpus */
/* Find the first bit length which could increase: */
@@ -556,9 +552,8 @@ local void gen_bitlen(s, desc)
m = s->heap[--h];
if (m > max_code) continue;
if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
+ Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
tree[m].Len = (ush)bits;
}
n--;
@@ -580,7 +575,7 @@ local void gen_codes (tree, max_code, bl_count)
ushf *bl_count; /* number of codes at each bit length */
{
ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
+ unsigned code = 0; /* running code value */
int bits; /* bit index */
int n; /* code index */
@@ -588,7 +583,8 @@ local void gen_codes (tree, max_code, bl_count)
* without bit reversal.
*/
for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ code = (code + bl_count[bits-1]) << 1;
+ next_code[bits] = (ush)code;
}
/* Check that the bit counts in bl_count are consistent. The last code
* must be all ones.
@@ -601,7 +597,7 @@ local void gen_codes (tree, max_code, bl_count)
int len = tree[n].Len;
if (len == 0) continue;
/* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
+ tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
@@ -823,7 +819,7 @@ local int build_bl_tree(s)
if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
}
/* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
s->opt_len, s->static_len));
@@ -864,65 +860,63 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
/* ===========================================================================
* Send a stored block
*/
-void _tr_stored_block(s, buf, stored_len, eof)
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
deflate_state *s;
charf *buf; /* input block */
ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
+ int last; /* one if this is the last block for a file */
{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
+ send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
+ bi_windup(s); /* align on byte boundary */
+ put_short(s, (ush)stored_len);
+ put_short(s, (ush)~stored_len);
+ if (stored_len != 0) {
+ /* Avoid calling memcpy when stored_len equals to zero to
+ avoid UBSAN errors */
+ zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
+ }
+ s->pending += stored_len;
+#ifdef ZLIB_DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
s->compressed_len += (stored_len + 4) << 3;
+ s->bits_sent += 2*16;
+ s->bits_sent += stored_len<<3;
#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+ deflate_state *s;
+{
+ bi_flush(s);
}
/* ===========================================================================
* Send one empty static block to give enough lookahead for inflate.
* This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
*/
-void _tr_align(s)
+void ZLIB_INTERNAL _tr_align(s)
deflate_state *s;
{
send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
#endif
bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
}
/* ===========================================================================
* Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
+ * trees or store, and write out the encoded block.
*/
-void _tr_flush_block(s, buf, stored_len, eof)
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
deflate_state *s;
charf *buf; /* input block, or NULL if too old */
ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
+ int last; /* one if this is the last block for a file */
{
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
int max_blindex = 0; /* index of last bit length code of non zero freq */
@@ -931,8 +925,8 @@ void _tr_flush_block(s, buf, stored_len, eof)
if (s->level > 0) {
/* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
+ if (s->strm->data_type == Z_UNKNOWN)
+ s->strm->data_type = detect_data_type(s);
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -978,24 +972,26 @@ void _tr_flush_block(s, buf, stored_len, eof)
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
* transform a block into a stored block.
*/
- _tr_stored_block(s, buf, stored_len, eof);
+ _tr_stored_block(s, buf, stored_len, last);
#ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */
#else
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
+ send_bits(s, (STATIC_TREES<<1)+last, 3);
+ compress_block(s, (const ct_data *)static_ltree,
+ (const ct_data *)static_dtree);
+#ifdef ZLIB_DEBUG
s->compressed_len += 3 + s->static_len;
#endif
} else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_bits(s, (DYN_TREES<<1)+last, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
+ compress_block(s, (const ct_data *)s->dyn_ltree,
+ (const ct_data *)s->dyn_dtree);
+#ifdef ZLIB_DEBUG
s->compressed_len += 3 + s->opt_len;
#endif
}
@@ -1005,21 +1001,21 @@ void _tr_flush_block(s, buf, stored_len, eof)
*/
init_block(s);
- if (eof) {
+ if (last) {
bi_windup(s);
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
s->compressed_len += 7; /* align on byte boundary */
#endif
}
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
+ s->compressed_len-7*last));
}
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
-int _tr_tally (s, dist, lc)
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
deflate_state *s;
unsigned dist; /* distance of matched string */
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
@@ -1071,8 +1067,8 @@ int _tr_tally (s, dist, lc)
*/
local void compress_block(s, ltree, dtree)
deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
+ const ct_data *ltree; /* literal tree */
+ const ct_data *dtree; /* distance tree */
{
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
@@ -1102,7 +1098,7 @@ local void compress_block(s, ltree, dtree)
send_code(s, code, dtree); /* send the distance code */
extra = extra_dbits[code];
if (extra != 0) {
- dist -= base_dist[code];
+ dist -= (unsigned)base_dist[code];
send_bits(s, dist, extra); /* send the extra distance bits */
}
} /* literal or match pair ? */
@@ -1114,28 +1110,48 @@ local void compress_block(s, ltree, dtree)
} while (lx < s->last_lit);
send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
}
/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ * a) There are no non-portable control characters belonging to the
+ * "black list" (0..6, 14..25, 28..31).
+ * b) There is at least one printable character belonging to the
+ * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ * "gray list" that is ignored in this detection algorithm:
+ * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
* IN assertion: the fields Freq of dyn_ltree are set.
*/
-local void set_data_type(s)
+local int detect_data_type(s)
deflate_state *s;
{
+ /* black_mask is the bit mask of black-listed bytes
+ * set bits 0..6, 14..25, and 28..31
+ * 0xf3ffc07f = binary 11110011111111111100000001111111
+ */
+ unsigned long black_mask = 0xf3ffc07fUL;
int n;
- for (n = 0; n < 9; n++)
+ /* Check for non-textual ("black-listed") bytes. */
+ for (n = 0; n <= 31; n++, black_mask >>= 1)
+ if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ return Z_BINARY;
+
+ /* Check for textual ("white-listed") bytes. */
+ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+ || s->dyn_ltree[13].Freq != 0)
+ return Z_TEXT;
+ for (n = 32; n < LITERALS; n++)
if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+ return Z_TEXT;
+
+ /* There are no "black-listed" or "white-listed" bytes:
+ * this stream either is empty or has tolerated ("gray-listed") bytes only.
+ */
+ return Z_BINARY;
}
/* ===========================================================================
@@ -1147,7 +1163,7 @@ local unsigned bi_reverse(code, len)
unsigned code; /* the value to invert */
int len; /* its bit length */
{
- unsigned res = 0;
+ register unsigned res = 0;
do {
res |= code & 1;
code >>= 1, res <<= 1;
@@ -1185,35 +1201,7 @@ local void bi_windup(s)
}
s->bi_buf = 0;
s->bi_valid = 0;
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
s->bits_sent = (s->bits_sent+7) & ~7;
#endif
}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/zlib/trees.h b/zlib/trees.h
index 72facf900f77..d35639d82a27 100644
--- a/zlib/trees.h
+++ b/zlib/trees.h
@@ -70,7 +70,7 @@ local const ct_data static_dtree[D_CODES] = {
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
};
-const uch _dist_code[DIST_CODE_LEN] = {
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
@@ -99,7 +99,7 @@ const uch _dist_code[DIST_CODE_LEN] = {
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
diff --git a/zlib/uncompr.c b/zlib/uncompr.c
index b59e3d0defb2..f03a1a865e34 100644
--- a/zlib/uncompr.c
+++ b/zlib/uncompr.c
@@ -1,5 +1,5 @@
/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,53 +9,85 @@
#include "zlib.h"
/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
+ Decompresses the source buffer into the destination buffer. *sourceLen is
+ the byte length of the source buffer. Upon entry, *destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit,
+ *destLen is the size of the decompressed data and *sourceLen is the number
+ of source bytes consumed. Upon return, source + *sourceLen points to the
+ first unused input byte.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
+ Z_DATA_ERROR if the input data was corrupted, including if the input data is
+ an incomplete zlib stream.
*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
- uLong sourceLen;
+ uLong *sourceLen;
{
z_stream stream;
int err;
+ const uInt max = (uInt)-1;
+ uLong len, left;
+ Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+ len = *sourceLen;
+ if (*destLen) {
+ left = *destLen;
+ *destLen = 0;
+ }
+ else {
+ left = 1;
+ dest = buf;
+ }
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
err = inflateInit(&stream);
if (err != Z_OK) return err;
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
- return Z_DATA_ERROR;
- return err;
- }
- *destLen = stream.total_out;
+ stream.next_out = dest;
+ stream.avail_out = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = len > (uLong)max ? max : (uInt)len;
+ len -= stream.avail_in;
+ }
+ err = inflate(&stream, Z_NO_FLUSH);
+ } while (err == Z_OK);
- err = inflateEnd(&stream);
- return err;
+ *sourceLen -= len + stream.avail_in;
+ if (dest != buf)
+ *destLen = stream.total_out;
+ else if (stream.total_out && err == Z_BUF_ERROR)
+ left = 1;
+
+ inflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK :
+ err == Z_NEED_DICT ? Z_DATA_ERROR :
+ err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
+ err;
+}
+
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return uncompress2(dest, destLen, source, &sourceLen);
}
diff --git a/zlib/watcom/watcom_f.mak b/zlib/watcom/watcom_f.mak
new file mode 100644
index 000000000000..37f4d74c19c0
--- /dev/null
+++ b/zlib/watcom/watcom_f.mak
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom flat model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_f.mak"
+
+C_SOURCE = adler32.c compress.c crc32.c deflate.c &
+ gzclose.c gzlib.c gzread.c gzwrite.c &
+ infback.c inffast.c inflate.c inftrees.c &
+ trees.c uncompr.c zutil.c
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj &
+ gzclose.obj gzlib.obj gzread.obj gzwrite.obj &
+ infback.obj inffast.obj inflate.obj inftrees.obj &
+ trees.obj uncompr.obj zutil.obj
+
+CC = wcc386
+LINKER = wcl386
+CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_f.lib
+
+.C.OBJ:
+ $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+ wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj
+ wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj
+ wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj
+ wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj
+ wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+ $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+ $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+ del *.obj
+ del $(ZLIB_LIB)
+ @echo Cleaning done
diff --git a/zlib/watcom/watcom_l.mak b/zlib/watcom/watcom_l.mak
new file mode 100644
index 000000000000..193eed7b318a
--- /dev/null
+++ b/zlib/watcom/watcom_l.mak
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom large model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_l.mak"
+
+C_SOURCE = adler32.c compress.c crc32.c deflate.c &
+ gzclose.c gzlib.c gzread.c gzwrite.c &
+ infback.c inffast.c inflate.c inftrees.c &
+ trees.c uncompr.c zutil.c
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj &
+ gzclose.obj gzlib.obj gzread.obj gzwrite.obj &
+ infback.obj inffast.obj inflate.obj inftrees.obj &
+ trees.obj uncompr.obj zutil.obj
+
+CC = wcc
+LINKER = wcl
+CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_l.lib
+
+.C.OBJ:
+ $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+ wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj
+ wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj
+ wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj
+ wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj
+ wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+ $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+ $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+ del *.obj
+ del $(ZLIB_LIB)
+ @echo Cleaning done
diff --git a/zlib/win32/DLL_FAQ.txt b/zlib/win32/DLL_FAQ.txt
new file mode 100644
index 000000000000..12c009018c37
--- /dev/null
+++ b/zlib/win32/DLL_FAQ.txt
@@ -0,0 +1,397 @@
+
+ Frequently Asked Questions about ZLIB1.DLL
+
+
+This document describes the design, the rationale, and the usage
+of the official DLL build of zlib, named ZLIB1.DLL. If you have
+general questions about zlib, you should see the file "FAQ" found
+in the zlib distribution, or at the following location:
+ http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. What is ZLIB1.DLL, and how can I get it?
+
+ - ZLIB1.DLL is the official build of zlib as a DLL.
+ (Please remark the character '1' in the name.)
+
+ Pointers to a precompiled ZLIB1.DLL can be found in the zlib
+ web site at:
+ http://www.zlib.net/
+
+ Applications that link to ZLIB1.DLL can rely on the following
+ specification:
+
+ * The exported symbols are exclusively defined in the source
+ files "zlib.h" and "zlib.def", found in an official zlib
+ source distribution.
+ * The symbols are exported by name, not by ordinal.
+ * The exported names are undecorated.
+ * The calling convention of functions is "C" (CDECL).
+ * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
+
+ The archive in which ZLIB1.DLL is bundled contains compiled
+ test programs that must run with a valid build of ZLIB1.DLL.
+ It is recommended to download the prebuilt DLL from the zlib
+ web site, instead of building it yourself, to avoid potential
+ incompatibilities that could be introduced by your compiler
+ and build settings. If you do build the DLL yourself, please
+ make sure that it complies with all the above requirements,
+ and it runs with the precompiled test programs, bundled with
+ the original ZLIB1.DLL distribution.
+
+ If, for any reason, you need to build an incompatible DLL,
+ please use a different file name.
+
+
+ 2. Why did you change the name of the DLL to ZLIB1.DLL?
+ What happened to the old ZLIB.DLL?
+
+ - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
+ compilation settings that were incompatible to those used by
+ a static build. The DLL settings were supposed to be enabled
+ by defining the macro ZLIB_DLL, before including "zlib.h".
+ Incorrect handling of this macro was silently accepted at
+ build time, resulting in two major problems:
+
+ * ZLIB_DLL was missing from the old makefile. When building
+ the DLL, not all people added it to the build options. In
+ consequence, incompatible incarnations of ZLIB.DLL started
+ to circulate around the net.
+
+ * When switching from using the static library to using the
+ DLL, applications had to define the ZLIB_DLL macro and
+ to recompile all the sources that contained calls to zlib
+ functions. Failure to do so resulted in creating binaries
+ that were unable to run with the official ZLIB.DLL build.
+
+ The only possible solution that we could foresee was to make
+ a binary-incompatible change in the DLL interface, in order to
+ remove the dependency on the ZLIB_DLL macro, and to release
+ the new DLL under a different name.
+
+ We chose the name ZLIB1.DLL, where '1' indicates the major
+ zlib version number. We hope that we will not have to break
+ the binary compatibility again, at least not as long as the
+ zlib-1.x series will last.
+
+ There is still a ZLIB_DLL macro, that can trigger a more
+ efficient build and use of the DLL, but compatibility no
+ longer dependents on it.
+
+
+ 3. Can I build ZLIB.DLL from the new zlib sources, and replace
+ an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
+
+ - In principle, you can do it by assigning calling convention
+ keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
+ it depends on what you mean by "an old ZLIB.DLL", because the
+ old DLL exists in several mutually-incompatible versions.
+ You have to find out first what kind of calling convention is
+ being used in your particular ZLIB.DLL build, and to use the
+ same one in the new build. If you don't know what this is all
+ about, you might be better off if you would just leave the old
+ DLL intact.
+
+
+ 4. Can I compile my application using the new zlib interface, and
+ link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
+ earlier?
+
+ - The official answer is "no"; the real answer depends again on
+ what kind of ZLIB.DLL you have. Even if you are lucky, this
+ course of action is unreliable.
+
+ If you rebuild your application and you intend to use a newer
+ version of zlib (post- 1.1.4), it is strongly recommended to
+ link it to the new ZLIB1.DLL.
+
+
+ 5. Why are the zlib symbols exported by name, and not by ordinal?
+
+ - Although exporting symbols by ordinal is a little faster, it
+ is risky. Any single glitch in the maintenance or use of the
+ DEF file that contains the ordinals can result in incompatible
+ builds and frustrating crashes. Simply put, the benefits of
+ exporting symbols by ordinal do not justify the risks.
+
+ Technically, it should be possible to maintain ordinals in
+ the DEF file, and still export the symbols by name. Ordinals
+ exist in every DLL, and even if the dynamic linking performed
+ at the DLL startup is searching for names, ordinals serve as
+ hints, for a faster name lookup. However, if the DEF file
+ contains ordinals, the Microsoft linker automatically builds
+ an implib that will cause the executables linked to it to use
+ those ordinals, and not the names. It is interesting to
+ notice that the GNU linker for Win32 does not suffer from this
+ problem.
+
+ It is possible to avoid the DEF file if the exported symbols
+ are accompanied by a "__declspec(dllexport)" attribute in the
+ source files. You can do this in zlib by predefining the
+ ZLIB_DLL macro.
+
+
+ 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
+ convention. Why not use the STDCALL convention?
+ STDCALL is the standard convention in Win32, and I need it in
+ my Visual Basic project!
+
+ (For readability, we use CDECL to refer to the convention
+ triggered by the "__cdecl" keyword, STDCALL to refer to
+ the convention triggered by "__stdcall", and FASTCALL to
+ refer to the convention triggered by "__fastcall".)
+
+ - Most of the native Windows API functions (without varargs) use
+ indeed the WINAPI convention (which translates to STDCALL in
+ Win32), but the standard C functions use CDECL. If a user
+ application is intrinsically tied to the Windows API (e.g.
+ it calls native Windows API functions such as CreateFile()),
+ sometimes it makes sense to decorate its own functions with
+ WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
+ it calls standard C functions such as fopen()), it is not a
+ sound decision to request the inclusion of , or to
+ use non-ANSI constructs, for the sole purpose to make the user
+ functions STDCALL-able.
+
+ The functionality offered by zlib is not in the category of
+ "Windows functionality", but is more like "C functionality".
+
+ Technically, STDCALL is not bad; in fact, it is slightly
+ faster than CDECL, and it works with variable-argument
+ functions, just like CDECL. It is unfortunate that, in spite
+ of using STDCALL in the Windows API, it is not the default
+ convention used by the C compilers that run under Windows.
+ The roots of the problem reside deep inside the unsafety of
+ the K&R-style function prototypes, where the argument types
+ are not specified; but that is another story for another day.
+
+ The remaining fact is that CDECL is the default convention.
+ Even if an explicit convention is hard-coded into the function
+ prototypes inside C headers, problems may appear. The
+ necessity to expose the convention in users' callbacks is one
+ of these problems.
+
+ The calling convention issues are also important when using
+ zlib in other programming languages. Some of them, like Ada
+ (GNAT) and Fortran (GNU G77), have C bindings implemented
+ initially on Unix, and relying on the C calling convention.
+ On the other hand, the pre- .NET versions of Microsoft Visual
+ Basic require STDCALL, while Borland Delphi prefers, although
+ it does not require, FASTCALL.
+
+ In fairness to all possible uses of zlib outside the C
+ programming language, we choose the default "C" convention.
+ Anyone interested in different bindings or conventions is
+ encouraged to maintain specialized projects. The "contrib/"
+ directory from the zlib distribution already holds a couple
+ of foreign bindings, such as Ada, C++, and Delphi.
+
+
+ 7. I need a DLL for my Visual Basic project. What can I do?
+
+ - Define the ZLIB_WINAPI macro before including "zlib.h", when
+ building both the DLL and the user application (except that
+ you don't need to define anything when using the DLL in Visual
+ Basic). The ZLIB_WINAPI macro will switch on the WINAPI
+ (STDCALL) convention. The name of this DLL must be different
+ than the official ZLIB1.DLL.
+
+ Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
+ with the ZLIB_WINAPI macro turned on, and with the minizip
+ functionality built in. For more information, please read
+ the notes inside "contrib/vstudio/readme.txt", found in the
+ zlib distribution.
+
+
+ 8. I need to use zlib in my Microsoft .NET project. What can I
+ do?
+
+ - Henrik Ravn has contributed a .NET wrapper around zlib. Look
+ into contrib/dotzlib/, inside the zlib distribution.
+
+
+ 9. If my application uses ZLIB1.DLL, should I link it to
+ MSVCRT.DLL? Why?
+
+ - It is not required, but it is recommended to link your
+ application to MSVCRT.DLL, if it uses ZLIB1.DLL.
+
+ The executables (.EXE, .DLL, etc.) that are involved in the
+ same process and are using the C run-time library (i.e. they
+ are calling standard C functions), must link to the same
+ library. There are several libraries in the Win32 system:
+ CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
+ Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
+ depend on it should also be linked to MSVCRT.DLL.
+
+
+10. Why are you saying that ZLIB1.DLL and my application should
+ be linked to the same C run-time (CRT) library? I linked my
+ application and my DLLs to different C libraries (e.g. my
+ application to a static library, and my DLLs to MSVCRT.DLL),
+ and everything works fine.
+
+ - If a user library invokes only pure Win32 API (accessible via
+ and the related headers), its DLL build will work
+ in any context. But if this library invokes standard C API,
+ things get more complicated.
+
+ There is a single Win32 library in a Win32 system. Every
+ function in this library resides in a single DLL module, that
+ is safe to call from anywhere. On the other hand, there are
+ multiple versions of the C library, and each of them has its
+ own separate internal state. Standalone executables and user
+ DLLs that call standard C functions must link to a C run-time
+ (CRT) library, be it static or shared (DLL). Intermixing
+ occurs when an executable (not necessarily standalone) and a
+ DLL are linked to different CRTs, and both are running in the
+ same process.
+
+ Intermixing multiple CRTs is possible, as long as their
+ internal states are kept intact. The Microsoft Knowledge Base
+ articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
+ "HOWTO: Link with the Correct C Run-Time (CRT) Library"
+ mention the potential problems raised by intermixing.
+
+ If intermixing works for you, it's because your application
+ and DLLs are avoiding the corruption of each of the CRTs'
+ internal states, maybe by careful design, or maybe by fortune.
+
+ Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
+ as those provided by Borland, raises similar problems.
+
+
+11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
+
+ - MSVCRT.DLL exists on every Windows 95 with a new service pack
+ installed, or with Microsoft Internet Explorer 4 or later, and
+ on all other Windows 4.x or later (Windows 98, Windows NT 4,
+ or later). It is freely distributable; if not present in the
+ system, it can be downloaded from Microsoft or from other
+ software provider for free.
+
+ The fact that MSVCRT.DLL does not exist on a virgin Windows 95
+ is not so problematic. Windows 95 is scarcely found nowadays,
+ Microsoft ended its support a long time ago, and many recent
+ applications from various vendors, including Microsoft, do not
+ even run on it. Furthermore, no serious user should run
+ Windows 95 without a proper update installed.
+
+
+12. Why are you not linking ZLIB1.DLL to
+ <> ?
+
+ - We considered and abandoned the following alternatives:
+
+ * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
+ LIBCMT.LIB) is not a good option. People are using the DLL
+ mainly to save disk space. If you are linking your program
+ to a static C library, you may as well consider linking zlib
+ in statically, too.
+
+ * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
+ CRTDLL.DLL is present on every Win32 installation.
+ Unfortunately, it has a series of problems: it does not
+ work properly with Microsoft's C++ libraries, it does not
+ provide support for 64-bit file offsets, (and so on...),
+ and Microsoft discontinued its support a long time ago.
+
+ * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
+ with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
+ raises problems related to the status of ZLIB1.DLL as a
+ system component. According to the Microsoft Knowledge Base
+ article KB326922 "INFO: Redistribution of the Shared C
+ Runtime Component in Visual C++ .NET", MSVCR70.DLL and
+ MSVCR71.DLL are not supposed to function as system DLLs,
+ because they may clash with MSVCRT.DLL. Instead, the
+ application's installer is supposed to put these DLLs
+ (if needed) in the application's private directory.
+ If ZLIB1.DLL depends on a non-system runtime, it cannot
+ function as a redistributable system component.
+
+ * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
+ Borland's, or Cygwin's, raises problems related to the
+ reliable presence of these runtimes on Win32 systems.
+ It's easier to let the DLL build of zlib up to the people
+ who distribute these runtimes, and who may proceed as
+ explained in the answer to Question 14.
+
+
+13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
+ how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
+ (Visual Studio .NET) or newer?
+
+ - Due to the problems explained in the Microsoft Knowledge Base
+ article KB326922 (see the previous answer), the C runtime that
+ comes with the VC7 environment is no longer considered a
+ system component. That is, it should not be assumed that this
+ runtime exists, or may be installed in a system directory.
+ Since ZLIB1.DLL is supposed to be a system component, it may
+ not depend on a non-system component.
+
+ In order to link ZLIB1.DLL and your application to MSVCRT.DLL
+ in VC7, you need the library of Visual C++ 6.0 or older. If
+ you don't have this library at hand, it's probably best not to
+ use ZLIB1.DLL.
+
+ We are hoping that, in the future, Microsoft will provide a
+ way to build applications linked to a proper system runtime,
+ from the Visual C++ environment. Until then, you have a
+ couple of alternatives, such as linking zlib in statically.
+ If your application requires dynamic linking, you may proceed
+ as explained in the answer to Question 14.
+
+
+14. I need to link my own DLL build to a CRT different than
+ MSVCRT.DLL. What can I do?
+
+ - Feel free to rebuild the DLL from the zlib sources, and link
+ it the way you want. You should, however, clearly state that
+ your build is unofficial. You should give it a different file
+ name, and/or install it in a private directory that can be
+ accessed by your application only, and is not visible to the
+ others (i.e. it's neither in the PATH, nor in the SYSTEM or
+ SYSTEM32 directories). Otherwise, your build may clash with
+ applications that link to the official build.
+
+ For example, in Cygwin, zlib is linked to the Cygwin runtime
+ CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
+
+
+15. May I include additional pieces of code that I find useful,
+ link them in ZLIB1.DLL, and export them?
+
+ - No. A legitimate build of ZLIB1.DLL must not include code
+ that does not originate from the official zlib source code.
+ But you can make your own private DLL build, under a different
+ file name, as suggested in the previous answer.
+
+ For example, zlib is a part of the VCL library, distributed
+ with Borland Delphi and C++ Builder. The DLL build of VCL
+ is a redistributable file, named VCLxx.DLL.
+
+
+16. May I remove some functionality out of ZLIB1.DLL, by enabling
+ macros like NO_GZCOMPRESS or NO_GZIP at compile time?
+
+ - No. A legitimate build of ZLIB1.DLL must provide the complete
+ zlib functionality, as implemented in the official zlib source
+ code. But you can make your own private DLL build, under a
+ different file name, as suggested in the previous answer.
+
+
+17. I made my own ZLIB1.DLL build. Can I test it for compliance?
+
+ - We prefer that you download the official DLL from the zlib
+ web site. If you need something peculiar from this DLL, you
+ can send your suggestion to the zlib mailing list.
+
+ However, in case you do rebuild the DLL yourself, you can run
+ it with the test programs found in the DLL distribution.
+ Running these test programs is not a guarantee of compliance,
+ but a failure can imply a detected problem.
+
+**
+
+This document is written and maintained by
+Cosmin Truta
diff --git a/zlib/win32/Makefile.bor b/zlib/win32/Makefile.bor
new file mode 100644
index 000000000000..d152bbb7ffd9
--- /dev/null
+++ b/zlib/win32/Makefile.bor
@@ -0,0 +1,110 @@
+# Makefile for zlib
+# Borland C++ for Win32
+#
+# Usage:
+# make -f win32/Makefile.bor
+# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
+
+# ------------ Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
+# added to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+CC = bcc32
+AS = bcc32
+LD = bcc32
+AR = tlib
+CFLAGS = -a -d -k- -O2 $(LOC)
+ASFLAGS = $(LOC)
+LDFLAGS = $(LOC)
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+#OBJA =
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+#OBJPA=
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $<
+
+.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+ $(AR) $(ZLIB_LIB) $(OBJPA)
+
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+ -del $(ZLIB_LIB)
+ -del *.obj
+ -del *.exe
+ -del *.tds
+ -del zlib.bak
+ -del foo.gz
diff --git a/zlib/win32/Makefile.gcc b/zlib/win32/Makefile.gcc
new file mode 100644
index 000000000000..305be50afef6
--- /dev/null
+++ b/zlib/win32/Makefile.gcc
@@ -0,0 +1,182 @@
+# Makefile for zlib, derived from Makefile.dj2.
+# Modified for mingw32 by C. Spieler, 6/16/98.
+# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
+# Last updated: Mar 2012.
+# Tested under Cygwin and MinGW.
+
+# Copyright (C) 1995-2003 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type from the top level zlib directory:
+#
+# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
+#
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
+#
+# To install libz.a, zconf.h and zlib.h in the system directories, type:
+#
+# make install -fwin32/Makefile.gcc
+#
+# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
+#
+# To install the shared lib, append SHARED_MODE=1 to the make command :
+#
+# make install -fwin32/Makefile.gcc SHARED_MODE=1
+
+# Note:
+# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
+# the DLL name should be changed from "zlib1.dll".
+
+STATICLIB = libz.a
+SHAREDLIB = zlib1.dll
+IMPLIB = libz.dll.a
+
+#
+# Set to 1 if shared object needs to be installed
+#
+SHARED_MODE=0
+
+#LOC = -DASMV
+#LOC = -DZLIB_DEBUG -g
+
+PREFIX =
+CC = $(PREFIX)gcc
+CFLAGS = $(LOC) -O3 -Wall
+
+AS = $(CC)
+ASFLAGS = $(LOC) -Wall
+
+LD = $(CC)
+LDFLAGS = $(LOC)
+
+AR = $(PREFIX)ar
+ARFLAGS = rcs
+
+RC = $(PREFIX)windres
+RCFLAGS = --define GCC_WINDRES
+
+STRIP = $(PREFIX)strip
+
+CP = cp -fp
+# If GNU install is available, replace $(CP) with install.
+INSTALL = $(CP)
+RM = rm -f
+
+prefix ?= /usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+ gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+OBJA =
+
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+test: example.exe minigzip.exe
+ ./example
+ echo hello world | ./minigzip | ./minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+ ./example_d
+ echo hello world | ./minigzip_d | ./minigzip_d -d
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.S.o:
+ $(AS) $(ASFLAGS) -c -o $@ $<
+
+$(STATICLIB): $(OBJS) $(OBJA)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+ $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \
+ -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+ $(STRIP) $@
+
+example.exe: example.o $(STATICLIB)
+ $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
+ $(STRIP) $@
+
+minigzip.exe: minigzip.o $(STATICLIB)
+ $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
+ $(STRIP) $@
+
+example_d.exe: example.o $(IMPLIB)
+ $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
+ $(STRIP) $@
+
+minigzip_d.exe: minigzip.o $(IMPLIB)
+ $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
+ $(STRIP) $@
+
+example.o: test/example.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/example.c
+
+minigzip.o: test/minigzip.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
+
+zlibrc.o: win32/zlib1.rc
+ $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
+
+.PHONY: install uninstall clean
+
+install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
+ @if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \
+ echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \
+ exit 1; \
+ fi
+ -@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'
+ -@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig
+ -if [ "$(SHARED_MODE)" = "1" ]; then \
+ mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \
+ $(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \
+ $(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \
+ fi
+ -$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'
+ -$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'
+ -$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'
+ sed \
+ -e 's|@prefix@|${prefix}|g' \
+ -e 's|@exec_prefix@|${exec_prefix}|g' \
+ -e 's|@libdir@|$(LIBRARY_PATH)|g' \
+ -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \
+ -e 's|@includedir@|$(INCLUDE_PATH)|g' \
+ -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \
+ zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc
+
+uninstall:
+ -if [ "$(SHARED_MODE)" = "1" ]; then \
+ $(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \
+ $(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \
+ fi
+ -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h
+ -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h
+ -$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)
+
+clean:
+ -$(RM) $(STATICLIB)
+ -$(RM) $(SHAREDLIB)
+ -$(RM) $(IMPLIB)
+ -$(RM) *.o
+ -$(RM) *.exe
+ -$(RM) foo.gz
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/zlib/win32/Makefile.msc b/zlib/win32/Makefile.msc
new file mode 100644
index 000000000000..6831882de43e
--- /dev/null
+++ b/zlib/win32/Makefile.msc
@@ -0,0 +1,163 @@
+# Makefile for zlib using Microsoft (Visual) C
+# zlib is copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+#
+# Usage:
+# nmake -f win32/Makefile.msc (standard build)
+# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
+# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
+# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
+# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
+# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
+
+# The toplevel directory of the source tree.
+#
+TOP = .
+
+# optional build flags
+LOC =
+
+# variables
+STATICLIB = zlib.lib
+SHAREDLIB = zlib1.dll
+IMPLIB = zdll.lib
+
+CC = cl
+AS = ml
+LD = link
+AR = lib
+RC = rc
+CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)
+WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
+ASFLAGS = -coff -Zi $(LOC)
+LDFLAGS = -nologo -debug -incremental:no -opt:ref
+ARFLAGS = -nologo
+RCFLAGS = /dWIN32 /r
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
+ gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
+OBJA =
+
+
+# targets
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
+ example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+$(STATICLIB): $(OBJS) $(OBJA)
+ $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
+ $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
+ -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;2
+
+example.exe: example.obj $(STATICLIB)
+ $(LD) $(LDFLAGS) example.obj $(STATICLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip.exe: minigzip.obj $(STATICLIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+example_d.exe: example.obj $(IMPLIB)
+ $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip_d.exe: minigzip.obj $(IMPLIB)
+ $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+{$(TOP)}.c.obj:
+ $(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/test}.c.obj:
+ $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.c.obj:
+ $(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+{$(TOP)/contrib/masmx86}.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h
+
+deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
+
+gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h $(TOP)/inffixed.h
+
+inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h
+
+inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h $(TOP)/inffixed.h
+
+inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h
+
+trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h
+
+uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
+
+gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm
+
+inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm
+
+inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \
+ $(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h
+
+inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm
+
+match686.obj: $(TOP)/contrib\masmx86\match686.asm
+
+example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+zlib1.res: $(TOP)/win32/zlib1.rc
+ $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+ example_d
+ echo hello world | minigzip_d | minigzip_d -d
+
+
+# cleanup
+clean:
+ -del $(STATICLIB)
+ -del $(SHAREDLIB)
+ -del $(IMPLIB)
+ -del *.obj
+ -del *.res
+ -del *.exp
+ -del *.exe
+ -del *.pdb
+ -del *.manifest
+ -del foo.gz
diff --git a/zlib/win32/README-WIN32.txt b/zlib/win32/README-WIN32.txt
new file mode 100644
index 000000000000..df7ab7f4b34f
--- /dev/null
+++ b/zlib/win32/README-WIN32.txt
@@ -0,0 +1,103 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.11 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled
+examples are distributed in this package, example and minigzip. The example_d
+and minigzip_d flavors validate that the zlib1.dll file is working correctly.
+
+Questions about zlib should be sent to . The zlib home page
+is http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html
+before asking for help.
+
+
+Manifest:
+
+The package zlib-1.2.11-win32-x86.zip will contain the following files:
+
+ README-WIN32.txt This document
+ ChangeLog Changes since previous zlib packages
+ DLL_FAQ.txt Frequently asked questions about zlib1.dll
+ zlib.3.pdf Documentation of this library in Adobe Acrobat format
+
+ example.exe A statically-bound example (using zlib.lib, not the dll)
+ example.pdb Symbolic information for debugging example.exe
+
+ example_d.exe A zlib1.dll bound example (using zdll.lib)
+ example_d.pdb Symbolic information for debugging example_d.exe
+
+ minigzip.exe A statically-bound test program (using zlib.lib, not the dll)
+ minigzip.pdb Symbolic information for debugging minigzip.exe
+
+ minigzip_d.exe A zlib1.dll bound test program (using zdll.lib)
+ minigzip_d.pdb Symbolic information for debugging minigzip_d.exe
+
+ zlib.h Install these files into the compilers' INCLUDE path to
+ zconf.h compile programs which use zlib.lib or zdll.lib
+
+ zdll.lib Install these files into the compilers' LIB path if linking
+ zdll.exp a compiled program to the zlib1.dll binary
+
+ zlib.lib Install these files into the compilers' LIB path to link zlib
+ zlib.pdb into compiled programs, without zlib1.dll runtime dependency
+ (zlib.pdb provides debugging info to the compile time linker)
+
+ zlib1.dll Install this binary shared library into the system PATH, or
+ the program's runtime directory (where the .exe resides)
+ zlib1.pdb Install in the same directory as zlib1.dll, in order to debug
+ an application crash using WinDbg or similar tools.
+
+All .pdb files above are entirely optional, but are very useful to a developer
+attempting to diagnose program misbehavior or a crash. Many additional
+important files for developers can be found in the zlib127.zip source package
+available from http://zlib.net/ - review that package's README file for details.
+
+
+Acknowledgments:
+
+The deflate format used by zlib was defined by Phil Katz. The deflate and
+zlib specifications were written by L. Peter Deutsch. Thanks to all the
+people who reported problems and suggested various improvements in zlib; they
+are too numerous to cite here.
+
+
+Copyright notice:
+
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/zlib/win32/VisualC.txt b/zlib/win32/VisualC.txt
new file mode 100644
index 000000000000..1005b219410c
--- /dev/null
+++ b/zlib/win32/VisualC.txt
@@ -0,0 +1,3 @@
+
+To build zlib using the Microsoft Visual C++ environment,
+use the appropriate project from the contrib/vstudio/ directory.
diff --git a/zlib/win32/zlib.def b/zlib/win32/zlib.def
new file mode 100644
index 000000000000..a2188b000621
--- /dev/null
+++ b/zlib/win32/zlib.def
@@ -0,0 +1,94 @@
+; zlib data compression library
+EXPORTS
+; basic functions
+ zlibVersion
+ deflate
+ deflateEnd
+ inflate
+ inflateEnd
+; advanced functions
+ deflateSetDictionary
+ deflateGetDictionary
+ deflateCopy
+ deflateReset
+ deflateParams
+ deflateTune
+ deflateBound
+ deflatePending
+ deflatePrime
+ deflateSetHeader
+ inflateSetDictionary
+ inflateGetDictionary
+ inflateSync
+ inflateCopy
+ inflateReset
+ inflateReset2
+ inflatePrime
+ inflateMark
+ inflateGetHeader
+ inflateBack
+ inflateBackEnd
+ zlibCompileFlags
+; utility functions
+ compress
+ compress2
+ compressBound
+ uncompress
+ uncompress2
+ gzopen
+ gzdopen
+ gzbuffer
+ gzsetparams
+ gzread
+ gzfread
+ gzwrite
+ gzfwrite
+ gzprintf
+ gzvprintf
+ gzputs
+ gzgets
+ gzputc
+ gzgetc
+ gzungetc
+ gzflush
+ gzseek
+ gzrewind
+ gztell
+ gzoffset
+ gzeof
+ gzdirect
+ gzclose
+ gzclose_r
+ gzclose_w
+ gzerror
+ gzclearerr
+; large file functions
+ gzopen64
+ gzseek64
+ gztell64
+ gzoffset64
+ adler32_combine64
+ crc32_combine64
+; checksum functions
+ adler32
+ adler32_z
+ crc32
+ crc32_z
+ adler32_combine
+ crc32_combine
+; various hacks, don't look :)
+ deflateInit_
+ deflateInit2_
+ inflateInit_
+ inflateInit2_
+ inflateBackInit_
+ gzgetc_
+ zError
+ inflateSyncPoint
+ get_crc_table
+ inflateUndermine
+ inflateValidate
+ inflateCodesUsed
+ inflateResetKeep
+ deflateResetKeep
+ gzopen_w
diff --git a/zlib/win32/zlib1.rc b/zlib/win32/zlib1.rc
new file mode 100644
index 000000000000..234e641c3294
--- /dev/null
+++ b/zlib/win32/zlib1.rc
@@ -0,0 +1,40 @@
+#include
+#include "../zlib.h"
+
+#ifdef GCC_WINDRES
+VS_VERSION_INFO VERSIONINFO
+#else
+VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+#endif
+ FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+ PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS 1
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+ BEGIN
+ VALUE "FileDescription", "zlib data compression library\0"
+ VALUE "FileVersion", ZLIB_VERSION "\0"
+ VALUE "InternalName", "zlib1.dll\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ VALUE "OriginalFilename", "zlib1.dll\0"
+ VALUE "ProductName", "zlib\0"
+ VALUE "ProductVersion", ZLIB_VERSION "\0"
+ VALUE "Comments", "For more information visit http://www.zlib.net/\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/zlib/zconf.h b/zlib/zconf.h
deleted file mode 100644
index 7dbeb3be43c6..000000000000
--- a/zlib/zconf.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && defined(OS2)
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include /* for off_t */
-# include /* for SEEK_* and off_t */
-# ifdef VMS
-# include /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/zlib/zconf.h.cmakein b/zlib/zconf.h.cmakein
new file mode 100644
index 000000000000..a7f24cce60ff
--- /dev/null
+++ b/zlib/zconf.h.cmakein
@@ -0,0 +1,536 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+#cmakedefine Z_PREFIX
+#cmakedefine Z_HAVE_UNISTD_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define adler32_z z_adler32_z
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define crc32_z z_crc32_z
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateGetDictionary z_deflateGetDictionary
+# define deflateInit z_deflateInit
+# define deflateInit2 z_deflateInit2
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzfread z_gzfread
+# define gzfwrite z_gzfwrite
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzvprintf z_gzvprintf
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit z_inflateBackInit
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCodesUsed z_inflateCodesUsed
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit z_inflateInit
+# define inflateInit2 z_inflateInit2
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateResetKeep z_inflateResetKeep
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateValidate z_inflateValidate
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# define uncompress2 z_uncompress2
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+#ifdef Z_SOLO
+ typedef unsigned long z_size_t;
+#else
+# define z_longlong long long
+# if defined(NO_SIZE_T)
+ typedef unsigned NO_SIZE_T z_size_t;
+# elif defined(STDC)
+# include
+ typedef size_t z_size_t;
+# else
+ typedef unsigned long z_size_t;
+# endif
+# undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/zlib/zconf.h.in b/zlib/zconf.h.in
new file mode 100644
index 000000000000..5e1d68a004e9
--- /dev/null
+++ b/zlib/zconf.h.in
@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define adler32_z z_adler32_z
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define crc32_z z_crc32_z
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateGetDictionary z_deflateGetDictionary
+# define deflateInit z_deflateInit
+# define deflateInit2 z_deflateInit2
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzfread z_gzfread
+# define gzfwrite z_gzfwrite
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzvprintf z_gzvprintf
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit z_inflateBackInit
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCodesUsed z_inflateCodesUsed
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit z_inflateInit
+# define inflateInit2 z_inflateInit2
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateResetKeep z_inflateResetKeep
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateValidate z_inflateValidate
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# define uncompress2 z_uncompress2
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+#ifdef Z_SOLO
+ typedef unsigned long z_size_t;
+#else
+# define z_longlong long long
+# if defined(NO_SIZE_T)
+ typedef unsigned NO_SIZE_T z_size_t;
+# elif defined(STDC)
+# include
+ typedef size_t z_size_t;
+# else
+ typedef unsigned long z_size_t;
+# endif
+# undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/zlib/zlib.3 b/zlib/zlib.3
index 90b8162870fd..bda4eb073709 100644
--- a/zlib/zlib.3
+++ b/zlib/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "18 July 2005"
+.TH ZLIB 3 "15 Jan 2017"
.SH NAME
zlib \- compression/decompression library
.SH SYNOPSIS
@@ -9,15 +9,15 @@ for full description]
The
.I zlib
library is a general purpose data compression library.
-The code is thread safe.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
It provides in-memory compression and decompression functions,
including integrity checks of the uncompressed data.
This version of the library supports only one compression method (deflation)
-but other algorithms will be added later
-and will have the same stream interface.
+but other algorithms may be added later
+with the same stream interface.
.LP
Compression can be done in a single step if the buffers are large enough
-(for example if an input file is mmap'ed),
or can be done by repeated calls of the compression function.
In the latter case,
the application must provide more input and/or consume the output
@@ -30,91 +30,63 @@ with an interface similar to that of stdio.
.LP
The library does not install any signal handler.
The decoder checks the consistency of the compressed data,
-so the library should never crash even in case of corrupted input.
+so the library should never crash even in the case of corrupted input.
.LP
All functions of the compression library are documented in the file
.IR zlib.h .
The distribution source includes examples of use of the library
in the files
-.I example.c
+.I test/example.c
and
-.IR minigzip.c .
+.IR test/minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
.LP
Changes to this version are documented in the file
.I ChangeLog
-that accompanies the source,
-and are concerned primarily with bug fixes and portability enhancements.
+that accompanies the source.
.LP
-A Java implementation of
.I zlib
-is available in the Java Development Kit 1.1:
-.IP
-http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
-.LP
-A Perl interface to
-.IR zlib ,
-written by Paul Marquess (pmqs@cpan.org),
-is available at CPAN (Comprehensive Perl Archive Network) sites,
-including:
-.IP
-http://www.cpan.org/modules/by-module/Compress/
-.LP
-A Python interface to
-.IR zlib ,
-written by A.M. Kuchling (amk@magnet.com),
-is available in Python 1.5 and later versions:
-.IP
-http://www.python.org/doc/lib/module-zlib.html
+is built in to many languages and operating systems, including but not limited to
+Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go.
.LP
-A
-.I zlib
-binding for
-.IR tcl (1),
-written by Andreas Kupries (a.kupries@westend.com),
-is availlable at:
-.IP
-http://www.westend.com/~kupries/doc/trf/man/man.html
-.LP
-An experimental package to read and write files in .zip format,
+An experimental package to read and write files in the .zip format,
written on top of
.I zlib
by Gilles Vollant (info@winimage.com),
is available at:
.IP
-http://www.winimage.com/zLibDll/unzip.html
+http://www.winimage.com/zLibDll/minizip.html
and also in the
.I contrib/minizip
directory of the main
.I zlib
-web site.
+source distribution.
.SH "SEE ALSO"
The
.I zlib
-web site can be found at either of these locations:
+web site can be found at:
.IP
-http://www.zlib.org
-.br
-http://www.gzip.org/zlib/
+http://zlib.net/
.LP
-The data format used by the zlib library is described by RFC
+The data format used by the
+.I zlib
+library is described by RFC
(Request for Comments) 1950 to 1952 in the files:
.IP
-http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
+http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
.br
-http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
+http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
.br
-http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
-.LP
-These documents are also available in other formats from:
-.IP
-ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
.LP
-Mark Nelson (markn@ieee.org) wrote an article about
+Mark Nelson wrote an article about
.I zlib
for the Jan. 1997 issue of Dr. Dobb's Journal;
a copy of the article is available at:
.IP
-http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+http://marknelson.us/1997/01/01/zlib-engine/
.SH "REPORTING PROBLEMS"
Before reporting a problem,
please check the
@@ -127,22 +99,40 @@ Please read the
.I zlib
FAQ at:
.IP
-http://www.gzip.org/zlib/zlib_faq.html
+http://zlib.net/zlib_faq.html
.LP
before asking for help.
Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
-.SH AUTHORS
-Version 1.2.3
-Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org)
-and Mark Adler (madler@alumni.caltech.edu).
-.LP
-This software is provided "as-is,"
-without any express or implied warranty.
-In no event will the authors be held liable for any damages
+.SH AUTHORS AND LICENSE
+Version 1.2.11
+.LP
+Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+.LP
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
-See the distribution directory with respect to requirements
-governing redistribution.
+.LP
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+.LP
+.nr step 1 1
+.IP \n[step]. 3
+The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+.IP \n+[step].
+Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+.IP \n+[step].
+This notice may not be removed or altered from any source distribution.
+.LP
+Jean-loup Gailly Mark Adler
+.br
+jloup@gzip.org madler@alumni.caltech.edu
+.LP
The deflate format used by
.I zlib
was defined by Phil Katz.
diff --git a/zlib/zlib.h b/zlib/zlib.h
index 022817927ce3..08f491999c40 100644
--- a/zlib/zlib.h
+++ b/zlib/zlib.h
@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
+ version 1.2.11, January 15th, 2017
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+ Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -24,54 +24,58 @@
The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef ZLIB_H
#define ZLIB_H
-#include "zconf.h"
+#include
#ifdef __cplusplus
extern "C" {
#endif
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
+#define ZLIB_VERSION "1.2.11"
+#define ZLIB_VERNUM 0x12b0
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 11
+#define ZLIB_VER_SUBREVISION 0
/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
(providing more output space) before each call.
- The compressed data format used by default by the in-memory functions is
+ The compressed data format used by default by the in-memory functions is
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
around a deflate stream, which is itself documented in RFC 1951.
- The library also supports reading and writing files in gzip (.gz) format
+ The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio using the functions that start
with "gz". The gzip format is different from the zlib format. gzip is a
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
- This library can optionally read and write gzip streams in memory as well.
+ This library can optionally read and write gzip and raw deflate streams in
+ memory as well.
- The zlib format was designed to be compact and fast for use in memory
+ The zlib format was designed to be compact and fast for use in memory
and on communications channels. The gzip format was designed for single-
file compression on file systems, has a larger header than zlib to maintain
directory information, and uses a different, slower check method than zlib.
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in the case of corrupted input.
*/
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
@@ -80,23 +84,24 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state;
typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
+ z_const Bytef *next_in; /* next input byte */
uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
+ uLong total_in; /* total number of input bytes read so far */
- Bytef *next_out; /* next output byte should be put there */
+ Bytef *next_out; /* next output byte will go here */
uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
+ uLong total_out; /* total number of bytes output so far */
- char *msg; /* last error message, NULL if no error */
+ z_const char *msg; /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */
free_func zfree; /* used to free the internal state */
voidpf opaque; /* private data object passed to zalloc and zfree */
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
+ int data_type; /* best guess about the data type: binary or text
+ for deflate, or the decoding state for inflate */
+ uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */
uLong reserved; /* reserved for future use */
} z_stream;
@@ -126,45 +131,47 @@ typedef struct gz_header_s {
typedef gz_header FAR *gz_headerp;
/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
opaque value.
- zalloc must return Z_NULL if there is not enough memory for the object.
+ zalloc must return Z_NULL if there is not enough memory for the object.
If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
+ thread safe. In that case, zlib is thread-safe. When zalloc and zfree are
+ Z_NULL on entry to the initialization function, they are set to internal
+ routines that use the standard library functions malloc() and free().
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use by the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
*/
/* constants */
#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_PARTIAL_FLUSH 1
#define Z_SYNC_FLUSH 2
#define Z_FULL_FLUSH 3
#define Z_FINISH 4
#define Z_BLOCK 5
+#define Z_TREES 6
/* Allowed flush values; see deflate() and inflate() below for details */
#define Z_OK 0
@@ -176,8 +183,8 @@ typedef gz_header FAR *gz_headerp;
#define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5)
#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
*/
#define Z_NO_COMPRESSION 0
@@ -197,7 +204,7 @@ typedef gz_header FAR *gz_headerp;
#define Z_TEXT 1
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
+/* Possible values of the data_type field for deflate() */
#define Z_DEFLATED 8
/* The deflate compression method (the only one supported in this version) */
@@ -207,134 +214,162 @@ typedef gz_header FAR *gz_headerp;
#define zlib_version zlibVersion()
/* for compatibility with versions < 1.0.2 */
+
/* basic functions */
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
*/
/*
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
/*
deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
forced to flush.
- The detailed semantics are as follows. deflate performs one or both of the
+ The detailed semantics are as follows. deflate performs one or both of the
following actions:
- Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
+ accordingly. If not all input can be processed (because there is not
enough room in the output buffer), next_in and avail_in are updated and
processing will resume at this point for the next call of deflate().
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
+ - Generate more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
+ should be set only when necessary. Some output may be provided even if
+ flush is zero.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending. See deflatePending(),
+ which can be used if desired to determine whether or not there is more ouput
+ in that case.
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
+ decide how much data to accumulate before producing output, in order to
maximize compression.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed
+ codes block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
If flush is set to Z_FULL_FLUSH, all output is flushed as with
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
compression.
If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated
avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
avail_out is greater than six to avoid repeated flush markers due to
avail_out == 0 on return.
If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this
+ function must be called again with Z_FINISH and more output space (updated
+ avail_out) but no more input data, until it returns with Z_STREAM_END or an
+ error. After deflate has returned Z_STREAM_END, the only possible operations
+ on the stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used in the first deflate call after deflateInit if all the
+ compression is to be done in a single step. In order to complete in one
+ call, avail_out must be at least the value returned by deflateBound (see
+ below). Then deflate is guaranteed to return Z_STREAM_END. If not enough
+ output space is provided, deflate will not return Z_STREAM_END, and it must
+ be called again as described above.
+
+ deflate() sets strm->adler to the Adler-32 checksum of all input read
+ so far (that is, total_in bytes). If a gzip stream is being generated, then
+ strm->adler will be the CRC-32 checksum of the input read so far. (See
+ deflateInit2 below.)
deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
+ the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is
+ considered binary. This field is only for information purposes and does not
+ affect the compression algorithm in any manner.
deflate() returns Z_OK if some progress has been made (more input
processed or more output produced), Z_STREAM_END if all input has been
consumed and all output has been produced (only when flush is set to
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
+ if next_in or next_out was Z_NULL or the state was inadvertently written over
+ by the application), or Z_BUF_ERROR if no progress is possible (for example
+ avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and
+ deflate() can be called again with more input and more output space to
+ continue compressing.
*/
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
+ This function discards any unprocessed input and does not flush any pending
+ output.
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
deallocated).
*/
@@ -342,134 +377,157 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
- Initializes the internal stream state for decompression. The fields
+ Initializes the internal stream state for decompression. The fields
next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
+ the caller. In the current version of inflate, the provided input is not
+ read or consumed. The allocation of a sliding window will be deferred to
+ the first call of inflate (if the decompression does not complete on the
+ first call). If zalloc and zfree are set to Z_NULL, inflateInit updates
+ them to use default allocation functions.
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression.
+ Actual decompression will be done by inflate(). So next_in, and avail_in,
+ next_out, and avail_out are unused and unchanged. The current
+ implementation of inflateInit() does not process any header information --
+ that is deferred until inflate() is called.
*/
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
/*
inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
+ buffer becomes empty or the output buffer becomes full. It may introduce
some output latency (reading input without producing any output) except when
forced to flush.
- The detailed semantics are as follows. inflate performs one or both of the
+ The detailed semantics are as follows. inflate performs one or both of the
following actions:
- Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), then next_in and avail_in are updated
+ accordingly, and processing will resume at this point for the next call of
+ inflate().
+
+ - Generate more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. If the
+ caller of inflate() does not provide both available input and available
+ output space, it is possible that there will be no progress made. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
+ To assist in this, on return inflate() always sets strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
+ below. At the end of the stream, inflate() checks that its computed Adler-32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
only if the checksum is correct.
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained unless inflateGetHeader() is used. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ produced so far. The CRC-32 is checked against the gzip trailer, as is the
+ uncompressed length, modulo 2^32.
inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has
been reached and all uncompressed output has been produced, Z_NEED_DICT if a
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ value, in which case strm->msg points to a string with a more specific
+ error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL, or the state was inadvertently written over
+ by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
+ if no progress was possible or if there was not enough room in the output
+ buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is to be attempted.
*/
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
+ This function discards any unprocessed input and does not flush any pending
+ output.
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
+ inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
+ was inconsistent.
*/
+
/* Advanced functions */
/*
@@ -484,55 +542,70 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
int memLevel,
int strategy));
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
- The method parameter is the compression method. It must be Z_DEFLATED in
+ The method parameter is the compression method. It must be Z_DEFLATED in
this version of the library.
The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
deflateInit is used instead.
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
+ For the current implementation of deflate(), a windowBits value of 8 (a
+ window size of 256 bytes) is not supported. As a result, a request for 8
+ will result in 9 (a 512-byte window). In that case, providing 8 to
+ inflateInit2() will result in an error when the zlib header with 9 is
+ checked against the initialization of inflate(). The remedy is to not use 8
+ with deflateInit2() with this initialization, or at least in that case use 9
+ with inflateInit2().
- windowBits can also be greater than 15 for optional gzip encoding. Add
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute a check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to the appropriate value,
+ if the operating system was determined at compile time. If a gzip stream is
+ being written, strm->adler is a CRC-32 instead of an Adler-32.
+
+ For raw deflate or gzip encoding, a request for a 256-byte window is
+ rejected as invalid, since only the zlib header provides a means of
+ transmitting the window size to the decompressor.
The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
- The strategy parameter is used to tune the compression algorithm. Use the
+ The strategy parameter is used to tune the compression algorithm. Use the
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
@@ -540,38 +613,65 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
+ used strings preferably put towards the end of the dictionary. Using a
dictionary is most useful when the data to be compressed is short and can be
predicted with good accuracy; the data can then be compressed better than
with the default empty dictionary.
Depending on the size of the compression data structures selected by
deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
- Upon return of this function, strm->adler is set to the adler32 value
+ Upon return of this function, strm->adler is set to the Adler-32 value
of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
+ which dictionary has been used by the compressor. (The Adler-32 value
applies to the whole dictionary even if only a subset of the dictionary is
actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
+ Adler-32 value is not computed and strm->adler is not set.
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by deflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If deflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ deflateGetDictionary() may return a length less than the window size, even
+ when more than the window size in input has been provided. It may return up
+ to 258 bytes less in that case, due to how zlib's implementation of deflate
+ manages the sliding window and lookahead for matches, where matches can be
+ up to 258 bytes long. If the application needs the last window-size bytes of
+ input, then that would need to be saved by the application outside of zlib.
+
+ deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
*/
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
@@ -581,26 +681,26 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
This function can be useful when several compression strategies will be
tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
+ data with a filter. The streams that will be discarded should then be freed
by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
+ This function is equivalent to deflateEnd followed by deflateInit, but
+ does not free and reallocate the internal compression state. The stream
+ will leave the compression level and any other attributes that may have been
+ set unchanged.
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
*/
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
@@ -608,20 +708,36 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
int strategy));
/*
Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
+ interpretation of level and strategy is as in deflateInit2(). This can be
used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression approach (which is a function of the level) or the
+ strategy is changed, and if any input has been consumed in a previous
+ deflate() call, then the input available so far is compressed with the old
+ level and strategy using deflate(strm, Z_BLOCK). There are three approaches
+ for the compression levels 0, 1..3, and 4..9 respectively. The new level
+ and strategy will take effect at the next call of deflate().
+
+ If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
+ not have enough output space to complete, then the parameter change will not
+ take effect. In this case, deflateParams() can be called again with the
+ same parameters and more output space to try again.
+
+ In order to assure a change in the parameters on the first try, the
+ deflate stream should be flushed using deflate() with Z_BLOCK or other flush
+ request until strm.avail_out is not zero, before calling deflateParams().
+ Then no more input data should be provided before the deflateParams() call.
+ If this is done, the old level and strategy will be applied to the data
+ compressed before deflateParams(), and the new level and strategy will be
+ applied to the the data compressed after deflateParams().
+
+ deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
+ state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
+ there was not enough output space to complete the compression of the
+ available input data before a change in the strategy or approach. Note that
+ in the case of a Z_BUF_ERROR, the parameters are not changed. A return
+ value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
+ retried with more output space.
*/
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
@@ -645,31 +761,53 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
/*
deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
*/
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
int value));
/*
deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
gz_headerp head));
/*
- deflateSetHeader() provides gzip header information for when a gzip
+ deflateSetHeader() provides gzip header information for when a gzip
stream is requested by deflateInit2(). deflateSetHeader() may be called
after deflateInit2() or deflateReset() and before the first call of
deflate(). The text, time, os, extra field, name, and comment information
@@ -682,11 +820,11 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
1.3.x) do not support header crc's, and will report that it is a "multi-part
gzip file" and give up.
- If deflateSetHeader is not used, the default gzip header has text false,
+ If deflateSetHeader is not used, the default gzip header has text false,
the time set to zero, and os set to 255, with no extra, name, or comment
fields. The gzip header is returned to the default state by deflateReset().
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
@@ -694,43 +832,53 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
- This is another version of inflateInit with an extra parameter. The
+ This is another version of inflateInit with an extra parameter. The
fields next_in, avail_in, zalloc, zfree and opaque must be initialized
before by the caller.
The windowBits parameter is the base two logarithm of the maximum window
size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
+ deflateInit2() was not used. If a compressed stream with a larger window
size is given as input, inflate() will return with the error code
Z_DATA_ERROR instead of trying to allocate a larger window.
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
+ looking for any check values for comparison at the end of the stream. This
is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
+ such as zip. Those formats provide their own check values. If a custom
format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
+ recommended that a check value such as an Adler-32 or a CRC-32 be applied to
the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
+ most applications, the zlib format should be used as is. Note that comments
above on the use in deflateInit2() applies to the magnitude of windowBits.
- windowBits can also be greater than 15 for optional gzip decoding. Add
+ windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see
+ below), inflate() will not automatically decode concatenated gzip streams.
+ inflate() will return Z_STREAM_END at the end of the gzip stream. The state
+ would need to be reset to continue decoding a subsequent gzip stream.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
*/
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
@@ -738,36 +886,56 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the Adler-32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
+ expected one (incorrect Adler-32 value). inflateSetDictionary does not
perform any decompression: this will be done by subsequent calls of
inflate().
*/
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@@ -782,18 +950,32 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
/*
This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
+ but does not free and reallocate the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2. If the window size is changed, then the
+ memory allocated for the window is freed, and the window will be reallocated
+ by inflate() if needed.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
*/
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
@@ -801,54 +983,87 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
int value));
/*
This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above, or -65536 if the provided
+ source stream state was inconsistent.
+*/
+
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
gz_headerp head));
/*
- inflateGetHeader() requests that gzip header information be stored in the
+ inflateGetHeader() requests that gzip header information be stored in the
provided gz_header structure. inflateGetHeader() may be called after
inflateInit2() or inflateReset(), and before the first call of inflate().
As inflate() processes the gzip stream, head->done is zero until the header
is completed, at which time head->done is set to one. If a zlib stream is
being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
- The text, time, xflags, and os fields are filled in with the gzip header
+ The text, time, xflags, and os fields are filled in with the gzip header
contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
contains the maximum number of bytes to write to extra. Once done is true,
extra_len contains the actual extra field length, and extra contains the
extra field, or that field truncated if extra_max is less than extra_len.
If name is not Z_NULL, then up to name_max characters are written there,
terminated with a zero unless the length is greater than name_max. If
comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
absence. This allows the use of deflateSetHeader() with the returned
structure to duplicate the header. However if those fields are set to
allocated memory, then the application will need to save those pointers
elsewhere so that they can be eventually freed.
- If inflateGetHeader is not used, then the header information is simply
+ If inflateGetHeader is not used, then the header information is simply
discarded. The header is always checked for validity, including the header
CRC if present. inflateReset() will reset the process to discard the header
information. The application would need to call inflateGetHeader() again to
retrieve the header from the next gzip stream.
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
@@ -869,12 +1084,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
*/
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
@@ -882,25 +1098,26 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
out_func out, void FAR *out_desc));
/*
inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
A raw deflate stream is one with no zlib or gzip header or trailer.
This routine would normally be used in a utility that reads zip or gzip
files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the default
+ behavior of inflate(), which expects a zlib header and trailer around the
+ deflate stream.
inflateBack() uses two subroutines supplied by the caller that are then
called by inflateBack() for input and output. inflateBack() calls those
@@ -909,12 +1126,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
parameters and return types are defined above in the in_func and out_func
typedefs. inflateBack() will call in(in_desc, &buf) which should return the
number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
+ there is no input available, in() must return zero -- buf is ignored in that
+ case -- and inflateBack() will return a buffer error. inflateBack() will
+ call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
+ out() should return zero on success, or non-zero on failure. If out()
+ returns non-zero, inflateBack() will return with an error. Neither in() nor
+ out() are permitted to change the contents of the window provided to
inflateBackInit(), which is also the buffer that out() uses to write from.
The length written by out() will be at most the window size. Any non-zero
amount of input may be provided by in().
@@ -925,7 +1142,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
The in_desc and out_desc parameters of inflateBack() is passed as the
first parameter of in() and out() respectively when they are called. These
@@ -935,15 +1152,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
On return, inflateBack() will set strm->next_in and strm->avail_in to
pass back any unused input that was provided by the last in() call. The
return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
*/
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
@@ -964,7 +1181,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
7.6: size of z_off_t
Compiler, assembler, and debug options:
- 8: DEBUG
+ 8: ZLIB_DEBUG
9: ASMV or ASMINF -- use ASM code
10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
11: 0 (reserved)
@@ -995,27 +1212,28 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
27-31: 0 (reserved)
*/
+#ifndef Z_SOLO
/* utility functions */
/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
*/
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed data. compress() is equivalent to compress2() with a level
+ parameter of Z_DEFAULT_COMPRESSION.
+
compress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer.
@@ -1025,12 +1243,12 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
/*
- Compresses the source buffer into the destination buffer. The level
+ Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
+ length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed data.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
@@ -1040,159 +1258,306 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/*
compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
*/
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed data.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
*/
+ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen));
+/*
+ Same as uncompress, except that sourceLen is a pointer, where the
+ length of the source is *sourceLen. On return, *sourceLen is the number of
+ source bytes consumed.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
-typedef voidp gzFile;
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Three times that size in buffer space is allocated. A larger buffer
+ size of, for example, 64K or 128K bytes will noticeably increase the speed
+ of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
*/
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters. Previously provided
+ data is flushed before the parameter change.
+
+ gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
+ opened for writing, Z_ERRNO if there is an error writing the flushed data,
+ or Z_MEM_ERROR if there is a memory allocation error.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error. If len is too large to fit in an int,
+ then nothing is read, -1 is returned, and the error state is set to
+ Z_STREAM_ERROR.
*/
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
+ gzFile file));
/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
+ Read up to nitems items of size size from file to buf, otherwise operating
+ as gzread() does. This duplicates the interface of stdio's fread(), with
+ size_t request and return types. If the library defines size_t, then
+ z_size_t is identical to size_t. If not, then z_size_t is an unsigned
+ integer type that can contain a pointer.
+
+ gzfread() returns the number of full items read of size size, or zero if
+ the end of the file was reached and a full item could not be read, or if
+ there was an error. gzerror() must be consulted if zero is returned in
+ order to determine if there was an error. If the multiplication of size and
+ nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
+ is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
+
+ In the event that the end of file is reached and only a partial item is
+ available at the end, i.e. the remaining uncompressed data length is not a
+ multiple of size, then the final partial item is nevetheless read into buf
+ and the end-of-file flag is set. The length of the partial item read is not
+ provided, but could be inferred from the result of gztell(). This behavior
+ is the same as the behavior of fread() implementations in common libraries,
+ but it prevents the direct use of gzfread() to read a concurrently written
+ file, reseting and retrying on end-of-file, when size is not 1.
+*/
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
/*
Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
+ z_size_t nitems, gzFile file));
+/*
+ gzfwrite() writes nitems items of size size from buf to file, duplicating
+ the interface of stdio's fwrite(), with size_t request and return types. If
+ the library defines size_t, then z_size_t is identical to size_t. If not,
+ then z_size_t is an unsigned integer type that can contain a pointer.
+
+ gzfwrite() returns the number of full items written of size size, or zero
+ if there was an error. If the multiplication of size and nitems overflows,
+ i.e. the product does not fit in a z_size_t, then nothing is written, zero
+ is returned, and the error state is set to Z_STREAM_ERROR.
*/
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or a negative zlib error code in case
+ of error. The number of uncompressed bytes written is limited to 8191, or
+ one less than the buffer size given to gzbuffer(). The caller should assure
+ that this limit is not exceeded. If it is exceeded, then gzprintf() will
+ return an error (0) with nothing written. In this case, there may also be a
buffer overflow with unpredictable consequences, which is possible only if
zlib was compiled with the insecure functions sprintf() or vsprintf()
because the secure snprintf() or vsnprintf() functions were not available.
+ This can be determined using zlibCompileFlags().
*/
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
/*
- Writes the given null-terminated string to the compressed file, excluding
+ Writes the given null-terminated string to the compressed file, excluding
the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
+
+ gzputs returns the number of characters written, or -1 in case of error.
*/
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
*/
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
*/
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
*/
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
*/
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatenated gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
*/
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
the value SEEK_END is not supported.
+
If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
+ extremely slow. If the file is opened for writing, only forward seeks are
supported; gzseek then compresses a sequence of zeroes up to the new
starting position.
- gzseek returns the resulting offset location as measured in bytes from
+ gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error, in
particular if the file is opened for writing and the new starting position
would be before the current position.
@@ -1202,68 +1567,134 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
/*
Rewinds the given file. This function is supported only for reading.
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
*/
+/*
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
*/
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
*/
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
*/
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
*/
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
file that is being written concurrently.
*/
+#endif /* !Z_SOLO */
+
/* checksum functions */
/*
These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
+ anyway because they might be useful in applications using the compression
+ library.
*/
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
+ much faster.
+
+ Usage example:
uLong adler = adler32(0L, Z_NULL, 0);
@@ -1273,21 +1704,31 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
if (adler != original_adler) error();
*/
+ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
+ z_size_t len));
+/*
+ Same as adler32(), but with a size_t length.
+*/
+
+/*
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
z_off_t len2));
-/*
+
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
*/
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
performed within this function so it shouldn't be done by the application.
+
Usage example:
uLong crc = crc32(0L, Z_NULL, 0);
@@ -1298,9 +1739,15 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error();
*/
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
+ z_size_t len));
+/*
+ Same as crc32(), but with a size_t length.
+*/
/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
@@ -1328,27 +1775,135 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
unsigned char FAR *window,
const char *version,
int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
+#ifdef Z_PREFIX_SET
+# define z_deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+# define z_inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+#else
+# define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+# define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+# define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+# define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+#endif
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
+ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
#ifdef __cplusplus
}
diff --git a/zlib/zlib.pc.cmakein b/zlib/zlib.pc.cmakein
new file mode 100644
index 000000000000..a5e642938c69
--- /dev/null
+++ b/zlib/zlib.pc.cmakein
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@INSTALL_LIB_DIR@
+sharedlibdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/zlib/zlib.pc.in b/zlib/zlib.pc.in
new file mode 100644
index 000000000000..7e5acf9c77e7
--- /dev/null
+++ b/zlib/zlib.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+sharedlibdir=@sharedlibdir@
+includedir=@includedir@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/zlib/zlib2ansi b/zlib/zlib2ansi
new file mode 100755
index 000000000000..15e3e165f37d
--- /dev/null
+++ b/zlib/zlib2ansi
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+
+# Transform K&R C function definitions into ANSI equivalent.
+#
+# Author: Paul Marquess
+# Version: 1.0
+# Date: 3 October 2006
+
+# TODO
+#
+# Asumes no function pointer parameters. unless they are typedefed.
+# Assumes no literal strings that look like function definitions
+# Assumes functions start at the beginning of a line
+
+use strict;
+use warnings;
+
+local $/;
+$_ = <>;
+
+my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
+
+my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
+my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
+my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
+
+
+while (s/^
+ ( # Start $1
+ ( # Start $2
+ .*? # Minimal eat content
+ ( ^ \w [\w\s\*]+ ) # $3 -- function name
+ \s* # optional whitespace
+ ) # $2 - Matched up to before parameter list
+
+ \( \s* # Literal "(" + optional whitespace
+ ( [^\)]+ ) # $4 - one or more anythings except ")"
+ \s* \) # optional whitespace surrounding a Literal ")"
+
+ ( (?: $dList )+ ) # $5
+
+ $sp ^ { # literal "{" at start of line
+ ) # Remember to $1
+ //xsom
+ )
+{
+ my $all = $1 ;
+ my $prefix = $2;
+ my $param_list = $4 ;
+ my $params = $5;
+
+ StripComments($params);
+ StripComments($param_list);
+ $param_list =~ s/^\s+//;
+ $param_list =~ s/\s+$//;
+
+ my $i = 0 ;
+ my %pList = map { $_ => $i++ }
+ split /\s*,\s*/, $param_list;
+ my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
+
+ my @params = split /\s*;\s*/, $params;
+ my @outParams = ();
+ foreach my $p (@params)
+ {
+ if ($p =~ /,/)
+ {
+ my @bits = split /\s*,\s*/, $p;
+ my $first = shift @bits;
+ $first =~ s/^\s*//;
+ push @outParams, $first;
+ $first =~ /^(\w+\s*)/;
+ my $type = $1 ;
+ push @outParams, map { $type . $_ } @bits;
+ }
+ else
+ {
+ $p =~ s/^\s+//;
+ push @outParams, $p;
+ }
+ }
+
+
+ my %tmp = map { /$pMatch/; $_ => $pList{$1} }
+ @outParams ;
+
+ @outParams = map { " $_" }
+ sort { $tmp{$a} <=> $tmp{$b} }
+ @outParams ;
+
+ print $prefix ;
+ print "(\n" . join(",\n", @outParams) . ")\n";
+ print "{" ;
+
+}
+
+# Output any trailing code.
+print ;
+exit 0;
+
+
+sub StripComments
+{
+
+ no warnings;
+
+ # Strip C & C++ coments
+ # From the perlfaq
+ $_[0] =~
+
+ s{
+ /\* ## Start of /* ... */ comment
+ [^*]*\*+ ## Non-* followed by 1-or-more *'s
+ (
+ [^/*][^*]*\*+
+ )* ## 0-or-more things which don't start with /
+ ## but do end with '*'
+ / ## End of /* ... */ comment
+
+ | ## OR C++ Comment
+ // ## Start of C++ comment //
+ [^\n]* ## followed by 0-or-more non end of line characters
+
+ | ## OR various things which aren't comments:
+
+ (
+ " ## Start of " ... " string
+ (
+ \\. ## Escaped char
+ | ## OR
+ [^"\\] ## Non "\
+ )*
+ " ## End of " ... " string
+
+ | ## OR
+
+ ' ## Start of ' ... ' string
+ (
+ \\. ## Escaped char
+ | ## OR
+ [^'\\] ## Non '\
+ )*
+ ' ## End of ' ... ' string
+
+ | ## OR
+
+ . ## Anything other char
+ [^/"'\\]* ## Chars which doesn't start a comment, string or escape
+ )
+ }{$2}gxs;
+
+}
diff --git a/zlib/zutil.c b/zlib/zutil.c
index fc886094b0d1..a76c6b0c7e55 100644
--- a/zlib/zutil.c
+++ b/zlib/zutil.c
@@ -1,27 +1,27 @@
/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2017 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zutil.h"
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
+#ifndef Z_SOLO
+# include "gzguts.h"
#endif
-const char * const z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
+z_const char * const z_errmsg[10] = {
+ (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */
+ (z_const char *)"stream end", /* Z_STREAM_END 1 */
+ (z_const char *)"", /* Z_OK 0 */
+ (z_const char *)"file error", /* Z_ERRNO (-1) */
+ (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */
+ (z_const char *)"data error", /* Z_DATA_ERROR (-3) */
+ (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
+ (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */
+ (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
+ (z_const char *)""
+};
const char * ZEXPORT zlibVersion()
@@ -34,31 +34,31 @@ uLong ZEXPORT zlibCompileFlags()
uLong flags;
flags = 0;
- switch (sizeof(uInt)) {
+ switch ((int)(sizeof(uInt))) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
- switch (sizeof(uLong)) {
+ switch ((int)(sizeof(uLong))) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
- switch (sizeof(voidpf)) {
+ switch ((int)(sizeof(voidpf))) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
- switch (sizeof(z_off_t)) {
+ switch ((int)(sizeof(z_off_t))) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
@@ -85,41 +85,41 @@ uLong ZEXPORT zlibCompileFlags()
#ifdef FASTEST
flags += 1L << 21;
#endif
-#ifdef STDC
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifdef NO_vsnprintf
- flags += 1L << 25;
+ flags += 1L << 25;
# ifdef HAS_vsprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# endif
#else
- flags += 1L << 24;
+ flags += 1L << 24;
# ifdef NO_snprintf
- flags += 1L << 25;
+ flags += 1L << 25;
# ifdef HAS_sprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# endif
#endif
return flags;
}
-#ifdef DEBUG
-
+#ifdef ZLIB_DEBUG
+#include
# ifndef verbose
# define verbose 0
# endif
-int z_verbose = verbose;
+int ZLIB_INTERNAL z_verbose = verbose;
-void z_error (m)
+void ZLIB_INTERNAL z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
@@ -144,6 +144,44 @@ const char * ZEXPORT zError(err)
int errno = 0;
#endif
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
#ifdef SYS16BIT
@@ -176,11 +214,13 @@ local ptr_table table[MAX_PTR];
* a protected system like OS/2. Use Microsoft C instead.
*/
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
{
- voidpf buf = opaque; /* just to make some compilers happy */
+ voidpf buf;
ulg bsize = (ulg)items*size;
+ (void)opaque;
+
/* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
@@ -200,9 +240,12 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
return buf;
}
-void zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
int n;
+
+ (void)opaque;
+
if (*(ush*)&ptr != 0) { /* object < 64K */
farfree(ptr);
return;
@@ -218,7 +261,6 @@ void zcfree (voidpf opaque, voidpf ptr)
next_ptr--;
return;
}
- ptr = opaque; /* just to make some compilers happy */
Assert(0, "zcfree: ptr not found");
}
@@ -235,15 +277,15 @@ void zcfree (voidpf opaque, voidpf ptr)
# define _hfree hfree
#endif
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
{
- if (opaque) opaque = 0; /* to make compiler happy */
+ (void)opaque;
return _halloc((long)items, size);
}
-void zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
- if (opaque) opaque = 0; /* to make compiler happy */
+ (void)opaque;
_hfree(ptr);
}
@@ -260,22 +302,24 @@ extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
-voidpf zcalloc (opaque, items, size)
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
- if (opaque) items += size - size; /* make compiler happy */
+ (void)opaque;
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
(voidpf)calloc(items, size);
}
-void zcfree (opaque, ptr)
+void ZLIB_INTERNAL zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
+ (void)opaque;
free(ptr);
- if (opaque) return; /* make compiler happy */
}
#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/zlib/zutil.h b/zlib/zutil.h
index 8b4842ad8f55..b079ea6a80f5 100644
--- a/zlib/zutil.h
+++ b/zlib/zutil.h
@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -13,36 +13,32 @@
#ifndef ZUTIL_H
#define ZUTIL_H
-#define ZLIB_INTERNAL
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
#include "zlib.h"
-#ifdef STDC
-# ifndef _WIN32_WCE
+#if defined(STDC) && !defined(Z_SOLO)
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include
# endif
# include
# include
#endif
-#ifdef NO_ERRNO_H
-# ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
-# define errno z_errno
-# endif
- extern int errno;
-#else
-# ifndef _WIN32_WCE
-# include
-# endif
+
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
#endif
#ifndef local
# define local static
#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
+/* since "static" is used to mean two completely different things in C, we
+ define "local" for the non-static meaning of "static", for readability
+ (compile with -Dlocal if your debugger can't find static symbols) */
typedef unsigned char uch;
typedef uch FAR uchf;
@@ -50,13 +46,13 @@ typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
+ return (strm->msg = ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
@@ -88,67 +84,118 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include
+# endif
+# else /* MSC or DJGPP */
+# include
# endif
-# else /* MSC or DJGPP */
-# include
# endif
#endif
#ifdef AMIGA
-# define OS_CODE 0x01
+# define OS_CODE 1
#endif
#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
+# define OS_CODE 2
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
+#ifdef __370__
+# if __TARGET_LIB__ < 0x20000000
+# define OS_CODE 4
+# elif __TARGET_LIB__ < 0x40000000
+# define OS_CODE 11
+# else
+# define OS_CODE 8
+# endif
+#endif
+
#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
+# define OS_CODE 5
#endif
#ifdef OS2
-# define OS_CODE 0x06
-# ifdef M_I86
- #include
+# define OS_CODE 6
+# if defined(M_I86) && !defined(Z_SOLO)
+# include
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
+# define OS_CODE 7
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
# endif
#endif
-#ifdef TOPS20
-# define OS_CODE 0x0a
+#ifdef __acorn
+# define OS_CODE 13
+#endif
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+# define OS_CODE 10
+#endif
+
+#ifdef _BEOS_
+# define OS_CODE 16
#endif
-#ifdef WIN32
-# define OS_CODE 0x0b
+#ifdef __TOS_OS400__
+# define OS_CODE 18
#endif
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0f
+#ifdef __APPLE__
+# define OS_CODE 19
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
/* common defaults */
#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
+# define OS_CODE 3 /* assume Unix */
#endif
#ifndef F_OPEN
@@ -157,6 +204,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* functions */
+#if defined(pyr) || defined(Z_SOLO)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
@@ -166,12 +227,17 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
+#else
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
/* Diagnostic functions */
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
# include
- extern int z_verbose;
- extern void z_error OF((char *m));
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
@@ -187,13 +253,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define Tracecv(c,x)
#endif
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
#endif /* ZUTIL_H */